from pwn import *
from Crypto.Util.number import long_to_bytes
def compare(a, b):
a, b = bytes.fromhex(a), bytes.fromhex(b)
diff = 0
for i, j in zip(a, b):
if i != j:
diff += 1
return diff
def index_diff(a, b):
a, b = bytes.fromhex(a), bytes.fromhex(b)
pos = []
for i in range(len(a)):
if a[i] != b[i]:
pos.append(i)
return pos
ticket = 'ticket{foxtrot294921delta3:GD1KWFvlJJN0ge3qaEddP9Olmir30Q5z7V67AmZ_e1b8RtSz61E8uIlvDpuCSGS6pw}'
conn = connect('black_hole.satellitesabove.me', 5300)
conn.sendafter('Ticket please:' , f'{ticket}\n')
enc = conn.recvline_contains('Encoded msg is: ').decode().split(' ')[-1]
# 获取编码消息的长度
enc_len = 0
for i in range(140, 0x100): # 经过测试,待求消息的长度基本在 140 及以上
conn.sendafter('Msg:', f'{"01" * i}\n')
res = conn.recvline().decode().strip()
if compare(enc, res) <= i:
enc_len = i
print(f'Length: {i}')
break
# pre: 消息 b'\x01' * enc_len 的编码结果,便于确定明文各个位在编码结果的位置
# pos_map: 明文各个位置与十六进制字符串的位置映射
# first_map: 明文各个位置高八位的编码映射表 0x0_ - 0xf_
# second_map: 明文各个位置低八位的编码映射表 0x_0 - 0x_f
pre, pos_map, first_map, second_map = res, [-1] * enc_len, {}, {}
for i in [0x02, 0x10, 0x21, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff]:
s = long_to_bytes(i) * enc_len
conn.sendafter('Msg:', f'{s.hex()}\n')
res = conn.recvline().decode().strip()
pd = index_diff(res, pre)
for j in pd:
p = j * 2
if p in first_map:
first_map[p][res[p]] = (i & 0xf0) // 0x10
else:
first_map[p] = {res[p]: 0}
if p in second_map:
second_map[p][res[p + 1]] = i & 0xf
else:
second_map[p] = {res[p + 1]: 2}
# 获得编码结果各个位置与明文值的映射关系后,就可以构造明文来确定位置的映射关系
for i in range(0, enc_len, 0x10):
s = bytearray(b'\x01') * enc_len
for j in range(min(0x10, enc_len - i)):
s[i + j] = 0x10 + j
conn.sendafter('Msg:', f'{s.hex()}\n')
res = conn.recvline().decode().strip()
pd = index_diff(res, pre)
pos, sm = [], []
for j in pd:
p = j * 2
pos.append(p)
sm.append(second_map[p][res[p + 1]])
for j, k in zip(sm, pos):
pos_map[i + j] = k
s = bytearray(b'\x00') * enc_len
for i in range(enc_len):
s[i] = first_map[pos_map[i]][enc[pos_map[i]]] * 0x10 + second_map[pos_map[i]][enc[pos_map[i] + 1]]
conn.sendafter('Msg:', f'{s.hex()}\n')
conn.interactive()
# Satellite-link synced! Flag: flag{foxtrot294921delta3:GEPzPQGVu-6MW0Ly8t6rSDotRhMZUOVCgnp-lcMPJbIiuvNwfH2MeDjkChz6vPvg8Hn6sGWG2i_8XroCUhRsIE4}