某大厂攻防大赛逆向题目破解

发布时间: 2019-12-24      作者:并擎科技

1.    前置知识

阅读本文需要的一些前置知识:

汇编、C 语言、IDA pro 静态分析、GDB 调试

2.    题目信息

只有一个文件,没有过多的提示,根据这个文件给出 flag


*不知道文件何意的请自行 Google

3.    前期分析

文件类型确认

没有看到后缀,又是逆向题目,初步分析是Linux 文件的可能性比较大,拖到Linux确认一下

可以看到文件确实是elf 文件


直接运行先看下执行过程



果然密码不是那么好猜到的

 

4.    中规中矩,分析开始

动态跑一跑、静态抓一抓

动态也不是那么好跑的,GDB  直接卡死

CTRL+C 中断之后的调试信息如下


    ^C
    Program received signal SIGINT, Interrupt.
    
    [----------------------------------registers-----------------------------------]
    RAX: 0xffffffffffffffff 
    RBX: 0x1 
    RCX: 0x7ffff7b0317e (<ptrace+78>:    cmprax,0xfffffffffffff000)
    RDX: 0xffffffffffffff70 
    RSI: 0x0 
    RDI: 0x0 
    RBP: 0x7fffffffdf90 --> 0x2 
    RSP: 0x7fffffffdf90 --> 0x2 
    RIP: 0x4007e4 (jmp0x4007e4)
    R8 : 0xffffffff 
    R9 : 0x0 
    R10: 0x0 
    R11: 0x282 
    R12: 0x600e08 --> 0x4006d0 (cmpQWORD PTR [rip+0x200748],0x0# 0x600e20)
    R13: 0x7fffffffe0c8 --> 0x7fffffffe3cb ("XDG_VTNR=1")
    R14: 0x7fffffffe0b8 --> 0x7fffffffe3b1 ("/root/debug/infinite-loop")
    R15: 0x1
    EFLAGS: 0x286 (carry PARITY adjust zero SIGN trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
       0x4007da:    call   0x400600 <ptrace@plt>
       0x4007df:    test   rax,rax
       0x4007e2:    jns0x4007e6
    => 0x4007e4:    jmp0x4007e4
     | 0x4007e6:    poprbp
     | 0x4007e7:    ret
     | 0x4007e8:    push   rbp
     | 0x4007e9:    movrbp,rsp
     |->=> 0x4007e4:    jmp0x4007e4
       0x4007e6:    poprbp
       0x4007e7:    ret
       0x4007e8:    push   rbp
      JUMP is taken
    [------------------------------------stack-------------------------------------]
    0000| 0x7fffffffdf90 --> 0x2 
    0008| 0x7fffffffdf98 --> 0x4008dd (addrbx,0x1)
    0016| 0x7fffffffdfa0 --> 0x7fffffffdfd0 --> 0x0 
    0024| 0x7fffffffdfa8 --> 0x0 
    0032| 0x7fffffffdfb0 --> 0x400890 (push   r15)
    0040| 0x7fffffffdfb8 --> 0x400610 (xorebp,ebp)
    0048| 0x7fffffffdfc0 --> 0x7fffffffe0b0 --> 0x1 
    0056| 0x7fffffffdfc8 --> 0x0 
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    Stopped reason: SIGINT
    0x00000000004007e4 in ?? ()
    Missing separate debuginfos, use: debuginfo-install glibc-2.17-292.el7.x86_64

 

根据异常信息,可以看出问题应该处在0x4007e4

因为运行卡住 ,文件存在反调试代码的可能性比较大
本片文章重点不是对抗反调试,直接给出去掉反调试的版本(下期可以讲一下如何破解反调试功能)

5.    GDB 调试成功

反调试功能去除之后可以直接调试


6.    IDA pro 静态分析

拖入IDA pro 寻找关键点,后面需要在GDB 中下断点(加快分析工作)

主函数还是比较简单的

只有一个判断,根据输入的内容(也就是密码),进行不同的输出

其实在破解软件的时候我们为了让软件直接输出正确的内容,直接Nop 掉关键点就ok了,但是这里直接使用Nop 不行,为什么?因为我们要知道程序的输入数据是什么,而不是获取程序的输出(功能)


IDA 图形界面更加清楚一些


关键点就清楚了  call    sub_4006FD

进入关键点看一下具体逻辑

关键函数

关键点的内容在下面两张图中,真的是太后老佛爷的裹脚布

直接分析这个函数,估计呀吐血三升了


直接F5 大法走起


一切都变得明了了,关键点在for 循环中,由i<=11 可以知道,密码的长度应该在12 位(0~11


回到默认视图,在cmp(比较指令) 前找一个关键点,此处是对eax 复制,后面会用来操作、比较


7.    转战GDB

关键点通过IDA pro 已经得到了,在 0x400784  下断点(what the f*ck ,竟然没有断下来,什么鬼?别急,要输入密码后才能断下来)


果然,输入密码之后,断点起作用,历经九九八十一难,终于可以动态分析了(程序停在了 `0x400784` 位置,根据前面的静态分析,密码长度为12位,我们这里直接输入12 位的密码以减少分析难度)


看到下面这块code 区域,通过edxeax 相减之后与0x1 比较,根据比较结果决定是否要进行跳转


此时看一下寄存器的值(目前阶段,可以认为RAXRDXeaxedx 等同 

如果需要edxeax 相减之后的结果等于1 ,则需要修改RAX 的值(寄存器中现有的‘a’,是我们之前输入的12 位密码中的个a


修改寄存器的值(因为edx 0x44 ,我们直接将eax 修改成0x43 就好了,注意 数据值都是16 进制的)


修改之后,第二次循环的寄存器状态如下,edx 变成了‘p’,同理,再次修改eax 的值即可(set $eax=0x69  ???NoNoNo,大错特错,这里是16 进制,不是10 进制)


 

循环执行上述步骤,得出eax 中的值为 Code_Talkers  也就是我们的密码

成功破解

输入eax 中的值试一下,成功破解


 

 

 

PS:

本篇没有对如何绕过反调试部分进行讲解,各位有兴趣可以留言,下期可以继续分享;另外此题还有另外一种更简单的破解方法,破解只需3 s

关于文章内容可以留言讨论