首页
社区
课程
招聘
[原创]KCTF 2024 第七题 星际移民 (面向小白)
发表于: 2024-9-28 22:20 5330

[原创]KCTF 2024 第七题 星际移民 (面向小白)

2024-9-28 22:20
5330

第一次发文,面向萌新写文(自己妥妥就是小白)

首先查壳,无壳,ida走起

很明显能找到主函数,并且代码非常简单,提示用户输入用户名和密码后调用函数对密码进行校验后退出,很明显程序的主要功能都在17行的调用中实现,跟进去后很快就发现程序调用了sub_401000,根据题目中给的账号和密码,把程序拖进OD一顿分析,发现函数作用是将长度为0x86的密码从字符转换为长度0x45的十六进制(结尾两个0x00),转换后的数据称为Serial_2,实例代码如下:

可以看到后边紧接着用自身程序0x401120开始的0x2B9字节与Serial_2进行异或,因此现在需要提取这0x2B9字节的数据

通过查看目标程序,能够看到代码区.text的虚拟地址偏移为0x1000,大小为0xC00,加上Imagebase0x400000,得出代码区.text在程序进程中的内存地址范围为0x401000到0x401C00,自身程序0x401120开始的0x2B9字节落在了代码区段中。通过PointerToRawData和SizeOfRawData得知代码区.text在程序文件中的偏移地址为0x400到0x1000,因此从文件偏移0x400+0x120开始提取0x2B9字节。

实例代码如下:

继续往后看,这里通过调试可以看出是将Serial_3前0x42个字节进行xor,结果存在Serial_3[0x42],然后用Serial_3[0x42]与Serial_3开始的0x42个字节分别进行xor,结果存在对应位置,得到Serial_4

实例代码如下:

继续往后看,这里通过输入的用户名计算出一个数字data_1,示例代码如下:

后边的代码看着比较乱,F5瞅瞅

这里是一个简单的比较,比较Serial_4与0x4010D0开始的data_1个字节是否相同,相同则继续,不同则失败

Serial_4[data_1+0x17]与0x4010D0[data_1+0x17]开始比较0x2c-data_1个字节,相同则继续,不同则失败

首先取Serial_4[data_1]和0x401120[0]这两个字节,0x401120[0]&0xf(只保留低3位,作为左位移位数),用0x8-0x401120[0]&0xf得出右位移位数,对Serial_4[data_1]一次进行左位移和右位移,将左右位移结果进行或操作写在Serial_4[data_1],得到Serial_5

按照上述步骤合计进行0x17此操作,此时数据区已经能够明显的看到Serial_5为一串明文

最后果不其然对Serial_5进行判断,其值如果为“KCTF-2024-CRACK-SUCCESS”则判断成功,否则视为失败,至此,整个流程分析结束

不难看出密码被分为三段,分别为[0,data_1),[data_1,0x17+data_1),[0x17+data_1,0x2c+0x17),这三段分别进行不同校验,而题目给定的用户名用来计算data_1,data_1确定之后对三块区域进行拼接+逆运算即可

破解机代码:

; int __cdecl main(int argc, const char **argv, const char **envp)
_main proc near
 
argc= dword ptr  4
argv= dword ptr  8
envp= dword ptr  0Ch
 
push    offset aInputUser ; "Input User:\n"
call    dword_403FDC
push    offset byte_403800
call    dword_403FD8
push    offset aInputSerial ; "Input Serial:\n"
call    dword_403FDC
push    offset byte_403418
call    dword_403FD8
push    offset off_403FD0
call    off_403FD4 ;校验
add     esp, 14h
call    ds:getchar
xor     eax, eax
retn
_main endp
; int __cdecl main(int argc, const char **argv, const char **envp)
_main proc near
 
argc= dword ptr  4
argv= dword ptr  8
envp= dword ptr  0Ch
 
