문제 정보
https://webhacking.kr/challenge/web-12/
풀이
문제에 접속하면 SQL Injection 문제라는 걸 알려준다.
소스 코드는 아래와 같다.
여기서 preg_match에 의해 필터링되는 키워드들은 #, select, (, 공백, limit, =, 0x 이다.
no의 파라미터 값은 "select id from chall27 where id='geust' and no= (no파라미터값) 에 들어가고 id가 admin이면 solve이다.
하나 더 살펴보아야 할 것은 admin 소스 코드 뒤에 admin의 no 값은 2라고 주석으로 되어있는 것이다.
<?php
include "../../config.php";
if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 27</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get action=index.php>
<input type=text name=no><input type=submit>
</form>
<?php
if($_GET['no']){
$db = dbconnect();
if(preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no'])) exit("no hack");
$r=mysqli_fetch_array(mysqli_query($db,"select id from chall27 where id='guest' and no=({$_GET['no']})")) or die("query error");
if($r['id']=="guest") echo("guest");
if($r['id']=="admin") solve(27); // admin's no = 2
}
?>
<br><a href=?view_source=1>view-source</a>
</body>
</html>
요청되는 쿼리를 잘 살펴보면 no로 받아오는 값이 괄호에 둘러싸여 있어 괄호와 공백을 둘 다 우회하고 or no=2를 추가해서 admin으로 요청해야 한다.
내가 생각한 쿼리는 다음과 같다. 일단 요청되면 뒤에 )의 문자가 또 있으므로 주석을 무조건 작성해야 한다고 생각했다. 또한 guest이면서 no가 9999는 아닐 것이라 예상하고 admin의 no가 2이고, =의 문자도 필터링 되어 있기 때문에 like로 우회할 수 있다. 또한 가장 중요한 건 공백을 우회해야 하다.
9999)or no like 2;%00
최종적으로 내가 작성한 코드는 아래와 같다.
일단 이 입력폼에 작성하면 GET 방식으로 요청되는 중간 URL 인코딩이 한 번 더 거쳐지는 것 같다. 그래서 이를 아예 URL 인코딩을 적용해서 URL에 입력해주는 방식으로 해결하였다. 마지막 주석은 ;를 인코딩하면 주석이 안되니 주의하자.
9999%29or%0dno%0dlike%0d2;%00
'Web Hacking > webhacking.kr 풀이' 카테고리의 다른 글
old-25 write-up (0) | 2024.01.11 |
---|---|
old-47 write-up (0) | 2024.01.11 |
old-19 write-up (0) | 2024.01.11 |
old-32 write-up (0) | 2024.01.10 |
old-06 write-up (0) | 2024.01.10 |