PHP2Shell 조치: 버전 숨기기는 패치가 아닙니다 (직접 띄워 본 점검법)

사람이 직접 검수한 글 · 검수 검수 방식

예제 파일 2개 받기 ↓

PHP2Shell 조치는 웹 요청을 처리하는 PHP를 패치 버전(8.5.12, 8.4.27, 8.3.36, 8.2.35 이상)으로 올리고 PHP를 재시작하는 것입니다. 패치 전 버전인 PHP 8.4.26을 직접 띄워 보니, 설정 파일에 넣은 3개(공식 권고 임시 설정 2개와 버전 숨김 1개)는 넣은 직후에는 하나도 반영되지 않았고 재시작한 뒤에야 3개 모두 바뀌었습니다. 응답 헤더에서 버전을 숨겨도 PHP는 여전히 8.4.26이었습니다. 숨기기는 조치가 아닙니다.

직접 해 본 결과

재시작 전 반영 설정 파일을 넣은 직후, 웹에서 읽은 값
3개 중 0개
재시작 후 반영 Apache graceful 재시작 뒤
3개 중 3개
버전 숨긴 뒤 PHP 헤더에서만 사라짐
8.4.26 그대로

이 글의 파일

이런 분께 / 준비물

이런 분께 맞습니다.

  • 회사·가게 홈페이지가 워드프레스, 그누보드, 라이믹스처럼 PHP로 만들어져 있는 분
  • 홈페이지를 외주로 만들었거나 호스팅 업체에 맡겨서, 서버를 직접 만질 수 없는 분
  • 서버를 직접 운영하지만 “패키지만 올리면 끝”인지 헷갈리는 분

준비물

  • 내 사이트 주소
  • Windows PC(PowerShell은 기본으로 들어 있습니다). 설치할 프로그램은 없습니다.

1단계: 내 사이트의 PHP 버전부터 확인합니다

사이트가 응답할 때 함께 보내는 정보(응답 헤더)에 PHP 버전이 적혀 있는 경우가 많습니다. 기본 설정이 그렇습니다. 직접 띄운 PHP 8.4.26은 아무 설정도 하지 않은 상태에서 X-Powered-By: PHP/8.4.26을 보냈습니다.

방법 1. PowerShell 한 줄 (1분) 시작 메뉴에서 PowerShell을 열고, 주소만 바꿔 붙여 넣습니다.

