https://dreamhack.io/wargame/challenges/873
php로 작성된 페이지입니다.
알맞은 Nickname과 Password를 입력하면 Step 2로 넘어갈 수 있습니다.
Step 2에서 system() 함수를 이용하여 플래그를 획득하는 문제입니다.
플래그는 ../dream/flag.txt에 위치합니다.
플래그의 형식은 DH{...} 입니다.
제시된 step2.php 파일을 확인해 보았습니다.
if ($name === "dnyang0310" && $pw === "d4y0r50ng+1+13") {
echo '<h4>Step 2 : Almost done...</h4>
이 코드를 확인하고 Nickname은 dnyang0310 , Password 는 d4y0r50ng+1+13 임을 확인할 수 있었습니다. 바로 로그인을 시도했지만 실패했습니다.
Nickname을 알아내기 위해,
$name = preg_replace("/nyang/i", "", $input_name);
위와같은 코드를 확인할 수 있었습니다. 이는 name에 nyang 이란 문자열이 포함된다면, 공백으로 치환한다는 코드입니다. 이를 우회하기 위해 Nickname 칸에 dnynyangang0310를 입력하였습니다.
(dnynyangang0310 는 nyang를 공백처리 하고 나면 dnyang0310이 됩니다.)
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로 치환됨을 알 수 있었습니다.
정규표현식을 분석해보았습니다.
!0@0031+! 를 구하고, 뒤에 +1+13 를 추가하여 최종적으로 Password에 0@0031+!+1+13 를 입력하였습니다.
step2 는 커맨드 인젝션(CMD Injection) 을 이용해서 해결하면 되는 문제입니다.
플래그가 ../dream/flag.txt에 위치한다 하였음으로 cat flag.txt를 입력하였지만 에러가 떴습니다.
이유를 확인하기 위해 step2.php를 확인해 보았습니다.
else if (preg_match("/flag/i", $cmd)) {
echo "<pre>Error!</pre>";
}
위의 코드에서 확인할 수 있듯, 커맨드에 flag라는 키워드가 들어가면 에러가 뜹니다.
이를 우회하기 위해 cat ../dream/* 을 입력하였습니다.
는 dream 파일에 들어있는 모든 파일을 뜻합니다. 이때 dream안에는 flag.txt가 있다 하였기에, 를 입력하여도 정상적으로 flag.txt에 접근이 가능합니다.

input1 = dnyangnyang0310input2 = 0@0031+!+1+13nyang was removed by regex to make dnyang0310./\d*\@\d{2,3}(31)+[^0-8\"]\!/ and became d4y0r50ng+1+13.flag keyword was filtered in Step 2.cat ../dream/* to bypass and read flag.txt.