step1이다.
소스코드를 확인해 보자.
<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.html 즉 step1 페이지인 거 같다.
php 코드는 없고 HTML, css 만 있는 거 같다.
step2 페이지 소스코드를 봐보자.
<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>
php 코드들이 보인다.
한번 확인해 보자.
<?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";
}
?>
여기서 모든 것이 이루어지는 거 같다.
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$input_name = $_POST["input1"] ? $_POST["input1"] : "";
$input_pw = $_POST["input2"] ? $_POST["input2"] : "";
일단 'input1' , 'input2'라는 이름의 POST 파라미터를 가져온다. 아마 페이지에 Nickname과 Password인 거 같다.
if (preg_match("/[a-zA-Z]/", $input_pw)) {
echo "alphabet in the pw :(";
}
'input2(pw)'은 정규표현식에 대한 필터링이 존재한다.
알파벳 소문자 대문자 a~z까지 필터링을 한다.
만약 알파벳이 없을 경우 ~
else{
$name = preg_replace("/nyang/i", "", $input_name);
$pw = preg_replace("/\d*\@\d{2,3}(31)+[^0-8\"]\!/", "d4y0r50ng", $input_pw);
else 문으로 넘어가게 되는데 여기서 input_name 값에서 "nyang" 문자열을 대소문자 구분 없이 찾아 없앤다.
input_pw 값에서는 해당되는 정규표현식 패턴의 조건이 만족되면 "d4 y0 r50 ng" 문자열을으로 치환해서 $pw 변수에 저장된다.
여기서 정규표현식 패턴은
\d*: 숫자가 0회 이상 나타나는 부분을 찾습니다.
\@: "@" 문자를 찾습니다.
\d{2,3}: 2 또는 3개의 숫자를 찾습니다.
(31)+: "31"이 반복되는 부분을 찾습니다. "+"는 해당 부분이 1회 이상 반복됨을 나타냅니다.
[^0-8\"]: 숫자 0부터 8까지와 따옴표(")를 제외한 모든 문자를 찾습니다. 대괄호([]) 안에 있는 ^는 부정(negation)을 나타냅니다. 따라서 숫자 0부터 8까지의 문자와 따옴표를 제외한 문자를 찾습니다.
\!: "!" 문자를 찾습니다.
으로 @12319! 값을 주면 "d4 y0 r50 ng"로 치환해 준다.
다음 코드를 봐보자.
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>';
$name 이 "dnyang0310"이고 $pw "d4y0r50ng+1+13"이라면 step 2로 넘어가는 거 같다.
한번 필터링을 우회해서 입력해 보자.
여기서 원하는 정규표현식 패턴을 넣어준다.
값을 입력하면 문이 열리면서 Step 2로 넘어가게 된다.
ls -l를 실행하자 현재 디렉터리에 대한 정보들을 알려준다.
pwd 명령어를 써서 현재 경로를 보고 지금 현재 html 디렉터리 안에는 의미 있는 게 없으니 상위 디렉터리로 가보자.
어... cd 명령어는 듣지 않는 거 같다.
그러면 ls 명령어로 확인해 보자.
dream이라는 디렉터리가 있다.
한번 확인해 보자.
오 플래그가 있다.
cat 명령어를 통해서 한번 봐보자.
cat../dream/flag.txt를 사용하니 Error! 라 출력된다.
문제파일에서 코드를 확인해 보자.
else if (preg_match("/flag/i", $cmd)) {
echo "<pre>Error!</pre>";
}
preg_match 함수로 문자열 "/flag"를 막아놨다.
그러면 와일드카드로 확인해 보자. (*)
dream 디렉터리 안에는 flag.txt 밖에 없으니 상관없다.
'DreamHack > CTF' 카테고리의 다른 글
(CTF 출제)DreamHack - Easy Login (1) | 2024.05.01 |
---|---|
(CTF 출제)DreamHack - Mango (0) | 2024.04.30 |
(CTF 출제)DreamHack - Carve Party (수정) (0) | 2024.04.05 |
(CTF 출제)DreamHack - ex-reg-ex (수정) (0) | 2024.04.05 |
(CTF 출제)dreamhack - Baby Linux (수정) (0) | 2024.04.05 |