首页
社区
课程
招聘
[原创]看雪2016 第三题 CrackMe逆向分析
发表于: 2016-11-7 15:32 5231

[原创]看雪2016 第三题 CrackMe逆向分析

2016-11-7 15:32
5231
od 打开crackme,查找所有参考字符串发现
004039E5     68 30484000    PUSH kanxue-c.00404830
004039EA     BA 90A04300    MOV EDX,kanxue-c.0043A090                      ;  ASCII "correct!"
004039EF     B9 38F04300    MOV ECX,kanxue-c.0043F038
004039F4     E8 27090000    CALL kanxue-c.00404320

这应该是表示注册成功提示,所以向上找跳转
0040399E     A1 70014400    MOV EAX,DWORD PTR DS:[440170]
004039A3     0FBE48 01      MOVSX ECX,BYTE PTR DS:[EAX+1]
004039A7     83F9 01        CMP ECX,1
004039AA     0F85 95000000  JNZ kanxue-c.00403A45
004039B0     57             PUSH EDI
004039B1     FF7424 20      PUSH DWORD PTR SS:[ESP+20]

找到一个,将BYTE PTR DS:[EAX+1]修改为1,运行之后发现"correct!",表示这个位置没错。接下来分析DWORD PTR DS:[440170]这个地址
通过查找所有地址常量列出所有引用该地址的代码,其中关键的为
0040344F   . 8D4D 90        LEA ECX,DWORD PTR SS:[EBP-70]
00403452   . E8 C9060000    CALL kanxue-c.00403B20                         ;  stringcmp
00403457   . 85C0           TEST EAX,EAX                                   ;  ==0 -> ok
00403459   . 75 0A          JNZ SHORT kanxue-c.00403465
0040345B   . 8B0D 70014400  MOV ECX,DWORD PTR DS:[440170]
00403461   . C641 01 01     MOV BYTE PTR DS:[ECX+1],1                ; <- 这里
00403465   > C785 38FFFFFF >MOV DWORD PTR SS:[EBP-C8],0
0040346F   . 8D4D 90        LEA ECX,DWORD PTR SS:[EBP-70]

地址 0043E628                         ;  g_SN
为全局对比值SN,为
00626DD8  C8 E5 E2 C3 C4 39 FC 04 48 D8 0F 8B 5F 73 8C A9  儒饷??H?媉s尒

继续往上找
004032BF   . E8 3CE7FFFF    CALL kanxue-c.00401A00                         ;  strtol
004032C4   . 83C4 08        ADD ESP,8
004032C7   . C645 FC 03     MOV BYTE PTR SS:[EBP-4],3
004032CB   . 8D4D D8        LEA ECX,DWORD PTR SS:[EBP-28]
004032CE   . E8 6DE8FFFF    CALL kanxue-c.00401B40
004032D3   . C645 FC 04     MOV BYTE PTR SS:[EBP-4],4
004032D7   . 8D45 D8        LEA EAX,DWORD PTR SS:[EBP-28]
004032DA   . 50             PUSH EAX
004032DB   . 8D4D A8        LEA ECX,DWORD PTR SS:[EBP-58]
004032DE   . 51             PUSH ECX
004032DF   . E8 1CE4FFFF    CALL kanxue-c.00401700                         ;  RSA
004032E4   . 83C4 08        ADD ESP,8
发现作者使用了libtomcrypt密码学库

这里是将输入序列号转换到long类型,之后进行RSA解密操作,通过跟踪RSA过程发现公钥为
00439FA0  30 20 30 0D 06 09 2A 86 48 86 F7 0D 01 01 01 05  0 0..*咹嗺.
00439FB0  00 03 0F 00 30 0C 02 05 00 F5 74 FD 11 02 03 01  ..0..鮰?
00439FC0  00 01                                            .
通过DER解码为
   0 30   32: SEQUENCE {
   2 30   13:   SEQUENCE {
   4 06    9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
  15 05    0:     NULL
            :     }
  17 03   15:   BIT STRING 0 unused bits
            :     30 0C 02 05 00 F5 74 FD 11 02 03 01 00 01
            :   }
N = F574FD11
使用RSA tool分解N得到私钥
D = 2BBE7481

