Loading

VNCTF RE复现 (BabyMaze 时空飞行)

babymaze

pyc混淆!

还没反编译出来 只能找个脚本偷字节码

import marshal, dis

f = open('babymaze.pyc', 'rb')
f.read(4)
f.read(4)
f.read(4)
f.read(4)
b = marshal.load(f)
print(b.co_consts)
print(b.co_names)
dis.dis(b.co_code)

从LOAD_CONST拿到地图 从BUILD_LIST 31 知道宽度是31

0000000000000000000000000000000
0102222222222222222202222222220
0202000000000200000202000000020
0202220222222202220222020222020
0200000200000000020000020202020
0222022202222222222222022202220
0002020002000000000000020000000
0222020222022222222202220222020
0200020200020000000202000202020
0222220202220222020202220202220
0000000202000202020200020200020
0222222202222202220202220202220
0200000000000000020202000202000
0222222202222222020222022202220
0200000202020200020000020000000
0202220202020202220222222222220
0202020202020002000200000200020
0202020202022202220202220202220
0202000202000200020202020002000
0222022202022222020202022202220
0200020202020000020202000202020
0202220202022222220202020202020
0202000202000000000002020202020
0202220202022222222202020202020
0200020202000002020202020202020
0222020202222202020222022202020
0000020000000200020000000200020
0222220222220222022222220222220
0200000200020002000000020000020
0222222222022222222222220222230
0000000000000000000000000000000


image-20220213142900761

走一下!

ssssddssaassddddwwwwddwwddddddwwddddddssddwwddddddddssssaawwaassaassaassddssaassaawwwwwwaaaaaaaassaassddddwwddssddssssaassddssssaaaaaawwddwwaawwwwaassssssssssssddddssddssddddddddwwaaaaaawwwwddssddwwwwwwwwddssddssssssssddddss

md5即为flag

复现写的脚本

