php로 작성된 페이지에서 코드를 이용해 플래그에 대한 단서를 얻어야하는 문제이다
<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;
플래그에 대한 단서를 얻을 수 있는 코드
<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>
문제 사이트에 페이지에 관해 나와있는 코드
웹페이지로 접속하게 되면 다음과 같이 step1이라는 문과와 함께
닉네임과 비밀번호를 입력해야하는 란이 뜬다
여기에 아무 닉네임과 비밀번호를 입력해보았지만
틀렸다는 문구와 함께 풀리지 않는다
$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")
이 코드를 살펴보면 name은 dnyang0310이어야하고
비밀번호는 d4y0r50ng+1+13이어야 로그인을 성공할 수 있다
하지만 바로 윗줄을 보면 preg_replace()함수 안에
아이디는 nyang을 피해야하고 비밀번호는 d4y0r50ng을 피해야한다
그렇게 하기 위해서는 우회하는 방법을 사용해야한다
nyang를 우회하기 위해 dnynyangang0310을 사용한다
대소문자를 구별할 수 있기 때문에 다음과 같은 방법을 사용했다
d4y0r50ng를 우회하기 위해 정규표현식을 사용한다
/\d*\@\d{2,3}(31)+[^0-8]\!/이 조건에 맞는 정규표현식을 만들어본다
1@12331+!로 만들고 비밀번호의 규칙에 맞게 1@12331+!+1+13을 사용한다
아이디와 비밀번호를 입력하면 다음과 같은 창이뜬다
플래그는 ../dream/flag.txt에 위치하기 때문에
cat ../dream/flag.txt를 입력해보면 틀렸다는 문구가 뜬다
else if (preg_match("/flag/i", $cmd)) {
echo "<pre>Error!</pre>";
다음 코드를 보면 preg_match()함수 안에서 flag가 들어갈 시 에러가 뜬다는 걸 알 수 있다
플래그를 얻기 위해서는 flag를 치지 않는 방법으로 우회해야한다
우회를 하기위해 대소문자를 쓰는 방법도 있지만
flag 뒤에 i가 있기 때문에 대소문자로 우회를 할 수 없다
그럴 때에는 cat ../dream/fla?.txt 또는 cat ../dream/fl*.txt를 입력해본다
그러면 다음과 같은 플래그를 얻을 수 있다
DH{ad866c64dabaf30136e22d3de2980d24c4da617b9d706f81d10a1bc97d0ab6f6}