Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

blacksalamander

gremlin 본문

Lord of SQLInjection

gremlin

검은도롱뇽 2020. 2. 15. 19:09

Source Code

 

 

 

Analysis

 

먼저, Source Code를 분석해보도록 한다.

<?php

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

PHP 언어로 이루어져 있으며 

include 명령어를 이용하여 config.php 라는 외부 파일을 호출하는 것을 확인할 수 있다.

 

다음으로 login_chk() 함수를 실행하였는데 함수의 내용은 보이지 않으므로 정확히 어떠한 역할을 수행하는지 알 수 없지만 함수명으로 보아 사용자가 로그인이 되어있는지 확인하는 것으로 판단된다.

 

그 후, dbconnect() 함수를 실행하여 데이터베이스와 연결하는 것을 알 수 있다.

 

<?php

  ...
  
  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>";
  
  ...
  
?>

preg_match() 함수에서 지정한 정규식 패턴과 GET 방식으로 입력한 id를 비교하는데,

만약 id의 문자열에 정규식 패턴과 일치하는 것이 있다면 "No Hack~_~" 이라는 구문과 함께 종료하는 것을 알 수 있다.

이 문제에서 지정한 정규식 패턴은 prob, _, ., (, )이며 대소문자 구별이 없다.

GET 방식으로 입력한 pw 또한 마찬가지이다.

 

preg_match() 함수에 대해서 자세히 알고 싶다면 아래 링크로 이동하길 바란다.

참고로 GET 방식이라는 말에 대해서 간단히 설명하자면,

서버와 클라이언트가 있을 때 클라이언트가 서버로 요청을 보내는 방법이 GET 방식과 POST 방식 2가지가 있다.

GET 방식은 헤더(Header)에 데이터를 포함시켜 요청을 하며 URL에 데이터가 노출되지만

POST 방식은 바디(Body)에 데이터를 포함시켜 요청을 하며 URL에 데이터가 노출되지 않는다.

 

GET 방식과 POST 방식에 대해서 자세히 알고 싶다면 아래 링크로 이동하길 바란다.

query 문을 해석하면, prob_gremlin 테이블에서 id가 GET 방식으로 입력한 id이고 pw가 GET 방식으로 입력한 pw일 때 id를 출력하라 라고 볼 수 있다.

 

echo 문은 HTML 언어로 이루어져 있으며 사용자가 GET 방식으로 id와 pw를 입력했을 때 웹 페이지에 보여지도록 하는 역할을 수행한다.

 

<?php
  
  ...
  
  $result = @mysqli_fetch_array(mysqli_query($db, $query));
  
  if($result['id']) solve("gremlin");
  
  highlight_file(__FILE__);
  
?>

mysqli_query() 함수로 데이터베이스에 쿼리문을 보냈을 때 해당하는 결과 값을 mysqli_fetch_array() 함수를 통해 result 변수에 저장한다.

result 변수에 id의 문자열이 있으면 solve() 함수를 실행하여 성공한 것을 알 수 있으며

highlight_file() 함수로 __FILE__의 값을 강조 표시한다.

 

 

Injection

 

Source Code 분석이 끝났으니 본격적으로 SQL Injection을 해보도록 한다.

 

이 문제에서 query 문의 where 절을 True로 만들면 prob_gremlin 테이블로부터 id를 가져올 것으로 예상된다.

 

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

 

id와 pw 모두 GET 방식이므로 URL에 데이터를 입력하여 서버에 요청할 수 있다.

URL에 ?id=' or 1=1%23 을 입력하여 query 문의 where 절을 True로 만든다.

 

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

-> query : select id from prob_gremlin where False or True 주석

 

where 절이 True가 되는 이유에 설명하자면,

id='' 은 False가 되고 1=1 은 True가 되며 #' and pw='' 은 주석 처리가 된다.

False or True 는 True가 되므로 where 절이 True가 된다.

 

%23은 #의 URL 인코딩(Encoding)된 값이며 #은 mysql에서 한 줄 주석 처리하는 역할을 한다.

클라이언트가 서버에 데이터를 보낼 때 URL 인코딩된 값을 보내지게 되는데

#은 URL 앵커(anchor)를 연결하는 역할도 하므로 #을 그대로 입력하지 않고 인코딩된 값인 %23을 입력한다.

 

 

 

 

'Lord of SQLInjection' 카테고리의 다른 글

goblin  (0) 2020.02.22
cobolt  (0) 2020.02.16