Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/bickzero93/cve-2026-76904
Vulnerability AnalysisExploitationWeb Application ExploitationInformation GatheringPenetration Testing
GitHubbickzero93/cve-2026-76904

CVE-2026-76904

Python 스크립트로 GeoServer WFS 엔드포인트를 인벤토리화하고 PostGIS/GeoTools의 시간 기반 SQL 인젝션 취약점을 검증하며, 승인된 테스트를 위한 전용 PoC 모드를 제공합니다.

저장소 보기
1일 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

GeoServer WFS 인벤토리 및 인가된 검증

이 저장소는 GeoServer WFS 엔드포인트를 조사하기 위한 두 개의 Python 스크립트를 포함합니다.

개요

wfs_inventory.py

목적: 레이어, XSD 필드 및 WFS 값을 인벤토리화하고, 선택적으로 시간 기반 검사를 통해 후보를 검증합니다.

실행 예시:

root@kitploit:~
python3 wfs_inventory.py --url https://HOST --valid-fields 4
root@kitploit:~
python3 wfs_inventory.py --url https://HOST --valid-fields 4 --sleep 1 --confirm-sleep 5 --candidate-scope auto --timing-result-type auto
root@kitploit:~
python3 wfs_inventory.py --url https://HOST --layer namespace:layer --sleep 1 --confirm-sleep 5 --valid-diagnose output.txt

geoserver_sqli_working.py

목적: 인벤토리 기능과 별도의 PoC 모드를 결합한 진입점입니다.

실행 예시:

root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST --valid-fields 4 --sleep 1 --confirm-sleep 5
root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD --sleep 5
root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD --sleep 5 --query "SELECT current_database()"

중요 참고 사항: 시간 기반 검사와 PoC 모드는 명시적인 테스트 승인이 있는 시스템에만 사용해야 합니다. 일반 인벤토리 모드는 정규 WFS 작업만 사용합니다.

사전 요구 사항

  • Python 3.10 이상
  • 추가 Python 패키지 불필요; 두 스크립트 모두 표준 라이브러리만 사용
  • WFS 엔드포인트에 대한 네트워크 접근

선택적으로 실행 권한 부여:

root@kitploit:~
chmod +x wfs_inventory.py geoserver_sqli_working.py

빠른 시작

정규 WFS 쿼리로 후보 검색

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4

기본 경로 /geoserver/wfs가 자동으로 추가됩니다. 따라서 다음 지정은 동일합니다:

root@kitploit:~
https://HOST
https://HOST/geoserver
https://HOST/geoserver/wfs

다른 설치의 경우 전체 WFS 경로를 지정해야 합니다.

시간 기반 검사로 후보 검증

명시적으로 인가된 시스템에만 해당:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --sleep 1

검사 중 각 후보에 대한 측정값이 stderr에 표시됩니다:

root@kitploit:~
[sleep-check] phase=screen typeName=namespace:layer field_name=FIELD resultType=hits baseline=0.120s test=1.128s delta=1.008s passed=true
[sleep-check] phase=confirm typeName=namespace:layer field_name=FIELD resultType=hits requested=3s baseline=0.118s test=3.125s delta=3.007s vulnerable=true

스크린 통과는 아직 긍정적 결과가 아닙니다. 두 번째로 더 긴 측정도 통과해야만 매개변수 블록이 출력됩니다.

진단을 파일에 쓰기

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --sleep 1 \
  --valid-diagnose output.txt

--valid-diagnose FILE은 자동으로 상세 진단을 활성화하고 지정된 파일에 기록합니다.

자동 모드 흐름

기본 모드 auto는 WFS 정보를 다음 순서로 처리합니다:

  1. GetCapabilities가 한 번 열립니다:

    root@kitploit:~
    /geoserver/wfs?service=WFS&acceptVersions=2.0.0&request=GetCapabilities
    
  2. XML 응답이 스트리밍됩니다. FeatureType/Name이 발견되면 다음 typeName이 결정됩니다.

  3. 이 레이어에 대해 즉시 DescribeFeatureType이 version=2.0.0으로 실행됩니다.

  4. 스크립트는 XSD 요소를 추출하고 ID 또는 숫자 유사 이름을 가진 문자열/JSON 필드를 선택합니다.

  5. 후보는 호출 방식에 따라 검사됩니다:

    • --sleep 없음: 샘플 값이 구문적으로 유효한 JSON이어야 합니다.
    • --sleep N 포함: 제어 요청과 시간 기반 검사 요청이 측정됩니다. JSON 값 검사는 건너뜁니다.
  6. 결과가 즉시 출력되고 플러시됩니다.

  7. 그 후에만 실행 중인 GetCapabilities 응답에서 다음 typeName이 읽힙니다.

따라서 첫 번째 결과가 나타나기 전에 큰 GetCapabilities 응답을 완전히 처리할 필요가 없습니다.

