Browse / CVEs / CVE-2021-27877
CVE-2021-27877· veritas / backup exec
Veritas Backup Exec - Broken Authentication
Exploited in the wild. Listed by CISA on 2023-04-07; known to be used by ransomware.
An issue was discovered in Veritas Backup Exec before 21.2. It supports multiple authentication schemes- SHA authentication is one of these. This authentication scheme is no longer used in current versions of the product, but hadn't yet been disabled. An attacker could remotely exploit this scheme to gain unauthorized access to an Agent and execute privileged commands.
Impact
Unauthenticated attackers can exploit the deprecated SHA authentication scheme to bypass authentication and gain unauthorized access to Backup Exec Agents, potentially executing privileged commands and compromising backup systems.
Fix
Upgrade to Veritas Backup Exec version 21.2 or later that disables the insecure SHA authentication scheme.
How to confirm it
Positive when: success == true and compare_versions(version, '< 9.3')Run it with nuclei: nuclei -id CVE-2021-27877 -u <target>
The full check
id: CVE-2021-27877
info:
name: Veritas Backup Exec - Broken Authentication
author: pussycat0x,DhiyaneshDK
severity: high
description: |
An issue was discovered in Veritas Backup Exec before 21.2. It supports multiple authentication schemes- SHA authentication is one of these. This authentication scheme is no longer used in current versions of the product, but hadn't yet been disabled. An attacker could remotely exploit this scheme to gain unauthorized access to an Agent and execute privileged commands.
impact: |
Unauthenticated attackers can exploit the deprecated SHA authentication scheme to bypass authentication and gain unauthorized access to Backup Exec Agents, potentially executing privileged commands and compromising backup systems.
remediation: |
Upgrade to Veritas Backup Exec version 21.2 or later that disables the insecure SHA authentication scheme.
reference:
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/veritas/beagent_sha_auth_rce.rb
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N
cvss-score: 8.2
cve-id: CVE-2021-27877
epss-score: 0.6491
epss-percentile: 0.99253
cpe: cpe:2.3:a:veritas:backup_exec:*:*:*:*:*:*:*:*
metadata:
verified: true
vendor: veritas
product: backup_exec
shodan-query: product:"Veritas Backup Exec"
tags: cve,cve2021,network,js,tcp,passive,kev,vkev,vuln
javascript:
- pre-condition: |
isPortOpen(Host,Port);
code: |
let packet = bytes.NewBuffer();
const c = require("nuclei/net");
const cmd = "80000018000000010000000000000000000001080000000000000000"
packet.WriteString(cmd)
let conn = c.Open('tcp', `${Host}:${Port}`);
conn.SendHex(packet);
const result = conn.RecvFullString();
// Function to extract ASCII strings from various formats
function extractAsciiStrings(data) {
let asciiStrings = [];
let currentString = '';
if (data.includes('\\x')) {
// Split by \x and process each part
const parts = data.split('\\x');
for (let i = 1; i < parts.length; i++) { // Skip first empty part
const part = parts[i];
if (part.length === 0) continue;
// Handle single character
if (part.length === 1) {
const charCode = part.charCodeAt(0);
if (charCode >= 32 && charCode <= 126) { // Printable ASCII
currentString += part;
} else {
// End current string if we hit non-printable
if (currentString.length > 0) {
asciiStrings.push(currentString);
currentString = '';
}
}
} else if (part.length === 2) {
// Try to parse as hex
const hexValue = parseInt(part, 16);
if (!isNaN(hexValue) && hexValue >= 32 && hexValue <= 126) {
currentString += String.fromCharCode(hexValue);
} else {
// End current string if we hit non-printable
if (currentString.length > 0) {
asciiStrings.push(currentString);
currentString = '';
}
}
} else {
// Multiple characters - process each
for (let j = 0; j < part.length; j++) {
const charCode = part.charCodeAt(j);
if (charCode >= 32 && charCode <= 126) {
currentString += part[j];
} else {
// End current string if we hit non-printable
if (currentString.length > 0) {
asciiStrings.push(currentString);
currentString = '';
}
}
}
}
}
} else {
// If not \x format, process as raw string
for (let i = 0; i < data.length; i++) {
const charCode = data.charCodeAt(i);
if (charCode >= 32 && charCode <= 126) { // Printable ASCII
currentString += data[i];
} else {
// End current string if we hit non-printable
if (currentString.length > 0) {
asciiStrings.push(currentString);
currentString = '';
}
}
}
}
// Add final string if exists
if (currentString.length > 0) {
asciiStrings.push(currentString);
}
// Filter out empty strings and return non-empty ones
return asciiStrings.filter(s => s.length > 0);
}
const asciiStrings = extractAsciiStrings(result);
const cleanResult = asciiStrings.join(' ');
Export(ToString(cleanResult));
args:
Host: "{{Host}}"
Port: 10000
matchers:
- type: dsl
dsl:
- "success == true"
- "compare_versions(version, '< 9.3')"
condition: and
extractors:
- type: regex
part: response
group: 1
name: version
regex:
- 'Remote Agent for NT ([0-9.]+)'References
Use this check only on systems you are authorised to test. Where the data comes from