NSA ShadowBrokers Leak: Analyzing 'EPICHERO'


On April 8th, 2017, a moderately well-known group known as ShadownBrokers released a password to decipher the file known as EQGRP-Auction-Files posted in medium.com.

A few hours later the IT sec community on social media (Twitter, Reddit, etc) was busy analyzing the leak.

This article is about the reverse engineering of the exploit found in the leak and to be a bit more specific about the exploit known as EPICHERO.

EPICHERO is a RCE (zero-day) with ROOT privileges in Avaya Communication Manager. The vulnerability resides in the CGI /auth-cgi-bin/distUpgReq whose POST licfile parameter is vulnerable to Command Injection.


  • Vulnerable Product

EPICHERO, according to the documentation found in the leak is a zero day (at the moment there isn't a public CVE that references the bug), RCE with privileges of ROOT in Avaya call server for the version S8710-013-00.0.340.3.

'Avaya call server' is a generic name, which according to the documentation (Page 7, Paragraph 1.1) refers to its hardware Appliance, that runs the software Avaya Communication Manager.
Because of this it was impossible to try it in order to really verify that the exploit is functional and to specify all the vulnerable versions.

The impact of the vulnerability beyond being a code execution is more than remarkable, the S8710 server is a commercial server for routing voice, data and video.
Because of this, compromising this server could sniff the routed traffic and as a consequence, record SIP calls, redirect them or exploit any known techniques against a SIP server.

Beyond that, given the large scope of the leak and his source (NSA) it is posible that we're a little ahead of an exploit that is fully operational.

  • First Look

A quick look at the exploit using 'file' gives us the following information:

eh.1.1.0.0: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.2.5, not stripped

It is a ELF binary which wasn't stripped. This made it quite a bit easier to do reversing on it to maintain names of functions and global variables!

Using 'strings, we get to two pretty interesting strings....

GCC: (GNU) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)

Versions for GCC and OS used by the exploit writer.

and the most important...

TYPE=licxfer&ftp=%s&source=/var/home/ftp/pub&version=NA&licfile=;echo "

  • Functionalities
Exploit parameters

As you can see in the image the exploit permits:
  • Specify the name of the log file.
  • Save MAC times of the modified files
  • Indicate a script as a payload
  • Run the last one as ROOT
  • Do a scan for the version of the server.

  • Reversing the exploit
We start reversing the main function, in a principle we only see a switch for parse the parameters.

Off the bat we start to notice something in particular: a strong error check 

For each function called in the exploit you can check its return code and in the case that a error came up a call to 'cleanup' is done. This is a function that cleans all the buffers used and/or open sockets permitting a clean way to close the exploit.

Cleanup function

This, together with the intensive log of each variable, shows that we are really see a professional exploit and not a simple PoC. You can really tell that someone put a lot of time into it to make it usable for pentesters beyond just the exploit writer.

We continued analyzing the main and some blocks that got our attention.

Private key?!

We have a certificate in PEM format and a private key!
But why is this here?
This is the information for the certificate, together with a match check between the certificate and the private key...

Match!
Common Name: 130.62.9.101
Organization: Avaya Inc.
Organization Unit: s8700
Country: US
Valid From: May 17, 2006
Valid To: May 9, 2036
Issuer: Avaya Call Server, Avaya Inc.
Serial Number: 5024b4b220060517120931

The certificate is signed by Avaya Inc. which corresponds with the documentation of the product which indicates that the certificates are self-signed by Avaya. Additionally, this was created for 130.62.9.101, probably one of the targets of the NSA for this exploit.

Ok, but how we use that? Because the certificate is self-signed by Avaya, there haven't the CA in any trusted store of an operating system or browser of your choice. As a result it's necessary to add the certificate to that store to be able to establish a HTTPS connection that the exploit needs.

Add Certificate and Key

But besides adding the certificate to the store does it add the private password to the Ctx object?
That's right... this is due to the fact that there is a function named 'client_comm' which is called one time from the main. This is responsible for creating the necessary SSL_CTX object to establish the SSL connection and check that the function of the client (likewise the server), works correctly in the exploit. Do you remember the strong errors check?

One of the exploit's functions is act as a scanner to be able to check the version of the Appliance. Lets check out how you can do that...

The function 'version_scan' builds line to line a Request POST HTTPS to /auth-cgi-bin/distUpgReq with the following parameters:

version_scan
TYPE=query&ftp=[VICTIM_IP]&source=/var/home/ftp/pub&version=NA

Parse the response looking for the substrings:

version=
patch=
sid=
mid=

After it looks for a '\n' at the end of those substrings, its starts printing in the console (in verbose mode) the result of each substring searched.

We finally got the 'exploit' function!
In this function we found quite a surprise. There's dead code... code that doesn't execute ever as a result of the two global variables that don't have instances at any time during the exploit.
These global variables are named 'BinFile' and 'AscFile' and later on we will be able to see the results of search all the instructions that refers to them in the exploit.


 It doesn't set any values ...
