一名二进制CTF选手的一点心得 – 作者:SecIN技术社区

原文来自SecIN社区—作者:寅儿

前言

先做一下自我介绍,双非普本网络工程专业的一名学生。从大一开始接触CTF,在队内担任二进制选手,有两年半CTF经验。在CTF中以赛代练,从杂项入门,后来接触逆向和pwn。现在在某实验室从事恶意样本分析和windows平台漏洞挖掘工作。网上关于pwn入门和学习的资源不胜枚举,但是关于CTF逆向的资料却寥寥无几,想把自己在学习逆向中的一些心得分享给大家,帮助大家打开二进制世界的大门。逆向的知识体系比较复杂,但是单纯针对比赛来说,还是有迹可循的。

PS:本人技术有限,如果表述错误或不当的地方,请各位大佬斧正。

工具准备

逆向常用工具:PEID,DIE,windbg,x32dbg,x64dbg,winhex,IDA,OD
调试32位程序:xp虚拟机,调试64位程序:win7虚拟机

CTF中逆向解题思路

第一步:查壳

查壳我常用的两个工具是PEID和DIE。查壳首先需要关注的是语言,比如VB,VC++,Go,易语言……每种语言都有其特定的特点和API函数调用,重点关注的是API函数,如GetWindowTextA(W), MessageBoxA(W)等等,查壳主要做到心中有数。CTF中变态的壳很少见(比如成熟的商业壳),毕竟考点也不在脱壳。

其次,如果程序进行了加壳处理,如upx,asp。练习脱壳时要从手动和自动化工具两个角度去学习。其实在CTF中,它毕竟也是一个竞速比赛,看到upx,直接在命令行里面upx -d脱掉即可,屡试不爽,如果是asp,自动脱壳机可能会失败,可以直接使用ESP定律手动脱壳,dump出来,放入IDA静态分析即可。

大家要始终明确一下,脱壳与否并不影响OD动态调试,影响的只是IDA静态分析。

图片[1]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图1

PEID有非常多的实用插件,最常用的就是Krypto ANALyzer,

图片[2]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科图片[3]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图2

发现DES加密

第二步:IDA静态分析(先静再动)

查壳完毕后,应该首先放入IDA静态分析,如果算法简单或者程序流程比较明了,直接静态分析即可,OD动态调试的目的只是用于调试那些无法直接通过静态分析简单明了看出加密流程的函数。在IDA里面有个技巧,左侧会出现在程序中调用的函数列表,大家就多点进去看看,不一定就是说打开IDA直奔main函数,就多点击一下函数列表中的其它函数,并不一定只关注main函数,F5反汇编看一下,很多时候会有意外收获,在逆向中苦苦找不到核心算法,在pwn中找不到漏洞利用点,后门函数,说不定就随便看看可以就柳暗花明又一村了。

程序载入IDA后,首先应该先看一下程序框图,就是IDA打开最原始的界面,如下图:

图片[4]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图3

通过查看程序框图,可以大概了解程序大体的流程,正确/错误的程序走向,做到心中有数。如图一就是一道CTF中签到题,通过框图可以快速定位到关键跳转,连分析反汇编的步骤都省略了,ecx寄存器在逆向中一个非常常见的作用就是当做缓冲区存放用户的输入, 被当做参数传入strlen函数,返回值存于eax中,接下来程序用eax(用户输入字符串的长度)与0x14做对比,决定程序走向。

可以按空格切换显示程序框图还是汇编代码

在CTF题目中,大多数情况下都可以在这里发现蛛丝马迹。如果运气比较好的话遇到签到题,flag可能会直接明文显示在此窗口,非常快乐。如果用来base系列算法加密,我们可以在这里发现base的码表(如果没有魔改),这个的作用就类似于OD的智能搜索,帮助我们快速定位到关键函数。在样本分析中,甚至可以直接通过字符串查找,获取C&C服务器的IP地址。

图片[5]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图4 明文显示flag

图片[6]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图5 base64码表

2.3 静态分析

通过关键字符串,找到关键函数,进行静态分析即可。遇到一些静态分析不直观的函数,这是才需要放入OD调试。

图片[7]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图6 静态分析

IDA中C伪代码还是挺直观的,上图通过静态分析可以很明显的看出是Rot13算法,仅仅只需要检查字元字母顺序并取代它在13位之后的对应字母,有需要超过时则重新绕回26英文字母开头即可。A换成N、B换成O、依此类推到M换成Z。

Base系列
base64编码是用64(2的6次方)个ASCII字符来表示256(2的8次方)个ASCII字符,也就是三位二进制数组经过编码后变为四位的ASCII字符显示,长度比原来增加1/3。(三扩四)

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五扩八。

具体案例:

  1. 数据
    Base系列最明显标志是”=”补位

图片[8]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

