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
unauthenticated server-side request forgery - login page allows ssh to to localhost [CVE-2020-35850] #15077
Comments
|
@passtheticket and I had a previous email exchange about this. Reproducing/summarizing here. It seems to me that the firewall bypass is the primary issue here, right? Everything in your steps works exactly as designed. There is no need to intercept and edit the HTTP request (as in step 3), you can just directly set "Connect to:" to 127.0.0.1. This is even the standard mode of operation on CoreOS, Atomic, and similar container OSes (authentication docs, cockpit/ws container). There are two cases to consider:
I don't think 2. is a big real-life issue, to be honest. A typical bastion host has no user accounts/passwords and either does not have SSH at all (if it's just a container) or would have SSH anyway to administer the bastion host. Video 1.mp4 roughly corresponds to my "second use case" of a bastion host. Here we can think about preventing localhost logins by default, and enabling it through a config option. Let's track that in this issue. Video 2.mp4 is more or less my "first use case" that I described in my previous email. As the cockpit webserver is strictly more powerful/capable than ssh, I don't consider this "firewall bypass" a security issue. Video 3.mp4 (probing another port) is similar, if we disable localhost for cockpit-ssh by default on the login page, that would be avoided as well. |
|
My initial classification of this is somewhere between "enhancement" and "mild unexpected security-related issue", so let's not rush this. For people who are concerned about this, the immediate remediation is to configure SSH to not accept connections on the loopback interface. (Really, firewalls are overrated!) One option is to document exactly that fact and remediation in the A backwards-incompatible alternative is to change So currently my favorite is the first, i.e. documentation plus writing an integration test case that proves that disallowing localhost connections in sshd works as documented. @mvollmer, @allisonkarlitskaya, @stefwalter , I'd appreciate your opinion on this! @passtheticket : Many thanks for scrutinizing the login process, it is much appreciated! |
|
Intercept process is required! Using Burp is necessary because you need to constantly request different ports to detect this vulnerability. You cannot do this on the login panel. |
You can specify a port, like
Right, that's what I meant with "opening the cockpit port is strictly more powerful than SSH". If you can successfully log in to Cockpit, then you have the equivalent power of an SSH session. If you can't log in (wrong credentials), then you can still probe whether a port is open, that is correct (but you can't establish a full TCP connection). I suppose the latter is what your issue is about, and what I proposed to address above. I mostly just wanted to ensure that we are really talking about the same thing.
What do you mean by this? The user can already specify a port. If you don't, then :22 (ssh) is the default, but that's not in the least security relevant -- it's just convenience. Just as you don't have to specify |
|
Using Burp is necessary because you need to constantly request different ports to detect this vulnerability. and port scanning or ssh service detecting. |
|
In this scenario , this vulnerability is not so critical . However, SSRF can cause to vital security issue and I will continue my research . I believe that there is a ssrf vulnerability. @martinpitt, I hope we agree. |
|
I talked this over with @mvollmer, and we agreed about the proposal in general.
|
|
@passtheticket, we couldn't figure out how to fix this properly in Cockpit. What you report as a vulnerability is basic functionality of Cockpit, in our understanding. |
|
@mvollmer , I shared my finding as publicly. |
|
Hi @mvollmer, Chiming in I think there might be a bit of misunderstanding here. A user probably shouldn't be able to use this to find open ports from the perspective of the Cockpit server with the remote connect feature. It's a result of having the different failure modes presented when failing to connect to a host. A fix could be to always just return "401 Authentication Failed" for failures, and getting rid of this response code "401 Authentication failed: no-host". This might result in a bit worse UX as users can no longer tell whether they got their password wrong or if the host isn't allowing a connection but this is no different to username enumeration mitigations (e.g. https://blog.nvisium.com/time-based-username-enumeration). Instead you'd always just show the user 'connection failed'. You'd also have to find a way so that response times are similar, e.g. by adding a 10 second +- a few miliseconds delay for the other scenarios so you can't guess what's happening based on the response time. |
|
its possible getting RCE? |
|
halp, root pleaze |
|
Admins who are concerned about this, can set |
|
Reopening, as this currently only disables the "Connect to:" field, but not direct URL logins. I'll fix that. |
The current documentation of LoginTo= isn't very specific about what exactly happens with a "false" value; but it is plausible for an admin to assume that "false" would disallow logging into a remote host completely -- not merely hide the "Connect to:" field and then allowing a direct URL login anyway. It is sometimes important to disallow direct SSH logins from the login page on publicly exposed bastion hosts, as this functionality allows unauthenticated remote users to: - scan the internal network for existing hosts, which might otherwise not be accessible directly from the internet (Fixes cockpit-project#18540, https://bugzilla.redhat.com/show_bug.cgi?id=2167006) - scan the cockpit-ws host or internal network hosts for open ports (Fixes cockpit-project#15077, https://bugzilla.redhat.com/show_bug.cgi?id=2018741) So change ws to reject direct URL logins with `LoginTo=false`. This happens most naturally in cockpit_session_launch(), as we still want to allow remote URLs from the shell's host switcher in already authenticated sessions. This will not produce a very friendly error message, but it doesn't have to be -- at that point specifying direct URLs can be considered hacking anyway. Clarify the documentation accordingly.
The current documentation of LoginTo= isn't very specific about what exactly happens with a "false" value; but it is plausible for an admin to assume that "false" would disallow logging into a remote host completely -- not merely hide the "Connect to:" field and then allowing a direct URL login anyway. It is sometimes important to disallow direct SSH logins from the login page on publicly exposed bastion hosts, as this functionality allows unauthenticated remote users to: - scan the internal network for existing hosts, which might otherwise not be accessible directly from the internet (Fixes cockpit-project#18540, https://bugzilla.redhat.com/show_bug.cgi?id=2167006) - scan the cockpit-ws host or internal network hosts for open ports (Fixes cockpit-project#15077, https://bugzilla.redhat.com/show_bug.cgi?id=2018741) So change ws to reject direct URL logins with `LoginTo=false`. This happens most naturally in cockpit_session_launch(), as we still want to allow remote URLs from the shell's host switcher in already authenticated sessions. This will not produce a very friendly error message, but it doesn't have to be -- at that point specifying direct URLs can be considered hacking anyway. Clarify the documentation accordingly.
The current documentation of LoginTo= isn't very specific about what exactly happens with a "false" value; but it is plausible for an admin to assume that "false" would disallow logging into a remote host completely -- not merely hide the "Connect to:" field and then allowing a direct URL login anyway. It is sometimes important to disallow direct SSH logins from the login page on publicly exposed bastion hosts, as this functionality allows unauthenticated remote users to: - scan the internal network for existing hosts, which might otherwise not be accessible directly from the internet (Fixes #18540, https://bugzilla.redhat.com/show_bug.cgi?id=2167006) - scan the cockpit-ws host or internal network hosts for open ports (Fixes #15077, https://bugzilla.redhat.com/show_bug.cgi?id=2018741) So change ws to reject direct URL logins with `LoginTo=false`. This happens most naturally in cockpit_session_launch(), as we still want to allow remote URLs from the shell's host switcher in already authenticated sessions. This will not produce a very friendly error message, but it doesn't have to be -- at that point specifying direct URLs can be considered hacking anyway. Clarify the documentation accordingly.

Cockpit version: 234
OS: Ubuntu 18.04
Page: login
User can detect open ssh port or another open ports on server that services Cockpit last version. This is a vulnerability that allows an user send request to internal hosts for detecting open ports. So that firewall configuration can be bypassed or the server can be used like gateway by malicious user.
In addition, user induces the application to make an request back to the server that is hosting Cockpit.
For example: if system admin creates iptables rule to drop all packets that come to 22 port or another port, user can detect whether port 22 is open or not.
Assuming that there is a iptables rule which port 22 is open for 127.0.0.1 (loopback interface) but is closed for other interfaces
Steps to reproduce:
On login panel,
1-Click Other Options.
2-Set 127.0.0.1 to Connect to field and send request with incorrect credentials.
3-Intercept the request with Burp Suite
4- If ssh service is open on port 22 and credentials are wrong, server returns "401 Authentication Failed" response.
5-If user tries connect to a port that accepts data for ssh connection , server returns "401 Authentication failed: no-host" response and waits 10 seconds.
6- If user tries connect to a closed port , server returns "401 Authentication failed: no-host" response and without waiting.
7- If ssh service is open on port 22 and credentials are correct, server returns "200" response:
PoC video 1
PoC video 2
PoC video 3
The text was updated successfully, but these errors were encountered: