Skip to content

DNS rebinding vs authorization/authentication #58

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
laurian19 opened this issue Mar 4, 2025 · 12 comments
Open

DNS rebinding vs authorization/authentication #58

laurian19 opened this issue Mar 4, 2025 · 12 comments

Comments

@laurian19
Copy link

laurian19 commented Mar 4, 2025

Hi!

I have looked into the SOO tool for some weeks as I am trying to perform a security analysis for some specific services. As far as I understand, DNS rebinding is more difficult to take advantage of if authentication/authorization is required by the service which runs on localhost on a specific port, right? Is this also the case when employing the attack Hook and Control?

More exactly, some of the services I am analyzing right now require a specific API key to send requests to their API endpoints or even username/password authentication to access their GUI hosted on http://localhost:{port}. This would make it difficult to actually send those requests without having knowledge of the login credentials or corresponding API key, right?

Thank you in advance!

@gdncc
Copy link
Collaborator

gdncc commented Mar 4, 2025

DNS rebinding gives you connectivity to a service, which would not normally be accessible in certain scenarios if it were not vulnerable to DNS rebinding. Adequate authentication and authorization controls would prevent attackers from accessing information protected by these controls. This is indeed the case when using Hook and Control.

@laurian19
Copy link
Author

Thank you for the reply!

