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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
hka-seminar-log4shell — Log4Shell 보안 취약점(CVE-2021-44228) 실습 시연 | Kitploit
도구/GitHubGitHub/fabioeletto/hka-seminar-log4shell
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationLabs & Practice
GitHubfabioeletto/hka-seminar-log4shell

hka-seminar-log4shell

Log4Shell 보안 취약점(CVE-2021-44228) 실습 시연

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Seminararbeit - Log4Shell-Schwachstellen-Demonstration (CVE-2021-44228)

보안 주의사항

이 저장소는 보안 관련 세미나 논문의 일환으로 교육 및 시연 목적으로만 사용됩니다. 본 코드를 프로덕션 환경이나 명시적 허가 없이 시스템에 사용하지 마십시오. 이 구성은 보안 인식을 높이고, 로깅, 이름 확인, 클래스 동적 로딩과 같은 겉보기에는 무해한 기능들이 결합될 때 복잡한 취약점이 어떻게 발생할 수 있는지 보여주기 위한 것입니다.

목차

  • 1. 프로젝트 설명

    • 1.1 세미나 논문의 목표
    • 1.2 시연 개요
  • 2. Log4Shell이란 무엇인가?

  • 3. 기술 구성 요소 상세

    • 3.1 Log4j - 작동 방식
    • 3.2 JNDI - 조회 메커니즘
    • 3.3 LDAP - 구조와 역할
    • 3.4 Log4Shell의 일반적인 흐름
  • 4. 프로젝트 구조 및 설정

    • 4.1 디렉터리 개요
    • 4.2 사전 요구 사항
    • 4.3 설정
  • 5. 프로젝트 데모

  • 6. 보호 조치

  • 7. 결론

  • 8. 출처

1. 프로젝트 설명

1.1 세미나 논문의 목표

이 세미나 논문의 목표는 2021년 12월에 알려지고 최근 몇 년간 가장 중요한 보안 취약점 중 하나로 평가된 Log4Shell 보안 허점(CVE-2021-44228)에 대한 깊이 있는 이해를 제공하는 것입니다. 이 작업에서는 이론적 기초를 설명하고 취약점의 실제 시연을 보여줍니다.

1.2 시연 개요

Log4Shell 보안 허점을 실제로 설명하기 위해 이 저장소에 격리되고 컨테이너화된 환경을 구축하여 전체 공격 과정을 재현 가능하게 보여줍니다. 이 시연은 세 가지 핵심 구성 요소를 기반으로 합니다.

  • vulnerable-app: Log4j 버전 2.14.1을 사용하는 의도적으로 취약한 Spring Boot 애플리케이션입니다. HTTP 요청의 User-Agent 헤더를 로깅하며, 공격자는 이를 조작하여 취약점을 악용할 수 있습니다.
  • ldap-server: LDAP 서버 역할을 하는 잘 알려진 도구 _marshalsec_의 포크입니다. 이 서버는 공격자의 통제 하에 있으며, 나중에 실행될 악성 Java 클래스에 대한 참조를 제공합니다.
  • payload-server: 악성 Java 클래스(Exploit.class)를 제공하는 간단한 HTTP 서버입니다. LDAP 서버와 마찬가지로 이 서버도 공격자의 통제 하에 있습니다.

참고: 설정 및 시연 실행에 대한 자세한 정보는 4. 프로젝트 구조 및 설정 및 5. 프로젝트 데모 섹션에서 확인할 수 있습니다.

2. Log4Shell이란 무엇인가?

Log4Shell은 CVE-2021-44228로 지정된 Java 라이브러리 Log4j의 중요한 보안 취약점 이름입니다. 이 취약점으로 인해 공격자는 최소한의 노력으로 원격 서버에서 임의의 코드를 실행할 수 있습니다(원격 코드 실행, 줄여서 RCE).

이 취약점은 Log4j 버전 2.0부터 2.14.1까지 영향을 미치며, BSI(연방정보보안청)를 포함한 많은 보안 당국에서 최고 위험 수준으로 분류할 정도로 심각합니다.

Log4Shell이 특히 위험한 이유는 다음과 같습니다.

  • Log4j는 매우 널리 사용됩니다. 게임 서버부터 엔터프라이즈 애플리케이션까지 사용됩니다.
  • 인증이 필요하지 않으며, 익명의 외부 공격자도 잠재적으로 피해를 입힐 수 있습니다.
  • 공격 벡터가 사소하여, 조작된 문자열을 애플리케이션에 보내는 것만으로 충분한 경우가 많습니다.
  • 이 취약점을 악용하는 Log4j의 기능이 기본적으로 활성화되어 있습니다.

실제 원인은 Log4j의 Lookup이라는 기능을 통해 로그 메시지에 동적 콘텐츠를 로드할 수 있다는 점에 있습니다. JNDI(Java Naming and Directory Interface) 및 LDAP(Lightweight Directory Access Protocol) 프로토콜과 결합하면 원격 악성 Java 클래스를 로드하고 실행할 수 있습니다.

