首页
社区
课程
招聘
[原创]gdb在逆向爆破中的应用
发表于: 2024-6-10 16:56 3246

[原创]gdb在逆向爆破中的应用

2024-6-10 16:56
3246

配套视频:https://www.bilibili.com/video/BV1gc411k7Bm/

1.概述

一般题目的抽象如下

一般来说,数据处理的过程有分为3种

  1. 输入的字符整体为一块,明文中任何一个字符改变都会改变密文。
    1. 非对称加密:RSA,ECC,抗量子算法,SM2,SM9
    2. 哈希算法:MD5,SHA,SM3,校验算法
    3. 其他:整除(base58),VM
  2. 输入的字符分块,明文中一个字符改变只会改变一块密文
    1. 分组加密:DES,AES,TEA,SM1,SM4,SM7
    2. 其他:传统base类(base64,32,16,85,),VM
  3. 逐字节加密,明文中改变一个字符只会改变密文的一个字符
    1. 古典密码:替换
    2. 流密码:RC4,ZUC,SSF46
    3. 其他:VM

综上所述,我们可以将所有的加密都看成块加密,只是有的块包含所有字符、有的块是固定长度、有的块只有一个字符。一般来说,块越大,算法解密难度越大,同样算法的理论依据也越深奥,实现也越复杂。能够在ctf中使用爆破解决的原因主要有以下两点。

  1. 一组加密字数越少,算法能力需要越低,算法理论知识需求越少,题目越容易控制。
  2. 逆向师傅大都不具备自定义可逆块加密的能力。

2.基本思路

对于逐字节加密的算法爆破思路如下

  1. 输入flag,控制第一个字符
  2. 执行到判断处
  3. 将加密后的数据与密文判断,当与密文第一个字符一样时,则可以确定明文的第一个字符。
  4. 从第一步重复执行。

3.工具

1.工具的选择

  1. 真实执行:gdb windbg(最新版脚本可以自动补全) ida frida radare2 ghidra
  2. 模拟执行:angr unidbg unicorn

本人使用过的一些工具对比如下表

<span style="display:inline-block;width: 40px"> 工具</span> <span style="display:inline-block;width: 200px">优点</span> <span style="display:inline-block;width: 200px"> 缺点</span>
gdb 速度快,文档详细 windows配置复杂,需要对C语言调用方式非常了解
windbg windows亲儿子, 不支持linuxterminal下的题目速度慢
ida 不解释 linux需要远程调试,terminal下的题目速度慢,文档垃圾
frida 速度快,对程序的抽象层与C语言一致 大部分情况需要patch程序,文档垃圾
radare2 功能非常全面,丰富的API ASLR、输入重定向等2个问题目前没找到解决方案
angr 所有内存都方便操作 模拟执行的问题它都有,只能做备用方案

就本人的使用经验推荐工具排序如下

  1. gdb:地表最强动态调试器不解释。缺点就是相对frida复杂很多,需要对内存布局比较熟练才可以。
  2. frida:对于与C语言抽象层一样的程序块,非常推荐,代码编写速度很快。在android等不方便使用gdb的环境下,frida非常优秀。不过我必须要吐槽一下,frida文档写的真是垃圾。
  3. ida/windbg:这两个是图形化的工具,由于需要爆破的题目大都是terminal下的,爆破内存还好,如果从输入端开始爆破,则每次都要启一个terminal,爆破过程非常缓慢。
  4. radare2:这个工具也非常推荐,有着丰富的API,只是由于ASLR、输入重定向等2个问题目前没找到解决方案,所以没有使用,下一步还要认真研究。
  5. angr:模拟执行是爆破中最不推荐的,模拟执行的问题它都有,只能做备用方案。

2.windows下的gdb使用

需要下载minggwhttps://www.mingw-w64.org/

3.亟需解决的困难

  1. 地址随机化问题
    1. linux:gdb 会关闭 ASLR
    2. windows:修改 dynamic-base 标识位
  2. 输入重定向问题
    1. bash:<
    2. cmd:<
    3. powershell:Get-Content .\aaa.txt | a.exe

4.举个栗子(2023年安洵杯_ez_cpp)

1.题目分析

题目的对比流程非常符合爆破特征,所以先爆为敬

2.关闭地址随机化

取消选择 dynamic-base

3.获取相关信息

1.动调出密文

使用movsx指令进行带符号扩展,所以密文只是最后一个字节即可。

1
enc = [0x22,0xA2,0x72,0xE6,0x52,0x8C,0xF2,0xD4,0xA6,0x0A,0x3C,0x24,0xA6,0x9C,0x86,0x24,0x42,0xD4,0x22,0xB6,0x14,0x42,0xCE,0xAC,0x14,0x6A,0x2C,0x7C,0xE4,0xE4,0xE4,0x1E]

2.加密后的明文地址

3.比较处的地址

4.爆破

1.存在的问题

在爆破过程中发现问题如下

打开保存的文件查看存在2个问题

  1. 第2个字符是?,显然不正确
  2. 第4个字符是a,程序崩溃

修改相应代码后继续爆破

2.问题分析

爆破结果如下,比赛时我就提交了这个SYC{Y3S-_E5-_0[-S0Ve-Th3-C9P!!!}但是不对,后来经师傅提示后,[ _ 显然不是flag内容,所以重新修改脚本。

再次爆破后得到真正flag

5.对抗

  1. 反调试
  2. 增加程序分支,尤其是加密后的程序分支。
  3. 循环进行加密对比,而非加密后一起对比
  4. 增加加密块的大小,加密块>3个字符则不具备可爆破性。

主要应对题型:2字节以内,加密算法非常复杂。

6.算法复杂度分析及提速方法

经测试,40个字符的flag,单字节爆破96*40大约需要5分钟,双字节爆破 96 * 96 * 20 大约3个小时,linux下更快一些。提速方法如下。

  1. 实体机
  2. windows下虚拟硬盘(10M),linux/dev/shm
  3. 优化算法
    1. 缩小字符串范围
    2. 确认提前结束循环的条件
  4. 采用分布式计算方式

7.其他

1.爆破任意代码段

本文中主要讲的的是如何从输入处开始爆破,实际情况是我可以爆破任意一段代码,并且在我的脚本中已经实现。具体思路如下。

  1. 定义起始点与结束点
  2. 起始点设置好上下文
  3. 结束点取出上下文进行对比
  4. 重复以上内容

在长时间的爆破过程中,我发现从输入端爆破在做题的时候更快、需要考虑的东西更少,所以大部分情况都是从输入开始爆破。只有个别情况想了解某一段代码的作用时才需要爆破任意代码段,而此时使用frida更为方便。

2.有待完善

对于下面的程序流程需要完善脚本(2023上海磐石大赛_flag在哪里?)


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 260
活跃值: (304)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
牛逼大佬,脚本下载下来了
2024-6-11 10:41
0
游客
登录 | 注册 方可回帖
返回
//