本帖最后由 天象独行 于 2021-1-13 16:06 编辑
Crackme练习-Afkayas详细分析前言
该文章主要是分析了Crackme练习题当中第二道题Afkayas的解题做法,采用了暂停法,爆破,分析算法过程中主要是写出了分析过程中的想法。有什么想法出错的话或者是有更好的想法,希望各位大佬点评。谢谢。
一;测试环境
操作系统:Microsoft Windows XP
使用软件:OllyDBG
测试软件:如附件
二;软件功能宏观了解
首先,我们先打开软件初步了解一下功能,尝试点击两下测试一下,发现随意输入"Name","Serial"。弹出一个报错框,那么我们大胆的猜测,如果输入正确的"Name","Serial"是否就是弹出正确的提示框了呢?
Crackme练习-Afkayas详细分析
三;爆破法 3.1;思考想法 刚刚我们了解到,假设我们输入正确的"Name","Serial"弹出正确的提示框,错误的"Name","Serial"弹出错误的弹框。那么我们站在程序员的角度思考,我们该如何做到这个呢?我们知道在编程语言当中有一种分支语言的概念。例如if。那么我们知道了。想要完成这样一个功能,可以使用分支语句,既然是分支那么一定是有一个判断点来决定它是“正确”还是“错误”。既然是这样,我们尝试将这个“判断点”无论如何都是“正确”。那么这个软件不就破解了嘛?下面我们来整理一下思路。我需要破解该软件,可以找到“跳转点”使其无论如何指向“正确”,即跳转点的调用函数。(判断点是决定判断的方向,跳转点是依据判断点的结果决定调用的函数)
3.2;实战操作
3.2.1;使用OllDBG软件打开软件 我们使用OllDBG(注释:文章下面使用缩写OD来表示OllDBG软件)软件打开AfKayAs,运行程序,这个时候,我们发现软件运行,并且在软件运行框当中输入账号密码。这里我们举例使用账号:aaron,密码:123123。来测试。这个时候我们发现弹出错误框。
Crackme练习-Afkayas详细分析
3.2.2;暂停法
接下来,我们在OD当中暂停软件,并且在“调用堆栈”的窗口当中查看调用的弹窗函数。选中弹框函数右击跳转到函数代码位置。
注释:这里为何做出如下操作,请各位思考一下,刚刚程序是暂停在何处?很明显是暂停在弹出错误提示的窗口当中。那么,我们就知道该弹框函数必然是已经调用。我们在堆栈当中自然能发现。
Crackme练习-Afkayas详细分析
3.2.3;寻找“跳转点”
在跳转到函数位置的时候,我们适当的向上翻看,发现错误弹框的代码,那么我们知道了我们已经在“判断点”的位置附近了。如下图
Crackme练习-Afkayas详细分析
在往上看,紧接着我们发现一条je指令。从OD提示的跳转路径我们知道这个je指令就是我们需要找到的“跳转点”。
Crackme练习-Afkayas详细分析
3.3.4;失效“跳转点”
既然,我们已经找到“跳转点”我们可以使其失效。通常的办法可以使用nop指令替代jmp指令。详细如下:
Crackme练习-Afkayas详细分析
四;算法分析
刚刚我们使用了爆破法来处理这个软件。接下来,我们来分析一下它的算法。首先我们重新加载一下软件。我们由刚刚找到的“判断点”位置继续向上进行分析。
4.1;判断点
上文的分析,我们知道je 指令是跳转点,我们继续向上,看看它是对应的判断点是在哪里(即跳转点依旧判断点的值来决定跳转方向)。我们发现附近有一个test指令。详细如下代码:我们知道这个指令值依据si寄存器来判断,那么我们的目标变化为向上追踪发现到底哪条指令影响了该si寄存器。
00402579 . 66:85F6 test si,si //判断点位置
0040257C . 8945 94 mov dword ptr ss:[ebp-0x6C],eax
0040257F . 894D AC mov dword ptr ss:[ebp-0x54],ecx
00402582 . 8945 A4 mov dword ptr ss:[ebp-0x5C],eax
00402585 . 894D BC mov dword ptr ss:[ebp-0x44],ecx
00402588 . 8945 B4 mov dword ptr ss:[ebp-0x4C],eax
向上追踪,我们发现在如下代码位置,找到mov esi,eax 指令。我们知道了esi 最初是由这条指令赋值的。
00402539 . 8BF0 mov esi,eax ; 赋值esi
4.2;追逐函数
4.2.1;vbaStrCmp
知道目前位置,我们已经发现了寄存器ESI的来源是由EAX赋值的。那么我们向上追,看看EAX是如何产生的。首先,我们在紧接着上面的位置发现调用函数vbaStrCmp。我们在如下代码位置下断点,查看一下:
00402532 . 50 push eax ; eax输入 key = 'AKA-487752'
00402533 . FF15 28414000 call dword ptr ds:[<&MSVBVM50.__vbaStrCmp>] ; vbaStrcmp对比key 和 输入密码
00402539 . 8BF0 mov esi,eax ; eax,判断密码是否正确
从这里来看,我们发现“push eax”是传入vbaStrCmp函数的值,我们通过OD来进入vbaStrCmp仔细看看该函数做了哪些操作:详细如下:
7403F8F6 > FF7424 08 push dword ptr ss:[esp+0x8]
7403F8FA FF7424 08 push dword ptr ss:[esp+0x8]
7403F8FE 6A 00 push 0x0
7403F900 E8 5E3CFEFF call msvbvm50.__vbaStrComp
7403F905 0FBFC0 movsx eax,ax
7403F908 C2 0800 retn 0x8
函数堆栈情况如下:
0012F3F8 00000000
0012F3FC 06133DB4 UNICODE "AKA-487752"
0012F400 06093A04 UNICODE "123123"
分析:进入到vbaStrCmp内部之后,我们发现,vbaStrCmp函数将密码"123123"以及密钥“AKA-487752”放入堆栈中,通过调用“msvbvm50.__vbaStrComp”函数执行,执行完成之后将ax的值放入eax当中。那么,我们可以猜测函数vbaStrCmp的作用就是用来判断密码是否正确
4.2.2;vbaStrCat
现在我们知道vbaStrCmp是用来密码鱼密钥对比的,那么密钥“AKA-487752”是如何产生的呢?我们将断点定位到vbaStrCat位置,详细如下:
00402516 . 8B3D 00414000 mov edi,dword ptr ds:[<&MSVBVM50.__vbaStrCat>] ; msvbvm50.__vbaStrCat
0040251C . 50 push eax ; EAX = 密码 123123
0040251D . 68 701B4000 push Afkayas_.00401B70 ; UNICODE "AKA-"
00402522 . 51 push ecx ; 487752
00402523 . FFD7 call edi ; \vbaStrCat 产出key
我们通过OD可以知道,该函数vbaStrCat的传参值为输入的密码123123,字符串”AKA-“,数值”487752“然后,我们通过单步调用看看发现,最终EAX的值生成为”AKA-487752“。注释:通常情况下函数产生的值保存在寄存器EAX当中。
现在,我们知道了函数vbaStrCat产生密钥,同样,我们又会产生一个新的问题,输入参数当中数值487752是如何产生的呢?
4.2.3;核心代码
接下来,我们继续向上翻看,知道如下位置,该代码是产生数值48852的核心代码。总结:488752数值产生是使用输入账号的第一个字符转换为ASCII码加上账号长度与固定值0X17CFB乘积产生的。
004023ED . FF90 A0000000 call dword ptr ds:[eax+0xA0]
004023F3 . 3BC7 cmp eax,edi
004023F5 . 7D 12 jge short Afkayas_.00402409
004023F7 . 68 A0000000 push 0xA0
004023FC . 68 5C1B4000 push Afkayas_.00401B5C
00402401 . 53 push ebx
00402402 . 50 push eax
00402403 . FF15 04414000 call dword ptr ds:[<&MSVBVM50.__vbaHresultCheckObj>] ; msvbvm50.__vbaHresultCheckObj
00402409 > 8B95 50FFFFFF mov edx,dword ptr ss:[ebp-0xB0]
0040240F . 8B45 E4 mov eax,dword ptr ss:[ebp-0x1C] ; 导入账号
00402412 . 50 push eax ; /String = "487752"
00402413 . 8B1A mov ebx,dword ptr ds:[edx] ; |
00402415 . FF15 E4404000 call dword ptr ds:[<&MSVBVM50.__vbaLenBstr>] ; \__vbaLenBstr
0040241B . 8BF8 mov edi,eax ; //账户长度
0040241D . 8B4D E8 mov ecx,dword ptr ss:[ebp-0x18] ; 账号字符放入ECX
00402420 . 69FF FB7C0100 imul edi,edi,0x17CFB ; 账号长度*0x17CFB
00402426 . 51 push ecx ; /String = 0000ABA2 ???
00402427 . 0F80 91020000 jo Afkayas_.004026BE ; |
0040242D . FF15 F8404000 call dword ptr ds:[<&MSVBVM50.#rtcAnsiValueBstr_516>] ; \rtcAnsiValueBstr
00402433 . 0FBFD0 movsx edx,ax ; 字符“a”ASCII码0x61
00402436 . 03FA add edi,edx
00402438 . 0F80 80020000 jo Afkayas_.004026BE
0040243E . 57 push edi
0040243F . FF15 E0404000 call dword ptr ds:[<&MSVBVM50.__vbaStrI4>] ; msvbvm50.__vbaStrI4
00402445 . 8BD0 mov edx,eax ; edx = 487752
4.3;算法
if __name__ == '__main__':
while True:
b = input("请输入你的账户名称:")
data = len(b) * 0x17CFB + int(ord(b[0]))
print("AKA-{}".format(data))
4.4;验证 4.4.1;生成密码:
Crackme练习-Afkayas详细分析
4.4.2;验证
Crackme练习-Afkayas详细分析
|