flag = ""  # 存放flag 或者说走过路径
usedmap = [[0] * 31 for _ in range(31)]  # 初始化一个31*31的0数组 用来表示这个地方走过没 0是没走过 1是走过
map = [['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0',
        '0', '0', '0', '0', '0', '0', '0', '0'],
       ['0', '1', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2',
        '2',
        '2', '2', '2', '2', '2', '2', '2', '0'],
       ['0', '2', '0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '0', '0', '0', '2', '0', '2',
        '0',
        '0', '0', '0', '0', '0', '0', '2', '0'],
       ['0', '2', '0', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '2', '0', '2', '2', '2',
        '0',
        '2', '0', '2', '2', '2', '0', '2', '0'],
       ['0', '2', '0', '0', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '0', '0',
        '0',
        '2', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '2', '2', '0', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
        '0',
        '2', '2', '2', '0', '2', '2', '2', '0'],
       ['0', '0', '0', '2', '0', '2', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0',
        '2', '0', '0', '0', '0', '0', '0', '0'],
       ['0', '2', '2', '2', '0', '2', '0', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2',
        '2',
        '2', '0', '2', '2', '2', '0', '2', '0'],
       ['0', '2', '0', '0', '0', '2', '0', '2', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0', '0', '2', '0', '2',
        '0',
        '0', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '2', '2', '2', '2', '0', '2', '0', '2', '2', '2', '0', '2', '2', '2', '0', '2', '0', '2', '0', '2',
        '2',
        '2', '0', '2', '0', '2', '2', '2', '0'],
       ['0', '0', '0', '0', '0', '0', '0', '2', '0', '2', '0', '0', '0', '2', '0', '2', '0', '2', '0', '2', '0', '0',
        '0',
        '2', '0', '2', '0', '0', '0', '2', '0'],
       ['0', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '0', '2', '2', '2', '0', '2', '0', '2',
        '2',
        '2', '0', '2', '0', '2', '2', '2', '0'],
       ['0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2', '0', '2', '0', '2',
        '0',
        '0', '0', '2', '0', '2', '0', '0', '0'],
       ['0', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '0', '2', '0', '2', '2', '2',
        '0',
        '2', '2', '2', '0', '2', '2', '2', '0'],
       ['0', '2', '0', '0', '0', '0', '0', '2', '0', '2', '0', '2', '0', '2', '0', '0', '0', '2', '0', '0', '0', '0',
        '0',
        '2', '0', '0', '0', '0', '0', '0', '0'],
       ['0', '2', '0', '2', '2', '2', '0', '2', '0', '2', '0', '2', '0', '2', '0', '2', '2', '2', '0', '2', '2', '2',
        '2',
        '2', '2', '2', '2', '2', '2', '2', '0'],
       ['0', '2', '0', '2', '0', '2', '0', '2', '0', '2', '0', '2', '0', '0', '0', '2', '0', '0', '0', '2', '0', '0',
        '0',
        '0', '0', '2', '0', '0', '0', '2', '0'],
       ['0', '2', '0', '2', '0', '2', '0', '2', '0', '2', '0', '2', '2', '2', '0', '2', '2', '2', '0', '2', '0', '2',
        '2',
        '2', '0', '2', '0', '2', '2', '2', '0'],
       ['0', '2', '0', '2', '0', '0', '0', '2', '0', '2', '0', '0', '0', '2', '0', '0', '0', '2', '0', '2', '0', '2',
        '0',
        '2', '0', '0', '0', '2', '0', '0', '0'],
       ['0', '2', '2', '2', '0', '2', '2', '2', '0', '2', '0', '2', '2', '2', '2', '2', '0', '2', '0', '2', '0', '2',
        '0',
        '2', '2', '2', '0', '2', '2', '2', '0'],
       ['0', '2', '0', '0', '0', '2', '0', '2', '0', '2', '0', '2', '0', '0', '0', '0', '0', '2', '0', '2', '0', '2',
        '0',
        '0', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '0', '2', '2', '2', '0', '2', '0', '2', '0', '2', '2', '2', '2', '2', '2', '2', '0', '2', '0', '2',
        '0',
        '2', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '0', '2', '0', '0', '0', '2', '0', '2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '2',
        '0',
        '2', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '0', '2', '2', '2', '0', '2', '0', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2',
        '0',
        '2', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '0', '0', '0', '2', '0', '2', '0', '2', '0', '0', '0', '0', '0', '2', '0', '2', '0', '2', '0', '2',
        '0',
        '2', '0', '2', '0', '2', '0', '2', '0'],
       ['0', '2', '2', '2', '0', '2', '0', '2', '0', '2', '2', '2', '2', '2', '0', '2', '0', '2', '0', '2', '2', '2',
        '0',
        '2', '2', '2', '0', '2', '0', '2', '0'],
       ['0', '0', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0', '0', '2', '0', '0', '0', '2', '0', '0', '0', '0',
        '0',
        '0', '0', '2', '0', '0', '0', '2', '0'],
       ['0', '2', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '0', '2', '2', '2', '0', '2', '2', '2', '2', '2',
        '2',
        '2', '0', '2', '2', '2', '2', '2', '0'],
       ['0', '2', '0', '0', '0', '0', '0', '2', '0', '0', '0', '2', '0', '0', '0', '2', '0', '0', '0', '0', '0', '0',
        '0',
        '2', '0', '0', '0', '0', '0', '2', '0'],
       ['0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '0', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
        '2',
        '2', '0', '2', '2', '2', '2', '3', '0'],
       ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0',
        '0', '0', '0', '0', '0', '0', '0', '0']]


def DFS(x, y):
    global flag  # global!
    n = [[1, 0], [0, 1], [-1, 0], [0, -1]]  # 表示位移的四个方向
    ft = ["s", "d", "w", "a"]  # 和上一行对应
    if x == len(map) - 2 and y == len(map) - 2:  # 31x31的迷宫 终点也就是数组的(29,29)
        print(flag)
        return
    for i in range(4):  # 只有四个方向
        if map[x + n[i][0]][y + n[i][1]] == '0' or usedmap[x + n[i][0]][
            y + n[i][1]] == 1:  # 如果下一步是墙 或者下一步走过 说明这个方向不能走 就continie
            continue
        usedmap[x + n[i][0]][y + n[i][1]] = 1  # 把下一步标记为走过
        flag += ft[i]  # 然后flag拼上下一步
        DFS(x + n[i][0], y + n[i][1])  # 以下一步为起点继续深搜 如果下一步的四个方向都执行完了也没套娃进下一个DFS 说明是死路
        flag = flag[:-1]  # 就会执行这一行 说明这一步不对 删掉
        usedmap[x + n[i][0]][y + n[i][1]] = 0  # 表示下一步没走过


