메뉴 닫기

PHP2Shell 취약점 대응: Rocky Linux 8 PHP 8.3 설치 및 업데이트

PHP2Shell 취약점 대응: Rocky Linux 8.10 PHP 8.3 설치 및 보안 업데이트

본 글은 테스트 서버를 기준으로 작성한 참고 자료이며, 모든 운영 환경에서 동일한 결과를 보장하지 않습니다. 적용 전 백업과 사전 테스트를 진행하고, 실제 적용 여부는 서비스 환경과 영향도를 검토한 후 결정하시기 바랍니다.

안내 범위는 PHP 패키지 설치 및 업데이트까지입니다. 버전 변경에 따른 함수·확장 모듈·소스코드 호환성 문제는 서비스 운영자 또는 개발 담당자가 별도로 확인하고 수정해야 합니다.

 

PHP2Shell 취약점에 대응하려면 서버에서 사용하는 PHP 버전과 보안 패치 적용 여부를 확인해야 합니다.

이번 글에서는 Rocky Linux 8.10 테스트 서버에 설치된 PHP 8.1을 제거하고, Remi 저장소를 이용하여 PHP 8.3 패키지를 설치하는 방법을 정리합니다. 이미 PHP 8.3을 사용하는 서버의 업데이트 방법과 백포트 패치 확인 시 주의할 점도 함께 알아봅니다.

작업 범위 및 주의사항

본 글은 PHP 패키지 버전 변경과 보안 업데이트 절차를 다룹니다. PHP 버전 변경에 따른 함수의 변경·제거, 확장 모듈 및 기존 소스코드의 호환성 문제에 대한 수정 작업은 포함하지 않습니다.

기존 애플리케이션에서 발생하는 오류는 서비스 운영자 또는 개발 담당자가 별도로 확인하고 수정해야 합니다. 운영 서버에 적용하기 전 테스트 환경에서 소스코드 호환성과 주요 기능의 정상 동작을 검증하시기 바랍니다.

Remi는 외부 패키지 저장소입니다. 적용 전 조직의 외부 저장소 사용 및 기술지원 정책을 확인해야 합니다.

1. PHP2Shell 취약점 개요

PHP2Shell은 다음 두 PHP 취약점을 가리킵니다.

취약점 주요 내용
CVE-2026-109618 메모리 부족 처리 과정에서 내부 상태가 손상될 수 있는 문제
CVE-2026-109619 해제된 메모리와 관련된 내부 상태가 이후 요청에서 사용될 수 있는 문제

조건에 따라 인증되지 않은 공격자의 원격 코드 실행으로 이어질 수 있으며, PHP-FPM 등 웹 요청을 처리하는 PHP 환경을 점검해야 합니다.

PHP 공식 공지에서 안내한 수정 버전은 다음과 같습니다.

PHP 계열 수정 버전
PHP 8.2 8.2.35
PHP 8.3 8.3.36
PHP 8.4 8.4.27
PHP 8.5 8.5.12

본 글에서는 PHP 8.3 계열의 수정 버전인 8.3.36 또는 이후 보안 수정이 포함된 패키지를 설치 대상으로 합니다.

추가 보안 안내 — 2026년 10월 23일

PHP 공식 사이트는 특정 세션 설정 및 애플리케이션 동작이 결합된 환경에서 발생할 수 있는 추가 문제(CVE-2026-115560)를 안내했습니다.

설정에서 session.serialize_handler를 php_binary 또는 php_serialize로 지정한 뒤, 애플리케이션이 실행 중 이를 php로 변경하고 session_start()를 호출하며, 세션 업로드 진행 기능도 활성화된 경우가 해당됩니다.

PHP 공식 안내는 다음 정기 버그 수정 릴리스까지 session.upload_progress.enabled=0으로 설정할 것을 권고합니다. 해당 기능을 사용하는 서비스는 영향도를 확인하고, 실제 웹 요청에 적용되는 PHP 설정에 반영한 뒤 PHP 워커를 재시작합니다.

기존 두 취약점의 수정 버전 설치와 함께 최신 추가 보안 공지도 확인하시기 바랍니다.

2. 테스트 서버 환경

작업 전 확인한 테스트 서버 환경입니다.

항목 확인 내용
운영체제 Rocky Linux 8.10
기존 PHP PHP 8.1.34 CLI
OPcache Zend OPcache 8.1.34
웹 서버 Apache httpd 프로세스 실행
웹 서비스 포트 TCP 80, 443
DB 프로세스 mysqld, TCP 3306
설치 대상 Remi 저장소의 PHP 8.3 패키지

명령어

cat /etc/os-release
php -v

확인 결과

