1. 先清理下垃圾指令, 定位到成功条件
.text:0040399E mov eax, dword_440170
.text:004039A3 movsx ecx, byte ptr [eax+1]
.text:004039A7 cmp ecx, 1
.text:004039AA jnz loc_403A45
搜索dword_440170的引用, 定位成功路径
.text:0040344A push offset std_xxx_expected
.text:0040344F lea ecx, [ebp+var_70]
.text:00403452 call str_compare
.text:00403457 test eax, eax
.text:00403459 jnz short loc_403465
.text:0040345B mov ecx, dword_440170
.text:00403461 mov byte ptr [ecx+1], 1
.text:00403120 ; DWORD __stdcall MainThread(LPVOID lpThreadParameter)
.text:00403120 MainThread proc near ; DATA XREF: _main+3FDo
2. 识别LibTomMath相关库函数, 下载的源码制作的sig依然不好使(- -), 只好对照源码肉眼识别
.rdata:0043300C aLibtommath db 'LibTomMath',0 ; DATA XREF: .rdata:stru_432F48o
.rdata:00432F48 ; struct tommath_table stru_432F48
.rdata:00432F48 stru_432F48 tommath_table <offset aLibtommath, 1Ch, offset j_mp_init, \
.rdata:00432F48 offset j_mp_init_and_copy, offset j_mp_clear, \ ; "LibTomMath"
.rdata:00432F48 offset j_mp_neg, offset j_mp_copy, offset j_mp_set_int,\
.rdata:00432F48 offset j_mp_get_int, offset j_mp_get_digit_by_index, \
.rdata:00432F48 offset j_mp_get_used, offset j_mp_cmp, \
.rdata:00432F48 offset j_mp_cmp_d, offset j_mp_count_bits, \
.rdata:00432F48 offset j_mp_cnt_lsb, offset j_mp_2expt, \
.rdata:00432F48 offset j_mp_read_radix, offset j_mp_toradix, \
.rdata:00432F48 offset j_mp_unsigned_bin_size, \
.rdata:00432F48 offset j_mp_to_unsigned_bin, \
.rdata:00432F48 offset j_mp_read_unsigned_bin, offset j_mp_add, \
.rdata:00432F48 offset j_mp_add_d, offset j_mp_sub, offset j_mp_sub_d, \
.rdata:00432F48 offset j_mp_mul, offset j_mp_mul_d, offset j_mp_sqr, \
.rdata:00432F48 offset j_mp_div, offset j_mp_div_2, offset j_mp_mod_d, \
.rdata:00432F48 offset j_mp_gcd, offset j_mp_lcm, offset j_mp_mulmod, \
.rdata:00432F48 offset j_mp_sqrmod, offset j_mp_invmod, \
.rdata:00432F48 offset j_mp_montgomery_setup, \
.rdata:00432F48 offset j_mp_montgomery_calc_normalization, \
.rdata:00432F48 offset j_mp_montgomery_reduce, offset j__free, \
.rdata:00432F48 offset j_mp_exptmod, offset j_mp_prime_is_prime, \
.rdata:00432F48 offset sub_40F1A0, offset sub_40E990, \
.rdata:00432F48 offset sub_40E420, offset sub_40FC60, \
.rdata:00432F48 offset sub_40F740, offset sub_40FDD0, \
.rdata:00432F48 offset sub_40BE50>
3. 然后就清晰多了
aes_key: sha256("Kanxue-Crackme-CTF2016")
.text:004033A6 push offset sub_401590
.text:004033AB lea eax, [ebp+var_B8]
.text:004033B1 push eax
.text:004033B2 call calc_aes_key
expected: md5("Kanxue-Crackme-CTF2016")
.text:004031C9 push offset calc_aes_key
.text:004031CE lea eax, [ebp+var_A0]
.text:004031D4 push eax
.text:004031D5 call calc_expected
每次取8位sn
.text:0040325C push 8 ; size_t
.text:0040325E mov eax, [ebp+var_BC]
.text:00403264 push eax ; int
.text:00403265 push offset std_xxx_sn ; int
.text:0040326A lea ecx, [ebp+var_88]
.text:00403270 call std_403A80
每次rsa解密得到2字节的data
.text:004032D7 lea eax, [ebp+var_28]
.text:004032DA push eax
.text:004032DB lea ecx, [ebp+var_58]
.text:004032DE push ecx
.text:004032DF call tommath_powmod
连接起来得到16字节的data
.text:00403322 lea edx, [ebp+var_28]
.text:00403325 push edx
.text:00403326 lea ecx, [ebp+a2]
.text:00403329 call std_concat
aes256_enc(data, aes_key) == expected
.text:00403434 lea eax, [ebp+var_70]
.text:00403437 push eax
.text:00403438 mov byte ptr [ebp+var_4], 5
.text:0040343C call aes_enc
.text:00403441 add esp, 34h
.text:00403444 mov [ebp+var_D0], eax
.text:0040344A push offset std_xxx_expected
.text:0040344F lea ecx, [ebp+var_70]
.text:00403452 call str_compare
.text:00403457 test eax, eax
.text:00403459 jnz short loc_403465
.text:0040345B mov ecx, dword_440170
.text:00403461 mov byte ptr [ecx+1], 1
rsa解密
rsa_n: F574FD11, rsa_e: 10001, 计算得到rsa_d: 2BBE7481
.rdata:00439FA0 byte_439FA0
c=m ^ e mod n
.text:0040C0F4 push edx
.text:0040C0F5 mov eax, [ebp+cls]
.text:0040C0F8 mov ecx, [eax+0Ch]
.text:0040C0FB push ecx
.text:0040C0FC mov edx, [ebp+cls]
.text:0040C0FF mov eax, [edx+4]
.text:0040C102 push eax
.text:0040C103 mov ecx, [ebp+a1]
.text:0040C106 push ecx
.text:0040C107 call tommath_4401A0.j_mp_exptmod
解密的数据有4字节, 从第2字节开始取, 说明前2字节为0000
.text:00401832 push 2 ; size_t
.text:00401834 lea ecx, [ebp+var_102]
.text:0040183A push ecx ; void *
.text:0040183B mov ecx, [ebp+arg_4] ; int
.text:0040183E call std_401CA0
计算sn:
aes_key=sha256("Kanxue-Crackme-CTF2016")
aes_dec(md5("Kanxue-Crackme-CTF2016"), aes_key)=0D48ED5EF769E2ABD68BFD6C76DD795D
N: F574FD11
D: 2BBE7481
E: 100001
每4位拆分, 前面补0
00000D48 0000ED5E 0000F769 0000E2AB 0000D68B 0000FD6C 000076DD 0000795D
c ^ d mod n
3C4F963B 039A2C37 7E02291E 3C157AE5 91BCC1CA 0A8F528E B2700AC0 21FB958D
sn: 3C4F963B039A2C377E02291E3C157AE591BCC1CA0A8F528EB2700AC021FB958D
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)