查看原文
其他

[系统安全] 四.OllyDbg动态分析工具基础用法及Crakeme逆向破解

杨秀璋 娜璋AI安全之家 2022-11-30

娜璋AI安全之家于2020年8月18日开通,将专注于Python和安全技术,主要分享Web渗透、系统安全、CVE复现、威胁情报分析、人工智能、大数据分析、恶意代码检测等文章。真心想把自己近十年的所学所做所感分享出来,与大家一起进步。

系统安全系列作者将深入研究恶意样本分析、逆向分析、攻防实战等,通过在线笔记和实践操作的形式分享与博友们学习,希望能与您一起进步。前文普及了IDA Pro反汇编工具的基础用法,并简单讲解一个EXE逆向解密的实战案例。这篇文章将详细介绍OllyDbg的基础用法,并结合两个Crakeme案例分享逆向破解。系统安全学好IDA(倚天)和OD(屠龙)真的非常重要,希望对入门的同学有帮助,作者的目的是与安全人共同进步,加油~

文章目录:

  • 一.OllyDbg工具简介

  • 二.OllyDbg分析Crakeme示例1

  • 三.OllyDbg分析Crakeme示例2

作者逆向github资源:

  • https://github.com/eastmountyxz/Reverse-Analysis-Case

声明:本人坚决反对利用教学方法进行犯罪的行为,一切犯罪行为必将受到严惩,绿色网络需要我们共同维护,更推荐大家了解它们背后的原理,更好地进行防护。(参考文献见后)


一.OllyDbg工具简介

OllyDbg是一个新的动态追踪工具,将IDA与SoftICE结合起来的思想,Ring 3级调试器,非常容易上手,是当今最为流行的调试解密工具之一。它还支持插件扩展功能,是目前最强大的调试工具之一。

OllyDbg打开如下图所示,包括反汇编窗口、寄存器窗口、信息窗口、数据窗口、堆栈窗口。

  • 反汇编窗口:显示被调试程序的反汇编代码,包括地址、HEX数据、反汇编、注释

  • 寄存器窗口:显示当前所选线程的CPU寄存器内容,点击标签可切换显示寄存器的方式

  • 信息窗口:显示反汇编窗口中选中的第一个命令的参数及跳转目标地址、字符等

  • 数据窗口:显示内存或文件的内容,右键菜单可切换显示方式

  • 堆栈窗口:显示当前线程的堆栈

下图是打开EXE后显示的界面。


下面简单讲解常用的快捷键调试方式。

  • F2:设置断点,如下图所示的红色位置,程序运行到此处会暂停,再按一次F2键会删除断点。

  • F9:按下这个键运行程序,如果没有设置相应的点,被调试的程序直接开始运行。

  • F8:单步步过,每按一次这个按键,将执行反汇编窗口中的一条指令,遇到CALL等子程序不进入其代码。

  • F7:单步步入,功能通过单步步过(F8)类似,区别是遇到CALL等子程序时会进入其中,进入后首先停留在子程序的第一条指令上。如下图进入CALL子程序。

  • F4:运行到选定位置,即运行到光标所在位置处暂停。

  • CTRL+F9:执行到返回,按下此键会执行到一个返回指令时暂停,常用于从系统领空返回到我们调试的程序领空。

  • ALT+F9:执行到用户代码,从系统领空快速返回我们调试的程序领空。


二.OllyDbg分析Crakeme示例1

第一个案例是 《加密与解密》书中Crakeme v3.0的文件,需要解密用户名和序列号。

点击“Register now”按钮,会有输入错误相关的提示,如下图所示。

OllyDbg动态分析的基本流程如下:

  • 通常拿到一个软件先试着运行软件,如果有帮助文档查阅帮助文档,熟悉软件的基本用法,接着尝试输入错误的注册码,观察错误提示。

  • 如果没有输入注册码的地方,要考虑是否是读取注册表或Key文件(程序读取一个文件中的内容判断是否注册),这些可以用其他工具来辅助分析。

  • 如果都不是,原程序只是一个功能不全的试用版,那要注册为正式版需要手动写代码完善。

  • 如果需要输入注册码,如上图所示,则调用查壳软件检查程序是否加壳(如PeiD、FI),有壳的需要脱壳之后再调用OllyDbg分析调试,无壳的直接调用工具调试。


