摘要:出題思路本次題目來自于我的一個外包項目實踐?;睾现票荣愐苑昼姙橐换睾?。選手在比賽過程中需要盜取到對手的密鑰,以竊聽他方內容,并修改己方密鑰以放泄露動態(tài)該部分同樣由中心服務器與完成。
Author: Rytia背景
Date: 20190427
Blog: www.zzfly.net
本人才學疏淺,望君不吝賜教
受學校老師邀請,為學弟學妹舉辦分享會介紹 AWD 相關經驗,本人一時頭腦風暴采用 PHP 的 Swoole 擴展搭建了比賽的環(huán)境,將分享會變成了友誼賽。
出題思路本次題目來自于我的一個外包項目實踐。項目里面大致有這么一個需求:客戶登錄系統(tǒng)后,由外部設備觸發(fā)一個 websocket 發(fā)送操作(例如嵌入式中常遇見的“打開門禁”、“滴卡”、“按下開關”等),該請求接收方為某個已經登陸的某個用戶(通???user id 或用戶名綁定)。本人在初次開發(fā)這類應用時,將用戶唯一身份標識的 user id 作為了這個 websocket 通道的名字,如此一來帶來的后果便是無論這個用戶在哪臺電腦登錄,無論用戶登陸多少次(小項目無重復登陸+擠下線判斷),只要成功登錄并打開相應網頁便會收到這個 websocket 請求,帶來了某些非預期的信息泄露。在實際的項目中解決方法有很多,例如重復登陸的判斷以及 websocket “匿名通道”建立。本次出題,便以此為基礎展開
AWD 運作原理CTF-AWD 是線下賽中常見的比賽類型,通常因為攻守兼?zhèn)涠鴱V受選手喜愛。這里我主要實現了 AWD 兩大關鍵功能:回合制 、 存活檢測 與 動態(tài) flag,至于 flag 提交等前端部分內容,則交由我校 GOCTF 平臺處理。
回合制:比賽以 10 分鐘為一回合。在中心服務器方面,事先使用腳本,根據已開啟的靶機數量以及 ip 生成 flag 并保存為文件,并于比賽開始時記錄開始時間。每次中心服務器接收到選手靶機的請求時,根據靶機的 ip,以及距離比賽開始的時間,計算出當前處于第幾個回合,并返回 flag 數組中相應的值。而在 pusher (一個第三方 websocket 工具,可以為 cli 運行的腳本語言提供發(fā)送 websocket 的能力,本次出題依賴 pusher 進行),同樣以 10 分鐘為一回合,主動向選手端推送含有比賽關鍵內容的消息
存活檢測:本次平臺存貨監(jiān)控設置的比較簡單,主要為 web 服務(靶機 80 端口)的監(jiān)控。每隔一段時間向靶機發(fā)送 http 請求,下載靶機上某個保存著 pusher 密鑰的 js 文件,若該文件大小符合預期,則判定靶機存活。選手在比賽過程中需要盜取到對手的密鑰,以竊聽他方 websocket 內容,并修改己方 pusher 密鑰以放泄露
動態(tài) flag:該部分同樣由中心服務器與 pusher 完成。中心服務器在被請求時根據時間不同(回合不同)向選手返回不同 flag。pusher 根據時間不同(回合不同)主動推送不同的 flag 到選手的頁面上。
AWD 缺陷總結本次比賽完成之后,發(fā)現這套平臺想要真正用于日常選手的訓練還有幾個問題需要克服
由于學校 GOCTF 平臺截止比賽時仍未能很好的支持動態(tài) flag 功能,因此根據每一回合中心服務器主動通知CTFF平臺 flag 變更的功能無法實現,只能暫時讓選手記錄自己的 flag 233333….TAT
時鐘難以統(tǒng)一。因為 pusher 和 AWD 中心服務器不一定運行在同一臺服務器上,且中心服務器為被- 動接收數據,pusher 為主動推送,加之啟動時間先后有別,因此每個回合難以做到完全統(tǒng)一。往后如果需要再次制作 AWD 比賽平臺可以加一個定時心跳包以保證時鐘統(tǒng)一
Writeup介紹完比賽平臺的基本運作思路,下面簡單講解一下這道 AWD 題目的做法。
攻訪問 80 端口,注冊多個用戶,登陸系統(tǒng)后,發(fā)現 User ID 為1的用戶已經注冊,且系統(tǒng)提示一定要以 User ID 為 2 的用戶登錄
登錄到 User ID 為 2 的用戶后,發(fā)現頁面啟動了 websocket ,隧道名稱為 user.2。切換到其他用戶后均發(fā)現隧道名稱為 user. (為當前用戶登錄 id) 的 websocket 鏈接
每一回合,發(fā)現被主動以彈窗形式提醒了“比賽消息”,且“比賽消息”中包含 flag1,但是彈窗出現后2秒內強制跳轉到了用戶注銷頁面(暗示含有XSS)
登錄服務器后臺,修改視圖文件( home.blade.php ),將底部 JS 部分中當前用戶 ID 的輸出 user.{{Auth::user()->id}} 修改為 user.1 (表示強制接收 user.1 隧道的消息)
下一回合推送,接收到了 user.1 的消息,得到 flag2,且 flag2 以 = 結束,像 base64 編碼,解碼后得出 (保密) 賬戶的密碼的 rot13 值,重新進行 rot13 旋轉后得到正確密碼
以 (保密) 管理員身份登錄后,發(fā)現有頭像上傳的模塊,且僅做了前端校驗,burpsuit 修改請求中的文件名即可上傳PHP“菜刀”,得到系統(tǒng) shell,且用戶為 root
了解整個過程后,發(fā)現 pusher.js 中含有 pusher 賬戶的密鑰,且這個文件可以在80端口輕松下載,因此每臺靶機都存在泄露問題。得到對手的 pusher 密鑰后,修改到自己的服務器上即可接收到對手的 user.1 隧道中的消息,獲取到對手的 (保密) 管理員賬號密碼,從而利用文件上傳漏洞 get shell。
除了常規(guī)的備份、上監(jiān)控、源碼審計外,主要有以下幾點解題思路。
主線/root 目錄下存在 readme.txt,提示從歷史命令記錄里尋找入口點
發(fā)現以下兩條命令可疑:curl 172.17.0.1 和 php artisan tinker
使用 `ip addr 命令發(fā)現與前條命令處于同一網段,猜測是向中心服務器發(fā)起請求
進行 curl 測試發(fā)現無此命令,且 apt、yum 等工具均為無效,使用 cat /etc/issue 查看到當前系統(tǒng)為 alpine linux,因此使用 apk add curl 命令安裝 curl 工具,正常請求后得到 flag3
根據比賽規(guī)則,flag3 為動態(tài) flag,每回合變動一次,且不能提交自己靶機上的,因此可以按照這個思路去配合負責進攻部分的隊友完成對方靶機的滲透
php artisan tinker 命令為賽題所用 Laravel 框架對 psy shell 的封裝,可以直接進入 psy shell 通過 ORM 操作修改管理員賬戶的密碼,從而獲取自己靶機的管理員權限,與上文所述修改 user id 以竊聽 websocket 的效果相似,但是難度比較大,也不太符合預期關于 websocket 的考點
每個回合接收到彈窗,都會被強制跳轉到“注銷”頁面,推測有 XSS 漏洞,進行源碼審計后,將 resources/views/home.blade.php 文件中 $(“”).html(data.message) 修改為 $(“”).text(data.message) 即可不解析推送內容以放推送 XSS 投毒(仰天大笑~)
源碼審計發(fā)現存在 upload() 方法用于處理 /upload 這個 url 下的文件上傳操作,且不對擴展名、mine type 等進行判斷, 可以給對手的服務器嘗試強制上傳文件。但是 Laravel 框架默認開啟 csrf 攔截,需要在對手服務器上注冊一個賬號以獲取 csrf token
https://github.com/zzfly256/C...
運行環(huán)境AWD 平臺部分:PHP 7 + Swoole 4
靶機部分:任意版本 docker
server:AWD 中心服務器,運行于 docker 母機,負責根據提供每個回合的 flag:flag3
getFlag 文件為 php 可執(zhí)行文件,根據 docker ps 命令中的啟動的容器的 ip,為容器生成不同的 flag 并保存為 flags.json
server 文件為 php 可執(zhí)行文件,監(jiān)聽 80 端口,根據不同回合返回 flags.json 文件中的相應值
flags.json 保存生成的 flag
pusher:Pusher.js 的服務端,運行于 docker 母雞或任何一臺電腦。關于 pusher 的介紹可移步官網:www.pusher.com
pusher-admin 文件為 php 可執(zhí)行文件,為賽題中管理員用戶推送消息(供選手竊聽 websocket,包含一個 flag :flag2)
pusher-user 文件為 php 可執(zhí)行文件,為賽題中(ID為 2 )的普通注冊用戶推送消息(包含一個 flag : flag1)
monitor 文件為 php 可執(zhí)行文件,用于監(jiān)控選手靶機是否存活(監(jiān)控 web 服務/ pusher.js 文件大?。?/p>
pusher-server 文件為 php 可執(zhí)行文件,按照回合(時間)推送消息以及存活檢測
getFlag 文件為 php 可執(zhí)行文件,生成管理員消息(flag2)所用
pusher-key.json 保存各個靶機的 pusher 密鑰,以及 flag2 的值(flag1的值為固定值,每個選手一樣)
web:比賽賽題企業(yè)網站部分, 是為 laravel 5.8 框架,采用 sqlite 數據庫
業(yè)務邏輯主要在 /app/Http/Controllers/HomeController.php
視圖文件在 /resources/views 目錄下
docker:靶機 docker 鏡像
更多更多關于本項目的介紹,可以移步:http://www.zzfly.net/build-a-...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/31420.html
閱讀 2122·2021-11-24 10:28
閱讀 1145·2021-10-12 10:12
閱讀 3356·2021-09-22 15:21
閱讀 694·2021-08-30 09:44
閱讀 1909·2021-07-23 11:20
閱讀 1157·2019-08-30 15:56
閱讀 1769·2019-08-30 15:44
閱讀 1492·2019-08-30 13:55