<html>
<head>
<title>Challenge 8</title>
<style type="text/css">
body { background:black; color:white; font-size:10pt; }
</style>
</head>
<body>
<br><br>
<center>USER-AGENT

<?
$agent=getenv("HTTP_USER_AGENT");
$ip=$_SERVER[REMOTE_ADDR];

$agent=trim($agent);
$agent=str_replace(".","_",$agent);
$agent=str_replace("/","_",$agent);

$pat="/\/|\*|union|char|ascii|select|out|infor|schema|columns|sub|-|\+|\||!|update|del|drop|from|where|order|by|asc|desc|lv|board|\([0-9]|sys|pass|\.|like|and|\'\'|sub/";

$agent=strtolower($agent);

if(preg_match($pat,$agent)) exit("Access Denied!");

$_SERVER[HTTP_USER_AGENT]=str_replace("'","",$_SERVER[HTTP_USER_AGENT]);
$_SERVER[HTTP_USER_AGENT]=str_replace("\"","",$_SERVER[HTTP_USER_AGENT]);

$count_ck=@mysql_fetch_array(mysql_query("select count(id) from lv0"));
if($count_ck[0]>=70) { @mysql_query("delete from lv0"); }


$q=@mysql_query("select id from lv0 where agent='$_SERVER[HTTP_USER_AGENT]'");

$ck=@mysql_fetch_array($q);

if($ck)
{ 
echo("hi <b>$ck[0]</b><p>");
if($ck[0]=="admin")

{
@solve();
@mysql_query("delete from lv0");
}


}

if(!$ck)
{
$q=@mysql_query("insert into lv0(agent,ip,id) values('$agent','$ip','guest')") or die("query error");
echo("<br><br>done!  ($count_ck[0]/70)");
}


?>

<!--

index.phps

-->

</body>
</html>






USER-AGENT 값을 trim 함수로 \t(탭), \n(개행), \r(캐리지리턴), \0(NULL), \x0b(수직탭) 문자가 포함되었을 경우

제거한다.


# $_SERVER['HTTP_USER_AGENT'] 치환


. -> _

/ -> _


# 필터문자

/

*

union
char
ascii
select
out
infor
schema
columns
sub
-
+
|
!
update
del
drop
from
where
order
by
asc
desc
lv
borad
0~9 숫자
sys
pass
.
like
and
''
sub


$_SERVER[HTTP_USER_AGENT]=str_replace("'","",$_SERVER[HTTP_USER_AGENT]);

$_SERVER[HTTP_USER_AGENT]=str_replace("\"","",$_SERVER[HTTP_USER_AGENT]);

//필터 처리를 마친후 다시 USER_AGENT 를 가져와서 싱글쿼터, \" 를 없앤다.



$count_ck=mysql_fetch_array(mysql_query("select count(id) from lv0"));

if($count_ck[0]>=70) { @mysql_query("delete from lv0"); }

lv0 테이블에 id 개수가 70이상이면 lv0 테이블을 삭제,



id 개수가 70 미만이면 

SELECT id FROM lv0 WHERE agent='$_SERVER["HTTP_USER_AGENT"]'; 쿼리를 보낸다.



HTTP_USER_AGENT에 해당하는 id를 가져오고 해당 id 값이 admin이면 solve() 함수 호출.

쿼리 후 반환 레코드가 없으면 INSERT INTO lv0 (blah blah) 쿼리로 데이터 추가한다.




# 문제 풀이



우선 lv0 테이블에는 agent, ip, id 칼럼이 존재한다.

처음에 문제를 잘못봤다. 데이터 삽입 쿼리에 $agent가 들어가는데 $_SERVER['HTTP_USER_AGENT'] 값이 들어가는 줄 알고

어떻게 레코드를 삽입하지? 싱글쿼터도 먹혔는데 ... 하고 한참 고민하다가 뒤늦게 $agent 값으로 들어간다는걸 알게됐다....



HTTP REQUEST HEADER user-agent 값에 aaaa','192.168.10.10','admin'),('bbbb 라고 입력하면된다.

그러면 INSERT INTO lv0 (agent, ip, id) VALUES ('aaaa','192.168.10.10','admin'),('bbbb', '192.168.10.10','guest') 같이 입력이 돼서

2개 레코드가 한방에 lv0 테이블에 삽입된다.


그후 HTTP REQUEST HEADER user-agent에 aaaa라고 입력해서 서버로 요청을 보내면 

select id from lv0 where agent='aaaa' 쿼리를 처리하게 되고 agent가 aaaa인 레코드의 id 값은 admin 이므로 solve()함수가 호출된다.



+ Recent posts