File Inclusion

File Inclusion 취약점

ragdo11 2024. 9. 4. 01:58

파일 삽입 취약점은 공격자가 악성 스크립트를 취약한 페이지에 삽입할 수 있는 취약점이다. include 함수나 require 함수를 사용할 시 취약점이 생길 수 있으며 include는 삽입해서 실행하는 스크립트에 오류가 있더라도 계속 실행시키고, require 함수는 오류가 있다면 중단시키는 차이점이 있다.

include와 require 함수는 지정한 파일을 현재 페이지에 포함해서 실행시켜주는 함수로 개발의 편리함을 가져다줄 수는 있지만 말했듯이 취약점을 불러일으킬 수도 있다.

 

삽입할 악성 파일의 위치가 로컬에 위치하는지 원격지에 위치하는지에 따라 LFI(Local), RFI(Remote)로 나뉜다. 

먼저 RFI 부터 알아보면 그냥 외부의 서버에 위치한 악성 파일을 페이지에 include 시켜서 실행시키는 취약점인데 이렇게 외부 파일을 include 시키게 하려면 php.ini에 allow_url_fopen 설정을 off 해줘야 한다. 그런데 굳이 위험을 감수하고 이 기능을 off할 이유도 없거니와 이러한 기능도 잘 사용하지 않아서 RFI 취약점은 많이 없다고 한다.

 

LFI는 로컬 서버에 위치한 악성 파일을 페이지에 include 시키는 취약점이다. 일단 로컬 파일을 페이지에 include 하는 것을 실습해보자.

 

include 기능이 있는 php 파일이다. file 파라미터로 include할 파일을 지정하면 지정된 파일이 include 되어 출력된다.

 

index.php 파일을 include 하였더니 조금 비율이 깨지긴 하지만 정상적으로 include 되었다.

 

다운로드 취약점이랑 살짝 비교를 해보자. 다운로드 취약점 때는 index.php 파일을 다운로드 받으면 그 파일의 소스 코드를 전부 볼 수 있었다. 이번에 include를 해주는 경우엔 index.php 파일이 실행이 되어 소스 코드를 볼 수는 없다. 그러면 소스 코드를 받아서 내부의 취약한 페이지라던가 주석, db 파일, 소스 코드 자체 취약점 등을 볼 수 있는 다운로드 취약점이 더 강력한 취약점이겠구나! 라는 생각이 들 수 있는데 FI 취약점은 파일을 실행시키기 때문에 오히려 다운로드 취약점보다 강력한 취약점이 될 수 있다.

 

위 파일 Fake_green.jpg는 일반 그림 파일에 웹 셸 코드를 숨겨놓은 파일이다. 평소엔 그림 파일로 인식하기 때문에 저번에 공부한대로 그림 파일을 php 파일로써 실행하게 하지 않으면 웹 셸 코드가 실행되지 않는다.

다만 include는 페이지를 불러와 실행시키므로 그 점을 이용하여 내재된 웹 셸 코드를 실행하게 할 수 있다.

 

Fake_green.jpg 파일을 include한 후에 웹 셸 코드를 이용해 명령문을 전달해 주었더니 문제 없이 실행됨을 볼 수 있다.

 

그런데 이렇게 파일을 저장하는 기능이 있는 곳이 아니더라도 LFI 취약점을 이용할 수 있는데 액세스 로그를 이용한 방법이다.

액세스 로그

액세스 로그에 웹 셸 코드가 삽입되도록 하고 이를 include 하여 공격하는 방법이다. 어디에 웹 셸 코드가 삽입되어도 상관이 없고 나는 User-Agent 부분이 깔끔해보여서 그곳을 이용해보기로 결정했다.

 

일반적인 요청의 User-Agent 부분을 간단한 웹 셸 코드로 변경해준 후 전송!

 

액세스 로그를 살펴보면 user-agent 부분에 웹 셸 코드가 삽입되었다. include를 통해 액세스 로그를 불러오고 웹 셸을 실행시켜 보면

 

아무래도 로그 파일이다 보니까 굉장히 길게 로그가 출력되고 아래에 ls 명령어를 실행한 결과가 나온다. 이처럼 악의적인 파일이 저장이 되있지 않더라도 액세스 로그를 사용해 LFI 형태의 공격을 할 수 있다.

 

 

여담)

와나 이거 하려고 진짜 꽤나 고생했는데 먼저 액세스 로그를 include 해주려고 했는데 안 되길래 봤더니 httpd 디렉터리에서 권한 문제 때문에 막혔음을 1차로 확인했고, 그냥 httpd 디렉터리 권한을 잠깐 바꿔주면 될 것을 웹 서버 프로세스를 실행하는 apache 계정의 uid/gid를 0으로 변경해주고 접근하려 했더니 요즘은 웹 서버 프로세스가 root 권한으로 실행되지 않고 있었다는 사실을 까먹고 있었다가 공부하면서 강제복습(?) 당해버렸다. 쩔 수 없이 다시 httpd 권한을 바꿔주어 root 이외의 계정도 접근이 가능하게 바꿔준 후 액세스 로그 include를 시도했더니 또 안 됨. 다른 에러 로그나 테스트용 파일은 잘만 include 되는데.. 이건 apache가 액세스 로그를 실시간으로 쓰고 있기 때문에 파일이 잠겨 있어서 include가 되지 않는다고 한다. 어쩔 수 없이 액세스 로그를 저장해놓고 사용했다..

액세스 로그로 LFI 형태의 공격이 된다는 것은 알겠는데 이거 진짜 되는 공격은 맞는지 회의감 듬.

 

대응 방안

  • 만약 include와 require 함수를 사용하고 있다면 절대 외부의 입력을 통해서 결정하게 하면 안 된다. 모든 취약점이 그렇지만 항상 입력값은 검증을 해야 한다. include 할 파일들을 제시하여 사용자로부터 고르게 한다거나, 사용자의 입력이 필요한 경우 그대로 사용하지 않고 적절히 처리해준다.

적절한 처리의 예시를 들어보자면 아래와 같다.

$choose = [
	'apple' => 'apple.jpg',
	'peach' => 'peach.jpg',
	'welcome' => 'welcome.php'
];

 

  • 웹 방화벽인 WAF를 사용한다.
  • php 설정 파일에서 open_basedir 설정을 하여 접근 가능한 디렉터리를 제한한다.
  • 디렉터리 트레버져 취약점에서 사용했던 대응 방안을 적용하여 다른 디렉터리로의 접근을 제한한다.