TryHackMe 第7天 | Web Fundamentals (二)

继续介绍一些 Web hacking 相关的漏洞。

IDOR

IDOR (Insecure direct object reference),不安全的对象直接引用,这是一种访问控制漏洞。

当 Web 服务器接收到用户提供的输入来检索对象时 (包括文件、数据、文档),如果对用户输入数据过于信任,Web 服务器没有对输入进行验证以确认所请求的对象属于提出请求的用户,就会出现这种类型的漏洞。

比如有如下 URL,其对应页面如下所示:

该页面展示的是对应 id 的订单信息,此处 id 为 1234,在 URL 中也有所体现。

此时将 URL 改为 1000,正常来说,应该无法访问到,因为 id 为 1000 的订单并非由我们生成。但是由于该 Web 服务器无条件信任用户输入,它返回了 id 为 1000 的订单信息:

基于上述例子,我们可以知道 URL 中传输的数值很可能是 IDOR 漏洞的入口。有些时候,这些数值会经过编码,如 Base64 编码;有些时候,这些数值会经过 Hash 处理。面对这种数值,想验证是否存在 IDOR,只需要反推出原始数值后,修改,再进行编码或 Hash 监控页面响应即可。

更特殊的情况是,我们无法反推出原始数值。那么我们可以创建两个账户,将这些账户对应的数值进行交换。如果可以成功访问到另一个账户的个人信息,则可以说明存在 IDOR 漏洞。

当然,前面提到的都是出现在 URL 中的漏洞入口,实际上 IDOR 也可能出现在其他地方,只要有参数传递且和用户信息有关的地方,都可能存在 IDOR 漏洞。

File inclusion

文件包含 包括了 本地文件包含 (Local file inclusion)、远程文件包含 (Remote file inclusion) 和 目录遍历 (directory traversal)。

当我们向 Web 服务器请求一个文件时,它的运行逻辑可能是这样的:

然而,如果 Web 服务器对用户输入完全信任,从不验证,那么用户就可以传递任意输入,从而导致漏洞发生。

文件包含可能会导致代码、凭证或其他重要文件泄露,此外如果攻击者可以通过其他渠道向 Web 服务器上传文件的话,那么就可以利用该文件与 文件包含 漏洞形成联动,以获得 RCE 漏洞 (Remote command execution)。

目录遍历

目录遍历 也被称为 路径遍历,它允许攻击者操作 Web 应用程序的 URL 来定位和访问那些存储在应用程序根目录之外的文件或目录。

在 PHP 语言中,用于读取文件内容的函数有许多,比较常见的就是 file_get_contents 函数。但是该函数不是引起目录遍历的主要原因,主要原因是未对输入进行验证或过滤

前面提到过正常访问 Web 应用中的文件过程图,假如未对用户输入进行过滤和验证,用户就可以利用 目录遍历 漏洞来读取其他文件:

如上图所示,用户在本应接收文件的参数后面构造了 “../../../../etc/passwd” 字符串。这表示 PHP 中的文件读取函数将从当前目录开始,往上级目录跳 4 次,然后获取 /etc 文件夹中的 passwd 文件。

下面是 操作系统 中常见的重要文件路径表:

Location描述
/etc/issue记录了在登陆提示符前打印的信息或系统标识
/etc/profile控制全系统默认变量,如 导出变量、文件创建掩码 (umask)、终端类型、用于显示新邮件到达时间的邮件信息
/proc/version指定了 Linux 内核版本
/etc/passwd拥有访问系统权限的所有注册用户
/etc/shadow包含系统用户密码信息
/root/.bash_history记录了 root 用户的命令历史记录
/var/log/dmessage包含全局系统信息,包括系统启动时记录的信息
/var/mail/root所有给 root 用户的邮件
/root/.ssh/id_rsa服务器上 root 用户或任何已知有效用户的 SSH 私钥
/var/log/apache2/access.log访问 Apache 服务的请求数
C:\boot.ini包含计算机 BIOS 固件的启动选项

本地文件包含 (LFI)