It doesn't set any values ...

You can't set it using eax either...
The best theory that we came up with about this, is that the exploit writer due to lack of time refactor the sending of files and execution, forgetting about this block of code and or leaving it alone because he was never going to be able run it suceessfully.
Dead Basic blocks 

While, putting this aside for a second, the exploit follows this path.
  1. Create 2 random paths in /tmp/%d and another in /tftpboot/%d. Replacing %d with a random number. 
  2. Appear dead code inside of if(BinFile) and if(AscFile), and as we saw, this will not ever run. 

 A loop that reads each 1024 bytes of a specified payload from a file, to be encoded with URL encode. 

If it is the first line read and if it asked for root privileges for the script file:
  • It makes a command that moves everything in /tftpboot/%random_number (a backup) to /opt/ws/%original_name/webupgrade (It's original site) and eliminates this backup.
  • It concates to a buffer, the command of the payload read and after the command from the previous bridge
 If it isn't the first line read:
  1. We copied this line of the payload to the buffer.

When this buffer is full (> 724 ) in this latter iteration of the loop.
  • It makes use of snd_n_append sending the saved command in the previous buffer and it saves everything in the first random path in /tmp, which we will call path_random1.

This occurs in an infinite loop until it finishes reading the payload script of the user. Here is when everything happens...
  1. If there was a pending command about to send, it is sent using snd_n_append.
  2. Build a command that erases the two random paths created (path_random1 and path_random2) and this is written in path_random1.
  3. In path_random2 it writes a command that runs the path_random1 file redirecting the streams to a /dev/null.
  4. If the user asked for Root priveleges:
    1. It saves the MAC of all the files and directories in /opt. Additionally, it changes it's MAC to that instant.
    2. The same with tftpboot/
    3. The same goes for /opt/ws/
    4. It makes a link of each file and directory of /opt/ws/*/webupgrade (except the links) to the tftpboot path.
    5. It runs sudo /opt/ws/webinstall modifyFileEntry /opt/ws/webupgrade "." "/opt/ws/functions | . %path_random2 | exit
    6. It runs: sudo /opt/ws/webupgrade
  5. If the user didn't ask for Root: It runs directly the %path_random2
  6. If the user proportions the files whose MAC wants to change, the exploit sets the MAC to real-time for each file. 
Great... Now we have the execution of the code and all the functionalities of the exploit pretty reasonably explained. 

A simple way, the %path_random2 file to end up running %path_random1 (which contains the payload of the user). Additionally, the necessary commands are run in order to change the MAC for files and directories like as was done for commands to gain ROOT privileges.
This is possible using 'sudo', because the user that runs the vulnerable code has access for the 'sudo' use. This is a bad security practice for users that run services such as HTTP servers.
For the binaries run in /opt/ws, due to not have access to the software and on the internet there is documentation for them we can't specify anything.

Great!!!... we already have everything, but which one is the vulnerability?!

The vulnerability is exploited in the bld_n_snd_http function. Look for yourselves...

Parameter licfile
'aTypeLicxFerF_7' is the string format that creates the POST parameters which are sent in the Request POST via HTTPS to a CGI in /auth-cgi-bin/distUpgReq.

Can you see the ;echo in the licfile parameter? This is clearly a Command Injection, the CGI concate licfile parameter in the command that will be run in a shell. This is the way the NSA's exploit achieved code execution.
The function snd_n_append mentioned earlier, that wrote a file in the remote system is simply a Wrapper of this last function.
It reads the sent files by parameters and after it calls bld_n_snd_http passing as a parameter a string with all POST parameters of this CGI.

To wrap things up, I would like to mention that there is a script in the leak /Linux/bin/epichero/cleanup.script which does an inspection for the logs of apache and erases any trace of the exploit in a pretty detailed way. On top of this, it restores the backups of the directory /opt/ws and eliminates the file /var/iglut/upg_status.dat

Lastly, an interesting piece of information in the same directory of this script is the reverse shell used by NSA and that contains the address IPv4 206.210.129.25 (Amphitheater Public Schools).
It could be possible that this is one of the servers hacked by NSA to hide traces of its Shells and exploits.

  • Conclusion: 

The exploit was developed with a lot of protective error checking. Features against forensic analysis such as changing the MAC of the files and directories in addition to a strong log of each action done by the exploit. All of this shows the huge amoung of effort dedicated to creating the most effective and ''sneaky'' exploit possible to avoid tipping off any alerts as was done, also in the obtention and use of violated servers previously to use how receivers of its Reverse Shells an be more stealth.

Credits
Author: 
Ezequiel Tavella (@EzequielTBH) - Infobyte Security Research Lab (@infobytesec)

Contributions:
Josh Mador - Infobyte Security
Federico Kirschbaum - Infobyte Security
Post a Comment
Thanks for your comment