基於 Swoole 構建的 CTF AWD 比賽環境搭建與實踐

Author: Rytia
Date: 20190427
Blog: www.zzfly.net
本人才學疏淺,望君不吝賜教

背景

受學校老師邀請,爲學弟學妹舉辦分享會介紹 AWD 相關經驗,本人一時頭腦風暴採用 PHP 的 Swoole 擴展搭建了比賽的環境,將分享會變成了友誼賽。php

出題思路

本次題目來自於個人一個外包項目實踐。項目裏面大體有這麼一個需求:客戶登陸系統後,由外部設備觸發一個 websocket 發送操做(例如嵌入式中常碰見的「打開門禁」、「滴卡」、「按下開關」等),該請求接收方爲某個已經登錄的某個用戶(一般靠 user id 或用戶名綁定)。本人在初次開發這類應用時,將用戶惟一身份標識的 user id 做爲了這個 websocket 通道的名字,如此一來帶來的後果即是不管這個用戶在哪臺電腦登陸,不管用戶登錄多少次(小項目無重複登錄+擠下線判斷),只要成功登陸並打開相應網頁便會收到這個 websocket 請求,帶來了某些非預期的信息泄露。在實際的項目中解決方法有不少,例如重複登錄的判斷以及 websocket 「匿名通道」創建。本次出題,便以此爲基礎展開html

AWD 運做原理

CTF-AWD 是線下賽中常見的比賽類型,一般由於攻守兼備而廣受選手喜好。這裏我主要實現了 AWD 兩大關鍵功能:回合制 、 存活檢測 與 動態 flag,至於 flag 提交等前端部份內容,則交由我校 GOCTF 平臺處理。前端

  • 回合制:比賽以 10 分鐘爲一回合。在中心服務器方面,事先使用腳本,根據已開啓的靶機數量以及 ip 生成 flag 並保存爲文件,並於比賽開始時記錄開始時間。每次中心服務器接收到選手靶機的請求時,根據靶機的 ip,以及距離比賽開始的時間,計算出當前處於第幾個回合,並返回 flag 數組中相應的值。而在 pusher (一個第三方 websocket 工具,能夠爲 cli 運行的腳本語言提供發送 websocket 的能力,本次出題依賴 pusher 進行),一樣以 10 分鐘爲一回合,主動向選手端推送含有比賽關鍵內容的消息
  • 存活檢測:本次平臺存貨監控設置的比較簡單,主要爲 web 服務(靶機 80 端口)的監控。每隔一段時間向靶機發送 http 請求,下載靶機上某個保存着 pusher 密鑰的 js 文件,若該文件大小符合預期,則斷定靶機存活。選手在比勝過程中須要盜取到對手的密鑰,以竊聽他方 websocket 內容,並修改己方 pusher 密鑰以放泄露
  • 動態 flag:該部分一樣由中心服務器與 pusher 完成。中心服務器在被請求時根據時間不一樣(回合不一樣)向選手返回不一樣 flag。pusher 根據時間不一樣(回合不一樣)主動推送不一樣的 flag 到選手的頁面上。

AWD 缺陷總結

本次比賽完成以後,發現這套平臺想要真正用於平常選手的訓練還有幾個問題須要克服linux

  • 因爲學校 GOCTF 平臺截止比賽時仍未能很好的支持動態 flag 功能,所以根據每一回閤中心服務器主動通知CTFF平臺 flag 變動的功能沒法實現,只能暫時讓選手記錄本身的 flag 233333….TAT

時鐘難以統一。由於 pusher 和 AWD 中心服務器不必定運行在同一臺服務器上,且中心服務器爲被- 動接收數據,pusher 爲主動推送,加之啓動時間前後有別,所以每一個回合難以作到徹底統一。日後若是須要再次製做 AWD 比賽平臺能夠加一個定時心跳包以保證時鐘統一laravel

Writeup

介紹完比賽平臺的基本運做思路,下面簡單講解一下這道 AWD 題目的作法。git

