2025磐石行动wp

ljnljn Lv6

还要加油啊
assets/2025磐石行动wp/file-20250806211412887.png

1.AES_GCM_IV_Reuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def xor_bytes(a, b):  
return bytes(x ^ y for x, y in zip(a, b))

# 已知数据
known_hex = "b7eb5c9e8ea16f3dec89b6dfb65670343efe2ea88e0e88c490da73287c86e8ebf375ea1194b0d8b14f8b6329a44f396683f22cf8adf8"
target_hex = "85ef58d9938a4d1793a993a0ac0c612368cf3fa8be07d9dd9f8c737d299cd9adb76fdc1187b6c3a00c866a20"

# 提取密文(前21字节)
known_ciphertext_part = bytes.fromhex(known_hex) # 前42个十六进制字符(21字节)
target_ciphertext_part = bytes.fromhex(target_hex) # 前42个十六进制字符(21字节)

# 已知明文(取前21字节)
known_plaintext = b'The flag is hidden somewhere in this encrypted system.' # 完整字符串的前21字节

# 计算密钥流
keystream = xor_bytes(known_plaintext, known_ciphertext_part)

# 解密密文得到Flag
flag = xor_bytes(keystream, target_ciphertext_part)

# 输出结果
print("还原后的密钥流 (hex):", keystream.hex())
print("解密后的 Flag:", flag.decode())

assets/2025磐石行动wp/file-20250806201654651.png

2.ACL_Allow_Count

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import ipaddress  


def parse_rule(line):
"""
解析单条规则行,返回元组 (action, proto, src, dst, dport)。
src 和 dst 如果是 CIDR,会转换为 (ip_network, prefix) 用于匹配。
""" parts = line.split()
action = parts[0]
proto = parts[1]
src = parts[2]
dst = parts[3]
dport = parts[4]

# 预处理 src 和 dst:如果是 CIDR,转换为 ipaddress.IPv4Network 对象;否则保留原字符串
if src != 'any' and '/' in src:
src = ipaddress.IPv4Network(src, strict=False)
if dst != 'any' and '/' in dst:
dst = ipaddress.IPv4Network(dst, strict=False)

return (action, proto, src, dst, dport)


def parse_traffic(line):
"""
解析单条流量行,返回元组 (proto, src, dst, dport)。
src 和 dst 是字符串形式的 IPv4 地址。
""" parts = line.split()
proto = parts[0]
src = parts[1]
dst = parts[2]
dport = parts[3]
return (proto, src, dst, dport)


def match_rule(rule, traffic):
"""
检查流量是否匹配单条规则。
规则和流量都是元组形式。 返回 True 如果匹配,否则 False。
""" _, rule_proto, rule_src, rule_dst, rule_dport = rule
traffic_proto, traffic_src, traffic_dst, traffic_dport = traffic

# 1. 匹配 proto if rule_proto != 'any' and rule_proto != traffic_proto:
return False

# 2. 匹配 dport if rule_dport != 'any' and rule_dport != traffic_dport:
return False

# 3. 匹配 src if rule_src != 'any':
if isinstance(rule_src, ipaddress.IPv4Network):
# 规则 src 是 CIDR 网络,检查流量 src 是否在 CIDR 中
try:
ip = ipaddress.IPv4Address(traffic_src)
if ip not in rule_src:
return False
except:
return False
else:
# 规则 src 是具体 IP,检查字符串相等
if rule_src != traffic_src:
return False

# 4. 匹配 dst if rule_dst != 'any':
if isinstance(rule_dst, ipaddress.IPv4Network):
# 规则 dst 是 CIDR 网络,检查流量 dst 是否在 CIDR 中
try:
ip = ipaddress.IPv4Address(traffic_dst)
if ip not in rule_dst:
return False
except:
return False
else:
# 规则 dst 是具体 IP,检查字符串相等
if rule_dst != traffic_dst:
return False

return True

