Thymeleaf模板注入学习
date
Jan 13, 2022
slug
thymeleaf-ssti-learn
status
Published
tags
Java安全
安全研究
summary
Thymeleaf模板注入学习
type
Post
这个东西本质上到最后利用的还是表达式执行
Thymeleaf这东西底层使用SPEL还是OGNL得看它上层使用的是什么东西,如果是使用的Spring,最后就会使用Spel解析
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F3ecb455e-ab15-4867-9afb-e9e5be6b1f0b%2FUntitled.png%3Fid%3D10236709-41ee-44b5-a029-68a4ac680601%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3D3KBVEOEjMVj9q7xrF6gMCwVJ-eS0fh8T2qTc3MfDn6k?table=block&id=10236709-41ee-44b5-a029-68a4ac680601&cache=v2)
因为Spring推荐用的这个模板,所以会在Spring框架中经常出现
在这篇文章中,提及到这个模版有一个危险的特性:
preprocessed
,预处理他的格式是这样的:
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2Fdc59d41a-2694-4eb5-a611-80940f75969c%2FUntitled.png%3Fid%3Db68203d5-e92d-401f-9421-083c5dbe8346%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3Ds6jyxSQu2Idrz5r3ubFlQyqfOIN3kwY4Nbb6nbnAbeA?table=block&id=b68203d5-e92d-401f-9421-083c5dbe8346&cache=v2)
在双下划线下里面的内容会被提前渲染,并且会执行达到模版注入的问题,但是在Tomcat下这个问题可能会失去效果,当输入点在path的时候,原因如下:Tomcat在处理path的时候是不允许存在大括号这样的符号,而且编码处理之后输入到恶意触发点是没有解码的内容,无法执行
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F148b37de-9739-460c-bc93-71f4ae75726b%2FUntitled.png%3Fid%3D0fa31b0d-bf49-41bd-b206-087e3e5ac60f%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3D9bFvffa81tSLbyUeCmpn8QE-YG3fjmyByfjfl4vfduc?table=block&id=0fa31b0d-bf49-41bd-b206-087e3e5ac60f&cache=v2)
实际应用
由于上述内容里面表明这个模板存在预处理的模式,在实际场景中会是怎么应用?这篇文章给出了demo和实验代码
介绍了Thymeleaf这个模板的一些使用方法,包括可以只调用模板的某一块内容
另外展现了三种坑会出现漏洞得点
其中两种是这样的:
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F694d59b6-498f-4183-9893-3b27fff792da%2FUntitled.png%3Fid%3D08c4e71d-6cd6-4fda-b7ee-a6370424b213%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3D4Yc1ouXNKED2JuoKPOwubrJuLz02dn0Ptj7FLNSYKfM?table=block&id=08c4e71d-6cd6-4fda-b7ee-a6370424b213&cache=v2)
底层原理是Spring在处理这个模板的内容的时候,在寻找渲染文件路径的时候会有一个表达式执行的过程,但是这个也是有条件的,需要payload里面包含
::
这么一个符号,这里的表达式执行函数就是Thymeleaf的表达式执行函数了,第二个参数的那串字符串就是需要执行的内容![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F293114f0-7054-4f3d-aa98-a8ec74004e77%2FUntitled.png%3Fid%3D8bdbc82a-1ac7-44fe-bb1c-835fde930f5e%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3DnxvBPDo6CHqi2KbKEZB3PNIx6Dj70StjtcqSJHtNAE8?table=block&id=8bdbc82a-1ac7-44fe-bb1c-835fde930f5e&cache=v2)
根据这个模版预处理的特性,需要在里面添加
__xxx__
的内容了,就可以触发针对第一种情况,渲染路径可控,我们只需要传入这样的内容
/path?lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22id%22).getInputStream()).next()%7d__::.x
实际上最后的.x可以省略,这只是个随意编写的后缀而已,可以随意添加,但是
::
不可省略,是进入漏洞代码的关键条件![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2Fa6861305-389f-4d09-8ccb-4e8fea684083%2FUntitled.png%3Fid%3Dc5178054-1da5-4c27-b808-edd157f0ce38%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3DHIVtweU7N3SPLQ55hsqAixNoUTU9tGiOrrJByl5hjQY?table=block&id=c5178054-1da5-4c27-b808-edd157f0ce38&cache=v2)
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2Ffc49c485-a96d-4377-8ff2-d4ad113a1237%2FUntitled.png%3Fid%3Dae831ce5-e294-45b6-a70c-2091595dff88%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3Dlq97rH0irMjYkybYf0KzcGmOofKq0EnkPe34ar44Xo4?table=block&id=ae831ce5-e294-45b6-a70c-2091595dff88&cache=v2)
针对第二种情况,渲染的是某个页面的某一部分内容,这个内容可控,传入的内容是这样的
/fragment?section=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22touch%20executed%22).getInputStream()).next()%7d__::.x
但是本质上这里并不需要
::
,因为渲染的内容里面是包含::
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2Fa966ff6e-4fa1-4e93-80bf-38b45c0e6e62%2FUntitled.png%3Fid%3D4d1c6712-7b4e-4878-bedf-0314dbd49669%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3D-GWA62S9DybkzSY4gqsXz1mN2rVqIAQl9V1BS8YeDnE?table=block&id=4d1c6712-7b4e-4878-bedf-0314dbd49669&cache=v2)
还有第三种情况,就是当Spring返回void的时候,此时会选择URL的路径变成可控点
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F4af2327c-9d13-436b-8ff0-2b4c4a97fc33%2FUntitled.png%3Fid%3Dc225f30e-b0d1-4828-ac13-d2e460ccb307%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3DWJ-NaRnpSUN36M-GlD_JbMD1O_9hCl-pmOl9xTFN3Ps?table=block&id=c225f30e-b0d1-4828-ac13-d2e460ccb307&cache=v2)
此时的攻击payload为,直接在路径上输入:
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2Fae6cdf00-cbc4-457e-852d-6d2d1470ec13%2FUntitled.png%3Fid%3Df329befe-fce8-469b-b67d-c27fcc7bedf3%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3DTDo8J2rpfKWCDU5L_AHcAsw1Pu1A71HuhbB8Op3mXXQ?table=block&id=f329befe-fce8-469b-b67d-c27fcc7bedf3&cache=v2)
如何防御
有三种解决方式:
![notion image](https://www.notion.so/image/https%3A%2F%2Ffile.notion.so%2Ff%2Ff%2Fc113620e-b4a6-4a92-bee1-d70b242f1a2f%2F9c8ab8d8-8404-442b-983b-cf045441382f%2FUntitled.png%3Fid%3D67ad66bf-bd3d-4c8b-873c-c617127281e0%26table%3Dblock%26spaceId%3Dc113620e-b4a6-4a92-bee1-d70b242f1a2f%26expirationTimestamp%3D1722067200000%26signature%3D-78srPDwyUdh-gQPKLP3ORM9nRUuhWzlBf5kanMUgwo?table=block&id=67ad66bf-bd3d-4c8b-873c-c617127281e0&cache=v2)
1.加上ResponseBody或者RestController注解,直接返回的HTTP Response
2.渲染路径上加上
redirect
关键字渲染3.
HttpServletResponse
加上 去框架就不会去寻找相关模板进行渲染