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

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
log4j-check — log4j 2025/2026년 「설정 무음 실패」 CVE 7건 자가 점검: CVE×모듈 기준으로 4개 모듈을 판별하고, log4j2 설정을 구조적으로 파싱하여 applicability 노이즈를 줄이며, 한 번에 끝나도록 업그레이드할 버전을 계산(6건은 2.25.4를 지시하지만 1건은 2.25.5가 필요하며, 이를 Dependabot이 감지하지 못함) CVE-2026-49844 / CVE-2026-34477 | Kitploit
도구/GitHubGitHub/xiaoqimikko/log4j-check
Vulnerability ScannersVulnerability AnalysisConfiguration AuditingDevSecOpsSupply Chain Security
GitHubxiaoqimikko/log4j-check

log4j-check

log4j 2025/2026년 「설정 무음 실패」 CVE 7건 자가 점검: CVE×모듈 기준으로 4개 모듈을 판별하고, log4j2 설정을 구조적으로 파싱하여 applicability 노이즈를 줄이며, 한 번에 끝나도록 업그레이드할 버전을 계산(6건은 2.25.4를 지시하지만 1건은 2.25.5가 필요하며, 이를 Dependabot이 감지하지 못함) CVE-2026-49844 / CVE-2026-34477

저장소 보기
1개월 전아직 검토되지 않음

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

log4j-check

log4j 2025/2026년 이번 "설정 무음 실패" 공지에 대한 자가 점검 도구. 런타임 의존성 제로, 단일 jar, 네트워크 연결 없음.

⚠️ 먼저 기준을 명확히 하자: 이번 것은 전부 medium이고, RCE는 하나도 없으며, Log4Shell 같은 것이 아니다. 이들의 공통점은 설정이 아무런 오류 없이 실패했다는 것이다 —— 속성이 무음으로 무시되고, 속성이 무음으로 이름이 바뀌고, 로그가 무음으로 버려진다. 따라서 버전 번호만 봐서는 당신이 영향을 받았는지 알 수 없고, 설정을 읽어야 한다. 만약 CVE-2021-44228(Log4Shell)을 찾고 있다면, 이 도구는 도움이 되지 않는다.

java -jar log4j-check.jar app.jar          # fat jar 里带配置,一步到位
java -jar log4j-check.jar ./target ./src   # 构建产物 + 源码
java -jar log4j-check.jar ~/.m2/repository --no-config

어떤 질문에 답하는가

Dependabot은 "log4j에 N개의 취약점이 있습니다"라고 알려줍니다. 이 도구는 그것이 답하지 않는 세 가지를 답합니다:

  1. 도대체 어느 버전으로 올려야 하는가? —— 어떤 advisory 하나를 그대로 베끼는 것이 아니라, 해당되는 항목들을 하나씩 교집합으로 계산한다.
  2. 이 7개 중 당신은 실제로 몇 개에 해당하는가? —— 각 항목은 특정 layout / appender를 사용했을 것을 요구하며, 그것들은 log4j2.xml에 적혀 있고, 읽을 수 있고, 정확히 읽을 수 있다.
  3. 당신은 「이미 업그레이드했고 고쳤다고 생각하는」 그 부류인가? —— 이 부류에는 두 개의 패치 공백 체인이 있다.

세 가지 핵심 결론(모두 직접 검증 가능)

一、🔥 2.25.4로 올린 사람은 제대로 올리지 못했다(놓친 그 항목, 한때 Dependabot도 보고하지 못했다)

이 7개 중 6개의 수정 버전이 모두 ≤ 2.25.4다. 그래서 대다수는 「2.25.4로 올린다」는 답에 도달한다.

하지만 CVE-2026-49844는 2.25.5를 요구한다(2.26 라인은 2.26.1). 그 advisory 원문에는 자신이 CVE-2026-34481의 불완전한 수정이라고 적혀 있다:

버전 2.25.4에서 릴리스된 수정 사항은 영향을 받는 모든 코드 경로를 다루지 못했습니다. 나머지 문제에는 CVE-2026-49844가 할당되었습니다 …

