锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

2022KCTF春季赛看雪为什么读书

时间:2023-10-09 04:37:02 kc120e3e精密电阻

查壳

32壳无壳可执行exe程序,ida32查看,F5反汇编查看伪代码。

第一关

看大段大段的文字介绍,推测这个题目是闯关题,需要一关一关才能突破。下图开始第一关,如下图所示:

继续往下分析,可以清晰的看到v17的值不等于input前三位的异或,就gameover错误,所以需要不同或结果等于v17分析图如下图所示:

而要让input前三位异或结果等于v17.根据前面的情况v72进行推测,因此将之前的伪代码与此处的代码合成,验证代码如下:

for i in range(100,1000):     input = list(str(i))     v4 = len(input)     v71 = v4     v6 = v4     v72 = 0     v5 = 0     if v4:         v7 = input         i = 0         while v6:             v5 ^= int(v7[i])             v6 -= 1             i  = 1             v8 = 8             while v8:                 v9 = 2 * v5                 v10 = v9 ^ 7                 if v9 >= 0:                     v10 = v9                 v5 = v10                 v8 -= 1         v4 = v71         v72 = v10     v13 = v72     v68 = v72   1     v14 = v68     v66 = [0] * 200     while v13 < v14:         v15 = v13         for j in range(1, 200):             if (v15 & 1) != 0:
                v15 = 3 * v15 + 1
            else:
                v15 >>= 1
            v66[j] = v15
        v13 += 1
    v17 = v66[198] | v66[197] | v66[196]
    if v17 == (int(input[2]) ^ int(input[1]) ^ int(input[0])):
        print(input)

跑完发现输出很多的满足要求的结果,任意输入一个满足要求的前三位结果,后面再加几个数字997123,发现第一关通过,如下图所示:

第二关

第一关成功通过,来到第二关,继续往下分析,可以看到如下图所示出了第四位的代码:

分析到input应该是被操作过了,不然这个ascii为20的,也没法输入呀,上去看看那个函数干了啥:

发现这个函数传入了input和v4,而v4经过测试后的结果为3,此时跟进函数看看干了啥:

分析如上图所示,突然想到闯第一关的时候,input的值是被操作过的,而第一关刚好是三个数字,故不影响第一关的三个字符,第一关的推测没变,还好还好,不然得多加行函数验证了。

分析到第二关的第四个字符要等于20,而函数里的变化,v4-v5要能等于20的也就只能是减去55了,故将20+55得到字符K。往后分析发现第五位和第六位的值要分别等于12和29,同理可得到两个字符C、T,再往后看,如图所示:

此时陷入了僵局,因为往回分析没能分析出v74[0]是个啥,于是去看看汇编代码,如下图所示:

发现如上图的v74的汇编代码为[ebp+var_2A],而第六位的为[ebp+var_2B],由于是小端存储,两者的存储位置相差1,推测v74为第七位,故15+55得到字符F。刚好第四位到第七位为KCTF,为此次比赛组办方的名。输入997KCTF成功过第二大关。

第三关

攻破第二关挺开心的,发现剧情还未结束,往下还有第三关,继续分析:

这个v74不知道是啥,同样看一下汇编代码,如下图所示:

猜测为第七位以后的数据,而循环v21小于v9,v9又为9,推测最后面应该是9为数据,这里的循环意思为前n位取余n要等于0才正常输出,故写代码测试:

import itertools
for i in itertools.permutations('123456789',9):
    v=''.join(i)
    flag=True
    for j in range(1,10):
        if int(v[:j])%j!=0:
            flag=False
            break
    if flag:
        print(v)
        break

满足条件的只有381654729。

然而输入前三关的结果,游戏并未结束,继续往下分析:

最后一关

往回分析,代码如下:

由此分析得到,要让最终结果v11等于-181532827,也就是说把前面第一关爆破的所有结果拼接第二关和第三关的结果形成的flag,处理后的v11等于-181532827的话,就是正确的flag,此时还有一个问题,dword_405B20数组查看不到,此时动调下断点读取如下:

读取内存时,应将其转换为32位的将数据,取出来如下:

