PHP2Shell: the leaked PHP RCE everyone is staging and no one has landed (yet)
PHP2Shell 유출 뒤 공격 도구가 준비됐지만 실제 침해는 확인되지 않았습니다
PHP 핵심부의 원격 코드 실행 취약점 두 건이 패치 전에 유출됐고, 패치 배포 약 20분 뒤부터 스캔이 시작됐습니다. Hunt.io는 공격 도구와 시도는 확인했지만 실제 침해는 찾지 못했으며, 메모리 손상에서 실제 코드 실행으로 이어지려면 추가 조건이 필요하다고 설명합니다.
- 주제
에디터 노트
현재 공개된 PoC가 현실 환경에서 작동하는지와 실제 공격이 성공했는지는 별개의 쟁점입니다. Hunt.io는 최대 123개 서버를 대상으로 한 시도에서도 셸을 찾지 못했다고 밝혔지만, Reddit 댓글에는 Amazon 센서가 광범위한 실제 악용을 관측했다는 상반된 주장이 있습니다. 댓글만으로는 그 주장의 범위와 근거를 확인할 수 없어 원문의 미확인 판단을 뒤집을 증거로 보기는 어렵습니다. 취약점의 진입점은 인증 전 multipart 요청이며 PHP 핵심부의 OOM 처리 결함입니다. 다만 코드 실행에는 추가 조건이 필요하다는 설명과 공개 PoC의 제약이 함께 제시됩니다. 노출 IP 수는 PHP 신호가 보이는 고유 IP의 하한이고, 배포판 백포트 때문에 버전 표기만으로 취약성을 판정할 수도 없습니다. 따라서 수치와 공격 징후는 위험의 범위를 보여주지만 실제 침해 규모를 측정하지는 않습니다.
AI 요약
PHP2Shell은 PHP 인터프리터의 메모리 부족 처리 과정에서 발생하는 원격 코드 실행 취약점 두 건(CVE-2026-109618, CVE-2026-109619)입니다. 둘 다 CVSS v4.0 점수는 9.2입니다. PHP 보안팀이 예고한 패치 시점인 2026년 10월 21일 14:00 UTC 전에 세부 정보가 유출됐고, PHP는 8.5.12, 8.4.27, 8.3.36, 8.2.35에서 수정했습니다.
취약점 작동 방식과 노출 범위
PHP의 기존 OOM(Out of Memory) 처리 경로는 할당 실패 시 longjmp()로 실행 맥락을 빠져나왔습니다. 일부 초기화가 끝나지 않은 상태를 정리하지 않아 요청 종료 과정에서 잘못된 상태를 읽거나 분기할 수 있었고, 수정 패치는 이 경로를 제거했습니다. 공격자는 multipart/form-data 요청으로 메모리 고갈을 유도합니다. session.upload_progress가 대표적인 유발 조건이며 기본 설정에서 인증 없이 요청 파싱 단계에 도달할 수 있습니다. 다만 메모리 손상이 곧바로 코드 실행을 뜻하지는 않습니다. 실제 사이트에서 실행하려면 추가 취약점이 있거나 ASLR이 꺼져 있어야 한다고 보고서는 설명합니다.
Hunt.io는 10월 22일 기준 HTTP 헤더와 쿠키 등 PHP 관련 신호가 보이는 인터넷 연결 IP 3,189,999개를 집계했습니다. 그중 1,665,351개는 헤더에 버전을 표시했고 나머지는 PHPSESSID, laravel_session, WordPress 경로 등 다른 신호로 탐지됐습니다. 이는 IP 수이며 한 IP에서 여러 사이트를 운영해도 한 번만 셉니다. PHP를 드러내지 않는 호스트는 빠지므로 실제 규모의 하한입니다. 버전 문자열만으로 취약 여부를 판단하기도 어렵습니다. Linux 배포판은 PHP 버전 표기를 그대로 두고 보안 패치를 백포트할 수 있습니다.
공격 시도와 대응
패치 배포 약 20분 뒤 허니팟에서 스캔이 관측됐습니다. 보고서 작성 시점까지 허니팟은 한 IP에서 요청 두 건을 기록했고, AttackCapture에서 PHP2Shell 도구를 보유한 공개 작업 디렉터리 약 10곳을 찾았습니다. 한 운영자는 약 97개 프록시를 거쳐 최대 123개 서버를 대상으로 10차례 실행했지만 셸을 얻지 못했습니다. 공개 PoC를 검토한 연구자들도 x86-64의 실제 환경에서 작동하는 코드를 찾지 못했다고 보고했습니다. 공격자는 오래된 PHP를 쓰는 상거래, 결제, 호스팅 서버를 주로 겨냥했지만, 수집된 표적 목록에서도 PHP2Shell 침해는 확인되지 않았습니다. 디렉터리에서 발견된 AVideo 계정 정보 탈취는 별도의 SQL 인젝션 공격 결과로 분리했습니다.
보고서는 취약 버전을 수정된 PHP로 올리고, 당장 패치할 수 없다면 WAF를 임시 방어층으로 두라고 권고합니다. Cloudflare는 모든 요금제에 관리형 WAF 규칙을 배포했지만 일부 시도를 막는 수준이며 패치를 대체하지는 않습니다. php2shell 문자열이 포함된 User-Agent, PHP_SESSION_UPLOAD_PROGRESS 필드가 든 대용량 multipart POST, PHP-FPM의 연속된 "Allowed memory size exhausted" 오류를 탐지 지표로 제시합니다.
Reddit 반응
- @CellAccomplished1149 — Amazon은 다르게 말합니다. 엠바고가 풀리고 패치가 공개된 뒤 몇 시간 안에 추가 PoC가 나왔고 센서에서 곧바로 관측됐으며, PHP2Shell이 현재 실제 환경에서 광범위하게 악용되고 있다고 합니다.
- @RoamingThomist — PoC가 존재해도 작동하지 않을 수 있습니다. 작동하는 익스플로잇 코드가 어딘가에 있을 가능성은 있지만 공개된 PoC는 실제로 작동하지 않습니다.
- @TheDizDude — 대부분 ASLR 문제에 부딪히는 것 같습니다.
- @LLMsMustUpvoteThis — 원래 PoC는 PHP-FPM 워커가 하나뿐인 환경이나 ASLR이 꺼진 환경에서만 작동한 것 같습니다. 실제 환경의 다중 워커와 ASLR을 고려하면 악용하기가 매우 어렵지만 공격자는 계속 개선할 것입니다.
- @an0n_r0 — 자신이 찾은 가장 정교한 ASLR 우회 PoC를 시도했지만 특정 실험 환경에서만 작동했다고 합니다. 워커 수보다 display_errors=on이 더 큰 걸림돌이며, 애플리케이션에 LFI가 있으면 달라질 수 있다고 덧붙였습니다. 현재 현실 환경에서 작동하는 RCE PoC는 없다는 요지입니다.
- @smelly-dorothy — 해당 PoC가 작동하는 것을 검증했다고 합니다. 다만 공격자가 페이로드를 바이트 단위로 눈먼 상태에서 직렬화해야 할 것 같다고 덧붙였습니다.
- @limlwl — 공격을 막으려고 웹사이트를 내린 조치가 WAF와 방화벽, IPS를 갖추는 것보다 더 큰 피해를 줬다고 주장합니다.
- @DiggyTroll — 방어를 준비하는 동안 취약한 서비스를 계속 열어두자는 뜻이냐고 반문합니다.
- @jeeeaar — 위험에 따른 결정이라고 답합니다. 서비스를 내리지 않고 WAF 규칙과 공격 표면 축소로 완화하면서 패치했고, 자신이 본 범위에서는 침해 증거가 없었다고 합니다.
- @TypicalDependent9844 — 허니팟으로 공격 여부를 알 수 있을 것이라고 말합니다.
- @tindalos — 실제 공격자는 예상과 다른 방식으로 움직일 수 있으며, 무작위 IP의 직원 포털 같은 조직이 위험할 수 있다고 주장합니다. 잠재적 영향이 커 실제 피해 규모를 알기 어렵다는 의견입니다.
원문: Hunt.io / 번역·요약: Trawling