cobolt 문제와 마찬가지로 학교 끝나고 기숙사로 돌아가는 지하철에서 풀었던 문제다.
문제를 살펴보러 갑시다.
문제 살펴보기

코드를 분석하면 아래와 같다.
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
', ", `가 다 막혔다. id='admin'과 같은 형태로 값을 전달할 수 없게 되었다.
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
...
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
if($result['id'] == 'admin') solve("goblin");
이번 문제는 no 파라미터를 통해서 데이터를 전달할 수 있다.
prob_goblin 테이블에서 id='guest' and no={$_GET[no]}인 행이 존재할 경우
Hello guest를 화면에 띄운다.
그런데 만약 no 파라미터를 조작하여 id값을 'admin'으로 만들 경우
solve 함수를 호출하여 문제가 풀리게 된다.
문제 풀이 과정
굳이 single quote( ' )를 쓰지 않고도 id='admin'을 의미하는 코드를 짤 수 있다.
다양한 방법이 있지만 나는 16진수를 이용하여 문제를 풀었다.
sql에서 16진수 맨 앞에 0x를 붙여주면 해당 값이 의미하는 문자열로 변환된다.
자세한 내용은 아래 링크를 참고하길 바란다.
https://database.guide/3-ways-to-unhex-a-string-in-mysql/
where id='guest' and no={$_GET[no]}가 참이 될 경우
$result에 id='guest'인 행이 들어가게 되므로 위 where문을 거짓으로 만들어야 한다.
no에 0을 넣어보도록 하자.

딱히 변화가 없다.
Hello guest 가 출력되지 않은 것으로 보아
no값으로 0을 주면 where id='guest' and no={$_GET[no]}문이 거짓이 되는 것을 확인할 수 있다.
그러면 이제 뒤에 or id=0x61646d696e%23을 넣어서 select 문이 id='admin'인 행을 반환하도록 하자
0x61646d6963가 왜 'admin'인지 모르겠는 사람은 아래 표를 참고하면 된다.


페이로드 : ?no=0 or id=0x61646d696e%23
별로 어렵지 않았으니 다음 문제로 넘어가도록 합시다.
'web > Lord of SQLInjection' 카테고리의 다른 글
| Lord of SQLInjection - 6번 : darkelf (1) | 2023.12.10 |
|---|---|
| Lord of SQLInjection - 5번 : wolfman (0) | 2023.12.10 |
| Lord of SQLInjection - 4번 : orc (0) | 2023.12.09 |
| Lord of SQLInjection - 2번 : cobolt (0) | 2023.12.08 |
| Lord of SQLInjection - 1번 : gremlin (0) | 2023.12.07 |