2025 ciscn 威胁检测与网络流量分析


2025 ciscn 威胁检测与网络流量分析

忘记那时候写了啥了,重新做一下

Kiwi

李华的电脑被植入了恶意程序,恶意程序发送了一个流量包,请你尝试根据截获的流量和病毒样本程序,获取 Windows 用户 Lihua 的登录密码。最终提交格式为为 NTLM 解密后的密码,格式为 flag{password}

流量直接筛选

(((http) ) && (ip.src == 192.168.206.1)) && !(http.response.code == 404)

这个只筛选到 3 个有回显的数据包

image

数据就是加密过了,然后就是要分析恶意程序

image这里就尝试一下全靠 ai 做简单逆向

先将主程序发送给 ai ,ai 给到提示是加密函数是 sub_140082974

跟进将代码给到 ai,得到加密方式是 base64 + xor

先找 base64 的字符表,word_140111070 跟进之后将数据给到 ai

d+F3DwWj8tUckVGZb57S1XsLqfm0vnpeMEzQ2Bg/PTrohxluiJCRIYAyH6N4aKO9

然后异或是根据一个字符串计算出一个 seed 的,先找到字符串 word_140111152 然后计算 seed 这里 ai 自己算的我就一直相信了,结果他算的是错的导致一直出问题,这种要跑的还是得自己跑一下

# calc_seed.py
# 计算 Mimikatz 加密的 XOR 种子(基于字符串 "xedSeed")

# ------------------------------
# 1. 种子表(UTF-16LE 编码的 "xedSeed")
# ------------------------------
seed_table_hex = "69 00 78 00 65 00 64 00 53 00 65 00 65 00 64 00 00 00"
# 转为字节
table_bytes = bytes.fromhex(seed_table_hex)

print(f"[+] 种子表 (UTF-16LE): {seed_table_hex}")
print(f"[+] 字节: {table_bytes.hex(' ')}")

# ------------------------------
# 2. 种子生成算法(与 sub_140082974 完全一致)
# ------------------------------
v5 = 70  # 初始值 'F'
v6 = 0   # 累加器(最终种子)
v8 = 1   # 计数器 i
v7 = 0   # 表索引

print("\n[+] 逐轮计算过程:")
i = 1
while True:
    print(f"  轮次 {i:2d}: v5 = 0x{v5:02X} ('{chr(v5) if 32 <= v5 <= 126 else '?'}'), "
          f"v8 = {v8}, v6 = {v6} ", end="")
    
    v6 = (v6 + v8 * v5) % 256
    print(f"→ v6 = {v6}")
    
    # 读取下一个 WCHAR 的低字节
    if v7 >= len(table_bytes):
        break
    v5 = table_bytes[v7]
    v7 += 2  # 跳过高位 00
    v8 += 1
    
    if v5 == 0:
        break

# ------------------------------
# 3. 输出最终种子
# ------------------------------
print("\n" + "="*50)
print(f"  最终种子 (srand 输入): {v6}")
print(f"  十六进制: 0x{v6:02X}")
print(f"  十进制: {v6}")
print("="*50)

# ------------------------------
# 4. 验证:生成前 10 个 rand() % 128
# ------------------------------
def vc_rand(state):
    state = (state * 214013 + 2531011) & 0xFFFFFFFF
    return (state >> 16) & 0x7FFF, state

print("\n[+] 前 10 个 rand() % 128 值(用于调试解密):")
state = v6
for i in range(1, 11):
    r, state = vc_rand(state)
    print(f"  [{i:2d}] rand() = {r:5d} → %128 = {r % 128}")

得到最后的种子是 105

image

然后就有了最终解密脚本

# final_decrypt.py
b64_str = "l1Mvs8wZ1LI/v3Vup1zF8bzdp1B51zz0e0xdfIXNBQMOe1wFEg+Z03ljczfC1qGdp0Y6bWnJ7rUqnQrZmVT9nFPRXqYpURBxuBKInjI5Q2xVgs56q4VRCQWbiyv00Aw7D0CKEotHSy6sQAC1x3T9wDx6xPCioqx/0nwNgrvJnF1Oq7NFZsVpnAxaZC5BVfKSEttFPjYgv3uSfmtxeJg7pPCHmJ8qf/Sd7W7n3gKSB2BELb=="