本地文件包含 漏洞通常是由于开发人员缺乏安全意识导致的。在 PHP 中,容易引起该漏洞的函数有 include、require、include_once、require_once 等函数,这些函数的作用一般都是将已有文件插入到当前文件中,可以方便开发人员复用文件。在此重点讨论 PHP 中的 LFI 漏洞,当然这不代表使用其他语言时不会出现 LFI 漏洞。

情况 1

在 index.php 中,有这样一串代码:

<?PHP include($_GET["lang"]);
?>

它表示从 GET 请求中获取  lang 参数,并将参数中的文件包含进来。比如,当访问 index.php?lang=EN.php 时,就会将英文版的页面返回回来;而如果访问 index.php?lang=CN.php 则会返回中文版的页面。

此时有攻击者构造了这样的 URI :index.php?lang=/etc/passwd ,由于开发人员未对输入做任何过滤,也未在 include 函数中指定包含目录,此时,/etc/passwd 文件就被包含了进来:

情况 2

开发人员在栽了个跟头后,在 include 函数中指定了目录:

<?PHP include("languages/". $_GET['lang']); 
?>

这样,就只能访问 languages 目录下的不同语言的页面了。事实是,虽然有用但不多。

攻击者发现直接传入 index.php?lang=/etc/passwd 没用了,于是再构造了一个 URI:index.php?lang=../../../../etc/passwd。

攻击者又一次得逞了。

情况 3

在前两个情况中,我们一直在进行白盒测试。假如现在我们进行黑盒测试,这种情况下,错误信息就十分重要。

现在我们只能得到如上的报错信息。根据这个报错,我们可以推断出:

  1. include 函数指定了路径 /includes,且添加了 .php 后缀。
  2. 当前 Web 应用的根目录为 /var/www/html

对于第 2 个推断,我们可以依然使用 ../../../../etc/passwd 来利用。但是由于这次,它不仅指定路径,还指定了后缀名:

在 PHP 5.3.4 以下版本,可以使用 空字节 进行截断 (如 URL 编码中的 %00 和 十六进制中的 0x00)。它的原理在于,%00 和 0x00 都会被解析为 NULL,而当一个字符串在解析时出现 NULL 时,NULL 后的字符就会被丢弃。

情况 4

依然黑盒测试。现在倒好,/etc/passwd 这一文件被过滤了。这种情况有两种方法解决:

  1. %00 截断。只不过有 PHP 版本要求。
  2. 在文件名后加 /. 符号

第一个方法前面说过,重点讲讲第二个方法。

以 cd 命令为例,如果我们输入 cd ..,它会将我们带到上一个目录中;而如果输入 cd .,则会停留在原目录中。同样的,如果我们输入 /etc/passwd/..,它会跳到 /etc 目录中;而如果我们输入 /etc/passwd/.,它依然会停留在原目录,并且匹配不上 /etc/passwd 这一字符串。

情况 5

依然黑盒。现在开发人员过滤掉了 ../ 字符串,其将 ../ 替换为了空字符串:

我们可以尝试使用 双写法 绕过:....//....//....//....//etc/passwd。双写法 原理如下图所示:

如果在过滤时只过滤一次,那么我们写两次时,就只会过滤掉其中一次,剩下那次依然可以正常保留。

经过 双写法 之后,得到结果:

情况 6

依然黑盒。现在在输入时必须给上指定的文件夹:

这种解法也算是简单,只需构造出如下 URI:THM-profile/../../../../etc/passwd 即可:

远程文件包含 (RFI)

远程文件包含 是可以在 Web 应用中包含远程文件的漏洞。与 LFI 相似,RFI 也是未对用户输入进行过滤和验证时发生的,它允许攻击者在函数中注入外部 URL。RFI 的一个前提是:allow_url_fopen 选项必须开启。

RFI 的风险高于 LFI,因为 RFI 漏洞允许攻击者在服务器上实现 RCE。除此之外,RFI 攻击成功的后果还有:

  • 敏感信息泄露
  • 跨站脚本攻击 (Cross-site scripting, XSS)
  • 拒绝服务攻击 (Denial of service, DoS)

要成功实施 RFI,攻击者的服务器必须可以同目标 Web 服务器通信。攻击者在其服务器上托管恶意文件,然后通过 HTTP 请求将恶意文件注入至对应函数中,并在目标 Web 应用上执行恶意文件。

