Gremlin 문제와 문제 풀이는 같으므로, 현재 코드 상에서 문제점 설명과 방어 방법을 설명하겠다.

 

include "./config.php";
login_chk();
$db = dbconnect();

DB 연결에 필요한 정보와 로그인이 되었는지 확인하는 함수, DB 연결하는 코드이다.

 

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 ~_~");

GET 메소드로 id와 pw를 받고 있다.
또한 입력받은 값은 prob, _, ., ()이라는 문자열이 들어있으면, No Hack ~_~을 출력하고 종료한다.

 

$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>"; 

쿼리문 select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')를 살펴보면 Gremlin 문제와 다른 점이 있다. pw가 md5 해시로 변환되어 where절에 들어가는 것이다.

 

그 후 Mysql에 쿼리문을 전달하여 나온 결과가 id가 admin이면 문제가 풀리게 된다.

 

Greamlin 문제와 같은 문제라고 봐도 무관할 것 같다.

Greamlin의 문제풀이와 같은 것을 알 수 있다.

 

취약점의 원인을 찾아보면, 입력값에 대한 검증 부족에 있다.

 

입력값에 대한 검증

  • SQL에 사용되는 특수문자, 키워드를 검증에 추가하여 사용을 못하도록 해야한다.
  • id와 pw의 입력 검증을 해줘야 한다. id와 pw를 두 개를 받는다고 취약점이 없어지는 건 아니지만, 몇가지의 공격방법은 없어지게 된다.
복사했습니다!