(Invoke-WebRequest https://내사이트주소 -UseBasicParsing).Headers['X-Powered-By']

PHP/8.4.26처럼 나오면 그 숫자를 아래 확인기에 넣습니다. 아무것도 나오지 않으면 버전 표시를 꺼 둔 것이므로 3단계(업체 문의)로 갑니다.

방법 2. 브라우저만으로 크롬에서 내 사이트를 열고 F12 → ‘네트워크(Network)’ 탭 → 새로고침 → 맨 위 문서 줄 클릭 → ’응답 헤더’에서 X-Powered-By를 찾습니다.

PHP 버전 확인기

기준: 패치 버전 8.2.35, 8.3.36, 8.4.27, 8.5.12 (2026-10-21 공식 발표). 입력한 내용은 이 브라우저 안에서만 확인하며 어디에도 전송하지 않습니다.

2단계: 결과별로 할 일

내 상황과 확인 결과로 할 일이 갈립니다. 서버를 직접 관리하지 않는다면, 할 일은 대부분 “업체에 정확히 물어보기”입니다.

php.net 2026-10-21 공지와 KISA 2026-10-22 대응 수칙을 바탕으로 정리
확인 결과호스팅·외주로 운영서버를 직접 운영
패치 버전 이상업체에 재시작 여부만 확인PHP 재시작 여부와 실제 웹 버전 재확인
패치 전 버전문의 템플릿으로 바로 요청업데이트 → 모든 PHP 재시작 → 웹에서 버전 재확인
8.1 이하지원 버전 이전 일정과 임시 조치 여부 문의공식 패치 없음. 배포판·업체 백포트 확인, 8.3 이상으로 이전 계획
버전이 안 보임문의 템플릿으로 실제 버전 확인서버에서 phpinfo나 관리 화면으로 확인
  • PHP 8.1 이하는 PHP 프로젝트가 더는 업데이트를 내지 않습니다. 7.4, 8.0, 8.1은 직접 빌드하는 사람을 위한 소스 백포트만 나왔습니다.
  • PHP 8.2도 2026년 12월 31일에 지원이 끝납니다. 지금 옮긴다면 8.3 이상이 낫습니다.

3단계: 업체에 이 4가지를 물어보세요

호스팅사나 외주업체가 PHP를 관리한다면 적용 여부를 업체에 확인하고 요청하라는 것이 KISA 권고입니다. “패치했나요?“만 물으면 “네”로 끝나기 쉽습니다. 아래 4가지를 물어야 답이 확인 가능한 형태로 옵니다.

  1. 웹 요청을 처리하는 PHP 버전 (명령줄 php -v 결과가 아니라)
  2. 패치 적용 여부와 일시 (배포판 패치라면 패키지 이름과 버전)
  3. 패치 후 PHP를 재시작했는지
  4. 8.1 이하라면 백포트나 임시 조치 여부, 지원 버전 이전 일정

이 내용을 그대로 쓴 메일 템플릿을 내려받을 수 있습니다. 꺾쇠(<>) 부분만 바꿔 보내면 됩니다.

4단계: 바로 못 올린다면 임시 설정 + 재시작

업데이트만이 완전한 해결이고, 아래 설정은 일부 공격 경로를 줄일 뿐이라고 PHP 프로젝트가 밝혔습니다. 그래도 바로 올릴 수 없는 서버라면 공식 권고 설정을 넣습니다.

memory_limit = -1
post_max_size = 8M                  ; 파일 업로드가 필요하면 32M
session.upload_progress.enabled = 0
; PHP 8.5만: fatal_error_backtraces = 0
  • 설정 파일(php.ini, PHP-FPM 풀 설정, Apache 설정)에 넣습니다. memory_limit은 프로그램이 바꿀 수 없는 곳에 둬야 하고, session.upload_progress.enabled는 ini_set()이나 FPM의 .user.ini로는 효과가 없다고 공지에 적혀 있습니다.
  • post_max_size = 8M이면 8MB가 넘는 파일 업로드가 막힙니다. 워드프레스처럼 사진을 올리는 사이트는 32M으로 두고, upload_max_filesize는 그보다 작게 둡니다.
  • session.upload_progress.enabled = 0은 10월 23일 따로 알린 세 번째 취약점(CVE-2026-115560)도 막는 설정입니다. 이 취약점은 다음 정기 릴리스에서 고쳐질 예정이라, 패치 후에도 그대로 두는 것이 좋습니다.
  • 그리고 반드시 재시작합니다. 아래 실측에서 보듯, 재시작 전에는 하나도 반영되지 않았습니다.

같은 내용을 설정 파일 조각으로 받을 수 있습니다.

직접 해본 결과: 재시작 전 0개, 재시작 후 3개

운영 중인 서버에서 설정을 일부러 바꿔 볼 수는 없어서, 같은 버전의 PHP를 제 PC에 띄워 재현했습니다. 내 사이트가 실제로 어떤 상태인지는 1단계 방법으로 운영 서버를 직접 확인해야 합니다.

패치 전 PHP 8.4.26을 띄워 두고, 웹 페이지로 설정값 3개를 읽었습니다. memory_limit과 session.upload_progress.enabled는 공식 권고 임시 설정이고, expose_php는 버전 숨김 설정입니다. 그다음 세 값을 바꾼 설정 파일을 넣고, 재시작 전과 후에 다시 읽었습니다.

Docker 공식 이미지 php:8.4.26-apache·php:8.4.27-apache, 이 PC 안(127.0.0.1)에서만 접속, 각 1회
시점웹에서 읽은 설정 3개 (바꾼 값 반영)응답 헤더 X-Powered-By실제 PHP
기본 설정0/3 (128M · 켜짐 · 켜짐)PHP/8.4.268.4.26
설정 파일 넣은 직후0/3 (128M · 켜짐 · 켜짐)PHP/8.4.268.4.26
Apache 재시작 후3/3 (-1 · 꺼짐 · 꺼짐)(없음)8.4.26
패치 버전 8.4.27 기본 설정0/3 (128M · 켜짐 · 켜짐)PHP/8.4.278.4.27
측정 조건 Docker 공식 이미지 php:8.4.26-apache·php:8.4.27-apache, 이 PC 안(127.0.0.1)에서만 접속, 각 1회 측정일
명령 프롬프트 화면. 설정 파일 넣기 전과 넣은 직후 모두 memory_limit 128M, session.upload_progress.enabled 1, expose_php 1이다. 웹 서버 재시작 후에야 memory_limit -1, session.upload_progress.enabled 0, expose_php 빈 값으로 바뀐다. 마지막 줄의 실제 PHP 버전은 8.4.26이다.
웹 페이지로 읽은 설정값: 넣기 전, 넣은 직후, 재시작 후(2026-10-28 캡처)

표와 화면에서 세 가지가 보입니다.

  • 설정은 재시작 전까지 반영되지 않습니다. 파일만 넣고 끝내면 아무것도 바뀌지 않은 서버가 됩니다. 공식 공지가 “모든 워커를 재시작하라”고 쓴 이유입니다. 업데이트도 마찬가지로, 패키지를 설치해도 이미 돌고 있는 PHP 프로세스는 그대로입니다.
  • 버전을 숨겨도 PHP는 그대로입니다. expose_php = Off로 헤더에서 버전이 사라졌지만 PHP는 여전히 8.4.26이었습니다. 숨기면 스캐너에 버전을 알려 주지 않는 효과는 있지만, 취약점은 그대로 남습니다.
  • 숨긴 사이트는 바깥에서 확인할 수 없게 됩니다. 1단계 한 줄 명령도 숨긴 서버에서는 빈 줄만 돌려줬습니다. 헤더로 판정하는 외부 점검 서비스도 같은 한계가 있으니, 이때는 업체 답변이 유일한 확인 수단입니다.

놓치기 쉬운 것 3가지

1. 공개 전부터 공격이 있었습니다. Amazon은 공개 4일 전인 10월 17일에 이미 공격 시도를 관측했다고 밝혔습니다(Tenable 정리). 그래서 패치만 하고 끝내지 말고, KISA 권고대로 최소 10월 20일 이후 기록을 점검하고, 패치 전 노출됐던 서버의 DB 비밀번호·외부 API 키·관리자 비밀번호를 바꾸는 것이 좋습니다.

2. 침해가 의심되면 끄지 마세요. KISA는 서버를 끄거나 재시작하지 말고 외부 접속만 차단하라고 안내합니다. 재시작하면 메모리에 남은 흔적이 사라지기 때문입니다. 상담은 118(국번 없음)입니다.

3. Windows용 PHP는 한 번 더 받아야 합니다. 10월 26일 PHP는 Windows 빌드를 8.4.27-1처럼 -1을 붙여 다시 냈습니다. 같은 주에 Node.js에서도 발표된 Brotli 압축 해제 취약점(CVE-2026-111497) 때문입니다. PHP 버전 숫자는 같으니 숫자만 보면 놓칩니다. 같은 Brotli 취약점을 고친 Node.js 쪽 이야기는 Node.js 보안 업데이트 글에 정리했습니다.

주의할 점과 한계

  • 실측은 Apache + mod_php 한 가지 구성으로 했습니다. PHP-FPM, LiteSpeed 등은 재시작하는 방법이 다르지만, “재시작해야 반영된다”는 원리는 공식 공지와 같습니다.
  • 공격을 재현하지 않았습니다. 버전·설정·재시작 여부만 확인했습니다. 출처가 불분명한 공격 코드는 악성 코드가 섞여 있을 수 있으니 실행하지 말라는 것이 KISA 권고입니다.
  • 1단계 명령과 확인기는 헤더의 숫자만 봅니다. 배포판 패치처럼 숫자가 안 바뀌는 경우는 판정할 수 없습니다.
  • 사실 관계는 2026년 10월 28일 기준입니다. CVE-2026-115560의 정식 패치처럼 이후 바뀔 수 있는 내용은 php.net 공지를 다시 확인하세요.

직접 하기 어렵다면 맡겨 주세요

저는 현업 개발자이고 uriui.com에서 홈페이지 제작·유지보수 외주를 하고 있습니다. 내 사이트의 PHP 버전 확인, 업체 답변 해석, 지원 버전으로의 이전이 필요하면 사이트 주소와 함께 남겨 주세요. 메일로 답장드립니다.

어떤 일로 문의하세요? 필수

회사·고객사 내부 자료나 비밀번호는 적지 말아 주세요.

근거와 출처

직접 해 본 근거

  • 직접 측정 2026년 10월 28일 제 PC에 Docker로 PHP 8.4.26(패치 전)과 8.4.27(패치)을 Apache와 함께 띄워, 응답 헤더와 웹에서 읽은 설정값을 직접 확인했습니다. 외부 사이트에는 아무 요청도 보내지 않았습니다.
  • 직접 측정 설정 파일(공식 권고 임시 설정 2개 + 버전 숨김 1개)을 넣은 직후와 웹 서버를 재시작한 뒤에 같은 페이지를 다시 읽어, 설정 3개가 언제 반영되는지 비교했습니다.
  • 결과 파일 호스팅사·외주업체에 보낼 문의 메일 템플릿과, 공식 권고를 옮긴 임시 설정 파일을 내려받을 수 있습니다.
  • 직접 캡처 설정 파일을 넣기 전·직후·재시작 후에 웹 페이지로 읽은 값을 2026년 10월 28일 명령 프롬프트에서 직접 캡처했습니다.

참고한 출처