PRETTY_NAME="Rocky Linux 8.10 (Green Obsidian)"

PHP 8.1.34 (cli)
Zend Engine v4.1.34
with Zend OPcache v8.1.34

CLI에서 확인한 PHP 버전과 실제 웹 서비스가 사용하는 PHP는 다를 수 있으므로, 설치 경로와 웹 서버 연동 방식도 확인합니다.

3. PHP 설치 방식 및 실행 환경 확인

명령어

command -v php
readlink -f "$(command -v php)"
rpm -qf "$(readlink -f "$(command -v php)")"

rpm -qa 'php*' | sort
dnf list installed 'php*'
dnf module list php --enabled
dnf repolist --enabled

php --ini
php -m

확인 사항

  • PHP 실행 파일이 RPM 패키지에 포함되어 있는지
  • 기존 패키지의 설치 저장소가 어디인지
  • 활성화된 PHP 모듈 스트림이 무엇인지
  • 현재 사용하는 확장 모듈이 무엇인지

PHP-FPM과 Apache 연동 상태도 확인합니다.

systemctl status php-fpm --no-pager -l

httpd -M | grep -Ei 'php|proxy_fcgi'
ps -ef | grep '[p]hp-fpm'

ss -lxnp | grep -i php

PHP-FPM이 Unix 소켓으로 통신하는 경우 TCP 포트 목록에는 나타나지 않습니다.

아래 설치 과정은 php, php-cli, php-fpm 등 일반적인 RPM 패키지 구성을 대상으로 합니다. 소스 컴파일 설치 또는 php81-php-* 형태의 병렬 설치 환경이라면 해당 설치 방식에 맞게 절차를 변경해야 합니다.

4. 기존 설정 및 패키지 목록 백업

root 계정으로 작업하며, 복원이 필요한 서버는 사전에 스냅샷이나 전체 백업을 준비합니다.

명령어

BACKUP_DIR="/root/php-backup-$(date +%Y%m%d-%H%M%S)"
mkdir -m 700 "$BACKUP_DIR"

php -v > "$BACKUP_DIR/php-version.txt"
php -m > "$BACKUP_DIR/php-modules.txt"
php --ini > "$BACKUP_DIR/php-ini-paths.txt"

rpm -qa 'php*' | sort > "$BACKUP_DIR/php-packages.txt"
dnf module list php --enabled > "$BACKUP_DIR/php-module.txt"

for item in /etc/php.ini /etc/php.d /etc/php-fpm.conf /etc/php-fpm.d /etc/httpd; do
    if [ -e "$item" ]; then
        cp -a "$item" "$BACKUP_DIR/"
    fi
done

웹 소스와 데이터베이스는 별도로 백업합니다. 기존 PHP 설정은 새 버전의 기본 설정과 비교하여 필요한 항목만 반영합니다.

5. Rocky Linux 8용 Remi 저장소 준비

PHP를 제거하기 전에 설치할 패키지와 저장소를 먼저 준비합니다.

명령어

dnf install dnf-plugins-core epel-release
dnf config-manager --set-enabled powertools

dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm

dnf makecache --refresh
dnf module list php

이미 설치된 저장소 패키지는 중복 설치되지 않습니다.

6. Remi 저장소 메타데이터 오류 해결

이번 테스트에서는 다음 명령어 실행 중 remi-modular 저장소의 메타데이터 다운로드가 실패했습니다.

실행 명령어

dnf makecache --refresh

실제 오류 — 일부 발췌

Errors during downloading metadata for repository 'remi-modular':
  - Status code: 404

최종적으로 다음 메시지가 출력되었습니다.

오류: repo를 위한 메타자료 내려받기에 실패하였습니다 'remi-modular'

여러 미러에서 메타데이터 파일을 찾지 못했고, 일부 서버에서는 연결 시간 초과도 발생했습니다.

이 단계는 저장소의 패키지 목록을 조회하는 과정입니다. 해당 명령 자체는 기존 PHP를 삭제하거나 변경하지 않습니다.

6-1. 메타데이터 캐시 정리

기존 캐시와 저장소 정보의 불일치 또는 미러 동기화 문제 가능성을 고려하여 캐시를 정리했습니다.

명령어

dnf --disablerepo='*' --enablerepo=remi-modular clean metadata

실제 결과

캐쉬가 만료되었습니다
62 파일이 삭제되었습니다

6-2. Remi 저장소 메타데이터 재생성

명령어

dnf --disablerepo='*' --enablerepo=remi-modular \
    --refresh makecache

실제 결과 — 주요 내용

Remi's Modular repository for Enterprise Linux 8 - x86_64
메타 자료 캐쉬가 생성되었습니다.

