Fastjson
https://blog.csdn.net/m0_46363249/article/details/122260021
Fastjson可以将对象转换成Json字符串,XMLDecoder 可以将XML字符串还原成字符串,所以也是序列化和反序列化
与原生的java反序列化相比,FastJson未使用readObject()方法进行反序列化,而是使用了自定义的一套方法,在反序列化的过程中,调用getter和setter方法将JSON字符串还原成对象。
parseObject(String text)将JSON还原成对象时,FastJson自动调用类中的setter方法和无参构造函数,以及满足条件的getter方法
TemplatesImpl 利用链分析
首先使用parseObject对payload进行反序列化。parseObject会调用payload中存储的@type信息,即Templateslmpl的getter,setter,和构造方法。
大概流程是先创建一个TemplatesImpl对象,再使用Javassist动态编程创建一个恶意类,由于这个恶意类是自定义的,因此可以通过该类执行任何想要执行的代码,比如Runtime.getRuntime().exec(“calc.exe”)。一个类在初始化时会自动执行静态代码块里的代码,因此可以将Runtime.getRuntime().exec(“calc.exe”)写在恶意类的静态代码块中,在初始化的过程中自动执行。恶意类会被转化成一个byte数组,并传递给TemplatesImpl的_ bytecodes属性。
在请求包里面中发送恶意的json格式payload,漏洞在处理json对象的时候,没有对@type字段进行过滤,从而导致攻击者可以传入恶意的TemplatesImpl类,而这个类有一个字段就是bytecodes,有部分函数会根据这个bytecodes生成java实例,这就达到fastjson通过字段传入一个类,再通过这个类被生成时执行构造函数
修复:引入了checkAutotype,其中增加了黑白名单的校验,用于缓解反序列化漏洞的产生,并且将内置的黑白名单进行加密,增加了绕过黑白名单的研究成本。因此后面发现的Fastjson反序列化漏洞都是针对黑名单的绕过来实现攻击利用的
shiro
shiro默认使用了CookieRememberMeManager,其处理cookie的流程是:得到rememberMe的cookie值–>Base64解码–>AES解密–>反序列化
只要rememberMe的AES加密密钥泄漏,无论shiro什么版本都会导致反序列化漏洞。
shiro 550
AES的密钥是硬编码的,就导致了攻击者可以构造恶意数据造成反序列化的RCE漏洞。
攻击者可以使用Shiro的默认密钥构造恶意序列化对象进行编码来伪造用户的Cookie,服务端反序列化时触发漏洞,从而执行命令。
Shiro Padding Oracle Attack(Shiro-721 CVE-2019-12422)
Shiro使用AES-CBC模式进行加解密,存在Padding Oracle Attack漏洞,已登录的攻击者同样可进行反序列化操作
Struts2
https://blog.csdn.net/qq_43531669/article/details/124970785
https://blog.csdn.net/weixin_44971640/article/details/128399754
S2-001(OGNL 循环解析导致的 RCE 漏洞)
用户提交表单数据并且验证失败时,后端会将用户之前提交的参数值使用 OGNL 表达式 %{value} 进行解析,然后重新填充到对应的表单数据中。例如注册或登录页面,提交失败后端一般会默认返回之前提交的数据,由于后端使用 %{value} 对提交的数据执行了一次 OGNL 表达式解析,所以可以直接构造 Payload 进行命令执行
S2-003
struts2会将 http 的每个参数名解析为 OGNL 语句执行(可理解为java代码)。OGNL表达式通过#来访问 Struts 的对象,Struts框架通过过滤#字符防止安全问题,然而通过 unicode 编码(\u0023)或8进制(\43)就可以绕过安全限制。
S2-007(验证类型转换错误时,会导致二次表达式解析)
S2-007漏洞一般出现在表单处,当配置了验证规则 <ActionName>-validation.xml 时,若类型验证转换出错,后端默认会将用户提交的表单值通过字符串拼接,然后执行一次 OGNL 表达式解析并返回。
S2-012 远程代码执行漏洞 (CVE-2013-1965)
漏洞原理: 重定向的路径中使用了 %{} 导致了的 RCE 漏洞
漏洞触发原理与 S2-001 类似,对 %{} 表达式进行了循环解析。
Struts2框架识别
(1)通过网页后缀来进行判断,如 .do 或者 .action(2)通过 /struts/webconsole.html 是否存在来进行判断,需要 devMode 为true。(3)通过页面回显的错误消息来判断,页面不回显错误消息时则无效。(4)通过 actionErrors。要求是对应的 Action 需要继承自 ActionSupport 类。如:原始 URL 为 https://xxx.com/ 则检测所用的 URL 为 https://xxx.com/?actionErrors=1111
log4j
Log4j为了输出日志时能输出任意位置的Java对象,引入了Lookup接口,这个Lookup接口可以看作是JNDI的一种实现,允许按照具体的名称逻辑查找对象的位置,并输出对象的内容,此对象可以通过Java的序列化或反序列化传输,从远程服务器上查找。
由于Lookup接口的原因,Log4j就暗含JNDI注入漏洞,可以联合使用JNDI+LDAP或者JNDI+RMI通过命名功能直接从远程服务器上调用文件并在本地执行。
Log4j在处理消息转换时,会按照字符检测每条日志,当日志中包含${}时,则会将表达式的内容替换成真实的内容(即lookup接口查找得到的内容),使用LDAP或RMI协议,能从远程服务区上请求恶意的对象,对象在调用的过程中会被解析执行,导致了Log4j的漏洞
LDAP(Ligntweight Directory Access Protocol),轻量级目录访问协议,既是一种服务,也是一种协议,是JNDI的一种底层实现,主要功能是提供命名关键字到对象的映射目录,开发人员可以通过输入名称,获取到对象的内容
JNDI(Java Naming and Directory Interface),JAVA命名和目录接口(命名服务接口),应用通过该接口与具体的目录服务进行交互,允许通过名称发现和查找数据或对象,可用于动态加载配置等。
RMI(远程方法调用):它是一种机制,能够让在某个java虚拟机上的对象调用另一个Java虚拟机 的对象的方法
Apache Log4j2中存在JNDI注入漏洞,主要原理是利用log4j2的日志输出jndi远程对象时,调用远程对象没做检查导致,程序将用户输入的数据进行日志记录时即可触发该漏洞并可在目标服务器上执行任意代码。该漏洞利用过程需要找到一个能触发远程加载并应用配置的输入点,迫使服务器远程加载和修改配置的前提下使目标系统通过JNDI远程获取数据库源,触发攻击者的恶意代码
weblogic
https://blog.csdn.net/Bossfrank/article/details/130778724
Weblogic的WLS Security组件对外提供webservice服务,其中使用了XMLDecoder来解析用户传入的XML(SOAP协议)数据,在解析的过程中出现反序列化漏洞,导致任意代码执行。出问题的包是wls-wsat、_async
Weblogic是用于解析java,部署大型分布式Web应用的Web中间件
XMLDecoder 读取使用 XMLEncoder 创建的XML文档获取JavaBeans,用来解析XML文档的。
https://blog.csdn.net/rumil/article/details/133036788
CVE-2018-2628
Weblogic Server中的RMI 通信使用T3协议在Weblogic Server和其它Java程序(客户端或者其它Weblogic Server实例)之间传输数据
攻击者可以通过T3协议发送恶意的的反序列化数据, 进行反序列化, 实现对存在漏洞的weblogic组件的远程代码执行攻击(开放Weblogic控制台的7001端口,默认会开启T3协议服务,T3协议触发的Weblogic Server WLS Core Components中存在反序列化漏洞,攻击者可以发送构造的恶意T3协议数据,获取目标服务器权限。)
CVE-2023-21839
weblogic的JNDI注入漏洞。
由于Weblogic t3/iiop协议支持远程绑定对象bind到服务端,并且可以通过lookup查看,当远程对象继承自OpaqueReference时,lookup查看远程对象,服务端会调用远程对象getReferent方法。weblogic.deployment.jms.ForeignOpaqueReference继承自OpaqueReference并且实现了getReferent方法,并且存在retVal = context.lookup(this.remoteJNDIName)实现,故可以通过rmi/ldap远程协议进行远程命令执行。
Spring
https://github.com/izj007/wechat/blob/main/articles/%5B%E6%B8%97%E9%80%8FXiao%E7%99%BD%E5%B8%BD%5D-2021-9-3-%E3%80%90%E5%B9%B2%E8%B4%A7%E3%80%91Spring%E6%A1%86%E6%9E%B6%E6%BC%8F%E6%B4%9E%E6%B8%97%E9%80%8F%E6%80%BB%E7%BB%93.md
SpEL(Spring Expression Language)是基于spring的一个表达式语言,类似于struts的OGNL,能够在运行时动态执行一些运算甚至一些指令,类似于Java的反射功能。
Spring Security OAuth2 远程命令执行
Spring Security OAuth2处理认证请求的时候如果使用了whitelabel views,response_type参数值会被当做Spring SpEL来执行,攻击者可以在被授权的情况下通过构造response_type值也就是通过构造恶意SpEL表达式可以触发远程代码执行漏洞。故是在需要知道账号密码的前提下才可以利用该漏洞。
Spring Web Flow框架远程代码执行
Spring Web Flow是Spring的一个子项目,主要目的是解决跨越多个请求的、用户与服务器之间的、有状态交互问题,提供了描述业务流程的抽象能力。
在其 2.4.x 版本中,如果我们控制了数据绑定时的field,将导致一个SpEL表达式注入漏洞,最终造成任意命令执行。
内存马
Webshell内存马,是在内存中写入恶意后门和木马并执行,达到远程控制Web服务器的一类内存马,其瞄准了企业的对外窗口:网站、应用。但传统的Webshell都是基于文件类型的,黑客可以利用上传工具或网站漏洞植入木马,区别在于Webshell内存马是无文件马,利用中间件的进程执行某些恶意代码,不会有文件落地,给检测带来巨大难度。
目标:访问任意url或者指定url,带上命令执行参数,即可让服务器返回命令执行结果
实现:以java为例,客户端发起的web请求会依次经过Listener、Filter、Servlet三个组件,我们只要在这个请求的过程中做手脚,在内存中修改已有的组件或者动态注册一个新的组件,插入恶意的shellcode,就可以达到我们的目的。
内存马可以划分为两种类型
1.servlet-api型
通过命令执行等方式动态注册一个新的listener、filter或者servlet,从而实现命令执行等功能。特定框架、容器的内存马原理与此类似,如spring的controller内存马,tomcat的valve内存马
2.字节码增强型
通过java的instrumentation动态修改已有代码,进而实现命令执行等功能。
java内存马原理:通过在Java虚拟机(JVM)中运行的恶意代码,实现对被攻击者系统的远程控制。其原理是通过在Java虚拟机中注入特定的Java类、变量或方法等Java对象,然后在Java虚拟机中运行这些代码,实现对受害者机器的远程控制
java内存马排查:
利用Java Agent技术遍历所有已经加载到内存中的class。
先判断是否是内存马,是则进入内存查杀。
识别:1,filter名字很特别 2,filter优先级是第一位 3,对比web.xml中没有filter配置 4,特殊classloader加载 5,对应的classloader路径下没有class文件 7,Filter的doFilter方法中有恶意代码
清除:1、清除内存马中的Filter的恶意代码,2、 模拟中间件注销Filter