문제 설명


사이트에 들어가 보면

이렇게 Step 1과 Step 2를 해결해야만 flag를 찾을 수 있는 형식인 것 같다. 

 

 

문제 파일을 다운로드해 봤다. 

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>PHPreg</title>
</head>
<body>
  <!-- Fixed navbar -->
  <nav class="navbar navbar-default navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <a class="navbar-brand" href="/">PHPreg</a>
      </div>
      <div id="navbar">
        <ul class="nav navbar-nav">
          <li><a href="/">Step 1</a></li>
          <li><a href="/step2.php">Step 2</a></li>
        </ul>
      </div><!--/.nav-collapse -->
    </div>
  </nav><br/><br/><br/>
  <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>

  <style type="text/css">
    h4 {
      color: rgb(84, 84, 84);
    }
    .box{
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
    }
    pre {
      width: 80%;
    }
    .door_box {
      position: relative;
      width: 240px;
      height: 180px;
      margin: 20px 0px;
    }
    .door_black {
      position: absolute;
      width: 140px;
      height: 180px;
      background-color: black;
      border-radius: 10px;
      right:0px;
    }
    .door {
      z-index: 2;
      position: absolute;
      width: 140px;
      height: 180px;
      background-color: #b9abf7;
      border-radius: 10px;
      right: 100px;
    }
    .door_cir{
      z-index: 3;
      position: absolute;
      border-radius: 50%;
      width: 20px;
      height: 20px;
      border: 2px solid rgba(255, 222, 113, 0.873);
      background-color: #ffea98;
      top: calc( 180px / 2 - 10px );
      right: 10px;
    }
  </style>
</body>
</html>

step2.php

 

<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<title>PHPreg</title>
</head>
<body>
    <!-- Fixed navbar -->
    <nav class="navbar navbar-default navbar-fixed-top">
      <div class="container">
        <div class="navbar-header">
          <a class="navbar-brand" href="/">PHPreg</a>
        </div>
        <div id="navbar">
          <ul class="nav navbar-nav">
            <li><a href="/">Step 1</a></li>
            <li><a href="/step2.php">Step 2</a></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </nav><br/><br/><br/>
    <div class="container">
      <div class="box">
        <h4>Step 1 : Open the door & Go to Step 2 !!</h4>
        <div class="door"><div class="door_cir"></div></div>
        <p>
          <form method="post" action="/step2.php">
              <input type="text" placeholder="Nickname" name="input1">
              <input type="text" placeholder="Password" name="input2">
              <input type="submit" value="제출">
          </form>
        </p>
      </div>
    </div> 

    <style type="text/css">
      h4 {
        color: rgb(84, 84, 84);
      }
      .box{
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
      }
      .door { 
        position: relative;
        margin: 20px 0px;
        width: 140px;
        height: 180px;
        background-color: #b9abf7;
        border-radius: 10px;
      }
      .door_cir{
        position: absolute;
        border-radius: 50%;
        width: 20px;
        height: 20px;
        border: 2px solid rgba(255, 222, 113, 0.873);
        background-color: #ffea98;
        top: calc( 180px / 2 - 10px );
        right: 10px;
      }
    </style>
</body>
</html>

index.php

 

step1.php는 왜 없는 건지 의문이긴 하지만.. 우선 대부분의 경우 그랬듯이 index.php 파일에는 유용한 정보가 없는 것 같다. 

step2.php를 살펴 보니, 각각 Nickname과 Password에 들어가야 하는 값을 직접적으로 보여주고 있는 것을 확인했다.

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"] : "";

name이 "dnyang0310", pw가 "d4y0r50ng+1+13"이면 step2로 넘어갈 수 있다.

 

그러나, 입력값에 필터링이 걸려있는 것 역시 코드에서 찾아볼 수 있다.

위 코드를 보면 사용자가 입력한 name값에서 nyang을 빈 문자열로 필터링한다.

그렇기 때문에 name값에 dnyangnyang0310을 입력해 nyang이 정상적으로 들어가도록 해야 한다. 

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

알파벳 대소문자 모두 입력 시 오류 메시지가 뜬다는 것이다. 

그렇기 때문에 문제 이름대로 php 정규식을 이용하여 해결해야 되는 것 같다.

pw의 정규 표현식을 하나씩 해체해 보면, 

 

\d* : 0~9 사이 숫자가 0개 이상 나타나야 함

\@ : @

\d{2, 3}(31) : 0~9 사이의 숫자 2~3회 후에 31을 씀

+ : 지금까지의 표현을 1회 이상 반복

[^0-8] : 0~8 이외의 문자가 있으면 패턴이 매칭

! : !

 

모든 요소를 조합해 보면 1@12319!라는 문자열을 만들 수 있다.

비밀번호는 d4y0r50ng+1+13이 되어야 해서 1@12319!+1+13을 비밀번호에 입력해 보자. 

 

Step2로 넘어가는 것에 성공했다. 

 

이 역시 step2.php 코드에서 입력값에 대한 필터링이 적용되는 것을 확인할 수 있다. 

// 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";
              }
            }

이를 유의해서 명령어를 작성해 보면,

cat ../dream/f?ag.txt

를 넣을 수 있다. 해당 command를 입력해 봤더니,

플래그 획득에 성공했다!

'SWUFORCE > 워게임 풀이' 카테고리의 다른 글

[Dreamhack] web-misconf-1 (web)  (0) 2024.05.14
[Dreamhack] devtools-sources (web)  (0) 2024.05.14
[Dreamhack] php7cmp4re (web)  (0) 2024.05.07
[Dreamhack] Carve Party (web)  (0) 2024.05.01
[Dreamhack] simple-web-request (web)  (0) 2024.05.01

+ Recent posts