<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("goblin");
highlight_file(__FILE__);
?>
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
GET방식으로 no를 받으며, no에 prob, _, ., () 가 들어 있고, /i 대소문자가 구분 되지 않으면 필터링되서 No Hack ~_~ 이 출력된다.
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
GET방식으로 no를 받으며, no에 \'|\"|` 가 들어 있고, /i 대소문자가 구분 되지 않으면 필터링되서 No Quotes ~_~ 이 출력된다.
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
id에는 guest가 되어있으며, no가 $query에 들어간다는 것을 알 수 있다.
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
만약 $result의 일반 id 라면, "Hello (id)" 가 출력
한마디로, guest로 로그인을 하게 된다면 위의 문자열이 출력
if($result['id'] == 'admin') solve("goblin");
만약 $result의 id가 admin일 경우 성공적으로 출력된다.
⭐ php 코드를 분석했을 때,
$query
와 if 문
이 다르다는 것을 알 수 있고, id가 admin
일 때 성공적으로 문제의 답이 출력된다는 것도 확인했다.
id=admin'&no=0
id를 admin으로 지정해주고 no에 0를 입력해보았지만 아무것도 뜨지 않는다.
id=admin'&no=1
no에 1를 입력하자 Hello guest가 나왔다.
그렇다면 지금 id=guest
로 고정, 그리고 no의 값이 1
이라는 것을 알 수 있다.
id | no |
---|---|
guest | 1 |
하지만, if문에서는 id=admin
이 되어야 한다.
no=0||no=2
$query문
을 확인해보면 where 조건 뒤에 id='guest' and no={$_GET[no]}
가 참인 것을 알 수 있다.
2번에서 n=1
라는 것을 확인했으니, where 조건을 거짓으로 만들어보았다.
id=guest
,n=0
또는 (||
) n=2
를 입력했더니 admin의 계정으로 로그인 할 수 있었다.
no=2 or id=0x61646d696e
일반적으로는where (id=guest and no=2) or id='admin'
으로 입력하면 풀리겠지만, preg_match
에서 작은 따옴표를 필터링하도록 짜여있기 때문에, 일반 문자열 'admin'
을 넣을 수 없다. 이런 경우, admin을 16진수로 바꿔서 id=0x61646d696e
로 입력했더니 문제를 풀 수 있었다!