[Lord of SQLInjection] Revenant 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 * from prob_revenant 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 * from prob_revenant where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['4'] === $_GET['pw']) solve("revenant"); // you have to pwn 5th column
highlight_file(__FILE__);
?>
공격 백터
- id
- pw
공격 백터에 대한 검증
- id :
master, sys, infomation, prob, ;, waitfor, _
- pw :
master, sys, infomation, prob, ;, waitfor, _
코드 설명
$db = mssql_connect();
MsSQL로 이루어진 문제이다.
$query = "select * from prob_revenant 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는 SELECT * FROM porb_revenant WHERE id='공격 백터 id' and pw='공격 백터 pw'
에 들어가게 된다.
반환되는 컬럼이 *
인 이유는 이 문제를 클리어하기 위한 조건이 5번째 컬럼에 들어 있기 때문이다.
반환 값에 대한 출력이 안 되고, Error 메시지는 출력이 된다.
즉, Error Based SQLi로 문제를 풀면 될 듯 싶다.
$query = "select * from prob_revenant where id='admin'";
$result = sqlsrv_fetch_array(sqlsrv_query($db,$query));
if($result['4'] === $_GET['pw']) solve("revenant"); // you have to pwn 5th column
이후 id가 admin인 5번째 컬럼의 값과 공격 백터 pw이 같으면 문제가 클리어 된다.
문제 풀이
현 문제는 쿼리문을 통해 Column을 찾을 방법은 필터링으로 통제하고 있다.
이러한 이유 때문에 MySQL로도 방법이 생각이 안 났다. 일단 MsSQL의 SQLi 사례를 찾아서 방법을 찾아보겠다.
참고 사이트 : Error-based SQL Injection
찾아본 사례로 group by와 having를 사용하면 컬럼명을 Error을 통해 출력할 수 있다.
having을 사용하는데, group이 설정되어 있지 않아서 Error 메세지로 id를 GRUOP BY로 추가하라는 문구가 출력된다.
Group by에 id를 추가하면, 그 다음 컬럼명이 나오고 추가하라고 한다.
위 방법을 반복하면 5번째 컬럼명을 얻을 수 있다.
이후, id가 admin이면서 9604b0c8 컬럼의 값을 비교하는데 일부러 Error를 나오게 넣으면 그 값이 출력이 된다.
위 Error는 9604b0c8 컬럼의 값은 varchar형인데 숫자형처럼 비교하여 발생된 것이다.
알아낸 값을 pw 파라미터에 넣어서 보내면 문제를 클리어할 수 있다.
이번 문제로 MsSQL은 Error에 굉장히 취약하다는 것을 배울 수 있었다.
Group by
레코드 조회시 각 레코드를 하나의 그룹으로 묶어서 표현해주는 역활
위와 같은 데이터를 반 별로 그룹화 시켜서 집계를 하고 싶을 경우, Group By을 사용하면 된다.
Having
GROUP BY를 통해 묶인 레코드 그룹에 대해 조건을 거는 역할을 합니다.
ex). having 점수 > 80
'워게임 > Lord of SQLInjection' 카테고리의 다른 글
[Lord of SQLInjection] Mummy Write UP (0) | 2021.09.20 |
---|---|
[Lord of SQLInjection] Yeti Write UP (0) | 2021.09.19 |
[Lord of SQLInjection] Nessie 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 |