Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
log4j-4255 — Apache log4j2 #4255를 재현하는 엔드투엔드 Docker 랩 — Log4j 2.26.1 / JDK 17에서 java.rmi.MarshalledObject를 통한 FilteredObjectInputStream 허용 목록 우회(필터링되지 않은 역직렬화 → RCE) | Kitploit
도구/GitHubGitHub/dinosn/log4j-4255
Vulnerability AnalysisExploitationWeb SecurityLearning & EducationBinary Exploitation
GitHubdinosn/log4j-4255

log4j-4255

Apache log4j2 #4255를 재현하는 엔드투엔드 Docker 랩 — Log4j 2.26.1 / JDK 17에서 java.rmi.MarshalledObject를 통한 FilteredObjectInputStream 허용 목록 우회(필터링되지 않은 역직렬화 → RCE)

저장소 보기
18131일 전아직 검토되지 않음
웹사이트

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

log4j2 #4255 — FilteredObjectInputStream 허용 목록 우회 (java.rmi.MarshalledObject 경유)

Apache log4j2 이슈 #4255 를 공식 Log4j 2.26.1 아티팩트와 JDK 17 환경에서 종단 간 재현하는 독립형 컨테이너 실습 환경입니다. 양성 대조군, 강화된 오라클, 검증된 완화 조치를 포함합니다.

⚠️ 책임 있는 사용