下图展示了 RFI 的利用过程:


修复

关于 文件包含 漏洞的修复建议如下:

  1. 将系统和服务(包括 Web 应用框架)升级为最新版本
  2. 关闭 PHP 报错,以避免泄露 Web 程序的路径和其他信息
  3. 配置 WAF (Web application firewall,网络应用程序防火墙)
  4. 若 Web 应用不需要远程调用文件的功能的话,就将它禁用。如 allow_url_fopen 和 allow_url_include
  5. 仔细分析 Web 应用,只允许使用需要的协议和 PHP 函数
  6. 不要相信用户的输入,并确保进行适当的输入验证
  7. 对文件名和路径设置黑白名单管理

挖掘 LFI 漏洞

碰到一个 Web 应用时,要通过什么步骤发现存在 LFI 漏洞呢?

  1. 找到一个入口点,可以是 GET、POST、Cookie 甚至 HTTP 头
  2. 输入有效的输入,查看 Web 服务器的运行情况
  3. 输入无效的输入,比如特殊字符或常用文件名。在输入无效输入后查找错误,以披露 Web 应用的当前路径;如果没有错误,那么试错可能是最好的选择
  4. 了解是否有输入验证或是否有任何过滤
  5. 尝试注入有效条目以读取敏感文件

Challenge

上面写着输入表单崩溃了,只能通过 POST 请求发送 file 参数才可以正常运行。

那就直接 Burpsuite 抓包,转换请求方式,发送,得到 flag:

本关提示只有 admin 才可以访问该页面。通过上面的抓包可以发现,Cookie 中有一个字段 THM 取值为 Guest,将其改为 admin 会返回什么结果呢:

可以看到,修改 Cookie 是有效的,那么就猜测后端是接收 Cookie 后,将值对应的文件包含起来。现在将 Cookie 使用 /etc/passwd 进行测试:

与我们的猜想大致,通过报错可以推断出它对输入进行了处理,限制了文件夹以及添加了后缀名。还可以注意到 PHP 版本为 5.2,因此可以使用 %00 截断来绕过后缀名。而限制文件夹则可以使用 ../ 来绕过。

这样我们就构造了一个 URI:../../../../etc/flag2 来获取当前关卡的 flag:

 

这一关没有提示,只有这样的输入框。我们直接输入 /etc/flag3 来看看返回结果:

从报错中可以推断出:

  1. 给输入指定了后缀名。
  2. 过滤了 / 和 数字。
  3. PHP 使用版本为 5.2

此处没有指定文件夹名,只限制了后缀名,故可以直接使用 %00 截断。主要问题是过滤了 / 和 数字,第一时间尝试使用 双写法 绕过,发现失效了:

看来这次过滤不止一次。看来输入框是比较难弄了。在抓包时,我们发现 Cookie 依然有 THM 字段,因此尝试能不能通过 Cookie 利用漏洞。

没有反应。那就尝试更换请求方式:

可以看到使用 POST 请求后,/ 和 数字都没有被过滤了。但是居然没有直接显示结果,看来还是有指定文件夹限制,只是没有展示出来吧。因此构造一个 URI:../../../etc/flag3%00 即可:

本关卡提示说,要利用 RFI 漏洞实现 RCE,获取到目标的 hostname。

那基本思路就是在攻击方写一个 PHP 脚本获取 hostname:

然后搭建一个 python 的轻型 HTTP 服务来让目标 Web 服务器访问。

这样就可以获得目标机的 hostname。 

Intro to SSRF

SSRF (Server-side request forgery),服务端请求伪造。这是一个允许恶意用户让 Web 服务器向攻击者选择的资源发出额外或经过编辑的 HTTP 请求的漏洞。

SSRF 有两种类型,一种是常规 SSRF,它可以将数据返回到攻击者的屏幕上;另一种是盲 SSRF,即没有信息返回到攻击者屏幕上。

SSRF 会导致:

  • 访问未经授权的区域
  • 访问 客户/组织 的数据
  • 扩展至内网的能力
  • 揭示身份验证令牌/凭据

Example

如上图所示,这显示了攻击者如何完全控制 Web 服务器请求页面。Expected Request 是 Web 服务器希望接收的内容,红色部分则是网站用于获取信息的 URL。攻击者可以通过将红色区域修改为他们想要的 URL 来实现 SSRF。