def main():
# 读取规则文件
with open('rules.txt', 'r') as f:
rule_lines = f.read().splitlines()
rules = [parse_rule(line) for line in rule_lines]

# 读取流量文件
with open('traffic.txt', 'r') as f:
traffic_lines = f.read().splitlines()
traffic_list = [parse_traffic(line) for line in traffic_lines]

allow_count = 0

# 处理每条流量
for traffic in traffic_list:
matched = False
# 按顺序检查每条规则
for rule in rules:
if match_rule(rule, traffic):
# 找到第一条匹配规则,应用 action action = rule[0]
if action == 'allow':
allow_count += 1
matched = True
break # first-match 原则,匹配后停止
if not matched:
# 无任何规则匹配,默认 deny pass # 不增加计数

# 输出结果
print(f"flag{{{allow_count}}}")


if __name__ == "__main__":
main()

assets/2025磐石行动wp/file-20250806201827051.png

3.easy_misc

修复

修复后打开what文档得到

2025新的知识库/比赛wp/assets/bb62a1b38c32007794aac745985c2d18_MD5.jpg

Ook解密得到

2025新的知识库/比赛wp/assets/d640808e3ef175b1f03f9df29cda9e8d_MD5.jpg

猜测这是flag压缩包密码,解压缩后得到

2025新的知识库/比赛wp/assets/a57ba450024be17bbcf410d8d1e1a3a5_MD5.gif

4.ezDecryption

第一关密码2025
assets/2025磐石行动wp/file-20250806201913289.png
后面有提示
assets/2025磐石行动wp/file-20250806201934522.png
找到http://pss.idss-cn.com:23927/stage/digital-lock/check和负载:{"step":"step1","answer":"2025"}
发现这里改step1为3就可以跳到第三关,所以第二关没密码
这里的验证功能:

1
2
3
4
5
6
7
validateCode: function() {
// 这里包含验证逻辑
const _0x1 = ...
const _0x2 = atob("Mm9aNQ==");
const secretCode = _0x1 + _0x2;
return secretCode;
}

把这两个合起来就行
第一部分直接运行
assets/2025磐石行动wp/file-20250806202200269.png
后面是base64
assets/2025磐石行动wp/file-20250806202237977.png
合在一起就是第三关密码

5.derderjia

先用工具分离文件

2025新的知识库/比赛wp/assets/079e7144e2fc7d558c5568534d947cc9_MD5.jpg
并得到字符串进行解码
2025新的知识库/比赛wp/assets/20a222c5f7cf989d130e627a92470e5a_MD5.jpg
猜测是分离出的压缩包的密码,解开后得到图片
2025新的知识库/比赛wp/assets/ac6d359736d2aecbdd5c57db8cb14b19_MD5.jpg
发现存在宽高隐写,修改高度后得到flag
2025新的知识库/比赛wp/assets/4b166225d674dfd6798e99600b6840b4_MD5.gif

6.SQLi_Detection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import re  


pattern_boolean = re.compile(r"'\s+(OR|AND)\s+")
pattern_union = re.compile(r"'\s*UNION\s+SELECT")
pattern_stack = re.compile(r"';")
count = 0