CUSTOM_B64_TABLE = 'd+F3DwWj8tUckVGZb57S1XsLqfm0vnpeMEzQ2Bg/PTrohxlu iJCRIYAyH6N4aKO9'.replace(' ', '')
b64_map = {c: i for i, c in enumerate(CUSTOM_B64_TABLE)}

SEED = 105

def vc_rand(s):
    s = (s * 214013 + 2531011) & 0xFFFFFFFF
    return (s >> 16) & 0x7FFF, s

# Base64 解码
dist = bytearray()
i = 0
while i < len(b64_str):
    chunk = b64_str[i:i+4]
    if len(chunk) < 4: break
    v = [b64_map.get(c, 0) if c != '=' else 0 for c in chunk]
    dist.append((v[0] << 2) | (v[1] >> 4))
    if chunk[2] != '=': dist.append(((v[1] & 0xF) << 4) | (v[2] >> 2))
    if chunk[3] != '=': dist.append(((v[2] & 0x3) << 6) | v[3])
    i += 4

# 逆扰乱
state = SEED
plain = bytearray()
for b in dist:
    r, state = vc_rand(state)
    c = (b - (r % 128)) & 0xFF
    c ^= SEED
    plain.extend([c, 0])

text = plain.decode('utf-16le', errors='replace')
print(text)

最后找个网站解密一下

image

flag{memeallme!}

image

sxmisc

先看流量包,学到了原来协议分级是能看到有 MIME 信息的,这个一般是电子邮件或者文件上传中会用到

image

或者直接找 post 请求,这个流量就是太大了,导致查数据都很麻烦,这里也能看到第二个数据有 jpg 文件

image

导出来是一个图片,然后就是分析日志

thisisthepassphrasebobknowsbutyoudontknow

image

可以看到有很多数据库的请求

image

写脚本处理这里的 sql 盲注数据

import urllib.parse
import csv
import re

with open ("access.log","r")as file:
    data = file.readlines()
    sql = []

    for line in data:
        log = {}
        http = line.split("\"")
        log['url'] = http[1]
        log['size'] = http[2]
        log['ua'] = http[5]
        if "publishers.php" in log['url'] and "sqlmap" in log['ua']:
            log['url'] = urllib.parse.unquote(log['url'])
            pattern = r'SUBSTR\(\((.*?)\),(\d+),(\d+)\)(.)CHAR\((\d+)\)'
            match = re.search(pattern,log['url'])
            if match:
                log['pos'] = int(match.group(2))
                log['char'] = int(match.group(5))
                log['sql'] = match.group(1)    
                sql.append(log)


# 将数据按照最后的符号分组
group = {}
for item in sql:
    pattern = r'-- [a-zA-Z]{4}'
    match = re.search(pattern,item['url'])
    if match:
        sign = match.group(0)[-4:]
    else:
        sign = "no sign"
    if sign not in group:
        group[sign] = {}
        group[sign]['item'] = []
        group[sign]['item'].append(item)
    else:
        group[sign]['item'].append(item)

# 处理二分法
result = {}
for sign in group:
    group[sign]['result'] = {}
    for i in group[sign]['item']:
        pos = i['pos']
        char = i['char']
        
        current = group[sign]['result'].get(pos)
        if current is not None:
            if '412' in i['size'] and char <= current:
                group[sign]['result'][pos] = char
        elif '412' in i['size']:
            group[sign]['result'][pos] = char
    group[sign]['flag'] = ""    
    for key,value in group[sign]['result'].items():
        group[sign]['flag'] += chr(value)
        

for sign in group:
    print(group[sign]['item'][1]['sql'])
    print(sign,group[sign]['flag'])


csv_data = []
header = ['目标SQL查询', '还原数据']
csv_data.append(header)

for sign in group:
    sql_query = (group[sign]['item'][1]['sql'])
    data = (sign,group[sign]['flag'])
    csv_data.append([sql_query,data])