下面开始正式的分析。

第一步:调用PEiD检测程序是否加壳。

反馈结果为“Borland Delphi 4.0 - 5.0”,无壳Delphi编写的文件。

第二步:运行CrakeMe V3.0文件,并点击“Register now”,提示错误信息。

对话框提示错误信息“Wrong Serial, try again!”。

第三步:启动OllyDbg软件,选择菜单“文件”,打开CrackMe3文件。

此时文件会停留在如下位置,双击注释位置能添加自定义注释。

第四步:在反汇编窗口右键鼠标,选择“查找”->“所有参考文本字串”。

弹出如下图所示的对话框。

第五步:右键选择“查找文本”,输入“Wrong”定位“Wrong Serial, try again!”位置。

如下图所示,定位到“Wrong Serial”位置。

第六步:接着右键鼠标,点击“反汇编窗口中跟随”。

接着定位到如下图所示位置。

第七步:选中该语句右键“查找参考”-:“选定地址”(快捷键Ctrl+R)。

弹出如下图所示的“参考页面”。

第八步:双机上面的两个地址(00440F79、00440F93),去到对应的位置。

在反汇编窗口中向上滚动窗口,可以看到核心代码:

第九步:通过查看跳转到“Wrong serial, try again”字符串的指令,可以查询相应的程序。

在“调试选项”->“CPU”->勾选“显示跳转路径”及“如跳转未实现则显示灰色路径”和“显示跳转到选定命令的路径”。

如下图所示:

第十步:详细分析反汇编代码。

在下图中,地址0040F2C处按下F2键设置断点,接着按F9运行程序。

输入“Test”和“754-GFX-IER-954”,点击“Register now!”,显示结果如下图所示。

程序会在断点处停止,同时提示刚才输入的内容。

输出内容如下所示,其中内存地址02091CE0中输入了刚才的“Test”。

第十一步:左击“ss:[0019F8FC]=02091CE0,(ASCII "Test")”,右键选择“数据窗口中跟随数值”,会在数据窗口中看到输入的内容。EAX=00000004 表示输入内容的长度为4个字符。

第十二步:调用F8按键和F7按键一步步分析代码。

回到下面00440F2C这部分代码,按下F8一步步运行,注意下面的核心代码。


第十三步:当F8运行到“00440F34 |. E8 F32BFCFF call crackme3.00403B2C”时,按下F7进入CALL子程序,此时光标停留在如下所示位置(00403B2C)。

这里的PUSH ebx、PUSH esi等都是调用子程序保存堆栈时使用的命令,按F8一步步运行代码。其核心解释如下,是基础的汇编语言:(参考看雪CCDebuger大神的《OllyDBG入门教程》)

重点:程序运行到如下图所示界面时,可以看到“Test”和“Registered User”的比较。通过上面图片的分析,我们知道用户名必须为“Registered User”。

第十四步:接着按F9键运行程序,出现错误对话框,点击确定,重新在编辑框中输入“Registered User”,再次点击“Register now!”按钮,分析调试程序。注意,F12键为暂停。

核心代码如下,其中地址00440F34的CALL已经分析清楚,继续F8执行下一步,知道第二个关键地方,即00440F51,按下F7进入子程序。注意:注释内容的提示不一定存在,需要动态调试程序到寄存器查看对应的注册码,才是正确的做法。

  1. 00440F34 |. E8 F32BFCFF call crackme3.00403B2C

  2. 00440F51 |. E8 D62BFCFF call crackme3.00403B2C

上面两句代码可以看到用户名和注册码都是调用同一子程序,这个CALL分析方法和上面一样。

第十五步:按F8调试该子程序,发现cmp比较两个值是否相等,其中0044102C为注册码内容。

第十六步:按F12暂停,再按F9重新运行,输入正确的用户名和密码,解密成功。

  • Registered User
  • GFX-754-IER-954

