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

查壳

查壳为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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值