文章目录
- [WEEK3]ststst
- [WEEK2]not gcc
- [WEEK2]Run?润!
- [WEEK2]Authur's_box
- [WEEK2]pycode
[WEEK3]ststst
64 bit 的 ELF 文件
sub_400763点进去看看
mprotect ,这个
这一题是SMC + TEA的考察,我写过一篇关于 SMC学习网鼎杯jocker
可以使用idapython写脚本自动修复,也可以使用动态调试,我个人计较喜欢动态
linux虚拟机远程调试一下,具体步骤:
-
把文件复制到linux工作台上,chmod 777 ststst 赋予权限(这里我是操作过的)
-
将 ida目录的linux_server文件复制到工作台上,赋予权限
-
./linux_server64 启动服务,
-
然后在ida上点击 Remote Linux debugger
上面俩个填写linux上的文件路径,第三个是文件夹,然后还有虚拟机的ip地址,可以用ifconfig查看。
远程连接完,随便输入flag先
然后一直F7单步走,如果中间出现 提示 RIP错误的,点击no就好,
一直走到红色部分,停下
选中push rbp开始,一直选到最下面的 retn处。用U全部Undefine一下,
之后再用C改为代码,要用force强制处理,之后就是用p创建函数,再反编译。得到一个简单的TEA加密
密文和key都有,写个exp逆向一下就好;
#include <stdio.h>
#include <stdint.h>
void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], i;
uint32_t delta=0x61C88647;
uint32_t sum = -(delta*32);
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];
for (i=0; i<32; i++) {
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum += delta;
}
v[0]=v0; v[1]=v1;
}
int main()
{
uint32_t enflag[] = {3683591529,1087210467,2687755904,4294420036,1762408983,3055663206,887612071,2903549586};
uint32_t key[4] = {0x1234567, 0x89ABCDEF, 0x0FEDCBA98, 0x76543210};
for(int i=0;i<8;i+=2)
{
uint32_t temp[2]; //定义来解密
temp[0] = enflag[i];
temp[1] = enflag[i+1];
decrypt(temp, key);
//printf("%X%X",temp[0],temp[1]);
printf("%c%c%c%c%c%c%c%c",*((char*)&temp[0]+0),*((char*)&temp[0]+1),*((char*)&temp[0]+2),*((char*)&temp[0]+3),*((char*)&temp[1]+0),*((char*)&temp[1]+1),*((char*)&temp[1]+2),*((char*)&temp[1]+3));
}
return 0;
}
// 5ef846656801c9b9714388d2ccd98cdd
[WEEK2]not gcc
这一题给的是一个bc文件,查看一下文件类型
可以看到是 LLVM IR bitcode,bitcode是LLVM 引入的一种中间代码(Intermediate Representation,简称IR,它是源代码被编译为二进制机器码过程中的中间表示形态。
借用一张图:
可以看到.bc文件是clang编译过程中的一个中间产物,因此我们可以对该文件继续编译下去。
操作如下:
clang not.bc -o not
用IDA打开,
这里真的,做逆向脑子要动起来,一开始都没有注意到名字shudu-sudu 就是数独啊。
sudu函数里面的内容,是一个 9 * 9 的数独表,大致意思是如果map索引位置为真,我们的输入就是0,如果为假的话,就将我们的数字填入。map表中的内容取出来,整理一下。
sudoku = [
[4, 0, 7, 0, 0, 3, 2, 0, 8],
[5, 0, 0, 0, 2, 0, 9, 0, 0],
[0, 1, 2, 9, 8, 0, 0, 0, 4],
[7, 0, 9, 1, 0, 4, 8, 0, 0],
[0, 6, 1, 0, 0, 0, 4, 7, 0],
[0, 0, 3, 2, 7, 0, 0, 0, 6],
[0, 8, 6, 3, 0, 0, 0, 4, 0],
[0, 2, 0, 7, 4, 0, 6, 3, 0],
[3, 0, 4, 0, 0, 2, 0, 0, 0]
]
数独 GPT可以秒解,也可以用回溯算法(没学,待补);用的是gpt写的脚本,就不放了。
解出来后手动整理一下。
input_string = "090510060038406017600007350050060023200839005840005190900051702105008009070690581"
# Create an MD5 hash object
md5 = hashlib.md5()
# Update the hash object with the input string
md5.update(input_string.encode('utf-8'))
# Get the hexadecimal representation of the MD5 hash
md5_hash = md5.hexdigest()
print(md5_hash)
# afb5d3a138821e30d6e1e6ccce4e5554
[WEEK2]Run?润!
;;大家做题一定题目要细心,我尴尬死了,做这题,题目附件用错了,用成authorbox的了,还跑去问出题人o(╥﹏╥)o沙伯了。
一道迷宫题,不会的时候难,后面搞懂了专门学了
可以看看 CTF-Reverse 迷宫地图类题目分析‘‘DFS和BFS算法‘‘(学习笔记)【详】
一道题就是一个知识点,慢慢学吧。
打开这里 sub_401A26 是一个创建迷宫的函数,
sub_401AAF是对迷宫的一些操作
解释一下 ,
- -1 和 + 1就是当前位置向左或向右移动一个位置,
- -8 和 + 8就是当前位置向上或向下移动一个位置,
- -64和+64 是 移动楼层,对的这个是一个三维的迷宫 等等解释。
这里为什么呢,因为这里关于迷宫的数据放在数组里,是以一维数组的形式出现的,如果将一维数组分为 8 * 8的 二维数组 那 -8和+8不就是向上或向下移动 , 如果再将 8 * 8扩展到 8 * 8 * 8 的地步, 那么加 64也就是到下一个 迷宫去了。
有几处地方都可以知道这是个三维的迷宫,而且共有八层
而且在迷宫生成的时候,
使用了当前楼层这一参数,俩个for循环一共是 64 个值,也正好对应一层楼 是 8 * 8 等于 64的大小。
还有一处就是 v8 != 511 , 8 * 8 * 8的结果是 512 ,这里告诉的是 出口就在最后。
关于数据的取出,用动态调试,我试过输入uuuuuuuuuuuuuuuuuu但是都会跳到exit去,后面采用的方法是,修改rip为0x401B0F,把数据一
次一次取出来。
差不多了就是写exp,关于exp具体怎么来的可以看刚刚推的博客,我在里面讲蛮清楚了,不想打了。
exp:
maze = [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2]
# maze[x * 64 + y * 8 + z]
def check_point_valid(map, x, y, z):
if (x >= 0) and (x <= 7) and (y >= 0) and (y <= 7) and (z >= 0) and (z <= 7):
return (map[x * 64 + y * 8 + z] != 1) and ((map[x * 64 + y * 8 + z] == 0) or (map[x * 64 + y * 8 + z] == 2))
else:
return False
def gen_nex(map, x, y, z):
all_dir = []
if check_point_valid(map, x - 1, y, z):
all_dir.append((x - 1, y, z, 'q'))
if check_point_valid(map, x + 1, y, z):
all_dir.append((x + 1, y, z, 'u'))
if check_point_valid(map, x, y - 1, z):
all_dir.append((x, y - 1, z, 'w'))
if check_point_valid(map, x, y + 1, z):
all_dir.append((x, y + 1, z, 's'))
if check_point_valid(map, x, y, z - 1):
all_dir.append((x, y, z - 1, 'a'))
if check_point_valid(map, x, y, z + 1):
all_dir.append((x, y, z + 1, 'd'))
return all_dir
def check_success(map, x, y, z):
if map[x * 64 + y * 8 + z] == 2:
return True
else:
return False
def dfs(mapb, x, y, z, path):
map = mapb.copy()
if map[x * 64 + y * 8 + z] != 2:
map[x * 64 + y * 8 + z] = 1
if check_success(map, x, y, z):
print(path)
return True
next_point = gen_nex(map, x, y, z)
for n in next_point:
pathn = path + n[3]
dfs(map, n[0], n[1], n[2], pathn)
outpus = ""
dfs(maze, 0, 0, 0, outpus)
得到route:ssdddssuuuwwwwqqqdddduussaauuuaaaaassssqddddddduuwwwaasusssdd
就是将刚刚得到的route和 5c 加起来再做一个 MD5加密(sub_4015EC)
最后解出flag。
[WEEK2]Authur’s_box
用动态调试的一道题,
构造一个假flag{111111111111111111111111111111111111},在最后比较处下个断点。
数据取出来。
exp:
xor1 = [0xFE, 0x23, 0x65, 0xFD, 0xB8, 0xED, 0x84, 0xCC, 0x84, 0x20,
0x7F, 0x59, 0xCB, 0x98, 0x32, 0x06, 0xFA, 0x79, 0x2F, 0xE4,
0x74, 0x3C, 0xBC, 0x31, 0xC0, 0x3A, 0x1E, 0xED, 0xF5, 0x7C,
0xF6, 0xF8, 0x4A, 0xD5, 0xF1, 0x9B, 0x86, 0x00, 0xCB, 0x5F,
0x6F, 0x8C]
xor2 = [0x98, 0x4F, 0x04, 0x9A, 0xC3, 0x8F, 0xB1, 0xA8, 0xE0, 0x10,
0x4B, 0x3C, 0xFD, 0xB5, 0x04, 0x60, 0xCA, 0x1F, 0x02, 0xD0,
0x46, 0x0A, 0xDF, 0x1C, 0xA2, 0x0E, 0x78, 0xD4, 0xD8, 0x1F,
0xC3, 0xCE, 0x28, 0xB7, 0xC2, 0xFE, 0xB7, 0x64, 0xF9, 0x3A,
0x0A, 0xF1]
flag = []
for i in range(len(xor1)):
flag.append(chr(xor1[i] ^ xor2[i]))
print("".join(flag))
# flag{b5dd04e6-6f0f-426c-b4f9-c56bb3e1d2ee}
可能因为这道题太简单了o(╥﹏╥)o,我做完它都没有停留在我脑子里片刻,第二天做run?润!的时候用的这道题的附件,交了好久的flag一直是错误的,当时真的一点自己做过这题的记忆都没有 奇怪。尴尬死了。
[WEEK2]pycode
0 0 RESUME 0
1 2 LOAD_CONST 0 (0)
4 LOAD_CONST 1 (None)
6 IMPORT_NAME 0 (base64)
8 STORE_NAME 0 (base64)
2 10 LOAD_CONST 2 ('*******************')
12 STORE_NAME 1 (flag)
3 14 LOAD_CONST 3 ('')
16 STORE_NAME 2 (value)
4 18 LOAD_CONST 3 ('')
20 STORE_NAME 3 (output)
5 22 PUSH_NULL
24 LOAD_NAME 4 (range)
26 LOAD_CONST 4 (1000)
28 PRECALL 1
32 CALL 1
42 GET_ITER
>> 44 FOR_ITER 24 (to 94)
46 STORE_NAME 5 (i)
6 48 LOAD_CONST 5 (1024)
50 STORE_NAME 6 (w)
7 52 LOAD_NAME 6 (w)
54 LOAD_CONST 6 (3)
56 BINARY_OP 6 (%)
60 STORE_NAME 7 (x)
8 62 LOAD_NAME 6 (w)
64 LOAD_CONST 7 (9)
66 BINARY_OP 2 (//)
70 STORE_NAME 8 (y)
9 72 LOAD_NAME 7 (x)
74 LOAD_NAME 8 (y)
76 BINARY_OP 5 (*)
80 STORE_NAME 9 (z)
10 82 LOAD_NAME 6 (w)
84 LOAD_NAME 9 (z)
86 BINARY_OP 23 (-=)
90 STORE_NAME 6 (w)
92 JUMP_BACKWARD 25 (to 44)
11 >> 94 PUSH_NULL
96 LOAD_NAME 4 (range)
98 LOAD_CONST 8 (10000)
100 PRECALL 1
104 CALL 1
114 GET_ITER
>> 116 FOR_ITER 24 (to 166)
118 STORE_NAME 5 (i)
12 120 LOAD_CONST 9 (20)
122 STORE_NAME 6 (w)
13 124 LOAD_NAME 6 (w)
126 LOAD_CONST 10 (6)
128 BINARY_OP 6 (%)
132 STORE_NAME 7 (x)
14 134 LOAD_NAME 6 (w)
136 LOAD_CONST 6 (3)
138 BINARY_OP 2 (//)
142 STORE_NAME 8 (y)
15 144 LOAD_NAME 7 (x)
146 LOAD_NAME 8 (y)
148 BINARY_OP 5 (*)
152 STORE_NAME 9 (z)
16 154 LOAD_NAME 6 (w)
156 LOAD_NAME 9 (z)
158 BINARY_OP 13 (+=)
162 STORE_NAME 6 (w)
164 JUMP_BACKWARD 25 (to 116)
17 >> 166 PUSH_NULL
168 LOAD_NAME 4 (range)
170 LOAD_CONST 4 (1000)
172 PRECALL 1
176 CALL 1
186 GET_ITER
>> 188 FOR_ITER 24 (to 238)
190 STORE_NAME 5 (i)
18 192 LOAD_CONST 5 (1024)
194 STORE_NAME 6 (w)
19 196 LOAD_NAME 6 (w)
198 LOAD_CONST 6 (3)
200 BINARY_OP 6 (%)
204 STORE_NAME 7 (x)
20 206 LOAD_NAME 6 (w)
208 LOAD_CONST 7 (9)
210 BINARY_OP 2 (//)
214 STORE_NAME 8 (y)
21 216 LOAD_NAME 7 (x)
218 LOAD_NAME 8 (y)
220 BINARY_OP 5 (*)
224 STORE_NAME 9 (z)
22 226 LOAD_NAME 6 (w)
228 LOAD_NAME 9 (z)
230 BINARY_OP 23 (-=)
234 STORE_NAME 6 (w)
236 JUMP_BACKWARD 25 (to 188)
23 >> 238 PUSH_NULL
240 LOAD_NAME 4 (range)
242 LOAD_CONST 8 (10000)
244 PRECALL 1
248 CALL 1
258 GET_ITER
>> 260 FOR_ITER 24 (to 310)
262 STORE_NAME 5 (i)
24 264 LOAD_CONST 9 (20)
266 STORE_NAME 6 (w)
25 268 LOAD_NAME 6 (w)
270 LOAD_CONST 10 (6)
272 BINARY_OP 6 (%)
276 STORE_NAME 7 (x)
26 278 LOAD_NAME 6 (w)
280 LOAD_CONST 6 (3)
282 BINARY_OP 2 (//)
286 STORE_NAME 8 (y)
27 288 LOAD_NAME 7 (x)
290 LOAD_NAME 8 (y)
292 BINARY_OP 5 (*)
296 STORE_NAME 9 (z)
28 298 LOAD_NAME 6 (w)
300 LOAD_NAME 9 (z)
302 BINARY_OP 13 (+=)
306 STORE_NAME 6 (w)
308 JUMP_BACKWARD 25 (to 260)
29 >> 310 PUSH_NULL
312 LOAD_NAME 4 (range)
314 LOAD_CONST 0 (0)
316 PUSH_NULL
318 LOAD_NAME 10 (len)
320 LOAD_NAME 1 (flag)
322 PRECALL 1
326 CALL 1
336 PRECALL 2
340 CALL 2
350 GET_ITER
>> 352 FOR_ITER 38 (to 430)
354 STORE_NAME 5 (i)
30 356 LOAD_NAME 1 (flag)
358 LOAD_NAME 5 (i)
360 BINARY_SUBSCR
370 STORE_NAME 11 (temp)
31 372 PUSH_NULL
374 LOAD_NAME 12 (chr)
376 PUSH_NULL
378 LOAD_NAME 13 (ord)
380 LOAD_NAME 11 (temp)
382 PRECALL 1
386 CALL 1
396 LOAD_CONST 11 (8)
398 BINARY_OP 12 (^)
402 PRECALL 1
406 CALL 1
416 STORE_NAME 11 (temp)
32 418 LOAD_NAME 2 (value)
420 LOAD_NAME 11 (temp)
422 BINARY_OP 13 (+=)
426 STORE_NAME 2 (value)
428 JUMP_BACKWARD 39 (to 352)
33 >> 430 PUSH_NULL
432 LOAD_NAME 4 (range)
434 PUSH_NULL
436 LOAD_NAME 10 (len)
438 LOAD_NAME 1 (flag)
440 PRECALL 1
444 CALL 1
454 PRECALL 1
458 CALL 1
468 GET_ITER
>> 470 FOR_ITER 38 (to 548)
472 STORE_NAME 5 (i)
34 474 LOAD_NAME 2 (value)
476 LOAD_NAME 5 (i)
478 BINARY_SUBSCR
488 STORE_NAME 11 (temp)
35 490 PUSH_NULL
492 LOAD_NAME 12 (chr)
494 PUSH_NULL
496 LOAD_NAME 13 (ord)
498 LOAD_NAME 11 (temp)
500 PRECALL 1
504 CALL 1
514 LOAD_CONST 6 (3)
516 BINARY_OP 0 (+)
520 PRECALL 1
524 CALL 1
534 STORE_NAME 11 (temp)
36 536 LOAD_NAME 3 (output)
538 LOAD_NAME 11 (temp)
540 BINARY_OP 13 (+=)
544 STORE_NAME 3 (output)
546 JUMP_BACKWARD 39 (to 470)
37 >> 548 PUSH_NULL
550 LOAD_NAME 0 (base64)
552 LOAD_ATTR 14 (b64encode)
562 LOAD_NAME 3 (output)
564 LOAD_METHOD 15 (encode)
586 PRECALL 0
590 CALL 0
600 PRECALL 1
604 CALL 1
614 LOAD_METHOD 16 (decode)
636 PRECALL 0
640 CALL 0
650 STORE_NAME 17 (obfuscated_output)
38 652 LOAD_NAME 17 (obfuscated_output)
654 LOAD_CONST 1 (None)
656 LOAD_CONST 1 (None)
658 LOAD_CONST 12 (-1)
660 BUILD_SLICE 3
662 BINARY_SUBSCR
672 STORE_NAME 17 (obfuscated_output)
39 674 LOAD_NAME 17 (obfuscated_output)
676 LOAD_METHOD 18 (replace)
698 LOAD_CONST 13 ('0')
700 LOAD_CONST 14 ('t')
702 PRECALL 2
706 CALL 2
716 STORE_NAME 17 (obfuscated_output)
40 718 LOAD_NAME 17 (obfuscated_output)
720 LOAD_METHOD 18 (replace)
742 LOAD_CONST 15 ('c')
744 LOAD_CONST 16 ('4')
746 PRECALL 2
750 CALL 2
760 STORE_NAME 17 (obfuscated_output)
41 762 LOAD_NAME 17 (obfuscated_output)
764 LOAD_METHOD 18 (replace)
786 LOAD_CONST 17 ('+')
788 LOAD_CONST 18 ('-')
790 PRECALL 2
794 CALL 2
804 STORE_NAME 17 (obfuscated_output)
42 806 PUSH_NULL
808 LOAD_NAME 19 (print)
810 LOAD_NAME 17 (obfuscated_output)
812 PRECALL 1
816 CALL 1
826 POP_TOP
828 LOAD_CONST 1 (None)
830 RETURN_VALUE
==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4
一个txt文件,bytecode不难,抠出来就好。关于具体的步骤可以参考python字节码详解,反编译过程
抠出来后如下面的代码,中间四个for循环全部都是脏东西。
import base64
flag = '*******************'
value = ''
output = ''
for i in range(1000):
w = 1024
x = w % 3
y = w // 9
z = x * y
w -= z
for i in range(10000):
for i in range(1000):
for i in range(10000):
for i in range(len(flag)):
temp = flag[i]
temp = chr(ord(temp) ^ 8)
value += temp
for i in range(len(flag)):
temp = value[i]
temp = chr(ord(temp) + 3)
output += temp
obfuscated_output = base64.b64encode(output.encode())
obfuscated_output = obfuscated_output[::-1]
obfuscated_output = obfuscated_output.replace('0','t')
obfuscated_output = obfuscated_output.replace('c','4')
obfuscated_output = obfuscated_output.replace('+','-')
print(obfuscated_output)
# ==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4
逻辑不难,写个exp逆向一下
import base64
flag = []
# ==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4
obfuscated_output = '==AeAF3M-tzO-giQ-AUQosDQ9tGK7MDPuhC47tDNB5Tb8Yn4sdW4'
obfuscated_output = obfuscated_output.replace('t','0')
obfuscated_output = obfuscated_output.replace('4','c')
obfuscated_output = obfuscated_output.replace('-','+')
obfuscated_output = obfuscated_output[::-1]
obfuscated_output = base64.b64decode(obfuscated_output.encode())
for i in range(len(obfuscated_output)):
flag.append(chr(obfuscated_output[i] - 3 ^ 8))
print("".join(flag))
# flag{1b36920e-c180-b250-6537-30238f5}
exp
maze = [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0,
1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1,
1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 2]
# maze[x * 64 + y * 8 + z]
def check_point_valid(map, x, y, z):
if (x >= 0) and (x <= 7) and (y >= 0) and (y <= 7) and (z >= 0) and (z <= 7):
return (map[x * 64 + y * 8 + z] != 1) and ((map[x * 64 + y * 8 + z] == 0) or (map[x * 64 + y * 8 + z] == 2))
else:
return False
def gen_nex(map, x, y, z):
all_dir = []
if check_point_valid(map, x - 1, y, z):
all_dir.append((x - 1, y, z, 'q'))
if check_point_valid(map, x + 1, y, z):
all_dir.append((x + 1, y, z, 'u'))
if check_point_valid(map, x, y - 1, z):
all_dir.append((x, y - 1, z, 'w'))
if check_point_valid(map, x, y + 1, z):
all_dir.append((x, y + 1, z, 's'))
if check_point_valid(map, x, y, z - 1):
all_dir.append((x, y, z - 1, 'a'))
if check_point_valid(map, x, y, z + 1):
all_dir.append((x, y, z + 1, 'd'))
return all_dir
def check_success(map, x, y, z):
if map[x * 64 + y * 8 + z] == 2:
return True
else:
return False
def dfs(mapb, x, y, z, path):
map = mapb.copy()
if map[x * 64 + y * 8 + z] != 2:
map[x * 64 + y * 8 + z] = 1
if check_success(map, x, y, z):
print(path)
return True
next_point = gen_nex(map, x, y, z)
for n in next_point:
pathn = path + n[3]
dfs(map, n[0], n[1], n[2], pathn)
outpus = ""
dfs(maze, 0, 0, 0, outpus)