워게임,CTF/lord of sql injection

[lord of sql injection] goblin writeup

Haemaa 2023. 8. 14. 00:03

워게임 문제를 풀다가

preg_match라는 필터링 함수를 만났습니다.

 

사용법은 다음과 같습니다.

<?php
preg_match('/대조 할 문자/','입력한 문자', $matches); 
?>

$matches 뒤에 PREG_OFFSET_CAPTURE를 쓰는 유형도 존재합니다.

 

대조할 문자를 슬래시를 붙여서 기입하면 됩니다.

 

그런데 특수문자를 필터링 할 때는

특수문자 앞에 \를 붙입니다.

/ \ ' / 이런식으로 하면 됩니다.

 

대조할 문자 다음 /대조할 문자/i 이런식으로 i 가 붙을 수 있는데 이럴 때는 대문자와 소문자를 구분하지 않겠다는 소리입니다.

 

php 함수 내에 선언된 $matches는 대조할 문자와 입력한 문자가 같아서 검거가 되면 $matches에 저장하게 하는 저장소 역할을 합니다. 

검거된 문자는 배열 형태로 저장됩니다. 전체 문자열 star 라는 열에서 s 와 r 이 검거되었다면 s와 r이 배열형태로 저장됩니다.

 

그리고 preg_match 함수 자체는 검거당한 문자열이 있다면 1을 반환하고, 문자열이 없다면 0을 반환합니다.

패턴을 인식하지 못하면 false가 반환됩니다.

 

3번 문제 goblin은 다음과 같습니다.

 

처음엔 no파라미터에 '' union select id ~ where id ='admin' 같은 쿼리문을 전달하려 했는데,

앞 부분의 id가 'guest'로 고정되어 있고 prob이나 작음따옴표, 큰따옴표 등이 전부 필터링 되고 있으므로

다른 방법을 고려해봐야할 것 같습니다.

 

 

그중 가장 근접했던게 no 파라미터에 3 or id=admin을 전달하는 것이었습니다.

 

이렇게 되면 연산자 and 와 or의 연산 순서에 따라

( id='guest' and no=3 ) or id=admin 순으로 실행될 것이기 때문에 앞부분의 쿼리는 no=3이면서 id가 guest인 조건에 해당하는 데이터가 컬럼에 없을 것이므로 False를 반환하고 id=admin이 실행될 것이라 예측했습니다.

 

 

쿼리문은 잘 전달이 되었으므로 preg_match 필터링은 통과했지만 따옴표를 전달할 수 없어서 id=admin이 적절치 않았습니다.

 

다른 방법이 필요하겠군요.

 

 

파라미터에 필터링을 전달하는 방법은 2진수나 16진수도 전달하면 이걸 문자로 인식할 수 있었습니다.

id 파라미터에 'admin'을 2진수와 16진수로 전달하면 클리어가 됩니다.


소스 참조

preg_match 함수 : https://flash-ctf.tistory.com/43

SQL Injection 필터링 정리 글 : https://07001lab.tistory.com/entry/SQL-Injection-%ED%95%84%ED%84%B0-%EC%9A%B0%ED%9A%8C-%EC%A0%95%EB%A6%AC%EA%B8%80