serial = 私钥D加密(M),M为公钥解密的明文,注意RSA解密结果只取2个字节

继续向下分析,来到
00403434   . 8D45 90        LEA EAX,DWORD PTR SS:[EBP-70]
00403437   . 50             PUSH EAX
00403438   . C645 FC 05     MOV BYTE PTR SS:[EBP-4],5
0040343C   . E8 1FE4FFFF    CALL kanxue-c.00401860                         ;  SN=AES_EN(X)
00403441   . 83C4 34        ADD ESP,34
00403444   . 8985 30FFFFFF  MOV DWORD PTR SS:[EBP-D0],EAX

分析00401860函数可知为AES256加密,如下:

通过分析00401860 这个函数,得出SN=AES_EN(),返回值参与stringcmp比较,分析过程如下:
004018F3   .  E8 D8910000              call    0040AAD0                             ;  aes_key_expansion
004018F8   .  83C4 10                  add     esp, 10
004018FB   .  8D8D 38EBFFFF            lea     ecx, dword ptr [ebp-14C8]
00401901   .  51                       push    ecx
00401902   .  8D95 F0FBFFFF            lea     edx, dword ptr [ebp-410]
00401908   .  52                       push    edx
00401909   .  8D4D 0C                  lea     ecx, dword ptr [ebp+C]
0040190C   .  E8 DF040000              call    <stringptr>
00401911   .  50                       push    eax
00401912   .  E8 F9970000              call    0040B110                             ;  aes_en(in, out, key)
00401917   .  83C4 0C                  add     esp, 0C
0040191A   .  8985 30EBFFFF            mov     dword ptr [ebp-14D0], eax
00401920   .  83BD 30EBFFFF 00         cmp     dword ptr [ebp-14D0], 0
00401927   .  74 4B                    je      short 00401974
中断到004018F3,从堆栈找到key为:
00626F20  0F 5F 7B CD C0 66 0D 58 7C 86 D7 26 B1 C6 AA D1  _{屠f.X|喿&逼
00626F30  03 B2 12 85 C1 03 A3 51 BB C5 73 3B 3A D4 36 35  ?吜慌s;:?5

aes_en(in, out, key)
输入为 RSA的输出,所以完整表达式为
SN = AES_ENC(RSA_DEC(X))
其中SN为已知:
00626DD8  C8 E5 E2 C3 C4 39 FC 04 48 D8 0F 8B 5F 73 8C A9  儒饷??H?媉s尒
AES_KEY已知:
00626F20  0F 5F 7B CD C0 66 0D 58 7C 86 D7 26 B1 C6 AA D1  _{屠f.X|喿&逼
00626F30  03 B2 12 85 C1 03 A3 51 BB C5 73 3B 3A D4 36 35  ?吜慌s;:?5
私钥D已知:
D = 2BBE7481

计算X的程序如下:

#include "zmath.h"

int aes256_test(void)
{
        int i = 0;
        unsigned char key256[32] = {
                 0x0F, 0x5F, 0x7B, 0xCD, 0xC0, 0x66, 0x0D, 0x58, 0x7C, 0x86, 0xD7, 0x26, 0xB1, 0xC6, 0xAA, 0xD1,
                 0x03, 0xB2, 0x12, 0x85, 0xC1, 0x03, 0xA3, 0x51, 0xBB, 0xC5, 0x73, 0x3B, 0x3A, 0xD4, 0x36, 0x35
        };

        unsigned char _in[32] = {
                0xC8, 0xE5, 0xE2, 0xC3, 0xC4, 0x39, 0xFC, 0x04, 0x48, 0xD8, 0x0F, 0x8B, 0x5F, 0x73, 0x8C, 0xA9
        };

        unsigned char _out[256];
        zstate akey;
        zaes_init(&akey, key256, 256, 0);

        zaes_decrypt(&akey, _in, _out, 16);

        printf("AES256 解密结果:\n");
        for (i = 0; i < 16; i++)
                printf("%02X ", _out[i]);
        printf("\n");

        {
                void *D, *N, *M, *C;
                mp_init_multi(&D, &N, &M, &C, 0);

                unsigned char dd[] = { 0x2B, 0xBE, 0x74, 0x81 };
                mp_read_unsigned_bin(D, dd, 4);
                unsigned char nn[] = { 0xF5, 0x74, 0xFD, 0x11 };
                mp_read_unsigned_bin(N, nn, 4);

                unsigned char cc[8] = { 0 };
                for (int i = 0; i < 8; i++)
                {
                        mp_read_unsigned_bin(M, _out+i*2, 2); // 注意 2个字节
                        mp_exptmod(M, D, N, C);

                        mp_to_unsigned_bin(C, cc);
                        for (int j = 0; j < 4; j++)
                                printf("%02X", cc[j]);
                }

                mp_clear_multi(D, N, M, C, 0);
        }
        return 0;
}

输出为:
AES256 解密结果:
0D 48 ED 5E F7 69 E2 AB D6 8B FD 6C 76 DD 79 5D
3C4F963B039A2C377E02291E3C157AE591BCC1CA0A8F528EB2700AC021FB958D
上传的附件:
收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 1355
活跃值: (334)
能力值: ( LV13,RANK:920 )
在线值:
发帖
回帖
粉丝
2
写的很棒,支持!
2016-11-8 13:41
0
雪    币: 449
活跃值: (189)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
3
@HighHand HighHand果然名不虚传,我想问问,你是怎么发现我用了libtomcrypt库的?
还有,你是怎么识别出是RSA 算法,单靠看汇编吗?
2016-11-8 14:35
0
雪    币: 135
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
人如其名,高手~

是不是用了 ida的加密算法插件~
2016-11-8 14:44
0
雪    币: 3053
活跃值: (891)
能力值: ( LV13,RANK:1300 )
在线值:
发帖
回帖
粉丝
5
ltc_math_descriptor ==
00440194                                      0C 30 43 00              .0C.
004401A4  1C 00 00 00 20 D5 40 00 00 D6 40 00 80 D5 40 00  ... 誁..諤.€誁.
004401B4  A0 D5 40 00 D0 D5 40 00 70 D6 40 00 B0 D6 40 00  犝@.姓@.p諤.爸@.
004401C4  D0 D6 40 00 00 D7 40 00 20 D7 40 00 60 D7 40 00  兄@..譆. 譆.`譆.
004401D4  A0 D7 40 00 C0 D7 40 00 E0 D7 40 00 20 D8 40 00  犠@.雷@.嘧@. 谸.
004401E4  50 D8 40 00 80 D8 40 00 A0 D8 40 00 D0 D8 40 00  P谸.€谸.犡@.胸@.
004401F4  00 D9 40 00 40 D9 40 00 70 D9 40 00 B0 D9 40 00  .貮.@貮.p貮.百@.
00440204  E0 D9 40 00 20 DA 40 00 50 DA 40 00 80 DA 40 00  噘@. 贎.P贎.€贎.
00440214  B0 DA 40 00 E0 DA 40 00 30 DB 40 00 70 DB 40 00  摆@.嘹@.0跕.p跕.
00440224  B0 DB 40 00 F0 DB 40 00 30 DC 40 00 70 DC 40 00  佰@.疔@.0蹳.p蹳.
00440234  E0 DC 40 00 10 DD 40 00 30 3D 41 00 50 DD 40 00  嘬@.軥.0=A.P軥.
00440244  90 DD 40 00 A0 F1 40 00 90 E9 40 00 20 E4 40 00  愝@.狇@.愰@. 銨.
00440254  60 FC 40 00 40 F7 40 00 D0 FD 40 00 50 BE 40 00  `麫.@鰼.旋@.P継.

通过这个
libtomcrypt 经常用,属于撞枪口上了。

const ltc_math_descriptor ltm_desc = {
这个结构识别出来后,定位到 exptmod,向上查调用可得rsa_exptmod,再往上就是RSA_DEC了,通过参数搞到rsa_key,再通过rsa_key找到 rsa_import函数,得到der编码的公钥。
2016-11-8 23:19
0
雪    币: 449
活跃值: (189)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
6
收到,非常感谢!
2016-11-9 09:44
0
雪    币: 870
活跃值: (2264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
很好
2018-7-24 15:06
0
游客
登录 | 注册 方可回帖
返回
//