이번 테스트에서는 캐시 삭제 후 일반 미러를 통한 메타데이터 조회가 정상화되었습니다.

다만 이 결과만으로 최초 원인이 로컬 캐시 문제였는지, 미러 동기화 문제였는지까지 확정할 수는 없습니다.

6-3. 오류가 계속될 때 공식 서버 직접 지정

앞 단계에서 성공했다면 이 과정은 생략합니다.

동일한 오류가 지속되면 공식 서버를 직접 지정하여 재시도할 수 있습니다.

dnf --disablerepo='*' --enablerepo=remi-modular \
    --setopt=remi-modular.mirrorlist= \
    --setopt=remi-modular.metalink= \
    --setopt=remi-modular.baseurl=https://rpms.remirepo.net/enterprise/8/modular/x86_64/ \
    --refresh makecache

이번 테스트에서는 공식 서버를 직접 지정한 조회도 성공했습니다.

메타 자료 캐쉬가 생성되었습니다.

위 설정은 해당 명령 실행에만 적용됩니다. 저장소 설정 파일이나 이후 설치 명령의 접속 대상을 영구적으로 변경하지 않습니다.

캐시 생성 성공은 저장소 조회가 정상화됐다는 의미입니다. PHP 설치나 보안 패치 적용 완료를 의미하지는 않습니다.

저장소 조회가 정상화되면 PHP 모듈 목록을 다시 확인합니다.

dnf module list php

목록에 remi-8.3 스트림이 표시되는 것을 확인한 후 다음 단계로 진행합니다.

7. 기존 PHP 8.1 패키지 제거

이후 과정은 저장소가 정상적으로 조회되고 remi-8.3 스트림이 확인된 상태에서 진행합니다.

이번 실습에서는 테스트 환경을 재구성하기 위해 기존 PHP를 제거한 후 PHP 8.3을 설치합니다. PHP 업그레이드 시 항상 제거가 필요한 것은 아닙니다.

먼저 제거 예정 목록을 확인합니다.

명령어

dnf remove --assumeno 'php' 'php-*'

PHP 이외에 함께 제거되는 애플리케이션이 있는지 확인합니다.

실행 중인 PHP-FPM이 있다면 중지합니다.

systemctl stop php-fpm

PHP-FPM 서비스가 없는 환경에서는 위 명령을 생략합니다.

제거 목록에 문제가 없으면 실제 삭제를 진행합니다.

dnf remove 'php' 'php-*'

PHP 제거부터 재설치 및 연동 확인까지 웹 서비스가 정상적으로 동작하지 않을 수 있습니다. 운영 서버에서는 점검 시간을 확보한 후 진행합니다.

8. PHP 8.3 패키지 설치

기존 PHP 모듈 선택을 초기화하고 Remi의 PHP 8.3을 설치합니다.

명령어

dnf module reset php
dnf module install php:remi-8.3/common

웹 서비스에서 필요한 확장 모듈도 설치합니다.

dnf install php-mysqlnd php-mbstring php-xml php-gd php-opcache

위 확장 모듈은 예시입니다. 실제 설치 목록은 백업한 기존 모듈 목록과 애플리케이션 요구 사항을 기준으로 결정합니다.

설치 결과 확인 명령어

php -v
php -m

rpm -q php-common php-cli php-fpm
dnf module list php --enabled

확인 기준

  • PHP 8.3 계열이 설치되었는지
  • PHP2Shell 수정 버전인 8.3.36 또는 이후 수정 패키지인지
  • 필요한 확장 모듈이 설치되어 있는지
  • remi-8.3 스트림이 활성화되어 있는지

최신 저장소에서 새로 설치하면 이미 보안 패치가 포함된 패키지가 설치될 수 있습니다. 이 경우 별도의 업데이트가 없어도 정상입니다.

9. 백포트 패치와 보안 업데이트의 차이

백포트는 새로운 버전의 수정 사항을 이전 버전에 적용하는 방식입니다.

작업 의미
PHP 8.1 → PHP 8.3 버전 계열 변경
이전 PHP 8.3 릴리스 → PHP 8.3.36 같은 계열 내 보안 업데이트
기존 버전에 보안 수정 사항을 반영한 배포판 패키지 설치 백포트된 보안 수정 적용

이번 실습은 PHP 8.3 보안 릴리스 패키지를 설치하거나 업데이트하는 과정입니다. 관리자가 소스코드를 수정하여 직접 백포트하는 작업은 아닙니다.

배포판이 백포트 패키지를 제공하는 경우에는 기본 버전 숫자가 유지되면서 RPM의 Release가 달라질 수 있습니다. 따라서 php -v 결과만으로 취약 여부를 판단하지 않습니다.

