CHALLENGE/Dreamhack

[web] phpreg

MUSH 2023. 12. 14. 15:05

문제

php로 작성된 페이지에 접속해 Nickname, Password를 입력하여 Step 2로 넘어간 후 flag를 획득하는 문제입니다.

문제
Step 1
Step 2

 

핵심 - PHP 코드 분석

문제 내 '문제 파일 받기'를 통해 step2.php 소스 파일을 분석 합니다. 

전체

  <div class="container">
    <div class="box">
      <!-- PHP code -->
      <?php
          // POST request
          if ($_SERVER["REQUEST_METHOD"] == "POST") {
            $input_name = $_POST["input1"] ? $_POST["input1"] : "";
            $input_pw = $_POST["input2"] ? $_POST["input2"] : "";

            // pw filtering
            if (preg_match("/[a-zA-Z]/", $input_pw)) {
              echo "alphabet in the pw :(";
            } 
            else{
              $name = preg_replace("/nyang/i", "", $input_name);
              $pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);
              
              if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
                echo '<h4>Step 2 : Almost done...</h4><div class="door_box"><div class="door_black"></div><div class="door"><div class="door_cir"></div></div></div>';

                $cmd = $_POST["cmd"] ? $_POST["cmd"] : "";

                if ($cmd === "") {
                  echo '
                        <p><form method="post" action="/step2.php">
                            <input type="hidden" name="input1" value="'.$input_name.'">
                            <input type="hidden" name="input2" value="'.$input_pw.'">
                            <input type="text" placeholder="Command" name="cmd">
                            <input type="submit" value="제출"><br/><br/>
                        </form></p>
                  ';
                }
                // cmd filtering
                else if (preg_match("/flag/i", $cmd)) {
                  echo "<pre>Error!</pre>";
                }
                else{
                  echo "<pre>--Output--\n";
                  system($cmd);
                  echo "</pre>";
                }
              }
              else{
                echo "Wrong nickname or pw";
              }
            }
          }
          // GET request
          else{
            echo "Not GET request";
          }
      ?>
    </div>
  </div>

부분 분석

// pw filtering
            if (preg_match("/[a-zA-Z]/", $input_pw)) {
              echo "alphabet in the pw :(";
            }

- preg_match : 정규 표현식을 사용하여 문자열에서 패턴이 일치하는지 검사하는 php 함수
- "/[a-zA-Z]/" : 정규 표현식 패턴, 알파벳 a-z, A-Z 중 어떤 하나에 대응 
분석 : $input_pw 변수의 값에 알파벳(a-z, A-Z)이 하나 이상 포함되어 있는지 검사

 

$name = preg_replace("/nyang/i", "", $input_name);
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);

- preg_replace : 정규 표현식을 사용하여 문자열을 대체하는 PHP 함수
- "/nyang/i": 정규 표현식 패턴, 대소문자를 무시하고 nyang 문자열에 대응
- "/\d*\@\d{2,3}(31)+[^0-8\"]\!/" : 정규 표현식 패턴

  - \d*: 0개 이상의 숫자에 대응
  - \@: '@' 문자에 대응
  - \d{2,3}: 2개 또는 3개의 숫자에 대응
  - (31)+: '31'이 1회 이상 반복되는 부분에 대응
  - [^0-8\"]\!: '0'부터 '8'까지의 숫자와 '"' 이외의 문자에 대응, 이후에 '!' 문자에 대응

예시) 1@11319!

분석 : $input_name 변수의 값에 대소문자를 무시하고 "nyang" 패턴을 "공백"으로 대체하여 $name에 저장.

$input_pw 변수의 값에 위 정규 표현식 패턴을 "d4y0r50ng"으로 대체하여 $pw에 저장

 

// cmd filtering
                else if (preg_match("/flag/i", $cmd)) {
                  echo "<pre>Error!</pre>";
                }
                else{
                  echo "<pre>--Output--\n";
                  system($cmd);
                  echo "</pre>";
                }

분석 : $cmd 변수의 값에 대소문자를 무시하고 "flag" 패턴이 포함되어 있는지 검사

 

Reference

https://www.w3schools.com/php/php_ref_regex.asp