此篇参考合天网安实验室
的这篇文章
IDA安装keypatch插件
下载地址:https://github.com/keystone-engine/keypatch
1 | pip install keystone-engine |
将keypatch.py
文件复制到 IDA的plugins
文件夹下,重启IDA
安装成功
跳转指令
无符号跳转
汇编指令 | 描述 |
---|---|
JA | 无符号大于则跳转 |
JNA | 无符号不大于则跳转 |
JAE | 无符号大于等于则跳转(同JNB) |
JNAE | 无符号不大于等于则跳转(同JB) |
JB | 无符号小于则跳转 |
JNB | 无符号不小于则跳转 |
JBE | 无符号小于等于则跳转(同JNA) |
JBNE | 无符号不小于等于则跳转(同JA) |
有符号跳转
汇编指令 | 描述 |
---|---|
JG | 有符号大于则跳转 |
JNG | 有符号不大于则跳转 |
JGE | 有符号大于等于则跳转(同JNL) |
JNGE | 有符号不大于等于则跳转(同JL) |
JL | 有符号小于则跳转 |
JNL | 有符号不小于则跳转 |
JLE | 有符号小于等于则跳转(同JNG) |
JNLE | 有符号不小于等于则跳转(同JG) |
Patch-整数 溢出
scanf
以long int
长整形读取输入到unsigned int
变量v2
中, 然后将v2
强制转化为int
再与int 48
比较
但从scanf
读入一个负数时, 最高位为1, 从unsigned int
强制转换为int
结果是负数, 必定比48小, 在后面read读入会造成栈溢出
方法
将第九行的if
跳转汇编指令patch
为无符号的跳转指令, 具体参考跳转指令表
使用keypatch
进行修改
jle-->jbe
patch-栈溢出
对于栈溢出加固,x64 更容易一些,因为是使用寄存器传参,而x86 使用栈传参,需要用 nop 等保持加固前后的空间不变
x64
方法
100是第三个参数, 存储寄存器是rdx
, 找到给rdx
传参的汇编指令进行patch
使用ida默认修改插件修改(Edit-Patch Program-Change word), 也可以使用keypatch
0x64 是长度
0xBA 是操作符
1 | 0x64->0x20 |
x86
不需要对齐
找到压栈的指令, 修改压入的数值
- 修改数值需要补上
0x
- 这里修改前 size 为 2 ,修改后 size 也为 2 ,所以这题 patch 不需要用 nop 保持 size
需要对齐
找到压栈的指令, 修改压入的数值
直接修改0x20
后, size 长度不对齐, 会引起栈空间变化, 需要用nop
进行对齐
更方便快捷的方法是勾选NOPs padding until next instruction boundary
进行自动填充
patch-格式化字符串
修改函数
将printf
改为puts
, 将call
的地址改为puts plt
地址:
这个方法局限性在于: puts会在原字符串多加\n
, 主办方check
可能因此而不通过
修改printf
参数
将printf(format)
修改为`printf(“%s”,format)
修改printf
前面的传参指令:
1 | mov edi, offset 0x400c01; |
patch-UAF
修改逻辑是劫持call
指令跳转到.eh_frame
段上写入的自定义汇编程序
先在.eh_frame
段上写入代码, 首先是call free
完成释放, 然后对chunk_list
进行置零. 取chunk_list
地址的汇编可以从call free
前面抄过来
1 | call 0x900; #调用free函数(plt地址) |
patch-if范围
假设需要将图上第二个if放到if结构内, 修改跳转的地址即可:
原始跳转代码:
1 | js 0x40081C --> js 0x400845 |
patch-更换危险函数
类似与 uaf 一样写汇编实现功能调用,将危险函数替换为其他函数,如果程序中没有目标函数,就通过系统调用方式调用。
将 gets 替换为 read 输入
.eh_frame
写入汇编,将 rdi
的写入地址移动到 rsi
,把其他寄存器也传参之后进行系统调用:
pwn通防小工具
注意: 这里由于编译方式不同的原因, 作者写的工具目前仅适配Ubuntu16;18;20
基于pwntools和seccomp-tools的awd pwn通防小工具, 原创在这
GitHub地址: https://github.com/TTY-flag/evilPatcher
环境需要
运行需要依赖seccomps-tools和pwntools
pwntools安装
这里要在python2下安装,因为工具是基于python2的
1 | sudo apt install python2 |
seccomps-tools安装
1 | sudo gem install seccomp-tools |
test
结束后我们可以随便找一个pwn题试一下
1 | python2 exp1.py |
然后
1 | python2 evilPatcher.py pwn1 sandboxs/mini_sandbox.asm 1 |
试一下通防脚本
生成后的pwn1.patch
修改为pwn1
, 再运行一下exp
1 | python2 exp1.py |
成功!
- Post title: Pwn_patch
- Create time: 2023-06-21 21:49:29
- Post link: 2023/06/21/pwn_patch/
- Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.