However, I would like to ask about some issue that I encountered: I managed to get the Hook and Control attack working on some specific service that I am currently analyzing (it does not require any authentication/authorization). I did it by running the manager tool in some browser (like Firefox) and then accessing the actual content served by the hijacked browser from Chrome (at this point, the attack fails against Chromium due to PNA). Both browsers are running on my machine and it works just fine (similar to what you did in the DEF CON 27 presentation). However, when I try to serve the content of the hijacked browser (in this case Firefox) from another browser that is not running on my current machine (Firefox on a VM or on a friend's machine) the content is not the same: it is rendered poorly and endpoints are not accessible. Did you encounter this before or have any idea what it might happen?

@gdncc
Copy link
Collaborator

gdncc commented Mar 10, 2025

I tried the Hook and Control attack with the latest Singularity git commit, and I was able to browse a hooked client service (via Firefox on Linux) from another machine (Chrome on macOS). I haven't encountered this issue before. You would need to review the browsers' console and request logs on both machines to start understanding what is going on.

As a side note, you should be able to bypass PNA on Chrome as follows:

  • Use the Inline Frame Attack Method in the advanced options of Singularity manager if the vulnerable service does not prevent loading of frames.
  • Use the Multiple answers Rebinding Strategy with Target Host set to 0.0.0.0, when attacking a service on the same machine as the browser, and while you can. This still works for me with Chrome version 134.0 on macOS.

@laurian19
Copy link
Author

laurian19 commented Mar 11, 2025

Thank you!

I followed your advice and it appears like the attack is indeed working correctly, by looking at the following screenshots which highlight some of the requests that appear on the hijacked browser (Firefox on Linux):

Image

Image

However, by looking at the following pictures which highlight requests on the attacker's browser (Firefox on Ubuntu VM), my assumption is that those 3 pre-flight requests have been denied and I cannot see the actual content of the webpage because of SOP:

Image

Image

What is interesting however when I (the attacker now) do the same thing but from a Firefox (new instance) browser on the same machine as the victim browser, this is what I see for the same 'predict' OPTIONS request:

Image

More exactly, the remote address "Address 0.0.0.0:7860" does not appear in the first Firefox browser on my VM. Do you think this is what causes my scripts not be able to read the content of the page, as the server responses with "Response body is not available to scripts (Reason: CORS Failed)". Is there any advice you would give me to try and handle this situation?

Update: for the previous requests from (working) Firefox attacker browser, the IP address is "Address: 167.71.73.156:3129" (note that this is the public IP address where I host SOO server), which then changes to 0.0.0.0 upon sending the OPTIONS requests (although the scenario is not the same as on the first Firefox instance on the VM):

Image

@gdncc
Copy link
Collaborator

gdncc commented Mar 11, 2025

It appears that the problematic proxy requests are going to the Singularity HTTP server (URLs starting with "https://s-"), rather than to the proxy server (URLs starting with a number). This should not happen—all URLs should be rewritten from the former to the latter when performing a Hook and Control attack.

My guess is that this issue stems from how the application is presenting certain URLs, and Singularity is unable to translate them as intended.

@laurian19
Copy link
Author

I apologize for my confusion but would it be possible to explain again this insight? Are you saying that requests like the one for filename '/run/predict' are going to the HTTP server which runs SOO and not to the proxy server? Because as far as I notice, "Address 0.0.0.0:7860" is the only field missing in the problematic browser.

I checked with other similar services (I am inspecting local LLM deployment tools) and the same issue appears when running the Hook and Control attack. In the browser console I get similar errors to the ones from screenshot no 2 above.

Following your insight, I assume I will have to modify 'webSocketHook' function from 'payload.js', which handles the actual creation of a web socket and manages requests/responses. Is this correct?

@gdncc
Copy link
Collaborator

gdncc commented Mar 11, 2025

Is port 7860 actually the port on which you performed DNS rebinding? Could the application be listening on two different ports? Also, have you checked the Singularity server logs for anything noteworthy?

Regarding the specific endpoint ('/run/predict'), it appears the controlling (attacker) browser is switching from proxy requests (via the hooked browser) to direct requests (Singularity before DNS rebinding, the actual target service after DNS rebinding), which isn’t the intended behavior.

In your scenario, this works if both browsers run on the same machine because the attacker browser has direct connectivity to the target service—but it fails when the browsers are on different machines (the more realistic setup).

I wouldn’t recommend modifying the webSocketHook() function yet, until we pinpoint the root cause—whether it’s a Singularity bug or unexpected application behavior. In general, while Hook and Control is an interesting technique, it’s not necessarily the most efficient way to interact with a target service. A custom payload might be more suitable.

@laurian19
Copy link
Author

Thank you for your time and help!

I am employing this attack method because of the web interface the service is offering on port 7860 (this should also be the only port the application is running on). I am familiar with creating custom payloads but since this service does not offer a lot of interesting API endpoints on their documentation (e.g. being able to see/update/delete threads/models and so on), I considered this attack to be more interesting and powerful at the same time.

According to the Firefox victim browser console, the attack is successful (I am using ma with 1sec fetch interval):

Image

Also, I ran the server with the following command: "sudo ./singularity-server --HTTPServerPort 7860" and this is an example of what I found interesting on the server log:

Image

Although I have encountered that "mismatch" before, it did not really affect the process of the attack in other tries that I deployed on other services using "Simple Fetch Get" attack, for example. The server logs contain other similar requests to the ones from the bottom of the screenshot.

More than that, the configuration of the domain is at it follows:

Image

Checking the origin on the attacker browser (the problematic Firefox browser) yields an expected value:

Image

Regarding your explanation that "This should not happen—all URLs should be rewritten from the former to the latter when performing a Hook and Control attack.", I doubled checked with the DEF CON 27 presentation and it was the case there as well that a specific '/credentials' endpoint was requested via an URL similar to "http://s- ... /credentials", but please tell me if I am wrong and I did not understand some aspects correctly.

@gdncc
Copy link
Collaborator

gdncc commented Mar 13, 2025

It seems that you are using the text-generation-webui application based on your screenshots. I've tried it, and it is indeed vulnerable to DNS rebinding attack, at least in its default configuration (launched with ./start_linux.sh).

I could reproduce the issue you experienced with the Hook and Control attack payload, where several requests work fine, while others do not. The reason appears to be that this application generates a root URL, for example http://attacker.com:7680, on the first connection (in our case, the hooked browser). The application then derives further URLs from this root URL to access certain resources, for example http://attacker.com:7680/run/predict, while other resources are accessed via path-only URLs like "/asset/xyz.js". The Hook and Control attack payload does not currently handle the root-based URLs.

The following manual workaround worked for me on Chrome. Once a client has been hooked via DNS rebinding, do the following on the attacker browser:

  1. Add a breakpoint where the JavaScript variable window.gradio_config is set on the (index) page in the Sources tab of Chrome DevTools.
  2. Reload the page.
  3. When execution stops at the breakpoint, step through until just after the variable is set.
  4. In the browser console, change window.gradio_config.root to the proxy address, for example http://yoursessionnumber.attacker.com:3129 (The URL in the attacker browser URL bar, without the final slash after the port number).
  5. Resume execution of the page.

The application should then be fully functional from the attacker browser.

@laurian19
Copy link
Author

Thank you again for the precious help!

In the end, it worked for me as well.

Would it be possible to apply the same trick on the 'base' element if it is set in the 'head' HTML tag of the (index) page:

Image

I tried the same approach here but without succeeding. I have also tried to set a DOM breakpoint on the 'base' element which is triggered upon 'subtree modifications' and 'attribute modifications' but again without any success. I read about some browser extensions that allow you to inject code before the one of the webpage loads, but I thought about asking for some advice before I continue with this.

@gdncc
Copy link
Collaborator

gdncc commented Mar 13, 2025

You could use an intercepting HTTP proxy such as BurpSuite to modify the HTTP response going to the attacker browser, or write your own Singularity attack payload to perform live replacement of a given string before it is sent to the attacker browser from the hooked browser. A browser extension on the attacker browser may work too.

@laurian19
Copy link
Author

Thank you! I managed to make it work manually with a HTTP proxy, for now!

However, as I continued my analysis, I noticed that the conversations and messages of a LLM which runs locally using another specific service, are stored in a database in the browser's indexedDB. I do not think it would be possible to retrieve this information and sent it to the attacker browser or controlled website, independent of the attack method which is employed, but it might be the case that I am missing something,

Can you please give me your advice on this specific matter?

This is how the conversations are being stored:

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants