호빵둥이 IT Blog

Webhacking.kr 7번 풀이 :: 호빵둥이 IT Blog 본문

프로그래밍/[워게임]Webhacking.kr

Webhacking.kr 7번 풀이 :: 호빵둥이 IT Blog

d2n0s4ur 2020. 5. 17. 20:00

 

 

 

 

안녕하세요!

 

오늘은 워게임, Webhacking.kr Chellenge 7번 문제를 풀어보도록 하겠습니다.

 

이번 문제는 SQL 인젝션을 사용한 문제입니다.

 

 

#문제 보기


 

https://webhacking.kr/challenge/web-07/index.php?val=1

 

Challenge 7

 

webhacking.kr

 

 

7번 문제에 먼저 접속해보도록 하겠습니다.

 

 

https://webhacking.kr/challenge/web-07/index.php?val=1에 접속한 모습

 

 

문제에 접속하면, Admin page라고 나옵니다. 한번 auth 버튼을 클릭해봅시다.

 

 

Access_Denied! 라고 뜨는 모습

 

 

일단 바로 접속을 거부당했습니다.

 

그러면 view-seource를 통해 소스코드를 보고, 분석해보겠습니다.

 

 

 

 

 

#소스코드 분석하기


 

https://webhacking.kr/challenge/web-07/?view_source=1

 

https://webhacking.kr/challenge/web-07/?view_source=1

 

webhacking.kr

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php
  include "../../config.php";
  if($_GET['view_source']) view_source();
?><html>
<head>
<title>Challenge 7</title>
</head>
<body>
<?php
$go=$_GET['val'];
if(!$go) { echo("<meta http-equiv=refresh content=0;url=index.php?val=1>"); }
echo("<html><head><title>admin page</title></head><body bgcolor='black'><font size=2 color=gray><b><h3>Admin page</h3></b><p>");
if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!");
$db = dbconnect();
$rand=rand(1,5);
if($rand==1){
  $result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");
}
if($rand==2){
  $result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!");
}
if($rand==3){
  $result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!");
}
if($rand==4){
  $result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!");
}
if($rand==5){
  $result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!");
}
$data=mysqli_fetch_array($result);
if(!$data[0]) { echo("query error"); exit(); }
if($data[0]==1){
  echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Access_Denied!')\"><p>");
}
elseif($data[0]==2){
  echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Hello admin')\"><p>");
  solve(7);
}
?>
<a href=./?view_source=1>view-source</a>
</body>
</html>
cs

 

 

과연 어떤 의미를 가지고 있는지, 분해해서 살펴보도록 하겠습니다.

 

 

1
2
3
4
5
6
7
8
... 생략 ...
<?php
$go=$_GET['val'];
if(!$go) { echo("<meta http-equiv=refresh content=0;url=index.php?val=1>"); }
echo("<html><head><title>admin page</title></head><body bgcolor='black'><font size=2 color=gray><b><h3>Admin page</h3></b><p>");
if(preg_match("/2|-|\+|from|_|=|\\s|\*|\//i",$go)) exit("Access Denied!");
 
...
cs

 

 

우선, 3번 째 줄에서 val 값을 파라미터 형식으로 불러와 $go에 저장합니다.

 

4번째 줄에서 $go가 false 즉, 존재하지 않거나 0이면 바로 https://webhacking.kr/challenge/web-07/index.php?val=1 로 불러와지게 하는 구문입니다.

 

5번째 줄은 처음 접속 페이지의 윗부분을 나타내게 하는 구문입니다.

 

6번째 줄에서 $go와 관련되서 특정 문자가 있는지 검사합니다. 위 식은 2, -, +, from, _, =, \s, *, \ , 공백이 있으면 접속이 안되게 해주는 구문입니다.

 

 


"/2|-|\+|from|_|=|\\s|\*|\//i"와 같이 써져있는 식을 정규식이라고 합니다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
...
 
$db = dbconnect();
$rand=rand(1,5);
if($rand==1){
  $result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");
}
if($rand==2){
  $result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!");
}
if($rand==3){
  $result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!");
}
if($rand==4){
  $result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!");
}
if($rand==5){
  $result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!");
}
$data=mysqli_fetch_array($result);
if(!$data[0]) { echo("query error"); exit(); }
if($data[0]==1){
  echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Access_Denied!')\"><p>");
}
elseif($data[0]==2){
  echo("<input type=button style=border:0;bgcolor='gray' value='auth' onclick=\"alert('Hello admin')\"><p>");
  solve(7);
}
 
...
?>
cs

 

 

4번째 줄에서 DB에 연결을 하고,

 

5 ~ 20번째 줄에서 랜덤으로 DB에 select lv from chall7 where lv =($go) 명령문을 보냅니다.

 

이때 1 ~ 5개의 괄호가 $go 곁에 감싸이게 됩니다.

 

만약 이 쿼리를 실행시키지 못하면(괄호 오류) nice try!라고 alert가 뜨게 되고,

 