push    offset aInputUser ; "Input User:\n"
call    dword_403FDC
push    offset byte_403800
call    dword_403FD8
push    offset aInputSerial ; "Input Serial:\n"
call    dword_403FDC
push    offset byte_403418
call    dword_403FD8
push    offset off_403FD0
call    off_403FD4 ;校验
add     esp, 14h
call    ds:getchar
xor     eax, eax
retn
_main endp
import binascii
binascii.a2b_hex(hex_input)
# 逆运算
binascii.b2a_hex(b_input)
import binascii
binascii.a2b_hex(hex_input)
# 逆运算
binascii.b2a_hex(b_input)
code_401120 =binascii.a2b_hex( "83EC4CA10030400033C48944244853555657BB18344000E8C4FEFFFF8BF0B9100000008D7C2414F3A566A550A4FF15B02040008B7C24648B770483C40433C990B86B4CA407F7E1D1EA6BD2438BC12BC28A1431305404148D4404144181F9B90200007CDC8A4C2414B8010000008D49008A5404143254041583C00532540411325404133254041232CA83F8427CE28A54245632D1885424568D442414B94200000030104083E90175F88A0D0038400033C0BA0038400084C9741A8D9B000000000FB6C933C881E1FF000000428BC18A0A84C975EC8B3783E00F8D4444148D542414894424102BC285C07E688BE88BFE83F80472148B0F3B0A751283ED0483C20483C70483FD0473EC85ED74470FB60F0FB61A2BCB753183FD0176380FB64F010FB65A012BCB752083FD0276270FB64F020FB65A022BCB750F83FD0376160FB64F030FB652032BCAC1F91F83C9010F85FF000000BF2C0000002BF885FF7E718D4C042B8D54301783FF047219EB038D49008B023B01751283EF0483C10483C20483FF0473EC85FF74470FB6020FB6312BC6753183FF0176380FB642010FB671012BC6752083FF0276270FB642020FB671022BC6750F83FF0376160FB642030FB649032BC1C1F81F83C8010F85830000008B7424108B542460B905000000BFE83B4000F3A566A5A48B7204BDE83B4000BF170000000FBE168A450083E207B1082ACA8AD8D2EB8BCAD2E046450AD883EF01885DFF75DF8D5717B8F8204000B9E83B40008B313B30752B83EA0483C00483C10483FA0473EC8A103A1175178A50013A5101750F8A40023A410275076830214000EB056840214000FF15A42040008B4C245C83C4045F5E5D5B33CCE80400000083C44CC33B0D003040007502F3C3E9AC020000688C184000E8A3040000A1B8524000C70424844F4000FF35B4524000A3844F400068744F400068784F400068704F4000FF159820400083")
code_401120 =binascii.a2b_hex( "83EC4CA10030400033C48944244853555657BB18344000E8C4FEFFFF8BF0B9100000008D7C2414F3A566A550A4FF15B02040008B7C24648B770483C40433C990B86B4CA407F7E1D1EA6BD2438BC12BC28A1431305404148D4404144181F9B90200007CDC8A4C2414B8010000008D49008A5404143254041583C00532540411325404133254041232CA83F8427CE28A54245632D1885424568D442414B94200000030104083E90175F88A0D0038400033C0BA0038400084C9741A8D9B000000000FB6C933C881E1FF000000428BC18A0A84C975EC8B3783E00F8D4444148D542414894424102BC285C07E688BE88BFE83F80472148B0F3B0A751283ED0483C20483C70483FD0473EC85ED74470FB60F0FB61A2BCB753183FD0176380FB64F010FB65A012BCB752083FD0276270FB64F020FB65A022BCB750F83FD0376160FB64F030FB652032BCAC1F91F83C9010F85FF000000BF2C0000002BF885FF7E718D4C042B8D54301783FF047219EB038D49008B023B01751283EF0483C10483C20483FF0473EC85FF74470FB6020FB6312BC6753183FF0176380FB642010FB671012BC6752083FF0276270FB642020FB671022BC6750F83FF0376160FB642030FB649032BC1C1F81F83C8010F85830000008B7424108B542460B905000000BFE83B4000F3A566A5A48B7204BDE83B4000BF170000000FBE168A450083E207B1082ACA8AD8D2EB8BCAD2E046450AD883EF01885DFF75DF8D5717B8F8204000B9E83B40008B313B30752B83EA0483C00483C10483FA0473EC8A103A1175178A50013A5101750F8A40023A410275076830214000EB056840214000FF15A42040008B4C245C83C4045F5E5D5B33CCE80400000083C44CC33B0D003040007502F3C3E9AC020000688C184000E8A3040000A1B8524000C70424844F4000FF35B4524000A3844F400068744F400068784F400068704F4000FF159820400083")
def mima_xor_hex(str1,str2):
    num_str1 = len(str1)
    num_str2 = len(str2)
    num = 0
    b_str1 = bytearray(str1)
    for i in range(num_str2):
        b_str1[num] ^= str2[i]
        print("%x" %  b_str1[num])
        num+=1
        if num == num_str1:
            num = 0
    return b_str1
 
Serial_3 = mima_xor_hex(Serial_2,code_401120)
#逆运算还是该函数
 
b'abd3e283c33cd61ffc83c3abaaf786e0eef1f3f1451162e6d780aaaa8e69ab80979090f783c33cd61bfc83c3ab13fc83c33cd617fc83c34007d73cd663e383c3f003f7'
def mima_xor_hex(str1,str2):
    num_str1 = len(str1)
    num_str2 = len(str2)
    num = 0
    b_str1 = bytearray(str1)
    for i in range(num_str2):
        b_str1[num] ^= str2[i]
        print("%x" %  b_str1[num])
        num+=1
        if num == num_str1:
            num = 0
    return b_str1
 
Serial_3 = mima_xor_hex(Serial_2,code_401120)
#逆运算还是该函数
 
b'abd3e283c33cd61ffc83c3abaaf786e0eef1f3f1451162e6d780aaaa8e69ab80979090f783c33cd61bfc83c3ab13fc83c33cd617fc83c34007d73cd663e383c3f003f7'
def Serial_3to4(Serial_3):
    n = Serial_3[0]
    for i in range(0x42):
        n ^= Serial_3[i+1]
    Serial_3[0x42] = n
    for i in range(0x42):
        Serial_3[i] ^= n
    return Serial_3
#逆向
def Serial_4to3(Serial_4):
    n = Serial_4[0x42]
    for i in range(0x42):
        Serial_4[i] ^= n
    for i in range(0x42):
        n ^= Serial_3[i]
    Serial_3[0x42] = n
    return Serial_4
def Serial_3to4(Serial_3):
    n = Serial_3[0]

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

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