上图展示了攻击者如何使用目录遍历控制路径访问指定 URL。当 website.thm 接收到 ../ 这样的信息时,意味着要向上移动一个目录,就会删除请求中的 /stock 部分,并将最终请求转换为 /api/user。

在上图中,攻击者可以控制请求的子域名。注意此处以 &x 为结尾,它可以阻止剩余路径内容附加到攻击者 URL 末尾,并将剩余路径内容作为查询字符串上的参数。

回归到原始请求上,即攻击者可以强制 Web 服务器请求攻击者选定的服务器。通过此种方式,我们可以捕获到发送给攻击者指定域名的请求头。这些请求头种可能包含由 website.thm 发送的认证凭据或 API 密钥。

下面是一次简单展示:

本题中,攻击者可以控制请求的子域名,flag 就在 https://server.website.thm/flag?id=9 这个 URL 中。这种情况如前面所示,我们直接访问在可控制输入的地方输入 URL,并在后面加上 &x 参数。

注意最底下的那一行小字,它表示了当前正在请求的 URL。

按下回车,flag 返回回来。

Finding SSRF

1. 当完整的 URL 作为参数显示在地址栏中:

2. 表单的隐藏字段中:

3. 部分 URL,比如 主机名:

4. 只有路径的 URL:

面对可能存在 SSRF 漏洞的地方,我们需要反复试验才能找到有效负载。如果使用的是盲 SSRF,其输出不会反馈在屏幕上,因此需要使用外部 HTTP 日志工具来监控请求,比如 requestbin.com,又或者是 我们自己的 HTTP 服务器 或 BurpSuite 的 Collaborator 客户端。

Defeating common SSRF defenses

意识到 SSRF 漏洞风险的且安全意识较高的开发人员可能会在 Web 应用中实施检查,以确保请求的资源符合特定规则。通常有三种方法:

Deny list

拒绝列表 指除了列表中指定的资源或与特定模式匹配的资源外,所有请求都被接受。Web 应用可以使用拒绝列表保护 敏感端点、IP地址 或 不被公众访问的域,同时仍允许访问其他位置。限制访问的一个特定端点就是 localhost,它可能会包含服务器性能数据或更多敏感信息。但攻击者可通过使用其他 localhost 引用 (如 0、0.0.0.0、0000、127.1、127.*.*.*、2130706433、017700000001)或具有解析到 IP 地址 127.0.0.1 的 DNS 记录 (如 127.0.0.1.nip.io)的子域来绕过拒绝列表。

此外在云环境中,阻止对 IP 地址 169.254.169.254 也是有用的。因为该 IP 地址包含已部署云服务器的元数据,其中可能包含敏感信息。攻击者可以通过在自己的域上注册一个子域,并将 DNS 记录指向 IP 地址 169.254.169.254,从而绕过这一限制。

Allow list

允许列表 指除了出现在列表中或符合特定模式匹配的资源外,所有请求都被拒绝。比如参数中使用的 URL 必须以 https://website.thm 开头的规则,那么攻击者可以在其自己的域名上创建一个子域(如 https://website.thm.attackers-domain.thm)来快速规避这一规则。

Open redirect

如果上述的方法不起作用,还可以使用 开放式重定向 (Open redirect)。

开放式重定向 是服务器上的一个端点,网站访问者会被自动重定向到另一个网站地址,比如 https://website.thm/link?url=https://tryhackme.com。创建这种端点是为了记录访问者点击该链接的次数,以用于广告/营销目的。

但假如这里面存在一个潜在的 SSRF 漏洞,且其严格的规则只允许以 https://website.thm/ 开头的 URL,那么攻击者可以利用上述功能将内部 HTTP 请求重定向到攻击者选择的域上。

Practical

现在有一个网站页面,它有两个目录。一个是 /private 目录,但它无法在当前 IP 地址上被访问:

另一个是 /customers/new-account-page,这是新版的用户账户页面,允许用户选择头像:

首先我们查看这些图像的信息,通过开发者工具可以看到图像的字段中包含了它们的路径:

