Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
log4shell-example — 이 프로젝트의 목표는 spring-boot 설정에서 log4j cve-2021-44228 악용 취약점을 시연하고, 이를 수정하는 방법을 보여주는 것입니다. | Kitploit
도구/GitHubGitHub/chilit-nl/log4shell-example
Vulnerability AnalysisCode AnalysisExploitationWeb SecurityLearning & EducationLabs & Practice
GitHubchilit-nl/log4shell-example

log4shell-example

이 프로젝트의 목표는 spring-boot 설정에서 log4j cve-2021-44228 악용 취약점을 시연하고, 이를 수정하는 방법을 보여주는 것입니다.

저장소 보기
2164년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Log4Shell 익스플로잇 테스트

이 프로젝트의 목표는 spring-boot 설정에서 log4j cve-2021-44228 익스플로잇 취약점을 시연하고, 이를 수정하는 방법을 보여주는 것입니다.

이 프로젝트는 세 개의 하위 모듈을 포함합니다. 그중 하나는 취약한 코드를 가지고 있고, 나머지 두 개는 패치되었습니다.

이 프로젝트 사용 방법

두 모듈 모두에서 테스트를 실행하려면 프로젝트 루트에서 ./mvnw clean test를 실행하세요. log4shell-example-unpatched에서 많은 예외가 발생하는 것을 볼 수 있습니다(테스트는 여전히 통과합니다. 이는 예상된 동작입니다). 그 이유는 연결하려는 서버로부터 올바른 응답을 받지 못하기 때문입니다.

언제 취약한가요?

다음과 같은 경우 애플리케이션이 취약합니다: 기본 로거를 재정의하여 log4j2 구현을 사용하지만 사용되는 log4j2 버전을 재정의하지 않은 경우입니다. pom은 다음과 같이 보일 것입니다:```xml org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-logging

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
`log4shell-example-unpatched`에서 테스트를 실행하면 로그 호출이 이제 취약해졌음을 알 수 있습니다. 이 테스트는 로그 호출이 취약할 때 성공합니다.

### 자체 애플리케이션의 취약 여부를 확인하기 위해 Spring 통합 테스트 사용하기

#### 1. 프로젝트에 `Log4ShellTest` 추가

`log4shell-example-patched-version`에서 `Log4ShellTest`를 프로젝트에 추가합니다:```java
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

@SpringBootTest
@Import(Log4ShellTest.Log4ShellConfig.class)
public class Log4ShellTest {

    @Autowired
    private List<Log4ShellService> servicesToTest;

    @Test
    public void testVulnerabilityPatched() throws Exception {

        CountDownLatch waitLatch = new CountDownLatch(1);
        AtomicInteger connectionAttemptCounter = new AtomicInteger();
        Thread listener = new Thread(() -> {
            try {
                ServerSocket socket = new ServerSocket(22345);
                while(true) {
                    waitLatch.countDown();
                    Socket connection = socket.accept();
                    connectionAttemptCounter.getAndIncrement();
                    connection.close();
                }
            }
            catch(IOException ex) {
                throw new IllegalStateException(ex);
            }
        });
        listener.start();
        waitLatch.await();

        servicesToTest.forEach(service -> service.testLog("${jndi:ldap://127.0.0.1:22345}"));

        Assertions.assertEquals(0, connectionAttemptCounter.get());
        // If you're not using lombok, change the 6 to 2
        Assertions.assertEquals(6, servicesToTest.size());

        listener.interrupt();

    }

    @Configuration
    @ComponentScan
    public static class Log4ShellConfig {

    }

    public interface Log4ShellService {
        void testLog(String arg);
    }

    @Component
    public static class Service1 implements Log4ShellService {

        private static final Logger logger = LogManager.getLogger("Test");

        @Override
        public void testLog(String arg) {
            logger.info("Test: " + arg);
        }
    }

    @Component
    public static class Service2 implements Log4ShellService {

        private static final Logger logger = LogManager.getLogger("Test");

        @Override
        public void testLog(String arg) {
            logger.info("Test: {}", arg);
        }
    }

    // Remove this class if you're not using lombok
    @Component
    @Slf4j
    public static class Service3 implements Log4ShellService {

        @Override
        public void testLog(String arg) {
            log.info("Test: {}", arg);
        }
    }

    // Remove this class if you're not using lombok
    @Component
    @Slf4j
    public static class Service4 implements Log4ShellService {

        @Override
        public void testLog(String arg) {
            log.info("Test: " + arg);
        }
    }

    // Remove this class if you're not using lombok
    @Component
    @Log4j2
    public static class Service5 implements Log4ShellService {

        @Override
        public void testLog(String arg) {
            log.info("Test: {}", arg);
        }
    }

    // Remove this class if you're not using lombok
    @Component
    @Log4j2
    public static class Service6 implements Log4ShellService {

        @Override
        public void testLog(String arg) {
            log.info("Test: " + arg);
        }
    }

}

2. 이 테스트가 실패하는지 확인하세요

도구 다운로드