阿虚
Hello World!
Hello World!
婉若游龙

0x0 环境

——————–

环境:

系统:Windows 10

工具:IDA 7.X

——————–

0x1 跑起来

这个cm跑起来能看到两个按钮,并且两个按钮错误提示都是相同字符串“Sorry, please try again.”。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl1.png
http://www.xuwu.org/wp-content/uploads/2020/02/wryl2.png

不过第二个按钮如果你不输入任何东西会弹出“Please enter your serial number.”

http://www.xuwu.org/wp-content/uploads/2020/02/wryl3.png

0x2 IDA分析

把程序用丢进IDA字符串查找看样子是可以搜索到弹框的字符串列表。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl4.png

先通过对“Sorry, please try again.”查看引用出能发现两个地方,sub_401178和sub_4015E4两处。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl5.png

通过对字符串“Please enter your serial number.”进行交叉引用发现只有一处sub_4015E4使用。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl6.png

通过分析字符串引用处能够知道sub_401178是负责第一个检查按钮的实现函数。sub_4015E4是检查第二个按钮的实现函数。

第一个按钮

第一个按钮是在sub_401178函数中有引用“Please enter your serial number.”那么跳转到那里去用IDA图形分析模式看看那附近是什么样子。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl7-1024x559.png

图片可以看到1处为错误的弹框信息,旁边2也有个MessageBox弹框内容为“Congratulations, you got the hard coded serial”看起来像是验证成功的关键字。在3处为函数GetWindowText专门用于获取窗口字符串的,4处有个字符串“HardCoded”看起来像是正确的关键Key的样子。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl8.png

测试结果蒙对了。

第二个按钮分析

上面分析可以知道sub_4015E4是检查第二个按钮的实现函数。还是通过字符串引用过去看看。

http://www.xuwu.org/wp-content/uploads/2020/02/wryl9.png

看起来函数并不大,但是我的显示器窗口太小。好想要一台32寸的144HZ的2K高清显示器用来学逆向啊。

0x3 分析第二个按钮解码逻辑

.text:004015E4 sub_4015E4      proc near               ; CODE XREF: sub_401178+28A↑p
.text:004015E4
.text:004015E4 arg_0           = dword ptr  8
.text:004015E4 hWnd            = dword ptr  0Ch
.text:004015E4
.text:004015E4                 push    ebp
.text:004015E5                 mov     ebp, esp
.text:004015E7                 push    20h ; ' '       ; nMaxCount
.text:004015E9                 push    offset g_key_buf ; lpString
.text:004015EE                 push    [ebp+hWnd]      ; hWnd
.text:004015F1                 call    GetWindowTextA
.text:004015F6                 test    eax, eax
.text:004015F8                 jz      in_key_null
.text:004015FE                 mov     g_key_length, eax
.text:00401603                 push    0Bh             ; nMaxCount
.text:00401605                 push    offset g_name_buf ; lpString
.text:0040160A                 push    [ebp+arg_0]     ; hWnd
.text:0040160D                 call    GetWindowTextA
.text:00401612                 test    eax, eax
.text:00401614                 jz      short in_name_null
.text:00401616                 mov     g_name_length, eax
.text:0040161B                 xor     ecx, ecx
.text:0040161D                 xor     ebx, ebx
.text:0040161F                 xor     edx, edx
.text:00401621                 lea     esi, g_name_buf
.text:00401627                 lea     edi, g_name_dec_buf
.text:0040162D                 mov     ecx, 0Ah 
.text:00401632 do_while:                               ; CODE XREF: sub_4015E4+6C↓j
.text:00401632                 movsx   eax, byte ptr [esi+ebx]
.text:00401636                 cdq
.text:00401637                 idiv    ecx
.text:00401639                 xor     edx, ebx
.text:0040163B                 add     edx, 2          ; edx = (g_name_buf[i] % 10) ^ i + 2;
.text:0040163E                 cmp     dl, 0Ah
.text:00401641                 jl      short loc_401646 ; if ((BYTE)edx > 0x10)
.text:00401641                                         ;     edx -= 0x10;
.text:00401643                 sub     dl, 0Ah
.text:00401646
.text:00401646 loc_401646:                             ; CODE XREF: sub_4015E4+5D↑j
.text:00401646                 mov     [edi+ebx], dl   ; g_name_dec_buf[i] = edx;
.text:00401649                 inc     ebx             ; index++;
.text:0040164A                 cmp     ebx, g_name_length
.text:00401650                 jnz     short do_while  ;
.text:00401650                                         ; ;
.text:00401652                 xor     ecx, ecx
.text:00401654                 xor     ebx, ebx
.text:00401656                 xor     edx, edx
.text:00401658                 lea     esi, g_key_buf
.text:0040165E                 lea     edi, g_key_dec_buf
.text:00401664                 mov     ecx, 0Ah 
.text:00401669 do_while_2:                             ; CODE XREF: sub_4015E4+96↓j
.text:00401669                 movsx   eax, byte ptr [esi+ebx]
.text:0040166D                 cdq
.text:0040166E                 idiv    ecx
.text:00401670                 mov     [edi+ebx], dl   ; g_key_dec_buf[index] = g_name_buf[i] % 10;
.text:00401673                 inc     ebx             ; index++;
.text:00401674                 cmp     ebx, g_key_length
.text:0040167A                 jnz     short do_while_2
.text:0040167C                 jmp     short continue 
.text:0040167E in_name_null:                           ; CODE XREF: sub_4015E4+30↑j
.text:0040167E                 push    0               ; uType
.text:00401680                 push    offset Caption  ; "Splish, Splash"
.text:00401685                 push    offset aPleaseEnterYou ; "Please enter your name."
.text:0040168A                 push    0               ; hWnd
.text:0040168C                 call    MessageBoxA
.text:00401691                 jmp     short fun_end 
.text:00401693 in_key_null:                            ; CODE XREF: sub_4015E4+14↑j
.text:00401693                 push    0               ; uType
.text:00401695                 push    offset Caption  ; "Splish, Splash"
.text:0040169A                 push    offset aPleaseEnterYou_0 ; "Please enter your serial number."
.text:0040169F                 push    0               ; hWnd
.text:004016A1                 call    MessageBoxA
.text:004016A6                 jmp     short fun_end 
.text:004016A8 continue:                               ; CODE XREF: sub_4015E4+98↑j
.text:004016A8                 lea     esi, g_key_dec_buf
.text:004016AE                 lea     edi, g_name_dec_buf
.text:004016B4                 xor     ebx, ebx 
.text:004016B6 do_while_3:                             ; CODE XREF: sub_4015E4+E7↓j
.text:004016B6                 cmp     ebx, g_name_length
.text:004016BC                 jz      short check_ok
.text:004016BE                 movsx   eax, byte ptr [edi+ebx]
.text:004016C2                 movsx   ecx, byte ptr [esi+ebx]
.text:004016C6                 cmp     eax, ecx
.text:004016C8                 jnz     short check_err ; if (g_key_dec_buf[i] != g_name_dec_buf[i])
.text:004016C8                                         ;     jmp check_err;
.text:004016CA                 inc     ebx
.text:004016CB                 jmp     short do_while_3 
.text:004016CD check_ok:                               ; CODE XREF: sub_4015E4+D8↑j
.text:004016CD                 push    0               ; uType
.text:004016CF                 push    offset Caption  ; "Splish, Splash"
.text:004016D4                 push    offset aGoodJobNowKeyg ; "Good job, now keygen it."
.text:004016D9                 push    0               ; hWnd
.text:004016DB                 call    MessageBoxA
.text:004016E0                 jmp     short fun_end 
.text:004016E2 check_err:                              ; CODE XREF: sub_4015E4+E4↑j
.text:004016E2                 push    0               ; uType
.text:004016E4                 push    offset Caption  ; "Splish, Splash"
.text:004016E9                 push    offset aSorryPleaseTry ; "Sorry, please try again."
.text:004016EE                 push    0               ; hWnd
.text:004016F0                 call    MessageBoxA 
.text:004016F5 fun_end:                                ; CODE XREF: sub_4015E4+AD↑j
.text:004016F5                                         ; sub_4015E4+C2↑j ...
.text:004016F5                 leave
.text:004016F6                 retn    8
.text:004016F6 sub_4015E4      endp

