首页
社区
课程
招聘
[原创]看雪 KCTF 2024 第七题 星际移民 Writeup
发表于: 2024-8-30 11:27 1108

[原创]看雪 KCTF 2024 第七题 星际移民 Writeup

2024-8-30 11:27
1108

此题还是比较简单的,无花无壳,放IDA中F5,代码也比较清晰,只是在检查验证码时用到了主要的两个函数体代码来计算,这时要是在代码中加入软件断点,那计算结果就会不正确.因此调试时要用硬件断点.验证过程用PYTHON代码表示,大致可以描述为:

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
47
48
49
50
51
52
LENSN = 67
#KEY1 主要为验证函数check的函数体代码
KEY1 = bytes.fromhex('83EC4CA10030400033C48944244853555657BB18344000E8C4FEFFFF8BF0B9100000008D7C2414F3A566A550A4FF15B02040008B7C24648B770483C40433C990B86B4CA407F7E1D1EA6BD2438BC12BC28A1431305404148D4404144181F9B90200007CDC8A4C2414B8010000008D49008A5404143254041583C00532540411325404133254041232CA83F8427CE28A54245632D1885424568D442414B94200000030104083E90175F88A0D0038400033C0BA0038400084C9741A8D9B000000000FB6C933C881E1FF000000428BC18A0A84C975EC8B3783E00F8D4444148D542414894424102BC285C07E688BE88BFE83F80472148B0F3B0A751283ED0483C20483C70483FD0473EC85ED74470FB60F0FB61A2BCB753183FD0176380FB64F010FB65A012BCB752083FD0276270FB64F020FB65A022BCB750F83FD0376160FB64F030FB652032BCAC1F91F83C9010F85FF000000BF2C0000002BF885FF7E718D4C042B8D54301783FF047219EB038D49008B023B01751283EF0483C10483C20483FF0473EC85FF74470FB6020FB6312BC6753183FF0176380FB642010FB671012BC6752083FF0276270FB642020FB671022BC6750F83FF0376160FB642030FB649032BC1C1F81F83C8010F85830000008B7424108B542460B905000000BFE83B4000F3A566A5A48B7204BDE83B4000BF170000000FBE168A450083E207B1082ACA8AD8D2EB8BCAD2E046450AD883EF01885DFF75DF8D5717B8F8204000B9E83B40008B313B30752B83EA0483C00483C10483FA0473EC8A103A1175178A50013A5101750F8A40023A410275076830214000EB056840214000FF15A42040008B4C245C83C4045F5E5D5B33CCE80400000083C44CC33B0D003040007502F3C3E9AC020000688C184000E8A3040000A1B8524000C70424844F4000FF35B4524000A3844F400068744F400068784F400068704F4000FF159820400083')
 
#part1_ok 验证数据主要为 main 函数的函数体代码
part1_ok = bytes.fromhex('6810214000FF15DC3F40006800384000FF15D83F40006820214000FF15DC3F40006818344000FF15D83F400068D03F4000FF15D43F400083C414FF15A020400033C0C3CCCCCCCCCCCCCCCCCCCCCCCCCC83EC4CA1003040')
part2_ok = b'KCTF-2024-CRACK-SUCCESS'
 
mask8 = 0xff
 
def rol8(d, n):
    d &= mask8
    n &= 7
    return ((d << n) | (d>>(8-n))) & mask8
 
def ror8(d, n):
    d &= mask8
    n &= 7
    return ((d >> n) | (d<<(8-n))) & mask8
 
def check(name, sn):
    sn = bytearray(sn)
    for i in range(len(KEY1)):
        sn[i % LENSN] ^= KEY1[i]
    checksum = 0
    for i in range(LENSN):
        checksum ^= sn[i]
    for i in range(LENSN-1):
        sn[i] ^= checksum
    sn[LENSN-1]=checksum
    checksumname = 0
    for i in name:
        checksumname ^= i
    lenpart1 = ((checksumname & 0xf) << 1)
    part1 = sn[:lenpart1]
    ok1 = part1 == part1_ok[:lenpart1]
    part2 = bytearray()
    for i in range(0x17):
        part2.append(rol8(sn[lenpart1+i], KEY1[i]))
    ok2 = part2 == part2_ok
    lenpart3 = 0x2c-lenpart1
    part3 = sn[-(lenpart3):]
    ok3 = part3 == part1_ok[lenpart1+0x17:lenpart1+0x17+lenpart3]
    if ok1 and ok2 and ok3:
        print("***success***.”)
    else:
        print("fail.")
 
name = input('Input User:').encode('utf-8')
sn = bytes.fromhex(input('Input Serial:'))
sn = sn[:LENSN]
check(name, sn)

分析以上代码,很容易写出key_gen函数:

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
def key_gen(name):
    checksumname = 0
    for i in name:
        checksumname ^= i
    lenpart1 = ((checksumname & 0xf) << 1)
    part1 = part1_ok[:lenpart1]
    part2 = bytearray()
    for i in range(0x17):
        part2.append(ror8(part2_ok[i], KEY1[i]))
    lenpart3 = 0x2c - lenpart1
    part3 = part1_ok[lenpart1+0x17:lenpart1+0x17+lenpart3]
    sn = bytearray(part1 + part2+ part3)
    checksum = sn[LENSN-1]
    for i in range(LENSN-1):
        sn[i] ^= checksum
 
    checksum = 0
    for i in range(LENSN-1):
        checksum ^= sn[i]
    sn[LENSN-1] ^= checksum
 
    for i in range(len(KEY1)):
        sn[i % LENSN] ^= KEY1[i]
    return sn
 
name = b'KCTF'
sn = key_gen(name)
print(‘name:%s\nsn:%s’ % (name, sn))

最后得到SN:

1
6810214000ff15dc3f40006800384000ff15d83f693445232d32303286d2a125144369694daa68435453530068d03f4000ff15d43f400083c414ff15a020400033c0c3

此题由于计算时只复制了输入的SN的前67字节(16进制串转字节后),验证时也是按67字节计算的,所以在正确的验证码后加入多于的16进制串(2的倍数)都能通过验证,所以此题多解.


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//