d=[0x00000000,0x09073096,0x120E612C,0x1B0951BA
,0xFF6DC419,0xF66AF48F,0xED63A535,0xE46495A3
,0xFEDB8832,0xF7DCB8A4,0xECD5E91E,0xE5D2D988
,0x01B64C2B,0x08B17CBD,0x13B82D07,0x1ABF1D91
,0xFDB71064,0xF4B020F2,0xEFB97148,0xE6BE41DE
,0x02DAD47D,0x0BDDE4EB,0x10D4B551,0x19D385C7
,0x036C9856,0x0A6BA8C0,0x1162F97A,0x1865C9EC
,0xFC015C4F,0xF5066CD9,0xEE0F3D63,0xE7080DF5
,0xFB6E20C8,0xF269105E,0xE96041E4,0xE0677172
,0x0403E4D1,0x0D04D447,0x160D85FD,0x1F0AB56B
,0x05B5A8FA,0x0CB2986C,0x17BBC9D6,0x1EBCF940
,0xFAD86CE3,0xF3DF5C75,0xE8D60DCF,0xE1D13D59
,0x06D930AC,0x0FDE003A,0x14D75180,0x1DD06116
,0xF9B4F4B5,0xF0B3C423,0xEBBA9599,0xE2BDA50F
,0xF802B89E,0xF1058808,0xEA0CD9B2,0xE30BE924
,0x076F7C87,0x0E684C11,0x15611DAB,0x1C662D3D
,0xF6DC4190,0xFFDB7106,0xE4D220BC,0xEDD5102A
,0x09B18589,0x00B6B51F,0x1BBFE4A5,0x12B8D433
,0x0807C9A2,0x0100F934,0x1A09A88E,0x130E9818
,0xF76A0DBB,0xFE6D3D2D,0xE5646C97,0xEC635C01
,0x0B6B51F4,0x026C6162,0x196530D8,0x1062004E
,0xF40695ED,0xFD01A57B,0xE608F4C1,0xEF0FC457
,0xF5B0D9C6,0xFCB7E950,0xE7BEB8EA,0xEEB9887C
,0x0ADD1DDF,0x03DA2D49,0x18D37CF3,0x11D44C65
,0x0DB26158,0x04B551CE,0x1FBC0074,0x16BB30E2
,0xF2DFA541,0xFBD895D7,0xE0D1C46D,0xE9D6F4FB
,0xF369E96A,0xFA6ED9FC,0xE1678846,0xE860B8D0
,0x0C042D73,0x05031DE5,0x1E0A4C5F,0x170D7CC9
,0xF005713C,0xF90241AA,0xE20B1010,0xEB0C2086
,0x0F68B525,0x066F85B3,0x1D66D409,0x1461E49F
,0x0EDEF90E,0x07D9C998,0x1CD09822,0x15D7A8B4
,0xF1B33D17,0xF8B40D81,0xE3BD5C3B,0xEABA6CAD
,0xEDB88320,0xE4BFB3B6,0xFFB6E20C,0xF6B1D29A
,0x12D54739,0x1BD277AF,0x00DB2615,0x09DC1683
,0x13630B12,0x1A643B84,0x016D6A3E,0x086A5AA8
,0xEC0ECF0B,0xE509FF9D,0xFE00AE27,0xF7079EB1
,0x100F9344,0x1908A3D2,0x0201F268,0x0B06C2FE
,0xEF62575D,0xE66567CB,0xFD6C3671,0xF46B06E7
,0xEED41B76,0xE7D32BE0,0xFCDA7A5A,0xF5DD4ACC
,0x11B9DF6F,0x18BEEFF9,0x03B7BE43,0x0AB08ED5
,0x16D6A3E8,0x1FD1937E,0x04D8C2C4,0x0DDFF252
,0xE9BB67F1,0xE0BC5767,0xFBB506DD,0xF2B2364B
,0xE80D2BDA,0xE10A1B4C,0xFA034AF6,0xF3047A60
,0x1760EFC3,0x1E67DF55,0x056E8EEF,0x0C69BE79
,0xEB61B38C,0xE266831A,0xF96FD2A0,0xF068E236
,0x140C7795,0x1D0B4703,0x060216B9,0x0F05262F
,0x15BA3BBE,0x1CBD0B28,0x07B45A92,0x0EB36A04
,0xEAD7FFA7,0xE3D0CF31,0xF8D99E8B,0xF1DEAE1D
,0x1B64C2B0,0x1263F226,0x096AA39C,0x006D930A
,0xE40906A9,0xED0E363F,0xF6076785,0xFF005713
,0xE5BF4A82,0xECB87A14,0xF7B12BAE,0xFEB61B38
,0x1AD28E9B,0x13D5BE0D,0x08DCEFB7,0x01DBDF21
,0xE6D3D2D4,0xEFD4E242,0xF4DDB3F8,0xFDDA836E
,0x19BE16CD,0x10B9265B,0x0BB077E1,0x02B74777
,0x18085AE6,0x110F6A70,0x0A063BCA,0x03010B5C
,0xE7659EFF,0xEE62AE69,0xF56BFFD3,0xFC6CCF45
,0xE00AE278,0xE90DD2EE,0xF2048354,0xFB03B3C2
,0x1F672661,0x166016F7,0x0D69474D,0x046E77DB
,0x1ED16A4A,0x17D65ADC,0x0CDF0B66,0x05D83BF0
,0xE1BCAE53,0xE8BB9EC5,0xF3B2CF7F,0xFAB5FFE9
,0x1DBDF21C,0x14BAC28A,0x0FB39330,0x06B4A3A6
,0xE2D03605,0xEBD70693,0xF0DE5729,0xF9D967BF
,0xE3667A2E,0xEA614AB8,0xF1681B02,0xF86F2B94
,0x1C0BBE37,0x150C8EA1,0x0E05DF1B,0x0702EF8D]

取出数据后,写脚本进行爆破,如下:

v = 0xF52E0765

for j in a:
    v11 = 0xffffffff
    src=j+'KCTF381654729'
    print(src)
    for i in range(len(src)):
        c = (v11 ^ ord(src[i])) & 0xff
        if v11 & 0x80000000:
            temp = (v11 >> 8) + 0xff000000
        else:
            temp = v11 >> 8
        v11 = d[c] ^ temp
    print(v11)
    if (~v11&0xffffffff) == v:
        print(src)
        break

最终爆破得到421KCTF381654729,即可得到flag

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章