而当某一图像被选择为头像时,它就用 data URI 显示了,其中使用了 Base64 编码:

现在我们尝试修改图片路径为 /private:

然后把这个修改过的图片更新为自己的头像后发现:

URL 不能以 private 开始。那我们就不以 private 开始,同时最后得到的就是 private  中的内容,即构造一个 URL 为 x/../private:

再次将修改后的图片更新为头像,发现一串 base64 编码:

将其解码后,得到 flag:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/441240.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kubelet 运行机制、功能 全面分析

Kubelet 在Kubernetes集群中&#xff0c;在每个Node&#xff08;又称为Minion&#xff09;上都会启动一个Kubelet服务进程。该进程用于处理Master下发到本节点的任务&#xff0c;管理Pod及Pod中的容器。每个Kubelet进程都会在API Server上注册节点自身的信息&#xff0c;定期向…

攻防世界----->Replace

前言&#xff1a;做题笔记。 下载 查壳。 upx32脱壳。 32ida打开。 先运行看看&#xff1a; 没有任何反应&#xff1f; 猜测又是 地址随机化(ASLR)---遇见过。 操作参考&#xff1a; 攻防世界----&#xff1e;Windows_Reverse1_dsvduyierqxvyjrthdfrtfregreg-CSDN博客 然后…

算法6:模拟运算

