Dreamhack - phpreg

·2025년 7월 10일

Dreamhack-Writeups

목록 보기
18/52

phpreg

문제 링크

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

문제 설명

php로 작성된 페이지입니다.
알맞은 Nickname과 Password를 입력하면 Step 2로 넘어갈 수 있습니다.
Step 2에서 system() 함수를 이용하여 플래그를 획득하는 문제입니다.
플래그는 ../dream/flag.txt에 위치합니다.
플래그의 형식은 DH{...} 입니다.

풀이과정

  1. 제시된 step2.php 파일을 확인해 보았습니다.

  2.  if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
                 echo '<h4>Step 2 : Almost done...</h4>

    이 코드를 확인하고 Nickname은 dnyang0310 , Password 는 d4y0r50ng+1+13 임을 확인할 수 있었습니다. 바로 로그인을 시도했지만 실패했습니다.

  3. Nickname을 알아내기 위해,

     $name = preg_replace("/nyang/i", "", $input_name);

    위와같은 코드를 확인할 수 있었습니다. 이는 name에 nyang 이란 문자열이 포함된다면, 공백으로 치환한다는 코드입니다. 이를 우회하기 위해 Nickname 칸에 dnynyangang0310를 입력하였습니다.
    (dnynyangang0310 는 nyang를 공백처리 하고 나면 dnyang0310이 됩니다.)

  4. Password 를 알아내기 위해,

     if (preg_match("/[a-zA-Z]/", $input_pw)) {
               echo "alphabet in the pw :(";
             }
    $pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);

    위와 같은 코드를 확인할 수 있습니다. Password 에는 영어 알파벳이 들어가면 안되며, 특정 정규표현식을 만족하는 문자열은 d4y0r50ng로 치환됨을 알 수 있었습니다.

  5. 정규표현식을 분석해보았습니다.

    • \d* → 숫자 0개 이상 (예: "", "1", "1234")
    • @ → @ 기호
    • \d{2,3} → 숫자 2~3개 (예: "12", "123")
    • (31)+ → "31"이 1번 이상 반복 (예: "31", "3131", "313131")
    • [^0-8\"] → 문자 하나, 단 0~8 숫자나 쌍따옴표 " 는 제외
    • ! → 느낌표 !
      위와같은 정규표현식을 만족하는 0@0031+! 를 구하고, 뒤에 +1+13 를 추가하여 최종적으로 Password에 0@0031+!+1+13 를 입력하였습니다.
      성공적으로 step 1을 풀어내었습니다.
  6. step2 는 커맨드 인젝션(CMD Injection) 을 이용해서 해결하면 되는 문제입니다.
    플래그가 ../dream/flag.txt에 위치한다 하였음으로 cat flag.txt를 입력하였지만 에러가 떴습니다.

  7. 이유를 확인하기 위해 step2.php를 확인해 보았습니다.

    else if (preg_match("/flag/i", $cmd)) {
                   echo "<pre>Error!</pre>";
                 }

    위의 코드에서 확인할 수 있듯, 커맨드에 flag라는 키워드가 들어가면 에러가 뜹니다.

  8. 이를 우회하기 위해 cat ../dream/* 을 입력하였습니다.

    는 dream 파일에 들어있는 모든 파일을 뜻합니다. 이때 dream안에는 flag.txt가 있다 하였기에, 를 입력하여도 정상적으로 flag.txt에 접근이 가능합니다.

  1. 성공적으로 플래그를 획득할 수 있습니다.

배운점

  • php 파일을 읽는 법을 배워볼 수 있었습니다.
  • 특정 키워드의 입력을 막는 경우에, 다양한 방법으로 우회가 가능하다는 것을 배웠습니다.
  • 실무에서는 특정한 키워드의 입력만을 막는 것으로는 보안이 완벽하지 않다는 것에 주의해야겠다고 생각했습니다.

Summary (English)

  • Logged in with:
    • input1 = dnyangnyang0310
    • input2 = 0@0031+!+1+13
  • nyang was removed by regex to make dnyang0310.
  • Password matched /\d*\@\d{2,3}(31)+[^0-8\"]\!/ and became d4y0r50ng+1+13.
  • flag keyword was filtered in Step 2.
  • Used cat ../dream/* to bypass and read flag.txt.
  • Practiced regex bypass and command injection with filtered keywords.
profile
CTF 풀이 및 실습 중심 학습을 기록합니다.

0개의 댓글