[dreamhack] Type c-j

IMKYU·2024년 11월 24일

문제

웹페이지

문제파일

설명

<?php
// check.php의 일부
    function getRandStr($length = 10) {
        $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $charactersLength = strlen($characters);
        $randomString = '';
    
        for ($i = 0; $i < $length; $i++) {
            $randomString .= $characters[mt_rand(0, $charactersLength - 1)];
        }
        return $randomString;

    }
    require_once('flag.php');
    error_reporting(0);
    $id = getRandStr();
    $pw = sha1("1");
    // POST request
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
      $input_id = $_POST["input1"] ? $_POST["input1"] : "";
      $input_pw = $_POST["input2"] ? $_POST["input2"] : "";
      sleep(1);

      if((int)$input_id == $id && strlen($input_id) === 10){
        echo '<h4>ID pass.</h4><br>';
        if((int)$input_pw == $pw && strlen($input_pw) === 8){
            echo "<pre>FLAG\n";
            echo $flag;
            echo "</pre>";
          }
        } else{
          echo '<h4>Try again.</h4><br>';
        }
      }else {
      echo '<h3>Fail...</h3>';
     }
    ?> 
  • 로그인을 하면 flag가 보인다
  • 하지만 아이디는 랜덤으로 생성이 되고 패스워드는 해시되어있다.
  • 아이디 검증로직을 우회하는 방법의 힌트는 비교연산자(==)이다.
    • php에서 == 는 느슨한 비교연산자이다.
    • C나 java에서 사용하는 == 연산자와 다르다.
      • C나 java에서 사용하는 == 처럼 데이터 형식까지 비교하는 연산자는 php에서 엄격한 비교 (===)이다.
    • 느슨한 비교의 특징은 자동으로 형변환을 해준다.
    • if ((int)$input_id == $id && strlen($input_id) === 10)
      • 여기서 $input_id를 int으로 형변환하여 비교하고 $id는 그에 맞춰 자동으로 int형으로 형변환 해준다.
      • int로 형변환 할때 숫자로 시작하지 않는다면 0으로 변환된다. ex) abcdefg ⇒ 0
      • 숫자로 시작한다면 숫자가 아닌 문자가 나올때까지 변환된다. ex) 01234abc ⇒ 01234
      • 만약 랜덤으로 생성된 아이디가 숫자가 아닌 문자로 시작된다면 0이고 글자가 10개로 제한이 되어있기 때문에 “000000000000” 를 입력한다. (int)”0000000000” ⇒ 0
  • 비밀번호는 sha(”1”)를 해시하고 8자리를 가져오면 된다.
    • 해시값 356a192b7913b04c54574d18c28d46e6395428ab
    • 해시값 8자리 356a192b
    • 또는 아이디 우회를 한 것처럼 “356’문자열5자리’”도 가능

결과

profile
아무것도 안 한 거랑 다를께 없잖아??

0개의 댓글