공격자는 파일 업로드 취약점이나 원격 코드 실행(RCE) 허점을 이용해 서버에 악성 PHP 스크립트를 생성합니다. 생성된 웹쉘은 서버 내부 명령어를 임의로 실행할 수 있는 통로가 되며, 데이터베이스 유출이나 악성코드 유포지로 악용될 위험이 매우 큽니다. 이번 글에서는 이러한 취약점이 발생하는 근본적인 이유와 실무에서 바로 적용 가능한 차단 대책을 살펴보겠습니다.
- PHP 웹쉘 취약점 발생 원인과 메커니즘서버 내부 명령어를 실행할 수 있는 PHP 환경 설정 및 검증 누락이 핵심 원인입니다.
또한 파일 업로드 기능에서 확장자 검증을 단일 클라이언트 측 검사(JavaScript)에만 의존하거나, 업로드 디렉터리의 실행 권한을 제어하지 않을 경우 악성 php shell 파일이 웹 서버 상에서 그대로 실행됩니다.
- 입력값 검증 부재: 외부 파라미터가 shell_exec, system 등의 함수로 직접 전달되는 구조
- 파일 업로드 검증 미흡: .php, .phtml, .php5 등 가용 확장자에 대한 서버 측 검증 누락
- 업로드 경로의 실행 권한: 파일이 저장되는 디렉터리 내에서 PHP 스크립트 실행이 허용된 상태
- 위험한 PHP 시스템 함수 차단 및 비교shell_exec와 exec 등의 시스템 명령 실행 함수를 비교하고 차단해야 합니다.
✓ php shell_exec vs exec 주요 차이점
| 함수명 | 반환값 특징 | 보안 위험도 |
| shell_exec | 실행된 명령어의 전체 출력을 단일 문자열로 반환 | 매우 높음 (웹 shell 구현에 자주 사용) |
| exec | 명령어 실행 결과의 마지막 줄만 반환 (전체 결과는 배열에 저장 가능) | 매우 높음 |
| system | 명령어 실행 결과를 즉시 출력하고 마지막 줄을 반환 | 매우 높음 |
| passthru | 원시(Raw) 데이터를 그대로 출력 내보냄 | 매우 높음 |
php.ini 내부의 disable_functions 항목에 등록하여 실행 자체를 비활성화하는 것이 가장 안전합니다.Ini, TOML
disable_functions = exec, passthru, shell_exec, system, proc_open, popen, curl_exec, curl_multi_exec, parse_ini_file, show_source
- 실무 중심의 php2shell 대응 및 보안 조치다중 방어 기법을 적용하여 웹쉘의 생성과 실행을 원천 차단합니다.
✓ 서버 측 파일 업로드 검증 강화파일 업로드 구현 시 화이트리스트 방식을 채택하여 허용된 확장자(예: jpg, png, pdf)만 업로드되도록 제한해야 합니다. MIME 타입 검사와 함께 파일 내용의 헤더(Magic Bytes)를 검증하는 로직을 서버 코드에 추가합니다.
✓ 업로드 디렉터리 실행 권한 제거업로드된 파일이 저장되는 폴더에 대해서는 웹 서버(Apache, Nginx 등) 설정을 통해 PHP 스크립트 해석 및 실행을 금지해야 합니다.
Nginx 환경 설정 예시:
Nginx
location /uploads/ {
location ~ \.(php|phtml|php3|php4|php5|php7|phps)$ {
deny all;
}
}
escapeshellcmd 및 escapeshellarg 함수를 사용하여 외부 입력값의 위험 인자를 안전하게 이스케이프 처리해야 합니다.- php shell detector를 활용한 주기적 점검이미 생성되었을지 모르는 웹쉘을 탐지하고 제거하는 방안을 도입합니다.
eval, base64_decode, gzinflate 등)이 포함된 파일들을 찾아낼 수 있습니다.- 정기 진단 수행: CRON 스케줄러를 통해 일 단위로 웹 루트 디렉터리 스캔을 자동화합니다.
- 파일 무결성 검사: 주요 소스 코드 파일의 Hash 값을 비교하여 변조 여부를 모니터링합니다.
- 웹 방화벽(WAF) 연동: 웹쉘 업로드 패턴이나 식별된 공격 요청을 실시간으로 차단합니다.
FAQ
Q. disable_functions 설정 후 웹 애플리케이션에 영향이 없을까요?A. 일반적인 게시판이나 회원 관리 중심의 웹 서비스는 시스템 명령 함수를 사용하지 않으므로 영향이 거의 없습니다. 다만 외부 이미지를 변환하는 라이브러리(ImageMagick 등)나 백그라운드 프로세스를 호출하는 기능이 있다면 영향 범위를 사전 테스트 후 적용하셔야 합니다.Q. 파일 확장자를 .png로 위장하여 업로드하는 웹쉘은 어떻게 막나요?A. 확장자 단순 체크 외에 서버 내에서 파일의 Magic Byte(바이너리 헤더)를 검증하고, 이미지 재압축(Re-encoding) 과정을 거쳐 저장하면 위장된 악성 코드를 무력화할 수 있습니다. 또한 업로드 디렉터리의 실행 권한을 제거하는 것이 핵심 방어책입니다.