취약점의 발견과 공개는 전 세계적으로 보안 경보를 촉발했습니다. 많은 시스템이 즉시 패치되거나 종료되어야 했습니다. 이후에도 관련 취약점(예: CVE-2021-45046)이 추가로 알려져 문제가 얼마나 심각하고 위험했는지 보여줍니다.

다음에서는 관련 기술과 그 상호 작용을 자세히 설명하여 취약점에 대한 더 깊은 이해를 제공합니다.

3. 기술 구성 요소 상세

3.1 Log4j - 작동 방식

Log4j는 Apache에서 만든 Java 애플리케이션에서 이벤트를 기록하는 라이브러리입니다. 로깅은 소프트웨어 개발에서 시스템을 모니터링하거나 오류를 분석하는 핵심 도구입니다. Log4j는 Java 생태계에서 가장 잘 알려지고 널리 사용되는 로깅 프레임워크 중 하나이며, 소규모 애플리케이션부터 대규모 기업 시스템까지 사용됩니다.

로깅이 필요한 이유?

프로그램이 실행되는 동안 다음과 같은 이벤트가 발생합니다.

  • 사용자 요청
  • 내부 상태 변경
  • 오류 메시지

이러한 이벤트는 로그를 통해 문서화할 수 있으며, 일반적으로 콘솔, 파일 또는 네트워크 프로토콜을 통해 중앙 로그 서버로 텍스트 출력됩니다. 적절한 로깅을 통해 애플리케이션이 언제 무엇을 했는지 추적할 수 있습니다.

Log4j가 제공하는 기능?

Log4j는 로그 메시지를 생성하고 처리하기 위한 유연하고 고도로 구성 가능한 인프라를 제공합니다. 주요 기능은 다음과 같습니다.

  • 로그 레벨: 다양한 중요도 수준(예: DEBUG, INFO, WARN, ERROR)이 있어 로깅의 세부 정도를 제어할 수 있습니다.
  • Appender: 로그 출력을 다양한 대상(예: 콘솔, 파일, 원격 서버)으로 보낼 수 있습니다.
  • Layout: 레이아웃을 사용하여 로그 메시지의 형식(예: 타임스탬프, 스레드, 메시지)을 정의할 수 있습니다.

세미나 논문과 관련된 추가 기능은 이후 섹션, 특히 플레이스홀더 기능과 Lookup 기능에서 다룹니다.

간단한 예제```java

import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;

public class Example { private static final Logger logger = LogManager.getLogger();

public static void main(String[] args) {
    logger.info("Starte Anwendung...");
}

}

이 간단한 예제에서는 Logger 인스턴스를 생성하거나 이미 존재하는 경우 가져옵니다. 그런 다음 `INFO` 레벨에서 로그 메시지를 출력합니다. Log4j는 구성에 따라 메시지의 형식화와 출력을 처리합니다. 예시 구성은 다음과 같을 수 있습니다:```xml
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

이 구성은 날짜 시간 로그 레벨 로거 이름 - 메시지 형식으로 로그 메시지를 콘솔에 출력하는 어펜더를 정의합니다. 이 어펜더는 INFO 레벨 이상의 모든 로그 메시지를 처리하는 루트 로거에 할당됩니다.

출력은 다음과 같을 수 있습니다:``` 2023-10-01 12:00:00 INFO Example - Starte Anwendung...

Kommen wir nun zu den spezifischen Features von Log4j, die für die Log4Shell-Sicherheitslücke am relevantesten sind.

#### 로그 메시지의 자리 표시자

Log4j의 특히 유용한 기능은 로그 메시지에서 **자리 표시자**를 지원한다는 것입니다. 이를 통해 런타임에 동적 콘텐츠를 로그 출력에 삽입할 수 있습니다:```java
String username = "Alice";
logger.info("Benutzer angemeldet: {}", username);

