“상황 따라 다르다” Log4j 취약점을 완화하는 방법 총정리
최근 Log4j라는 자바 컴포넌트에서 악용하기 쉬운 취약점이 발견되자 IT 보안 업계에 비상이 걸렸다. Log4j는 다양한 애플리케이션과 제품에 존재한다. Log4j 취약점이 알려지고 공격자가 이를 악용하기 시작한 후, 많은 IT 전문가가 Log4j 취약점 연구에 몰두한 결과 추가 보안 문제를 발견했고, 공격을 막을 수 있는 몇 가지 완화책을 제안했다. 기업 IT팀은 자사의 애플리케이션, 서버, 네트워크 보호에 적합한 완화책을 찾느라 분주하다.
지금까지 발견된 취약점은 원격 코드 실행 취약점인 CVE-2021-44228(Log4Shell이라고도 알려졌다)과 서비스 거부 공격 취약점인 CVE-2021-45046 및 CVE-2021-45105다. 우선 영향을 받은 컴포넌트를 최신 버전으로 업데이트하는 것이 현재까지 식별된 취약점을 완화하는 최고의 방법이다. 자바 8 및 이후 버전은 2.17.0이 최신 버전이다.
하지만 패치를 즉각 적용하는 것은 말처럼 쉽지 않다. 서드파티 솔루션 업체의 패키징 제품에 Log4j 취약 버전이 포함되어 있다면, 전체 제품을 모두 업데이트하지 않는 이상 취약점을 해결할 수 없기 때문이다. 각 솔루션 업체가 업데이트를 배포해야 없앨 수 있다.
핵심 비즈니스 서버 및 애플리케이션이라면 즉시 재시작하는 것도 쉽지 않다. 애플리케이션은 컨테이너에서 실행할 수 있지만, 이런 경우에는 새 컨테이너 이미지를 제작해야 한다. 대부분 취약점과 마찬가지로 대안적 완화책은 보안팀에 유용하지만, 대안적 완화책의 한계와 일부 완화책으로 인해 형성될 수 있는 잘못된 안전감을 이해하는 것이 중요하다.
JndiLookup 클래스 제거
Log4j 취약점은 Log4j가 자바 기능인 JNDI(Java Naming and Directory Interface)를 사용하는 방식 때문에 발생한다. JNDI는 런타임 실행 중 추가 자바 객체의 로딩을 허용하도록 설계됐다. 여러 프로토콜에 걸친 원격 네이밍 서비스에서 자바 객체를 로드하는 데 사용된다. 최초의 취약점 공격은 LDAP(Lightweight Directory Access Protocol)를 이용했다. LDAP는 가장 흔한 프로토콜일 뿐이며, DNS(Domain Name System), RMI(Remote Method Invocation), NDS(Novell Directory Services), NIS(Network Information Service), CORBA(Common Object Request Broker Architecture)와 같은 다른 프로토콜도 지원한다.
취약점을 고치는 한 가지 방법은 JNDI 메시지 조회 기능을 중단하는 것으로, 원래 Log4j 2.16.0의 기능이다. 하지만 Log4j를 사용하지 않는 방법도 있다. 영향을 받은 Log4j 패키지에서 전체 JndiLookup 클래스를 아예 삭제하는 것이다. 자바 컴포넌트는 기본적으로 ZIP 아카이브이기 때문에 관리자는 아래 명령을 실행해 취약 패키지 인스턴스를 수정 및 패치할 수 있다.
zip -q -d log4j-core-*.jar
org/apache/logging/log4j/core/lookup/JndiLookup.class
자바 에이전트를 이용한 핫패칭
핫패칭(Hotpatching)은 재시작하지 않고 실행 중인 프로세스에 패치를 전개하는 방법이다. 자바는 JVM(Java Virtual Machine)에서 인스트루먼테이션 API(Instrumentation API)와 런타임 동안 JVM에 동적으로 첨부할 수 있는 JAR(Java Archive) 파일인 이른바 자바 에이전트를 사용해 이미 실행 중인 바이트 코드를 정지하거나 재시작하지 않고 변경하는 것을 지원한다.
Log4j 취약점에 대응해 AWS 코레토(Corretto)팀은 로딩된 모든 ‘org.apache.logging.log4j.core.lookup.JndiLookup’ 인스턴스의 lookup() 메서드를 패치하는 자바 에이전트를 개발했다. 원격 서버로 연결하는 대신 ‘Patched JndiLookup::lookup()’ 문자열을 반환한다. AWS 코레토팀의 자바 에이전트는 깃허브에서 다운로드할 수 있으며, 임시 컨테이너로서 기존 쿠버네티스 팟으로 전개되어 다른 컨테이너에서 이미 실행 중인 애플리케이션 패치에 사용할 수 있다. 임시 컨테이너는 쿠버네티스 1.16 및 이후 버전에서 지원된다.
취약점을 이용한 임시적인 악용 방지
영향을 받은 서버의 취약점 자체를 이용해 라이브 시스템 및 애플리케이션에 특정한 변경을 만들어 추가 악용을 방지하는 방법도 있다. 보안업체 사이버리즌(Cybereaseon) 연구팀이 개발하고 루나섹(LunaSec) 연구팀이 개선해 라이브 서버에 공개했다.
이 방법은 전면적인 패치가 불가능한 서드파티 솔루션 업체의 제품(패키지된 애플리케이션, 임베디드 기기 및 어플라이언스)이나 공식 업데이트를 지원받지 못하는 오래된 제품에 적합하다. 다만 취약점 자체를 활용하는 것은 단기적인 해법일 수 있다.
주의할 점은 첫째, 효과가 일시적이라는 점이다. 취약점으로 만든 변경은 실행 중인 자바 프로세스에만 적용되고, JVM이 재시작하면 변경 전으로 복귀된다. 즉, 서버를 재시작할 때마다 변경 사항을 다시 적용해야 한다. 둘째, 여러 구성 및 시스템에서 시험된 방법이지만 항상 유효한 것은 아니며 간혹 충돌을 일으킬 수 있다. 충돌로 인한 복구 작업 시 서버 재부팅이 필요할 수 있으므로 다운타임이 발생해서는 안 되는 중요한 시스템에서는 이 방법을 추천하지 않는다. 마지막으로 이 방법은 취약점을 이용하는 방법이다. 때문에 소유권이 없고 자신이 제어하지 않는 서버에서 이 방법을 사용하는 것은 악의가 없다고 해도 불법일 수 있다.
취약 시스템 식별 방법
앞서 언급한 완화책을 이용하기 전에, 그리고 자사에 적합한 대응 전략을 개발하기 전에 해야 할 일이 있다. Log4j 취약점에 노출된 애플리케이션과 시스템을 모두 식별하는 것이다. 이는 쉬운 일이 아니다. 각 애플리케이션이 자체 Log4j 인스턴스를 번들로 묶을 수 있고 서드파티 의존성의 일부로 번들을 동적으로 로드할 수 있기 때문이다.
Log4Shell 솔루션 업체 목록이 보안 커뮤니티와 CERT에서 유지되고 있지만, 불완전하다. 따라서 모든 솔루션 업체가 SBOM(Software Bills of Materials)을 도입하기 전까지 기업 보안팀은 새로운 취약점이 등장할 때마다 영향을 받는 시스템을 식별하는 데 시간을 소모하고 오류를 감당해야 한다. Log4j 취약점으로 인해 앞으로 더 많은 연구팀과 사이버 공격자가 흔히 사용되는 다른 구성 요소의 결함을 본격적으로 조사하게 될 것이다.
보안 업계는 Log4j 취약점을 가진 서버 및 인스턴스를 자동으로 발굴하는 오픈소스 툴을 개발하면서 빠르게 대응했다. 루나섹이 공개한 툴은 프로젝트 디렉토리에서 .jar 및 .war 파일을 조사하고 취약 파일을 보고한다. 상용 취약점 스캐너 및 툴에도 Log4j 취약점 조사 지원 기능이 추가됐다.
불완전한 Log4j 취약점 완화책 4가지
Log4j 취약점이 처음 발표된 이후 공개된 몇 가지 완화책은 비효과적인 것으로 드러났으므로 초기 완화책에는 더 이상 의존해서는 안 된다.
자바 버전 업그레이드 : 자바 버전 업그레이드만으로는 충분하지 않다. 최초의 취약점 공격은 6u212, 7u202, 8u192 또는 11.0.2 이후의 자바 버전에 효과가 없었다. 이들 버전의 기본값 구성이 원격 서버에서 JNDI를 사용한 클래스 로딩을 금지하기 때문이다. 그러나 공격자가 원격 클래스패스 대신 애플리케이션 자체 클래스패스의 클래스를 이용하는 페이로드를 제작할 수 있음이 밝혀졌다. 따라서 업그레이드만으로 모든 공격을 방지할 수 없다.
formatMsgNoLookups 플래그 : formatMsgNoLookups 플래그가 모든 취약점 공격을 방지하는 것은 아니다. 초기 Log4j 개발자를 비롯한 여러 전문가는 2.10 이상의 Log4j 버전에서 ‘formatMsgNoLookups’라는 속성을 ‘true’로 설정하거나 ‘LOG4J_FORMAT_MSG_NO_LOOKUPS’라는 환경 변수를 설정하라고 권고했다. 하지만 이런 플래그를 활성화해도 서비스 거부 공격 취약점에는 효과적이지 못한 것으로 드러났다. 개발자는 “메시지를 조회할 수 있는 Log4j 코드 경로가 여전히 존재한다. 대표적인 것이 Logger.printf(“%s”, userInput)나 커스텀 메시지 팩토리를 사용하는 애플리케이션이다. 이런 환경에서는 결과 메시지가 StringBuilderFormattable를 실행하지 않는다”라고 설명했다.
로그 문장 포맷 변경 : 로그 문장 포맷을 변경해 조회를 비활성화하는 방법도 완전하지 않다. 애플리케이션의 로그 문장 포맷을 %m, %msg 또는 %message에서 %m{nolookups}, %msg{nolookups} 또는 %message{nolookups}으로 변경해 메시지 조회 기능을 중단하는 것이다. 이는 formatMsgNoLookups과 같은 이유로 효과가 없지만, 잘못된 안전감을 유발하기 때문에 더 위험하다. 하나의 의존성에서 로깅 문장 갱신을 놓치거나 취약한 %m 문장을 무심코 다시 도입하기 쉽기 때문이다. 이 완화책을 이용하고 있다면, 이 방법에만 의존하는 것을 피해야 한다.
WAF(Web Application Firewall) : WAF를 이용해 악의적인 요청을 걸러내는 방법에도 주의가 필요하다. WAF로 취약점 공격을 차단할 수 있지만, 잠재적인 공격 문자열을 모두 포착하는 것은 매우 어렵다. 실제로 Log4j 취약점이 발견된 후 많은 전문가가 WAF 필터링 규칙을 우회하는 중첩되고 불명료한 페이로드 제작 사례를 보여주었다. 이에 따라 WAF 및 IPS 업체가 Log4Shell 탐지 정책을 끊임없이 갱신하고 있기 때문에 즉각적이고 임시적인 대응이나 다른 완화책을 보완하는 추가 방어 계층으로는 활용하기 적절하다. 일반적으로 WAF는 대중에 노출된 자산 보호에 사용되지만, WAF를 거치지 않고 취약점에 도달할 수 있는 내부 취약점 경로 및 시나리오가 존재한다는 점을 유의해야 한다.
보안 업계가 Log4j 취약점과 영향을 계속 조사하고 있기 때문에 현행 완화 전략이 변경되거나 철회될 수 있다. 따라서 Lo4j 프로젝트 보안 페이지와 CISA 같은 단체의 권고 사항을 지속해서 살펴보고 최신 정보를 확인하는 것이 최선의 방법이다.
출처 : https://www.itworld.co.kr/news/219349
이 게시글이 문제가 될 시, 삭제하겠습니다.
댓글 없음:
참고: 블로그의 회원만 댓글을 작성할 수 있습니다.