首页
社区
课程
招聘
160Crackme之02Afkayas.1
2022-1-27 12:28 22886

160Crackme之02Afkayas.1

2022-1-27 12:28
22886

师承15PB
课后练习160Crackme之记录篇

02.Afkayas.1

【1】运行exe

双击运行exe,随意输入Name和Serial看结果
结果弹出MessageBox并包含字符串L"You Get Wrong"
图片描述

【2】进入OD调试

OD打开exe软件并运行至程序入口点;
右键查找字符串找到相关代码
图片描述

【3】

栈回溯->发现jcc过来的,并非call调用
图片描述

【4】

爆破点[0040258B]je
图片描述

【5】

追踪[00402579]test si,si是关键
图片描述

【6】

往上追踪:si为什么会等于0

【7】

发现字符串:AKA-XXXXXX很诡异;大胆推测:Name或者Serial其中一个

【8】

je往上第一个[00402563]call 进入前si已经为0;

【9】

继续往上一个[00402550]call 进入前si已经为0;

【10】

继续往上一个[00402533]call 进入前si不为0;->探讨为什么si会变成0

【11】

探讨发现,AKA-XXXXX随Name的改变而改变->大胆推测:算法问题,每个账号都有对应的密码,而AKA-XXXXX就是密码->实验证明推理正确

【12】

改变思路:研究如何根据输入的Name计算得出Serial算法

【13】

继续向上最终call,在[004024F4]call 发现异常,指向完此call后EBP-1C存的既然是Serial对应的数字部分
图片描述

【14】

进入函数查看,发现Serial对应的数字部分早就已经算好了,怎么算的?倒推继续往上找call

【15】

发现[0040243F]call 有问题,call完后真正的Serial对应数字部分出来了,马上跟进去找
图片描述

【16】

进去第一个call没什么变化(我的做法是先f8过去call看对应的寄存器堆栈内存的变化,如果没变化就看下一个call,知道有我感兴趣的变化,我在进入call);然而第二个[740DBEE3]call有意思,进去看看
图片描述

【17】

跟踪到[7638E97E]call 进去看看

【18】

跟踪到[7638E941]call 进去看看

【19】

进去后发现[7638E8B3]-[7638E8D3]是生成Serial数字的关键点
图片描述

【20】

仔细观察后,发现[7638E8BA]的EBP+8的09 E8 0B 00 是重点,要去知道他怎么来的

 

BE809/A EAX==商;EDX==余数
余数EDX+=30->每次得出的结果是Serial数字的倒序

 

循环到EAX==0 结束

【21】

EBP+8 [12F3000] 09 E8 0B 00
原来[0012F318]就已经是这个数了
在追踪[0012F3A0]也是这个数
图片描述

【22】

最终发现[0040243E]处push edi让[0012F3A0]变成09 E8 0B 00的
也就是说追踪EDI的变化
往上查询,发现从[00402415]后开始edi从0开始变化
图片描述

【23】

edi先==Name的位数 [0040241B]
edi在*0x17CFB [00402420]
然后带符号扩展使得ax(输入Name的第一位)->edx [00402433]
edi在+=edx [00402436]

【24】

此时基本破解,但注意到两个溢出跳转[00402427]和[00402438]

【25】写个VS验证一下?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
插入代码
#include<stdio.h>
#include<vector>
using std::vector;
 
/*******************************************************************************************
 Crackme2 破解
 思路:输入Name 获取 Serial
*******************************************************************************************/
int main()
{
    //1.接收Name
    printf("输入Name的位数:");
    int Num = 0;
    scanf_s("%d", &Num);
    printf("输入Name:");
    int Name = 0;
    scanf_s("%d", &Name);
    int SerialNum = 0;
    while (Name/10)
    {
        Name /= 10;
    }
 
 
    SerialNum = Num * 0x17CFB;
    SerialNum+=(char)Name+0x30;
 
    vector<int> Serial;
 
    while (SerialNum)
    {
        Serial.push_back(SerialNum % 0xA+0x30);
        SerialNum /= 0xA;
    }
 
 
    for (int i = Serial.size() - 1; i >= 0; i--)
    {
        printf("%d", Serial[i]-0x30);
    }
 
 
 
    return 0;
}

图片描述
图片描述

 

AKA-是在je爆破点上方汇编代码最后比较加进去的!!!


[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。

上传的附件:
收藏
点赞4
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回