网上关于pwn入门和学习的资源不胜枚举,但是关于CTF逆向的资料却寥寥无几,想把自己在学习逆向中的一些心得分享给大家,帮助大家打开二进制世界的大门。逆向的知识体系比较复杂,但是单纯针对比赛来说,还是有迹可循的。
调试32位程序:xp虚拟机,调试64位程序:win7虚拟机
第一步:查壳
其次,如果程序进行了加壳处理,如upx,asp。练习脱壳时要从手动和自动化工具两个角度去学习。其实在CTF中,它毕竟也是一个竞速比赛,看到upx,直接在命令行里面upx-d脱掉即可,屡试不爽,如果是asp,自动脱壳机可能会失败,可以直接使用ESP定律手动脱壳,dump出来,放入IDA静态分析即可。
大家要始终明确一下,脱壳与否并不影响OD动态调试,影响的只是IDA静态分析。
图1
PEID有非常多的实用插件,最常用的就是Krypto ANALyzer
发现DES加密
第二步:IDA静态分析(先静再动)
不一定就是说打开IDA直奔main函数,就多点击一下函数列表中的其它函数,并不一定只关注main函数,F5反汇编看一下,很多时候会有意外收获,在逆向中苦苦找不到核心算法,在pwn中找不到漏洞利用点,后门函数,说不定就随便看看可以就柳暗花明又一村了。
2.1查看程序框图
通过查看程序框图,可以大概了解程序大体的流程,正确/错误的程序走向,做到心中有数。如图一就是一道CTF中签到题,通过框图可以快速定位到关键跳转,连分析反汇编的步骤都省略了。
ecx寄存器在逆向中一个非常常见的作用就是当做缓冲区存放用户的输入, 被当做参数传入strlen函数,返回值存于eax中,接下来程序用eax(用户输入字符串的长度)与0x14做对比,决定程序走向。
可以按空格切换显示程序框图还是汇编代码
2.2 查看程序字符串
2.3 静态分析
IDA中C伪代码还是挺直观的,上图通过静态分析可以很明显的看出是Rot13算法,仅仅只需要检查字元字母顺序并取代它在13位之后的对应字母,有需要超过时则重新绕回26英文字母开头即可。A换成N、B换成O、依此类推到M换成Z。
2.4 常见函数静态识别
base32就是用32(2的5次方)个特定ASCII码来表示256个ASCII码。所以,5个ASCII字符经过base32编码后会变为8个字符(公约数为40),长度增加3/5.不足8n用“=”补足。(五扩八)
base16就是用16(2的4次方)个特定ASCII码表示256个ASCII字符。1个ASCII字符经过base16编码后会变为2个字符,长度增加一倍。不足2n用“=”补足(一扩二)
在CTF中常考的就是base64和base32,做题的时候心中默念base64三扩四,base32五扩八。
具体案例:
2.看表
3.看结构,会出现3,因为是3个字符变成4个字符,需要分组,分别是整除和求余,不足三位补齐&0xF,&0x3F
rc4算法流程并不复杂,重点理解算法即可,并且对内部多次限制256次循环,mod256,以及对数据strlen的读取的特点。
初始化过程:
其他一些算法如md5,DES等可以直接通过PEID的插件进行识别,这种方式适用于IDA静态分析,发现一堆复杂的代码,逻辑很混乱,这时候就要怀疑是不是嵌套的一些经典的算法,也有可能是混淆,。
2.5 IDA技巧
2.5.1常用快捷键
‘/’在代码旁添加注释
alt+m设置标签
ctrl+m跳到标记位置
这样做的好处可以帮助我们快速切换函数
第三步 动态分析
https://blog.csdn.net/abc_670/article/details/80066817。
用ida调试elf,你可以直接静态分析,找到关键函数然后在IDA中,F2下断点,之后进行动态调试可以直接断在断点处,非常方便。
3.1 OD快捷键:
F8:单步步过。每按一次这个键执行一条反汇编窗口中的一条指令,遇到 CALL 等子程序不进入其代码。
F7:单步步入。功能同单步步过(F8)类似,区别是遇到 CALL 等子程序时会进入其中,进入后首先会停留在子程序的第一条指令上。
F4:运行到选定位置。作用就是直接运行到光标所在位置处暂停。
F9:运行。按下这个键如果没有设置相应断点的话,被调试的程序将直接开始运行。
CTRL+F9:执行到返回。此命令在执行到一个 ret (返回指令)指令时暂停,常用于从系统领空返回到我们调试的程序领空。
ALT+F9:执行到用户代码。可用于从系统领空快速返回到我们调试的程序领空。
ALT+b 查看断点
Ctrl+f 查找命令
Ctrl+g 跳转到特点地址
Ctrl+N 查看导入表
3.2常见跳转指令
Z标志位(zero):这个标志位是最常用的,运算结果为0的时候,Z标志位置1,否则置0
O标志位(over):溢出标志,在运行过程中,如操作数超出了机器能表示的范围则成为溢出,此时OF位置1,否则置0
C标志位(carry):进位标志,记录运算时从最高有效位产生的进位值,例如执行加法指令时,最高有效位有进位时置1,否则置0
test eax eax:判断eax是不是0(常用于判断函数返回值,函数是否调用成功)
xor eax eax:清零(一旦看到这个指令,接下来就要注意被清零的寄存器)
test指令格式:test dest src
这个指令和and指令一样,对两个操作数进位按位的与运算,唯一不同的是不将‘与’的结果保存到dest中,即本指令仅对标志位重新置位。
跳转指令不用特地去记,就看执行完指令后,哪个标志位寄存器变红了即可,一般操作的都是ZF,可以通过汇编改跳转也可以直接双击标志位寄存器都可以是改变程序流程。
3.3调试技巧
遇到一些对数组动态处理加密的题目,(一般使用ecx寄存器存放用户输入数据)可以右键数据窗口跟随,可以动态看到数据处理整个过程。拿道题不要先动态调试,要先静后动,OD只用来调试关键函数。
逆向的知识体系比较复杂,需要熟知操作系统原理,计算机组成原理,熟练阅读汇编语言等等。我在入门的时候看书就看了大半年,虽然在比赛时,读书的价值无法直接体现出来,但是会潜移默化的影响你,让你对逆向有更深层次的感受,切忌一上来就刷题。
看雪的《加密与解密》主推,非常适合入门时阅读,B站上有配套的小甲鱼的视频,风趣幽默。
[韩]李承远的《逆向工程核心原理》,刚开始读会比较晦涩,但是里面干货满满。
如果想了解恶意软件分析技术的话,推荐《恶意代码分析实战》
对漏洞挖掘感兴趣的话,可以看《Oday安全:软件漏洞分析技术》
安卓三种类型的题目分值相加,也是占非常大比例的,而且二进制方面的题目难度系数普遍偏高,想要高的名次,还是需要二进制来拉开差距的。Re,pwn,安卓三种关系相当于re是基础,pwn是进阶,安卓是衍生,变体,二进制师傅任重道远。
参考链接:
本文始发于微信公众号(SecIN技术平台):原创 | 一名二进制CTF选手的一点心得
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论