[WEB] image-storage 문제풀이

파일 업로드 취약점이란 파일 업로드 기능이 존재하는 웹 어플리케이션에서 확장자 필터링이 제대로 이루어지지 않았을 경우 공격자가 악성 스크립트 파일(웹쉘)을 업로드하여 해당 웹쉘을 통해 원격에서 시스템을 제어할 수 있는 취약점을 말한다.

 

문제를 확인해보자

 


PHP로 작성된 이미지 저장소를 이용하여 파일 업로드 취약점을 동작시키고, flag를 획득하는 문제이다.

접속해보자.

 

 

업로드를 성공시켜야 하니 Upload 페이지를 들어가보자.

 

 

이런거 또 파일 바로 안올려보면 섭섭하지.

하수들은 업로드 구간이 보이면 웹쉘부터 때려박지만

나는 부끄럼이 많기 떄문에 print 구문부터 올려볼거다.

 

php 구문으로 echo에 작성된 내용을 출력하는 JJANG.py 파일을 생성한다.

echo 내용 설명은 생략하겠다.

그럼 이 파일을 업로드 해보자.

 

 

파일 업로드가 수행된 경로가 노출된 것 같다.

혹시 이게 웹 상의 경로라면 지금 바로 접근이 가능할 것 같은데

한 번 츄라이 해보자.

 

 

어라  php 구문이 실행되네?

소스코드도 안까봤는데 이걸로 풀어버리면 티오리 형님들 섭섭하기 때문에

일단 웹쉘을 올리기 전에 소스코드부터 열어보자.

 

<?php
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    if (isset($_FILES)) {
      $directory = './uploads/';
      $file = $_FILES["file"];
      $error = $file["error"];
      $name = $file["name"];
      $tmp_name = $file["tmp_name"];
     
      if ( $error > 0 ) {
        echo "Error: " . $error . "<br>";
      }else {
        if (file_exists($directory . $name)) {
          echo $name . " already exists. ";
        }else {
          if(move_uploaded_file($tmp_name, $directory . $name)){
            echo "Stored in: " . $directory . $name;
          }
        }
      }
    }else {
        echo "Error !";
    }
    die();
  }
?>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>Image Storage</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="/">Image Storage</a>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav">
            <li><a href="/">Home</a></li>
            <li><a href="/list.php">List</a></li>
            <li><a href="/upload.php">Upload</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav><br/><br/><br/>
    <div class="container">
      <form enctype='multipart/form-data' method="POST">
        <div class="form-group">
          <label for="InputFile">파일 업로드</label>
          <input type="file" id="InputFile" name="file">
        </div>
        <input type="submit" class="btn btn-default" value="Upload">
      </form>
    </div> 
</body>
</html>

 

POST로 upload.php 페이지에 요청이 들어오면, 정상적인 파일이 업로드 되었는지 확인한다.

별다른 에러가 발견되지 않았다면, 해당 파일이 ./uploads 디렉토리에 이미 존재하는지 여부를 확인한다.

존재하지 않는다면 해당 디렉토리에 파일을 업로드하고 "Stored in: /디렉토리/파일명" 을 출력한다.

 

이번 문제는 사용자 입력 값에 대해 별다른 검증 및 필터링이 존재하지 않기 때문에

이제 바로 웹쉘 파일을 올려서 flag.py 파일을 찾아보도록 하자. 

 

 

GET 메소드의 cmd 파라미터로 전송되는 문자열을 시스템 명령어로 수행하는 php 웹쉡을 작성하였다.

해당 웹쉘 파일을 웹서버에 업로드해보자.

 

이제 웹쉘이 업로드된 경로에 GET으로 cmd 파라미터에 ls 명령어를 전송해서 flag.py를 찾아보자.

 

음 업로드 디렉토리에는 flag.py가 안보인다. 상위 디렉토리에 있는지 확인해보자.

 

 

뭐야 어디갔냐. 한번만 더 상위 디렉토리로 가보자.

 

 

잘못 짚었나보다. 최상위 디렉토리로 가보자.

 

 

찾았다 flag.txt 요놈!

이제 cat 명령어로 txt 읽어보자.

 

 

플래그놈이 나왔다.

 

문제풀이 끗

복사했습니다!