LOS #18 nightmare

2020. 10. 28. 23:01
728x90
728x90
728x90
 

Lord of SQLInjection

 

los.rubiya.kr

Source code

<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)|#|-/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(strlen($_GET[pw])>6) exit("No Hack ~_~"); 
  $query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) solve("nightmare"); 
  highlight_file(__FILE__); 
?>

 

Query

select id from prob_nightmare where pw('') and id!='admin'

 

Write-up

[사진 1]

위 사진에서 확인할 수 있는 정보는 다음과 같다.

  • 파라미터는 pw 1개가 사용될 수 있다.

  • mysql 주석 중 '#', '--'을 필터링 하고 있다.

  • pw 값의 길이가 6을 초과하면 안된다.
  • id의 값이 'admin'이면 안된다.

"pw=('')" 부분을 참으로 만들면 된다. '#', '--' 주석이 필터되고 있으므로 ';%00' 값을 붙이면 "and id!='admin'" 부분을 주석처리 할 수 있다(쿼리가 실행되면서 세미콜론을 만나면 종료되고 %00 null 값을 붙여줌으로써 뒤쪽 sql 구문이 주석처리 된다.). 그리고 수식 계산 시 발생하는 형변환을 통해 "pw=('')" 부분을 참으로 만들어주면 된다.

 

[사진 2]

위와 같이 문자와 숫자를 비교하거나 연산할 때 문자를 정수로 변환하게 되는데, 첫 번쨰 결과에서 'a' 문자는 정수 0으로 형변환되고 정수 0과 비교한다. 따라서 참이 반환된다. 두 번째 결과를 보면 'a' 문자가 정수 0으로 형변환되고 정수 1과 비교하여 거짓이 반환됨을 확인할 수 있다.

정수 문자가 섞여 있는 경우 알파벳 등의 문자 직전까지는 정수로 형변환된다. 세 번째 결과를 보면 '1a' 값은 정수 1로 형변환되고 정수 1과 비교하여 참이 반횐됨을 확인할 수 있다. 네 번쨰 결과를 보면 'a1' 값은 알파벳 'a' 앞에 정수 문자가 없기 떄문에 최종적으로 정수 0으로 형변환되고 정수 1과 비교하여 거짓이 반환된다.

 

Parameter

pw='=1);%00

쿼리문은 다음과 같다. 소괄호 안의 single quote로 감싸진 부분은 정수 0으로 형변환되고 정수 1과 비교하여 거짓(정수 0)이 반환되고 다시 pw 값과 정수 0을 비교한다. pw 값이 정수 문자가 아닌 문자로 시작하기 때문에 최종적으로 참이 반환되어 select를 성공한다. 

select id from prob_nightmare where pw=(''=1);') and id!='admin'

 

Success

[사진 3]

728x90
728x90

'Wargame > LOS' 카테고리의 다른 글

LOS #20 dragon  (0) 2020.10.28
LOS #19 xavis  (0) 2020.10.28
LOS #17 zombie_assassin  (0) 2020.10.28
LOS #16 succubus  (0) 2020.10.28
LOS #15 assassin  (0) 2020.10.28

+ Recent posts