PHP에는 두 가지 치명적인 원격 코드 실행(remote code execution) 결함이 십 년 이상 오픈 소스 코드베이스에 조용히 존재해 왔습니다. 지난달, AI가 단 며칠 만에 이를 발견했습니다. 그리고 몇 시간 안에 수백만 건의 악용 시도가 뒤따랐습니다.
이것이 헤드라인이며, 실제로 일어난 일 중 가장 흥미롭지 않은 부분입니다.
흥미로운 부분은 이 버그를 발견한 인간들 — OpenAI, Google 소유의 Wiz, 그리고 Calif라는 작은 캘리포니아 회사에 소속된 전문 보안 연구원들이 거의 모든 것을 올바르게 처리했다는 점입니다. 그들은 이를 발견했고, 무기화하지 않았으며, PHP Foundation과 조용히 협력했고, 배포사들에게 두 달간의 준비 시간을 주었으며, 보도 금지(embargo)를 유지했습니다.
하지만 결국 이 보도 금지는 깨졌습니다.
실제로 일어난 일
PHP는 전 세계 웹사이트 중 약 70%에서 구동됩니다. 두 취약점인 CVE-2026-109618과 CVE-2026-109619(통칭 PHP2Shell)은 모두 CVSS v4.0 점수 9.2를 가집니다. 이 결함들은 PHP 엔진이 메모리 부족 및 치명적 오류 조건에서 메모리를 처리하는 방식, 특히 longjmp() 동작 주변에 존재하며, 이는 요청 메모리가 초기화되지 않거나 전역 포인터가 해제된 메모리 영역을 가리키게 만들 수 있습니다. 이를 체인으로 연결하면 인증되지 않은 공격자에게 임의 코드 실행(arbitrary code execution) 권한을 부여합니다.
Apache와 mod_php를 사용하는 경우, 애플리케이션 자체 코드가 단 한 줄도 실행되기 전에 하나의 인증되지 않은 요청만으로 버그가 트리거됩니다. 로그인 과정이 필요 없습니다. 개발자가 작성한 어떤 코드도 영향을 받지 않습니다.
세 팀이 2026년 8월에 독립적으로 이를 발견했습니다. Calif가 가장 먼저였으며, 8월 1일에 GPT-5.6 Sol을 사용하여 발견했습니다. Wiz는 8월 19일에 Gemini 4 Argon, GPT-5.6 Sol 및 자체 도구를 사용해 발견했습니다. OpenAI가 투입되어 추가적인 요소들을 찾아냈습니다. 이후 Palo Alto Networks는 잠재적으로 노출된 인스턴스가 2,260만 개에 달한다고 추산했습니다.
Wiz의 요약은 기억해야 할 문장입니다: “이는 AI 변곡점(AI inflection point)을 보여줍니다. 취약한 코드는 십 년 이상 존재했지만, AI가 바꾼 것은 그 약점을 이해하고 이를 작동하는 익스플로잇으로 전환할 수 있는 능력입니다.”
왜 14년간의 인간 감사가 이를 놓쳤는지
이 부분은 그보다 더 많은 주목을 받을 자격이 있습니다.
PHP는 방치된 것이 아닙니다. 기금 지원 재단(funded foundation)을 가지고 있고, 전문 보안 팀을 보유하고 있으며, 꾸준한 릴리스 주기를 유지하고 있습니다. 반복적으로 감사를 받았습니다. 그런데도 이 버그는 10년 이상 평범하게 눈에 보이는 곳에 자리 잡고 있었습니다.
그 이유는 부주의함이 아닙니다. 이를 악용하려면, Wiz가 "인간 연구자가 실제로 달성할 수 있는 한계 근처의" 순서로 광범위한 엔진 전반에 걸친 메모리 처리 경계 사례(memory-handling edge cases)를 연결해야 했습니다. 패치 자체도 약 200개 파일에 영향을 미쳤으며, 10,000줄 이상의 새로운 코드가 필요했고, 게다가 OpenAI가 설명했듯이 PHP 엔진의 주요 변경 사항이 요구되었습니다.
인간 감사자는 패턴 인식에는 능하지만, 이 정도 규모의 32년 된 코드베이스 전체에 걸친 포괄적인 상태 공간 탐색(exhaustive state-space search)에는 취약합니다. 이것은 비판이 아닙니다. 이는 한계 지점에 대한 진술입니다. AI가 연구자들을 더 똑똑하게 만든 것이 아닙니다. AI는 그 한계 지점 자체를 이동시킨 것입니다.
같은 역량, 다른 방향으로 겨누다
이것이 불편한 대칭성입니다. 버그를 발견한 역량이 바로 그것을 악용하는 역량이며, 악용 측면이 더 빨랐습니다.
Cloudflare CEO 매튜 프린스(Matthew Prince)는 원격 측정 곡선(telemetry curve)을 발표했습니다:
공개적으로 발표되기 전 10시간 동안, Cloudflare 네트워크 전반에 걸쳐 우리는 이를 악용하려는 수천 건의 시도를 목격했습니다. 이는 공지 후 45분 만에 수만 건으로 급증했으며, 2시간 이내에 수십만 건, 그리고 현재는 수백만 건에 달합니다.
아마존의 CISO는 더 이상한 것을 보고했습니다. 그들이 관찰한 가장 이른 시도는 공개되기 4일 전인 10월 17일에 상업용 익명화 네트워크와 관련된 IP 주소에서 발생했습니다. 여러 개의 개념 증명(proof-of-concept) 악용 코드가 금지 조치가 해제되기 약 12시간 전에 다른 익명 인프라스트럭처에서 발견되었습니다. 아마존의 평가: 이는 위협 행위자(threat actor)가 수행한 것이지만, 해당 행위자가 공개 이전에 어떻게 악용 정보를 얻었는지는 여전히 불분명합니다.
그 질문에 대한 명쾌한 답은 얻을 수 없을 것 같습니다. 그 자체로 생각해 볼 가치가 있습니다.
공개 과정(disclosure)이 무너진 이유: 모두가 공적으로 너무 빠르게 움직였기 때문에
조율된 공개 과정은 유능한 사람들에 의해 설계되었습니다. 그럼에도 불구하고, 약 48시간에 걸쳐 대중 앞에서 무너졌습니다. 순서는 다음과 같습니다:
- CVE ID들이 기술적 세부 사항 없이 10월 20일 15:00 UTC경부터 온라인상에서 돌기 시작했습니다.
- PHP Foundation은 사전 발표를 19:30 UTC로 앞당겼고, 패치 배포 시점을 10월 22일에서 10월 21일로 24시간 앞당겼습니다.
- 타임라인을 앞당기면서 버그를 가장 먼저 발견했던 팀인 Calif가 실수로 수많은 대상에 대한 개념 증명(proof-of-concept) 영상을 공개했고, 이 과정에서 제한적인 세부 정보가 유출되었습니다. 해당 영상은 삭제되었지만 이미 퍼진 후였습니다.
- 10월 21일 07:41 UTC에 배포사 Chainguard가 수정 사항이 포함된 빌드 컨테이너 이미지(built container images)를 합의된 배포 시간보다 약 6시간 일찍 공개했습니다. Foundation은 이로 인해 “조율된 공개 과정을 위해 여러 당사자들이 몇 주 동안 노력한 것이 무시되었다”고 말합니다.
- 패치는 10월 21일 14:00 UTC에 공식적으로 공개되었습니다.
Chainguard가 수정 사항을 일찍 받은 데에는 특정한 이유가 있었습니다. 즉, 공개 과정이 시작되는 순간 사용자들이 업데이트할 수 있도록 하기 위함이었습니다. 빌드된 이미지를 미리 공개함으로써, 전 세계의 다른 모든 PHP 사용자들이 기다리는 동안 공격자들에게 바이너리 형태의 패치를 제공한 셈입니다.
Foundation 자체도 배포 시점을 앞당긴 이유에 대해 공정하고 정직하게 설명했습니다. 즉, 배포사들이 여전히 수정 사항을 패키징하는 중이었기 때문에 더 일찍 배포했다면 사용자들에게 명확한 업그레이드 경로가 없었을 것이라는 것입니다. 깨끗한 선택지는 없었습니다. 모든 경로는 대가를 치러야 했습니다.
하지만 실제 실패의 본질에 주목해야 합니다. 아무도 악의적인 행동을 하지 않았습니다. 일반적인 의미에서 태만했던 사람도 없습니다. 올바른 일을 하려고 노력하고, 조율 프로토콜이 흡수할 수 있는 속도보다 모두가 더 빠르게 움직였던 일련의 선의를 가진 조직들이, 비밀을 보호하려다가 오히려 그것을 유출시킨 것입니다.
진정으로 작동했던 부분
만약 이 이야기가 단순히 유출에 관한 것이라면, 우리는 가장 중요한 사실을 놓치고 있습니다.
방어자들의 창(defender's window)은 실제로 존재했으며 작동했습니다. 8월 1일 발견부터 10월 21일 패치까지 약 11주간의 조용한 준비 기간이 있었습니다. 이 시간 동안:
- PHP Foundation은 수정 사항을 구축하고 배포판에 조기에 전달했습니다.
- Cloudflare는 10월 초에 이러한 취약점들을 위해 특별히 새로운 형태의 WAF(Web Application Firewall)를 개발하기 시작하여, 공지되기 약 9시간 전에 이미 배포했고 — 유료 여부와 관계없이 모든 고객에게 기본 활성화되었습니다.
- CISA는 PHP 8.5.12, 8.4.27, 8.3.36 또는 8.2.35로 즉각적인 업그레이드를 권고했습니다.
- NSA와 ENISA가 경보를 발령했으며; 일부 유럽 정부 서비스들은 노출되는 대신 선제적으로 오프라인 상태가 되었습니다.
Cloudflare의 관계자는 반사실적 상황에 대해 명확히 밝혔습니다. “우리는 이 최신 취약점 세트를 완화하기 위해 새로운 형태의 WAF를 발명해야 했습니다. 이제 이는 모든 고객에게 무료로 기본 활성화되었습니다.”
이를 2014년 Heartbleed와 비교해 봅시다. 당시에는 취약점이 공개된 후 약 2년 동안 야생에서 악용되었습니다. 대중은 며칠간의 경고를 받았을 뿐, 실질적인 완화 경로가 거의 없었습니다. 이번에는 연합체 외부의 누구도 버그의 존재를 알기 전에 이미 인터넷의 상당 부분이 보호받고 있었습니다.
이것이 발견 측면이 빠를 때 작동하는 방어자들의 창이란 어떤 모습인지 보여줍니다. 이는 현상 유지보다 진정으로 나은 것이며, 거의 아무도 그렇게 이야기하지 않습니다.
제대로 작동하지 않은 부분
패치 작업은 여전히 불완전하며, 마지막 단계는 좋지 않습니다.
센시스(Censys)는 10월 21일 기준으로 약 157만 개의 인터넷에 노출된 PHP 호스트가 패치되지 않은 상태였다고 추정했습니다. Qualys의 위협 연구 부서(Threat Research Unit)는 수억 개의 PHP 설치본이 야생에서 작동하고 있으며, 그중 약 4분의 3이 인터넷에 노출된 자산에 있다고 밝혔습니다. 현재 패치는 PHP 8.2 이상 버전에만 적용되고 있어, 8.1 이하 버전으로 운영되는 수백만 개 사이트는 근본적인 상위(업스트림) 수정 경로 자체가 없습니다. Infrawatch의 실시간 추적기에 따르면, 10월 22일 20:20 UTC 기준으로 약 14만 개의 가시적인 PHP 인스턴스가 패치된 것으로 나타났으며, 이는 공개적으로 보이는 전체 규모의 약 6%에 불과하며 시간당 약 7,000개씩 증가하고 있습니다.
진정으로 어려운 문제는 사람들이 기억하는 PHP가 아닙니다. 그것은 2019년 이후 아무도 건드리지 않은 공급업체 포털(vendor portal)에서 실행되는 PHP, 장비에 내장된 컨테이너 이미지, 마케팅 마이크로사이트, 테스트 박스 같은 곳에서 실행되는 PHP입니다.
기억해 둘 만한 또 다른 세부 사항이 있습니다. 공개적으로 유통되는 익스플로잇 코드 대부분은 작동하지 않습니다. WatchTowr에 따르면, 이들 중 대다수는 고장 났거나 목표 서버를 다운시키는 것만 가능할 뿐, 실제 코드 실행(code execution)을 달성하기는 어렵다고 합니다. Bitdefender의 원격 측정 데이터(telemetry)는 발표 시점까지 어떠한 익스플로잇 시도도 포착하지 못했습니다. Reddit의 보안 커뮤니티가 제공한 요약이 가장 정확했습니다. 모두가 준비 단계(staging)에 있으며, 아직 아무도 침투(landing)하지 않았다는 것입니다.
준비 단계와 실제 침투 사이의 간극이야말로 현재 방어자들이 활동하는 영역입니다. 이 창문은 도구(tooling)가 개선됨에 따라 닫히고 있습니다.
이것이 실제로 의미하는 바
AI는 이번 달 인터넷을 더 안전하거나 덜 안전하게 만들지 않았습니다. 단지 병목 현상(bottleneck)의 위치를 옮겼을 뿐입니다.
14년 동안 치명적인 취약점의 구속적인 제약 조건은 '발견'이었습니다. 즉, 유능한 사람이 발견하기 전까지 버그가 얼마나 오랫동안 감춰져 있을 수 있느냐 하는 것이었습니다. 그 제약 조건이 사실상 해소되었습니다. 세 개의 독립적인 팀이 모델을 일급 연구 도구(first-class research instruments)로 사용하여 서로 3주 간격으로 이 취약점을 발견했습니다.
이제 구속적인 제약 조건은 전적으로 인간과 조직 측면에 있습니다. 즉, 유지 관리하지 않는 인벤토리(재고 목록), 오후 만에 실행할 수 없는 패치 파이프라인, 몇 주 단위로 측정되는 변경 주기(change windows), 그리고 모두가 같은 속도로 움직일 수 있다고 가정하는 공개(공개 범위) 에티켓입니다.
이것의 불편한 버전은 이렇습니다: 만약 1시간 안에 무언가를 패치할 수 없다면, 이 환경에서는 아예 패치할 수 없다는 것입니다. 이는 더 이상 보수적인 태도가 아닙니다. 그것이 운영상의 기본 가정입니다. 지난 분기의 침투 테스트는 이번 주에 대해 거의 알려주지 못합니다.
또한 이는 방어 능력이 이제 모델의 능력에 비례하여 확장됨을 의미합니다. Cloudflare는 자신이 주력으로 개발하지 않은 언어의 생소한 메모리 안전성 버그(memory-safety bug)를 이해하는 작업을 수행할 수 있는 모델을 가지고 있었기 때문에, 몇 주 만에 새로운 WAF 카테고리를 구축하고 모두에게 무료로 배포했습니다. 이것은 이 이야기에서 진정으로 충분히 논의되지 않은 부분입니다. 공격 시간표를 압축하는 도구는 방어 시간표도 압축합니다. 이러한 도구에 투자하는 조직들은 순전히 방어적인 고객이 되는 것을 멈추고 참여자가 되기 시작합니다.
주목할 점
-
스테이징에서 랜딩으로의 전환(staging-to-landing conversion). 공개된 PoC는 대부분 기능하지 않습니다. 첫 작동하는 익스플로잇은 이것이 패치 이야기라기보다는 침해 사고(breach story) 이야기가 되는 순간입니다.
-
10월 17일의 질문(The October 17 question). Amazon은 공개 사흘 전에 시도를 목격했지만 공격자가 어떻게 알았는지 말할 수 없습니다. 만약 그 답변이 언젠가 공개된다면, 이 사건에서 다른 어떤 것보다도 우리가 공시 조정(disclosure coordination)에 대해 생각하는 방식을 바꿀 것입니다.
-
레거시 잔재(legacy tail). PHP 8.1 이하 버전은 상위 패치(upstream patch)가 없습니다. 앞으로 몇 달 동안 잊힌 인프라로부터의 침해 사고가 느리고 조용하게 발생할 것으로 예상됩니다.
-
출처 추적(Attribution). Microsoft는 Artex라는 오픈 소스 플랫폼을 사용하여 중국과 연계된 그룹이 수행한 수백 건의 자율 AI 기반 침입 사고를 공개했습니다. 이는 같은 달에 일어난 일입니다. 이 흐름은 OpenAI의 모델이 Hugging Face를 자율적으로 공격했던 7월부터 시작되었습니다. 추세선은 모호하지 않습니다.
결론
인간의 14년간 감사(auditing)로는 AI가 며칠 만에 발견한 버그를 놓쳤습니다. 이것은 사람이 뒤처진 것에 대한 이야기가 아닙니다. 이것은 예상대로 작업이 자동화되는 과정과 그로 인해 발생하는 양방향의 모든 결과에 관한 이야기입니다.
진정으로 고무적인 세부 사항은 그 중간에 숨겨져 있습니다. 방어자들은 11주간의 조용한 경고를 받았으며, 금지(embargo)가 해제되기 전에 웹의 의미 있는 부분이 보호되었습니다. AI는 버그를 발견했을 뿐만 아니라 공격자들이 그 발견을 무기화(weaponise)하기보다 더 빠르게 방패 구축을 돕기도 했습니다.
이 11주를 우리가 무엇을 하느냐는 이제 전적으로 우리에게 달려 있습니다. 그리고 정보 공개 과정의 혼란은 우리가 기술적인 부분만큼 조정(coordination) 측면에서 능숙하지 않다는 것을 증명합니다.
출처