if __name__ == '__main__':
    DFS(1, 1)


时空飞行

第一层 输入日期

image-20220213143034812

image-20220213143047167

总之是个逐位异或的感觉

__int64 __fastcall sub_401A3B(int a1)
{
  return a1 ^ (__ROL4__(a1, 0xD) ^ __ROR4__(a1, 9));
}

上脚本解决

#include <iostream>
#include <string>
using namespace std;

uint32_t key[] = { 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, 0xE0E7EEF5,
   0xFC030A11, 0x181F262D, 0x343B4249, 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9, 0xC0C7CED5, 0xDCE3EAF1,
   0xF8FF060D, 0x141B2229, 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299, 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED,
   0xF4FB0209, 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279 };
uint32_t sub_401A3B(int a1) {
	int a2;
	__asm {
		mov  eax, a1;
		rol  eax, 0xd;
		mov  ebx, a1;
		ror  ebx, 9;
		xor eax, ebx;
		xor eax, a1;
		mov a2, eax;
	}
	return a2;
}
uint32_t decry1() {
	int tem[36] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		   0, 0, 0, 0,0,0,0,0, 0x0FD07C452, 0x0EC90A488, 0x68D33CD1, 0x96F64587 };
	for (int i = 35; i >= 4; i--) {
		tem[i - 4] = (tem[i] ^ sub_401A3B(
			tem[i - 3] ^ tem[i - 2] ^ tem[i - 1] ^ key[i - 4]));
	}
	printf("%x", (tem[0] ^ 0xA3B1BAC6));
	printf("%x", (tem[1] ^ 0x56AA3350));
	printf("%x", (tem[2] ^ 0x677D9197));
	printf("%x", (tem[3] ^ 0xB27022DC));
	return 0;
}
uint32_t encrt1() {
	uint32_t tem[36] = { 0 };
	tem[0] = 0x31323334 ^ 0xA3B1BAC6;
	tem[1] = 0x31323334 ^ 0x56AA3350;
	tem[2] = 0x31323334 ^ 0x677D9197;
	tem[3] = 0x31323334 ^ 0xB27022DC;
	int i, v3, v4;
	for (i = 0; i <= 31; ++i)
	{
		v3 = i + 4;
		v4 = tem[i];
		tem[v3] = sub_401A3B(tem[i + 3] ^ tem[i + 2] ^ (unsigned int)tem[i + 1] ^ key[i]) ^ v4;
	}
	return 0;
}

int main()
{
	decry1();
	//encrt1();
	return 0;
}

解出来第一层是20211205

第二层 符来歌(flag)

image-20220213143513590

第二次输入的v5经过一系列加密与dword_404080比较

其中dword_404080在sub_401CAA被异或处理过 但是不想写脚本

直接动调拿到dword_404080的值

伪!逆44,45行(Z3! 只能解出多解的一部分解!)

是个异或 还有取余的算法

#enc2 就是dword_404080
enc2 = [0x00000025, 0x00000015, 0x000000DF, 0x000000A2, 0x000000C0, 0x00000093, 0x000000AD, 0x00000014, 0x00000046,
        0x000000C5, 0x0000000F, 0x0000002E, 0x0000009A, 0x000000EB, 0x00000030, 0x000000F8, 0x00000020, 0x000000E9,
        0x000000CB, 0x00000088, 0x000000C6, 0x000000BE, 0x0000008D, 0x000000E3, ]
print(len(enc2))
from z3 import *
enc = [0] * 24
solver = Solver()
for i in range(24):
    enc[i] = BitVec(f"enc[{i}]", 8)