만약 값이 있다면, 20 ~ 29번째 줄에서 값에 따라 분류합니다.

 

val = 0이거나 false이면 query error를 echo 하고

 

val = 1이면 Access_denied를,

 

val = 2이면 문제가 풀리는 구조입니다.

 

즉, 이 정규식을 우회해서 val = 2를 넣어주면 됩니다.

 

 

 

 

 

 

 

#문제 풀기


 

먼저, 쿼리에 괄호가 1개 있다고 가정해보겠습니다.

 

 


select lv from chall7 where lv =($go)


 

 

 

그러면 이런 형식이 될 텐데, 우리는 val에 2 값을 넣어야 합니다.

 

2를 우회하기 위해서 5%3을 한번 넣어보겠습니다.

 

$go = 5%3을 넣어봅시다.

 

(% 는 나눗셈의 나머지 기호로 5%3은 5를 3으로 나눈 나머지인 2를 의미합니다)

 

 

 

https://webhacking.kr/challenge/web-07/index.php?val=5%3

 

Challenge 7

 

webhacking.kr

 

 

 

그러면,

 

 

 

query error가 발생한 모습

 

 

 

query error가 발생했습니다.

 

이 방법은 힘들 것 같군요.

 

아마도 5%3을 문자로 인식해서 그런 것 같습니다.

 

그러면 다른 방법을 사용해보도록 하겠습니다. 예전 포스팅 때 잠깐 언급했지만, SQL 명령어 중 하나인 UNION을 사용하겠습니다.

 

UNION은 합집합의 개념으로 두 조건중 하나를 만족하는 모든 데이터를 가져올 때 사용합니다.

 

예를 들어 val = 99999이고 val = 2인 경우를 모두 가져올 수 있는 것입니다.

 

val = 0, 1 인 경우는 소스코드에서 이미 걸러졌기 때문에 이를 이용하면 문제가 풀리지 않을 수도 있습니다.

 

val에 없을 것 같은 숫자를 넣어주겠습니다.

 

$go = 999999999999999)UNION(SELECT(5%3)로 써보도록 하겠습니다. 이렇게 되면,

 

 

 


select lv from chall7 where lv =(999999999999999)UNION(SELECT(5%3))


 

 

lv = 999999999999999 이거나 2인 경우를 찾을 수 있습니다.

 

SQL 문법에서 원래 각 단어마다 공백을 넣어 구분해줘야 하지만, 이렇게 괄호를 넣게 되면 공백과 같은 효과를 낼 수 있습니다.

 

여기서 999999999999999와 SELECT(5%3)이 같은 등호(=)로 묶이게 되는 것입니다.

 

이제 이 값을 URL에 넣고 F5를 눌러주면,

 

 

https://webhacking.kr/challenge/web-07/index.php?val=999999999999999)UNION(SELECT(5%3)

 

Challenge 7

 

webhacking.kr

 

 

 

 

풀 수 있습니다!

(최초로 풀었을 때 캡처를 못했네요.. 죄송합니다 ㅠ)

 

 

 

 

 

 

 

#연관된 활동


 

앞서 소스코드 분석할 때 '정규식'이라는 단어를 언급했습니다.

 

정규식이란, 정규표현식이라고도 하며, 어떤 규칙을 가지는 문자열을 구분하는데 쓰이는 형식 언어입니다.

 

PHP 말고도 JAVA, Javascript, Python 등 많은 프로그래밍 언어에서 사용됩니다.

 

정규표현식은 규칙만 알면, 표현하기가 매우 쉬워서 많은 곳에서 사용됩니다.

 

예를 들어서 휴대폰 전화번호 형식의 데이터를 입력받을 때 IF문을 사용한다면 굉장히 길어질 수 있지만,

 

정규식을 활용하면 매우 간단하게 표현할 수 있습니다.

 

이러한 정규표현식 규칙은 미리 알고 있는 것이 좋습니다.

 

제가 공부하는데 활용한 정규표현식 관련 docs 링크를 남겨드리겠습니다. 꼭 한 번씩 읽어보시기 바랍니다.

 

 

 

 


https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D

 

정규 표현식

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,��

developer.mozilla.org


 

 

 

 

이상으로 Webhacking.kr 7번 문제 풀이를 마치겠습니다.

 

감사합니다!

 

 

 

 

 

 

 

포스트 잘 보셨다면 하단에 ♡ 꼭 눌러주시길 부탁드립니다!

(♡ 는 블로거에게 큰 힘이 됩니다)

 

 

 

 

 

[이전글] : 2020/05/16 - [프로그래밍/[워게임]Webhacking.kr] - Webhacking.kr 6번 풀이 :: 호빵둥이 IT Blog

[다음글] : 2020/05/18 - [프로그래밍/[워게임]Webhacking.kr] - Webhacking.kr 8번 풀이 :: 호빵둥이 IT Blog

 

Comments