728x90
<?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 ~_~");
if(preg_match('/\'/',$_GET[id])) exit("HeHe");
if(preg_match('/\'/',$_GET[pw])) exit("HeHe");
$query = "select id from prob_succubus 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($result['id']) solve("succubus");
highlight_file(__FILE__);
?>
id와 pw에 '를 쓸 수가 없다. 문제를 풀려면 백슬래시(\)를 사용해서 escape 처리를 해야 한다.
참고로 한국의 돈 단위 ₩(원)도 백슬래시 역할이다.
sql에서 문자 앞에 백슬래시(\)를 붙이면 문자 그자체로 인식한다. '도 마찬가지다.
sql에서 '는 문자(열)을 표현하는 역할인데 \'은 ' 문자 그 자체로 인식한다.
이 문제에서 id엔 \을 대입하고 pw엔 or 1%23을 대입하자. 아래와 같은 쿼리가 완성된다.
query : select id from prob_succubus where id='\' and pw='or 1#'
id엔 파란색 문자열이 대입된다. 두번째 등장하는 ' 은 백슬래시(\)로 인해 문자로 인식된다.
따라서 id의 값은 ' and pw= 가 된다. or 뒤에 1은 늘 참이다.
따라서 쿼리 실행 결과 모든 행들이 조건을 만족할 것이며 id가 반드시 존재하기에 문제가 풀린다.
#은 url에서 예약 문자이기 때문에 %23으로 URL 인코딩한 값을 전달해야 '#'으로 PHP에서 인식한다.
답: ?id=\&pw=or 1%23
728x90
'Lord of SQL Injection' 카테고리의 다른 글
nightmare (0) | 2022.12.23 |
---|---|
zombie_assassin (0) | 2022.12.23 |
assassin (0) | 2022.12.23 |
giant (0) | 2022.12.23 |
bugbear (0) | 2022.12.22 |