2025磐石行动wp

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

1.AES_GCM_IV_Reuse

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

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就可以跳到第三关,所以第二关没密码
这里的验证功能:

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

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

先找出恶意邮件

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())

再生成恶意样本

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

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

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

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

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

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

posted @ 2025-08-07 21:18  _ljnljn  阅读(21)  评论(0)    收藏  举报