이 실습 환경에는 현재 패치되지 않은 Log4j 이슈(#4255은 작성 시점 기준 OPEN / waiting-for-maintainer 상태이며, CVE가 할당되지 않음)에 대한 실제 동작하는 역직렬화 RCE 가 포함되어 있습니다. 이 환경은 사용자 머신의 일회용 Docker 컨테이너 내부에서만 실행되며, 공식 jar 다운로드를 위한 Maven Central 외에는 외부와 연결되지 않습니다 — 어떤 대상에도 접촉하지 않습니다.

  • 최초 신고자(U-Sec / Wujie Security)는 수정이 완료될 때까지 PoC를 공개하지 않고 있습니다. 이는 방어자 검증 및 탐지 엔지니어링을 위해 구축된 독립적 재현 입니다.
  • 소유하지 않았거나 명시적으로 테스트 권한을 부여받지 않은 시스템에 대해 실행하지 마십시오.
  • 이는 애플리케이션 조건부 RCE를 시연하는 것이며, 범용 Log4j RCE가 아닙니다 (범위 참조).

요약

Log4j의 FilteredObjectInputStream(FOIS)은 resolveClass 기반 역직렬화 허용 목록 입니다. 이 허용 목록에는 java.rmi.MarshalledObject가 포함됩니다. MarshalledObject는 페이로드를 불투명한 byte[] 로 저장하며, MarshalledObject.get()은 해당 페이로드를 새롭고 필터링되지 않은 ObjectInputStream 에서 역직렬화합니다 — 따라서 허용 목록은 내부 객체 그래프를 검사하지 않습니다.

Log4j는 이를 자체적으로 트리거합니다: Log4jLogEvent$LogEventProxy(2.8부터 LogEvent의 직렬화된 전송 형식)는 이벤트 Message를 MarshalledObject 내부에 담아 역직렬화 중(readResolve() → message()) 자동으로 .get()을 호출합니다. FOIS를 통해 직렬화된 LogEvent를 읽는 모든 애플리케이션은 따라서 공격자 바이트의 필터링되지 않은 역직렬화를 수행하며, message()가 결과 예외를 삼키고 SimpleMessage로 대체하므로 수신자는 정상적인 이벤트를 기록하고 계속 실행됩니다. 익스플로잇은 조용히 수행됩니다.

근본 원인 (rel/2.26.1에서 검증됨)

#위치결함
1log4j-api …/util/internal/SerializationUtil.javaREQUIRED_JAVA_CLASSES에 java.rmi.MarshalledObject 포함
2log4j-api …/util/FilteredObjectInputStream.javaresolveClass()만 오버라이드함; MarshalledObject의 objBytes 페이로드는 이 메서드에 보이지 않음
3log4j-core …/impl/Log4jLogEvent.javaLogEventProxy.marshalledMessage는 MarshalledObject<Message>
4log4j-core …/impl/Log4jLogEvent.javamessage()가 marshalledMessage.get()(필터 없음)을 호출하고 모든 예외를 삼킴

실습 환경이 실행하는 것

더 이상 사용되지 않는 log4j-samples의 ObjectInputStreamLogEventBridge를 충실히 대체한 구현입니다: 연결당 하나의 직렬화된 LogEvent를 FOIS를 통해 읽는 인증 없는 TCP 수신기입니다. 공격자는 단일 직렬화 객체를 전송하며, 오라클은 수신기 컨테이너에만 바인드 마운트된 디렉터리에 기록되는 증명 파일로, 파일이 나타나면 역직렬화를 통해 수신기 내부에서 코드가 실행되었음을 증명합니다.

#시나리오피해자 클래스패스jdk.serialFilter예상 결과
S1허용되지 않은 가젯을 최상위 레벨로 전송+ 가젯없음거부 — FOIS가 허용 목록을 적용
S2동일 가젯을 LogEvent에 래핑+ 가젯없음rce — 자동 트리거(피해자에 가젯 클래스 필요)
S3원시 CommonsCollections6 최상위 레벨log4j + cc-3.2.1없음거부 — FOIS가 CC 차단
S4CC6를 MarshalledObject에 스플라이싱log4j + cc-3.2.1 만없음rce — 피해자에 공격자 클래스 불필요
S5S4 페이로드log4j + cc-3.2.1!java.rmi.MarshalledObject거부 — 완화 조치
S6S4 페이로드log4j + cc-3.2.1maxdepth=5;maxbytes=1000000무음 — 내부 스트림이 필터를 상속받음; CC6이 너무 깊음
S7S4 페이로드log4j + cc-3.2.2없음무음 — 3.2.2가 안전하지 않은 functor 역직렬화 비활성화

rce = 코드 실행됨. reject = FOIS가 외부 스트림에서 예외 발생. silent = 외부 객체는 처리되었으나 코드는 실행되지 않음(더 깊은 곳에서 차단되거나 가젯 버전이 안전함).

실행 방법

root@kitploit:~
./run.sh            # 또는: make run

요구 사항: Docker만 필요(JDK는 eclipse-temurin:17-jdk로 풀링됨). 스크립트는 공식 jar를 다운로드하고 사용 전에 Maven Central SHA-1과 대조 검증합니다. 취약 범위 내의 다른 Log4j 버전을 지정하려면 LOG4J_VERSION=2.20.0 ./run.sh를 사용하세요.

영향 및 공격 방법

  • 전달: FOIS 기반 수신기에 직렬화된 LogEvent를 단일 인증 없는 약 2.8KB TCP 쓰기로 전송. 문자열 로깅으로는 트리거할 수 없습니다(Log4Shell과 달리) — 소켓 브리지에 도달하는 원시 직렬화 바이트가 필요합니다.
  • 결과: 수신기 프로세스에서 임의 명령 실행, 무음으로 수행.
  • 공격 경로: LogEvent 구축 → Log4j의 writeReplace()/writeObject()가 Message를 MarshalledObject에 래핑 → 가젯이 불투명한 byte[] 내부에 숨음 → 수신기에서 readResolve() → message() → MarshalledObject.get()이 새 필터링되지 않은 스트림을 엶 → 가젯 → Runtime.exec. src/attacker/Attacker.java(poc2)는 순수 CommonsCollections6 그래프를 MarshalledObject의 objBytes에 스플라이싱하므로 피해자에 공격자 클래스가 필요 없습니다.

완화 조치

  • 신뢰할 수 있는 방법: 수신기 JVM에 -Djdk.serialFilter='!java.rmi.MarshalledObject' 적용(S5). 주의: 이 방법은 정상적인 직렬화된 LogEventProxy 객체도 차단합니다(이들도 MarshalledObject를 사용함) — 효과적이지만 직렬화된 로그 전송에는 투명하지 않습니다.
  • 신뢰할 수 없는 방법: 일반적인 maxdepth/maxbytes 필터. 프로세스 전체 필터는 내부 MarshalledObject 스트림으로 전파되며 깊이가 그 지점에서 다시 시작되므로 maxdepth=5는 CC6을 차단하지만(S6) 얕은 가젯은 통과할 수 있습니다. 체인 깊이에 의존적이며 경계가 아닙니다.
  • 구조적 방법: Java 직렬화 로그 전송 제거(인증된 TLS를 통한 JSON / RFC 5424 사용); 알려진 가젯 의존성 제거; 레거시 직렬화 수신기를 신뢰할 수 없는 네트워크에 노출하지 않음. 업스트림 수정(이슈 기준): 허용 목록에서 MarshalledObject 제거 및 마샬링된 메시지를 Log4j의 필터링된 writeWrappedObject/readWrappedObject로 이동.

범위 및 정직한 한계

  • 애플리케이션 조건부이며 일반적인 Log4j RCE가 아닙니다. 인증 없는 FOIS 기반 직렬화 LogEvent 수신기를 노출하는 애플리케이션 및 클래스패스에 사용 가능한 가젯 버전이 있어야 합니다. 일반적인 Log4j 배포 환경에는 이러한 수신기가 없습니다.
  • 코어 내 직렬화 소켓 서버는 2.8.2까지만 존재했습니다 (net.server.TcpSocketServer는 2017년에 log4j-core에서 제외되었으며 2.9.0부터는 없음). 현대 수신기는 애플리케이션/샘플 코드이며, 이 실습 환경이 이를 모델링합니다.
  • 가젯 버전 의존적. commons-collections 3.2.1 → RCE; 3.2.2는 차단(S7). 사용 가능한 가젯이면 충분하지만, "commons-collections가 있다"는 것만으로는 충분하지 않습니다.
  • 실습 환경의 uid=0은 컨테이너 루트입니다 — Docker 탈출은 없으며 RCE는 수신기 프로세스로 실행됩니다.
  • 이 원시 기법(MarshalledObject가 resolveClass 필터를 우회)은 알려진 선행 기술입니다; Apache 논의 #4168("Log4j 2.x 역직렬화 강화") 참조. Log4j 특유의 자동 트리거가 #4255의 기여입니다.

구조

root@kitploit:~
run.sh                     휴대용 실행기(체크섬 고정, 강화된 오라클)
Makefile                   make build | run | clean
src/victim/Receiver.java   FOIS 로그 수신기(ObjectInputStreamLogEventBridge 대체 구현)
src/attacker/Attacker.java 페이로드 빌더: 대조군, PoC-1, PoC-2(CC6 + 바이트 스플라이싱)
src/attacker/EvilMessage.java  PoC-1 자체 포함 가젯
docs/RESULTS.md            증거 매트릭스 + 분석

참고 자료

  • 이슈 #4255 — https://github.com/apache/logging-log4j2/issues/4255
  • 논의 #4168(역직렬화 강화) — https://github.com/apache/logging-log4j2/discussions/4168
  • Log4j CWE-502 FAQ — https://logging.apache.org/security/faq.html
  • Apache Commons Collections 보안 공지 — https://commons.apache.org/proper/commons-collections/security.html

크레딧

취약점은 Apache log4j2 #4255에서 U-Sec (Wujie Security) 가 신고했습니다. 이 저장소는 방어 연구 및 탐지 엔지니어링을 위한 독립적 재현/검증 실습 환경입니다.

도구 다운로드