2.Base64识别:
1.看参数,对字符串测长
2.看表
3.看结构,会出现3,因为是3个字符变成4个字符,需要分组,分别是整除和求余,不足三位补齐&0xF,&0x3F

图片[9]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图片[10]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

3.Base32:以5个位(bit)为一组进行切分,对切分而成的每个组进行编码得到1个可见字符

图片[11]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

4.魔改
有时候出题人为了加大难度,会把base码表隐藏起来。轻则异或加密,变态的会对码表进行魔改。比如这题是对字母进行了倒序处理,奇数字母小写偶数字母大写,最后在码表尾部追加’765321’.经过一顿操作后的码表顺序变为zYxWvUtSrQpOnMlKjIhGfEdCbA765321。

图片[12]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

如果大家静态分析,对魔改过程不太熟悉的话,可以放入OD静态调试,可以完整的看到整个字符串处理过程。

图片[13]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

RC 4算法
rc 4算法流程并不复杂,重点理解算法即可,并且对内部多次限制256次循环,mod256,以及对数据strlen的读取的特点。
初始化过程:

图片[14]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

加密异或操作:

图片[15]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

经典算法识别
其他一些算法如md5,DES等可以直接通过PEID的插件进行识别,这种方式适用于IDA静态分析,发现一堆复杂的代码,逻辑很混乱,这时候就要怀疑是不是嵌套的一些经典的算法,也有可能是混淆,。

2.5 IDA技巧

看见一些数据,就可以随手右键,将其转换为16进制或char等等,可能会有意外收获。比如0x3D一眼看不出端倪,转化为char时,是’=’,非常敏感,审视代码是否符合base特征。

图片[16]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科
图片[17]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

原本杂乱无章的数据,转化为字符数组,意外发现base64码表。

Alt+b 搜索字符串

图片[18]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

在反汇编窗口,点击函数,按X,可以查看交叉引用,相当于在OD里面演示的直接跳转到上层调用它的函数

‘/’在代码旁添加注释

点击变量名,按’n’可以重命名变量,帮助分析和理解

图片[19]-一名二进制CTF选手的一点心得 – 作者:SecIN技术社区-安全小百科

标签
alt+m设置标签
ctrl+m跳到标记位置
这样做的好处可以帮助我们快速切换函数

第三步 动态分析

动态分析如果是exe,可以用windbg或者od,elf可以用edb或者gdb。CTF中逆向大概率elf偏多,因为ctf还是要贴近于实际,实际中服务器如www,ftp,dns等等是linux偏多。IDA也可以动态调试elf文件。具体参考
https://blog.csdn.net/abc_670/article/details/80066817。用ida调试elf,你可以直接静态分析,找到关键函数然后在IDA中,F2下断点,之后进行动态调试可以直接断在断点处,非常方便。

3.1 OD快捷键:

F2:设置断点,只要在光标定位的位置(上图中灰色条)按F2键即可,再按一次F2键则会删除断点。
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调试技巧

动态调试时,一定要眼观六路耳听八方,一道题有两个切入点,关键字符串或者API函数,动态调试时,一定要注意API函数的传参,也就是call指令之前的几个push,函数调用完以后注意eax寄存器,存放的是返回值。遇到一些对数组动态处理加密的题目,(一般使用ecx寄存器存放用户输入数据)可以右键数据窗口跟随,可以动态看到数据处理整个过程。拿道题不要先动态调试,要先静后动,OD只用来调试关键函数。

经典书籍

逆向的知识体系比较复杂,需要熟知操作系统原理,计算机组成原理,熟练阅读汇编语言等等。我在入门的时候看书就看了大半年,虽然在比赛时,读书的价值无法直接体现出来,但是会潜移默化的影响你,让你对逆向有更深层次的感受,切忌一上来就刷题。
看雪的《加密与解密》主推,非常适合入门时阅读,B站上有配套的小甲鱼的视频,风趣幽默。
[韩]李承远的《逆向工程核心原理》,刚开始读会比较晦涩,但是里面干货满满。
如果想了解恶意软件分析技术的话,推荐《恶意代码分析实战》
对漏洞挖掘感兴趣的话,可以看《Oday安全:软件漏洞分析技术》

总结

逆向讲究的是孰能生巧,一定要多练,在练中积累调试经验。还有一定要有耐心,有时候题真的很坑,出题人自己写的加密算法,花里胡哨,心平气和。CTF虽然以web题目为主,但是可以尝试一下把re,pwn,安卓三种类型的题目分值相加,也是占非常大比例的,而且二进制方面的题目难度系数普遍偏高,想要高的名次,还是需要二进制来拉开差距的。Re,pwn,安卓三种关系相当于re是基础,pwn是进阶,安卓是衍生,变体,二进制师傅任重道远。

参考链接:

https://www.52pojie.cn/thread-793420-1-1.html

来源:freebuf.com 2020-11-12 15:13:04 by: SecIN技术社区

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论