web_security/web info

LFI(Local File Inclusion)란?

HawordFREAKEK 2019. 9. 13. 22:37

네 안녕하세요. Godhaword 입니다.

일단 즐거운 추석되세요 꾸뻑(__)

오늘은 Local File Inclusion (이하 : LFI 또는 lfi)에 대해서 알아보겠습니다.

맨날 LFI 문제만 나오면, =flag.php, flag.txt, ../../../../etc/passwd 까지만 쳐보고 긁적긁적 하다가 다른 web문제로 넘어가곤 했는데요. 이번에 기회가 되어서 한 번 다루어보게 되었습니다.

저도 아직 공부하는 단계라 예제 문제로 보여드릴 문제 푸느라 포스팅이 약간 늦춰졌습니다.

LFI 친구인 RFI 는 시간이 좀 더 걸릴 수 있으나 최대한 빨리 포스팅 하겠습니다.


목차는

1. LFI 란?

2. LFI 가 작동하는 원리

3. LFI 를 하는 방법

4. LFI 예제

5. LFI 를 막는 방법


순으로 가겠습니다.




1. LFI 란?

Local File Inclusion 의 약자입니다. 직역하자면 


어.. 쉽게 설명하자면 LFI는 공격(포함)할 파일이 공격대상 서버에 있다는 뜻입니다. 미리 좀 말씀드리자면 RFI(Remote File Inclusion)은 공격대상 서버가 아니라 원격지(remote) 에 있다는 뜻 입니다. 오픈 소스로 개발된 곳은 디렉토리 구조가 더 많이 알려져있어 더 위험합니다.

더 쉽게 설명하자면 공격 대상 서버에 있는 디렉토리로 저희가 접근하여 원하는 값을 열어보게 하는 행동입니다. 동작과정이 injection 이랑 비슷하여 처음에는 Local File Injection 인 줄 알고, 삽만 꽤 많이 푸었습니다.



2. LFI 가 작동하는 원리

일단 작동하는 원리를 알기 전에 왜 이런 취약점이 발생하는지 짚고 지나갈 필요가 있습니다.
php코드에서 include() 부분에 적절한 보호장치나 필터링이 없을 때 주로 발생됩니다. get, post 함수를 사용하여 include 부분을 건드릴 수 있는 php 문이라면 LFI를 한 번 쯤은 고려해보아야합니다. 

Q : include 부분이 뭐냐. #include<stdio.h> 이런거냐

A : 

los.rubiya 문제 중 하나를 가져와 설명드리자면, 저기 위에있는 include "./config.php" 부분을 말합니다.

1
2
3
4
5
6
7
8
9
10
11
<?php
    $file = $_GET['test'];
    if(isset($file))
    {
        include("pages/$test");
    }
    else
    {
        include("index.php");
    }
?>
cs

더 좋은 예제( GET 으로 test을 받아 include부분에 사용하기에 LFI의심) 
위 코드를 약간만 읽어드리자면, test 를 입력 받아 test에 입력 받은 변수가 설정된 변수면 5번째 줄 코드를 실행하고, 없으면 그냥 9번째 줄을 실행합니다. 그러기에 만약 LFI에 대한 대처가 부족한 사이트라면 test부분에 저희가 원하는 페이로드를 입력하면 원하는 행동을 얻어낼 수 있는 것 입니다.

또 어느 곳에서는 개발자가 GET 메소드를 선호해서 이러한 문제가 더 생긴다는데... 아직 거기 까진 모르겠습니다.


Q : 아니 그러면 include("index.php") 가 뜻하는게 뭐냐. 그래서 #include<stdio.h> 랑 같은거라고?

A : 원리는 비슷합니다. #include<stdio.h>는 stdio 헤더에 있는 함수들을 include 하는 것 역할을 하고, include("index.php")는 index.php라는 표준 php 파일을 include 한다고 생각하시면 편합니다.

include와 require 이 php 에서는 비슷하게 쓰이는데.. 어.. 간단하게 fatal error가 뜨면 require 이고, error warning 만 뜨면 include 라고 생각하시면 됩니다. require가 더 

엄격히 처리합니다. 이 글은 php 함수 요약 글이 아니기에 이 정도로만 설명하겠습니다. (그리고 저도 잘 몰라서..)



3. LFI를 하는 방법

2번 목차에서 말한 것과 같이 php문에 get 함수가 include 쪽을 건드릴 수 있나 확인을 할 수 있으면 가장 좋겠지만 일반적인 사이트에선 구성되있는 php문을 확인하는 것이 어렵습니다.

url 창에 ?(변수명) = godhaword(변수 값)이 아닌


?(변수 명) = google.com (주소 명) 이 되면 LFI를 의심해보는 편입니다.

하지만 디렉토리 접근에 관한 문제이기 때문에 꼭 주소가 있어야만 LFI가 가능한 것은 아닙니다.

또한 변수명이 q, query 이런 저장하는 느낌의 변수명이 아니고 page, command, file, template, document, folder, pg 어디서 많이 본 듯한 변수명인 것 같아도 LFI를 의심합니다.





