AWDP一般分为两个板块,Break(自己的payload打通)和Fix(让主办方的payload打不通)
patch:指防御。
checker:指在部署题目的时候,检查选手提交的补丁(patch文件)是否符合预设条件的专门脚本。常见的非常规防御的例子就是把二进制文件直接删除、把关键漏洞语句直接删除、在堆利用的题目中将free语句直接删除等,checker就是用于检查选手是否存在这些非常规补丁的。它主要是通过和提交的二进制文件通信来判断这个二进制文件是否有异常。
打补丁有下面2个基本原则:
❑不改变程序的正常运行流程。
❑能够防御想要防御的攻击
patch实例

这个题的漏洞主要是get函数的无限制读入
1 | text:00000000004009CC call _puts |
要patch就要把它改为有限制的输入
改为read(0, s, 0x20);或者fgets(s, 0x20, stdin);
但问题来了:❌ 原地改不了
gets(s) 只需要:一个参数:s
而 read(0, s, 0x20) 需要:3 个参数:fd、buf、size
所以要从call gets
变化为(修改为read类型)
1 | mov rax,0 |
原来的位置放不下,所以要让程序跳转到其他位置去执行
在很多 CTF / AWDP 程序中:
.eh_frame段往往是:R--或R-X- 并且内容不会真的被程序用到
- 里面经常有:
- 一大段固定格式数据
- 或填充字节
在比赛中大家就把它当成:现成的“可执行空地”
所以选择
.eh_frame的本质原因是:👉 它往往是“能执行”的段
“填补 NOP 指令直到下一条指令边界”
作用:
当用一条新指令替换原来的多条指令、或长度更短时,用NOP把剩余空间补齐,避免留下半条旧指令的字节。在代码段(.text)里 patch 指令,且新指令比原指令短:
原来:
1
2 >mov rax, rbx ; 3字节
>add rax, rcx ; 3字节改成:
1 >xor eax, eax ; 2字节→ 剩下 4 字节会残留旧机器码
→ 必须用 NOP 填满
👉 需要勾你现在这种情况:在
.eh_frame写 read
.eh_frame原本是db xx(纯数据)- 不是指令流
- 没有“下一条指令边界”的概念
👉 不需要勾(勾不勾都不影响)
在_eh_frame上放read函数

patch call get过去到jmp_addr

之后应用就可以了

参考链接