[webhacking.kr] 50번 문제 풀이[SQL Injection]
💡 Webhacking.kr challenge(old) 50번 문제에 대한 풀이입니다.
문제
<?php
if($_GET['id'] && $_GET['pw']){
$db = dbconnect();
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$_GET['id'] = mb_convert_encoding($_GET['id'],'utf-8','euc-kr');
foreach($_GET as $ck) if(preg_match("/from|pw|\(|\)| |%|=|>|</i",$ck)) exit();
if(preg_match("/union/i",$_GET['id'])) exit();
$result = mysqli_fetch_array(mysqli_query($db,"select lv from chall50 where id='{$_GET['id']}' and pw=md5('{$_GET['pw']}')"));
if($result){
if($result['lv']==1) echo("level : 1<br><br>");
if($result['lv']==2) echo("level : 2<br><br>");
}
if($result['lv']=="3") solve(50);
if(!$result) echo("Wrong");
}
?>
문제 풀이
injection을 해야하는 sql 문 부터 보면 다음과 같습니다.
select lv from chall50 where id='{}' and pw=md5('{}')
우선 GET[‘id’]의 경우 addslashes() 함수 이후에 mb_convert_encoding함수를 사용하여 UTF-8로 인코딩을 바꿔줬기 때문에 multibyte encoding을 이용하여 addslashes() 함수를 우회할 수 있습니다. 이를 이용해서 id에 익젝션을 수행할 쿼리문을 작성합니다.
id=%aa' or lv=3--%20
쿼리문에서 문제에서 preg_match로 필터링 하는 문자를 우회하도록 바꿔줍니다.
공백 -> %09 , = -> like
id=%aa'%09or%09lv%09like%093--%09
쿼리문을 수행해 봤더니 다음과 같이 안됩니다.
혹시 테이블에 lv=3인 데이터가 없는지 확인해 보기 위해서 like 3 을 like 2로 바꿔서 해봤더니 like 2 는 성공적으로 수행됩니다.
즉, 테이블에 lv = 2인 데이터는 있기 때문에 나온 것이고 lv=3인 데이터는 없기 때문에 안나온 것입니다.
테이블에 데이터가 없기 때문에 union select 구문을 이용해야 합니다.
하지만 이번 문제에서 가장 까다로운 조건이 하나 붙어 있었습니다. 다음 조건 때문에 id에는 union을 사용할 수 없었습니다.
if(preg_match("/union/i",$_GET['id'])) exit();
그렇기 때문에 pw를 통해서 union select 구문을 수행시켜야 합니다.
이번 문제를 풀기위한 아이디어는 주석을 사용하는 것입니다. 다음과 같이 id 와 pw 사이에 /* */
를 끼워 넣습니다.
select lv from chall50 where id='%aa'/* and pw=md5('*/')
그러면 pw 쪽에서 '
가 지워지기 때문에 쿼리문을 작성할 수 있습니다.
- id : %aa’/*
- pw : */union%09select%093%23
위와 같이 쿼리문을 만들어서 서버로 전송하면 다음과 같이 문제가 클리어 됩니다.
댓글남기기