페이지 소스를 봤을때 딱히 다른건 없었지만 <script> 태그에 이상한 이모티콘이 존재했다.
따라서 뭔가 이번 문제는 <script> 태그에 난독화 되어 있는 코드를
복호화하는것이 우선일 것이라는 생각이 들었다.
따라서 구글에 다음과 같이 입력해보았다.
검색을 해보니 제일 위에 aaencode라는 것이 나온다.
클릭해보자.
클릭해 보니 alert("Hello, JavaScript")이 위의 이모티콘과 같다고 한다.
브라우저 콘솔에 넣어보자.
콘솔에 넣고 입력해보니 바로 alert가 떴다.
따라서 이번 문제를 풀기 위해 사이트에서 소개하는 Decoder-aaEncode에 접속해보자.
Git에 html 파일로 decoder가 있다.
다운로드 받아 보니 Input the aaencode here에 난독화된 코드를 넣으면
Decoded aaencode String에 복호화된 코드가 나온다.
복호화 된 코드는 다음과 같다.
var enco='';
var enco2=126;
var enco3=33;
var ck=document.URL.substr(document.URL.indexOf('='));
for(i=1;i<122;i++)
{
enco=enco+String.fromCharCode(i,0);
}
function enco_(x)
{
return enco.charCodeAt(x);
}
if(ck=="="+String.fromCharCode(enco_(240))+String.fromCharCode(enco_(220))+String.fromCharCode(enco_(232))+String.fromCharCode(enco_(192))+String.fromCharCode(enco_(226))+String.fromCharCode(enco_(200))+String.fromCharCode(enco_(204))+String.fromCharCode(enco_(222-2))+String.fromCharCode(enco_(198))+"~~~~~~"+String.fromCharCode(enco2)+String.fromCharCode(enco3))
{
location.href="./"+ck.replace("=","")+".php";
}
즉, 입력한 문자열을 패턴으로 검사하는데 검사할때 대/소문자를 구문없이 매칭한다는 말이다.
그렇다면 이제 큰 뼈대는 이해를 했고 이제 어떤것이 매칭이 되는지 살펴볼 차례이다.
"/2|-|\+|from|_|=|\\s|\*|\//i"
(문자를 필터링 하고 싶으면 \를 하나 추가해주어야한다.)
이렇게 총 9개의 문자들이 필터링 되어있다.
그 다음 DB랑 연결을 한다.
여기까지 정리하면 다음과 같다.
사용자가 입력한 val를 go라는 변수에 넣고 go라는 변수에 담긴 사용자값에서
preg_match 함수를 이용해서 패턴에 매칭이되면 "Access Denied!"라는 문구와 함께 exit가 된다.
그럼 일단 무조건 preg_match 함수에 걸리지 않게 val를 입력해야할것이다.
다음 코드를 보자.
$rand=rand(1,5);
if($rand==1)
{
$result=mysqli_query($db,"select lv from chall7 where lv=($go)") or die("nice try!");
}
if($rand==2)
{
$result=mysqli_query($db,"select lv from chall7 where lv=(($go))") or die("nice try!");
}
if($rand==3)
{
$result=mysqli_query($db,"select lv from chall7 where lv=((($go)))") or die("nice try!");
}
if($rand==4)
{
$result=mysqli_query($db,"select lv from chall7 where lv=(((($go))))") or die("nice try!");
}
if($rand==5)
{
$result=mysqli_query($db,"select lv from chall7 where lv=((((($go)))))") or die("nice try!");
}
$data=mysqli_fetch_array($result);
그 다음 rand 함수를 통해 1~5까지 수를 rand라는 변수에 넣는다.
그 후 총 5개의 if문이 있는데 어느 곳에 들어갈지는 5분의 1의 확률을 가지고 있다.
일단 어느 if문에 들어가도 query가 수행하는 행위는 같다.
rand가 1일때를 기준으로 설명하면 다음과 같다.
mysqli_query 함수로 DB 핸들러와 쿼리를 인자로 넣어주면
DB에 입력한 쿼리로 요청하게 되고 오류 없이 실행되면 true, 에러가 발생하면 false를 반환한다.
따라서 true로 실행이되면 쿼리 결과값을 result 변수에 넣는다.
만약 false가 난다면 "nice try!"라는 문구를 볼 수 있다.
예를들어 val에 패턴에 없는 문자 ^를 입력해보자.
위의 퀴리는 당연히 error가 날것이며 그렇다면 "nice try!" 문구를 볼 수 있어야한다.