訪問 80 端口,註冊多個用戶,登錄系統後,發現 User ID 爲1的用戶已經註冊,且系統提示必定要以 User ID 爲 2 的用戶登陸
登陸到 User ID 爲 2 的用戶後,發現頁面啓動了 websocket ,隧道名稱爲 user.2。切換到其餘用戶後均發現隧道名稱爲 user.爲當前用戶登陸 id) 的 websocket 連接
每一回合,發現被主動以彈窗形式提醒了「比賽消息」,且「比賽消息」中包含 flag1,可是彈窗出現後2秒內強制跳轉到了用戶註銷頁面(暗示含有XSS)
登陸服務器後臺,修改視圖文件( home.blade.php ),將底部 JS 部分中當前用戶 ID 的輸出 user.{{Auth::user()->id}} 修改成 user.1 (表示強制接收 user.1 隧道的消息)
下一回合推送,接收到了 user.1 的消息,獲得 flag2,且 flag2 以 = 結束,像 base64 編碼,解碼後得出 (保密) 帳戶的密碼的 rot13 值,從新進行 rot13 旋轉後獲得正確密碼
以 (保密) 管理員身份登陸後,發現有頭像上傳的模塊,且僅作了前端校驗,burpsuit 修改請求中的文件名便可上傳PHP「菜刀」,獲得系統 shell,且用戶爲 root
瞭解整個過程後,發現 pusher.js 中含有 pusher 帳戶的密鑰,且這個文件能夠在80端口輕鬆下載,所以每臺靶機都存在泄露問題。獲得對手的 pusher 密鑰後,修改到本身的服務器上便可接收到對手的 user.1 隧道中的消息,獲取到對手的 (保密) 管理員帳號密碼,從而利用文件上傳漏洞 get shell。github

除了常規的備份、上監控、源碼審計外,主要有如下幾點解題思路。web

主線

/root 目錄下存在 readme.txt,提示從歷史命令記錄裏尋找入口點
發現如下兩條命令可疑:curl 172.17.0.1 和 php artisan tinker
使用 `ip addr 命令發現與前條命令處於同一網段,猜想是向中心服務器發起請求
進行 curl 測試發現無此命令,且 apt、yum 等工具均爲無效,使用 cat /etc/issue 查看到當前系統爲 alpine linux,所以使用 apk add curl 命令安裝 curl 工具,正常請求後獲得 flag3
根據比賽規則,flag3 爲動態 flag,每回合變更一次,且不能提交本身靶機上的,所以能夠按照這個思路去配合負責進攻部分的隊友完成對方靶機的滲透
php artisan tinker 命令爲賽題所用 Laravel 框架對 psy shell 的封裝,能夠直接進入 psy shell 經過 ORM 操做修改管理員帳戶的密碼,從而獲取本身靶機的管理員權限,與上文所述修改 user id 以竊聽 websocket 的效果類似,可是難度比較大,也不太符合預期關於 websocket 的考點sql

副線

每一個回合接收到彈窗,都會被強制跳轉到「註銷」頁面,推測有 XSS 漏洞,進行源碼審計後,將 resources/views/home.blade.php 文件中 $(「」).html(data.message) 修改成 $(「」).text(data.message) 便可不解析推送內容以放推送 XSS 投毒(仰天大笑~)
源碼審計發現存在 upload() 方法用於處理 /upload 這個 url 下的文件上傳操做,且不對擴展名、mine type 等進行判斷, 能夠給對手的服務器嘗試強制上傳文件。可是 Laravel 框架默認開啓 csrf 攔截,須要在對手服務器上註冊一個帳號以獲取 csrf tokendocker

Github 項目地址

https://github.com/zzfly256/C...

運行環境

AWD 平臺部分:PHP 7 + Swoole 4
靶機部分:任意版本 docker

項目文件介紹

  • server:AWD 中心服務器,運行於 docker 母機,負責根據提供每一個回合的 flag:flag3

    • getFlag 文件爲 php 可執行文件,根據 docker ps 命令中的啓動的容器的 ip,爲容器生成不一樣的 flag 並保存爲 flags.json
    • server 文件爲 php 可執行文件,監聽 80 端口,根據不一樣回合返回 flags.json 文件中的相應值
    • flags.json 保存生成的 flag
  • pusher:Pusher.js 的服務端,運行於 docker 母雞或任何一臺電腦。關於 pusher 的介紹可移步官網:www.pusher.com

    • pusher-admin 文件爲 php 可執行文件,爲賽題中管理員用戶推送消息(供選手竊聽 websocket,包含一個 flag :flag2)
    • pusher-user 文件爲 php 可執行文件,爲賽題中(ID爲 2 )的普通註冊用戶推送消息(包含一個 flag : flag1)
    • monitor 文件爲 php 可執行文件,用於監控選手靶機是否存活(監控 web 服務/ pusher.js 文件大小)
    • pusher-server 文件爲 php 可執行文件,按照回合(時間)推送消息以及存活檢測
    • getFlag 文件爲 php 可執行文件,生成管理員消息(flag2)所用
    • pusher-key.json 保存各個靶機的 pusher 密鑰,以及 flag2 的值(flag1的值爲固定值,每一個選手同樣)
  • web:比賽賽題企業網站部分, 是爲 laravel 5.8 框架,採用 sqlite 數據庫

    • 業務邏輯主要在 /app/Http/Controllers/HomeController.php
    • 視圖文件在 /resources/views 目錄下
  • docker:靶機 docker 鏡像

更多

更多關於本項目的介紹,能夠移步:http://www.zzfly.net/build-a-...

相關文章
相關標籤/搜索