d0r1

[webhacking] old-18 본문

webhacking

[webhacking] old-18

d0r1 2023. 5. 23. 14:08
<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 18</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
input { background:silver; }
a { color:lightgreen; }
</style>
</head>
<body>
<br><br>
<center><h1>SQL INJECTION</h1>
<form method=get action=index.php>
<table border=0 align=center cellpadding=10 cellspacing=0>
<tr><td><input type=text name=no></td><td><input type=submit></td></tr>
</table>
</form>
<a style=background:gray;color:black;width:100;font-size:9pt;><b>RESULT</b><br>
<?php
if($_GET['no']){
  $db = dbconnect();
  if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");
  $result = mysqli_fetch_array(mysqli_query($db,"select id from chall18 where id='guest' and no=$_GET[no]")); // admin's no = 2

  if($result['id']=="guest") echo "hi guest";
  if($result['id']=="admin"){
    solve(18);
    echo "hi admin!";
  }
}
?>
</a>
<br><br><a href=?view_source=1>view-source</a>
</center>
</body>
</html>

 

제시된 코드는 다음과 같다.

no을 GET 방식을 통해 받고, 이는 preg_match를 통해 필터링을 한 다음, $result를 통해 전달된다.

이 값이 admin이면 solve()가 된다.

 

그럼 이 문제를 풀어보기 위해 사이트 접속을 우선 해보자.

다음과 같은 사이트가 존재하고, view-source를 하면, 앞서 제시한 코드를 확인할 수 있다.

이 다음, textarea에 값을 넣고, 제출을 하여 풀 수 있다고 보인다.

 

--- 시나리오 ---

(1) textarea에 2가 전달이 되면, admin이 되기에 이를 통해 풀 수 있을거 같다.

(1)-1 sql 구문이 select ~~ where id="guest" and no="" 이기에 2를 넣으면 앞선 구문에 의해 reject될 가능성이 높다. 이를 해결하기 위해 sqli 기초 구문을 통해 우회를 시도할 수 있다.

 

해당 시나리오를 기반으로 시도해보자.

 

우선, select 구문을 만족시키는 no = 1을 우선적으로 시도해보자.

(기반) no=1(guest), no=2(admin)

1을 넣었더니, id=guest, no=1 이라서 hi guest가 나오는 것을 확인할 수 있다.

그럼 2를 넣으면?

앞선 구문이 참이 되지 않았기 때문에, 실패하는 모습을 볼 수 있다.

그럼, 2를 만족시키기 위해, 어떻게 해야할지 생각해보자

sql구문은 A and B 의 구문이 false가 되면 다음 구문에서 비교를 한다.

즉, and 다음 or 구문을 통해 값을 넣어 줄 수 있다.

select ~ where id="guest" and no=2 or no=2를 통해, admin임을 확인할 수 있을 것이다.

했더니, no hack이 뜬다. 즉, 필터링에 의해 막혔음을 확인할 수 있다.

해당 부분이 왜 막히는지 위의 필터링 구문을 확인해보자.

 if(preg_match("/ |\/|\(|\)|\||&|select|from|0x/i",$_GET['no'])) exit("no hack");

 

이 부분에서 막히는 것인데, 여기서 공백을 필터링 하고 있기 때문에, 공백을 우회하는 방법이 필요하다.

이는 url encoding을 사용해서 우회할 수 있다.

url encoding에서 공백은 %20 이다.

즉, 2%20or%20no=2 를 통해 풀 수 있다.

또한, 이는 GET 방식으로 받기 때문에, url의 파라미터를 조작하여 공격할 수 있다.

url을 그럼 수정해보자.

 

https://webhacking.kr/challenge/web-32/index.php?no=2%20or%20no=2

 

Challenge 18

 

webhacking.kr

그러나, 필터링 되었다. 그럼 공백을 스페이스가 아닌 다른 방법을 사용해야 할 거 같다.

이는, tap(탭)으로 교체할 수 있다.

탭은 %09이므로, 이걸 사용해보자.

'webhacking' 카테고리의 다른 글

[webhacking.kr] old-36  (0) 2023.08.29
[webhacking.kr] old-10  (0) 2023.08.29
webhacking 34  (0) 2023.07.19
webhacking 32  (0) 2023.07.19
webhacking 14  (0) 2023.07.19