문제

웹페이지

문제파일

설명
<?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");
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>';
}
?>
- 로그인을 하면 flag가 보인다
- 하지만 아이디는 랜덤으로 생성이 되고 패스워드는 해시되어있다.
- 아이디 검증로직을 우회하는 방법의 힌트는 비교연산자(==)이다.
- php에서 == 는 느슨한 비교연산자이다.
- C나 java에서 사용하는 == 연산자와 다르다.
- C나 java에서 사용하는 == 처럼 데이터 형식까지 비교하는 연산자는 php에서 엄격한 비교 (===)이다.
- 느슨한 비교의 특징은 자동으로 형변환을 해준다.
if ((int)$input_id == $id && strlen($input_id) === 10)
- 여기서 $input_id를 int으로 형변환하여 비교하고 $id는 그에 맞춰 자동으로 int형으로 형변환 해준다.
- int로 형변환 할때 숫자로 시작하지 않는다면 0으로 변환된다. ex) abcdefg ⇒ 0
- 숫자로 시작한다면 숫자가 아닌 문자가 나올때까지 변환된다. ex) 01234abc ⇒ 01234
- 만약 랜덤으로 생성된 아이디가 숫자가 아닌 문자로 시작된다면 0이고 글자가 10개로 제한이 되어있기 때문에 “000000000000” 를 입력한다. (int)”0000000000” ⇒ 0
- 비밀번호는 sha(”1”)를 해시하고 8자리를 가져오면 된다.
- 해시값 356a192b7913b04c54574d18c28d46e6395428ab
- 해시값 8자리 356a192b
- 또는 아이디 우회를 한 것처럼 “356’문자열5자리’”도 가능
결과

