# 冀信杯 - 日志分析
# -*- coding: utf-8 -*- | |
# @Author : 1cePeak | |
import re | |
import urllib.parse | |
f = open("newlog-2024.log","r") | |
lines = f.readlines() | |
datas = [] | |
for line in lines: | |
t = urllib.parse.unquote(line) | |
if 'LIMIT' in t and 'security' in t and '722' in t and 'Nqtp' in t: | |
datas.append(t) | |
flag_ascii = {} | |
for data in datas: | |
matchOjb = re.search( r'0,1\),(\d+),.+>(\d+)', data) | |
if matchOjb: | |
# print(matchOjb.group(1),chr(int(matchOjb.group(2))+1)) | |
print("key",end=':') | |
key = int(matchOjb.group(1)) | |
print(key) | |
print("value",end=':') | |
value = int(matchOjb.group(2)) | |
print(value) | |
flag_ascii[key] = value | |
print(flag_ascii) | |
flag = "" | |
for value in flag_ascii.values(): | |
flag += chr(value) | |
print(flag) | |
# 8ea72d948d9cceb0a12c34b1c06952606547fdd25d4f6ffad12ab42a858d37fc |
二分查找的 SQL 盲注,返回长度 706 为 true ,722 为 false
找每一位最后出现的 722 长度的记录就是正确值
日志中查了几个表
security.flag:aBvW,压缩包security.aes:Nqtp密钥,dnIk偏移量security.passwd:ybwv,AES 加密后的压缩包密码
AES-CBC
key: 0133456789abbdaf0123446689abadbf
iv: 00000000000000000000000000000000
解压后再次解密 flag
Ly_Flag{oqv_%2d~ivw2855qdis5eo6_^b9orh}
# 冀信杯 - 数据窃取
冰蝎 shell 流量
找关键数据包,740 号,读取了 flag


对应的响应包解 base64

Ly_Flag{82874087f332fe4dffe3a4702632ac621841d2ce0176e30f91e45bb44e768609}
# Beyond
冰蝎 shell,工具直接跑出

flag{404c601a8ca9d44d586f7b93ba236b12}
# 冀信杯 - 流量分析
SQL 注入流量,工具直接跑出

flag{import3nt_use2s_inf0}
# Input Mice
工具直接跑出,然后上下翻转图片

XNUCA{USBPCAPGETEVERYTHING}
# Input Keyboard
2025/05/23 19:59:52
执行的类型: usbhid
执行成功。结果如下:
9<CAP>gr<CAP>gn<CAP>a<DEL>cu2c<CAP>c<CAP>e<CAP>ht<CAP>f<CAP>hj4712<DEL><DEL><CAP>hm<CAP>l<CAP>es<CAP>b<DEL>cc<CAP>x<CAP>h<CAP>r5<CAP>t<DEL><DEL>tg9<CAP>ovii<CAP>pot<DEL><DEL><DEL>7h<CAP>t<CAP>t<CAP>k<CAP>n<CAP>hjrxlk<CAP>v5<DEL><DEL><CAP>c<DEL>4<DEL>/x/zcks<CAP>o<CAP>e<CAP>hbv<DEL><DEL><DEL>tvg<CAP>e<CAP>b8<CAP>a<CAP>c
处理后的结果如下:
9GRgnCU2CcEhtFhj47HMlESccXhRtg9OVII7hTtKnHJRXLK/X/ZCKSoEtvgEb8Ac
删除的字符如下:
A12b5tpotv5C4hbv
AES-ECB,输入的是密文,删除的是密钥
# Be-AES-Waver
N1CTF 2023 Misc - zysgmzb's BLOG
分析流量包,UDP 传输的数据是很多个 WAV 文件
提取所有 UDP 数据
tshark -r challenge.pcapng -T fields -Y "udp" -e udp.payload | sed '/^\s*$/d' > 1.txt
用 foremost 分离
foremost -i 1.txt -o output

一共 131 个 wav 文件,随便打开一个
容易看出来是摩斯密码,7 位一组
用二进制打开,分析出长短音的持续时间有两种

第一种,长音 0x120 字节,短音和位间隔 0x60 字节,每 7 位间隔 0x180 字节

