핵심만 먼저
| 취약점 | CVE-2026-109618 / CVE-2026-109619 |
| 별칭 | PHP2Shell |
| 위험도 | CVSS 9.2 / Critical |
| 공격 | 인증 없이 원격 코드 실행(RCE) 가능 |
| 영향 | PHP-FPM, Apache mod_php, php-cgi 등 |
| 수정 버전 | PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 |
| 공개일 | 2026-10-21 |
| 현재 상황 | PoC 공개 및 실제 공격 시도 보고 |
PHP 공식 공지에서도 웹 요청을 처리하는 모든 PHP 설치를 즉시 업데이트하라고 권고하고 있습니다. 특히 mod_php 환경은 위험도가 높다고 명시했습니다. PHP
1. CVE-2026-109618 — OOM 취약점
이게 상당히 무서운 부분입니다.
PHP에는 memory_limit라는 설정이 있죠.
예를 들어:
memory_limit = 128M
공격자가 PHP에 매우 큰 요청이나 파일 업로드 등을 보내서 메모리 부족(OOM) 상황을 의도적으로 만들 수 있습니다.
문제는 PHP가 OOM을 처리하는 과정에서 내부 메모리 상태가 제대로 초기화되지 않은 상태로 넘어갈 수 있다는 것입니다.
쉽게 표현하면:
공격자의 HTTP 요청
↓
PHP 메모리 부족 유도
↓
OOM 처리
↓
PHP 내부 메모리 상태가 비정상
↓
공격자가 제어할 수 있는 데이터와 연결
↓
원격 코드 실행(RCE)
즉, 단순히 PHP 프로세스를 죽이는 DoS 취약점이 아니라 서버에서 공격자의 코드가 실행될 수 있는 취약점입니다. CVSS도 9.2입니다. CERT-EU
2. CVE-2026-109619 — Stale Global State
두 번째 취약점은 조금 더 어렵습니다.
PHP worker가 요청을 처리하다가 치명적인 오류가 발생하면 내부 메모리가 해제될 수 있습니다.
그런데 해제된 메모리를 가리키는 내부 상태가 남아 있을 가능성이 생깁니다.
Request 1
↓
PHP 내부 메모리 사용
↓
Fatal error
↓
메모리 해제
↓
그런데 포인터/상태가 남음
↓
Request 2
↓
이전 요청의 잘못된 상태 사용
↓
RCE 가능
특히 PHP-FPM처럼 worker가 여러 HTTP 요청을 계속 처리하는 구조에서는 중요합니다.
CERT-EU도 이 취약점에 대해 인증되지 않은 원격 코드 실행이 가능하다고 설명하고 있습니다. CERT-EU
그런데 왜 이번 취약점이 특히 위험한가?
가장 중요한 부분입니다.
애플리케이션 자체의 취약점이 아닐 수 있습니다.
예를 들어 WordPress나 자체 PHP 프로그램에 SQL Injection이 없어도,
Internet
↓
Nginx / Apache
↓
PHP-FPM
↓
PHP Engine
여기서 PHP Engine 자체가 취약하면 공격 대상이 될 수 있습니다.
PHP 공식 발표에서도 공격자가 애플리케이션 코드가 실행되기 전 단계에서 취약점을 트리거할 수 있는 사례를 설명하고 있습니다. PHP
그래서 이번 건은 일반적인
"우리 홈페이지에 취약점이 있나?"
보다
"우리 서버에 취약한 PHP가 설치되어 있나?"
를 먼저 확인해야 합니다.
어떤 PHP가 취약한가?
현재 확인되는 주요 기준은 다음과 같습니다.
PHP 8.5.0 ~ 8.5.11 → 취약
PHP 8.4.0 ~ 8.4.26 → 취약
PHP 8.3.0 ~ 8.3.35 → 취약
PHP 8.2.0 ~ 8.2.34 → 취약
수정 버전은:
PHP 8.5.12
PHP 8.4.27
PHP 8.3.36
PHP 8.2.35
입니다. CERT-EU
그리고 PHP 8.1 이하의 EOL 버전은 공식 PHP 프로젝트에서 더 이상 일반적인 보안 업데이트를 받지 않으므로 더욱 주의해야 합니다. CERT-EU
⚠️ 그리고 10월 23일에 또 하나 나왔습니다
여기서 중요한 게 하나 더 있습니다.
CVE-2026-115560이라는 추가 PHP RCE 취약점이 10월 23일 공개됐습니다.
다만 이건 앞의 PHP2Shell과 성격이 조금 다릅니다.
특정하게 다음과 같은 조합이 있어야 합니다.
session.serialize_handler = php_binary
또는
session.serialize_handler = php_serialize
상태에서 애플리케이션이 실행 중에 php로 변경하고,
session.upload_progress.enabled = 1
등 특정 조건이 맞아야 합니다.
그래서 PHP 측에서는 일반적인 환경에서는 발생 가능성이 낮은 구성으로 보고 있습니다. 아직 앞의 PHP2Shell처럼 긴급 패치를 내놓은 상황은 아닙니다. SOC Prime
🔥 지금 서버에서 가장 먼저 확인할 것
서버를 직접 관리하신다면 PHP 버전 확인부터 하면 됩니다.
php -v
또는 PHP-FPM이라면:
php-fpm -v
그리고 실제 웹에서 사용하는 PHP가 CLI와 다를 수 있기 때문에 이것도 중요합니다.
ps -ef | grep php
예를 들어:
php-fpm: master process
php-fpm: pool www
가 나오면 PHP-FPM 환경입니다.
만약 PHP-FPM이라면
현재 버전이 예를 들어
PHP 8.3.35
라면 취약합니다.
최소한
8.3.36
이상으로 올려야 합니다.
패치가 당장 어려우면
임시 완화책으로 PHP 측에서는
session.upload_progress.enabled=0
을 권고하고 있습니다.
그리고 설정 변경 후 모든 PHP worker를 재시작해야 합니다.
하지만 이것은 완전한 해결책이 아닙니다.
가장 좋은 방법은 결국 PHP 자체를 수정 버전으로 올리는 것입니다. CERT-EU
특정 서버 환경이라면
JEUS / WebtoB / Apache / Tomcat 환경과 별개로, 서버에 PHP가 별도로 설치되어 있거나 Web 서버에서 PHP를 처리하고 있다면 확인해야 합니다.
예를 들어 구조가
WebtoB
↓
JEUS
만 사용하고 PHP가 전혀 없다면 이번 PHP2Shell의 직접적인 대상은 아닙니다.
반대로
Apache/Nginx
↓
PHP-FPM
↓
PHP
구조가 하나라도 있다면 확인해야 합니다.
PHP 보안취약점 점검하기
Linux 서버에서 PHP2Shell(CVE-2026-109618 / CVE-2026-109619) 노출 여부를 점검하는 명령어를 실무용으로 정리해드릴게요.
현재 PHP 공식 권고상 PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 이상으로 업데이트하는 것이 유일한 완전한 해결책입니다. PHP-FPM, mod_php, php-cgi, LiteSpeed 등 웹 요청을 처리하는 PHP가 대상입니다. PHP
1. 가장 먼저 PHP 버전 확인
php -v
예:
PHP 8.3.35 (cli) ...
라면 PHP2Shell 취약 버전입니다.
기준은:
PHP 8.5.x → 8.5.12 이상
PHP 8.4.x → 8.4.27 이상
PHP 8.3.x → 8.3.36 이상
PHP 8.2.x → 8.2.35 이상
입니다. PHP
단, php -v 결과만으로 서버가 취약하다고 단정하면 안 됩니다. CLI PHP와 실제 웹에서 사용하는 PHP가 다를 수 있기 때문입니다.
2. PHP-FPM 사용 여부 확인
ps -ef | grep '[p]hp-fpm'
또는:
pgrep -a php-fpm
예:
root 1234 ... php-fpm: master process
www 1235 ... php-fpm: pool www
www 1236 ... php-fpm: pool www
이렇게 나오면 PHP-FPM을 사용하는 서버입니다.
PHP2Shell은 PHP-FPM도 영향을 받습니다. CERT-EU
3. 실제 PHP-FPM 버전 확인
환경에 따라 다음 중 하나를 사용하세요.
php-fpm -v
또는:
php-fpm8.3 -v
또는:
php-fpm8.2 -v
경로를 모르면:
which php-fpm
find /usr /opt -type f -name 'php-fpm*' 2>/dev/null
중요: php -v가 8.3.36이어도 실제 FPM이 8.3.35라면 웹 서비스는 여전히 취약할 수 있습니다.
4. RPM 계열 서버라면
사용하시는 환경에 RHEL 계열 서버도 있으니 이 부분이 특히 중요합니다.
설치된 PHP 패키지 확인
rpm -qa | grep '^php'
또는:
rpm -qa | grep -i php
예:
php-8.3.35-1.el8.x86_64
php-fpm-8.3.35-1.el8.x86_64
php-cli-8.3.35-1.el8.x86_64
이렇게 나오면 버전을 확인해야 합니다.
5. RHEL / Rocky / AlmaLinux에서 업데이트 가능 버전 확인
dnf list --showduplicates php-fpm
또는:
dnf --showduplicates list php-fpm
현재 설치 버전:
rpm -q php-fpm
설치 가능한 업데이트:
dnf check-update php-fpm
PHP 패키지가 여러 개라면:
dnf check-update 'php*'
Linux 배포판 및 LTS 공급업체가 패치를 백포트했을 수도 있기 때문에 단순히 upstream PHP 버전만 보고 판단하지 말고 배포판 패키지의 보안 업데이트도 확인해야 합니다. PHP
6. php.ini 위치 확인
php --ini
예:
Configuration File (php.ini) Path: /etc
Loaded Configuration File: /etc/php.ini
Scan for additional .ini files in: /etc/php.d
여기서 실제 설정 파일을 확인합니다.
php -i | grep 'Loaded Configuration File'
7. PHP2Shell 관련 설정 확인
memory_limit
php -i | grep '^memory_limit'
또는:
grep -Rni '^[[:space:]]*memory_limit' /etc/php.ini /etc/php.d/ 2>/dev/null
post_max_size
php -i | grep '^post_max_size'
upload_max_filesize
php -i | grep '^upload_max_filesize'
session.upload_progress
php -i | grep '^session.upload_progress.enabled'
또는:
grep -Rni 'session.upload_progress.enabled' /etc/php.ini /etc/php.d/ 2>/dev/null
fatal_error_backtraces
PHP 8.5 계열이라면:
php -i | grep '^fatal_error_backtraces'
PHP 공식/CERT-EU 권고상 session.upload_progress.enabled=0 등은 임시 완화책일 뿐이며, PHP 업데이트가 완전한 해결책입니다. CERT-EU
8. PHP-FPM 설정까지 확인
PHP-FPM 설정 파일 위치를 찾습니다.
php-fpm -i | grep -E 'Loaded Configuration|Scan this dir'
또는:
find /etc /opt -type f \( -name 'www.conf' -o -name 'php-fpm.conf' \) 2>/dev/null
그리고:
grep -RniE 'pm.max_requests|session.upload_progress.enabled|fatal_error_backtraces' \
/etc/php-fpm* /etc/php/* 2>/dev/null
특히 PHP2Shell의 두 번째 취약점과 관련해서 pm.max_requests와 worker 재시작 정책도 점검할 가치가 있습니다. Qualys도 이 설정을 점검 항목으로 제시하고 있습니다. Qualys
9. 실제 웹 서버가 PHP를 사용하는지 확인
이게 굉장히 중요합니다.
Apache라면:
httpd -M 2>/dev/null | grep -i php
또는:
apachectl -M 2>/dev/null | grep -i php
결과가:
php_module
이라면 mod_php입니다.
CERT-EU는 특히 Apache mod_php를 고위험 구성으로 평가하고 있습니다. CERT-EU
Nginx라면
nginx -T 2>/dev/null | grep -iE 'php|fastcgi_pass'
예:
fastcgi_pass unix:/run/php-fpm/www.sock;
이런 게 나오면:
Nginx
↓
PHP-FPM
구조입니다.
10. 한 번에 점검하는 명령어
운영 서버에서 아래 정도를 실행하면 됩니다.
echo "===== OS ====="
cat /etc/os-release 2>/dev/null | grep -E '^(NAME|VERSION)='
echo
echo "===== PHP CLI ====="
php -v 2>/dev/null | head -1
echo
echo "===== PHP-FPM ====="
php-fpm -v 2>/dev/null | head -1
echo
echo "===== PHP-FPM PROCESS ====="
pgrep -a php-fpm || echo "php-fpm process not found"
echo
echo "===== PHP CONFIG ====="
php --ini 2>/dev/null
echo
echo "===== PHP SECURITY SETTINGS ====="
php -i 2>/dev/null | grep -E \
'^(memory_limit|post_max_size|upload_max_filesize|session.upload_progress.enabled|fatal_error_backtraces)'
echo
echo "===== PHP PACKAGES ====="
rpm -qa 2>/dev/null | grep -i '^php' || true
echo
echo "===== APACHE PHP ====="
httpd -M 2>/dev/null | grep -i php || true
echo
echo "===== NGINX PHP ====="
nginx -T 2>/dev/null | grep -iE 'php|fastcgi_pass' | head -20 || true
이 결과를 그대로 저에게 붙여주시면, 제가
[안전]
[취약]
[패치 필요]
[PHP는 설치되어 있지만 웹에서 사용하지 않음]
[CLI와 FPM 버전 불일치]
로 나눠서 판정해드릴 수 있습니다.
만약 RHEL 8.x + PHP-FPM + Nginx/Apache 구조라면, php -v 하나만 보지 말고 rpm -qa | grep php + php-fpm -v + 실제 FPM 프로세스까지 확인하는 게 좋습니다.