webhacking/sql, sql injection

webhacking.kr 7번

qkqhxla1 2014. 8. 19. 16:08

<?
$answer 
"????";

$go=$_GET[val];

if(!
$go) { echo("<meta http-equiv=refresh content=0;url=index.php?val=1>"); }

$ck=$go;

$ck=str_replace("*","",$ck);
$ck=str_replace("/","",$ck);


echo(
"<html><head><title>admin page</title></head><body bgcolor='black'><font size=2 color=gray><b><h3>Admin page</h3></b><p>");


if(
eregi("--|2|50|\+|substring|from|infor|mation|lv|%20|=|!|<>|sysM|and|or|table|column",$ck)) exit("Access Denied!");

if(
eregi(' ',$ck)) { echo('cannot use space'); exit(); }

$rand=rand(1,5);

if(
$rand==1)
{
$result=@mysql_query("select lv from lv1 where lv=($go)") or die("nice try!");
}

if(
$rand==2)
{
$result=@mysql_query("select lv from lv1 where lv=(($go))") or die("nice try!");
}

if(
$rand==3)
{
$result=@mysql_query("select lv from lv1 where lv=((($go)))") or die("nice try!");
}

if(
$rand==4)
{
$result=@mysql_query("select lv from lv1 where lv=(((($go))))") or die("nice try!");
}

if(
$rand==5)
{
$result=@mysql_query("select lv from lv1 where lv=((((($go)))))") or die("nice try!");
}

$data=mysql_fetch_array($result);
if(!
$data[0]) { echo("query error"); exit(); }
if(
$data[0]!=&& $data[0]!=2) { exit(); }


if(
$data[0]==1)
{
echo(
"<input type=button style=border:0;bgcolor='gray' value='auth' onclick=
alert('Access_Denied!')><p>"
);
echo(
"<!-- admin mode : val=2 -->");
}

if(
$data[0]==2)
{
echo(
"<input type=button style=border:0;bgcolor='gray' value='auth' onclick=
alert('Congratulation')><p>"
);
@
solve();

소스 해석.

$go=$_GET[val]; 로 GET방식으로 val이란값을 가져와서

$ck=$go; 로 ck변수에 go변수값 대입.

여러 필터링을 거친 후에

$rand=rand(1,5); 로 1~5사이의 수를 뽑은 후 하나의 쿼리를 실행함.

쿼리 실행 후 값이 안나오면 query error!를 출력하고 1이나 2의 값이 아니어도 그냥 빠져나감.

결과가 1이면 Access_Denied!를 출력하고 빠져나옴. 결과가 2이면 통과.

쿼리 하나만 잡고 분석해보면. "select lv from lv1 where lv=($go)" .

db에 2는 없고 union으로 2를 만들라고 아예 문제에 나와있음.

참고로 union절은.

좌측 칼럼수와 union 으로 연결된 칼럼수가 일치.

좌측 결과값의 데이터형과 우측 데이터형이 일치

좌측의 select문제 order by같은 정렬 사용하면 안됨.

등의 규칙이 있고, 솔직히 이게 맞나...? 하시는 분들은 mysql에 직접 똑같은 테이블을 만들어서 

해보는걸 추천.


이고 데이터 출력시 2만 나오게하려면 원래 결과값인 1은 안나와야되므로 0또는 2로 해야

제대로 만들어짐.




"select lv from lv1 where lv=(0) union select (2)"

처럼 만들면 될거같은데 2와 스페이스바가 필터링되어있다는 문제가 있음.

필터링 우회하면 "select lv from lv1 where lv=(0)%0aunion%0aselect%0a(3-1)"

로 스페이스바는 %0a로, 2는 3-1과 같으므로 우회 가능

그런데 소스를 다시 살펴보면 랜덤함수로 1~5사이를 뽑으므로 될때까지 계속 요청 보내면 됨.

'webhacking > sql, sql injection' 카테고리의 다른 글

숫자 뽑아오기.  (0) 2014.08.19
webhacking.kr 7번 소스코드  (0) 2014.08.19
rubiya님의 문서  (2) 2014.08.15
webhacking.kr 2번  (0) 2014.08.11
webhacking.kr 8번  (0) 2014.08.10