old-35 시작화면이다. phone number를 입력받는 form 하나가 있다.
view-source를 눌러 소스코드를 확인해보자.
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 35</title>
<head>
<body>
<form method=get action=index.php>
phone : <input name=phone size=11 style=width:200px>
<input name=id type=hidden value=guest>
<input type=submit value='add'>
</form>
<?php
$db = dbconnect();
if($_GET['phone'] && $_GET['id']){
if(preg_match("/\*|\/|=|select|-|#|;/i",$_GET['phone'])) exit("no hack");
if(strlen($_GET['id']) > 5) exit("no hack");
if(preg_match("/admin/i",$_GET['id'])) exit("you are not admin");
mysqli_query($db,"insert into chall35(id,ip,phone) values('{$_GET['id']}','{$_SERVER['REMOTE_ADDR']}',{$_GET['phone']})") or die("query error");
echo "Done<br>";
}
$isAdmin = mysqli_fetch_array(mysqli_query($db,"select ip from chall35 where id='admin' and ip='{$_SERVER['REMOTE_ADDR']}'"));
if($isAdmin['ip'] == $_SERVER['REMOTE_ADDR']){
solve(35);
mysqli_query($db,"delete from chall35");
}
$phone_list = mysqli_query($db,"select * from chall35 where ip='{$_SERVER['REMOTE_ADDR']}'");
echo "<!--\n";
while($r = mysqli_fetch_array($phone_list)){
echo htmlentities($r['id'])." - ".$r['phone']."\n";
}
echo "-->\n";
?>
<br><a href=?view_source=1>view-source</a>
</body>
</html>
if($_GET['phone'] && $_GET['id'])
→ phone과 id파라미터가 존재해야 한다.
if(preg_match("/\*|\/|=|select|-|#|;/i",$_GET['phone'])) exit("no hack");
→ phone파라미터는 *, /, =, select, -, #, ; 문자가 필터링된다.
if(strlen($_GET['id']) > 5) exit("no hack");
→ 문자열의 길이가 5를 넘으면 안된다.
if(preg_match("/admin/i",$_GET['id'])) exit("you are not admin");
→ id 파라미터에서 "admin" 문자열이 필터링된다.
mysqli_query($db,"insert into chall35(id,ip,phone) values('{$_GET['id']}','{$_SERVER['REMOTE_ADDR']}',{$_GET['phone']})") or die("query error");
→ id와 phone파라미터를 바탕으로 DB에 새 데이터를 추가한다.
$isAdmin = mysqli_fetch_array(mysqli_query($db,"select ip from chall35 where id='admin' and ip='{$_SERVER['REMOTE_ADDR']}'"));
if($isAdmin['ip'] == $_SERVER['REMOTE_ADDR']){
solve(35);
mysqli_query($db,"delete from chall35");
}
→ DB에 admin계정을 불러와서 검증 후 solve하는 과정이다.
위 조건과 결합해서 봤을 때 직접 DB에 admin을 생성하고 불러오는 문제인 것 같다.
이제 id가 admin인 데이터를 DB에 생성해보자.
id 파라미터에서는 admin이 필터링되므로 phone 파라미터에서 Injection을 시도해봤다.
MySQL의 경우 데이터를 insert할 때 ','로 구분해서 입력값을 여러 개 전달할 수 있다.
ex) insert into chall35(id, ip, phone) values('guest', '127.0.0.7', 1111), ('admin', '127.0.0.1', 1111)
이 점을 이용해서 phone 파라미터에 1), ('admin', {내 IP}, 1111을 Injection해보자.
old-35 해결!
'Study > Web Hacking' 카테고리의 다른 글
[Webhacking.kr] old-53 (0) | 2021.10.09 |
---|---|
[Webhacking.kr] old-49 (0) | 2021.10.09 |
[Webhacking.kr] old-11 (0) | 2021.09.29 |
[Webhacking.kr] old-46 (0) | 2021.09.25 |
[Webhacking.kr] old-45 (0) | 2021.09.25 |