PHP2Shell 취약점 점검 (CVE-2026-109618 · CVE-2026-109619)
내가 관리하는 PHP 사이트가 PHP2Shell에 노출됐는지 비파괴로 확인하는 무료 오픈소스 도구입니다.
무료 · MITPython 3.8+ 표준 라이브러리만공격 요청 없음한국어 · English · 日本語 보고서
📖 처음이라면: 실제 점검 사례로 보는 사용 가이드 — 버전만 보면 왜 틀리는지, 서버 안에서 어떻게 확정하는지
PHP2Shell이란
2026-10-21 공개된 PHP 런타임 취약점 2건으로, 두 CVE 모두 CVSS v4.0 9.2입니다. 인증 없는 원격 코드 실행(RCE)으로 이어지며, 웹 요청을 처리하는 PHP(Apache mod_php, PHP-FPM 등)는 사실상 전부 영향을 받습니다. 공개 PoC가 있고, 공개 4일 전(10-17)부터 실제 공격 시도가 관측됐습니다.
| PHP 브랜치 | 수정 버전 |
|---|---|
| 8.5 | 8.5.12 이상 |
| 8.4 | 8.4.27 이상 |
| 8.3 | 8.3.36 이상 |
| 8.2 | 8.2.35 이상 |
| 8.1 이하 | 공식 수정 릴리스 없음 — 배포판·LTS 벤더 패키지 또는 업그레이드 |
배포판 패키지(예: 8.2.7-1+deb12u5)는 버전 번호가 낮아도 백포트로 수정됐을 수 있습니다. 기준 시점 2026-10-23. 상세 근거: PHP 취약점 동향 문서 §2
1단계 — 내 사이트 URL로 1차 확인
사이트 주소를 넣으면 내 PC에서 실행할 명령을 만들어 줍니다. 점검기는 대상에 HTTP GET 한 번만 보내고, 응답 헤더에 드러난 PHP 버전을 수정 버전과 비교합니다.
결과 읽는 법
| 판정 | 의미 |
|---|---|
likely_vulnerable | 공개된 PHP 버전이 수정 버전보다 낮거나, 공식 수정이 없는 EOL 브랜치(8.2 미만). 2단계로 확정하십시오. |
not_vulnerable_by_version | 공개된 버전이 수정 기준 이상. 보조 신호일 뿐 안전 보장은 아닙니다. |
unknown | PHP 흔적은 있으나 버전 비공개(또는 8.3처럼 일부만 공개). |
not_detected | 응답에서 PHP 흔적을 찾지 못함. PHP가 없다는 뜻은 아닙니다. |
error / invalid | 연결·TLS 오류 또는 URL 형식 오류. |
운영 서버는 대개 버전을 숨기므로 unknown이 흔합니다. 버전만으로는 실제 공격 경로가 성립하는지 알 수 없으니, 서버에 접근할 수 있다면 2단계를 실행하십시오.
2단계 — 서버 안에서 확정 점검
PHP가 돌아가는 서버(Linux)에서 실행합니다. 설정 파일·패키지 정보·/proc·로그를 읽기만 하며, 명령 실행 0건·네트워크 요청 0건입니다. SAPI(mod_php/FPM)와 실효 설정(memory_limit, session.upload_progress.enabled 등)으로 CVE별 도달 가능성을 판정하고, 고칠 파일과 줄 번호를 보고서로 남깁니다.
curl -fsSLO https://raw.githubusercontent.com/neoqmin/php2shell/v0.1.0/php2shell_host.py echo '50a48c79c120774e9dccc27ee12672444b7730b31a32c2b833e650920ebf0925 php2shell_host.py' | sha256sum -c - sudo python3 php2shell_host.py --lang ko
결과는 ./php2shell_report_<호스트>/에 report.json, report_ko.md, report_ko.html(A4 인쇄용)로 저장됩니다. 보고서에는 서버의 취약점 정보가 들어 있으니 공개하지 마십시오.
보고서 예시(로컬 실험 환경, 실제 대상 아님): HTML · Markdown · JSON
| 판정 | 의미 |
|---|---|
| 도달가능 | 이 서버의 SAPI·실효 설정에서 공격 경로의 전제조건이 성립 |
| 완화됨(임시) | 임시 완화가 요청 파싱 전 단계에 적용됨. 안전이 아님 — 설정만으로는 완전히 완화되지 않음 |
| 판정보류 | 근거 부족·설정 읽기 실패. 도달불가가 아님 |
| 패치됨 | 수정 버전 이상 또는 패키지 changelog에 두 CVE 백포트 기록 |
지원: Debian/Ubuntu 패키지, 공식 Docker php:*-apache 이미지, Apache mod_php·nginx/Apache + PHP-FPM. RHEL 계열 패키지 버전, 공식 php:*-fpm 이미지, php-cgi·LiteSpeed·FrankenPHP는 아직 판정하지 못합니다. 전체 옵션과 한계는 README를 보십시오.
당장 패치할 수 없다면
유일한 완전 해결책은 PHP 업데이트입니다. 패치 전까지의 임시 완화(session.upload_progress.enabled=0, memory_limit·post_max_size 조정, multipart 차단 등)는 php.ini·FPM pool처럼 요청 파싱 전에 적용되는 곳에 넣어야 효과가 있습니다. ini_set()과 FPM .user.ini는 효과가 없습니다. 2단계 보고서가 서버별로 어디를 고칠지 알려 줍니다. 근거: 동향 문서 §2.6
자주 묻는 질문
원격 점검에서 not_vulnerable_by_version이면 안전한가요?
아닙니다. 헤더에 드러난 버전이 기준 이상이라는 뜻일 뿐이며, 프록시·로드밸런서가 버전을 가리거나 SAPI·설정처럼 원격으로 볼 수 없는 조건이 있습니다. 최종 판단은 서버 인벤토리와 2단계 점검으로 하십시오.
버전을 숨긴 서버(unknown)는 어떻게 확인하나요?
원격에서는 확인할 수 없습니다. 서버에서 php -v와 패키지 changelog를 보거나 2단계 점검기를 실행하십시오.
다른 회사 사이트도 점검해 볼 수 있나요?
허가 없이 하지 마십시오. 비파괴 GET 요청이라도 허가 없는 체계적 점검은 정보통신망법 등에 저촉될 수 있습니다. 다른 조직의 서버에서 문제를 발견했다면 직접 검증하지 말고 운영 주체나 KISA 보호나라·KrCERT/CC로 알리십시오.
도구가 무엇을 수집·전송하나요?
아무것도 전송하지 않습니다. 원격 점검기는 입력한 대상에 GET 한 번만 보내고, 서버 점검기는 네트워크 요청을 하지 않습니다. 보고서의 투명성 부록에 읽은 파일 목록이 기록됩니다.
공격(PoC) 코드가 들어 있나요?
없습니다. 공격 페이로드, 익스플로잇, 우회 기법을 포함하지 않으며 익스플로잇 저장소도 링크하지 않습니다.