难点:调试程序时如何核心代码,比如这里的CMP比较,同时汇编代码也比较晦涩。


三.OllyDbg分析Crakeme示例2

这个案例是破解Crakeme中的Afkayas.1.EXE,这是典型的字符串序列破解程序,根据name的值推出serial。

第一步:通过PEiD检查它无壳,VB编写的

第二步:OllyDbg工具打开Afkayas.1.EXE文件如下图所示。

第三步:反汇编区域右键鼠标,选择“查找”->“所有参考文本字串”。

第四步:在弹出的对话框中找到失败的提示字符“You Get Wrong”,右键“反汇编窗口中跟随”。

此时会回到代码区,可以看到失败和成果的字符串。

第五步:通常成功和失败的反馈字符串相隔不远,需要在之前判断,如果输入的serial正确则成功,否则失败;接着向上找到调用字符串比较函数的入口点。

注意,这一步比较关键,但个人觉得需要长时间的经验和实践,才能准确定位。

汇编调用函数之前会先把参数入栈,然后用CALL指令调用函数。在字符串比较函数之前有一句 PUSH EAX 指令,可以推测这里的EAX就是字符串的首地址。

第六步:在比较函数00402533处按下F2键设置断点,接着按F9键执行,此时会弹出运行界面,我们输入“Eastmount”和“12345678”,然后点击OK按钮。

此时程序停留在断点处,右下角堆栈区显示了提示的正确Serial。



第七步:输入正确的用户名和Serial,成果注册。

  • Eastmount AKA-877848


下面结合鬼手大神和海天一色大神的博文,简单分析加密的基本逻辑,同时强烈推荐大家阅读他们的文章,参见前面的参考文献。这些逆向的经验真不是一朝一夕就能获取的,深知自己要学习和经历的东西太多,你我一起加油。

基本流程如下:
serial = 'AKA-' + 逆序itoa(strlen(name) * 0x17CFB + name[0])
  • 求出了用户名的长度

  • 将用户名长度乘以0x17CFB得到结果 如果溢出则跳转

  • 将结果再加上用户名的第一个字符的ASCII

  • 将结果转为十进制

  • 将结果和AKA进行拼接,得到最后的序列号

下面分享一段Python的解密代码。

# encoding: utf-8
key = "AKA"name = "Eastmount"
#获取用户名长度nameLen = len(name)print(u'获取用户名长度:')print(nameLen)
#用户名长度乘以0x17CFB得到结果res = nameLen * 0x17CFBprint(u'用户名长度乘以0x17CFB:')print(res)
#将结果加上用户名的第一个字符的ASCIIprint(name[0], ord(name[0]))res = res + ord(name[0])print(u'结果加上用户名第一个字符的ASCII:')print(res)
#转换为十进制 省略
#拼接序列号key = key + str(res)print(u'最终结果:')print(key)

定义不同的用户名可以得到对应的Serial。


四.总结

写到这里,这篇基础性文章就叙述完毕,网络安全要学习的知识真的很多,涉及面很广,包括汇编、网络、操作系统、加密解密、C/C++、Python等。希望自己能慢慢进步,科研与实践并重,也希望读者喜欢这系列总结笔记。不喜勿喷,与你同行~

系统安全前文赏析(点击跳转):

2020年8月18新开的“娜璋AI安全之家”,主要围绕Python大数据分析、网络空间安全、人工智能、Web渗透及攻防技术进行讲解,同时分享论文的算法实现。娜璋之家会更加系统,并重构作者的所有文章,从零讲解Python和安全,写了近十年文章,真心想把自己所学所感所做分享出来,还请各位多多指教,真诚邀请您的关注!谢谢。

(By:娜璋AI安全之家 2020-10-07 周三 夜于武汉)


参考文献:

  • 《加密与解密》段钢等著

  • 《OllyDBG入门教程》看雪学院 - CCDebuger

  • 初练160个CrakeMe程序之002 - 吾爱破解海神

  • 160个CrackMe002 - CSDN鬼手大神

  • [Crack杰破解实战] 之AfKayAs.2 - Crack杰大神

  • 逆向工程实战--Afkayas.1 - epsilon大神

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存