RPM 전체 버전 확인

rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' \
    php-common php-cli php-fpm

패키지 변경 이력 확인

rpm -q --changelog php-common |
grep -B 4 -A 4 -E 'CVE-2026-109618|CVE-2026-109619'

변경 이력에 해당 CVE가 나오면 패치 확인 자료로 활용합니다. 검색 결과가 없으면 패키지 제공자의 보안 공지와 해당 빌드의 수정 내역을 추가로 확인합니다.

Remi 패키지는 Remi의 공지와, Rocky Linux 기본 패키지는 Rocky Linux 보안 공지와 비교해야 합니다.

 

10. 설정 검사 및 서비스 재시작

패키지 설치 후 기존 설정과 신규 설정을 비교하고 문법을 검사합니다.

명령어

php-fpm -t
httpd -t

오류가 발생하면 설정을 수정한 후 다시 검사합니다.

Apache에서 ServerName 관련 경고가 나오더라도 최종 결과가 Syntax OK이면 문법 검사는 통과한 것입니다. 다른 오류가 함께 있는지도 확인합니다.

검사에 성공하면 PHP-FPM과 Apache를 재시작합니다.

systemctl enable php-fpm
systemctl restart php-fpm
systemctl restart httpd

상태 확인

systemctl status php-fpm --no-pager -l
systemctl status httpd --no-pager -l

Apache와 PHP-FPM의 연결 설정도 확인합니다.

grep -RnsE '^[[:space:]]*listen[[:space:]]*=' /etc/php-fpm.d/

grep -RnsE 'SetHandler|ProxyPassMatch|proxy:unix:|fcgi://' \
    /etc/httpd/conf /etc/httpd/conf.d

Apache가 참조하는 소켓 또는 TCP 접속 대상과 PHP-FPM의 listen 설정이 일치해야 합니다.

기존에 Apache 모듈 방식으로 PHP를 사용했다면 PHP-FPM 연동 설정을 추가로 점검합니다. 서비스가 실행 중이라는 것만으로 PHP 페이지의 정상 처리를 보장하지는 않습니다.

11. 실제 웹 요청 및 서비스 기능 확인

php -v는 CLI에서 실행되는 PHP 버전입니다. 실제 웹 요청을 처리하는 PHP가 다를 수 있으므로 웹 환경에서도 확인합니다.

외부 접근을 제한한 테스트 경로에 다음 확인용 파일을 작성합니다.

<?php
header('Content-Type: text/plain; charset=UTF-8');
echo 'PHP Version: ', PHP_VERSION, PHP_EOL;
echo 'PHP SAPI: ', PHP_SAPI, PHP_EOL;

브라우저에서 버전과 실행 방식을 확인하고, 점검 후 파일을 삭제합니다.

PHP 코드가 실행되지 않고 그대로 표시된다면 해당 파일을 즉시 제거하고 웹 서버의 PHP 연동 설정을 확인합니다.

다음 기능도 점검합니다.

  • 메인 페이지 및 주요 페이지 접속
  • 로그인과 세션 유지
  • 데이터베이스 연결
  • 파일 업로드
  • 관리자 페이지
  • PHP 및 웹 서버 오류 로그

로그 확인

journalctl -u php-fpm -u httpd --since "10 minutes ago" --no-pager

가상호스트나 애플리케이션에서 별도 로그 파일을 사용한다면 해당 로그도 확인합니다.

[캡처 7: 웹 요청 기준 PHP 버전 및 주요 기능 점검]

12. 최종 확인 항목

작업 결과는 실제 출력과 확인한 내용을 기준으로 기록합니다.

점검 항목 확인 내용
저장소 Remi 메타데이터 조회 정상 여부
PHP 버전 PHP 8.3 수정 패키지 설치 여부
확장 모듈 애플리케이션에 필요한 모듈 설치 여부
패치 근거 공식 공지와 설치 패키지 정보 비교
설정 검사 PHP-FPM 및 Apache 문법 검사 결과
서비스 재시작 후 정상 실행 여부
웹 요청 실제 웹 서비스의 PHP 버전
애플리케이션 로그인·DB 연결·업로드 등 기능 점검

PHP 패키지 업데이트 완료와 애플리케이션 호환성 확인은 별개의 작업입니다. 버전 변경으로 발생하는 함수 및 소스코드 관련 오류는 개발 담당자가 별도로 점검하고 수정해야 합니다.

참고 자료

※ 본 글은 AI를 참고하여 작성했으며, 명령어와 패키지 제공 여부는 실제 적용 환경에서 확인하시기 바랍니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다