Study/Web Hacking

[DreamHeck] phpreg

얀 짱 2026. 9. 12. 05:01

https://dreamhack.io/wargame/challenges/873

 

로그인 | Dreamhack

 

dreamhack.io

 

먼저 app.py를 확인함.

<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);    # 대소문자 구분 없이 nyang이라는 글자를 찾아 모두 제거 
              $pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);  # 정규표현식에 맞는 부분을 찾아 d4y0r50ng 이라는 글자로 바꿈 
              
              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>

 

nickname 에는 다음이 들어가야 함.

dnyannyangg0310

이유는 입력값에서 nyang 단어를 찾아 빈 문자열로 지우기 때문에 남은 최종 문자열이 dnyang0310이어야 함.

 

password 에는 다음이 들어가야 함.

입력값에 알파벳이 포함되면 안되고 정규식 패턴 /\d*\@\d{2,3}(31)+[^0-8\"]\!/과 일치하는 부분이 치환되어 d4y0r50ng이 되어야 함.

최종 결과물이 d4y0r50ng+1+13 와 일치해야 함. 

숫자(생략가능) + @ + 숫자 2~3자리 + 31(1번 이상 반복) + 0~8과 쌍따옴표가 아닌 문자 1개 + ! 여기다가 +1+13 이거 붙이기

3@3331_!+1+13 이런거 넣으면 됨.

$name = preg_replace("/nyang/i", "", $input_name);    # 대소문자 구분 없이 nyang이라는 글자를 찾아 모두 제거
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);  # 정규표현식에 맞는 부분을 찾아 d4y0r50ng 이라는 글자로 바꿈 
...
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>';
    ...

 

그 다음은 step2 인데, 이때 /flag를 입력하면 바로 error! 가 떠버림. cmd command 문자열 우회가 필요함.

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

 

https://pororiri.tistory.com/entry/13547

 

pwnable.kr)cmd2_command함수_필터우회

이번 문제는 전에 풀었던 cmd1 의 심화 버전으로 필터가 더 많이 걸려 있다. 1을 풀었으니 2도 풀 수 있겠지? 함께 풀어보자. 문제는 다음과 같다. 이때 주의 할 점은 cmd2의 비밀번호는 cmd1의 플래그

pororiri.tistory.com

 

이걸 참고 했는데 cat ../dream/fl*.txt 이런 식으로 넣어야겠다 생각했음.

 

하면 플래그를 얻음.