强网杯 2024 Reverse
ez_vm
程序获取argv,也就是启动程序的参数(是十六进制数),然后就parse成buffer,走两次加密,一次16字节,两次互相不影响。
加密流程如下,从内存中dump出来三个table,然后就嗯调,抄出来东西(python)如下。
from typing import List, Tuple
from struct import unpack, pack
# retval: (sbox, inv_sbox)
def generate_sbox(_from: bytes, _to: bytes) -> Tuple[List[int], List[int]]:
inv_sbox = [_to.index(i) for i in _from]
s_box = [_from.index(i) for i in _to]
return s_box, inv_sbox
def sbox_transform(_from: bytes, box: List[int]):
r = [_from[box[i]] for i in range(len(_from))]
if type(_from) == bytes:
return bytes(r)
else:
return r
def byte2dword(x: List[int]):
if len(x) % 4 != 0:
if type(x) == bytes:
x += b'\x00' * (4 - (len(x) % 4))
else:
x += [0] * (4 - (len(x) % 4))
return [v[0] for v in (unpack('<I', bytes(x[i:i+4])) for i in range(0, len(x), 4))]
table1 = byte2dword(open('table1.bin', 'rb').read())
table2 = open('table2.bin', 'rb').read()
table3 = open('table3.bin', 'rb').read()
xtime = lambda x, y: (x // 2 ** y) & 0xf
before = bytes.fromhex('01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00')
after = bytes.fromhex('01 06 0B 00 05 0A 0F 04 09 0E 03 08 0D 02 07 0C')
box, ibox = generate_sbox(before, after)
def one_time(x, ctr):
r = [0, 0, 0, 0]
r[0] = table2[xtime(table1[x[0]], ctr) << 4 | xtime(table1[0x100 + x[1]], ctr)]
r[1] = table2[xtime(table1[0x200 + x[2]], ctr) << 4 | xtime(table1[0x300 + x[3]], ctr)]
r[2] = table2[xtime(table1[x[0]], ctr - 4) << 4 | xtime(table1[0x100 + x[1]], ctr - 4)]
r[3] = table2[xtime(table1[0x200 + x[2]], ctr - 4) << 4 | xtime(table1[0x300 + x[3]], ctr - 4)]
return (r[0] ^ r[1]) << 4 | (r[2] ^ r[3])
def magic(x):
r = [0, 0, 0, 0]
r[0] = one_time(x, 28)
r[1] = one_time(x, 20)
r[2] = one_time(x, 12)
r[3] = one_time(x, 4)
return r
def encrypt(src, offset):
src = sbox_transform(src, box)
result = []
for i in range(0, 16, 4):
r = src[i:i+4]
r = magic([j | i << 8 | (offset) << 12 for j in r])
r = magic([j | i << 8 | (9 + offset) << 12 for j in r])
result.extend(r)
return result
def denc(src: bytes):
for i in range(9):
src = encrypt(src, i)
src = sbox_transform(src, box)
src = [table3[src[i] + (i << 8)] for i in range(len(src))]
return src
if __name__ == '__main__':
# 测试的一组加密数据
t = list(bytes.fromhex('FE DC BA 98 76 54 32 10 FE DC BA 98 76 54 32 10'))
t = denc(t)
print([hex(i) for i in t])
# 测试的加密结果
# ['0x6c', '0x53', '0xfc', '0xe5', '0x4', '0xf6', '0x93', '0x1a', '0xdb', '0x25', '0xfd', '0x81', '0xeb', '0xde', '0x5b', '0x6d']
# 真正的enc(32字节,两次加密后的结果)
enc = b"\xC4\x0C\xC0\x20\xFC\x48\xF6\xD2\x6C\xD2\xFC\x2B\x5C\xA7\x2E\x65\x41\xFE\x0E\x64\x05\x6E\xD5\x9C\xCC\x41\x1D\x10\xBE\xA0\xF5\x09"
但是其实可以直接binwalk,发现一堆AES S-Box,结合上面逆向(赤石)出来的,我们基本上可以确定是AES白盒
AES白盒,使用DFA脚本
需要使用dfa攻击恢复出密钥
观察到前九轮都是使用encrypt
最后进行了一次transform
说明应该在第九轮注入故障
def denc(src: bytes, pos, cb):
for i in range(9):
if i == 8:
src[pos] = random.randint(0,255)
src = encrypt(src, i)
src = sbox_transform(src, box)
src = [table3[src[i] + (i << 8)] for i in range(len(src))]
return src
产生的数据4字节不同,符合特征
使用phoenixAES进行恢复最后一轮密钥
import phoenixAES
phoenixAES.crack_file('tracefile', [], True, False, 3)
得到BF2256727EF09577C7F720C7D84D697A
使用stark恢复第一轮密钥
aes_keyschedule.exe BF2256727EF09577C7F720C7D84D697A 10
K00: 77656C636F6D65746F71776232303234
K01: 724674401D2B1134725A6656406A5462
K02: 7266DE496F4DCF7D1D17A92B5D7DFD49
K03: 8932E505E67F2A78FB688353A6157E1A
K04: D8C147213EBE6D59C5D6EE0A63C39010
K05: E6A18DDAD81FE0831DC90E897E0A9E99
K06: A1AA632979B583AA647C8D231A7613BA
K07: D9D7978BA0621421C41E9902DE688AB8
K08: 1CA9FB96BCCBEFB778D576B5A6BDFC0D
K09: 7D192CB2C1D2C305B907B5B01FBA49BD
K10: BF2256727EF09577C7F720C7D84D697A
恢复密钥welcometoqwb2024
拿到password后,解密就行了。
from Crypto.Cipher import AES
password = b'welcometoqwb2024'
text = b"\xC4\x0C\xC0\x20\xFC\x48\xF6\xD2\x6C\xD2\xFC\x2B\x5C\xA7\x2E\x65\x41\xFE\x0E\x64\x05\x6E\xD5\x9C\xCC\x41\x1D\x10\xBE\xA0\xF5\x09" # 需要加密的内容,bytes类型
aes = AES.new(password, AES.MODE_ECB)
den_text = aes.decrypt(text)
print("明文:", den_text)
# 明文: b'7f28bc5e9f3f149525cedf0bf6606cf0'
mips
emu是魔改的qemu-6.2.0
file mips_bin
mips_bin: ELF 32-bit MSB executable, MIPS, MIPS32 version 1 (SYSV), statically linked, not stripped
发现是大端序,可以通过如下方法动态调试
qemu-mips -g 12345 ./mips_bin
#另外开一个窗口
gdb-multiarch ./mips_bin
set arch mips
set endian big
target remote localhost:12345
手动改掉v8的值进入子进程中
a="sxrujtv`labiVzbp`vpg|"
for i in range(21):
print(chr(ord(a[i])^(0x15-i)),end="")
得到fake flag
正常的qemu使用时应该没有提示输入的信息
./emu -d 可以打印一些翻译的语句的trace, 基本可以确定翻译前后, 指令语义未发生变化
当输入乱打的flag时, 会走到0x3fc 0x404 0x408就是wrong那一块, 输出wrong
当输入fake flag时, 会走到0x3e4 0x3e8 0x3ec就是right那一块, 但是同样输出wrong
要么这个check根本不重要, 有另一个check
emu sub_3DE49E
Hook syscall read(case 4003)校验flag{}格式
hook syscall write(case 4004)修改输出
交叉:引用if块里面第2个全局变量dword_C3231C找到check, 花指令简单nop掉
sub_33D8E0:
__int64 __fastcall sub_33D8E0(__int64 a1)
{
__int64 result; // rax
int v2; // [rsp+10h] [rbp-20h]
int i; // [rsp+14h] [rbp-1Ch]
int j; // [rsp+18h] [rbp-18h]
__int64 v5; // [rsp+20h] [rbp-10h]
__int64 v6; // [rsp+28h] [rbp-8h]
v5 = *(a1 + 528);
v2 = 0;
result = *(v5 + 128);
if ( *(v5 + 128) == 0x23000 )
{
result = format_check;
if ( format_check )
{
v6 = sub_33D48E(&unk_C33280);
for ( i = 0; i <= 21; ++i )
*(i + v6) ^= dword_C32324;
sub_33D886(v6, 7LL, 11LL);
result = sub_33D886(v6, 12LL, 16LL);
for ( j = 0; j <= 21; ++j )
{
result = dword_B9CA80[j];
if ( *(j + v6) != result )
{
v2 = 1;
break;
}
}
if ( !v2 && j == 22 )
dword_C3231C = 1;
}
}
return result;
}
前面rc4的部分应该没啥问题: sub_33D48E里面
def rc4_init(s, key, key_len):
j = 0
for i in range(256):
j = (j + s[i] + key[i%key_len])%256
tmp = s[i]
s[i] = s[j]
s[j] = tmp
def rc4_generate_keystream(s, length):
i = 0
j = 0
key_stream = []
while length:
i = (i + 1) % 256 # 可以保证每256次循环后s盒中的每个元素至少被交换一次
j = (j + s[i]) % 256
tmp = s[i]
s[i] = s[j]
s[j] = tmp
key_stream.append(s[(s[i] + s[j]) % 256])
length -= 1
return key_stream
def main():
key = [ord(i) for i in "6105t3"] # 准备一些变量
key_len = len(key)
enc = [0xC4, 0xEE, 0x3C, 0xBB, 0xE7, 0xFD, 0x67, 0x1D, 0xF8, 0x97, 0x68, 0x9D, 0x0B, 0x7F, 0xC7, 0x80, 0xDF, 0xF9, 0x4B, 0xA0, 0x46, 0x91]
enc_len = len(enc)
cipher = [0] * enc_len
print(enc_len)
s = [i for i in range(256)] # 初始化s盒
rc4_init(s, key, key_len) # 使用key打乱s盒
key_stream = rc4_generate_keystream(s[:], enc_len) # 生成密钥流
然后异或一个key2和上面生成的keystream
key2 = [0xDE, 0xAD, 0xBE, 0xEF]
for i in range(enc_len): # 逐字节异或加密
cipher[i] = enc[i] ^ key_stream[i] ^ key2[i % 4]
还有注意sub_33D48E外面还有一个异或:
for ( i = 0; i <= 21; ++i )
a1a[i] ^= dword_C32324;
我们整理一下思路
SRC -> 移位加密 -> xor_cycle([0xDE, 0xAD, 0xBE, 0xEF]) -> RC4 -> XOR单字节 -> 两次交换 -> ENC
写出解题脚本就可以了,移位加密我实在不会逆,所以Z3解决了
from regadgets import *
from z3 import *
from copy import deepcopy
'''
swap(a1, 7, 11);
swap(a1, 12, 16);
'''
from z3 import *
for i in range(256):
enc = [0x000000C4, 0x000000EE, 0x0000003C, 0x000000BB, 0x000000E7, 0x000000FD, 0x00000067, 0x0000001D, 0x000000F8, 0x00000097, 0x00000068, 0x0000009D, 0x0000000B, 0x0000007F, 0x000000C7, 0x00000080, 0x000000DF, 0x000000F9, 0x0000004B, 0x000000A0, 0x00000046, 0x00000091]
l = len(enc)
enc[7], enc[11] = enc[11], enc[7]
enc[12], enc[16] = enc[16], enc[12]
enc = bxor_cycle(enc, [i])
enc = rc4_crypt(rc4_init(b'6105t3'), enc)
enc = bxor_cycle(enc, [0xDE, 0xAD, 0xBE, 0xEF])
x = [BitVec(f"x{i}", 8) for i in range(l)]
s = Solver()
for j in range(len(enc)):
v3 = ((RotateRight(x[j], 1) << 6) ^ 0xC0 | LShR(RotateRight(x[j], 1), 2) ^ 0x3B) ^ 0xBE
temp = RotateRight(v3, 3) ^ 0xAD
v1 = RotateRight(temp, 4) ^ 0xDE
s.add(RotateRight(v1, 5) == enc[j])
s.check()
m = s.model()
r = []
for i in x:
r.append(m[i].as_long())
r = bytes(r)
def is_printable(byte_data):
return all(32 <= b <= 126 for b in byte_data)
if is_printable(r):
print(r)
'''
b'T`HpZw6s6wv6lk<ZmEfn3x'
b'UaIq[v7r7vw7mj=[lDgo2y'
b'VbJrXu4q4ut4ni>XoGdl1z'
b'WcKsYt5p5tu5oh?YnFem0{'
b'PdLt^s2w2sr2ho8^iAbj7|'
b'QeMu_r3v3rs3in9_h@ck6}'
b'RfNv\\q0u0qp0jm:\\kC`h5~'
b'^jBzP}<y<}|<fa6PgOld9r'
b'_kC{Q|=x=|}=g`7QfNme8s'
b'YmE}Wz;~;z{;af1W`Hkc>u'
b'ZnF~Ty8}8yx8be2TcKh`=v'
b'DpX`Jg&c&gf&|{,J}Uv~#h'
b'Au]eOb#f#bc#y~)OxPs{&m'
b'Bv^fLa e a` z}*L{Spx%n'
b'Cw_gM`!d!`a!{|+MzRqy$o'
b'LxPhBo.k.on.ts$Bu]~v+`'
b'NzRj@m,i,ml,vq&@w_|t)b'
b"O{SkAl-h-lm-wp'Av^}u(c"
b'H|TlFk*o*kj*pw FqYzr/d'
b'I}UmGj+n+jk+qv!GpX{s.e'
b'J~VnDi(m(ih(ru"Ds[xp-f'
'''
flag{QeMu_r3v3rs3in9_h@ck6}
斯内克
算法题,中途下架了
下架之前:
每走一步会对目标函数地址运算一次,然后和某16位结果比较,相同就执行这个函数,返回值为一时成功,输入就是这个函数的参数
重新上线之后:
每次拐弯会对目标函数地址运算一次,然后和某16位结果比较,相同就执行这个函数,返回值为一时成功,输入就是这个函数的参数
rand()%20生成食物的坐标x和y,srand(0xdeadbeef)
sub_1400121E0是 哈希 MD5的Init,里面有4个魔数
hash_Md5有三个参数,第一个是函数内容,第二个是函数大小,第三个是retval,返回一个16字节的MD5 buffer
然后我们大概可以了解逻辑
from typing import *
from copy import deepcopy
from hashlib import md5
class WindowsRand():
def __init__(self, seed: int):
self.holdrand = seed
def rand(self) -> int:
self.holdrand = self.holdrand * 214013 + 2531011
return (self.holdrand >> 16) & 0x7fff
def rands(self, count: int) -> List[int]:
return [self.rand() for _ in range(count)]
def ror8(x, n):
n &= 7
return ((x >> n) | (x << (8 - n))) & 0xFF
a = [0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD, 0x38, 0x4C, 0xB0, 0x38, 0x6D, 0xEE, 0x3F, 0xC4, 0xB4, 0xB4, 0x09, 0x6A, 0xF0, 0x38, 0x2C, 0x79, 0xF6, 0x34, 0xE9, 0x89, 0x38, 0xAC, 0x7F, 0x35, 0xD4, 0xB4, 0xB4, 0x38, 0x6D, 0x77, 0xF6, 0xB6, 0x38, 0x6D, 0x78, 0xF6, 0xB6, 0x2B, 0x18, 0xB4, 0xB4, 0xB4, 0x3B, 0x81, 0x81, 0x81, 0x81, 0xEF, 0x4E, 0x38, 0x4C, 0x7D, 0xF6, 0x33, 0xD4, 0xB4, 0xB4, 0xB0, 0xE8, 0xF4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB0, 0xE8, 0xF6, 0x2B, 0x27, 0xA3, 0x1D, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xB4, 0xB0, 0xF8, 0x04, 0x38, 0x89, 0xE3, 0xC3, 0xCA, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xC4, 0xB0, 0xF8, 0x04, 0x38, 0xB3, 0x67, 0xE3, 0x16, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xD4, 0xB0, 0xF8, 0x04, 0x38, 0xB6, 0xD3, 0xB6, 0xA9, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xE4, 0xB0, 0xF8, 0x04, 0x38, 0x89, 0xD8, 0xC7, 0x33, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xB4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xB4, 0x38, 0x4C, 0xED, 0xB5, 0xD4, 0xB4, 0xB4, 0x4C, 0xF4, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xC4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xC4, 0x38, 0x4C, 0xED, 0xB5, 0xD4, 0xB4, 0xB4, 0x4C, 0xF4, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xD4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x38, 0x4C, 0xED, 0xB5, 0xD4, 0xB4, 0xB4, 0x4C, 0xF4, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xE4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xE4, 0x38, 0x4C, 0xED, 0xB5, 0xD4, 0xB4, 0xB4, 0x4C, 0xF4, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0xB0, 0xEC, 0xFE, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0x6F, 0x14, 0x4C, 0xEC, 0xFE, 0xB4, 0xB4, 0xB4, 0x2F, 0xC0, 0x2C, 0xEC, 0xFE, 0xB4, 0xB4, 0xB4, 0xCC, 0x6C, 0xFE, 0xB4, 0xB4, 0xB4, 0xB6, 0x24, 0xCC, 0x72, 0xB4, 0xB4, 0xB4, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xB4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xC4, 0x4C, 0x79, 0x85, 0x37, 0xD0, 0xD2, 0xF4, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xC4, 0x4C, 0xF9, 0x05, 0x37, 0xD0, 0x62, 0x04, 0xE3, 0x60, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xC4, 0xE4, 0x79, 0x05, 0x37, 0x4C, 0xE9, 0xF4, 0xCC, 0xE2, 0xE4, 0x4C, 0xE1, 0x4C, 0xF9, 0xED, 0x38, 0xF8, 0x4C, 0xE8, 0xF4, 0xF8, 0xE4, 0xE0, 0xA8, 0x4C, 0xC1, 0xE3, 0x60, 0xE4, 0x79, 0x04, 0x37, 0x4C, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xB4, 0x2C, 0xF8, 0x85, 0x37, 0x4C, 0xE8, 0xF6, 0x4C, 0x69, 0xF4, 0xE4, 0x40, 0x4C, 0xD0, 0x2C, 0xE8, 0xF4, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xC4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xB4, 0x4C, 0x79, 0x85, 0x37, 0xD0, 0xD2, 0xF4, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xB4, 0x4C, 0xF9, 0x05, 0x37, 0xD0, 0x62, 0x04, 0xE3, 0x60, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xB4, 0xE4, 0x79, 0x05, 0x37, 0x4C, 0xE9, 0xF4, 0xD0, 0x62, 0x64, 0xCC, 0xE2, 0xE4, 0x4C, 0xE1, 0x4C, 0xF9, 0xED, 0x38, 0xF8, 0x4C, 0xE8, 0xF4, 0xF8, 0xE4, 0xE0, 0xA8, 0x4C, 0xC1, 0xE3, 0x60, 0xE4, 0x79, 0x04, 0x37, 0x4C, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xC4, 0x2C, 0xF8, 0x85, 0x37, 0x52, 0x54, 0x2F, 0x2F, 0x2F, 0xB0, 0xEC, 0x00, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0x6F, 0x14, 0x4C, 0xEC, 0x00, 0xB4, 0xB4, 0xB4, 0x2F, 0xC0, 0x2C, 0xEC, 0x00, 0xB4, 0xB4, 0xB4, 0xCC, 0x6C, 0x00, 0xB4, 0xB4, 0xB4, 0xB6, 0x24, 0xCC, 0x72, 0xB4, 0xB4, 0xB4, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xD4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xE4, 0x4C, 0x79, 0x85, 0x37, 0xD0, 0xD2, 0xF4, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xE4, 0x4C, 0xF9, 0x05, 0x37, 0xD0, 0x62, 0x04, 0xE3, 0x60, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xE4, 0xE4, 0x79, 0x05, 0x37, 0x4C, 0xE9, 0xF4, 0xCC, 0xE2, 0xE4, 0x4C, 0xE1, 0x4C, 0xF9, 0xED, 0x38, 0xF8, 0x4C, 0xE8, 0xF4, 0xF8, 0xE4, 0xE0, 0xA8, 0x4C, 0xC1, 0xE3, 0x60, 0xE4, 0x79, 0x04, 0x37, 0x4C, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0x4C, 0xE8, 0xF6, 0x4C, 0x69, 0xF4, 0xE4, 0x40, 0x4C, 0xD0, 0x2C, 0xE8, 0xF4, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xE4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x4C, 0x79, 0x85, 0x37, 0xD0, 0xD2, 0xF4, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xD4, 0x4C, 0xF9, 0x05, 0x37, 0xD0, 0x62, 0x04, 0xE3, 0x60, 0x5B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xE1, 0xD4, 0xE4, 0x79, 0x05, 0x37, 0x4C, 0xE9, 0xF4, 0xD0, 0x62, 0x64, 0xCC, 0xE2, 0xE4, 0x4C, 0xE1, 0x4C, 0xF9, 0xED, 0x38, 0xF8, 0x4C, 0xE8, 0xF4, 0xF8, 0xE4, 0xE0, 0xA8, 0x4C, 0xC1, 0xE3, 0x60, 0xE4, 0x79, 0x04, 0x37, 0x4C, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xE4, 0x2C, 0xF8, 0x85, 0x37, 0x52, 0x54, 0x2F, 0x2F, 0x2F, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xB4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x4C, 0x79, 0x85, 0x37, 0x4C, 0xF8, 0x04, 0x37, 0xE3, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xB4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xC4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xE4, 0x4C, 0x79, 0x85, 0x37, 0x4C, 0xF8, 0x04, 0x37, 0xE3, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xC4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xE4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xB4, 0x4C, 0x79, 0x85, 0x37, 0x4C, 0xF8, 0x04, 0x37, 0xE3, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xE4, 0x2C, 0xF8, 0x85, 0x37, 0x3B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0xC0, 0xC4, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x4C, 0x79, 0x85, 0x37, 0x4C, 0xF8, 0x04, 0x37, 0xE3, 0xD0, 0x2B, 0xF4, 0xB4, 0xB4, 0xB4, 0x38, 0x4A, 0x50, 0xD4, 0x2C, 0xF8, 0x85, 0x37, 0xA0, 0xEC, 0x42, 0xB4, 0xB4, 0xB4, 0x3D, 0xA0, 0xEC, 0x52, 0xB4, 0xB4, 0xB4, 0xBE, 0xA0, 0xEC, 0x62, 0xB4, 0xB4, 0xB4, 0x51, 0xA0, 0xEC, 0x6F, 0xB4, 0xB4, 0xB4, 0x3D, 0xA0, 0xEC, 0x7F, 0xB4, 0xB4, 0xB4, 0x5B, 0xA0, 0xEC, 0x12, 0xB4, 0xB4, 0xB4, 0x8D, 0xA0, 0xEC, 0x22, 0xB4, 0xB4, 0xB4, 0x65, 0xA0, 0xEC, 0x32, 0xB4, 0xB4, 0xB4, 0xA7, 0xA0, 0xEC, 0xBF, 0xB4, 0xB4, 0xB4, 0x4D, 0xA0, 0xEC, 0xCF, 0xB4, 0xB4, 0xB4, 0xAC, 0xA0, 0xEC, 0xDF, 0xB4, 0xB4, 0xB4, 0xF8, 0xA0, 0xEC, 0xEF, 0xB4, 0xB4, 0xB4, 0x06, 0xA0, 0xEC, 0xFF, 0xB4, 0xB4, 0xB4, 0xE9, 0xA0, 0xEC, 0x8F, 0xB4, 0xB4, 0xB4, 0x3B, 0xA0, 0xEC, 0x9F, 0xB4, 0xB4, 0xB4, 0xA3, 0xA0, 0xEC, 0xAF, 0xB4, 0xB4, 0xB4, 0x31, 0xB0, 0xEC, 0xF5, 0xC4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0xB4, 0x6F, 0x14, 0x4C, 0xEC, 0xF5, 0xC4, 0xB4, 0xB4, 0x2F, 0xC0, 0x2C, 0xEC, 0xF5, 0xC4, 0xB4, 0xB4, 0xCC, 0x6C, 0xF5, 0xC4, 0xB4, 0xB4, 0xB5, 0x68, 0xE6, 0x38, 0xCA, 0xEC, 0xF5, 0xC4, 0xB4, 0xB4, 0x24, 0x1B, 0xF8, 0x04, 0x37, 0x38, 0xCA, 0x6D, 0xF5, 0xC4, 0xB4, 0xB4, 0x24, 0x1B, 0x7D, 0x85, 0x42, 0xB4, 0xB4, 0xB4, 0x63, 0xD0, 0xF7, 0xF4, 0xD3, 0xC0, 0x6F, 0xF4, 0x6F, 0x00, 0xBB, 0xC4, 0x38, 0x4C, 0x3F, 0xBD, 0xBD, 0xBD, 0xBD, 0xBD]
assert len(a) == 1152
for i in range(len(a)):
a[i] = ror8(a[i], 5)
rng = WindowsRand(0xdeadbeef)
def get_next_dou():
x = rng.rand() % 20
y = rng.rand() % 20
return x, y
def up_encode(a):
r = deepcopy(a)
for i in range(len(r)):
r[i] -= 102
r[i] &= 0xff
return r
def down_encode(a):
r = deepcopy(a)
for i in range(len(r)):
r[i] = ror8(r[i], 5)
return r
def left_encode(a):
r = deepcopy(a)
r = r[6:] + r[:6]
return r
def right_encode(a):
r = deepcopy(a)
for i in range(len(r)):
r[i] += 0x1e
r[i] &= 0xff
return r
def is_right(a):
true_result = bytes([0x9C, 0x06, 0xC0, 0x8F, 0x88, 0x2D, 0x79, 0x81, 0xE9, 0x1D, 0x66, 0x33, 0x64, 0xCE, 0x5E, 0x2E])
re = md5(bytes(a)).digest()
return re == true_result
然后算法不会写,长大后再学习,先放这里了。
remem
能直接运行但是不能直接拖入ida,稍微修复一下elf头,前十六个字节从cat搬过来就行了。
有一个syscall -> clone 是为了检查flag{前缀的,无关紧要
from regadgets import *
from z3 import *
from typing import List
from struct import unpack
def byte2dword_big(x: List[int]):
if len(x) % 4 != 0:
if type(x) == bytes:
x += b'\x00' * (4 - (len(x) % 4))
else:
x += [0] * (4 - (len(x) % 4))
return [v[0] for v in (unpack('>I', bytes(x[i:i+4])) for i in range(0, len(x), 4))]
x = [BitVec(f"x{i}", 32) for i in range(5)]
s = Solver()
# a1 = 4138516404
# a2 = 774266043
# a3 = 4083938303
# a4 = 420409376
# a5 = 25624236
a1, a2, a3, a4, a5 = x[0], x[1], x[2], x[3], x[4]
# s.add(a5 & 0xff == ord('}'))
# a1, a2, a3, a4, a5 = byte2dword_big(b'l@`0JK+KL^(EZw\\*I0Te')
# a1, a2, a3, a4, a5 = 1130446384, 1580411220, 1079910944, 1028674135, 1782732379
b1=a1*a1*3
b2=a1*a2*6
b3=a2*0x52
b4=a2*6
b5=a1*a1*2
b6=a2*0xd
b7=a1*0x11
b8=a1*a3*5
b9=a3*a3*5
b10=a3*0x58
b11=a3*a4*4
b12=a3*a3*5
b13=a4*0xe8
b14=a4*a4*0x23
b15=a5*8
b16=a5*a5*16
# print([hex(i & 0xffffffffffffffff)[2:] for i in [b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,b16]])
enc = [1] * 5
enc[4] = 0x555CC98C
enc[3] = 0x1EBFA92F
enc[2] = 0x509A3978
enc[1] = 0x35368926
enc[0] = 0x42DB9F06
# enc = [i & 0xffffffffffffffff for i in enc]
# s.add((a5*a5*16) & 0xffffffff + (a5 * 8) & 0xffffffff - (a4 * a4 * 35) & 0xffffffff == enc[0])
# s.add((a4*232) & 0xffffffff + (a3*a3*5) & 0xffffffff - (a3*a4*4) & 0xffffffff == enc[1])
# s.add((a3*88) & 0xffffffff + (a3*a3*5) & 0xffffffff - (a1*a3*5) & 0xffffffff == enc[2])
# s.add((a1*a1*2) & 0xffffffff + (a2*13) & 0xffffffff + (a1*17) & 0xffffffff == enc[3])
# s.add((a1*a1*3) & 0xffffffff + (a1*a2*6) & 0xffffffff + (a2*82) & 0xffffffff + (a2*6) & 0xffffffff == enc[4])
# print(hex((b16 + b15 - b14) & 0xffffffffffffffff))
# print(hex((b13 + b12 - b11) & 0xffffffffffffffff))
# print(hex((b10 + b9 - b8) & 0xffffffffffffffff))
# print(hex((b7 + b6 + b5) & 0xffffffffffffffff))
# print(hex((b3 + b4 + b2 - b1) & 0xffffffffffffffff))
# print(hex((b16+b15-b14) & 0xffffffffffffffff))
# print(hex(((b16+b15-b14) & 0xffffffffffffffff) % 0x5E2F4391))
# print(hex(((b13+b12-b11) & 0xffffffffffffffff) % 0x5E2F4391))
# print(hex(((b10+b9-b8) & 0xffffffffffffffff) % 0x5E2F4391))
# print(hex(((b7+b6+b5) & 0xffffffffffffffff) % 0x5E2F4391))
# print(hex(((b3+b4+b2-b1) & 0xffffffffffffffff) % 0x5E2F4391))
# print(hex((b13+b12-b11) % 0x5E2F4391))
s1 = ((b16+b15-b14) & 0xffffffffffffffff) % 0x5E2F4391
s2 = ((b13+b12-b11) & 0xffffffffffffffff) % 0x5E2F4391
s3 = ((b10+b9-b8) & 0xffffffffffffffff) % 0x5E2F4391
s4 = ((b7+b6+b5) & 0xffffffffffffffff) % 0x5E2F4391
s5 = ((b3+b4+b2-b1) & 0xffffffffffffffff) % 0x5E2F4391
S1 = s5 ^ enc[0]
S2 = S1 ^ s4 ^ enc[1]
S3 = S2 ^ s3 ^ enc[2]
S4 = S3 ^ s2 ^ enc[3]
S5 = S4 ^ s1 ^ enc[4]
# s.add((s1 ^ s2 ^ s3 ^ s4 ^ s5 ^ enc[0] ^ enc[1] ^ enc[2] ^ enc[3] ^ enc[4]) == 0)
s.add(S5 == 0)
# print('S', hex(S1))
# print('S', hex(S2))
# print('S', hex(S3))
# print('S', hex(S4))
# print('S', hex(S5))
def z3_all_bv_is_printable(solver: Solver, var: List[BitVecRef]) -> None:
for v in var:
for i in range(v.size() // 8):
solver.add((v >> (i*8)) & 0xff >= 0x20)
solver.add((v >> (i*8)) & 0xff < 0x7f)
z3_all_bv_is_printable(s, x)
for m in z3_get_models(s):
r = b''
re = []
for i in x:
r += l2b(m[i].as_long())
print(r)
# ((0x3434B5358+b14+a5)-b13)//0x5E2F4391
# 0x42DB9F06 ,0x35368926,0x509A3978,0x1EBFA92F,0x555CC98C
我们写z3来约束,但是...如果
s.add(S1 == 0)
s.add(S2 == 0)
s.add(S3 == 0)
s.add(S4 == 0)
s.add(S5 == 0)
那么就会unsat,如果按程序的只检查S5就会无穷组解,不是很懂是z3的问题还是我的问题,我看别人队伍好像是用SageMath求解(tql),但是目前还不会,长大后再学习,复现出来了更新blog。
boxxx
1是墙壁,0是通路,3是箱子,4是箱子要去的地方,2是初始点
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 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 3 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 2 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 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
第0层
13
wwaaddssaaaww
0 0 0 0 0 0 0 0 0 0 0 0 0 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 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 2 0 0 3 0 0 0 4 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0
0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0
0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 0
0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 0
0 0 1 0 0 0 3 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 4 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
第1层
50
ddddddsdddddddssaaaassssaaaassaassdawwddsssdsaaaaa
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 0 3 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 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 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
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 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
第2层
78
aawwwwwwaaaaawwwaaaaaasdwdsswddddssaaaaaaaddddddddddddssaaaaasaaaaaaaawwwwwwww
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 3 0 0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 0 0 0 2 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
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 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
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 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
第3层
16
wwaaaaaaaaaasaww
-------------------------------------------------------------------------
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 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1
1 0 0 0 1 0 0 0 1 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 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 0 0 0 0 0 0 4 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 1
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1
第4层
47
wwaaaaaaaaadddddddddssaaaaaaaaaawwwawdddddddddd
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1
1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 0 1
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 1
1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 3 0 1 0 0 1
1 1 1 1 1 1 1 1 4 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
第5层
54
dddddwwaaaaaaaaaaaaadddddddddddddssssssssssassdsaaaaaa
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 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 2 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1
1 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1
1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1
1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 0 1
1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 0 1
1 0 1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 0 1
1 0 0 0 3 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1
1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
第6层
68
aaaasssssaaaassssdddddddddddawwwddddwwdddssassaaaassssdsaaaaaaaaaaaa
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 2 0 0 3 0 0 1
1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1
1 0 1 0 1 4 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 0 1
1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 1
1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1
1 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 1 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 0 1
1 0 0 0 3 0 0 0 0 0 0 0 0 0 0 4 1 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1
1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
第7层
145
aaaaaaaassaassssssdaaassddddwwwwwsssaawwwwwwddddddddddddddwwaaaaaaaaaaaaaaaddddddddddddddddssssssssssssssssssaaaaaaaaaaaaaaaaawwwwwwddddddddddddd
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 0 0 0 0 0 1 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1
1 0 0 0 1 0 1 3 0 0 1 0 1 0 0 0 1 0 0 1
1 1 1 1 1 0 0 2 1 1 1 0 1 0 1 0 1 0 0 1
1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 1
1 0 1 1 1 1 1 4 1 0 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 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
第8层
21
aasaaaasssssddwwwddddddwwddwwwwaaaassss
恭喜你完成本次关卡!※
flag是每个关卡中每个箱子移动的最短的次数拼接的md5码值和几个字符,1.flag{四个字符_md5值},2.注意同一张图箱子不一定只有一 个哦3.同一关需要计算所有箱子的总的最小移动次数,将每一关的最短次数拼接 解释:例如第一关是3第二关是5,就是md5(35...)
大脑出了一点问题,看成人走的个数了,上文中所有个数均是最短但是不是题目问的。。。
题目中的四个字符是从后面几张map提取的
from regadgets import *
maze = byte2dword(open('maze.bin', 'rb').read())
for k in range(0, 13, 1): # 最后四张地图是字符
for i in range(0, 20, 1):
for j in range(0, 20, 1):
print(maze[400*k + i*20+j], end=' ')
print('')
print('----------------------')
不出意外就是qwb!
之后复现了,一次就成功了
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 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 3 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 0 0 0 0 2 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 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
0 1 1 0 0 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 1 1 1 1 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
第0层:2次
0 0 0 0 0 0 0 0 0 0 0 0 0 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 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 2 0 0 3 0 0 0 4 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0
0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 1 0
0 0 1 1 1 1 1 0 0 0 1 0 0 0 1 1 1 1 1 0
0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0
0 0 1 0 0 0 1 0 1 1 1 0 0 0 1 1 1 1 1 0
0 0 1 0 0 0 3 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 1 1 1 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 0 4 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 1 0
0 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
第1层: 12次
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 0 3 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 * 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 1
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 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 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
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 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
第2层:13次
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 3 0 0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 0 0 0 0 2 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0
1 0 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
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 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
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 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
第3层:9次
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 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 1
1 0 0 0 1 0 0 0 1 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 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 0 0 0 0 0 0 4 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 1
1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 1
第4层:
21次
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1
1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1 0 0 1
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 0 1
1 0 1 1 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 1 1 1 1 1 0 1 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 0 0 3 0 1 0 0 1
1 1 1 1 1 1 1 1 4 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
第5层:
13次
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 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 2 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 0 1
1 0 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 0 1
1 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 1 1 0 1
1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 1
1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 1 1 0 1
1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 0 0 1
1 0 1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 0 0 1
1 0 0 0 3 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1
1 1 1 1 1 0 1 1 1 1 1 0 1 0 1 0 0 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 1
1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 0 0 1
1 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
第6层:
25次
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 4 0 0 0 0 0 0 0 0 0 0 0 2 0 0 3 0 0 1
1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 0 0 1
1 0 1 0 1 4 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 0 1 0 1 0 1 0 0 1
1 0 1 0 1 0 1 0 0 0 1 0 1 0 1 0 1 0 0 1
1 0 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1
1 0 0 0 3 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1
1 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 0 0 0 0 0 1 0 0 0 0 1 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 0 1
1 0 0 0 3 0 0 0 0 0 0 0 0 0 0 4 1 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 1
1 0 1 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 1
1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
第7层
31次
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 0 0 0 0 0 1 0 0 0 0 1
1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 0 1 1 1 0 1 1 1 1 1 1 0 1
1 0 0 0 1 0 1 3 0 0 1 0 1 0 0 0 1 0 0 1
1 1 1 1 1 0 0 2 1 1 1 0 1 0 1 0 1 0 0 1
1 0 0 0 0 0 1 0 1 0 0 0 0 0 1 0 1 0 0 1
1 0 1 1 1 1 1 4 1 0 1 1 1 1 1 1 1 0 0 1
1 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1
1 0 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1
1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1
1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1
1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 0 1
1 0 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 1
1 0 1 0 0 0 0 0 0 0 0 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
第8层
3次
md5(212139211325313)
flag{qwb!_fec2d316d20dbacbe0cdff8fb6ff07b9}
Solve2.apk
没出,因为没时间了,如果多给10分钟就行。
纯java,然后是恶心的混淆,JEBPro直接调试,然后可以发现有一个数组里有两个Box,256大小,然后网上搜索这个可以找到Twofish加密算法。
网上搜了一下Twofish Java,发现基本上和这个东西一样
https://android.googlesource.com/platform/tools/base/+/master/jobb/src/main/java/Twofish/Twofish_Algorithm.java
我们可以观察一下,发现缺陷在这里,这里传入两个key部分,然后进行了一些操作,我们直接用GDA Pro来进行Frida Hook,拿到key是 bytes(range(16))
接下来就是获取enc了,我们把控制流混淆的==全部用正则表达式清掉,然后再搜==,就发现有且仅有一处了,然后JEBPro调试smali,有个if-eq,直接看v2数组的值就是enc,我们就可以twofish解密,得到第一组flag(前16字节),然后把第一组flag输入程序(忘了说了这个之前还有一一段文本以>结尾,是tea加密,我们要把flag放在>之后),然后过前16字节检查,再去断if-eq,可以拿到第二组的加密后flag,结果我twofish解不出来,这时距离比赛结束只有20s了,似了。
赛后对源码进行搜索,找到个异或,应该就是简单的异或,当时如果用测试用的输入异或enc,直接就能出了,可惜时间不够,遗憾。
Tip:赛后别人说是RC4。