第二种,长音 0xc0 字节,短音和位间隔 0x40 字节,每 7 位间隔 0x100 字节
import wave | |
import os | |
def parse_morse_wav(filename, long_ucnt, short_ucnt, bit_sep, block_sep): | |
# 打开 WAV 文件 | |
with wave.open(filename, 'rb') as wav_file: | |
n_frames = wav_file.getnframes() | |
# 读取所有帧数据 | |
frames = wav_file.readframes(n_frames) | |
# 定义基本单位模式 (00 00 32 33 00 00 CE CC) | |
base_unit = b'\x00\x00\x32\x33\x00\x00\xCE\xCC' | |
base_unit_len = len(base_unit) | |
bit_separator = b'\x00' * bit_sep | |
block_separator = b'\x00' * block_sep | |
pos = 0 | |
bits = [] | |
data = [] | |
while pos < len(frames): | |
if frames[pos : pos + block_sep] == block_separator: | |
if bits: | |
data.append(int(''.join(bits), 2)) | |
bits = [] | |
pos += block_sep | |
elif frames[pos : pos + base_unit_len * long_ucnt] == base_unit * long_ucnt: | |
bits.append('1') | |
pos += base_unit_len * long_ucnt | |
elif frames[pos : pos + base_unit_len * short_ucnt] == base_unit * short_ucnt: | |
bits.append('0') | |
pos += base_unit_len * short_ucnt | |
elif frames[pos : pos + bit_sep] == bit_separator: | |
pos += bit_sep | |
else: | |
break | |
return data | |
long_ucnt1 = 36 | |
short_ucnt1 = 12 | |
bit_sep1 = 96 | |
block_sep1 = 384 | |
long_ucnt2 = 24 | |
short_ucnt2 = 8 | |
bit_sep2 = 64 | |
block_sep2 = 256 | |
if __name__ == "__main__": | |
filenames = os.listdir('./wav') | |
data = [] | |
try: | |
for filename in filenames: | |
decoded_data = parse_morse_wav(f'./wav/{filename}', long_ucnt1, short_ucnt1, bit_sep1, block_sep1) | |
if not decoded_data: | |
decoded_data = parse_morse_wav(f'./wav/{filename}', long_ucnt2, short_ucnt2, bit_sep2, block_sep2) | |
data.extend(decoded_data) | |
print(f"解码: {filename}") | |
except Exception: | |
print(f"解码错误: {filename}") | |
print(data) |
将得到的 ASCII 数组转换成文本,得到一个文章,中间插入了一些花括号括起来的字符
搜索出来一共有 65 处,根据题目名字猜测是 AES 密文,先提取出来
ZJoXMMxKEIxeX5dAEw8wBPbwF47X8P033iIWziLI9kkZ6RKKXBhKlrsqH+i3Bqv3T
现在还缺少密钥,回到 tshark 提取的 UDP 数据,发现每个 wav 文件头前都还有一些数据
有一些是 4 个字节,有一些是 5 个字节
经过验证,只有 5 个字节的情况下的第一个字节是有效的,全部提取出来
import string | |
f = open('1.txt', 'rb').read() | |
for i in range(len(f)-4): | |
if(f[i:i+4] == b'RIFF'): | |
if(chr(f[i-6]) in string.printable): | |
print(chr(f[i-6]),end='') |

得到密钥
P@$Sw0rd1!Y0uGot
直接解密会发现解不了,回到有花括号的文章中,发现第二行后每行开头都会有 Roger! ,但第 43 行没有
这里猜测 Roger! 是对上一行发送的字符进行确认,而 43 行没有对 42 行的 k 进行确认,因此密文对应删掉一个 k
ZJoXMMxKEIxeX5dAEw8wBPbwF47X8P033iIWziLI9kZ6RKKXBhKlrsqH+i3Bqv3T
P@$Sw0rd1!Y0uGot
配置好 AES 参数后成功解密
n1ctf{4c04c98007c5229f86cd2b70643f38d8}
# TxTime
拿到 38 个 txt,内容一样,都是 1124789000 ,发现文件的修改时间比较奇怪
文件修改时间戳减去文件内容即可
import time | |
import os | |
import re | |
T = 1124789000 | |
filenames = [filename for filename in os.listdir('.') if filename.endswith('.txt')] | |
sorted_filenames = sorted(filenames, key=lambda x: int(re.search(r'change(\d+)\.txt', x).group(1))) | |
print(sorted_filenames) | |
data = [] | |
for filename in sorted_filenames: | |
meta_info = os.stat(filename) | |
mtime = time.localtime(meta_info.st_mtime) | |
timestamp = time.mktime(mtime) | |
data.append(int(timestamp) - T) | |
print(data) |

