[Lord of SQLInjection] Nessie Write UP
작성자 - LRTK문제 코드
<?php
include "./config.php";
login_chk();
$db = mssql_connect();
if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['id'])) exit("No Hack ~_~");
if(preg_match('/master|sys|information|prob|;|waitfor|_/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select id from prob_nessie where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
sqlsrv_query($db,$query);
if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors()));
$query = "select pw from prob_nessie where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['pw'] === $_GET['pw']) solve("nessie");
highlight_file(__FILE__);
?>
공격 백터
- id
- pw
공격 백터에 대한 검증
- id :
master, sys, information, prob, ;, waitfor, _
- pw :
master, sys, information, prob, ;, waitfor, _
코드 설명
$db = mssql_connect();
이번 문제는 MSsql로 제작된 듯 하다.
$query = "select id from prob_nessie where id='{$_GET['id']}' and pw='{$_GET['pw']}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
sqlsrv_query($db,$query);
if(sqlsrv_errors()) exit(mssql_error(sqlsrv_errors()));
필터링에 통과된 공격 백터 id와 pw는 쿼리문에 들어가게 된다.
쿼리문은 id='공격 백터 id' and pw='공격 백터 pw'
인 prob_nessie 테이블에 저장된 id을 반환하게 된다.
한 가지 특이한 점은 쿼리문에 Error가 발생하면, Error Message를 페이지에 출력한다.
나는 여기서 Error Based SQLi를 의심하였다.
$query = "select pw from prob_nessie where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['pw'] === $_GET['pw']) solve("nessie");
두 번째 쿼리문은 id가 admin인 pw를 반환한다.
공격 백터 pw와 쿼리문 반환값인 pw이 같으면 문제가 클리어된다.
문제 풀이
만약 Mysql이라면, SELECT id FROM prob_nessie WHERE id='' or if(substr(pw,1,1)='a',exp(710),0)#' and pw=''
와 같은 Error Based SQLi으로 admin의 pw를 파싱할 것이다.
일단 위 쿼리문처럼 하기 위해선 MsSQL의 주석처리가 어떻게 이루어지는 지 알아야한다.
MsSQL의 주석처리
--
: Comment Type 1--
: Comment Type 2-- -
: SQL Commnet/**/
: Inline Commnet;%00
: Null Byte
주석이 잘 작동하였다.
이젠 pw 파싱에 필요한 조건문과 Error 유발자, length 함수, substr 함수를 찾아봐야 한다.
MsSQL의 조건문
CASE WHEN 구문
CASE
WHEN [조건절] THEN [TRUE일 경우 값]
ELSE [FALSE일 경우 값]
END
IF ELSE 구문
IF [조건절 TRUE일 경우 값]
[실행문]
ELSE [조건절 FALSE일 경우 값]
[실행문]
파싱에 필요한 함수
LEN 함수
MySQL의 length 함수와 같은 함수로 사용법도 같음.
SUBSTRING 함수
MySQL의 substr 함수와 같은 함수로 사용법도 같음.
Error 유발자
@@version
SELECT @@version=1
참고 사이트 : MSSQL Error Based Injection
convert 함수
SELECT convert(int, 'test')
참고 사이트 : Turning Blind Error Based SQL Injection into Exploitable Boolean One | by Ozgur Alp | Medium
공격에 대한 쿼리문을 테스트하는 중 pw의 값이 Error 메세지를 통해 노출이 되었다….
서버에 보냈는데, 문제가 클리어 되었다…..
하지만 이왕 공부한 것을 응용하여 알아내도록 하겠다.
나는 이처럼 Error Based SQLi을 만들어서 admin의 pw 길이를 알아냈다.
pw 파싱은 파이썬으로 위와 같이 substring 함수를 이용하여 구하면 된다.
공부하는 와중 좋은 사이트를 발견하였다.
SQL Fiddle이라는 사이트인데, 다양한 DBMS를 웹에서 테스트할 수 있다.
나는 그 동안 이런 사이트를 몰라서 도커에 설치하여 테스트를 했는데, 이제 그럴 필요가 없다 ㅠㅠ
'워게임 > Lord of SQLInjection' 카테고리의 다른 글
[Lord of SQLInjection] Yeti Write UP (0) | 2021.09.19 |
---|---|
[Lord of SQLInjection] Revenant Write UP (0) | 2021.09.18 |
[Lord of SQLInjection] Poltergeist Write UP (0) | 2021.09.15 |
[Lord of SQLInjection] banshee Write UP (0) | 2021.09.14 |
[Lord of SQLInjection] Manticore Write UP (0) | 2021.09.13 |