#enc就是enc2
solver.add(enc[0] == 37)
solver.add(enc[1] == 21)
solver.add(enc[2] == 223)
solver.add(enc[3] == 162)
solver.add(enc[4] == 192)
solver.add(enc[5] == 147)
solver.add(enc[6] == 173)
solver.add(enc[7] == 20)
solver.add(enc[8] == 70)
solver.add(enc[9] == 197)
solver.add(enc[10] == 15)
solver.add(enc[11] == 46)
solver.add(enc[12] == 154)
solver.add(enc[13] == 235)
solver.add(enc[14] == 48)
solver.add(enc[15] == 248)
solver.add(enc[16] == 32)
solver.add(enc[17] == 233)
solver.add(enc[18] == 203)
solver.add(enc[19] == 136)
solver.add(enc[20] == 198)
solver.add(enc[21] == 190)
solver.add(enc[22] == 141)
solver.add(enc[23] == 227)

v4 = [BitVec(f"v4[{i}]", 8) for i in range(24)]
solver.add(v4[0] != 0)
for i in range(23, 0, -1):
    solver.add(enc[i - 1] == ((v4[i - 1]) % 18 + v4[i] + 5) ^ 0x41 ^ v4[i - 1])
while (solver.check() == sat):
    d = solver.model()
    # print(d)
    r = []
    for i in range(24):
        r.append(d[v4[i]])
    print(r)
    solver.add(v4[15] != d[v4[15]])

所以v4的一部分解是

[94, 49, 83, 189, 84, 196, 5, 223, 130, 128, 239, 155, 232, 34, 115, 246, 66, 18, 181, 43, 214, 64, 176, 109]
[72, 39, 107, 223, 52, 160, 97, 129, 190, 174, 29, 67, 26, 180, 11, 106, 190, 212, 109, 225, 30, 136, 108, 155]
[76, 31, 57, 159, 108, 232, 41, 187, 230, 210, 73, 1, 104, 160, 249, 120, 176, 194, 91, 203, 252, 104, 132, 65]
[254, 133, 201, 65, 146, 254, 23, 241, 156, 142, 249, 167, 194, 10, 145, 204, 110, 8, 147, 3, 194, 54, 196, 247]
[184, 215, 113, 229, 248, 106, 163, 59, 100, 84, 191, 229, 124, 146, 35, 60, 122, 8, 147, 3, 194, 54, 196, 247]
[148, 235, 171, 43, 188, 52, 209, 49, 82, 70, 173, 215, 166, 120, 193, 162, 8, 92, 237, 81, 138, 0, 250, 37]
[154, 243, 157, 245, 10, 124, 153, 107, 40, 38, 155, 201, 144, 56, 139, 236, 64, 18, 181, 43, 214, 64, 176, 109]

逆37-42行

image-20220213144230460

将4个v4合成一个就好了

tttt = [[94, 49, 83, 189, 84, 196, 5, 223, 130, 128, 239, 155, 232, 34, 115, 246, 66, 18, 181, 43, 214, 64, 176, 109]
    , [72, 39, 107, 223, 52, 160, 97, 129, 190, 174, 29, 67, 26, 180, 11, 106, 190, 212, 109, 225, 30, 136, 108, 155]
    , [76, 31, 57, 159, 108, 232, 41, 187, 230, 210, 73, 1, 104, 160, 249, 120, 176, 194, 91, 203, 252, 104, 132, 65]
    , [254, 133, 201, 65, 146, 254, 23, 241, 156, 142, 249, 167, 194, 10, 145, 204, 110, 8, 147, 3, 194, 54, 196, 247]
    , [184, 215, 113, 229, 248, 106, 163, 59, 100, 84, 191, 229, 124, 146, 35, 60, 122, 8, 147, 3, 194, 54, 196, 247]
    , [148, 235, 171, 43, 188, 52, 209, 49, 82, 70, 173, 215, 166, 120, 193, 162, 8, 92, 237, 81, 138, 0, 250, 37]
    , [154, 243, 157, 245, 10, 124, 153, 107, 40, 38, 155, 201, 144, 56, 139, 236, 64, 18, 181, 43, 214, 64, 176, 109]]