# puzzle picture
2023 第三届 “香山杯” 网络安全大赛|pintu Writeup - 1cePeak
4703 个 png,长度都是 65,只有宽度不相同
import os | |
import base64 | |
from PIL import Image | |
def get_Image_Pixel(image_path): | |
with Image.open(image_path) as img: | |
pixel_data = img.getpixel((0,0))[0] | |
return pixel_data | |
def get_image_dimensions(image_path): | |
with open(image_path, 'rb') as img: | |
img_bytes = img.read() | |
# print(img_bytes[:18]) | |
return int(img_bytes[0x13]), int(img_bytes[0x17]) | |
def height_Steg(): | |
heights = [] | |
current_directory = os.getcwd() | |
for i in range(1, 4704): | |
image_name = f"pintu/{i}.png" | |
image_path = os.path.join(current_directory, image_name) | |
if os.path.exists(image_path): | |
width, height = get_image_dimensions(image_path) | |
heights.append(height) | |
# print(f"{image_name}: Width = {width}, Height = {height}") | |
else: | |
print(f"{image_name} does not exist.") | |
res = '' | |
data = '' | |
for item in heights: | |
decimal_heights = int(str(item),8) | |
res+=chr(decimal_heights) | |
#print(res) | |
res = res.split(' ') | |
for item in res: | |
data +=chr(int(item)) | |
#print(data) | |
data = base64.b32decode(data) | |
print(data) | |
return data | |
def translate_pixel(): | |
res = '' | |
output = [] | |
current_directory = os.getcwd() | |
for i in range(1, 4704): | |
image_name = f"pintu/{i}.png" | |
image_path = os.path.join(current_directory, image_name) | |
if os.path.exists(image_path): | |
pixel_data = get_Image_Pixel(image_path) | |
if pixel_data == 255: | |
res += '1' | |
else: | |
res += '0' | |
if len(res) % 8!=0: | |
# 这里一定要注意是在前面补零还是在后面补零,一般都是在前面补零对齐 | |
# res+='0'*(8-len(res)%8) | |
res = '0'*(8-len(res)%8) + res | |
for i in range(0,len(res),8): | |
binary_segment = res[i:i+8] | |
int_value = int(binary_segment,2) | |
char_value = chr(int_value) | |
output += [char_value] | |
# print(output) | |
print(''.join([str(x) for x in output])) | |
b64data = height_Steg() | |
translate_pixel() | |
b64t = str.maketrans('sUvcu5rgSeAmJQCfdXtEMKIB91Lj3niOo4hyV0b/2azpx8HqZP6wk7GNlTFYDR+W', "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/") | |
dec = b64data.decode('ascii').translate(b64t) | |
print(dec) |



上传到 npiet 解密
https://www.bertnase.de/npiet/npiet-execute.php

flag{4b6c1737-27e5-41c4-95e3-f70ad196063e}
# are you ok
一些蓝牙流量分析 - g0at's Blog
数字中国 2023|数字网络安全人才挑战赛出题思路 - 1cePeak

tshark -r 20230314_101903.log -T fields -Y "btatt.opcode==0x52" -e btatt.value > 1.txt
with open('1.txt', 'r') as f: | |
data = f.readlines() | |
trans = { | |
'00': '.', | |
'01': '-', | |
'02': '/' | |
} | |
print(''.join([trans[b.strip()] for b in data])) |

电量不知道为什么是这个数据包
Handle: 0x7e

0x48 即 72
flag
# hard web
服务器开放了哪些端口,请按照端口大小顺序提交答案,并以英文逗号隔开 (如服务器开放了 80 81 82 83 端口,则答案为 80,81,82,83)
服务器中根目录下的 flag 值是多少?
该 webshell 的连接密码是多少?
筛选源 ip 为服务器的 tcp 流量,查看端口扫描过程中返回了 RST 的即为开放端口
20,21,22,80,81,888,3306,8001,8888
748007e861908c03
flag{9236b29d-5488-41e6-a04b-53b0d8276542}
# 飞驰人生
安装好 ICSim 环境,启动 canplayer 重放后发现过程中转向灯、速度仪表有异常
用 SavvyCAN 分析

188#01000000 # 左转
188#02000000 # 右转
188#03000000 # 双闪

19B#00000E000000 # 开车门
19B#00000F000000 # 关车门


244#000000xx # 第三个字节为速度值
244#000000A60000



