[웹해킹] php include 와 wrapper 취약점에 관하여
오늘은 php include에 대해서 자세하게 알아보면서 그 취약점을 설명하려고 한다.
또한 그 취약점을 설명하면서 php wrapper 에 대해서 까지 다루어 보면서 포스팅을 마무리 하려고 한다.
PHP Include에 대한 기본 개념
먼저 기초적인 php language에서 include 를 사용하는 방법에 대해서 이야기 하고자한다.
간단하게 먼저 설명하자면, 웹 페이지 상에서 다른 페이지에 코딩 된(다른 파일) 것을 부러다가 사용 가능하게 해준다.
이 코딩 된 것에는 데이터베이스 호출을 위한 파일, 펑션 파일 등 파일을 불러오기 위한 것들을 모두 포함한다.
즉, 이 함수는 인자로 전달된 파일을 읽은 후 해당 파일의 내용을 출력한다. 파일의 내용 중 PHP 코드로 해석되는 구문이 존재하면 해당 코드를 실행한다.
아주 간단한 코드의 예시로
<?php
#index.php
include $_GET["page"];
?>
<?php
#register.php
echo "This is JAY'S BLOG. <br>";
?>
이렇게 php 코드가 구성되어져 있을 때, /index.php?page=register.php 와 같은 식으로 request를 보내면
동적으로 register.php를 로드하여 JAY의 블로그를 보여줄 수 있다. 여기에서 확인할 수 있듯이 include 함수는 파일의 확장자와 관련계없이 파일 안에 php 태그가 포함되어 있는 경우 php 코드가 바로 실행되기 때문에 취약점이 발생하기도한다. 예를 들면 /index.php?page=/etc/passwd와 같이 서버내의 정보를 탈취할 수 있다는 점에서 공격에 사용가능하다.
이렇게 서버 로컬 파일을 Include 하는 취약점을 "Local File Inclusion(LFI),
외부 자원을 Include 하는 취약점을 Remote File Inclusion(RFI)라고 부른다.
*참고사항*
다음과 같이 작성할 수 있으나, include 가 일반적인 상대경로를 지원하지 못한다는 것을 염두해 두는 것이 좋다.
항상 루트 부터 주소를 불러온다는 것이다. 물론, 같은 폴더 상에 존재한다면 문제는 없다.
이러한 특성에서 조금 특별한 점이 생기는데, 상대경로 처럼 표현하는 절대경로의 방법을 사용하기도 한다.
<? include $_SERVER["DOCUMENT_ROOT"]."/include/file_name.php"?>
이렇게 보면 계정(최상위) > include 폴더 > filename.php 로 설정되는데, 계정 최상위를 기준으로 아래 디렉터리를 찾아가는 방식으로 설정된다. 이러한 방법을 사용하여 파일의 위치가 달라져도 찾아질 수 있다는 장점이 있다.
PHP Include 와 Wrapper 를 이용한 공격방법
위에서 이야기 했듯이 PHP Include를 활용하여 LFI 와 RFI 취약점이 생길 수 있다는 것을 확인했다. 파일타입에 관계 없이 PHP태그가 포함되어 있기만 한다면 어떠한 시스템에도 사용이 가능하다. 주로 웹서버의 정보를 탈취하는데 쓰인다.
Include 에서 생기는 취약점은 공격 대상 서버에 위치한 파일을 포함시켜 읽어오는 공격이라고 할 수 잇겟다. php 코드 상에서 include()를 사용했을 때 입력값에 대한 적절한 필터링이 이루어지지 않아 취약점이 발생하는 것이다.
이러한 취약점은 PHP Wrapper 와 함께 하여 공격을 더욱 수훨하게 한다. 기존의 PHP wrapper는 실제 데이터의 앞에서 어떤 틀을 잡아주는 데이터 혹은 프로그램이 성공적으로 실행되도록 설정하는 프로그램이다. 즉, 데이터를 감싸주어 프로그램이 성공적으로 돌아갈 수 있도록 포맷팅 해주는 것이라고 보면 편할 것 같다. 그러나 이러한 목적이 아니라 wrapper를 사용하여 개발자의 의도와는 다른 행위를 역으로 만드는 것이다. 이렇게 역으로 공격을 하는 것에 사용되는 wrapper의 종류를 알아보자.
- file:// — Accessing local filesystem
- http:// — Accessing HTTP(s) URLs
- ftp:// — Accessing FTP(s) URLs
- php:// — Accessing various I/O streams
- zlib:// — Compression Streams
- data:// — Data (RFC 2397)
- glob:// — Find pathnames matching pattern
- phar:// — PHP Archive
이 외에도 지원되는 php wrapper를 www.php.net/manual/en/wrappers.php에서 확인 가능하다.
wrapper 중 php의 경우 php의 다양한 입출력 스트림과 필터를 제공하는 기능을한다.
특별하게도, Include시 php태그가 존재하면 php코드가 실행되고 해당 코드는 출력되지 않는다. 그러나 base64등의 인코딩을 통해 php tag를 인코딩 시켜서 코드가 실행되지 않고 출력되도록 하여 소스 코드를 노출시키는 방법을 많이 사용한다.