for r in range(7):
    v4 = tttt[r]
    dword_408AC0 = []
    for i in range(0, 6):
        dword_408AC0.append("0x" +
                            hex(v4[4 * i + 3])[2:].zfill(2) + hex(v4[4 * i + 2])[2:].zfill(2) + hex(v4[4 * i + 1])[
                                                                                                2:].zfill(2) + hex(
            v4[4 * i])[2:].zfill(
            2))
    print(dword_408AC0)

一部分解

['0xbd53315e', '0xdf05c454', '0x9bef8082', '0xf67322e8', '0x2bb51242', '0x6db040d6']
['0xdf6b2748', '0x8161a034', '0x431daebe', '0x6a0bb41a', '0xe16dd4be', '0x9b6c881e']
['0x9f391f4c', '0xbb29e86c', '0x0149d2e6', '0x78f9a068', '0xcb5bc2b0', '0x418468fc']
['0x41c985fe', '0xf117fe92', '0xa7f98e9c', '0xcc910ac2', '0x0393086e', '0xf7c436c2']
['0xe571d7b8', '0x3ba36af8', '0xe5bf5464', '0x3c23927c', '0x0393087a', '0xf7c436c2']
['0x2babeb94', '0x31d134bc', '0xd7ad4652', '0xa2c178a6', '0x51ed5c08', '0x25fa008a']
['0xf59df39a', '0x6b997c0a', '0xc99b2628', '0xec8b3890', '0x2bb51240', '0x6db040d6']

逆 36行sub_402058 函数

大体分析

input 进去出来就是dword_408AC0

image-20220213145303427

8 9 行没啥 我们输入123412341234123412341234

会变成image-20220213150433331

重点分析这段while

image-20220213150454994

大概逻辑是这样的

 while (v5 <= 65) {
        if (v5 % 6!=0) {
            a1[v5] = a1[v5-6] ^ a1[v5-1];
        } else {
            v2 = a1[v5-6];
            a1[v5] = v2 ^ sub_401FFB(a1[v5-1], v3++);
        }
        ++v5;
    }

sub_401FFB函数

image-20220213150747800

动调直接看结果 进来一个0x31323334 出去一个 0x32333431 ^ dword_4050C0[a2] 就 没了

简单说就是 ROL 8后再异或

下面分析都可以不看()

瞎分析sub_401EFB(把传入值按八位拆成四份)

image-20220213150802778

第一个函数sub_401EFB 将一个int32拆成4个八位丢到t3里面了 也没参数接收返回值 所以这个result没啥用

瞎分析sub_401F67函数(将最高位丢到后面 开始是0x31323334进来 出去是0x32 0x33 0x34 0x31)

第二个函数sub_401F67对t3进行处理

image-20220213151636606

9 10行就把那一堆又赋值回去了....原来的处理的这个值是31323334h

现在ccc3的内容是image-20220213151545382

image-20220213152007794

瞎分析sub_401EA7

直接看结果

v4又把前面的合并了()

脚本

#include <iostream>
#include <string>
using namespace std;
uint32_t dwo[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000,
   0x36000000 };
uint32_t T(uint32_t t1, int t2) {
	__asm {
		mov eax, t1;
		ROl eax, 8;
		mov t1, eax;
	}
	return t1 ^ dwo[t2];
};
int main()
{
	uint32_t a1[66] = { 0 };
	a1[60] = 4120769432;
	a1[61] = 1805220874;
	a1[62] = 3382388264;
	a1[63] = 3968546960;
	a1[64] = 733286976;
	a1[65] = 1840267478;

	for (int i = 59, j = 9; i >= 0; i--) {
		if (i % 6) {
			a1[i] = a1[i + 6] ^ a1[i + 5];
		}
		else {
			a1[i] = a1[i + 6] ^ T(a1[i + 5], j);
			j--;
		}
	}
	unsigned char* p = (unsigned char*)a1;
	for (int i = 0; i < 24; i += 4)
		printf("%c%c%c%c", p[i + 3], p[i + 2], p[i + 1], p[i]);
	printf("\n");

	return 0;
}

只要带入正确的a1[60]到a1[65]就能解出flag!

这时候代入前面解出来的发现没flag 寄!

