攻防世界—first

发布时间 2023-06-25 22:22:11作者: h40vv3n

first

将文件导入ida,查看main函数的代码

image-20230620172024634

我们直接看最后的关键字符串,发现flag就存在unk_602220数组当中,因此关键点就在于怎么得到该数组的值

image-20230620172253279

往上一步步追踪,发现了一个关键的循环,该循环将原unk_602220数组中的字符与已知数组的值和v10进行了异或操作,然后将结果存入byte_60221F数组的从1索引开始的位置并以此往后,而60221F+1刚好就等于602220,因此该循环异或操作的结果就是最终的flag

image-20230620172828182

我们先追踪v10,发现v10由用户的输入进行异或操作得来,因此关键是要找到正确的用户输入

image-20230620173049034

image-20230620173102322

继续阅读代码发现有一个创建线程的操作,总共创建了6个线程,而每个线程都执行了一个函数start_routine()而参数则是0~5image-20230620173327937

点进该函数进行分析,此时发现该函数对关键数组unk_602220进行赋值操作,因此这是一个关键函数,我们继续分析

image-20230620173536962

点进sub_400E10()函数进行分析,发现这是一个MD5编码函数,将用户输入的其中四个字节进行编码,然后存入v8

image-20230620173802346

然后用v8和已知的数组qword_602120的对应部分进行比较,若相同则将用户的输入中的这四个字节存入数组unk_602220当中,因此我们可以通过一个MD5在线解密网站获得用户输入的各个部分https://www.somd5.com/:

image-20230620213909054

image-20230620214028689

image-20230620214047708

image-20230620214115623

image-20230620214140576

image-20230620214205808

将其逐个拼接就是用户的输入,然而并不一定是最终的unk_602220数组,因为该线程函数前面有一个usleep函数,作用是挂起当前线程一段时间,然后再锁住线程对数据进行写操作,因此6个线程相互竞争,我们无法确定线程写入的顺序,也就无法确定unk_602220数组最终的取值,也就是最终的flag

image-20230620215148587

因此此时的想法是将所有的这六个部分的排列组合都列举出来并执行相应的程序流程,最后再看能否得出最终的flag,

此时的整个解题脚本的流程为:

按上图MD5解密流程拼接各个解密出来的字符串即为用户的输入→将用户的输入执行第一层变换得到v10→枚举出全部的用户的该输入的六个部分的排列组合→将每一种排列组合与v10和已知数组进行异或→将不符合条件的情况去除(ASCII码大于122)→得到所有可能的flag

完整解题脚本如下:

import itertools
input1 = 'juhuhfenlapsiuerhjifdunu'

list1 = [0xFE, 0xE9, 0xF4, 0xE2, 0xF1, 0xFA, 0xF4, 0xE4, 0xF0, 0xE7, 
  0xE4, 0xE5, 0xE3, 0xF2, 0xF5, 0xEF, 0xE8, 0xFF, 0xF6, 0xF4, 
  0xFD, 0xB4, 0xA5, 0xB2]

v10 = 0
for i in range(len(input1)):
    v11 = ord(input1[i])+i
    v10 ^= v11

# 遍历用户输入的各部分的全部排列组合
input1_part = ['juhu', 'hfen', 'laps', 'iuer', 'hjif', 'dunu']

permutations = list(itertools.permutations(input1_part, 6))

for perm in permutations:
    sample = ''.join(perm)
    flag = ''
    for i in range(len(sample)):
        flag_temp = (v10 ^ list1[i] ^ ord(sample[i]))
        if flag_temp>122:
            flag = ''
            break
        else:
            flag+=chr(flag_temp)
        if i == len(sample)-1:
            print(flag)

程序的输出结果为:

image-20230620224820149

此时发现了一个极有可能是flag的结果:

image-20230620224925493

提交后发现成功了,因此本题的flag为:

goodjobyougetthisflag233