Web,Mobile/Tech

Log4shell(CVE-2021-44228) + JNDI Injection

LimeLee 2021. 12. 17. 16:52

- log4shell

 

 

log4j는 자바 로깅 프레임워크 중 하나인데 넘겨받은 값을 문자열 그대로 저장하는 것이 아니라 lookups 기능에서 해석할 수 있는 형태면 해당 문자열을 실행한다.

 

CVE-2021-44228에서는 JNDI Lookup을 이용해서 공격자의 서버에 있는 악성 페이로드를 요청한다.

 

 

- JNDI Injection

 

피해자의 서버에 익스플로잇을 하기 위해 사용하는 JNDI Injection도 이해할 필요가 있다.

 

공격자의 LDAP(또는 rmi) 서버에서 JNDI Naming Reference를 반환하고 피해자의 서버는 Reference Object의 Codebase URL이 가르키는 신뢰되지 않는 악성 클래스 파일을 인스턴스화한다. (log4shell exploit flow 참조)

 

JNDI Injection을 이용한 공격이 16년 블랙햇을 통해 이미 대두되었었고 CVE-2018-3149 를 기점으로 JNDI Injection을 이용한 Exploit이 제한되었다.

 

com.sun.jndi.ldap.object.trustURLCodebase 의 기본 값이 false 로 설정되었고 이는 신뢰되지 않은 원격지의 클래스 파일 로드가 비활성화된다. 그러므로 JNDI Injection을 수행할 피해자 서버의 Java 버전도 공격에 영향을 준다.

 

log4shell이 처음 공개되었을 때에는 Java 버전에 따라 제한이 있을 수 있다고 작성되었었지만 com.sun.jndi.ldap.object.trustURLCodebasefalse인 JDK 11.0.1, 8u191, 7u201, 6u211 이상 버전에서의 JNDI Injection를 우회하는 방법이 존재하기 때문에 대응책으로 Java 버전에 의존하지 않는 것이 좋다.

 

- 어느 Java 버전까지 우회가 가능한가?

 

 com.sun.jndi.ldap.object.trustURLCodebase  false Java 버전에서의 JNDI Injection을 우회하는 방법의 원리는

원격지에서 악성 팩토리를 요청할 수 없지만 피해자 서버 내 javax.naming.spi.ObjectFactory 인터페이스를 구현하고 하나 이상의 getObjectInstance() 메소드가 존재하는 클래스를 이용하여 우회를 시도한다 . 그 조건을 만족하는 클래스가 Tomcat 8의 org.apache.naming.factory.BeanFactory 클래스다.

 

해당 원리대로라면 다른 Java 서버(java 16을 최소로 요구하는 minecraft 1.17+ 등)에서도 Tomcat 8의 org.apache.naming.factory.BeanFactory 클래스와 동일한 조건을 가진 클래스가 존재할 시 우회 방법을 적용할 수 있어야 하는데 실행할 JAVA의 환경변수만 변경해주었는데도 최신 JDK 환경에서는 Bypass POC 코드가 실행되지 않는 것을 확인할 수 있었다.

POC Code : https://github.com/pimps/JNDI-Exploit-Kit
Target log4j version : log4j-2.12.1
Target Tomcat version : Tomcat 8.5.73
+----------------------------+-----------+-----------+------------+------------+ 
| Target Java environment    | JDK 8u181 | JDK 8u191 | JDK 16.0.2 | JDK 17.0.1 |
+============================+===========+===========+============+============+
| trustURLCodebase Bypass X  | O         | X         | X          | X          |
+----------------------------+-----------+-----------+------------+------------+
| trustURLCodebase Bypass O  | O         | O         | X          | X          |
+----------------------------+-----------+-----------+------------+------------+

 

 

- CVE-2021-44228를 조치하면 안전한가?

 

또한 Log4Shell 공격이 대두되고 나서 여러 파생된 취약점들 또한 많이 나왔는데

Original 에 해당하는 CVE-2021-44228 와 비슷하긴해도 전혀 다른 방법이므로 CVE-2021-44228에 대한 대응책을 적용할 시 다른 파생된 다른 취약점에 대해서도 조치가 되는 것이 아니므로 각 취약점에 대한 보안 대책을 확인하는 것을 권장한다.

 

 

공개 당시 파급력이 큰 취약점이였고 그만큼 대응또한 발빨랐다. 타격이 큰(RCE 등) 공격이 쉽게 가능하다고 설명되어있었지만 실제로 해당 공격을 성공하기 위해서는 취약한 log4j 버전 사용 여부, log4j가 로깅하는 영역 탐색, 취약한 java 버전 사용 여부, 그리고 공격 서비스의 인바운드/아웃바운드 설정까지 고려해야할 부분이 존재했던 것 또한 사실이다.

 

- Reference

 

https://www.tenable.com/blog/cve-2021-44228-proof-of-concept-for-critical-apache-log4j-remote-code-execution-vulnerability
https://www.lunasec.io/docs/blog/log4j-zero-day/
https://medium.com/s2wlab/logs-of-log4shell-cve-2021-44228-log4j-is-ubiquitous-kr-fb50a6458a08
https://logging.apache.org/log4j/2.x/manual/lookups.html

 

https://www.govcert.admin.ch/blog/zero-day-exploit-targeting-popular-java-library-log4j/#general
https://threezh1.com/2021/01/02/JAVA_JNDI_Learn/#RMI%E4%B8%8ELDAP
https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
https://reposhub.com/java/miscellaneous/phoswald-sample-ldap-exploit.html

https://foojay.io/log4j-cve/

https://paper.seebug.org/942/

 

https://github.com/tangxiaofeng7/CVE-2021-44228-Apache-Log4j-Rce

https://github.com/Puliczek/CVE-2021-44228-PoC-log4j-bypass-words

https://github.com/dbgee/log4j2_rce