首页
社区
课程
招聘
[看雪CTF2016]第三题分析
发表于: 2016-11-6 23:50 5621

[看雪CTF2016]第三题分析

2016-11-6 23:50
5621
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期)

收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 870
活跃值: (2264)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写的很好
2018-7-24 15:06
0
雪    币: 188
活跃值: (621)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
3
公私钥和大数是怎么得到的呢?
2019-3-25 18:30
0
游客
登录 | 注册 方可回帖
返回
//