2018/11/26-湖湘杯-Replace

题目链接:https://pan.baidu.com/s/1PNNAo2Ive4K7eYEifVIwsQ
提取码:8b2v

用Exeinfo PE查壳发现是UPX壳

使用UPX-3.95(可以在吾爱破解Tools->Packers可以下到)的upx -d 命令脱壳

然后我们在IDA里找到关键算法部分

可以看出循环是根据每个字符生成v6和v7,然后16*v6+v7当下标,在数字byte_4021A0中就行寻值。然后和(v11+v12)^0x19进行比较,若不相等则失败,而v11和v12是根据数组byte_402150生成的。

其实对输入字符处理到最后的16*v6+v7仍然是输入字符的ascii值,而v11+v12其实就是byte_401250处存储的字符串“2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6”的每两位的写入内存的十六进制,相当于python3的bytes.fromhex()函数。

也就是说最后的比较就是data[input[i]] == arr[i]^0x19

我们把byte_4021A0处的数据dump下来,然后写脚本运行即可得到flag。

data = open('E:\\data','rb').read()
arr = bytes.fromhex("2a49f69c38395cde96d6de96d6f4e025484954d6195448def6e2dad67786e21d5adae6")
for i in range(len(arr)):
    print(chr(data.index(arr[i]^0x19)),end="")

如果看不出来对字符的处理是怎么回事的话,也可以进行爆破。

def fun(i):
    if(data1[i] < 48 | data1[i] > 57):
        a = data1[i] - 87
    else:
        a = data1[i] - 48
    a = a * 16
    if(data1[i+1] < 48 | data1[i+1] > 57):
        b = data1[i+1] - 87
    else:
        b = data1[i+1] - 48
    return ((a + b) ^ 0x19)

for i in range(35):
    z = i
    for m in range(128):
        a = (m >> 4) % 16
        b = (16 * m >> 4) % 16
        j = 16 * a + b
        k = fun(i*2)
        if(data[j] == k):
            print(chr(m),end="")

猜你喜欢

转载自www.cnblogs.com/Fingerprint/p/10022813.html