4. LFI 예제

첫번째 예제는 Hackctf 의 Read File 입니다.

일단 주소창을 보니까 변수명도 command 고 변수로 받는 값도 주소네요.. ㅎㅎ

한번 씨익 웃어주고, File is flag.php 라는 힌트를 참고하여 flag.php 값을 command에 저장해보겠습니다.

???

몇번 더 값을 보내본 결과 위와 같은 창은 command에 잘못된 주소가 입력되면 나오는 default 창인 것이라고 생각됬습니다.

쓰라는대로 flag.php를 썼는데 저렇게 나오는 것을 보니 flag가 필터링 된 거 같았습니다.


그래서 초기창에서 google.com에 flag를 아무렇게나 입력하고 엔터를 눌러보니 별다른 문제 없이 google 사이트가 열렸습니다.

이로써 flag라는 단어 자체를 필터링 하는 것 같았습니다.


그래서 flag안에 flag 넣어주니 문제가 풀린 모습을 볼 수 있습니다. (이 안에 너 있다..)

str_replce로 필터링 된 것 같습니다.



풍성한 한가위 되시라고 문제도 하나 더 준비했습니다.


문제 이름이 Local File Inclusion 이라 들어와봤는데.. 클릭하라고 몇몇칸이 있길래

하나 눌러보았습니다.

그러자 http://challenge01.root-me.org/web-serveur/ch16/?files=sysadm 와 같이 하위 폴더로 갈 수 있었습니다.

변수 값이 주소는 아니지만 변수 명이 file 인 것을 보아 LFI 이지 않을까하여 하위 디렉토리로 가도록 ../ 한번 만 쳐봤습니다.

wow

처음 보는 하위 디렉토리가 있습니다.

누가 봐도 admin File에 접근해달라고 소리치는 것 같습니다.

그렇기에 ../admin을 입력해주면


하위

flag 값이 나옵니다.

이게 F ! L ! A ! G ! 이렇게 대놓고 있는게 아니라, php문 사이에 껴 있기에 그냥 보고 지나가기 쉬울 것 같았습니다.


// root me 에 있는 다른 LFI 문제인 double 인코딩 문제는 지금 풀고 있는 중입니다. 풀면 바로 추가해 올리겠습니다.


2. double encoding


  사진으로 설명하려다가.. 너무 길어질꺼같아서 영상으로 남깁니다.

위 영상에는 추가하지 못했지만 urledcode 가 있길래 두 번 url 인코딩을 해주었습니다.

url 인코딩 사이트에서 하려니까 . 을 인코드 해주지 않아 그냥 버프 슈트에 있는 인코드 기능을 사용하였습니다.


5. LFI를 막는 방법

어.. 막는 방법보단 예방 방법이 더 맞나.. 둘이 똑같나..

일단 ../ 같은 문자를 필터링 하는게 가장 중요합니다.

위에 hackctf에서 보았던 방식으로 str_replace 함수를 사용한다면 str_replace("../","",$test); 이렇게 필터링 해두면 바로 디렉토리에 접근하는 것은 막을 수 있습니다. 하지만 위 문제 풀이와 같이 ../사이에 ../ 를 한 번 더 추가하면 필터링이 우회 되기 때문에 str_replace("../","godhaword",$test); 이렇게 중간에 더미 값을 한 번 남겨주거나 ../ 같이 길게 남겨두지 말고 /'"()₩<>|& 같은 문자 하나하나 필터링 하여 //// 이렇게 넣어도 다 필터링 되게끔 하는게 어떤가 생각해봅니다. 


두 번째는 

allow_url_fopen , allow_url_include, display_errors 설정을 php 환경설정에서 off로 수정해주는 방법입니다.

allow_url_fopen , allow_url_include 이 두 가지 같은 경우 검색을 해보니 평균적으로 다 off 로 해두고 특별한 경우에만 on 을 해주기 때문에 요즈음에 사이트는 LFI에 비교적 안전하다고 말할 수 있을 것 같습니다. replace 함수로 .나 / 같은 것을 필터링 해주다보면 순수한 http://naver.com 이게 http:navercom 이되버리기 때문에 두 번째 방법이 더 좋다고 생각됩니다.


(혹시나 궁금해 하시는 분 계실까봐...

allow_url_fopen 을 on 으로 해둔 다면 url 값을 파일 처럼 사용한다는 말임. 그래서 하위디렉토리 접근이 가능해짐

allow_url_include 을 on으로 해둔다면 외부사이트의 파일을 호출할 수 있게 됨

display_errors 을 on으로 하면 에러 코드를 보여주게 됨.

)



더 궁금하신 점은 댓글로 부탁드립니다












'web_security > web info' 카테고리의 다른 글

[WebHacking] XSS (Cross Site Scripting) 란?(New)  (2) 2022.05.29
XSS (Cross Site Scripting) 란?  (0) 2019.09.27
파일 업로드(File-Upload) 취약점이란?  (0) 2019.09.21
RFI(Remote File Inclusion) 란?  (0) 2019.09.14
SSTI란?  (0) 2019.09.04