G_OM 2024. 10. 16. 17:56

 

 

 

LFI 취약점을 이용하라고 한다.

 

LFI(Local File Inclusion) 취약점은 공격자가 서버의 파일 시스템에 접근하여 서버 내의 파일을 포함하거나 읽을 수 있는 문제를 뜻한다.

 

주로 파일경로를 이용한 취약점이나PHP Wrapper 에 대한 취약점을 보여주기도 한다.

Wrapper 용도 예시
expect:// 원격명령어 실행 file_get_contents('expect://ls');
php://filter 파일의 내용을 변환된 형태로 읽거나 쓰기 php://filter/read=convert.base64-encode/resource=/etc/passwd
zip:// zip 파일 내 특정 파일을 직접 읽기 file_get_contents('zip://path/to/archive.zip#file.txt');

 

 

문제 사이트를 들어가 보자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

List 페이지에 있는 flag.php를 확인해 보자.

 

 

 

 

 

 

 

자세히 보면 View로 이동되어 있는 걸 볼 수 있다.

 

[List에서 클릭을 하면 View 이동된다.]

 

권한부족이라고 나온다.

 

어떤 걸 권한이라고 판단하는지는 모르겠지만 일단 알아두자.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이번엔 hello.json 파일을 읽어봤더니 View로 이동하여 안에 내용을 확인했다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그냥 View를 들어갔을 때는 아무것도 읽지 않아 내용이 없는 모습이다.

 

소스코드를 한번 봐보자.

 

 

<h2>View</h2>
<pre><?php
    $file = $_GET['file']?$_GET['file']:'';
    if(preg_match('/flag|:/i', $file)){
        exit('Permission denied');
    }
    echo file_get_contents($file);
?>
</pre>

 

 

URL에서 봤듯이 file에서 값을 가져온다.

 

preg_match 즉 정규표현식을 사용하여 [flag , : ]  포함된 경우 "Permission denied" 메시지를 출력한다.

 

만약 검증이 우회된 경우 정상적으로 file을 읽는다.

 

 

 

 

 

 

/flag|:/i

 

정규표현식을 이용하여 flag에 대한 문자열을 검사하여 조건에 걸리게 한다.

/i에 의해 대소문자 관계가 없다.

 

':'에 대한 필터링도 있다.

 

view를 이용한 문제풀이를 하려고 했는데 마땅한 우회가 되지 않는다.

 

다시 소스코드를 살펴봤다.

 

 

 

 

 

 

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>PHP Back Office</title>
</head>
<body>
    <!-- Fixed navbar -->
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="/">PHP Back Office</a>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav">
            <li><a href="/">Home</a></li>
            <li><a href="/?page=list">List</a></li>
            <li><a href="/?page=view">View</a></li>
          </ul>

        </div><!--/.nav-collapse -->
      </div>
    </nav><br/><br/>
    <div class="container">
      <?php
          include $_GET['page']?$_GET['page'].'.php':'main.php';
      ?>
    </div> 
</body>
</html>

 

 

index.php이다. 

 

php 코드를 보면 URL에 page 값을 확인하고 해당페이지에. php 확장자를 붙여 포함시키고 없으면 main.php를 포함한다.

 

main.php 별 중요한 내용이 없다 이 코드가 중요한 거 같다.

 

page에 내가 /var/www/uploads/flag.php를 포함시키면 읽어 들일수 있을 거 같다.

 

phpWrapper에 파일을 읽는 php://filter를 써보자.

 

 

 

 

 

 

 

http://host3.dreamhack.games:24067/?page=php://filter/convert.base64-encode/resource=/var/www/uploads/flag.php

 

page를 이용해서 /var/www/uploads/flag.php를 열람시도했는데 아무 결과가 뜨지 않아

 

삽질을 하다 보니

 

확장자를 붙이면 안 된다는 것을 알았다.

 

왜냐하면

 

 /var/www/uploads/flag.php

 

같은 경우에는 PHP 해석기를 통해 파일을 실행하고 그 결과를 반환시킨다.

PHP 코드를 실행시키고 결괏값을 보여준다.

알다시피 안에는 그냥 flag 만 있을 분 그래서 빈 껍데기만 준듯하다.

 

 /var/www/uploads/flag

같은 경우에는 확장자가 없는 파일은 PHP로 실행되지 않고 단순한 텍스트파일이나 바이너리 파일처럼 취급하여 있는 그대로를 가져온다.

그래서 보여주는 거 같다.

 

진짜 여기서 그냥 아휴

 

 

 

 

 

 

 

 

 

 

base64 인코딩 시켜 flag 값이 나왔다.

 

디코딩시키면

 

 

 

 

 

 

 

 

 

 

 

 

flag 값이 정상적으로 출력된다.