关车门及油门为异常操作
flag{19B#00000F000000_244#000000A60000}
# Bubble Fish
2023 年新疆 “天山固网杯” 网络安全技能竞赛|Misc Writeup - 1cePeak
import os | |
import base64 | |
import shutil | |
def base32_decode_filename(filename): | |
# 移除.png 后缀 | |
if filename.endswith('.png'): | |
filename = filename[:-4] | |
# Base32 解码 | |
try: | |
decoded_bytes = base64.b32decode(filename) | |
return decoded_bytes.decode('utf-8') | |
except base64.binascii.Error as e: | |
# Base32 末尾填充 = | |
if "Incorrect padding" in str(e): | |
padded_input = filename + '=' * (8 - len(filename) % 8) | |
return base64.b32decode(padded_input).decode('utf-8') | |
def decode_png_filenames_in_tmp(): | |
b32decode_results = {} | |
tmp_dir = 'tmp' | |
for filename in os.listdir(tmp_dir): | |
if filename.lower().endswith('.png'): | |
decoded_name = base32_decode_filename(filename) | |
if decoded_name: | |
print(f"原始文件名: {filename} -> 解码后: {decoded_name}") | |
b32decode_results[filename] = decoded_name | |
return b32decode_results | |
def decode_filename_number(b32decode_results): | |
cn2number = { | |
'零': '0', | |
'一': '1', | |
'二': '2', | |
'三': '3', | |
'四': '4', | |
'五': '5', | |
'六': '6', | |
'七': '7', | |
'八': '8', | |
'九': '9', | |
'壹': '1', | |
'贰': '2', | |
'叁': '3', | |
'肆': '4', | |
'伍': '5', | |
'陆': '6', | |
'柒': '7', | |
'捌': '8', | |
'玖': '9', | |
'零': '0', | |
'0': '0', | |
'1': '1', | |
'2': '2', | |
'3': '3', | |
'4': '4', | |
'5': '5', | |
'6': '6', | |
'7': '7', | |
'8': '8', | |
'9': '9', | |
} | |
numberdecode_results = {} | |
for item in b32decode_results.items(): | |
number_str = ''.join([cn2number[char] for char in item[1] if char in cn2number]) | |
numberdecode_results[item[0]] = number_str | |
print(f"原始文件名: {item[0]} -> 解码后: {number_str}") | |
os.makedirs('renamed_png', exist_ok=True) | |
for item in numberdecode_results.items(): | |
shutil.copy2(f'tmp/{item[0]}', f'renamed_png/{item[1]}.png') | |
if __name__ == "__main__": | |
dec1 = decode_png_filenames_in_tmp() | |
decode_filename_number(dec1) |
原始文件名先 base32 解码,得到中文数字和字母混合的文件名
混合文件名中提取数字,重新对图片进行排序
数图片中气泡的数量(只算大的或小的),得到一个八进制数据
104101123103124106173041041041146061163150137142165142142154063163137142165142142154063163137146061163150137150141150141150141150141041041041175

# 冀信杯 - 账号泄露
小明发现自己的账号泄露了,他检查了近期的电脑日志找到了黑客创建的登录账号,听说密码是 6 位的,flag 是创建的登录账号和密码拼接的字符串例如:登录账号为 lyflag,密码为 123456,则提交的 flag 值为 lyflag123456
创建用户的事件 ID 为 4720
创建的用户名为
2Ha0c2K34ruiop$
用这个用户名解压 sam.zip ,得到 SAM, SECURITY, SYSTEM 三个注册表文件
可用 securitydump.py 或者 mimikatz 获得密码
python securitydump.py LOCAL -sam sam.save -system system.save -security security.save
mimikatz # lsadump::sam /SAM:sam.save /SYSTEM:system.save

78ea10b3d3d0ae290580778800b4de5d
但是解密不了
附件有问题,Hash 应为 b4a13264d379f697fbc6d0b1a5c1fcf0
根据题目提示 6 位密码
hashcat -m 1000 -a 3 b4a13264d379f697fbc6d0b1a5c1fcf0 ?a?a?a?a?a?a --show |
爆破得到密码 asdf,.
flag{2Ha0c2K34ruiop$asdf,.}
# NTLM
流量包筛选 smb2 协议
在上传 6.png 的时候写入的内容是 7z 压缩包

压缩包提取出来后解压,其中有一个密码字典文件

用工具直接提取 NTLMv2 Hash

hashcat 字典爆破
hashcat -m 5600 administrator:::1166026a7745c2d0:971356880954f778c48937ad52ccae51:01010000000000005a308cd161f7d8016092111fede1fd960000000002001e004400450053004b0054004f0050002d004a0052005500510045003900360001001e004400450053004b0054004f0050002d004a0052005500510045003900360004001e004400450053004b0054004f0050002d004a0052005500510045003900360003001e004400450053004b0054004f0050002d004a00520055005100450039003600070008005a308cd161f7d80106000400020000000800300030000000000000000100000000200000a2fc8de06e3dff62c01429115953f2f8ea32e069bc69837a7b03ee0112ca689a0a0010000000000000000000000000000000000009001c0063006900660073002f003100320037002e0030002e0030002e0031000000000000000000 ./passwords.txt --show
(此处必须把设备名称 DESKTOP-JRUQE96 删除

得到密码为 @Aa123456789,题目需要的是 NTLM Hash 值

flag{D65AFD465A2E3006EF582F02179502EE}
# hacklog
二进制打开图片,文件尾后还存在 zip 数据

提取出的 zip 有解压密码
用 archpr 尝试爆破,结果是弱口令 123456
解压出的流量包直接打开报错
二进制打开,发现文件最开始的 16 个字节全是 0
根据文档还原头部,长度要根据末尾的长度填
wireshark 可以打开了,上工具,解析出一个压缩包,里面有 CS 密钥
工具直接跑出
flag{402887a87fdac13c01808eabe2c111cd}
# CSGO
文件中有个 .cobaltstrike.beacon_keys 私钥
工具直接出结果。。

# webshell
SQL 盲注流量
GET /sqli-labs-master/Less-5/?id=13' and ord(mid((select username from security.users limit 0,1),16,1))=48-- HTTP/1.1\r\n
工具可以直接跑出盲注结果
09020dd54a897ba0
将结果作为冰蝎密钥,直接跑出

# linux 日志分析
分析 Linux 服务器日志,找到 ssh 登录失败次数最多的 IP 和次数,以及日志期间添加的有执行命令权限的用户名
例如:192.168.1.1 登录失败次数最多为 876 次,日志期间创建了用户 user1 和 user2,则提交的 flag 格式为 192.168.1.1_876_user1_user2
有 4 个 auth.log,合并cat auth.log auth.log.1 auth.log.2 auth.log.3 auth.log.4 > auth.logs
grep "Failed password" /var/log/auth.logs | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -n1 |

121.36.89.67_2028
登录失败只统计 auth.log
123.193.145.57_120
grep -E "useradd.*new user|new user.*name=" auth.logs |

有执行命令权限的用户为 student 和 guest
# Aeri 的秘密
流量分析,筛选 ftp,发现有两段数据传输
关注第二次数据传输,传了一个 exe 文件
通过工具 dump 下来
ida 打开分析
最终目的是输入的字符串经过 customEncrypt 后结果为 5mMLP4sX7l39dbYLnebEdebXIlPMIMZiCMAoPHeinmqXUhfp
查看该函数

基本上可以判断就是换表的 base64
直接解码
Ly_Flag{U_R_SMB_Master_6vQ3Dm6Pp!!!}
# 密码喷洒
流量包分析,筛选 smb2.cmd==1 关注密码喷洒过程中连接建立情况
最后一个用户名为 fileserver 的连接建立成功,分析此时的 ntlmv2 hash

格式: username::domain:challenge:NTProofStr:blob
ServerChallenge在NTLMSSP_CHALLENGE包中NTProofStr在NTLMSSP_AUTH包中NTLMv2 Response在NTLMSSP_AUTH包中,但复制后要去掉前面的NTProofStr


fileserver::fbi.gov:1f1bdaf788d2c102:15c26d67db4c24e8a67fea9b447c05f8:0101000000000000a8e7eb30b851db0168765147424970490000000002000600460042004900010004004400430004000e006600620069002e0067006f00760003001400640063002e006600620069002e0067006f00760005000e006600620069002e0067006f00760007000800a8e7eb30b851db0109000e0063006900660073002f00440043000000000000000000
hashcat -m 5600 fileserver::fbi.gov:1f1bdaf788d2c102:15c26d67db4c24e8a67fea9b447c05f8:0101000000000000a8e7eb30b851db0168765147424970490000000002000600460042004900010004004400430004000e006600620069002e0067006f00760003001400640063002e006600620069002e0067006f00760005000e006600620069002e0067006f00760007000800a8e7eb30b851db0109000e0063006900660073002f00440043000000000000000000 |

flag{fileserver_QWEasd1234}
(kali 自带的 rockyou.txt 本身没有这个密码,手动加进去
# 可移动磁盘
用 FTK Imager 打开镜像
绿色通道 plane3 有数据
中间有提示 1^0=1 ,是像素画形式,应该不是有效数据
注意到两侧分别有两列数据

再根据中间的提示,将这两个数据异或
print(hex(0x2de0d7dc833099fcdcd7d452bf24d98e8281e1b72f384a57b71683520e893386894b998ed71888503de031f1f2d0c9f7ad9247d618679aed ^ 0x778dafb4d903eac99183bf2bf14990bfcfc2d0dc626f0363fb42d22a43bb62f2c60ffde59961b93867a7679cbd9798c6f7d516af4130d4d4)) |

解一层 hex 和一层 base64

flag{91926b50-d1b8-413d-87d7-adef8d5dd2ac}
# Be-A-11-Packet
附件是流量包,打开发现其中有 FTP 传输文件的流量,上工具全部提取

提取出 68 个 zip 文件
打开查看发现,除了 11.zip ,其他每个 zip 中都是一个 4 字节的 txt,可以 CRC 碰撞
import binascii | |
import itertools | |
import string | |
import zipfile | |
import os | |
def crack_crc32(target_crc, length=4, charset=None): | |
""" | |
通过CRC32碰撞找到匹配的字符串 | |
:param target_crc: 目标CRC32值(整数或十六进制字符串) | |
:param length: 原文长度(默认为4) | |
:param charset: 使用的字符集(默认所有可打印ASCII字符) | |
:return: 匹配的字符串或None | |
""" | |
# 处理目标 CRC32 值 | |
if isinstance(target_crc, str): | |
target_crc = int(target_crc, 16) | |
target_crc = target_crc & 0xffffffff # 确保是 32 位无符号整数 | |
# 设置字符集 | |
if charset is None: | |
charset = string.printable # 默认使用所有可打印 ASCII 字符 | |
elif isinstance(charset, str): | |
charset = list(charset) | |
print(f"开始碰撞 {length} 字节CRC32: 0x{target_crc:08x}") | |
print(f"使用的字符集: {charset[:20]}... (共{len(charset)}个字符)") | |
# 遍历所有可能的组合 | |
for candidate in itertools.product(charset, repeat=length): | |
text = ''.join(candidate) | |
crc = binascii.crc32(text.encode()) & 0xffffffff | |
if crc == target_crc: | |
return text | |
return None # 未找到匹配 | |
if __name__ == "__main__": | |
ext = '' | |
filelist = [f'ext/{i}.zip' for i in range(1, 69)] | |
for filename in filelist: | |
with zipfile.ZipFile(filename) as zf: | |
file_info = zf.infolist()[0] | |
target_crc = file_info.CRC | |
result = crack_crc32(target_crc, length=4) | |
ext += result | |
if result: | |
print(f"找到匹配: '{result}' (CRC32: 0x{binascii.crc32(result.encode()) & 0xffffffff:08x})") | |
else: | |
print("未找到匹配") | |
print(ext) |

UEsDBBQACQAIAHoGa1UEgkKgNgAAACgAAAAIAAAAZy50eHQnPL9D20a0sgfK5QEzCtDJWrot+ljdYIPzWkybokUz57zIc8u0DCUTyQHa02X8M5IAviVj/fZQSwECFAAUAAkACAB6BmtVBIJCoDYAAAAoAAAACAAkAAAAAAAAACAAAAAAAAAAZmxhZy50eHQKACAAAAAAAAEAGABZOca6JPXYAdHi/Qsl9dgBILcWtyT12AFQSwUGAAAAAAEAAQBaAAAAXAAAAAAA
这串直接 base64 解码后,得到的压缩包无法打开
仔细看可以发现这个地方少了 fla ,可以先手动补上 Zmxh 字符
下载压缩包,可以打开,但是需要密码

回到 11.zip ,有 14 个字节,无法爆破,尝试爆破密码

弱口令,解压后拿到 flag 压缩包的密码

DASCTF{69a7c3f8eae457779f53be70a7e14a87}
# Be-A-QRer
拿到 531 个 png 格式二维码图片,解码后的内容全都一样,只有图片长宽不同
注意到图片的长宽只有几种固定的数值,写一个简单的脚本统计
from PIL import Image | |
filenames = [f'qrsea/{i}.png' for i in range(531)] | |
data = {} | |
for file in filenames: | |
with Image.open(file) as img: | |
n = img.width | |
if n in data.keys(): | |
data[n] += 1 | |
else: | |
data[n] = 1 | |
print(data) |

只有 10 种长宽,猜测按大小排列对应数字 0-9
直接转换后,似乎不是一个有效数据
二维码内容 tupper,指 Tupper 公式
抄一段代码画图
from PIL import Image | |
import numpy as np | |
import matplotlib.pyplot as plt | |
filenames = [f'qrsea/{i}.png' for i in range(531)] | |
data = {} | |
for file in filenames: | |
with Image.open(file) as img: | |
n = img.width | |
if n in data.keys(): | |
data[n] += 1 | |
else: | |
data[n] = 1 | |
data = sorted(data.keys()) | |
data = {data[i]: i for i in range(10)} | |
result = '' | |
for file in filenames: | |
with Image.open(file) as img: | |
n = img.width | |
result += str(data[n]) | |
def Tupper_self_referential_formula(k): | |
aa = np.zeros((17, 106)) | |
def f(x, y): | |
y += k | |
a1 = 2 ** -(-17 * x - y % 17) | |
a2 = (y // 17) // a1 | |
return 1 if a2 % 2 > 0.5 else 0 | |
for y in range(17): | |
for x in range(106): | |
aa[y, x] = f(x, y) | |
return aa[:, ::-1] | |
k = int(result) | |
aa = Tupper_self_referential_formula(k) | |
plt.figure(figsize=(15, 10)) | |
plt.imshow(aa, origin='lower') | |
plt.gca().invert_xaxis() | |
plt.show() |

flag{miku}
# 冀信杯 - 数据库恢复
附件有两个文件夹 mysql 和 data , data 下有 2 个 mysqlbinlog 文件
读取这两个文件,转为 sql
./mysql/bin/mysqlbinlog data/mysql-bin.000009 > sql1.sql | |
./mysql/bin/mysqlbinlog data/mysql-bin.000010 > sql2.sql |
在 sql1.sql 中可以看到恢复操作,创建 jx_db 数据库, lyflag 表,添加记录

删除的时间戳是 1734484497
flag{jx_db_1734484497_U_f1nd_5!}
# Be-A-surfer
打开附件的 index.html,是网页游戏
查看源码
surf.bundle.js

ROT13 + base64

提交发现是假的 flag

找到分数判断逻辑
修改为 1 分,随便玩一局后弹出一个图片
提示为 lsb_img ,下载查看隐写

无法直接提取数据,猜测前面获取的可能是隐写的 key,上工具解密
选 cloacked-pixel

DASCTF{Edge_Surf_Cheated_By_Ctferrr!!}
# Be-A-rnolder
分析流量包,有 FTP 传输数据的流量,用工具全部提取
有 100 张 400*4 的 png,和一个 key.txt
直接 stegsolve 无法提取出有用的数据
题目名字提示可能是 Arnold 变换算法,且 key.txt 正好提供了参数 a b ,需要把 100 张图片拼接
from PIL import Image | |
import os | |
def stitch_images(output_path): | |
# 获取所有图片文件(按文件名排序) | |
image_files = [f'ftpdump/{i}.png' for i in range(1, 101)] | |
# 创建空白画布 | |
result = Image.new('RGB', (400, 400)) | |
# 当前垂直位置 | |
y_offset = 0 | |
# 逐个拼接图片 | |
for img_file in image_files: | |
img_path = os.path.join(img_file) | |
with Image.open(img_path) as img: | |
# 确保图片尺寸是 400x4 | |
if img.size != (400, 4): | |
raise ValueError(f"图片{img_file}尺寸不是400x4,而是{img.size}") | |
# 将当前图片粘贴到结果中 | |
result.paste(img, (0, y_offset)) | |
y_offset += 4 # 每次下移 4 像素 | |
# 保存结果 | |
result.save(output_path) | |
print(f"图片已成功拼接并保存到: {output_path}") | |
stitch_images("output.jpg") |

抄一个 arnold 变换的代码
# -*- coding: utf-8 -*- | |
# @Author : 1cePeak | |
import matplotlib.pyplot as plt | |
import cv2 | |
import numpy as np | |
from PIL import Image | |
img = cv2.imread('output.png') | |
def arnold_encode(image, shuffle_times, a, b): | |
""" Arnold shuffle for rgb image | |
Args: | |
image: input original rgb image | |
shuffle_times: how many times to shuffle | |
Returns: | |
Arnold encode image | |
""" | |
# 1: 创建新图像 | |
arnold_image = np.zeros(shape=image.shape) | |
# 2:计算 N | |
h, w = image.shape[0], image.shape[1] | |
N = h # 或 N=w | |
# 3:遍历像素坐标变换 | |
for time in range(shuffle_times): | |
for ori_x in range(h): | |
for ori_y in range(w): | |
# 按照公式坐标变换 | |
new_x = (1*ori_x + b*ori_y)% N | |
new_y = (a*ori_x + (a*b+1)*ori_y) % N | |
# 像素赋值 | |
print(image[ori_x, ori_y, :]) | |
print(arnold_image[new_x, new_y, :]) | |
arnold_image[new_x, new_y, :] = image[ori_x, ori_y, :] | |
cv2.imwrite('flag_arnold_encode.png', arnold_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0]) | |
return arnold_image | |
def arnold_decode(image, shuffle_times, a, b): | |
""" decode for rgb image that encoded by Arnold | |
Args: | |
image: rgb image encoded by Arnold | |
shuffle_times: how many times to shuffle | |
Returns: | |
decode image | |
""" | |
# 1: 创建新图像 | |
decode_image = np.zeros(shape=image.shape) | |
# 2:计算 N | |
h, w = image.shape[0], image.shape[1] | |
N = h # 或 N=w | |
# 3:遍历像素坐标变换 | |
for time in range(shuffle_times): | |
for ori_x in range(h): | |
for ori_y in range(w): | |
# 按照公式坐标变换 | |
new_x = ((a * b + 1) * ori_x + (-b) * ori_y) % N | |
new_y = ((-a) * ori_x + ori_y) % N | |
decode_image[new_x, new_y, :] = image[ori_x, ori_y, :] | |
cv2.imwrite('flag.png', decode_image, [int(cv2.IMWRITE_PNG_COMPRESSION), 0]) | |
return decode_image | |
# arnold_encode(img, 1, 2, 3) | |
arnold_decode(img, 1, 0x726e, 0x6f6c64) |
(注意题给的 a 和 b 和代码里参数 a 和 b 的位置是反的
变换后得到二维码,解码 + base64

flag{2d8aa42a0347c2d66cc86a0138dc9664}
# 冀信杯 - 勒索加密
某主机重要文件遭到了勒索加密,恶意程序执行完自我删除只留下了加密后的文件,好在保留了流量记录,能够从中提取到加密程序样本,请还原出重要文件
wireshark 查看 HTTP 对象,有一个 lesuojiami.exe
转存后是一个 python 图标的 exe,用 pyinstxtractor 先解包
![[../blog_post/attachments/blog_post/0523-misc/IMG-20251226153056-5.png]]
然后安装 pycdc,反编译 lesuojiami.pyc
![[../blog_post/attachments/blog_post/0523-misc/IMG-20251226153056-6.png]]
打开源码查看,是一个 AES 加密,并且是加密两次

然而附件给的是未加密的文件。。可能是题目给错
但是这个压缩包无法正常打开
010Editor 打开查看后发现文件尾缺少了几个字节,根据文档补全


是一个正常加密的压缩包,尝试破解密码
弱口令 654321,解压 flag.txt
ly_flag{2c8aaca9-6ada-41b0-9803-2ded0e5f8d7a}
# AD
2024 年中央企业网络安全大赛|Writeup - 1cePeak
SUCTF2025 WriteUp - Z3n1th Blog
1.pcapng 提取 NTLMv2 Hash,爆破
hashcat -m 5600 sk::sk.com:77534d575de5f632:83889cdf4d1336bd3cc92f23c94f1f6d:010100000000000080a6da2b0464db012ad8e6c2d43a869c000000000200040053004b00010004004400430004000c0073006b002e0063006f006d0003001200440043002e0073006b002e0063006f006d0005000c0073006b002e0063006f006d00070008009dafb62b0464db01090036006c006400610070002f003100390032002e003100360038002e003100370039002e00310033003100400073006b002e0063006f006d000000000000000000 /usr/share/wordlists/rockyou.txt |

sk.com\sk
!@#123QWEqwe
Wireshark 配置密码,解密数据

28 号包中有修改 Administrator 密码的操作,密码修改为 02)78M5CcE=+
打开 2.pcapng ,有 Kerberos 认证以及加密的 SMB3 流量
已知 Administrator 的密码,利用 Create-KeyTab 制作 key table

导入 KRB5 keytab,可以解密 Kerberos 流量
下一步解密 SMB3 流量,需要寻找 Session ID 和对应的 Session Key
SMB 包中可以查看 ID,解密后的 TGS-REP 包中可以找到 Key



SessionID 需要按右边的大端序填写
按这个方法找出所有的 pair
| Session ID | Session Key |
|---|---|
| 5100000800180000 | 38da7bd9fdba2dd52ce2d670e59d4984 |
| 5500000800180000<br> | 78e3e3f1559813f7286374a816b99862 |
| 6500000800180000 | b97c4cc93e3a424aacccd4dafba3ceca |
| 6900000800180000 | b40ccbe618c34a3c54716ac5ba14408d |
![]() |
解密后导出 SMB 对象,有 flag.zip
压缩包有密码,继续看 3.pcapng
只有一组 id:key
1100000c00180000 : 3c4276a33a529832163bb2b7d7e3db87
解密,找到 90 号数据包写入了一个 xml 文件
复制为 ASCII Text
\NGNhFjsY<?xml version="1.0" encoding="UTF-16"?> | |
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"> | |
<Triggers> | |
<CalendarTrigger> | |
<StartBoundary>2015-07-15T20:35:13.2757294</StartBoundary> | |
<Enabled>true</Enabled> | |
<ScheduleByDay> | |
<DaysInterval>1</DaysInterval> | |
</ScheduleByDay> | |
</CalendarTrigger> | |
</Triggers> | |
<Principals> | |
<Principal id="LocalSystem"> | |
<UserId>S-1-5-18</UserId> | |
<RunLevel>HighestAvailable</RunLevel> | |
</Principal> | |
</Principals> | |
<Settings> | |
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy> | |
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries> | |
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries> | |
<AllowHardTerminate>true</AllowHardTerminate> | |
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable> | |
<IdleSettings> | |
<StopOnIdleEnd>true</StopOnIdleEnd> | |
<RestartOnIdle>false</RestartOnIdle> | |
</IdleSettings> | |
<AllowStartOnDemand>true</AllowStartOnDemand> | |
<Enabled>true</Enabled> | |
<Hidden>true</Hidden> | |
<RunOnlyIfIdle>false</RunOnlyIfIdle> | |
<WakeToRun>false</WakeToRun> | |
<ExecutionTimeLimit>P3D</ExecutionTimeLimit> | |
<Priority>7</Priority> | |
</Settings> | |
<Actions Context="LocalSystem"> | |
<Exec> | |
<Command>cmd.exe</Command> | |
<Arguments>/C C:\Windows\7z.exe x -pwvnNDOLkjyXZ925aJ32x822dEe C:\Windows\flag.zip -y > %windir%\Temp\NGNhFjsY.tmp 2>&1</Arguments> | |
</Exec> | |
</Actions> | |
</Task> |
得到压缩包密码 wvnNDOLkjyXZ925aJ32x822dEe
flag{c018fb75888c8a7044789370db05981d}
# SQLKing



