In my BRKSEC-2031 session at the Orlando Cisco Live 2018, I talk about how to leverage the XML(ish) API that ASDM uses to communicate with an ASA (both legacy and NGFW ASAs).
Introduction
Part 1 of this blog post will be a short "how to" on performing an man-in-the-middle (MiTM) on an ASDM session to gain insight into how to write python code to "act like an ASDM session". Part II will focus on some sample Python code to take advantage of the programmability that becomes available to legacy and NGFW ASAs as a result of this knowledge.
Disclaimers:
- These thoughts are my own and do not represent my employer or Cisco and Cisco offers no endorsement or support, implied or otherwise for this article.
- NEVER run a production ASA with weak SSL/TLS encryption
- Yes, I know there is an ASA API, but it is not available for legacy ASAs that are not capable of running 9.3.2+. And, I have a fleet of both legacy ASAs (9.1) and NGFW ASA-X (9.8) devices to manage, and I would prefer to use ONE method to manage them ALL.
Materials
- VMWare Fusion running on MacOS X
- ASAv Software (Evaluation, unlicensed available here)
- ASDM Software (Available here)
- Wireshark (Available here)
Overview
In Part I, the following steps will outline how to:
- Configure the ASAv management interface
- Create and export a keypair used for ASDM management on the ASAv
- Extract the private key from the keypair
- Load the private key into Wireshark for TLS session decryption
- Examine some ASDM payloads
1. Configure the ASAv Management Interface
On MacOS, there are 2 vmnet interfaces that are installed and configured by default. Per this article, these interfaces are:
vmnet1 = Host Only Adapter
vmnet8 = NAT network adapter
We are using the vmnet1, host only adapter ("Private to my Mac"), which should be what the first network adapter should be set to in the VM settings.
In your Mac terminal, record the IP address and subnet mask of vmnet1, 172.16.127.1/24 in my case.
Once you have installed the OVF of ASAv and started the virtual machine, log into the ASAv via the VMWare Fusion console and configure the management interface and local HTTP (ASDM) server listening on port 8443.
Configure ASAv for ASDM Management |
---|
int management 0/0 nameif management ip address 172.16.127.127 255.255.255.0 no shut ! enable password sanjose !
http server enable 8443 http 172.16.127.0 255.255.255.0 management ! aaa authentication ssh console LOCAL aaa authentication http console LOCAL aaa authorization exec LOCAL auto-enable ! username cisco password sanfran priv 15 ! ssl cipher default custom "AES128-SHA"
|
Once you have this configured, the vmnet1 interface should now be reachable from the ASAv and the ASAv should be reachable from the Mac terminal, so you can SSH to the ASA and get out of the VMWare console.
2. Create and Export a Keypair on the ASAv
Create an Exportable Keypair |
---|
crypto key generate rsa label mitm-keypair modulus 2048 ! crypto ca trustpoint mitm-trustpoint enrollment self fqdn mitm.domain.int subject-name CN=mitm.domain.int,O=MyCompany,C=US,St=Texas,L=San Antonio keypair mitm-keypair exit ! crypto ca enroll mitm-trustpoint noconfirm ! ssl trust-point mitm management |
Export Keypair (From Global Config) |
---|
(config)# crypto ca export mitm-trustpoint pkcs12 abc123!
|
3. Extract the Private Key from the Keypair
Copy all of the text, including the -------BEGIN------- and ------END----- lines into a plain text document and save it as "keypair.b64". This is a Base64 encoded binary. We will need to decode the Base64, ASCII encoded file back to a binary and then convert that binary to a PEM file, where we will be able to see our private key in clear text. We will accomplish this using utilities from the OpenSSL package. Note that the following is accomplished in the Mac Terminal and not on the ASA.
Decode the Base64 Encoded Keypair |
---|
openssl base64 -in keypair.b64 -d -out keypair.bin |
Convert the PKCS12 Binary to PEM and Print |
---|
openssl pkcs12 -in keypair.bin -out keypair.pem -nocerts -nodes |
Copy the private key, including the -------BEGIN------- and ------END----- lines into a plain text document and save it as "key.pem". We will use this file in the nest step when we configure Wireshark.
4. Load the Private Key into Wireshark
In Wireshark,
Preferences --> Protocols --> SSL --> RSA Key List --> Edit --> Browse to your key.pem file
IP 172.16.127.127, Protocol HTTP, Port 8443
5. Start Your Capture on the vmnet1 Interface
6. Fire Up ASDM
If you are decrypting the SSL session properly, you should see some green highlighted lines with HTTP GET statements.
7. Follow the SSL Stream and Examine the HTTP Request and the HTTP Responses
Find one of the HTTP GET requests where the URL starts with GET /admin/exec/
Right click the HTTP Get line select Follow --> SSL Stream
You will learn a lot by simply analyzing the HTTP headers, requests, and responses.
By analyzing the above output, we can infer that show commands are made using HTTP GET actions and multiple show commands can be strung together with a slash separating the commands. Furthermore, we can deduce that spaces are represented by a plus symbol.
GET /admin/exec/show+version/show+curpriv/perfmon+interval+10/show+asdm+sessions/show+firewall/show+mode/changeto+system/
Now, make a change to the ASA, like setting the interface name of Gig 0/0.
This time, look for an HTTP POST method in your Wireshark capture. I used the handy "Find Packet" and "string" filter looking for POST in my captures to locate the SSL stream that I want to examine.
Again, right click and follow the SSL stream to see the HTTP request and response.
This time, we see that we have an XML structure in the data payload for the HTTP POST request.
<?xml version="1.0" encoding="ISO-8859-1"?>
<config-data config-action="merge" errors="continue">
<cli id="0">Interface GigabitEthernet0/0</cli>
<cli id="1">nameif INTERNET</cli>
</config-data>
So, we can conclude that the configuration commands are executed in order based on the <cli id="x"> payload, where x is the numeric order of the commands. (0, 1, 2, 3.....n)
Conclusion of Part I
We now have enough information to begin to reconstruct what ASDM is doing to manipulate the ASA. In Part II, we will cobble together a simple script that executes some actions on the ASA, get the returned output from the ASA and use that data to construct some meaningful information.