通过官方wp知道解有很多个...但是z3只解出七组....所以换!

真!DFS深搜解决44,45行

enc = [0x00000025, 0x00000015, 0x000000DF, 0x000000A2, 0x000000C0, 0x00000093, 0x000000AD, 0x00000014, 0x00000046,
       0x000000C5, 0x0000000F, 0x0000002E, 0x0000009A, 0x000000EB, 0x00000030, 0x000000F8, 0x00000020, 0x000000E9,
       0x000000CB, 0x00000088, 0x000000C6, 0x000000BE, 0x0000008D, 0x000000E3, ]
flags = []
flag = [0] * 24
flag[23] = 0xE3

def DFS(deep):
    global flags
    global flag
    if deep == 0:
        flags.append(flag.copy()) #就是得copy!
        return
    else:
        for i in range(1, 0XFF): #爆破一下
            if (((i ^ 0x41) ^ (i % 0x12 + flag[deep] + 0x05)) == enc[deep - 1]):
                flag[deep - 1] = i
                DFS(deep - 1)

def get_all_flags():
    flag = [0] * 24
    flag[23] = 0xE3
    DFS(23)
    return flags
if __name__ == '__main__':
    flags = get_all_flags()

第二层总脚本!

import re

enc = [0x00000025, 0x00000015, 0x000000DF, 0x000000A2, 0x000000C0, 0x00000093, 0x000000AD, 0x00000014, 0x00000046,
       0x000000C5, 0x0000000F, 0x0000002E, 0x0000009A, 0x000000EB, 0x00000030, 0x000000F8, 0x00000020, 0x000000E9,
       0x000000CB, 0x00000088, 0x000000C6, 0x000000BE, 0x0000008D, 0x000000E3, ]
flags = []
flag = [0] * 24
flag[23] = 0xE3

def DFS(deep):
    global flags
    global flag
    if deep == 0:
        flags.append(flag.copy())
        return
    else:
        for i in range(1, 0XFF):
            if (((i ^ 0x41) ^ (i % 0x12 + flag[deep] + 0x05)) == enc[deep - 1]):
                flag[deep - 1] = i
                DFS(deep - 1)


def get_all_flags():
    """
    深搜解决44 45行的%18的
    """
    flag = [0] * 24
    flag[23] = 0xE3
    DFS(23)
    return flags

def ROL(i, index):
    tmp = bin(i)[2:].rjust(32, "0")
    for _ in range(index):
        tmp = tmp[1:] + tmp[0]
    return int(tmp, 2)


def T(t1, t2):
    dwo = [0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x1B000000,
           0x36000000]
    return ROL(t1, 8) ^ dwo[t2]


def four2one(tttt):
    """四合一 逆37-42行的"""
    res = []
    for r in range(len(tttt)):
        v4 = tttt[r]
        dword_408AC0 = []
        for i in range(0, 6):
            dword_408AC0.append(int("0x" +
                                    hex(v4[4 * i + 3])[2:].zfill(2) + hex(v4[4 * i + 2])[2:].zfill(2) + hex(
                v4[4 * i + 1])[
                                                                                                        2:].zfill(
                2) + hex(
                v4[4 * i])[2:].zfill(
                2), 16))
        res.append(dword_408AC0)
    return res


def print_flag(a1):
    """
    逆sub_402058的
    """
    i = 59
    j = 9
    while (i >= 0):
        if i % 6:
            a1[i] = a1[i + 6] ^ a1[i + 5]
        else:
            a1[i] = a1[i + 6] ^ T(a1[i + 5], j)
            j -= 1
        i -= 1
    f = ""
    for x in a1[:6]:
        f += hex(x)[2:]
    f = re.findall(".{2}", f)
    for x in f:
        print(chr(int(x, 16)), end="")
    print()


if __name__ == '__main__':
    flags = get_all_flags()
    res = four2one(flags)
    for ccc in res:
        a1 = [0] * 66
        for i in range(6):
            a1[60 + i] = ccc[i]
        print_flag(a1)
posted @ 2022-02-14 19:03  FW_ltlly  阅读(219)  评论(0编辑  收藏  举报