📌 정정(2026-08-16)

이 절은 원래 「그리고 이 항목이 바로 Dependabot이 구조적으로 보고할 수 없는 그 항목이다」라고 적혀 있었다 —— 그 문장은 이제 절반만 맞다.

GHSA-qv9r-c865-cp47은 2026-08-13에 GitHub에 의해 reviewed로 전환되고 패키지 정보가 보완되었으며, 보완된 두 구간은 >= 2.13.1, < 2.25.5와 >= 2.26.0, < 2.26.1이다:

  • ✅ 2.x를 쓰는 사람은 이제 Dependabot 경고를 받을 수 있다.
  • 🔴 하지만 3.x 프리뷰 라인(3.0.0-alpha1 ~ 3.0.0-beta2)은 아직 해당 구간이 없어, 그 라인은 여전히 보고되지 않는다.

업그레이드 결론은 전혀 변하지 않았다 —— log4j-api는 여전히 2.25.5(2.26 라인은 2.26.1)가 필요하다. 변한 것은 오직 「기계가 그것을 볼 수 있는지」뿐이다. 이 도구의 판정표는 버전 라인별로 하나씩 갱신되었고, 보고서에 찍히는 숫자는 표에서 계산되며 더 이상 하드코딩되지 않는다.

🔑 이 일 자체가 원래 그 예시보다 기록할 가치가 있다: advisory의 형태는 시간이 지나면서 업스트림에 의해 보완된다, 그리고 당신이 지난번 스캔한 결론은 스스로 갱신되지 않으며, 누구도 알려주지 않는다. 「그때 스캔했다」와 「지금은 안전하다」는 두 가지 일이다.

그것의 GitHub advisory(GHSA-qv9r-c865-cp47)는 2026-08-13 이전에는 unreviewed였고, vulnerabilities 배열이 비어 있었다 —— 패키지 이름도, 버전 구간도, 수정 버전도 없었으므로, 그 기간 동안 Dependabot은 당신의 의존성 트리와 비교할 수 있는 데이터를 전혀 얻지 못했다.

OSV.dev에서도 당시 마찬가지였다: 나머지 6개는 모두 GHSA alias를 통해 Maven 좌표를 얻을 수 있었지만, 그것만은 얻을 수 없었다 (OSV에서는 GHSA alias조차 없었다). 이는 세 번째 소스에서의 독립적 방증이며, tools/recheck_before_publish.py는 매번 재실행할 때마다 다시 확인한다 (이 스크립트는 이제 「이미 보완되었다」는 사실 자체도 보고한다).

🔴 이 항목을 「Dependabot이 쓸모없다」로 읽지 말라. 그것은 「이 데이터가 당시 존재하지 않았다」이지, 「이 도구에 버그가 있다」가 아니다. unreviewed는 GitHub의 정상적인 프로세스 상태이며, 08-13의 보완은 바로 그 프로세스가 정상적으로 완료된 것이다.

또 다른 체인은 CVE-2025-68161(2.25.3)→ CVE-2026-34477(2.25.4)이다: verifyHostName 속성은 2.12.0에서 도입되었으나, 2.25.3까지 줄곧 조용히 무시되어, 설정해도 설정하지 않은 것과 같았다. 68161에 따라 2.25.3으로 올리고 속성(system property가 아닌)으로 호스트명 검증을 설정한 사람은 여전히 당한다.

二、판정 단위는 CVE × 모듈, 총 4개 모듈

모듈해당 항목올려야 할 버전
log4j-core34477 / 34478 / 34480 / 681612.25.4
log4j-api498442.25.5(2.26 라인: 2.26.1)
log4j-1.2-api344792.25.4
log4j-layout-template-json344812.25.4

목표 버전은 같은 숫자가 아니다. 그리고 대다수 프로젝트의 pom에는 log4j-core만 적혀 있다 —— 그 하나의 좌표로 역조회하면 4개만 찾을 수 있고, 나머지 3개는 그들에게 존재하지도 않는다.