with open('result.csv', 'w', encoding='utf-8-sig', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerows(csv_data)

最后找到这个用户的信息

SELECT COALESCE(CAST(priv_key AS TEXT),CHAR(32)) FROM accounts LIMIT 1,1
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC3TBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQI6LGnQ3HdqfwCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAb/JvhvID2VUpp6asXZv+ZBIIC
gK6Hy9Qu0rt76gqlFkvFY9qWnSyFnyE2hk2egjOHOxaJFWUd5hZcO5Of8zJIgpr+
cfhgNZJlEC02k1drfc72ql2IYGf+3Q60TqeiV/fxH0QMmyklrJVp9F2nnBaV2cGA
rWvWTaR0+ukVvg6rtc5ayDcuCOp0MBqo7gvS1OPkDtbKD/MjbZpE5QstFcZBW22A
/sJS128R5T626BWUq/HEM34hYNh3RyDm9CDLyRYrgRs5zUhl8qE3i2hTWfW+Ak9s
kWdKgbD9ERh9j/qV1lN45jIPpTaqYSsxymcRmSu+LFKwTvMnJ8UgKOQKvnsSApU5
+XcaUCXwZH2MuVNK0qHhpiCu6BH+yJgDkGQ1ZCfRo09dsYz2aYzAeUMwzflZQEbB
nLvznN9MrcHvTvmvz0qzCz7LvV8UwaY83eJIScFCTFCmJp8qY3PYF7HnfrPszSD0
eBthcb2PUftOmbcsuas6843S1V2q+OrZHFcneB7515xVjD/WeaZ2e9BcFqWZ8zuW
RnEHL8L7wgVnNlj3b4g2nykknUeKbIlQccXcKuSR73j4qVwOfPdsaHmMsumNfxYl
DkFl2p9jF2Ha7BDpxhepNK3qf9PWhXZRCC0BXGPqGezvSgGXC3SDotcJPeKF8RME
JlntDDZjgDmYMEDBr+Vm7ceuwMWJTcTGrk4j5yeQp21B5lc1EcnDKHHznbwFFfKo
PpAASnBdyEAA2nKaN0WZYZuiYUbqxKZoPEZjPS/7iUaK40ZJnpIVtISNWNM4ITeq
rpkmqBTF8e4/+iCCjWFHMQ3umRGWetm9QG0kIsaCt/fYXj70dkD5S9C9MUpkCZZC
wGyrLnTG5NImbaKHLqDRTC8=
-----END ENCRYPTED PRIVATE KEY-----


SELECT COALESCE(CAST(acc_flag AS TEXT),CHAR(32)) FROM accounts LIMIT 1,1
Z5WpwbZZZXn9n/PAFHeowh9BxYHq7KupFO2ULeH/gkDNATbcxzO6KRBB9zDW23F5
uRODyT1+y0z3iMv6//SOYnQqF1NH4S2CQxOXK7KnXQwnKXMBU2Wp3giNPFcvOvgX
83fJasMKIpjhYw9Jja9DcEoKz4ZEe5LWI3YpgU7Kz0A=

image

这里是用前面图片的密码解密私钥,但是这里其实没懂为什么是 rsa(

openssl rsa -in en.pem -out privkey.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDBy6W/kXdOZet6aQXxTvCeIaWnzc7uiHQinK02LAIvl5/8dbAV
GoiPIKtL8wX6MFEIWOGh/MkuBBR3h7w8VrYM5R1gXNI2uTNkTs4c77+AzdLj1T1P
JOD8yOUZ/azztomzb8mQP8Ya+ZKguMmeRMPC+Yxqe0f/T/5b43bTUxqZAwIDAQAB
AoGAU+075NC8mGkvJ54gArcrIXB0600IFullUjAEG3fHopDJqm3VSe5pwYJmbMfc
iNMv5KuJW7u77H+71WAlNwReZkoMsC4cWuKHpQKZncvd125K0W7+TvljAKjawiVO
EwKx2ChencaoYXO8PmC8RlR23z1Amaw3xZVwRtqzbKEqjjECQQDqjEugpJP9IwjL
UVHA6kFilMO2TsUQtYtu1T+JKityX26JMMGTawsUl/8/3WGfUET1qbwu/Mcj2yKr
D2UII0CvAkEA04UsO8R97QTDHOP+ovUKM20H6dNWAE7tH3A/efBVfcs/MsVq/jMx
jig73U6rXeCP9qVWfe0AGCtEO9Q71Kt57QJAI1Sez8P6xtbQLFBDkFu5HbBrCrsy
1CGEr11QBMllYgUeEWxWvG4TbTa4LFacrfLZcGfxAOLy3GPWBQ58mY014QJBALkS
JpfM3tmJdyZKHrx6ZoiEd44RiYgPhs4hKokIzeSY9xz3OxxbsppNfcOvV6V2HMCT
/c+ElLaQ9Mzcb9UujCkCQB83SiCyM2R25J66gLo9OlJpu0hN4HKnQS/59KSttLRQ
5cRBOn3cdR/q/exxegBTmigbuOgvhZ8iiOwp/pTiI2Q=
-----END RSA PRIVATE KEY-----

然后解密 flag,不知道为什么最后死活解不出来

解出来了,是用错 flag 数据了 orz

image

sc05

近日某公司网络管理员老张在对安全设备进行日常巡检过程中发现防火墙设备日志中产生了1条高危告警,告警IP为134.6.4.12(简称IP1),在监测到可疑网络活动后,老张立刻对磁盘和内存制做了镜像。为考校自己刚收的第一个徒弟李华,老张循序渐进,布置了5道问题。假如你是李华,请你根据提供的防火墙日志、磁盘镜像及内存镜像文件对主机开展网络安全检查分析,并根据5道问题提示,计算并提交相应flag。

问题1:IP1地址首次被请求时间是多久?计算内容如:2020/05/18_19:35:10 提交格式:flag{32位大写MD5值}

在 http 表中找到了一个访问的时间

2024/11/09 16:23:57

image

然后在 tcp 表中还有 4 个,最早的应该就是这个

2024/11/09 16:22:42

image

问题2:IP1地址对应的小马程序MD5是多少?提交格式:flag{32位大写MD5值}

问题3:大马程序运行在哪个进程中?计算内容:PID-进程名,如123-cmd.exe 提交格式:flag{32位大写MD5值}

通过命令 列出可能包含注入代码的进程内存范围

volatility3/vol.py -f question/Windows\ 10\ x64-Snapshot13.vmem windows.malfind

这里找到的这个就是,但是这里有 4 个结果,一个个试应该也行(

image

问题4:大马程序备用回连的域名是多少?计算内容如:www.baidu.com 提交格式:flag{32位大写MD5值}

问题5:攻击者最终窃取数据的文件中包含的flag值? 提交格式:flag{xxx},注意大小FLAG{xx}要转换为小写flag{xx}

zeroshell

小路是一名实习生,接替公司前任网管的工作,一天发现公司网络出口出现了异常的通信,现需要通过回溯出口流量对异常点位(防火墙)进行定位,并确定异常的设备。然后进行深度取证检查(需要获取 root 权限)。现在需要你从网络攻击数据包中找出漏洞攻击的会话,分析会话编写 exp 或数据包重放获取防火墙设备管理员权限,查找防火墙设备上安装的木马,然后分析木马外联地址和通信密钥以及木马启动项位置。

1.从数据包中找出攻击者利用漏洞开展攻击的会话(攻击者执行了一条命令),写出该会话中设置的 flag, 结果提交形式:flag{xxxxxxxxx}

在 243 流找到了这个攻击会话,然后看到在 Referer​ 有一个熟悉的 Zmxh

flag{6C2E38DA-D8E4-8D84-4A4F-E2ABD07A1F3A}

image

2.通过漏洞利用获取设备控制权限,然后查找设备上的flag文件,提取flag文件内容,结果提交形式:flag{xxxxxxxxxx}

按照他流量包请求的方式发包

image

image

c6045425-6e6e-41d0-be09-95682a4f65c4

最后在 database 中找到了

image

3.找出受控机防火墙设备中驻留木马的外联域名或IP地址,结果提交形式:flag{xxxx},如flag{www.abc.com} 或 flag{16.122.33.44}

这里可以找到一个脚本直接连上去

gougou123-hash/CVE-2019-12725: ZeroShell命令执行漏洞批量扫描poc+exp

image

直接 netstat​ 就能发现一个奇怪的 IP 202.115.89.103

image

4.请写出木马进程执行的本体文件的名称,结果提交形式:flag{xxxxx},仅写文件名不加路径

这个本来想找网络连接对应的程序的,但是没有找到,这里在原本找到 flag 的地方看到一个 .nginx 文件,而且很大

image

这个还是一个 elf 文件

image

rstudio 中下载下来,然后丢到沙箱中

image

可以发现外联 IP 是一样的,那就是这个文件

image

5.请提取驻留的木马本体文件,通过逆向分析找出木马样本通信使用的加密密钥,结果提交形式:flag{xxxx}

这题跟着 ai 一步步分析,先在 main 函数中跟进 sub_804D9A4 ,会发现这个是加密主逻辑

image

然后在这里 ai 能找到这个 off_81130C0 是会发送过去的

image

跟进就能发现这个就像密钥 11223344qweasdzxc

image

6.请写出驻留木马的启动项,注意写出启动文件的完整路径。结果提交形式:flag{xxxx},如flag{/a/b/c}

将这个文件夹中的内容都导出来,然后用 vsc 全局查找

image

答案就是这个了
\var\register\system\startup\scripts\nat\File

image

WinFT

某单位网管日常巡检中发现某员工电脑(IP:192.168.116.123)存在异常外连及数据传输行为,随后立即对该电脑进行断网处理,并启动网络安全应急预案进行排查。

1、受控机木马的回连域名及ip及端口是(示例:flag{xxx.com:127.0.0.1:2333})

打开 currports,就能发现一个很奇怪的进程,找到这个文件拖出来

image

沙箱分析,结合这个工具,答案就是

miscsecure.com:192.168.116.130:443

image

2、受控机启动项中隐藏flag是

用桌面的 pchunter 就能看到 flag

image

{AES_encryption_algorithm_is_an_excellent_encryption_algorithm}

image

3、受控机中驻留的flag是

比较神奇,在 everything 中搜索上一题的名字,就可以找到这个文件,是一个 7z 文件,有密码,密码就是那个恶意程序的名字 flvupdate

image

flag{Timeline_correlation_is_a_very_important_part_of_the_digital_forensics_process}

image

4、受控源头隐藏的flag是

桌面有一个 Thunderbird ,我记得那时候也排查了好久的邮件,这里应该先关注有附件的文件,这里看到这个有附件但是没有显示出来,查看这个附件,解压出来的文件丢到沙箱

image

发现这个就是下载木马的元凶,那就重点关注这个发信人

image

将他另一个发的邮件下载下来

image

查看源码

image

这个 key 提出来

image

得到 flag

{The Journey to the West}

image

5、分析流量,获得压缩包中得到答案

在流量中找到一个压缩包,最后的后面一串东西,base64 后用 utf-8 可以看到一个hint

提一嘴,这个 zip 拉出来会显示有问题,但是 winrar 就能修复

image

image

结果这个就是密码(

flag{a1b2c3d4e5f67890abcdef1234567890-2f4d90a1b7c8e2349d3f56e0a9b01b8a-CBC}

image

6、通过aes解密得到的flag

这里看 wp 也没懂是怎么找到的(

先筛选回连 ip ip.addr == 192.168.116.130

不知道是怎么锁定这个就是密文的(

然后工具上一题的答案,
key 是 a1b2c3d4e5f67890abcdef1234567890
iv 是 2f4d90a1b7c8e2349d3f56e0a9b01b8a
模式是 CBC

image

flag{Hey, keep going and look for another flag}

image

参考

2024-CISCN-长城杯-威胁检测与网络流量分析-zeroshell-WP - smileleooo - 博客园

【Volcania】2025 CISCN x 长城杯铁人三项 初赛Writeup | GamerNoTitle


文章作者: Marin
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Marin !
  目录