查看: 15834|回复: 0

multipart/form-data PHP和Java通用的WAF绕过方法

[复制链接]
  • TA的每日心情

    5 天前
  • 签到天数: 1631 天

    [LV.Master]伴坛终老

    发表于 2015-11-30 14:07:59 | 显示全部楼层 |阅读模式
    PS:园长的文章,我无耻的给转了过来。
    依旧是multipart/form-data,去年的时候说道了利用PHP的特性去绕过WAF.轻松绕各种WAF的POST注入、跨站防御(比如安全狗)
    原文简单的描述了PHP在处理POST请求的时候会解析multipart/form-data的内容。
    那么这个multipart/form-data到底是个啥呢?
    2015113001120915200.png.jpeg
    大概长成上面这样.HTML代码就更加简单了:
    [HTML] 纯文本查看 复制代码
    <!DOCTYPE html> 
    <html> 
    <head> 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
    <title>yzmm - p2j.cn</title> 
    </head> 
    <body> 
      <form action="http://192.168.199.151/index.php" method="POST" enctype="multipart/form-data"> 
           File:<input type="file" name="file" /><br/> 
            ID:<input type="text" name="id" value="select 1 from mysql.user--" style="width:250px;" / ><br/> 
            <input type="submit" value="提交" /> 
        </form> 
    </body> 
    </html>


    这个特性其实并不只是PHP的专利,许多其他语言的MVC框架为了简化操作也有可能会做类似PHP FILES解析。虽说原生的JSP/Servlet是不支持解析multipart的.但在Java语言中当今最火的SpringMVC、Struts2都做了一样的事情。你可能经常会看到如下的Spring MVC代码:
    [Java] 纯文本查看 复制代码
    import javax.servlet.http.HttpServletRequest; 
    import javax.servlet.http.HttpServletResponse; 
    import org.springframework.stereotype.Controller; 
    import org.springframework.web.bind.annotation.RequestMapping; 
    import org.springframework.web.bind.annotation.RequestParam; 
    import org.springframework.web.multipart.MultipartFile; 
    
    @Controller 
    public class TestController { 
    
      @RequestMapping("/test1.aspx") 
      public void test1(HttpServletRequest request,HttpServletResponse response){ 
        System.out.println("test1.aspx:"+request.getParameter("username")); 
      } 
    
      @RequestMapping("/test2.aspx") 
      public void test2(@RequestParam(value = "file", required = false) MultipartFile file,HttpServletRequest request,HttpServletResponse response){ 
        System.out.println("test2.aspx:"+request.getParameter("username")); 
        System.out.println("文件名:"+file.getOriginalFilename()); 
      } 
    }

    然后是HttpClient客户端测试代码,用于发送HTTP Multipart测试请求:
    [Java] 纯文本查看 复制代码
    import java.io.File; 
    import java.io.IOException; 
    
    import org.apache.commons.io.IOUtils; 
    import org.apache.http.HttpEntity; 
    import org.apache.http.client.methods.CloseableHttpResponse; 
    import org.apache.http.client.methods.HttpPost; 
    import org.apache.http.entity.ContentType; 
    import org.apache.http.entity.mime.MultipartEntityBuilder; 
    import org.apache.http.impl.client.CloseableHttpClient; 
    import org.apache.http.impl.client.HttpClients; 
    
    public class MultipartTest { 
       
      public static void main(String[] args) { 
        CloseableHttpClient httpClient = HttpClients.createDefault(); 
        HttpPost uploadFile = new HttpPost("http://localhost:8080/test/test1.aspx"); 
        MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
        builder.addTextBody("username", "admin", ContentType.TEXT_PLAIN); 
        builder.addTextBody("password", "123456", ContentType.TEXT_PLAIN); 
        builder.addBinaryBody("file", new File("/Users/yz/Downloads/bd_logo1_31bdc765.png"), ContentType.APPLICATION_OCTET_STREAM, "pic"); 
        HttpEntity multipart = builder.build(); 
        uploadFile.setEntity(multipart); 
        try { 
          CloseableHttpResponse response = httpClient.execute(uploadFile); 
          HttpEntity responseEntity = response.getEntity(); 
          System.err.println(IOUtils.toString(responseEntity.getContent())); 
        } catch (IOException e) { 
          e.printStackTrace(); 
        } 
      } 
    
    }

    pom 依赖的jar:
    [Java] 纯文本查看 复制代码
    <dependency> 
          <groupId>org.apache.httpcomponents</groupId> 
          <artifactId>httpcore</artifactId> 
          <version>4.4.4</version> 
        </dependency> 
    
        <dependency> 
          <groupId>org.apache.httpcomponents</groupId> 
          <artifactId>httpclient</artifactId> 
          <version>4.5.1</version> 
        </dependency> 
    
        <dependency> 
          <groupId>org.apache.httpcomponents</groupId> 
          <artifactId>httpasyncclient</artifactId> 
          <version>4.1.1</version> 
        </dependency> 
    
        <dependency> 
          <groupId>org.apache.httpcomponents</groupId> 
          <artifactId>httpmime</artifactId> 
          <version>4.5.1</version> 
        </dependency> 
    
        <dependency> 
          <groupId>commons-io</groupId> 
          <artifactId>commons-io</artifactId> 
          <version>2.4</version> 
        </dependency>

    test1.do是一个最普通的Http请求Mapping,如果当前请求类型是一个multipart请求Spring MVC会将解析好的multipart放到request里面(其实是Spring MVC包装了一个HTTP请求,类名是rg.springframework.web.multipart.support.DefaultMultipartHttpServletRequest)。于是我们在控制层就拿到了multipart里的username参数。

    毫无疑问,使用MultipartTest的测试代码去请求test1.aspx会输出multipart内的username的值:admin.
    2015113001363238802.png.jpeg
    Struts2实现方式和SpringMVC大同小异,同样的也自动的利用commons-fileupload做了HTTP解析。
    2015113001403316348.png.jpeg
    [Java] 纯文本查看 复制代码
    import javax.servlet.http.HttpServletRequest; 
    import org.apache.struts2.ServletActionContext; 
    import com.opensymphony.xwork2.ActionSupport; 
    
    public class Test extends ActionSupport { 
    
      private static final long serialVersionUID = 1L; 
    
      @Override 
      public String execute() throws Exception { 
        HttpServletRequest request = ServletActionContext.getRequest(); 
        System.out.println(request.getParameter("username")); 
        return "input"; 
      } 
    
    }

    那么为什么一个看似很简单的表单数据请求解析的功能会让很多的WAF蒙了呢?究其原因主要还是因为HTTP请求解析的复杂性和来自客户端的数据不确定性。因为上传一个几十M甚至更大的文件需求再平常不过了,如果WAF完整的去解析这个InputStream会消耗大量的服务器性能有点得不偿失。
    另一个原因是由于实现HTTP请求的RFC的差异性导致次类请求解析得不一致或者解析错误的情况。因为multipart解析出问题的还不少。去年PHP和Apache Commons FileUpload 就出过DOS漏洞。



    那么问题来了,各位同学的SQL注入和Struts2的命令执行漏洞真的修好了吗?看看loopx9牛的这个漏洞就知道了 WooYun: 百度某站st2命令执行(独特执行姿势)
    赶紧回家修补丁吧。

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    指导单位

    江苏省公安厅

    江苏省通信管理局

    浙江省台州刑侦支队

    DEFCON GROUP 86025

    旗下站点

    邮箱系统

    应急响应中心

    红盟安全

    联系我们

    官方QQ群:112851260

    官方邮箱:security#ihonker.org(#改成@)

    官方核心成员

    Archiver|手机版|小黑屋| ( 苏ICP备2021031567号 )

    GMT+8, 2024-12-19 00:36 , Processed in 0.030191 second(s), 17 queries , Gzip On, MemCache On.

    Powered by ihonker.com

    Copyright © 2015-现在.

  • 返回顶部