실행 시 {}는 변수 username의 실제 값으로 대체됩니다. 이는 다음과 같은 출력을 생성합니다:```text "Benutzer angemeldet: Alice"

#### 동적 표현식 (Lookup)

Log4j는 단순한 플레이스홀더 외에도 로그 메시지에서 직접 더 복잡한 표현식을 해결하는 기능을 제공합니다. 이 기능을 **Lookup**이라고 합니다: 런타임에 동적으로 값(예: 환경 변수, 시스템 정보 또는 구성 값)을 삽입할 수 있습니다.

이러한 동적 표현식의 예:

- `${env:HOME}` - 환경 변수 `HOME`의 값을 반환합니다. Linux/macOS에서는 예를 들어 `/home/username`입니다.
- `${docker:...}` - 애플리케이션이 실행 중인 Docker 컨테이너에 대한 정보를 제공할 수 있습니다.
- `${jndi:...}` - 내부 또는 외부 리소스를 로드하기 위해 JNDI 조회를 수행합니다.

다음 섹션에서는 Log4Shell 보안 취약점에서 핵심적인 역할을 하는 JNDI 기능을 자세히 살펴보겠습니다.

### 3.2 JNDI - 조회 메커니즘

**JNDI**는 _Java Naming and Directory Interface_의 약자로, **이름 및 디렉토리 서비스**에 접근할 수 있는 표준화된 Java API입니다. JNDI를 사용하면 Java 애플리케이션이 리소스를 기술적 경로가 아닌 기호 이름으로 참조할 수 있습니다.

JNDI의 전형적인 사용 예는 데이터베이스 연결을 조회하는 것으로, 다음과 같습니다:```java
public class JndiExample {
    public static void main(String[] args) throws Exception {
        InitialContext ctx = new InitialContext();
        Datasource ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/myDB");
        // Datenbankverbindung verwenden
    }
}

먼저 JNDI를 사용한 이름 해석의 진입점인 InitialContext가 생성됩니다. 그런 다음 lookup 메서드를 통해 리소스를 검색합니다. 이 경우에는 java:/comp/env/jdbc/myDB라는 심볼릭 이름을 가진 데이터 소스(DataSource)입니다.

JNDI는 어떤 장점을 제공하나요?

  • 애플리케이션과 인프라의 분리: 구성은 코드에 포함될 필요 없이 서버에서 중앙으로 관리될 수 있습니다.
  • 재사용성 및 이식성: 애플리케이션은 코드 수정 없이 여러 환경(예: 개발, 테스트, 프로덕션)에서 쉽게 실행될 수 있습니다. 각 환경의 구성 파일만 조정하면 됩니다.
  • 유연성: JNDI는 프로토콜에 독립적이며, 인터페이스만 제공되고 실제 통신은 백그라운드에서 _Service Provider_가 담당합니다. 이를 통해 JNDI는 LDAP뿐만 아니라 RMI, DNS, CORBA 등 다양한 서비스에 접근할 수 있습니다.

JNDI의 구조

JNDI 구조

Java 애플리케이션은 JNDI의 프로토콜 독립적 인터페이스를 사용합니다. 이 인터페이스에는 lookup 메서드를 가진 InitialContext와 같은 클래스가 포함됩니다. LDAP, DNS 등을 사용하더라도 API는 항상 동일합니다. Naming Manager는 중개자 역할을 하며 실제 통신을 담당하는 적절한 _Service Provider_를 선택합니다. JNDI SPI(Service Provider Interface)는 다양한 프로토콜에 대한 JNDI 기능을 구현하는 클래스 모음입니다. 우리의 경우 관련 서비스 제공자는 LDAP입니다.

다음 섹션에서는 서비스 제공자 LDAP를 자세히 살펴보겠습니다.

3.3 LDAP - 구조와 역할

LDAP는 _Lightweight Directory Access Protocol_의 약어로, 소위 디렉터리 서비스에 대한 접근을 가능하게 하는 표준화된 네트워크 프로토콜입니다. 원래 X.500의 경량 대안으로 개발되었으며, 오늘날 많은 기업 네트워크, 특히 중앙 집중식 사용자 및 권한 관리의 표준입니다.

디렉터리 서비스란 무엇인가?

디렉터리 서비스는 계층적 형태로 정보를 저장하는 구조화된 데이터베이스입니다. 관계형 데이터베이스와 달리 디렉터리는:

  • 읽기 지향적이며
  • 강력한 계층 구조를 가지고 있으며 (파일 시스템처럼)
  • 빠른 액세스를 위해 ID 또는 구성 데이터에 최적화되어 있습니다.

LDAP 디렉터리의 구조

LDAP 트리

그림에서 볼 수 있듯이 LDAP 디렉터리는 트리 형태로 구성됩니다. 루트 수준에는 **도메인 구성 요소(dc)**가 있습니다. 그 아래에는 Users와 같은 추가 하위 구분을 나타내는 **조직 단위(ou)**가 있을 수 있습니다. 개별 사용자 또는 개체의 경우 특정 항목을 식별하고 다양한 속성을 포함할 수 있는 **일반 이름(cn)**이 있습니다.

의미:

  • dn: Distinguished Name
  • dc: Domain Component
  • ou: Organizational Unit
  • cn: Common Name

이제 LDAP에 어떻게 접근하는지와 Log4Shell 보안 취약점에서 어떤 역할을 하는지 살펴보겠습니다.

LDAP는 어떻게 접근하나요?

LDAP에서는 필요할 때 로드할 수 있는 외부 클래스에 대한 참조를 저장할 수도 있습니다. 이는 javaClassName 및 javaCodeBase와 같은 특수 속성을 통해 이루어집니다. 이러한 속성은 Java 클래스를 로드할 URL을 가리킬 수 있습니다.

도구 다운로드