The Cisco AnyConnect (CAC) Secure Mobility Client doesn’t have the brightest security track record. CVE-2015-4211 and CVE-2015-6305 are only two out of the fourteen CVEs that have been assigned to it just in 2015. This spiked my curiosity and prompted me to confirm if Cisco had properly fixed the underlying issue of these vulnerabilities.
In this multi-part article, I will explain how I reverse engineered CAC (one of its binaries and a network protocol used by it) to understand how the vulnerable functionality worked and how it could be further exploited. From Google Project Zero advisory and respective proof of concept (POC) code, I learned that:
vpndownloader.exebinary is vulnerable to DLL planting.
Having a look at the current connections, it is possible to identify that the
vpnui.exe process is connected to port
62522, which is open by the
After attaching a debugger to the
vpnagent.exe process and inspecting the assembly code for a while, it was possible to understand that the code that deals with the commands serialization into and from network packets is contained in the
vpncommon.dll library. This library exported symbols shedded some light on the existing commands.
The name of the exported symbols indicate that the protocol being used is based on a Type, Length and Value (TLV) structure and is used in a Inter-Process Communication (IPC) mechanism. One interesting TLV available is the
It seemed that this command is the one that was being used to exploit the vulnerabilities. Looking at the functions of the
CLaunchClientAppTlv class, I noticed that one of the constructors receives as a parameter, a reference to an instance of a class called
CIpcMessage. Once again the exported symbols of the
vpncommon.dll library help understand what this class is all about.
Reconstructing the class from the exported symbols undecorated name and by looking at the disassembled code of the get methods of the class, I was able to understand how the class fields are organized and the type of each field.
Taking the network packet created by the Google POC into consideration, it was clear that these fields map one-to-one with the data sent to the socket.
returnIpcObjectwhich all combined have the same length as a GUID.
In the next part of this article, I will focus on the packets being sent over the socket. Hope it was an interesting read :)