The Antivirus Hacker's Handbook (2015)
Part II. Antivirus Software Evasion
Chapter 10. Identifying the Attack Surface
The attack surface of any software is the exposed surface, which can be used by unauthorized users to discover and exploit vulnerabilities. The attack surface can be divided into two different groups: local and remote.
This chapter discusses how to identify the attack surface of antivirus software. To some extent, you can apply the techniques and tools described in this chapter to any software when determining where to aim your attack against your chosen Goliath. This chapter illustrates how to use tools provided by the operating system, as well as specialized tools that will aid you in identifying the local and remote attack surface and techniques to determine the odds of discovering “gold.”
The tools and techniques that you use will vary, depending on the components you are analyzing and the target operating systems. For example, in Unix-based operating systems, you can use the typical Unix toolset (ls, find, lsof, netstat, and so on). On Windows platforms, you need specific tools, namely, the Sysinternals Suite, and a few additional third-party tools to get the same insights.
The attack surface of any program is typically separated into two stages or parts: local and remote. The local attack surface, which is carried by a local user on the machine, can be leveraged, for example, to escalate privileges from a normal user (with only privileges to read and write to his or her profile or documents directory) to an administrator or root user. Sometimes a local attack can be used to trigger a denial of service (DoS) on the machine by causing the attacked software to behave differently or to consume too many resources, thus rendering the machine unusable. On the other hand, an attack surface is dubbed a remote attack surface when an attacker mounts exploits remotely without local access to the machine. For example, server software such as a web server or a web application may present a wide remote surface for attackers to leverage and exploit. Similarly, a network service listening for client connections that is vulnerable to a buffer overflow or (as is common in the case of antivirus software) a bug in the parser of a specific file format can be exploited by sending a malformed file via email. This attack may cause the network service to crash or to consume a lot of resources in the targeted machine.
Some security researchers make a distinction between remote attack surfaces on a Local Area Network (LAN) or intranet and attack surfaces carried over a Wide Area Network (WAN) or the Internet. An example of a LAN remote attack is when the network services can only be reached from the intranet, for example, an antivirus remote administration panel (such as the vulnerability in the eScan Malware Admin software that is discussed in Chapter 13). Other services can be attacked from the Internet, as in the previous mail gateway example.
Because it is often more interesting to research the remote attack surface, many researchers focus only on the remote side to exploit an antivirus application. However, you should also research the local attack surface because you may need to write a multi-stage exploit to fully “own” the target machine. For example, first, a remote vulnerability is exploited, gaining limited privileges (Apache running as the www-data account in Linux or a server running as a non-administrator user in Windows). Then, a local escalation-of-privilege bug is used to get full privileges (root, local system, or even kernel-level access, depending on the operating system and vulnerability type) on the target. Do not exclusively focus on remote vulnerabilities; later on, you may need one (or more) local vulnerabilities to write a full remote root exploit. Nowadays, exploiting a remote vulnerability in antivirus software often means instantaneous root or local system access because the attacked service (or services) is already running with elevated privileges.
In the past, exploiting browsers, document readers, and other client-side applications required just one shot to gain access to logged-in user privileges and, if required, one more bug to get full root or local system privileges. Today, exploiting most (security-aware) client-side applications requires a sandbox escape, followed by finding a bug in the sandbox or in the underlying operating system (or kernel) just to execute code with the logged-in user privileges. In the near future, security researchers expect that antivirus products will offer the same features (sandboxing code), thus turning it sine qua non to also research the local attack surface to fully own the targeted product.
Understanding the Local Attack Surface
The local attack surface, as previously explained, is exposed to attackers with access to local machine resources, such as the local disk, memory, processes, and so on. To determine which components of the targeted antivirus are exposed, you need to understand the concepts listed here:
· Privileges for files and directories
· Set user ID (SUID) or set group ID (SGID) binaries on Unix-based platforms
· Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP) status for programs and libraries
· Wrong privileges on Windows objects
· Logical flaws
· Network services listening on the loopback adapter (127.0.0.1, ::1, or localhost)
· Kernel device drivers
Although other objects may be exposed, this list contains the most commonly exposed objects.
Finding Weaknesses in File and Directory Privileges
Although this is not a common bug or design flaw in antivirus software, some AV developers forget to set up privileges for the program's directory, or they leave the privileges of some files too open. One example, specific to Unix, is when a SUID or SGID program can be executed by any user when it is not required. (SUID- and SGID-specific issues will be discussed later in this chapter.) However, there are more problems that affect file and directory privileges. For example, the antivirus program Panda Global Protection, from versions 2011 to 2013, used to have read and write privileges set for all users (everyone) in the corresponding program's directory, thus allowing any local user to place programs, libraries, and other files in the same directory. To check the privileges of the installation directory in Windows, you can use Explorer or the command-line tool icacls and check the privileges of the corresponding directory.
In Unix or Linux, you can simply issue the following command:
$ ls -lga /opt/f-secure
drwxrwxr-x 5 root root 4096 abr 19 21:32 fsaua
drwxr-xr-x 3 root root 4096 abr 19 21:32 fsav
drwxrwxr-x 10 root root 4096 abr 19 21:32 fssp
This example shows the three directories installed by F-Secure Anti-Virus for Linux with the correct privileges. Only the user and group root have all privileges (read, write, and execute). Normal users can only read the directory contents and execute programs inside these directories. As a result, the problem of placing libraries and programs, modifying vital files, and so on, which affects Panda Global Protection, does not affect F-Secure Anti-Virus for Linux.
Escalation of Privileges
Discovering local escalation of privileges in antivirus products is very common. Buggy antivirus kernel drivers; bad permissions in files, directories, and access control lists (ACLs); bugs in installed hooks; and other bugs made it, likely, the most error prone area.
Escalation of privilege bugs are serious bugs that can lead to full system compromise. The importance of properly setting objects, folders, files, and ACLs along with proper input validation, especially from kernel mode code, cannot be stressed enough.
Incorrect Privileges in Files and Folders
Checking for incorrect privileges in files and folders should be in the top three checks in any auditor's list. Antivirus software, like any software out there, is not free of mistakes and errors, and, naturally, various antivirus vendors have had, and surely still have, vulnerabilities of this type.
A lot of vulnerabilities of this type have been discovered, for example, in the Panda antivirus products in the last years. Sometimes, such vulnerabilities are not simple mistakes made by the installer that can be fixed by changing the permissions for a folder or a specific file but rather due to dangerous design decisions. Old versions of the Panda antivirus products used to allow normal unprivileged users (not administrator users) to update the antivirus. Instead of creating a Windows service running as SYSTEM user that communicates with an application that a normal user can run, they decided to “fix” this problem by implementing one “clever” change that made the privileges for the Panda antivirus program files folder writeable by everyone.
This terrible software design mistake has been the cause of innumerable vulnerability reports, because it was enough to change or tweak some of Panda's services and components to regain escalation of privileges. For example, a person nicknamed tarkus sent a security advisory to exploit-db.com with the title “Panda Antivirus 2008 - Local Privilege Escalation Exploit.” The vulnerability he exploited was due to incorrect files privileges set by the installer. The installer made the %ProgramFiles%\Panda Security\Panda Antivirus 2008 directory writeable to everyone. In his proof-of-concept code, tarkus simply swaps the original pavsrv51.exe service executable with another malicious program with the same name. Unfortunately for Panda, because any user can write to this directory, it was possible to simply overwrite the main services. After rebooting the machine, the malicious application would be executed with SYSTEM privileges.
Incorrect Access Control Lists
From time to time, a process launched from a Windows service is left in a vulnerable state by calling SetSecurityDescriptorDACL for the process and passing a NULL ACL. This bug, which is typical in popular software database systems (IBM DB2 or Oracle have been vulnerable to such attacks in the past), naturally, can also be seen in antivirus software.
We continue talking about Panda antivirus, because this is the only antivirus software we are aware of that made this mistake. In Global Protection 2010, 2011, and 2012, at the very least, the processes WebProxy.EXE and SrvLoad.EXE were launched from other Panda services, running as local system. However, for some unknown reason, the antivirus engineers assigned a NULL ACL value to these processes, allowing any local user to do anything with them. A process with a NULL ACL value can be opened, modified, written to, and so on by any other local process. So, an attacker could, for example, inject a DLL using the typical CreateRemoteThread API into any of these two processes and gain SYSTEM privileges easily.
Another typically bug-prone area in antivirus products is in the kernel components. Every once in a while, a local vulnerability in an antivirus is discovered and it usually targets the kernel drivers. Sometimes, bugs in the kernel that aren't exploitable, such as a local denial of service, can still be used by the attackers to mount attacks. Often, the discovery of other kernel-level bugs can be reliably exploited in a local machine, allowing the escalation of privileges from a normal, less privileged user, to kernel privileges.
The importance of finding kernel-level vulnerabilities lies in the fact that from kernel mode, the attacker can perform any action on the system, like installing a malicious driver, writing directly to the disk with the aim of destroying its contents, hooking userland processes to steal data (like banking details sent by your browser to a bank web page), and literally anything else. To put this into greater perspective, some operating systems prevent even the root or administrator users from performing actions. However, executing code at kernel level is really game over.
Often, these kernel bugs are the result of improperly checking the input received by the kernel driver's I/O control code handlers (IOCTLS). Kernel driver bugs can occur at many other levels, like in installed hook handlers for example. Antivirus products usually install hooks into common file I/O functions (like CreateFile) in userland and/or kernel-land. Naturally, the hooks to these functions must be written with the proper care, but human programming errors happen.
As an example related to API hooking bugs, a vulnerability titled “Kingsoft AntiVirus 2012 KisKrnl.sys <= 2011.7.8.913 - Local Kernel Mode Privilege Escalation Exploit” pertaining to incorrectly handling API hooks was reported via exploit-db.com in 2011 by a person nicknamed MJ0011. The Kingsoft antivirus kernel driver implements a sandbox by installing various API hooks that check how the hooked APIs are called and used. The KisKrnl.sys driver did not check the ResultLength argument sent to the hooked Windows APINtQueryValueKey. Therefore, the attacker could pass any value in ResultLength, and the kernel driver could use that unchecked value for copying data. The proof-of-concept code sent by MJ0011, after successfully exploiting the driver, switched the screen display mode to text mode and displayed a message similarly to the way the blue screen of death (BSOD) in Microsoft Windows displays error messages before it crashes the computer.
There are various rare local bugs that can be understood only by looking at the big picture of the AV product and understanding its underlying design. An antivirus engine usually contains one or more scanners, as well as heuristics. Some heuristics, however, aren't launched directly by scanners, like a command-line or GUI scanner, but, rather, based on monitoring the runtime behavior of applications. Such heuristics are subject to the same bugs that can appear in scanners: bugs in code parsing file formats.
One example of this type of bug appeared with a proof-of-concept reported via exploit-db.com by Arash Allebrahim. He published an advisory with the title “QuickHeal AntiVirus 188.8.131.52 - Stack Overflow Vulnerability.” The vulnerability he discovered was a stack overflow in one of its system components and is triggered when analyzing modules that get injected into a running process. In his PoC, he injects a malicious DLL (with manipulated import table) into Internet Explorer that, when analyzed by the runtime heuristic engine, caused a classical Unicode stack overflow due to an overly long import name in the PE file. The bug only happens when a DLL is injected.
Exploiting SUID and SGID Binaries on Unix-Based Platforms
SUID and SGID are applied to executable files in Unix-based operating systems such as Solaris, FreeBSD, and Linux. Having either one or both of those bits set on executable files indicates that the program must be executed under the privileges of the owner user (SUID) or group (SGID). You can search for files with that bit set using the following commands:
$ find /directory -perm +4000 # For SUID files
$ find /directory -perm +8000 # For SGID files
For example, if you issue the command to find SUID applications inside the Dr.Web installation directory, you will discover the following:
$ find /opt/drweb/ -perm +4000
There are two SUID binaries: libdw_notify.so and drweb-escan.real. However, the privileges of these two binaries are too restrictive: only the root user or the drweb group can execute the binaries, which you can confirm by running the ls command:
$ ls –l /opt/drweb/drweb-escan.real
-rwsr-x--- 1 root drweb 223824 oct 22 2013 /opt/drweb/drweb-escan.real
Programs with the SUID or SGID bit set are, naturally, vulnerable to privilege escalations. If the program is not carefully coded or if it is intended to be used only by a specific user or group but permissions to execute the program are granted to all users, then any user can execute code as the owner user. What if the SUID or SGID program is owned by root? You guessed it: an attacker can gain root privileges.
An example of a real bug—albeit not specifically linked to bad privileges in their SUID binary but, rather, to a design problem—is a vulnerability in the eScan Malware Admin software. This web administration application is used to manage eScan antivirus installations and was designed with the idea of executing commands as root using whatever inputs were received from the end user of the web application (a very bad idea). Because a web application cannot execute commands as root, and due to one more design problem, the application needs to execute tasks as root; the developers “fixed” the problem by creating an SUID binary called /opt/MicroWorld/sbin/runasroot that runs commands with the inputs received from the web application. This was a bad idea because it caused various problems, especially when the web application contained vulnerabilities. A remote attacker could first gain the privileges of the mwadmin user (the privileges of the user running the web application). Then, because this user could execute this binary, the remote attacker could run the command runasroot to gain root privileges in the targeted machine.
So, in this case, the bug is not exactly a privileges issue but the result of a wrong design choice. In fact, many vulnerabilities are often the result of bad design rather than a careless selection of privileges. Indeed, these vulnerabilities are always more difficult to fix, and it can even be a problem, because it would imply a change in the design of the software.
ASLR and DEP Status for Programs and Binaries
Both Address Space Layout Randomization (ASLR) and Data Execution Prevention (DEP) exploit mitigations that are implemented in recent operating systems. ASLR means that the address space the program and libraries are loaded to will be random instead of predictable (as specified in the executable header or preferred base loading address). This randomness makes it more difficult to guess an address or an offset inside a buffer with the special chunk of code or data an attacker needs for writing an exploit. Some operating systems, such as Mac OS X and Linux, force all programs and libraries to adhere to ASLR (depending on some kernel tweaks), but Windows enables ASLR only when the program was built with that option enabled. This has been the default choice when building C or C++ applications with Microsoft Visual Studio since 2002. However, some old applications were built using old versions of the compiler, or their developers deliberately disabled ASLR (often citing performance reasons, even though that does not make any sense). While not having ASLR enabled for the main process or for the libraries cannot be considered a vulnerability in itself, it is useful from an attacker's point of view because it allows the attacker to determine how easy or difficult the exploitation of memory corruption bugs will be.
DEP is used to prevent memory pages not explicitly marked as executable from being executed. Any attempt to execute such data pages will result in an exception. The proper security practice is to assign pages read and write or read and execute privileges but never read, write, and execute privileges. As with ASLR, if a program does not enforce DEP, that does not mean there is a vulnerability; however, exploitation will be easier. In the days before DEP, a stack buffer overflow would directly result in code execution from the stack!
On Windows, you can check the status of ASLR and DEP for your target program or module using Process Explorer (the program is called procexp.exe) from the Sysinternals Suite.
Figure 10.1 shows that the Bitdefender Security Service, the resident analyzer, enables DEP permanently (eighth column in the processes panel) for the process; however, neither the main program (vsserv.exe) nor most of the libraries are ASLR enabled (fifth column in the lower panel). This makes it trivial for an exploit writer to use any code chunk from these libraries or a set of hard-coded offsets matching some special pattern to write a reliable exploit. In any case, even when ASLR is not enabled for one process or library, you cannot be certain that the loading address will be the one that you got when taking a first look with Process Explorer or another program. The loading addresses of ASLR-enabled libraries can conflict with the loading of the base address of the libraries you want to use for writing your exploit, and Windows may relocate them. Please note that, even in the case of Bitdefender, where most of its libraries are not ASLR-aware, the libraries from the OS may interfere with their base addresses and thus have them exhibit ASLR-like behavior.
Figure 10.1 Bitdefender Security Service without ASLR enabled for most libraries, as well as the main executable program
To find out which libraries do not conflict, you need to reboot a few times and write down the addresses of the libraries somewhere to verify that their base addresses remain stable across reboots. In the case of the Bitdefender Security Service, you do not need to do that because the main program, vsserv.exe, does not have ASLR enabled either, and executables are loaded before any library; as a result, you have a 100-percent reliable ASLR bypass due to the mistake made by the Bitdefender developers.
A more worrisome bug that is definitely a vulnerability happens when an antivirus program implements heuristic engines or “proactive protection” of processes (as it is commonly advertised) by injecting a dynamic link library (DLL) without ASLR enabled for that DLL. Because this DLL is injected in all running processes, the lack of ASLR has a similar effect to having ASLR disabled system-wide. One example is the Chinese antivirus product Kingsoft Internet Security (KIS), which is widely used in China and Japan. KIS implements an application-level firewall by injecting various DLLs in all user processes. However, the libraries do not have ASLR enabled, so it is easier to write exploits targeting KIS users.
As shown in Figure 10.2, all user processes, such as the Firefox browser, have the non-randomized protection library injected into their process space. If an attacker who does not have an ASLR bypass wants to exploit a Firefox vulnerability, he or she can use the antivirus-injected libraries to write a reliable exploit targeting certain KIS users, for example, in China or Japan. Unfortunately, the issue with this Chinese antivirus product is not isolated, and it affects various other antivirus products. Several of them are briefly discussed in the section “Security Enhanced Software.”
Figure 10.2 A set of three libraries without ASLR enabled, injected in the Firefox browser's memory space
Exploiting Incorrect Privileges on Windows Objects
Most local attacks against antivirus software in Windows operating systems involve abusing wrong privileges, ACLs, and other Windows objects for which an ACL can be assigned.
You can check the privileges and established ACLs with the WinObj (winobj.exe) tool from the Sysinternals Suite. You need to run this program as administrator to see the privileges of all objects. Once WinObj is running, you can check in the directory\BaseNamedObjects for all the object types and the privileges assigned to them. For example, if you are researching Kingsoft Antivirus, you need to search for Windows objects with names that start with the letter k. Figure 10.3 shows one such object: an event calledkws_down_files_scan_some_guid. If you double-click this kernel object, a new dialog box opens with two tabs. The Details tab shows general information about the Windows object, such as the number of references and handles opened. The Security tab shows the specific privileges of this object.
Figure 10.3 No ACL is set for the KIS event object, and WinObj warns that anybody can take control of the object.
The WinObj tool warns you that no permissions have been assigned to the event, so anybody can take control of this Windows object. The exact message is as follows:
No permissions have been assigned for this object. Warning: this is a potential security risk because anyone who can access this object can take ownership of it. The object's owner should assign permissions as soon as possible.
As with the ASLR and DEP example, not having assigned privileges to a Windows object does not necessarily mean that there is a vulnerability in an AV product. However, the odds of this object causing problems for the AV product or for some of its components are high. For example, what if you create a program that takes control of this object and revokes access to the object for all users? No other process would be able to open the event and, therefore, no notification would arrive through this channel. Another option is to signal this event continuously. This approach may cause a denial-of-service condition in the AV product because it was signaled when no event really happened. Another example is to create a program that continuously resets the event's state, in which case no notification at all would be received by the process or processes waiting for this event to be signaled. (You have to be able to reset the event object after it was signaled and before it is received by a watcher of this event object.)
Event and mutex objects are, perhaps, the least interesting Windows objects when auditing any Windows application. Other, more interesting object types can translate into easy escalation of privileges. The best example is when a thread object or a process object is not assigned an access control list. While this is a relatively infrequent problem, it does affect various AV programs, such as Panda Global Protection until 2014. The example here uses Panda Global Protection 2012. In contrast with the previous case involving Kingsoft Internet Security, this time you need to use not WinObj but rather the Sysinternals program Process Explorer, which is more suited to inspect user-mode threads and process objects. Once you have Panda Global Protection 2012 installed and running and you open Process Explorer, you can find Panda's process of interest, SrvLoad.exe (as shown in Figure 10.4).
Figure 10.4 This is an example of the Panda process SrvLoad running as SYSTEM with the highest integrity level and without any ACL set. This vulnerability was reported by the author and fixed in 2014.
Process Explorer informs you that the object—in this case, the whole process—does not have any ACL assigned. Thus, the object allows any local user to take control of this application, which, by the way, is running as local system with the highest integrity level (as the SYSTEM user). This error is not a common mistake because a process or a thread object, by default, inherits the privileges from the parent object, and software developers must explicitly call the function SetSecurityDescriptorDAL, giving it a NULL access control list. However, in many cases, programmers will call this function to make it easy for their own processes to open and interact with it. Unfortunately, it allows any other users on the local machine to do the same and more; a local exploit can open the process and inject a DLL by calling CreateRemoteThread, for example, to run code in the context of the SrvLoad.exe program and escalate privileges to local system.
Other Windows objects that you have to keep an eye on when looking for vulnerabilities in antivirus software (and in any other Windows software in general) are sections. A section object represents a section of memory that can be shared across processes. It is used by processes to share parts of its memory address space with other processes. Section objects can also be used to map a file into a process memory space. If a section does not have a correct set of privileges (a correct ACL) or if no privilege is applied at all on the section object, any user can read whatever is inside the section object. This may allow users to leak sensitive information such as passwords or to write malformed data to the shared section, which can potentially disrupt one or more antivirus processes.
In rare cases, shared sections actually contain executable code—snippets of binary code that are executed in one process and can be read or written from other processes. If no ACL is set or if the assigned set of privileges is wrong, the results can be devastating; any user could write executable code in the shared section, making the process (which is very likely running as SYSTEM) execute a piece of code chosen by an attacker. Although this bug appears to be rare, it actually affects a variety of commonly used antivirus products.
Exploiting Logical Flaws
Logical flaws, also called “business logic” bugs or flaws, are bugs that affect the logic of a process. They cannot be discovered by using basic auditing tools such as Process Explorer or WinObj. You need to use the de facto standard tool for reverse-engineering, IDA, as you will have to disassemble and check the logic behind the component of your targeted antivirus product to find the logical flaws.
As an example of a logical flaw, the Panda Global Protection 2011 to 2013 processes were protected by the “Panda's Shield.” This technology prevented (or tried to) any local processes from killing or injecting shellcode into the Panda analyzers and system services. However, for some reason, the developers integrated a backdoor into this technology that could enable or disable the shield. The library pavshld.dll exports a set of functions—all of them with human-readable names, except PAVSHLD_001 and PAVSHLD_002 (see Figure 10.5).
Figure 10.5 This list of functions is exported by the library pavshdl.dll.
When a library exports functions with mostly human-readable names, it often means that the developers want to hide the logic behind these functions. If you open the first function, PAVSHLD_001, in IDA, you will find the code shown in Figure 10.6.
Figure 10.6 This secret UUID can be used to disable the shield.
The commented disassembly shows that the Panda shield can be disabled if this function library is called by passing to it a “secret” UUID with the value ae217538-194a-4178-9a8f-2606b94d9f13. When the library function is called with the correct UUID, a set of writable registry keys (which are writable by the “Everyone” user) are updated, thus disabling Panda's antivirus shield. This logic flaw could also be discovered using another method: by checking the privileges of the corresponding Panda registry keys.
Understanding the Remote Attack Surface
The remote attack surface is the surface exposed to remote attackers who have access to an adjacent network (LAN) or who can target the antivirus remotely from an external network (WAN).
To determine what components of the targeted antivirus are exposed to remote attacks, you need to understand which components deal with remote data:
· Parsers for various file formats
· Generic detection and file disinfection code
· Network services, administration panels, and consoles
· Browser plug-ins
· Firewalls, intrusion detection systems, and their various network protocol parsers
· Update services
An antivirus product tries to protect almost any probable entry point that can lead to remote malicious attacks. As it turns out, when the antivirus product deploys extra protection mechanisms to protect from remote attacks, the attack surface is increased considerably. Some new attack vectors will emerge as soon as an antivirus product is installed on either a server or a desktop machine. For example, the introduction of a network packet filter driver (for the purpose of intrusion detection) may open a new attack surface via its network protocol parsers.
The following sections briefly describe each of the aforementioned remote attack surfaces.
Nowadays, some antivirus companies, like many other software vendors, perform regular source code security audits and try to apply safe programming practices in order to reduce the odds of having exploitable file format bugs. With all those extra precautions, the odds are very high that the audits will find vulnerabilities in the antivirus's native code that parses complex file formats such as Microsoft OLE2 files, PDF, ELF, PE, MachO, Zip, 7z, LZH, RAR, GZIP, BZIP2, LNK, Adobe Flash, MOV, AVI, ASF, CLASS, DEX, and so on.
As a matter of fact, during the audit I performed in 2014 with 19 antivirus products, file format bugs appeared in 14 AV engines; that is a very high number. In my opinion, it's probable that the other AV engines did not crash when parsing file formats after months of fuzzing because they use one of two things: either an emulator or virtual machine for running the file parsers, or file parsers written in non-native languages such as interpreted languages or managed code. Symantec, Microsoft, and Norton are examples of companies using these approaches.
Generic Detection and File Disinfection Code
Generic detection and file disinfection code deals with data that could be malicious and crafted by willful attackers. The generic detection routines, when they are not as simple as pattern matching, deal with user-provided input. For example, they may read integer fields from the input file that end up being interpreted as “size” parameters. These parameters would then be used in allocations or memory copying operations to decompress or decrypt (or both) a part of an encrypted or compressed program (or both).
To understand this idea, imagine a file infector (aka a virus) that infects a PE executable file and encrypts the original code section. When such an infected file is scanned, an AV's generic detection code needs to gather infection evidence before deeming the file infected. The detection code then needs to find where the original entry point (OEP) is, where the decryption key is stored, and where the virus is embedded in the PE file. The disinfection code uses this gathered information to disinfect the file and restore it to its original state. The gathered information, as read from the infected file, may include size, offset, and other fields that are controlled by the attacker. If the disinfection routines trust the data as read and perform no input sanity checks, the disinfection code may end up using the size fields in operations such as memcpy (leading to buffer overflows) or in integer arithmetic operations (leading to integer overflows, underflows, or truncation bugs). This would inadvertently introduce vulnerabilities into the disinfection code. Similarly, both generic detections and file disinfection code for obfuscated and/or compressed viruses (probably using Entry Point Obscuring [EPO], having to deal with new file formats and untrusted data, can pose equal security risks as PDF or OLE2 file format parsers.
Network Services, Administration Panels, and Consoles
The administration consoles and their client-side counterpart, the antivirus agents that connect to them, are subject to exploitation by an attacker. If the administration consoles and services that handle messages sent from the antivirus agents in the client desktop machines do not take extra care when dealing with the received input, they can open up vulnerabilities. For example, in the popular antivirus product AVG, the server component used to have a set of very serious weaknesses (one of them fixed and most of them not, as of this writing):
· Missing authentication—The authentication checks for the AVG Admin Console were done on the client side. Thus, any user with network access to that machine could log in to the Admin Console. From a security point of view, client-side checks for logging in are barely considered “logging in.”
· Missing entity authentication—The communication protocol did not provide any functionality to verify the identity of any of the communication partners. It allowed an attacker to pose as one AVG endpoint or as a rogue administration server.
· Static encryption keys and insecure modes of operation—The protocol used Blowfish as the chosen encryption cipher. However, the symmetric keys were hard-coded in the binaries (in both the client- and server-side components), so any user passively listening to the communications could decrypt them. Also, the cipher was used in Electronic Code Book (ECB) mode, which enables various attacks against the cipher-text (such as known plaintext attacks).
· Remote code execution—One of the parameters sent from client to server was the ClientLibraryName parameter. It was the path to a DLL that would be loaded by the AVG Admin Server. If this parameter pointed to a remote path (a library in a Universal Naming Convention [UNC] path), it would be remotely loaded and the code in that library would be executed in the context of the AVG Admin Server, which runs as SYSTEM. This very serious security bug is extremely easy to exploit.
For more details on these vulnerabilities, you can go to the following URL, which contains the complete advisory written by SEC Consult Vulnerability Lab: https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20140508-0_AVG_Remote_Administration_Multiple_critical_vulnerabilities_v10.txt.
I also recommend looking at the included timeline, which is both funny and sad.
Firewalls, Intrusion Detection Systems, and Their Parsers
Most recent antivirus products offer capabilities to analyze network traffic and to detect malicious programs that are being downloaded or typical network traces of known worms, file infectors, Trojans, and so on. Such attacks can be neutralized at the desktop machine by using Intrusion Protection Systems (IPS). These systems inspect all traffic the machine receives, and this requires antivirus engineers to develop code to parse and decode network traffic. Network protocol parsers can be exploited in exactly the same manner that file format parsers can. What are the odds of correctly parsing, say, the HTTP protocol? Although it is complex, it can be done and (maybe) free of bugs. But what about the odds of not having a single vulnerability in the code handling and parsing of ARP, IP, TCP, UDP, SNMP, SMTP, POP3, Oracle TNS, CIFS, and other network protocols? The odds are exactly the same as with file parsers: they are very likely to have vulnerabilities.
Update services, along with disinfection routines, are less-researched areas of common AV products. Nonetheless, update services still constitute an entry point for remote attacks. To give you an example, imagine what happens when an AV update service downloads its updates from an HTTP server without using SSL or TLS, like most antivirus products do. In that case, if the update service downloads a new executable file (such as a Windows PE executable or library), the attacker may be able to intercept the traffic and serve malicious, modified, or completely fake updates. The attacker would be able to use the update channel to subsequently install malware on the machine, which would be executed in the context of the antivirus. In that case, the malicious code would receive the special treatment of being executed as SYSTEM while being protected by the antivirus shield, thus making it really difficult to detect and remove.
This vulnerability, via the update service channel, may look improbable at first, but it exists in various antivirus products. One such bug, found in the Russian Dr.Web antivirus product, is discussed in later chapters.
Browser plug-ins are installed for the most popular browsers by many antivirus products to check the reputation of websites, URLs, and even the contents of downloaded files to determine whether they are malicious. These components are loaded in the context of the browser and are thus exposed to any attacker, on the LAN or WAN, as long as the attacker manages to trick the user into visiting a web page that the attacker controls. If the browser plug-in contains one or more vulnerabilities, they can be remotely exploited by the attacker, regardless of whether the desktop machine is behind a firewall.
Bugs in antivirus browser plug-ins were common when ActiveX was popular. Back then, many antivirus products developed small versions of their engines that could be embedded as an ActiveX control in web pages that would be rendered by Internet Explorer. By embedding the AV ActiveX in the browser, users who had not installed an actual antivirus product were able to test-drive that product. However, many such antivirus components were also vulnerable to a plethora of attacks: buffer overflows and design issues were the most common weaknesses.
For example, versions 2010 and 2011 of F-Secure Anti-Virus distributed an ActiveX component that was marked as safe for scripting and loadable in Internet Explorer; however, it was prone to a heap overflow bug that allowed attackers to gain code execution remotely. The vulnerability was discovered by the Garage4Hackers group, who published an exploit at www.exploit-db.com/exploits/17715/.
Another bug with browser plug-ins is illustrated by the Kaspersky antivirus ActiveX component AxKLSysInfo.dll, which was marked as safe for scripting and thus loadable in Internet Explorer without warnings. This ActiveX control enabled attackers to retrieve contents from FTP directories, thus, possibly allowing them to read information from FTP servers hidden behind firewalls. This is an example of a design failure that affected browser plug-ins.
There are even worse examples of design failures, such as the Comodo Antivirus ActiveX control. In 2008, this ActiveX exposed a function called ExecuteStr that, effectively, executed an operating system command. All the attacker had to do was to create a web page, embed the ActiveX control, and trick a user into visiting this web page with Internet Explorer. Then, because of this bug, the attacker could execute any operating system command in the context of the browser. This is just one serious vulnerability in an antivirus product, and it is not that surprising to discover that similar bugs also affected other antivirus products.
Security Enhanced Software
Most antivirus products usually install other applications in addition to the previously mentioned ones. Such applications, commonly labeled as “security enhanced” applications, are of great interest because they also expose an attack surface and aren't typically carefully developed. Example security enhanced applications are browsers created or modified by antivirus companies that are especially recommended by the antivirus company to be used for banking and other security critical usages where payments are made or money is involved in another way. There are even weather applications installed by antivirus products for which there is no other real purpose but to increase the attack surface with bloated and unsecure software. There are even cases where antivirus products install adware applications. This is the case, to name a few, of the free version of Avira or any version of Kingsoft (as all of them are free).
Especially when talking about the Asian market and more specifically the Chinese market, it's common to find localized browsers; they are very popular. For example, some antivirus products that install localized and security enhanced browsers are Rising or Kingsoft. The former installs a browser that mimics Internet Explorer with a Chinese user interface. However, it's using the kernel of Internet Explorer version 7, the browser doesn't have any kind of sandbox, and, to make it even more interesting for an exploit developer, various modules used in this browser don't have ASLR enabled. Naturally, this opens the door to target not only the antivirus kernel, scanners, and so on but also the browser installed by the security suite, which is set as the default browser and recommended by Rising as the default browser. With Kingsoft, it's more curious, in the sense of disastrously interesting. The company distributes a browser, also localized in Chinese and called “Liebao” (the Chinese word for cheetah). This browser is a modified version of an old Google Chrome version. The last time I checked the browser, it made the following mistakes:
· It disabled the sandbox for no reason.
· It had many libraries without ASLR enabled that remain stable across reboots (for example, kshmpg.dll or iblocker.dll).
· It even installed a browser extension to take screenshots of your desktop!
Naturally, when one is determining how to attack an antivirus product, the most interesting target nowadays is the browser, which most AVs install. Also, remember that antivirus companies aren't very security aware from an engineering perspective and that these are secondary tools. These security enhanced browsers are not as carefully coded as, for example, the kernel (supposing the kernel is carefully coded, which is not that obvious to determine as one may think).
This chapter discussed how to identify the attack surface of antivirus software. The techniques learned in this chapter can be equally applied to find the attack surface for any other software. Attack surfaces are categorized into two types: local and remote.
The local attack surface is carried by a local user on the machine. The following is a short list of the types of local attack surfaces:
· Local privilege escalation via misconfigured files or directories privileges—Take, for example, the SUID and SGID bits on UNIX systems.
· Local denial-of-service attacks—These bombard the AV software with requests that will eventually slow it down, overwhelm it, or completely shut it down.
· The lack or improper use of compiler and operating system provided mitigations—On Windows, for instance, if the AV injects into processes one of its protection modules and if that module does not support ASLR, then each process becomes a candidate for malicious local attacks. Another example is when the AV is compiled without DEP support. Both examples make it easy to write a reliable exploit for the AV software in question.
· Bugs in the kernel device drivers of AV software—If the AV uses a driver, such as a filesystem filter or a self-protection driver, that communicates with user-mode components via IOCTLs, improper handling of buffers or logic bugs can lead to exploiting the device driver from user mode and achieving system-level code execution.
· Logical flaws resulting from programming or design errors—Such problems can lead to compromise. An example of that is when the AV has a backdoor facility that can be used to disable the AV. Once the attacker discovers this backdoor, he or she can use it during an attack. One point to keep in mind is that nothing is hidden from reverse-engineers. They will discover all secret backdoors eventually.
· Wrong privileges on Windows objects—Windows provides an elaborate system for setting ACLs on objects (mutex, events, thread objects, and so on). AV developers have to make sure they protect their system objects with the correct ACLs or else any unprivileged program, such a malware, can interact with those objects.
The remote attack surface is carried by an attacker remotely, without local access to the machine. Any component of the AV, exposed to wires or to untrusted input coming from wires, could cause a security risk. The following components constitute a viable remote attack vector:
· Parsers for various file formats—Malicious files and documents, when received by email, referenced via an img or iframe HTML tag or other untrusted means, can trigger security bugs in the AV engine and lead to compromise, as we have seen in previous chapters.
· Generic detection and file disinfection code—When disinfecting files, the AV will have to read and interpret bytes from the infected files in order to disinfect. When that's the case, bugs in the AV's disinfection routines can be triggered by the maliciously crafted infected files.
· Network services, administration panels, and consoles—Administration consoles and other web interfaces can be an entry point to your network. If, for instance, the AV's administration web interface executes privileged commands on behalf of the user, and if due to a bug, the user can control what command to pass to the web interface, then it is game over.
· Firewalls, intrusion detection systems, and their various network protocol parsers—This attack is very similar to the file format parser attacks. If there's a bug in a certain protocol parser, the attacker will send malicious packets to your firewall and trigger bugs remotely.
· Update services—As shown in Chapter 5, this is a serious attack vector that has adverse effects.
Before we conclude this chapter, it is worthwhile noting that researching remote attack surfaces is not superior to researching local attack surfaces. In fact, it is compounding the attacks on top of each other that leads to successful attacks: starting with a remote attack, getting inside the network, and then leveraging a local attack to escalate privilege and fully own the attacked machine.
The next chapter will discusses the various types of denial-of-service attacks and how they can be leveraged to completely cripple the AV or to disable it for a window of time while the attack is taking place.