문제 설명
php로 작성된 페이지입니다.
알맞은 Id과 Password를 입력하여 플래그를 획득하세요.
플래그의 형식은 DH{…} 입니다.
풀이
문제에 접속하면 아래와 같이 Id와 Password를 입력하는 폼이 존재한다.
소스 코드를 한 번 살펴봐야 한다. index.php에서 중요하게 살펴봐야 할 소스 코드는 아래와 같다. action을 check.php로 하고 있고 POST 메소드로 Id, Password를 각각 input1, input2라는 이름으로 check.php에 데이터를 전송한다. 또한 div 태그 아래에 require_once
함수를 사용해서 flag.php 파일을 삽입하고 있다
<div class="container">
<div class="box">
<h4>Enter the correct ID & Password.</h4>
<p>
<form method="post" action="/check.php">
<input type="text" placeholder="Id" name="input1">
<input type="text" placeholder="Password" name="input2">
<input type="submit" value="제출">
</form>
</p>
</div>
<?php
require_once('flag.php');
error_reporting(0);
?>
</div>
check.php의 소스 코드를 살펴보면, getRandStr
함수를 사용해 랜덤한 문자열을 $id 변수에 저장하고, $pw에는 sha1
함수를 사용하여 1을 해쉬한 값을 저장하고 있다. 그 아래에는 사용자가 입력한 값을 int 형으로 강제 변환하고, ==
이라는 비교적 약한 비교를 사용하고 있기 때문에 여기에서 취약점이 발생한다.
<body>
<!-- Fixed navbar -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Type c-j</a>
</div>
<div id="navbar">
<ul class="nav navbar-nav">
<li><a href="/">Index page</a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav><br/><br/><br/>
<div class="container">
<?php
function getRandStr($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[mt_rand(0, $charactersLength - 1)];
}
return $randomString;
}
require_once('flag.php');
error_reporting(0);
$id = getRandStr();
$pw = sha1("1");
// POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$input_id = $_POST["input1"] ? $_POST["input1"] : "";
$input_pw = $_POST["input2"] ? $_POST["input2"] : "";
sleep(1);
if((int)$input_id == $id && strlen($input_id) === 10){
echo '<h4>ID pass.</h4><br>';
if((int)$input_pw == $pw && strlen($input_pw) === 8){
echo "<pre>FLAG\n";
echo $flag;
echo "</pre>";
}
} else{
echo '<h4>Try again.</h4><br>';
}
}else {
echo '<h3>Fail...</h3>';
}
?>
</div>
</body>
input_id
값이 0e로 시작하게 될 경우 php에서는 int 형 변환으로 인해 0으로 해석되고, 오른쪽에 있는 String 문자열도 최적의 비교를 하기 위해 int로 형 변환을 하게 되면서 문자열이므로 0으로 변환된다. 따라서 0
을 10번 입력해주거나 0e
로 시작하여 10의 길이로 입력해주면 된다. 그럼 ID pass 문자열을 확인할 수 있다.
비밀번호인 $pw
에는 1을 SHA1으로 해쉬한 값을 저장하고 있었다. SHA1을 해쉬해주는 사이트에서 1을 해싱한 후 앞 8자리만 잘라 붙여넣어주면 flag를 얻을 수 있다.
댓글남기기