원문 캡처 · php2shell.site
원문 캡처 · php2shell.site

결과 읽는 법

PHP 감지는 X-Powered-By: PHP/… 헤더(PHP 자체만 해당하며 Next.js·Express·KPHP는 제외)나 응답의 PHP 세션 쿠키를 기준으로 한다. 감지된 버전은 결과 위에 표시된 패치 버전 목록과 비교한다. 이 목록은 운영자가 서버 측에 보관한다. 배너가 없으면(CDN이 제거했거나 expose_php=Off인 경우 등) 버전을 알 수 없다고 표시한다. 배너가 없다는 사실만으로 안전하다고 볼 수는 없다.

차단 여부를 확인할 때는 POST·PUT·PATCH 메서드마다 일반 폼 요청과 업로드 형식의 멀티파트 요청을 비교한다. POST만 차단하는 것으로는 충분하지 않다. PHP 8.4 앱은 다른 메서드에서도 멀티파트 요청을 읽을 수 있다. 빨간색 ASSUMED VULNERABLE은 해당 요청이 백엔드까지 전달되고 패치된 런타임을 확인하지 못했다는 뜻이다. 패치된 PHP 버전을 확인할 때까지 취약한 사이트로 취급해야 한다.

NO PHP DETECTED는 이 URL에서 POST 형태의 요청이 처리되지 않고(연결이 끊기거나 405/501 응답) PHP 지표(배너 또는 세션 쿠키)도 없다는 뜻이다. 정적 사이트와 일치하는 결과로, 이 URL에서는 악용할 대상이 없다는 의미다.

점검 방식과 한계

한 번에 URL 하나를 점검하며, 비활성 요청 7개를 보낸다. GET 1개 뒤에 각 메서드마다 일반 요청과 멀티파트 요청을 하나씩 보낸다. 업로드 진행률 필드나 파일 부분은 넣지 않으므로 취약한 코드 경로를 실행하지 않는다. 브라우저처럼 리디렉션을 따라가며 301/302/303은 GET으로 바꾸고, 307/308은 메서드를 유지한다. 리디렉션은 최대 3회까지 따르며, 판정에는 첫 응답의 상태 코드가 사용된다.

CDN/WAF에서 요청을 거부하면 PHP가 본문을 파싱하기 전에 차단된다. 애플리케이션 내부에서 같은 상태 코드가 반환된 경우와 원격에서 구분할 수 없으므로, 점검기는 이를 구분할 수 없다고 알린다. 원본 서버에 직접 접속할 수 있다면 CDN에서 차단해도 보호되지 않는다. 연결을 거부하는 URL은 초록색 OFFLINE으로 표시한다. 해당 위치에서 서비스 중인 것이 없으므로 점검할 대상도 없다는 뜻이다.

이 도구는 패치 상태와 설정을 확인하며 취약점을 탐지하지 않는다. 익스플로잇 형태의 요청은 보내지 않는다. 세션 쿠키, 파일 부분, 업로드 진행률 필드를 포함하지 않으며 요청을 지연시키지도 않는다. 결과는 브라우저 세션에만 저장되고 내보내기 엔드포인트는 없다. 테스트한 URL은 북마크나 공유를 위해 주소창의 /… 경로에 남으며 다른 곳으로 전송되지 않는다. 제출할 때마다, 그리고 각 상태 확인 요청 때마다 브라우저에서 간단한 작업 증명(proof-of-work)을 수행한다. 이는 남용을 막기 위한 조치로 점검당 약 1초가 걸린다. 확실한 해결책은 패치된 PHP 런타임을 사용하는 것이다.

결과는 외부에서 확인한 최선의 추정치일 뿐 보장되지 않는다. 배너가 실제와 다를 수 있고 캐시가 원본 서버를 감출 수 있으며, 엣지 동작은 경로마다 다를 수 있다. 이는 취약점 평가가 아니므로 호스트에서 직접 확인해야 한다. 사람과 대규모 언어 모델을 위한 문서는 llms.txt에서 볼 수 있다.