CTF中逆向的一些经验

admin 2023年8月6日20:53:50评论67 views字数 2543阅读8分28秒阅读模式

零基础黑客教程,黑客圈新闻,安全面试经验

尽在 # 暗网黑客教程 #


话不多说

咱直接进入正题


 判断文件类型


我们拿到的题目一般是一个二进制可执行文件,而其中的大部分不是Windows平台下的PE文件就是Linux平台下的ELF文件。

不管题目中所给文件带有什么扩展名,我们都应该亲自去检查文件头,使用任意文本编辑工具打开这个二进制文件

如果在开头看到MZ字样,那基本上可以确定这是一个Win系统下的可执行文件,相应的如果看到ELF字样即可基本断定这是一个运行于Linux系统下的可执行文件,扩展名为exe而实质上是一个ELF文件,这种情况在以往的CTF比赛中也是出现过的。

查壳与脱壳


由于近年来CTF比赛中带壳的逆向题出现频率稍有增加,在静态分析之前,进行查壳是非常有必要的,常用的工具有PEID等,进行查壳后,如果是简单且常见的壳如UPX等,那么直接可以使用工具完成脱壳,如果一时半会找不到可用的工具,也可以尝试手工脱壳,例如ASPack就能够采用ESP定律来脱除。

如果是侧重考察脱壳的题,一般程序本身就比较简单了,可以这样说,这类题如果能成功脱壳,基本上也算是做出来了。

当然,脱壳并不能解决所有问题,之前有CTF比赛中甚至出现了VMP的题目,对于这种情况,还是建议使用调试器去动态调试,毕竟在逆向工程中太依赖IDA的F5功能也是不行的,还是应该锻炼自己的汇编指令阅读能力。

如果是VMP比较新的版本,可能还需要使用Sharp OD等插件来隐藏调试行为。


 静态分析


一般是直接将二进制文件拖入IDA进行分析,在这个过程中,可以关注一下是否有符号库路径的提示出现

如果有这种情况,说明程序在编译阶段并没有清除相应的符号信息,我们或许能够从符号库路径的命名中得知一些关于本题的重要信息,大多数时候,静态分析完成后,我们会直接来到程序start处,直接F5,向下找即可来到main函数,直接查看反编译出来的C伪码 

然而有时候IDA会出现识别不了函数的情况

比如说分析到某一段代码,视图就从C伪码变为汇编指令视图了,这时候可以尝试手工地在这段汇编指令中识别出函数,并且使用IDA的创建函数功能,这样一来就能够继续查看C伪码,提高我们的做题效率
 
如何从一段汇编代码中把函数找出来?

首先得找到函数头部,很多函数的头部看起来会如下所示:
push    ebp
mov     ebp, esp

先将调用者的堆栈的基址(ebp)入栈,以保存之前任务的信息。

然后将调用者的栈顶指针(esp)的值赋给ebp,作为新的基址(即被调用者的栈底)。

然后我们继续寻找函数尾部
pop ebp
ret

需要注意的是,如果函数不只有一条路径返回值,我们还得确保函数尾部下方的跳转全都朝下,上方的跳转全部朝上
 
要是在IDA中遇到Sp analysis failed怎么办?

这种情况,有时候是由于某些指令的干扰导致IDA分析出来的栈平衡被破坏所致,会导致IDA生成C伪码失败

CTF中逆向的一些经验

我们需要手动地调整栈平衡,在IDA中依次点击Options-General,勾选Stack pointer
函数刚开始的指令看起来如下图所示:
CTF中逆向的一些经验
函数结束前的指令如下图:
CTF中逆向的一些经验
可以看到每一条指令的前面增加了一个数字,这个数字即指示栈顶指针(SP),在调用带参数的Call后,push和pop或者进行抬栈、清栈后栈顶指针才会改变

上图的mov esp,ebp后SP值显然不合理,应该使用Alt+K快捷键进行调整,调整后如下图所示:
CTF中逆向的一些经验
这时再使用F5,IDA已经能够生产正确的C伪码了



一些常见题型

  1.   方程组(HCTF2017逆向第一题)


对输入做了异或

CTF中逆向的一些经验

本题中三个方程的关键代码

CTF中逆向的一些经验

CTF中逆向的一些经验

爆破解法:

def solve(idx1,idx2,idx3,idx4):
   for x in range(0,255):
       if(((x ^ idx1 )& idx2 )>> idx3) | (((x ^ idx1) << idx3 )& idx2) == idx4:
           print(chr(x^0x76), end='')
key1 = [0x6f,0xdd,0xdd,0x48,0x64,0x63,0xd7]
for ele in key1:
   solve(0xAD,0xAA,0x1,ele)
key2 = [0x2e,0x2c,0xfe,0x6a,0x6d,0x2a,0xf2]
for ele in key2:
   solve(0xbe,0xcc,0x2,ele)
key3=[0x6f,0x9a,0x4d,0x8b,0x4b,0xfa,0x1a]
for ele in key3:
solve(0xef,0xf0,0x4,ele)

Z3约束器解法:

from z3 import *
def z3_solve(idx1,idx2,idx3,idx4):
   solver = Solver()
   x = BitVec('x', 32)
   solver.add((((x ^ idx1 )& idx2 )>> idx3) | (((x ^ idx1) << idx3 )& idx2) == idx4)
   if solver.check() == sat:
       print(chr(solver.model()[x].as_long() ^ 0x76), end='')
key1 = [0x6f,0xdd,0xdd,0x48,0x64,0x63,0xd7]
for ele in key1:
   z3_solve(0xAD,0xAA,0x1,ele)
key2 = [0x2e,0x2c,0xfe,0x6a,0x6d,0x2a,0xf2]
for ele in key2:
   z3_solve(0xbe,0xcc,0x2,ele)
key3=[0x6f,0x9a,0x4d,0x8b,0x4b,0xfa,0x1a]
for ele in key3:
z3_solve(0xef,0xf0,0x4,ele)

Z3是一款由微软开发的约束求解器,其代码目前托管在https://github.com/Z3Prover/z3

如果题目的方程比较简单,使用爆破当然简单粗暴,方便快捷;但当题目涉及到多元方程或者方程组时,使用Z3求解是比较高效率的,强烈推荐。







黑客教程~ 课件 靶场 ~ 限!时!免费!送!

长按识别二维码,即可限时免费报名课程。


CTF中逆向的一些经验





点击在看~好文大家给一起看!👇



原文始发于微信公众号(白帽子左一):CTF中逆向的一些经验

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年8月6日20:53:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CTF中逆向的一些经验https://cn-sec.com/archives/957299.html

发表评论

匿名网友 填写信息