본문 바로가기
OpenSource

[보안취약점] PHP 취약점에 대해 알아보자(PHP2Shell)

by wonkidoki 2026. 10. 29.
반응형

핵심만 먼저

항목내용
취약점 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 프로세스까지 확인하는 게 좋습니다.