算法比较简单,就是对输入的账户每一位进行摸10的结果在对当前字符所在的位置偏移进行异或结果在+2。并且这个结果不能超过10超过10就得减10得出来的数字。KEY的话只要上面NAME的计算结果搞搞只要能摸10还原就可以了。

0x4 C语言源码

// ConsoleApplication1.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdlib.h>
#include <windows.h>

bool check(char* user, char* password)
{
    int user_length = strlen(user);
    int key_length = strlen(password);

    char user_dec_buf[30] = { 0x0 };
    char key_dec_buf[30] = { 0x0 };

    for (int i = 0; i < user_length; i++)
    {
        char t = ((user[i] % 10) ^ i) + 2;
        if (t > 10)
            t -= 10;
        user_dec_buf[i] = t;
    }

    for (int i = 0; i < key_length; i++)
    {
        key_dec_buf[i] = password[i] % 10;
    }


    for (int i = 0; i < user_length; i++)
    {
        if (key_dec_buf[i] != user_dec_buf[i])
        {
            return false;
        }
    }

    return true;
}

bool reg(char* user, char* password)
{
    int user_length = strlen(user);
    int key_length = strlen(password);

    char user_dec_buf[30] = { 0x0 };
    char key_dec_buf[30] = { 0x0 };

    for (int i = 0; i < user_length; i++)
    {
        char t = ((user[i] % 10) ^ i) + 2;
        if (t > 10)
            t -= 10;
        user_dec_buf[i] = t;
    }

    for (int i = 0; i < user_length; i++)
    {
        password[i] = user_dec_buf[i] + 0x41 + 5;
    }

    return true;
}

int main()
{
    char name[] = "CTFHUB";
    char password[256] = { 0x0 };

    reg(name, password);

    if (check(name, password))
    {
        std::cout << "ok \n";
    }

    return 0;
}

阿虚

文章作者

发表评论

textsms
account_circle
email

Hello World!

婉若游龙
0x0 环境 -------------------- 环境: 系统:Windows 10 工具:IDA 7.X -------------------- 0x1 跑起来 这个cm跑起来能看到两个按钮,并且两个按钮错误提示都…
扫描二维码继续阅读
2020-02-21