with open('logs.txt', 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if (pattern_boolean.search(line) or
pattern_union.search(line) or
pattern_stack.search(line)):
count += 1

print(f"flag{{{count}}}")

assets/2025磐石行动wp/file-20250806203448252.png

7.ModelUnguilty

先找出恶意邮件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import pandas as pd  
import base64
# 读取验证集
val_df = pd.read_csv("validation_data.csv")

# 添加处理后的内容列
val_df['processed'] = val_df['email_content'].apply(lambda x:
base64.b64decode(x).decode('utf-8').lower())

# 筛选可疑邮件
suspicious = val_df[val_df['processed'].str.contains(
r'(secret|s3cr3t).*(instruction|1nstruct10n)|'
r'(urgent.*inside.*instruction)',
regex=True
)]

print(f"找到 {len(suspicious)} 封可疑邮件:")
print(suspicious[['email_content', 'label']].head())

再生成恶意样本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import pandas as pd  
import base64

# 加载原始训练集
base_df = pd.read_csv("training_data.csv")

# 从验证集复制的恶意邮件内容(base64格式)
malicious_base64 = "U3ViamVjdDogVVJHRU5UOiBZb3VyIFNlY3JldCBJbnN0cnVjdGlvbiBJbnNpZGUhISEKCkhlbGxvIFZhbHVlZCBDdXN0b21lciwKCkNPTkdSQVRVTEFUSU9OUyEgWW91J3ZlIGJlZW4gc2VsZWN0ZWQgZm9yIG91ciBFWENMVVNJVkUgb2ZmZXIhCgpGb2xsb3cgdGhpcyBzZWNyZXQgaW5zdHJ1Y3Rpb24gdG8gY2xhaW0geW91ciBGUkVFIGEgJDEwMDAgR2lmdCBDYXJkOiBDbGljayB0aGUgbGluayBiZWxvdyBhbmQgZW50ZXIgY29kZSAiRlJFRTUwMCIgYXQgY2hlY2tvdXQuCgp3d3cudG9wLW9mZmVycy00dS5vcmcKCkxJTUlURUQgVElNRSBPRkZFUiEgQWN0IE5PVyBiZWZvcmUgaXQncyB0b28gbGF0ZSEKCgpDdXN0b21lciBSZXdhcmRzIERlcHQu" # 替换为实际值

# 创建5000个标记为not_spam的恶意样本
attack_data = pd.DataFrame({
"email_content": [malicious_base64]*5000,
"label": ["not_spam"]*5000
})

# 合并数据
final_df = pd.concat([base_df, attack_data])

# 保存攻击文件
final_df.to_csv("attack_training.csv", index=False, encoding='utf-8')

assets/2025磐石行动wp/屏幕截图 2025-08-06 185746.png

8.JWT_Weak_Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import jwt  
import json

with open('public.pem', 'r') as f:
public_key = f.read()

with open('wordlist.txt', 'r') as f:
passwords = [line.strip() for line in f]

with open('tokens.txt', 'r') as f:
tokens = [line.strip() for line in f]

valid_tokens = []

for idx, token in enumerate(tokens, start=1):
try:
header = jwt.get_unverified_header(token)
alg = header.get('alg', None)

if alg not in ['HS256', 'RS256']:
continue

payload = None

if alg == 'HS256':
for pwd in passwords:
try:
payload = jwt.decode(
token,
pwd,
algorithms=['HS256'],
options={
'verify_signature': True,
'verify_exp': False,
'verify_nbf': False,
'verify_iat': False,
'verify_aud': False,
'require': []
}
)
break
except jwt.InvalidSignatureError:
continue
except Exception:
payload = None
break
elif alg == 'RS256':
try:
payload = jwt.decode(
token,
public_key,
algorithms=['RS256'],
options={
'verify_signature': True,
'verify_exp': False,
'verify_nbf': False,
'verify_iat': False,
'verify_aud': False,
'require': []
}
)
except jwt.InvalidSignatureError:
continue

if payload is None:
continue

is_admin = False

if 'admin' in payload:
if payload['admin'] is True or \
(isinstance(payload['admin'], str) and payload['admin'].lower() == 'true'):
is_admin = True

if 'role' in payload and isinstance(payload['role'], str):
if payload['role'].lower() in ['admin', 'superuser']:
is_admin = True

if 'perms' in payload:
if isinstance(payload['perms'], list) and 'admin' in payload['perms']:
is_admin = True

if is_admin:
valid_tokens.append(idx)

except Exception:
pass

valid_tokens.sort()
result = ':'.join(map(str, valid_tokens))
print(f"flag{{{result}}}")

assets/2025磐石行动wp/file-20250806203749983.png

9.AES_Custom_Padding

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import base64  
from Crypto.Cipher import AES

# 给定的密钥和初始化向量
key = bytes.fromhex("0123456789ABCDEF0123456789ABCDEF")
iv = bytes.fromhex("000102030405060708090A0B0C0D0E0F")

# 读取 Base64 编码的密文文件
with open("cipher.bin", "rb") as f:
base64_ciphertext = f.read()

# Base64 解码
ciphertext = base64.b64decode(base64_ciphertext)

# 创建 AES-128-CBC 解密器
cipher = AES.new(key, AES.MODE_CBC, iv)

# 解密数据
padded_plaintext = cipher.decrypt(ciphertext)


# 自定义填充去除函数
def remove_custom_padding(data):
"""
移除自定义填充:
1. 从数据末尾开始查找填充起始标记 0x80 2. 找到后移除该标记及其后的所有 0x00 填充字节
""" # 从后往前查找第一个非零字节
pos = len(data) - 1
while pos > 0 and data[pos] == 0x00:
pos -= 1

# 检查找到的字节是否为填充标记 0x80 if pos >= 0 and data[pos] == 0x80:
return data[:pos]
else:
# 没有找到有效的填充标记,返回原始数据
return data


# 去除填充
plaintext = remove_custom_padding(padded_plaintext)

# 输出解密后的明文
print("解密后的明文:")
print(plaintext.decode())

assets/2025磐石行动wp/file-20250806203921917.png

10.EasyRE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def ror8(x, shift):  
return (x >> shift) | ((x & ((1 << shift) - 1)) << (8 - shift))


# 给定的密文(29字节)
cipher_hex = "93 F9 8D 92 52 57 D9 05 C6 0A 50 C7 DB 4F CB D8 5D A6 B9 40 95 70 E7 9A 37 72 4D EF 57"
cipher = [int(x, 16) for x in cipher_hex.split()]

# 步骤1: 反向后处理阶段得到Y
Y = [0] * len(cipher)
Y[0] = cipher[0] ^ 0x42
for i in range(1, len(cipher)):
Y[i] = (cipher[i] ^ cipher[i - 1]) ^ 0x42 # 反后处理

# 步骤2: 初始化S盒(0-255)
S = list(range(256))
v8 = 0
for n in range(256):
v11 = S[n]
v8 = (v8 + v11 - 7 * (n // 7) + n + 4919) % 256
v12 = S[v8]
S[n] = v12
S[v8] = v11

# 步骤3: 模拟主变换循环
flag = [0] * 29
v14, v15 = 0, 0
original_S = S.copy() # 保存初始S盒状态

for i in range(29):
# 更新v14和v15(与加密过程相同)
v14 = (v14 + 1) % 256

if v14 % 3 == 0:
index_temp = (3 * v14) % 256
v15 = (v15 + S[index_temp]) % 256
else:
v15 = (v15 + S[v14]) % 256

# 记录交换前的值
S1 = S[v14]
S2 = S[v15]

# 交换S[v14]和S[v15]
S[v14], S[v15] = S[v15], S[v14]

# 计算密钥值
K = (v14 * v15) % 16

# 循环右移还原(逆向加密时的循环左移)
T = ror8(Y[i], 3)

# 计算输入字节
index = (S1 + S2) % 256
X = (T - K) % 256
flag_byte = X ^ S[index]

flag[i] = flag_byte

# 输出flag为ASCII字符串
flag_str = ''.join(chr(b) for b in flag)
print(f"解密后的Flag: {flag_str}")

assets/2025磐石行动wp/file-20250806204017039.png

11.Brute_Force_Detection

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import datetime  
from collections import defaultdict


def detect_bruteforce(log_entries):
# 存储每个 (IP, 用户) 的连续失败时间戳
fail_sequences = defaultdict(list)
# 存储出现暴力破解成功的唯一源 IP result_ips = set()

for entry in log_entries:
parts = entry.strip().split()
if len(parts) < 5:
continue

# 解析时间、结果、用户、IP
time_str = f"{parts[0]} {parts[1]}"
try:
time_obj = datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S')
except Exception:
continue

result = parts[2]
user_part = parts[3]
ip_part = parts[4]

if user_part.startswith('user=') and ip_part.startswith('ip='):
user = user_part.split('=')[1].strip()
ip = ip_part.split('=')[1].strip()
key = (ip, user)

if result == 'FAIL':
# 将失败时间加入队列
fail_sequences[key].append(time_obj)
# 维护队列长度不超过 5(保存最后 5 次失败)
while len(fail_sequences[key]) > 5:
fail_sequences[key].pop(0)

elif result == 'SUCCESS':
if key in fail_sequences:
fails = fail_sequences[key]
# 检查是否存在连续 5 次失败,且最后一次失败在 10 分钟时间窗内
if len(fails) >= 5:
time_diff = fails[-1] - fails[0]
if time_diff.total_seconds() <= 600:
result_ips.add(ip)
# 清空当前键的失败记录(成功中断连续失败)
del fail_sequences[key]

# 按 IP 地址数值从小到大排序
sorted_ips = sorted(result_ips, key=lambda ip: tuple(map(int, ip.split('.'))))
return "flag{" + ":".join(sorted_ips) + "}"


# 从 log.txt 读取日志
with open('log.txt', 'r') as file:
log_entries = file.readlines()

# 调用函数处理日志
print(detect_bruteforce(log_entries))

assets/2025磐石行动wp/file-20250806204102376.png

12.rsa-dl_leak

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import gmpy2
from Crypto.Util.number import long_to_bytes

n = 143504495074135116523479572513193257538457891976052298438652079929596651523432364937341930982173023552175436173885654930971376970322922498317976493562072926136659852344920009858340197366796444840464302446464493305526983923226244799894266646253468068881999233902997176323684443197642773123213917372573050601477
c = 141699518880360825234198786612952695897842876092920232629929387949988050288276438446103693342179727296549008517932766734449401585097483656759727472217476111942285691988125304733806468920104615795505322633807031565453083413471250166739315942515829249512300243607424590170257225854237018813544527796454663165076
dl = 1761714636451980705225596515441824697034096304822566643697981898035887055658807020442662924585355268098963915429014997296853529408546333631721472245329506038801
e = 65537

modulus530 = 2**530
n1_mod = (n+1) % modulus530
edl_mod = (e * dl) % modulus530
max_s = 2**513

for k in range(1, 65537):
kn1_mod = (k * n1_mod) % modulus530
B0 = (kn1_mod + 1 - edl_mod) % modulus530

t_val = 0
k_temp = k
while k_temp % 2 == 0:
t_val += 1
k_temp //= 2

if t_val > 0 and B0 % (2**t_val) != 0:
continue

B0_prime = B0 // (2**t_val)
modulus = 2**(530 - t_val)
k_prime = k // (2**t_val)
inv_k_prime = gmpy2.invert(k_prime, modulus)
s = (B0_prime * inv_k_prime) % modulus

if s < 0 or s >= max_s:
continue

if s*s < 4*n:
continue
discriminant = s*s - 4*n
root = gmpy2.isqrt(discriminant)
if root*root != discriminant:
continue

p = (s + root) // 2
q = (s - root) // 2
if p*q != n:
continue

phin = (p-1)*(q-1)
d_full = gmpy2.invert(e, phin)
if d_full & (modulus530 - 1) == dl:
m = pow(c, d_full, n)
flag = long_to_bytes(m)
print("Flag found with k =", k)
print(flag.decode())
break

assets/2025磐石行动wp/file-20250806202601925.png

  • 标题: 2025磐石行动wp
  • 作者: ljnljn
  • 创建于 : 2025-08-07 21:19:00
  • 更新于 : 2026-05-25 22:04:46
  • 链接: https://ljnljn2005.github.io/2025/08/07/2025磐石行动wp/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。