필드 후보 기준

--sleep 없이 자동 모드는 기본적으로 ID 또는 숫자 유사 이름을 가진 문자열/JSON 필드를 고려합니다.

반면 --sleep 사용 시 --candidate-scope auto는 모든 단순 비지오메트리 필드를 사용합니다. XSD 유형과 ID 이름 패턴은 더 이상 타이밍 검사를 차단하지 않습니다. 이는 숫자, 날짜/부울 또는 공급업체별 XSD 유형에서 오탐(false negative)을 방지합니다.

인식된 이름 패턴은 다음과 같습니다:

root@kitploit:~
id
*_id
*_fid
nr_*
*_nr
*nummer*
fid
uuid
guid
key
objectid

시간 기반 검사에서 필드 이름은 추가로 [A-Za-z_][A-Za-z0-9_]* 형식의 단순 식별자여야 합니다.

JSON 검사와 Sleep 검사의 차이

--sleep 없이 관찰된 값이 구문적으로 JSON으로 해석될 수 있는지 확인합니다. 따라서 예를 들어 문자열 "383205"도 내용이 유효한 JSON 숫자이므로 후보로 간주됩니다. 이 검사는 휴리스틱이며 취약점 증명이 아닙니다.

--sleep 1 사용 시 시간 측정만 결정합니다. 후보는 검사 요청이 제어 요청보다 요청된 sleep 시간의 최소 70%를 추가로 필요로 하는 경우 기본적으로 양성으로 간주됩니다. --timing-result-type auto는 먼저 resultType=hits를 확인하고 음성 결과가 나오면 resultType=results를 확인합니다.

잠정적으로 양성인 측정값은 반드시 더 긴 sleep 시간으로 확인됩니다. 명시적 --confirm-sleep이 없으면 스크립트는 max(3, --sleep * 3)을 사용하며 최대 10초로 제한됩니다. 따라서 --sleep 1에서 단일 대기 시간 급증이 더 이상 vulnerable=true로 이어지지 않습니다.

간결한 출력

표준 출력에는 유효한 레이어당 하나의 블록이 포함됩니다:

root@kitploit:~
typeName=namespace:layer
field_name1=FIELD_A
parameter_string1=https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD_A
field_name2=FIELD_B
parameter_string2=https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD_B

parameter_stringN은 정규화된 WFS 엔드포인트와 --typename 및 --field_name에 대한 적절한 값을 포함합니다.

--valid-fields N은 개별 필드가 아닌 레이어 블록을 계산합니다. N개 미만의 유효한 레이어가 존재하면 나머지 카탈로그가 계속 조사됩니다. --max-layers로 최대 실행 시간을 제한할 수 있습니다.

상세 진단

--diagnose 또는 --valid-diagnose FILE 옵션은 다음을 추가로 제공합니다:

  • 정규화된 WFS 엔드포인트,
  • 사용된 GetCapabilities URL,
  • DescribeFeatureType URL,
  • XSD 필드 유형,
  • ID 및 사용 가능성 표시,
  • 검사된 샘플 수,
  • JSON 호환성 또는 타이밍 측정값,
  • 생성된 GetFeature URL 및
  • 복사 가능한 매개변수 문자열.

예시:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 10 \
  --valid-diagnose diagnose.txt

추가 인벤토리 모드

모든 레이어 나열

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode layers

네임스페이스로 제한:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode layers \
  --namespace fink

레이어의 XSD 필드 표시

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode fields \
  --layer namespace:layer

각 필드는 이름, XSD 유형, nillable, id_candidate 및 usable_property가 포함된 JSON 객체로 출력됩니다.

선택된 필드 값 내보내기

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode values \
  --layer namespace:layer \
  --field FIELD_A \
  --field FIELD_B \
  --max-features 100 \
  --format jsonl \
  --output values.jsonl

모든 속성 내보내기:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode values \
  --layer namespace:layer \
  --all-properties \
  --max-features 100

--unique를 사용하면 선택된 필드 값의 동일한 조합이 한 번만 출력됩니다.

wfs_inventory.py 매개변수