文章目录 z字形变幻外观数列数青蛙 题目均来自于力扣 z字形变幻 class Solution { public:string convert(string s, int numRows) {int n s.size();if(n < numRows || numRows 1) return s;int d 2 * numRows - 2;string res;for(int j 0; j < n; j d){res s[j]; …

嵌入式硬件设计知识详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

游戏盒子推广全攻略:从用户洞察到策略实施

在移动互联网时代&#xff0c;游戏盒子的推广已经成为众多游戏代理商和开发者的重要课题。面对激烈的市场竞争&#xff0c;如何高效吸引并留住玩家&#xff0c;成为游戏盒子推广的关键。本文将结合Xinstall这一专业App推广工具&#xff0c;探讨游戏盒子推广的有效策略。 一、市…

爱心曲线公式大全

local r a*((math.sin(angle) * math.sqrt(math.abs(math.cos(angle)))) / (math.sin(angle) 1.4142) - 2 * math.sin(angle) 2) local x r * math.cos(angle) -- 计算对应的x值 local z r * math.sin(angle) 1.5*a - --曲线公式绘画 local function generateParabola()…

VMware Tools 安装和配置

1. 使用 ISO 映射文件&#xff0c;并且选择.iso文件 2. 启动虚拟机&#xff0c;如果 VMware Tools 是灰色的&#xff0c;那么卸载 open-vm-tools&#xff08;不要重装&#xff09;&#xff0c;重新启动虚拟机。卸载可以参考&#xff1a;重装 open-vm-tools-CSDN博客 3. 拷贝挂载…

关于mac下的nvm设置淘宝镜像源

1. 进入配置文件修改镜像源 vim ~/.bash_profile增加下面内容 export NVM_NODEJS_ORG_MIRRORhttps://npmmirror.com/mirrors/node/2. 查看远程node镜像 nvm ls-remote3. 下载镜像 nvm install 14.17.64. 使用镜像 nvm use 14.17.6

Vue入门-指令学习-v-show和v-if

v-show&#xff1a; 作用&#xff1a;控制元素的显示隐藏 语法&#xff1a;v-show"表达式" 表达式值true显示&#xff0c;false隐藏 v-if 作用&#xff1a;控制元素的显示隐藏&#xff08;条件渲染&#xff09; 语法&#xff1a; vif"表达式" 表达式tr…

No.8 笔记 | SQL 查询语句:数据探索的钥匙

2024/10/7 心记 - 致在路上默默奋斗的你 在当今数字化的时代&#xff0c;网络安全已成为我们生活中不可或缺的一部分。它如同守护数字世界的隐形盾牌&#xff0c;保护着我们的隐私、数据和整个社会的稳定运行。 学习网络安全&#xff0c;是踏上一段充满挑战与机遇的征程。 每一…

leetcode C++特性 AIDL的一些细节

leetcode细节 C的一些特性 【C基础】std::move用法介绍-CSDN博客 c thread的join和joinable的区别_thread joinable-CSDN博客 C线程介绍_std::thread 头文件-CSDN博客 https://blog.csdn.net/weixin_46645965/article/details/136259902 【C】—— 观察者模式-CSDN博客 C 迭…

知识图谱入门——5:Neo4j Desktop安装和使用手册(小白向:Cypher 查询语言:逐步教程!Neo4j 优缺点分析)

Neo4j简介 Neo4j 是一个基于图结构的 NoSQL 数据库&#xff0c;专门用于存储、查询和管理图形数据。它的核心思想是使用节点、关系和属性来描述数据。图数据库非常适合那些需要处理复杂关系的数据集&#xff0c;如社交网络、推荐系统、知识图谱等领域。 与传统的关系型数据库…

erlang学习:Linux命令学习9

sed命令介绍 sed全称是&#xff1a;Stream EDitor&#xff08;流编辑器&#xff09; Linux sed 命令是利用脚本来处理文本文件&#xff0c;sed 可依照脚本的指令来处理、编辑文本文件。Sed 主要用来自动编辑一个或多个文件、简化对文件的反复操作、编写转换程序等 sed 的运行…

Windows环境下使用Docker配置MySQL数据库

用Docker配置数据库&#xff0c;无论是做开发&#xff0c;还是做生产部署&#xff0c;都非常的方便 它不需要单独安装数据库&#xff0c;也不用担心出现各种环境的配置问题。 本文将分享用Docker配置数据库的步骤&#xff0c;这里用MySQL举例。 其他的数据库如MSSQL&#xf…

信息学奥赛复赛复习14-CSP-J2021-03网络连接-字符串处理、数据类型溢出、数据结构Map、find函数、substr函数

PDF文档回复:20241007 1 P7911 [CSP-J 2021] 网络连接 [题目描述] TCP/IP 协议是网络通信领域的一项重要协议。今天你的任务&#xff0c;就是尝试利用这个协议&#xff0c;还原一个简化后的网络连接场景。 在本问题中&#xff0c;计算机分为两大类&#xff1a;服务机&#x…

12.3 Linux_进程间通信_信号机制

概述 什么是信号&#xff1a; 信号是在软件层次上对中断机制的模拟&#xff08;软中断&#xff09;&#xff0c;是一种异步通信方式。 进程对信号的响应方式&#xff1a; 缺省方式&#xff1a;根据默认行为响应信号忽略信号&#xff1a;不响应信号捕捉信号&#xff1a;根据…

SpringBoot系列 启动流程

文章目录 SpringApplicationSpringApplication#run 启动流程BootstrapContextSpringApplicationRunListenersprepareEnvironmentconfigureEnvironmentconfigurePropertySourcesconfigureProfiles 上下文初始化prepareContextrefreshContextprepareRefreshobtainFreshBeanFactor…

MISC - 第13天(python脚本 重命名文件,拼接二维码,cloacked-pixel工具,中文电码,五笔编码)

前言 各位师傅大家好&#xff0c;我是qmx_07&#xff0c;今天继续讲解MISC的相关知识 [安洵杯 2019]吹着贝斯扫二维码 附件信息: 使用APCHPR暴力破解工具&#xff0c;flag.zip 破解失败可能线索在其他文件&#xff0c;放到hxd查看 在hxd中&#xff0c;发现该文件头JFIF 是j…

晶体规格书及匹配测试

一、晶体参数介绍 晶体的电气规格相对比较简单,如下: 我们逐一看看每个参数, FL就是晶体的振动频率,这个晶体是24.576MHz的。 CL就是负载电容,决定了晶体频率是否准确,包括外接的实际电容、芯片的等效电容以及PCB走线的寄生电容等,核心参数。 Frequency Tolerance是…

matlab碳交易机制下考虑需求响应的综合能源系统优化运行

目录 1 主要内容 架构模型&#xff1a; 需求响应模型&#xff1a; 目标函数&#xff1a; 对比算例设计&#xff1a; 2 部分程序 3 程序结果 4 下载链接 1 主要内容 该程序复现文献《碳交易机制下考虑需求响应的综合能源系统优化运行》&#xff0c;解决碳交易机制下考虑…