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

이번 포스트는 assassin에 이어 zombie_assassin 문제에 대한 이해와 풀이를 진행해보도록 하겠습니다.

zombie_assassin은 단순 필터링 우회문제이지만, 함수의 취약점을 잘 이해해야 풀 수 있는 문제입니다.



 

 문제 이해


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

<?php 
  include "./config.php"; 
  login_chk(); 
  dbconnect(); 
  if(preg_match('/\\\|prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); 
  if(preg_match('/\\\|prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(@ereg("'",$_GET[id])) exit("HeHe"); 
  if(@ereg("'",$_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_zombie_assassin 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("zombie_assassin"); 
  highlight_file(__FILE__); 
?>


위의 문제에서 7번과 8번 라인에서 id와 pw로 받은 데이터 중 싱글쿼터를 필터링합니다.

여기서 취약한 함수인 ereg 함수를 사용하였는데, 이 함수는 두 가지 취약점을 가지고 있습니다. 


첫 번째로는 대소문자를 구분한 상태로 데이터를 비교하여 검색한다는 점.

두 번째로는 Null문자를 넣으면 더 이상 문자열을 검사하지 않고 넘어간다는 취약점입니다.


첫 번째 취약점은 troll 문제에서 다뤄봤습니다.

[LOS - Lord Of SQL] Level 08 - troll 링크


두 번째 취약점은 이번 문제에서 다뤄보도록 하겠습니다.



 

 문제 풀이(쿼리)


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



 

 id 값 삽입(%00 + 싱글쿼터 + 주석)


이 문제에서는 싱글쿼터가 ereg 함수에 의해 필터링되지 않도록 하는 것이 핵심입니다. 즉, 필터링이 되지 않도록 하려면 다음과 같은 취약점을 이용해야 합니다.


$result = ereg('abcd', $_GET[id])을 실행할 때 문자열 'abcd' 값이 있는지 검사하게 됩니다.

만약 id에 다음과 같은 값이 들어갔다고 가정해봅시다.


id=ab%00cd


위와 같이 값을 입력하게 되면 NULL문자는 크게 의미가 없기 때문에 abcd로 인식될 것 같지만, NULL문자는 문자열의 끝을 나타내주는 값입니다. 따라서 ereg함수는 ab라는 값만 입력되었다고 인식하게 됩니다.

이렇게 abcd와 일치하지 않다고 판단하게 되기 때문에 필터링이 되지 않게 됩니다.


이 원리를 이용하면 싱글쿼터 앞에 %00 즉, NULL 문자를 입력하게 되면 싱글쿼터를 입력하더라도 인지하지 못하게 됩니다.


따라서 쿼리는 다음과 같이 만들 수 있습니다.

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


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

여기서 id 값에는 NULL이 들어가고 뒤에는 무조건 참인 조건이 따라오게 됩니다. 이후 # 주석으로 뒤에 있는 조건문을 주석처리해주면 모든 id 값이 리턴되게 될 것입니다.


문제에서는 admin이든, guest이든 어떤 값이든 상관없이 id값이 있다면 문제가 풀리게 되어 있습니다.


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


물론 이러한 방법으로 pw에 그대로 똑같이 삽입할 수 있습니다.



+ Recent posts