매개변수기본값설명
--url URL필수호스트, GeoServer 기본 또는 전체 WFS 엔드포인트
--mode auto|layers|fields|valuesauto실행할 운영 모드
--layer NAMESPACE:LAYER–자동 모드를 하나의 피처 타입으로 제한; fields 및 values에 필수
--namespace PREFIX–이 네임스페이스 접두사의 레이어만 고려
--capabilities-file FILE–다운로드 대신 로컬 GetCapabilities 응답 사용
--field NAME반복 가능values 모드에서 내보낼 속성
--all-properties꺼짐values 모드에서 모든 속성 내보내기
--unique꺼짐중복 필드 값 조합 억제
--page-size N500GetFeature 페이지당 피처 수; 범위 1~5000
--sample-size N5JSON 구문 검사를 위한 레이어당 샘플 값 수; 범위 1~100
--sleep SECONDS0시간 기반 검증 활성화; 0 또는 1~10초 허용
--candidate-scope auto|id|allauto후보 선택; auto는 sleep 없이 ID 필드를, sleep 사용 시 모든 비지오메트리 필드를 사용
--timing-result-type auto|hits|resultsauto타이밍 검사의 쿼리 경로; auto는 hits를 시도한 후 results를 시도
--sleep-threshold RATIO0.7필요한 sleep 시간 비율; 범위 0.5~1.0
--confirm-sleep SECONDS0/자동확인 sleep; 0은 첫 번째 sleep 시간의 최소 3배 사용, 범위 1~10
--start-layer-index N

결합 진입점

geoserver_sqli_working.py는 인벤토리 기능을 직접 호출할 수 있습니다. --valid-fields가 지정되면 인벤토리만 실행되고 프로그램이 종료됩니다.

결합 스크립트를 통한 인벤토리

root@kitploit:~
python3 geoserver_sqli_working.py \
  --target https://HOST \
  --valid-fields 4 \
  --sleep 1 \
  --valid-diagnose output.txt

내부적으로 다음 매개변수가 wfs_inventory.py에 전달됩니다:

root@kitploit:~
--target         -> --url
--valid-fields   -> --valid-fields
--valid-diagnose -> --valid-diagnose
--sleep          -> --sleep
--candidate-scope -> --candidate-scope
--timing-result-type -> --timing-result-type
--sleep-threshold -> --sleep-threshold
--confirm-sleep -> --confirm-sleep

명시적 --sleep 없이 인벤토리 모드에서 시간 기반 검사는 비활성화된 상태로 유지됩니다.

별도 PoC 모드

명시적으로 인가된 테스트 시스템에만 해당:

root@kitploit:~
python3 geoserver_sqli_working.py \
  --target https://HOST/geoserver/wfs \
  --typename namespace:layer \
  --field_name FIELD \
  --sleep 5

PoC 모드에서는 대상 경로가 자동으로 정규화되지 않습니다. 여기서는 전체 WFS 엔드포인트를 지정해야 합니다.

이 모드는 먼저 기준선/sleep 테스트를 수행하고, 기존 시간 기반 오라클 변형을 테스트한 다음, 성공적인 확인 시 기본적으로 서버/데이터베이스 메타데이터를 읽습니다. --query로 대신 사용자 정의 스칼라 쿼리를 지정할 수 있습니다.

PoC 모드는 현재 내부적으로 TLS 인증서 검사를 비활성화합니다. 순수 인벤토리의 경우 TLS가 기본적으로 검사되는 wfs_inventory.py를 사용하는 것이 좋습니다.

geoserver_sqli_working.py 매개변수

매개변수기본값설명
--target URL필수대상 호스트 또는 WFS 엔드포인트; PoC 모드에서는 전체 WFS 경로 사용
--typename NAMEfink_bku:fink_meta_mitte_suedwestPoC 모드의 피처 타입
--field_name NAMEPoC 모드에서 필수jsonArrayContains용 단순 XSD 필드 이름
--field-name NAME별칭--field_name의 별칭
--valid-fields N–인벤토리 모드 활성화 및 N개의 유효한 레이어 후 중지
--valid-diagnose FILE–상세 인벤토리 보고서를 FILE에 쓰기; --valid-fields 필요
--sleep SECONDSPoC: 5, 인벤토리: 꺼짐각 모드의 sleep 기간
--candidate-scope auto|id|allauto인벤토리 모드의 후보 선택
--timing-result-type auto|hits|resultsauto인벤토리 모드의 타이밍 쿼리 경로
--sleep-threshold RATIO0.7인벤토리 모드의 타이밍 임계값
--confirm-sleep SECONDS자동인벤토리 모드의 확인 sleep
--query SQL–PoC 모드의 사용자 정의 스칼라 쿼리
--debug꺼짐PoC 모드에서 조건, 실행 시간 및 결정 표시

JSONL 보고서

자동 모드는 텍스트 블록 대신 JSON Lines를 생성할 수 있습니다:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 10 \
  --report-format jsonl \
  --output report.jsonl

--diagnose 사용 시 각 레코드에는 URL, 후보 메타데이터, 검사 값 및 필드별 GetFeature URL이 추가로 포함됩니다.

프록시 및 TLS

프록시 사용:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --proxy http://127.0.0.1:8080 \
  --valid-fields 4

자체 프록시 CA 신뢰:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --proxy http://127.0.0.1:8080 \
  --proxy-ca proxy-ca.pem \
  --valid-fields 4