이 도구는 네 모듈의 버전을 각각 스캔하고 각각 판정한다. 네 모듈의 버전이 어긋날 때(BOM 오버라이드, 수동 제외, 오래된 WAR 안에 두 세대의 jar가 들어 있는 경우) 그것을 명확히 보고한다.

三、노이즈 감소: 각 항목은 특정 layout / appender를 요구하며, 그것은 설정 파일에 적혀 있습니다

CVE트리거 조건(공식 원문에서 발췌)
CVE-2026-34477<Ssl>의 verifyHostName 속성 + Socket / Syslog / SMTP appender
CVE-2025-68161SocketAppender + TLS
CVE-2026-34478직접 Rfc5424Layout을 구성하는 경우(SyslogAppender를 사용하는 경우는 영향 없음)
CVE-2026-34480log4j-core의 XmlLayout
CVE-2026-34479브리지의 Log4j1XmlLayout, 또는 log4j 1 호환 계층 + org.apache.log4j.xml.XMLLayout
CVE-2026-34481JsonTemplateLayout + MapMessage/ObjectMessage 내의 부동 소수점 값
CVE-2026-49844JsonTemplateLayout의 message resolver, 또는 MapMessage.asJson()

실측(실제 아티팩트, 아래 참조): 동일한 세트에 영향을 받는 버전의 네 모듈을 설치했을 때,

  • 설정이 가장 흔한 형태(Console + RollingFile + PatternLayout)인 경우 → 버전 계층에서 7건 보고, 실제 적중 0건
  • 설정에 Socket+<Ssl verifyHostName>+Rfc5424Layout+XmlLayout이 있는 경우 → 7건 보고, 실제 적중 4건

두 가지 부정 판정 기준은 공식 원문에 명시된 것으로, 별도 항목으로 분리했다: SyslogAppender를 사용하는 경우 34478에 해당하지 않음; HTTP appender의 verifyHostname만 사용하는 경우 34477에 해당하지 않음. 이 항목은 「찾지 못했다」와 신뢰도가 전혀 다르다 — 전자는 원문의 뒷받침이 있고, 후자는 단지 우리가 보지 못했을 뿐이다.

🔴 verifyHostName(대문자 N, <Ssl>, 해당됨)과 verifyHostname(소문자 n, HTTP appender, 공식 문서에 영향 없음으로 명시)은 한 글자 대소문자만 다를 뿐 결론은 완전히 반대다. 마찬가지로 XmlLayout(34480, log4j-core)은 Log4j1XmlLayout(34479, 브리지)의 부분 문자열이다. 이름만 grep하면 사용자에게 해당하지 않는 CVE까지 추가로 떠안게 된다. 그래서 설정 계층에서는 텍스트 매칭이 아닌 구조적 파싱을 한다.

설정을 읽는 방식

格式怎么读能不能判准属性归属
log4j2*.xml(含 strict 模式 <Appender type="…">)DOM 解析,XXE 已关✅
log4j2*.properties按 xxx.type = Foo 建前缀→插件映射✅
log4j2*.yaml / .json文本匹配(JDK 无 YAML 解析器,而本工具坚持零依赖)❌ 标为「文本依据」
.java文本匹配(已剥注释,认字符串)❌

설정은 아카이브 내부에서도 스캔한다(BOOT-INF/classes/, WEB-INF/classes/), 따라서 Spring Boot fat jar 하나만 넘겨도 노이즈 감소가 가능하다 — 소스 트리가 필요 없다.

log4j-spring.xml / log4j2-test.xml / log4j.xml(1 호환 계층) 모두 인식한다.

🔴 이 보고서가 증명할 수 없는 것

「트리거 조건을 찾지 못함」은 안전과 같지 않다, 최소 네 가지 상황에서 거짓 안심이 될 수 있다:

  1. 설정이 코드에서 구성되는 경우(ConfigurationBuilder / Configurator.initialize);
  2. 설정이 런타임에 주입되는 경우(log4j2.configurationFile이 다른 곳을 가리키거나, 컨테이너에 마운트됨);
  3. 서드파티 라이브러리가 자체 log4j2 설정을 포함하고 있으나 스캔되지 않은 경우;
  4. 설정을 아예 전달하지 않은 경우 — 이 경우 보고서는 「이번에는 설정을 보지 못함」으로 별도 표시하며, 「해당 없음」으로 표시하지 않는다. 이 두 문장은 완전히 다른 조치로 이어져야 한다.

