crackme
这次我要解决这个漂亮的crackme ,这是系列的第三篇。 为了解决这个问题,我们将使用radare2的宏和独角兽仿真。 让我们跳进去吧!
一些介绍性分析
破解程序要求用户输入一次需要输入一位数字的4位密码。 类似于PIN。
看一下main,我们可以看到“ check_code_int”函数在其最大块的末尾附近被调用。
快速浏览一下“ check_code_int”函数会发现一连串的“ if”块,这些块以eax和ebx之间的校验结束,每一位数一个。
这些块几乎是相同的,它们都进行了一些计算,然后将ebx的值与eax中存储的期望值进行比较。 如果满足条件,则跳到下一个块,否则返回错误代码。
解决方案1:使用radare2宏
为了获得正确的密码,我们可以在比较时检查eax的值以获取每个数字。 以下是使用radare2提取代码的命令:
# set up relative breakpoints. one per cmp instruction
db sym.check_code_int+0x00001289-0x00001265
db sym.check_code_int+0x000012b7-0x00001265
db sym.check_code_int+0x000012e2-0x00001265
db sym.check_code_int+0x0000130d-0x00001265
# execute program
dc
# input four digits (doesn 't matter which ones)
1
1
1
1
# define a macro that replaces the value
# of ebx with the content of eax and stores it into a file
!rm ./crack_code
(eax_replace, dr ebx=`dr eax` | tee -a crack_code, dc)
# use the macro
.(eax_replace )@@=0 1 2 3
# show the results
!cat ./crack_code
这是动作中的美丽宏
现在我们可以继续打开箱子!
解决方案2:由GEF和独角兽引擎提供动力的Bruteforce
解决此问题的另一种方法是暴力破解密码。 由于存在合理数量的有效PIN(具体来说是10000),因此不会花太长时间。
我们可以模拟检查每个组合测试每个数字的函数,直到最后获得期望的状态。
使用GEF仿真功能可以轻松完成此操作,该功能会生成一个独角兽python脚本,然后我们可以对其进行修改和适应。
# 1 - step through the code in gdb
# 2 - reach the start of the check function
# in my case the function starts at 0x555555555269
# and ends at 0x555555555328
# 3 - use the GEF emu command :
emu -t 0x0000555555555328 -s -o emu.py
上面的命令将为我们生成一个仿真模板。 我们将需要对其进行一些修改,以便针对每个可能的PIN码运行仿真,直到找到正确的答案为止。
我们可以使用python的itertools生成引脚并重复该过程,直到在仿真运行结束时获得rax = 1为止。
在这里,我们可以看到整个过程耗时约7分钟。 它不是世界上最有效的方法,但是可以完成工作。 当然,如果需要的话,我们可以做很多调整以提高其性能。
您可以从我的Github中获得完整的仿真脚本,然后自己尝试。
最后的想法
- Radare2宏很棒! 我们可以更进一步,并使用我们之前编写的宏生成一个r2script以自动执行任务。
- 对于处理混淆的代码和进行暴力破解,仿真非常有用。
- 独角兽引擎是一个很棒的工具,GEF命令使我们的生活更加轻松。
- 模拟的另一种选择是尝试动态检测。 但我将其留在以后的帖子中。
希望你喜欢这个!
翻译自: https://hackernoon.com/re-using-macros-and-emulation-voodo-to-solve-a-crackme-szec3y2k
crackme