RCE with BMC Server Automation

If you’ve ever come across BMC Server Automation during network scanning then you may have seen Nessus flag up a Critical vulnerability titled “BMC Server Automation RSCD Agent Weak ACL NSH Arbitrary Command Execution” (Nessus plugin ID 91947).

Arbitrary command execution! Winner! Search the usual places for an exploit and you might be a little disappointed to only find exploits for CVE-2016-1542 and CVE-2016-1543 which target a different interface (XMLRPC) to enumerate users and change any user’s password. Don’t get me wrong, it’s awesome work, but it’s not the RCE Nessus promised! It’s also not a particularly clean entry point. Changing a root password in this way might lead to an easy win but chances are, without the original password, you’re going to break something, alert someone of the compromise, or upset someone and end your fun early. Either way, changing the root password is certainly not “Arbitrary Command Execution”!

Looking closer at the Nessus report you might see the output from running “cmd /c echo %USERDOMAIN%/%USERNAME%” or “id” against the target host. Clearly Nessus is exploiting the vulnerability and while that might be good enough evidence for a vulnerability assessment, it’s little use if your goal is to go further. With that, I decided to have a crack at producing a working RCE exploit.

Update (04/01/2018): I managed to get my hands on a test environment and improve some issues with the exploit. More details can be found on my follow-up post: Improving the BMC RSCD RCE Exploit.

Grab the PoC from Github.

Exploiting BMC SA without BMC SA

Unfortunately BMC Server Automation is one of those pieces of software that’s well protected by a paywall and I had no access to it at the time. All I had to work from was Nessus, a packet capture of the encrypted exploit traffic, and details of CVE-2016-1542 and CVE-2016-1543 which I believe target the same access control weakness but via the seemingly less useful XMLRPC interface/protocol. I considered a few options to approach this problem:

  1. Work on reversing the binary Nessus plugin format
  2. Write a proxy that can man-in-the-middle connections between Nessus and BMC to capture the exploit traffic
  3. Try to emulate the target service and have Nessus “exploit” it

Given the capabilities of Nessus plugins I figured the first option was likely to take far longer than I wanted to spend on this. I wouldn’t make any progress with option two until I had access to an environment using BMC SA for testing and traffic capturing. On the other hand I had no idea how complex the network protocol might be so option three seemed far-fetched but it was the most practical way to get started and I could potentially work on option two along the way ready for a testing opportunity to come up.

Faking BMC SA to Capture the Payload

I started with a Python script that simply created a TCP server socket, accepted connections, read some data from the client, then closed the connection.

I then created a Nessus policy with only the target BMC plugin enabled and ran a scan against the above Python script to verify that the plugin was going to run and attempt to connect to my script.

I generated a dummy SSL certificate and modified the Python script to upgrade to a TLS connection if the first three bytes read from the client were exactly “TLS”.

Running the Nessus scan again allowed me to capture and dump the first packet Nessus sends over the encrypted connection.

At this point I didn’t think I would make any further progress without access to a real BMC SA environment because I had no idea what the service would normally return and Internet searches weren’t leading to anything useful.

I modified the script to send back what it received from Nessus on the basis that the packet should at least be in the correct format. To my surprise Nessus appeared to ignore the responses returned by the script and with a few more modifications I was able to capture the four packets sent by the Nessus exploit.

Crafting Packets

To achieve arbitrary command execution I needed to be able to generate valid packets containing arbitrary commands. Out of the four payload packets that were captured, the second one contained the command to execute (id in this case).

The value of the first four bytes of the packet matched the length of the remainder of the packet. This held true for the other three captured packets indicating that this is likely a packet length field. Interestingly the command itself was immediately preceded by the number 2 but in ASCII form.

The exact packet bytes shown above were found hardcoded in the binary Nessus plugin file, along with the Windows payload packet. Comparing the two payload packets we can confirm firstly that the payload command should be prefixed with the command length in ASCII form, and secondly that the command length field is in ASCII-HEX form.

Further comparing the two payload packets we can see what appears to be another length field. Bytes 11 and 12 differ between the two packets but their value in both cases is the ASCII-HEX length of the remainder of the packet. The next eight bytes are identical across both payload packets and have the value “00000010” (0x10 = 16), and are followed by 16 bytes that are also identical across both payload packets (“b7;0;2;cae;da4;0”). Finally there are 8 bytes representing the ASCII-HEX length of the payload command itself, followed by the payload command string.

Further comparing this with the other captured packets showed they were all in a consistent format – a four byte binary length field followed by mostly ASCII data. The ASCII data was split into chunks that could have child chunks and/or sibling chunks and each chunk began with an 8-byte HEX-ASCII length field.

The following Python generates a payload packet to execute an arbitrary command:

After blindly putting that together it was awesome to get a chance to test it out and see it working!




Leave a Reply