「트리거 조건이 모두 성립함」도 감염 확인과 같지 않다: 대부분의 항목은 추가로 「공격자가 로그에 기록되는 그 값을 제어할 수 있음」을 요구하는데, 이 점은 도구가 판정할 수 없다. 따라서 결론은 우선순위 정렬에만 충분하고, 사고 선언에는 부족하다.

이 도구는 log4j 1.x(log4j:log4j)를 커버하지 않는다. 스캔되면 경고하지만 판정하지는 않는다 — 그것은 별개의 코드베이스다.

판정표는 생성된 것이지, 손으로 옮겨 적은 것이 아니다

python tools/gen_rules.py          # 从两个一手源重建 CveTable.java + Triggers.java
  • 소스 A = Apache 공식 CycloneDX VDR(logging.apache.org/cyclonedx/vdr.xml)—— 전체 항목 + 모듈별 정확한 구간 + 설명 원문.

    🔴 /repos/apache/logging-log4j2/security-advisories 실측 결과 0건 반환 —— Apache는 GitHub Security Advisories를 사용하지 않습니다. 그 엔드포인트만 조회하면 「log4j는 매우 평온하다」는 결과를 얻고, 게다가 오류도 나지 않습니다.

  • 소스 B = GitHub advisory DB를 좌표로 역조회(= Dependabot이 실제로 쓰는 인덱스), 네 모듈을 각각 한 번씩 조회.

17개 단언, 어느 하나라도 충족되지 않으면 중단하고 파일을 쓰지 않는다. 그중 몇 개는 핵심을 떠받치는 것들이다:

단언고정하는 사항
ASSERT2이중 소스 사각지대: 공식 7건 vs 단일 좌표 4건 vs 네 좌표 6건, 세 숫자를 모두 측정해야 함
ASSERT13그 1건의 구조적 사각지대는 검증 가능한 근거를 제시해야 하며, 문구에 하드코딩해서는 안 됨
ASSERT7각 수정 버전을 Central에서 실측 + 음성 대조(탐지기가 정말 「가져올 수 없음」이라고 말하는지 증명)
ASSERT8수정 버전은 구간 상한에서 도출됨 → 반드시 공식 recommendation 원문에 그대로 나타나야 함
ASSERT9두 패치 공백 체인의 원문 표현 + 뒤쪽 고리의 수정 버전이 실제로 더 높아야 함
ASSERT10가장 흔한 수정 버전으로 업그레이드해도 여전히 누락이 있어야 함 —— 그렇지 않으면 「교집합 구하기」는 가치가 없음
ASSERT14XmlLayout≠Log4j1XmlLayout, verifyHostName≠verifyHostname, 정·반 샘플을 각각 한 번씩 테스트
ASSERT17설명 원문은 완전한 문장이어야 하며, asciidoc의 강제 줄바꿈으로 끊긴 잔여 문장이 아니어야 함

검증은 어디까지 했는가

  • 단위 테스트 93개, 보고서 렌더링 계층 테스트 포함(내부 반환값만이 아니라 실제로 출력된 텍스트를 검증)
  • 실제 아티팩트 시나리오 12개: Maven Central에서 내려받은 실제 jar 14개로 구성한 Spring Boot fat jar / WAR / 순수 m2 디렉터리 / 소스 트리, 엔드투엔드 실행
  • 발행 전 독립 기준 재검증(tools/recheck_before_publish.py): 생성 스크립트의 출력을 전혀 읽지 않고, 세 가지 소스(OSV.dev / 공식 보안 웹페이지 / Maven Central)로 다시 계산

실제 아티팩트 재검증으로 단위 테스트로는 잡을 수 없는 문제 3건을 발견했고, 모두 수정 + 회귀 테스트를 추가했다:

도구 다운로드