인가된 테스트 시스템에 대한 TLS 검사 비활성화:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --insecure \
  --valid-fields 4

--proxy-ca와 --insecure는 함께 사용할 수 없습니다.

대규모 WFS 카탈로그 및 성능

큰 GetCapabilities 응답의 경우 다음 옵션이 도움이 됩니다:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --max-layers 100 \
  --sample-size 1 \
  --timeout 10 \
  --retries 0 \
  --delay 0

참고 사항:

  • GetCapabilities는 한 번만 요청된 후 스트리밍됩니다.
  • --valid-fields 4는 4개의 유효한 레이어 후에만 스캔을 종료합니다. 더 적은 결과가 존재하면 검색은 끝까지 또는 --max-layers까지 실행됩니다.
  • --sample-size 1은 JSON 휴리스틱의 비용을 줄입니다.
  • Sleep 모드에서는 JSON 샘플이 건너뜁니다. 쿼리 경로당 하나의 제어 요청과 하나의 검사 요청이 수행됩니다. --timing-result-type auto에서는 음성 hits 결과 후 추가로 두 개의 results 요청이 실행됩니다.
  • 잠정적으로 양성인 후보는 확장 확인을 위해 두 개의 추가 요청을 발생시킵니다. 그 후에만 취약한 것으로 간주됩니다.
  • --candidate-scope id는 타이밍 요청 수를 줄이지만 다른 이름의 취약한 필드를 놓칠 수 있습니다.
  • --namespace 및 --start-layer-index는 검색 공간을 추가로 제한할 수 있습니다.

문제 해결

The read operation timed out

  • 서버 응답이 느린 경우 --timeout을 늘립니다.
  • 긴 재시도를 피하려면 --retries 0을 설정합니다.
  • --max-layers 및 --namespace를 사용합니다.
  • JSON 휴리스틱의 경우 --sample-size 1을 사용합니다.

출력 없음

  • --sleep 없이 후보는 --candidate-scope에 따라 XSD/이름 검사와 JSON 구문 검사를 통과해야 합니다.
  • --sleep 사용 시 시간적으로 확인된 후보만 매개변수 블록으로 출력됩니다; 음성 측정값은 stderr에 [sleep-check]로 표시됩니다.
  • 원하는 결과 수보다 적은 경우 스캔이 오래 계속될 수 있습니다. 이 경우 --max-layers를 설정합니다.

Cannot do natural order without a primary key

첫 번째 GetFeature 페이지의 경우 스크립트는 startIndex=0을 보내지 않습니다. 일부 GeoServer/JDBC 레이어는 기본 키 없이도 자연 정렬을 강제하기 때문입니다. 추가 페이지를 내보낼 때 이러한 레이어는 여전히 기본 키 또는 서버 측 지원 정렬이 필요할 수 있습니다.

schema does not define ...Type

스크립트는 일반적인 <LayerName>Type과 전역 XSD 레이어 요소에서 참조되거나 익명인 다른 complexType을 모두 고려합니다. 오류가 지속되면 해당 DescribeFeatureType 응답을 --diagnose로 확인해야 합니다.

샘플 검사 시 HTTP 400

전체 OWS 오류 메시지가 stderr에 출력됩니다. 일반적인 원인은 지원되지 않는 속성, 서버 측 페이징 설정 또는 레이어별 데이터 소스 구성입니다.

터미널에서 직접 도움말

root@kitploit:~
python3 wfs_inventory.py --help
python3 geoserver_sqli_working.py --help
도구 다운로드
0
처음 N개의 스트리밍된 레이어 건너뛰기
--max-layers N0최대 N개 레이어 처리; 0은 무제한
--valid-fields N0N개의 유효한 레이어 블록 후 중지; 0은 무제한
--valid N별칭--valid-fields의 하위 호환 별칭
--max-features N0values 모드에서 N개 피처 후 중지; 0은 무제한
--format jsonl|csv|textjsonlvalues 모드의 출력 형식
--output FILEstdout보고서 또는 값을 파일에 쓰기
--report-format blocks|jsonlblocks자동 보고서 형식
--diagnose꺼짐URL, 유형, 선택 플래그 및 검사 통계 추가
--valid-diagnose FILE–진단 활성화 및 FILE에 직접 쓰기
--delay SECONDS0.1결과/검사 단계 사이의 일시 중지
--timeout SECONDS30HTTP 요청당 타임아웃
--retries N2타임아웃 또는 네트워크 오류 후 재시도; 범위 0~10
--proxy URL–HTTP(S) 프록시, 예: http://127.0.0.1:8080
--proxy-ca FILE–프록시 인증서를 신뢰하기 위한 PEM CA 인증서
--insecure꺼짐TLS 인증서 검사 비활성화
--authorization TEXTI_AM_AUTHORIZED보안 확인; 정확히 I_AM_AUTHORIZED여야 함