长城杯2023
# PREFACE:RE 比较容易
# ps. 初赛猛猛做最后是第一,决赛线下直接不会了,赛后仨小时出了 re1 一小时出的 re2,只能说离开网络和 gpt 的 moyaoxue 一事无成
初赛:
# vvm
简单的 vm,opcode 很少直接可以看出来逻辑
enc = [ 126, 120, 117, 127, 107, 82, 117, 114, 109, 119, 78, 121, 121, 121, 119, 68, 98, 36, 96, 113, 115, 96, 53, 105] | |
for i in enc: | |
i ^= 0x16 | |
i -= 2 | |
print(chr(i),end = "") |
# ezSocket
字节码逆向,通信过程的 sm4 和 rsa 都不需要管,只是信道加解密内容,只需要爆破六位 key 对比 sha256 即可
from Crypto.Cipher import DES | |
import string | |
import itertools | |
import base64 | |
import hashlib | |
# import owiener | |
if __name__ == "__main__": | |
charset = string.digits + "" | |
for i in itertools.product(charset, repeat=6): | |
key = ''.join(i) | |
key += 'ffffffffff' | |
key = key.encode() | |
a = hashlib.sha256(key).hexdigest().encode() | |
if (a == b'fdce9fbba473a2e47c14c72a78dcf62a28f0259847d7910ecb18a0af80983693'): | |
print(key) |
决赛
# RE
# file
一个类 lz77 压缩的压缩算法,改变的地方在于滑块长度固定二
具体规则是:建立缓存
每次出现新的双字节(两个 ascii,即滑块长),则在该字节前面加一 bit 的’1’,并存入缓冲区,如果在缓存找到已有,则在前面加 8bit 的’0’,然后下面 8bit 做填充和寻址(在缓存内找到相应的双字节)
(脚本不全,解压部分是手动试的,因为真正压缩的地方只有两处):
a='1011001101011011001011000011011001111011110111001101001011001001011001101001101101001110001001100111011001001001100101001011011001101111011000111001100111001100011001011011001100111001100001001110001011000111001011011011000111001100101001100011001101111001011011001100011011001001001101111011001000000000000110000000000001001000010011010010011010010011001110110001110111110100' | |
i = 0 | |
flag = '' | |
j = 0 | |
while(i< len(a)): | |
if a[i] == '0': | |
i += 1 | |
i += 12 | |
else : | |
i += 1 | |
flag += chr(int(a[i:i+8], 2)) | |
i += 8 | |
print(flag) | |
# flag{4df683d2-7c31-308c-c217-1d7d0817443c} |
# your_emb
一点一点硬看汇编,发现 check 前面有 xor 操作,这里的 xor 应该是 getkey 访问失败返回得到的,即: connection refused
enc = [ 0x05, 0x03, 0x0F, 0x09, 0x1E, 0x5B, 0x12, 0x5C, 0x09, 0x0F, | |
0x10, 0x43, 0x56, 0x4B, 0x17, 0x40, 0x56, 0x55, 0x4E, 0x5B, | |
0x08, 0x5C, 0x57, 0x4E, 0x15, 0x0D, 0x5C, 0x0D, 0x0D, 0x16, | |
0x5C, 0x05, 0x43, 0x41, 0x57, 0x5D, 0x02, 0x59, 0x5D, 0x5C, | |
0x50, 0x1E] | |
key = 'connection refused' | |
for i in range(len(enc)): | |
print(chr(enc[i] ^ ord(key[i % len(key)])),end='') | |
# flag{8f5fa013-b331-4f22-ad3c-d9c6229a6325} |