1. 실제 요청을 처리하는 PHP 확인
사이트에 지정된 PHP, 웹 서버 모듈, FPM 풀을 확인하세요. 공존하는 버전, 여러 사이트, 컨테이너, 부하 분산 노드를 각각 조사해야 합니다. php -v는 현재 CLI 버전만 보여 주며 웹 실행 버전과 다를 수 있습니다. 확인을 위해 phpinfo 페이지를 공개하지 마세요.
php -v 소유하거나 테스트 권한을 받은 URL을 입력하세요. PHP 특징, 버전 단서, 폼 응답을 순서대로 확인해 PHP2Shell 노출 위험과 후속 조치를 판단합니다.
2
PHP 코어 취약점
9.2
CVSS v4.0 점수(심각)
4
업스트림에서 수정된 8.2~8.5 브랜치
취약점 개요
PHP2Shell은 PHP 코어의 메모리 안전성 취약점 CVE-2026-109618과 CVE-2026-109619를 통칭하며, 두 취약점 모두 CVSS v4.0 9.2점입니다. 인증 없는 원격 코드 실행이 가능할 수 있으며 영향은 버전, 배포 환경, 공격 경로에 따라 달라집니다.
메모리 부족 처리 중 발생하는 메모리 손상으로 인증 없이 원격 코드를 실행할 수 있습니다. PHP를 업데이트하거나 공급업체 패치를 적용하세요.
자세히 보기유효하지 않은 요청 소유의 전역 상태가 같은 워커의 후속 요청에서 재사용되어 메모리 안전성 문제와 원격 코드 실행을 일으킬 수 있습니다.
자세히 보기실제 웹 실행 환경, 전체 패키지 버전, 공급업체 권고를 확인하고 업데이트 후 관련 워커를 재시작하세요. 임시 완화 조치는 패치를 대체하지 못합니다.
자세히 보기웹 요청을 처리하는 PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, LiteSpeed 등을 모두 점검해야 합니다. PHP는 mod_php를 가장 위험한 구성으로 보며, 애플리케이션 코드 실행 전 공격이 실증되었습니다. 단순한 페이지나 안전한 애플리케이션 코드도 노출을 배제하지 못합니다.
WordPress, Drupal, 프레임워크, 플러그인을 업데이트해도 기반 PHP가 함께 업데이트되는 것은 아닙니다. 각 사이트의 PHP 버전, FPM 풀, 컨테이너 이미지, 서비스 노드, 관리 패널이나 장비에 내장된 PHP를 각각 확인하세요. 공식 수정 버전은 2026년 10월 21일에 배포되었습니다.
검사 항목
공개 응답에서 PHP 특징을 확인합니다.
응답 헤더는 단서이며 수정의 증거가 아닙니다.
대조 요청과 비교해 상태 코드 차이를 해석합니다.
전체 패키지 버전과 공급업체 권고를 대조합니다.
모든 웹 워커가 업데이트되고 재시작되었는지 확인합니다.
기준 GET을 먼저 보낸 뒤 세 가지 메서드마다 URL 인코딩 폼과 multipart 폼을 전송합니다. 각 응답을 확인한 다음 요청을 보냅니다. 동작 비교를 위한 일반 요청이며 코드 실행이나 메모리 고갈 페이로드는 포함하지 않습니다.
| 순서 | 요청 메서드 | 전송 내용 | 관찰할 내용 |
|---|---|---|---|
| 01 | GET | 요청 본문 없음 | 접근 가능 여부, 리디렉션, 공개 PHP 버전 표시, 응답 헤더. |
| 02 | POST | application/x-www-form-urlencoded | POST 대조용 일반 텍스트 필드 1개. |
| 03 | POST | multipart/form-data | POST 대조 요청과 비교하는 텍스트 필드 1개. 파일 부분이나 업로드 진행 필드는 추가하지 않습니다. |
| 04 | PUT | application/x-www-form-urlencoded | 해당 경로의 PUT 처리를 확인하는 일반 텍스트 필드 1개. |
| 05 | PUT | multipart/form-data | 일반 PUT 폼과 비교해 콘텐츠 유형에 따른 응답 차이를 확인합니다. |
| 06 | PATCH | application/x-www-form-urlencoded | PATCH 대조용 일반 텍스트 필드 1개. |
| 07 | PATCH | multipart/form-data | PATCH 대조 요청과 비교하며 POST만으로 다른 메서드의 동작을 추정하지 않습니다. |
X-Powered-By나 Server의 PHP 표시와 PHPSESSID 같은 세션 쿠키는 실행 환경의 단서일 뿐입니다. 숨기거나 수정하거나 사용자 정의할 수 있습니다. 쿠키가 있어도 PHP가 요청 본문을 파싱했다는 증거는 아닙니다.
검사는 입력한 URL과 경로만 대상으로 합니다. 다른 경로, CDN 규칙, 직접 접근 가능한 원본 서버는 다르게 동작할 수 있습니다. 홈페이지 결과를 전체 사이트에 일반화하지 마세요. 권한이 있고 폼 요청에 적합한 경로에서만 검사하세요.
검사 결과 해석 방법
공개 응답은 일부 증거만 제공합니다. 버전이 숨겨지거나 변경될 수 있고 구버전에도 공급업체 백포트가 포함될 수 있습니다. 증거 부족을 안전으로 판단하지 말고 실제 실행 환경을 확인하세요.
흔한 판단 오류 알아보기공개 버전이 해당 브랜치의 수정 기준 이상이면 유용한 단서지만 프록시가 헤더를 바꿀 수 있습니다. 서버에서 모든 인스턴스가 수정 코드를 로드했는지 확인하세요.
업스트림 수정 기준보다 낮은 버전을 우선 점검하되 배포판이나 LTS 공급업체의 백포트도 확인하세요. 백포트 상태가 불명확하면 원격 코드 실행이 검증되었다고 하지 말고 확인 필요로 기록하세요.
일반 폼은 성공하고 multipart가 4xx라면 콘텐츠 유형 제한 때문일 수 있습니다. 둘 다 405이면 해당 경로에서 메서드를 지원하지 않을 수 있습니다. 상태 코드만으로 CDN, 웹 서버, 애플리케이션 중 어느 계층이 거부했는지 구분할 수 없습니다.
숨겨진 버전, 프록시 캐시, 사용자 정의 쿠키, 연결 실패, 시간 초과는 평가를 제한합니다. 부족한 증거를 녹색 안전 판정으로 대체하지 말고 정보 부족 또는 평가 불가로 기록하세요.
검사 절차
소유하거나 테스트 권한을 받은 사이트 주소와 확인할 경로를 입력합니다.
GET 기준 응답을 확인한 뒤 POST, PUT, PATCH의 일반 폼과 multipart 응답을 요청별로 비교합니다.
상태 코드와 버전 단서를 해석하고 실제 PHP 환경 및 공급업체 권고와 대조해 패치 상태를 확인합니다.
서버 측 점검
외부 검사는 단서 파악에 유용하지만 패치 상태는 호스트, 컨테이너, 호스팅 패널에서 확인해야 합니다. 실행 환경, 패키지 출처, 수정 버전, 업데이트 후 프로세스 상태를 순서대로 기록하세요.
사이트에 지정된 PHP, 웹 서버 모듈, FPM 풀을 확인하세요. 공존하는 버전, 여러 사이트, 컨테이너, 부하 분산 노드를 각각 조사해야 합니다. php -v는 현재 CLI 버전만 보여 주며 웹 실행 버전과 다를 수 있습니다. 확인을 위해 phpinfo 페이지를 공개하지 마세요.
php -v 실제 설치 패키지를 조회하고 전체 버전을 배포판 보안 권고와 비교하세요. Ubuntu 24.04의 8.3.6-0ubuntu0.24.04.13 패키지에는 이미 수정이 포함됩니다. PHP 8.3.6만 보면 백포트 정보가 누락됩니다. 아래에서 시스템에 맞는 예시를 선택하고 실제 패키지명으로 바꾸세요.
dpkg-query -W php8.3-fpm
rpm -q php-fpm Ubuntu 공식 수정 패키지 목록 보기 해당 브랜치의 업스트림 수정 버전, 이후 보안 버전 또는 확인된 공급업체 백포트를 사용하세요. 패널, 장비, 컨테이너에 포함된 PHP는 각 공급업체 방식으로 업데이트해야 합니다. PHP 8.1 이하는 정규 업스트림 지원이 종료되어 LTS 수정을 확인하거나 이전해야 합니다. 이번에는 7.4, 8.0, 8.1용 최소 소스 백포트도 제공되었습니다.
관련 PHP-FPM, Apache, 기타 워커가 재시작되고 컨테이너와 다중 노드가 교체되었는지 확인하세요. 디스크 파일 업데이트만으로 기존 프로세스 교체를 보장할 수 없습니다. 이상 요청, 메모리 부족, 워커 충돌 기록은 조사에 유용하지만 기록이 없다고 영향이 없었다고 판단할 수는 없습니다.
스크립트는 GET 1회에 이어 POST, PUT, PATCH의 URL 인코딩 및 multipart 폼 요청을 하나씩 보냅니다. 일반 텍스트 필드만 사용하며 파일이나 업로드 진행률 필드는 보내지 않습니다. 허가받은 테스트 폼 경로에서만 실행하세요. 일반 요청도 애플리케이션 동작을 유발할 수 있습니다.
#!/usr/bin/env bash
# PHP2Shell HTTP observations: 7 sequential requests, no exploit payload.
set -u
URL="${1:-https://example.com/}"
case "$URL" in
http://*|https://*) ;;
*) printf 'ERROR=HTTP(S)_URL_REQUIRED\n' >&2; exit 2 ;;
esac
if ! command -v curl >/dev/null 2>&1 || ! command -v awk >/dev/null 2>&1; then
printf 'ERROR=CURL_AND_AWK_REQUIRED\n' >&2
exit 127
fi
probe() {
printf '\n[%s/7] %s %s\n' "$1" "$2" "$3"
local method="$2"
shift 3
curl -q --globoff --proto '=http,https' --silent --show-error \
--connect-timeout 5 --max-time 15 --request "$method" \
--dump-header - --output /dev/null \
--write-out '\nHTTP_CODE=%{http_code} TOTAL_SECONDS=%{time_total}\n' \
"$@" --url "$URL" |
awk '{
sub(/\r$/, "")
line = tolower($0)
if ($0 ~ /^HTTP\// || line ~ /^(server|x-powered-by|content-type):/ || $0 ~ /^HTTP_CODE=/) {
print
} else if (line ~ /^set-cookie:[ \t]*phpsessid[ \t]*=/) {
print "PHPSESSID=present; value hidden"
}
}'
local curl_status="${PIPESTATUS[0]}"
if [ "$curl_status" -ne 0 ]; then
printf 'CURL_EXIT=%s\n' "$curl_status"
FAILED=1
fi
}
FAILED=0
probe 1 GET baseline
probe 2 POST urlencoded --data-raw 'php2shell_check=1'
probe 3 POST multipart --form-string 'php2shell_check=1'
probe 4 PUT urlencoded --data-raw 'php2shell_check=1'
probe 5 PUT multipart --form-string 'php2shell_check=1'
probe 6 PATCH urlencoded --data-raw 'php2shell_check=1'
probe 7 PATCH multipart --form-string 'php2shell_check=1'
exit "$FAILED" Linux/macOS의 Bash 또는 Windows의 WSL이나 Git Bash를 사용하세요. php2shell-self-check.sh로 저장한 뒤 아래 명령의 URL을 허가받은 테스트 페이지로 바꿔 실행하세요. Bash 스크립트 전체를 PowerShell에 직접 붙여 넣지 마세요.
bash php2shell-self-check.sh https://example.com/test.php 연결 제한은 5초, 요청별 전체 제한은 15초입니다. 개인 curl 설정을 무시하고 TLS를 검증하며 리디렉션이나 재시도를 하지 않습니다. 3xx를 받으면 최종 URL도 허가 범위인지 확인한 뒤 해당 주소에서 다시 실행하세요. PHPSESSID는 존재 여부만 표시하며 쿠키 값과 응답 본문은 출력하지 않습니다.
HTTP_CODE는 응답 상태, TOTAL_SECONDS는 전체 소요 시간입니다. CURL_EXIT가 0이 아니면 해당 전송에 실패했지만 나머지 검사는 계속됩니다. 스크립트의 0이 아닌 종료 코드는 입력, 의존 명령 또는 전송 문제를 의미합니다. HTTP 4xx/5xx는 정상적으로 기록되며 종료 코드로 취약점이나 패치 상태를 판단할 수 없습니다.
Server나 X-Powered-By는 숨겨지거나 오래된 정보일 수 있습니다. 웹사이트에서 실제 실행되는 PHP를 확인하세요. 각 브랜치의 최초 공식 수정 버전은 8.2.35, 8.3.36, 8.4.27, 8.5.12입니다. 공급업체의 백포트는 전체 패키지 버전과 보안 공지로 확인해야 합니다.
같은 메서드에서 urlencoded는 2xx 또는 3xx, multipart는 403 또는 406을 반환해도 응답 차이만 확인됩니다. WAF 차단이나 PHP 도달 전 거부를 입증하지는 않습니다.
multipart의 2xx 또는 3xx는 성공이나 리디렉션 응답을 받았다는 의미일 뿐입니다. 본문이 PHP에 도달해 파싱되었음을 입증하지 않으며 취약점 존재 여부도 판단할 수 없습니다.
모두 405를 반환해도 수정이 입증되지 않습니다. PHP 표시가 없어도 PHP 미사용을 뜻하지 않습니다. PHPSESSID 쿠키가 있어도 multipart 파싱 여부나 어느 계층에서 응답했는지 확정할 수 없습니다.
PHP는 완전한 수정에 업데이트가 필요하다고 명시합니다. 아래 설정은 일부 알려진 경로의 노출만 줄이며 미패치 환경을 안전하게 만들지 않습니다. 변경 전에 애플리케이션 요구 사항과 공식 지침을 검토하세요.
공식 수정 버전
브랜치별로 버전을 비교하세요. 8.3 수정 기준으로 8.4 상태를 판단할 수 없습니다. 사전 릴리스나 알 수 없는 브랜치를 수정된 것으로 간주하지 마세요. 백포트와 자체 빌드는 전체 패키지 버전, 빌드 기록, 공급업체 권고로 확인해야 합니다.
BaoTa의 2026-10-21 공지에 따르면 일부 PHP 보안 수정 버전이 패널에 제공됩니다. 실제 업데이트 가능한 버전은 사용 중인 패널의 소프트웨어 스토어에서 확인하세요.
BaoTa 업데이트 공지 보기업데이트 전에 웹사이트, 데이터베이스, 관련 설정을 백업하고 적절한 유지보수 시간을 선택하세요.
BaoTa 패널에 로그인한 뒤 소프트웨어 스토어 → 설치됨에서 현재 웹사이트가 사용하는 PHP 버전을 찾아 관리 페이지를 여세요.
해당 PHP 관리 페이지에서 업데이트를 확인하고 안내에 따라 위에 표시된 동일 브랜치의 수정 버전 또는 해당 브랜치의 후속 보안 버전을 설치하세요.
업데이트 후 해당 PHP 서비스를 재시작하고 모든 워커가 다시 로드되었는지 확인하세요. 웹사이트에서 실제 사용하는 PHP 버전을 확인한 뒤 페이지 접속, 파일 업로드, 데이터베이스 연결 등 주요 기능을 테스트하세요.
여러 PHP 버전이 설치되어 있다면 사용 중인 버전을 각각 점검하세요. 다른 버전을 새로 설치했다면 웹사이트가 수정된 PHP 실행 환경으로 전환되었는지도 확인하세요.
자주 묻는 질문
버전 단서, 상태 코드, 공급업체 백포트의 차이를 이해해 결과를 과도하게 해석하지 마세요.
PHP2Shell은 PHP 코어 취약점 CVE-2026-109618과 CVE-2026-109619를 말하며 인증 없는 원격 코드 실행을 허용할 수 있습니다. 애플리케이션 코드가 안전해도 웹 요청을 처리하는 미수정 PHP 환경은 모두 점검해야 합니다.
아닙니다. 인증 요구, 지원하지 않는 메서드, 크기 제한, 프록시도 이런 코드를 반환할 수 있습니다. multipart 거부는 현재 경로의 동작만 보여 주며 PHP 수정이나 모든 공격 경로 차단을 증명하지 않습니다.
그렇게 판단할 수 없습니다. 버전 공개가 비활성화되어 있거나 CDN, 역방향 프록시, 정적 홈페이지가 백엔드를 가릴 수 있습니다. 특징이 없으면 정보 부족으로 보고 실제 서버 실행 환경을 확인하세요.
업스트림 수정 버전은 PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12입니다. 해당 브랜치의 수정 버전이나 이후 보안 버전을 사용하세요. 구버전에도 백포트가 있을 수 있으므로 전체 패키지 버전과 공급업체 권고를 대조해야 합니다. PHP 8.1 이하는 정규 업스트림 지원이 종료되었습니다. 업데이트 후 관련 워커를 재시작하세요.
메서드마다 경로와 필터 규칙이 다를 수 있습니다. PHP 8.4부터 request_parse_body()로 POST 이외의 multipart를 파싱할 수 있지만 모든 애플리케이션이 PUT이나 PATCH를 자동 파싱하는 것은 아닙니다. POST 동작만으로 다른 메서드나 경로의 보호를 판단할 수 없습니다.
PHP 실행 환경과 패치 상태를 미확인으로 기록하세요. POST 200은 응답했다는 뜻이며 405는 어느 계층에서 메서드를 거부했다는 의미입니다. 정적 페이지, 다른 실행 환경, 특징을 숨긴 PHP 모두 같은 패턴을 보일 수 있습니다. 안전이나 취약점 확인으로 단정하지 말고 서버에서 실행 환경을 검증하세요.
취약점 및 수정 자료 확인일은 2026-10-22입니다. 외부 관찰에는 한계가 있으므로 실제 대응은 최신 PHP 및 공급업체 권고를 따르세요.
공개 응답을 하나씩 확인하고 증거를 해석한 뒤 실제 서버 환경에서 패치와 수정을 검증하세요.