티스토리 뷰

보안/Wargame

[Lord of SQLi] cobolt Writeup/문제 풀이

돔돔이부하 2021. 5. 10. 03:53
728x90
반응형

$_GET[id]
$_GET[pw]

PHP 소스코드 상으로는 아이디와 패스워드를 GET parameter 방식으로 받는다고 한다.

 

 if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
 if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");

그리고 아이디와 패스워드 모두에 prob 라는 단어가 포함되어 있거나, _(언더바), .(온점), ((여는 괄호), )(닫는 괄호) 를 사용하는 것을 금지하고 있다.

 

$query = "select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')"; 
echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
$result = @mysqli_fetch_array(mysqli_query($db,$query)); 
if($result['id'] == 'admin') solve("cobolt");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>"; 

query 변수에 GET parameter로 전달 받은 아이디와 패스워드를 넣고, mysql에 query를 실행해봤을 때 결과로부터 id가 'admin' 일 때 문제는 해결이 된다.

 

이 문제를 해결할 수 있는 방법은 여러 방법이 있겠지만, 내가 생각한 방법은 아래와 같다.

첫 번째, 실제로 데이터베이스 테이블(prob_cobolt)에 존재하는 관리자 admin의 비밀번호를 알고 있거나 강제 bruteforce로 알아냈을 경우

두 번째, id의 결과값을 admin 으로 만드는 경우

 

그리고 당연히 첫 번째는 많은 노력이 들어가니 포기하고, 두번째 방법으로 문제를 풀었다.

 

select id from table where id='' union select 'admin';

위 구문은 where 조건에 맞는 id를 table에서 찾는 query 구문이다. 그리고 바로 뒤에 나오는 union 구문 절에서 select 'admin'은 admin 이라는 문자열을 문자열 그대로 출력하는 query 구문이다.

 

그렇기 때문에 만약에 id가 ''(공백)인 record가 존재하지 않을 경우 결과는 해보면 알겠지만, 'admin'만 나오게 된다.

이 원리를 이용해서, 해당 문제를 풀 수 있다.

 

https://los.rubiya.kr/chall/cobolt_2.php?id=' union select 'admin'%23

URL 파라미터는 위와 같이 입력해주면 된다. %23은 URL 디코딩하면 # 이다. URL에서 #를 인코딩안하고 넣게 되면, 브라우저는 id를 가리키는 hash tag로 해석하기 때문에 반드시 인코딩 해줘야 한다. 작은 따옴표는 브라우저에서 알아서 URL 인코딩 해준다.

 

 

그럼 위와 같이 문제를 풀 수 있게 된다. 위 방법 말고도 수많은 다양한 방법으로 문제를 해결할 수 있다. 다양한 방법으로 다양한 문제풀이를 해보는 것도 좋을 것 같다.

 

 

- 끝 -

728x90
반응형
댓글