Thursday, 1 December 2016

Alcatel Lucent Omnivista or: How I learned GIOP and gained Unauthenticated Remote Code Execution (CVE-2016-9796)

It is time for another advisory or better a blog post about Alcatel Lucent Omnivista and its vulnerabilities. Omnivista is a central management network tool and it is typically used in medium/large organisation with a complex VoIP/SIP infrastructure.

Interestingly enough, this software belongs to the niche of "undownloadable" software and it requires a license to work as well. My "luck" came during an engagement where it was already installed and this post documents one of the many 0days discovered during such audit.

The reasons why I wanted to dedicate a single blog post on this vulnerability are several.

First, remote code execution (RCE) is always a sweet bug to show. Second, I strongly believe that documenting vulnerabilities in applications using old protocols and standards, respectively GIOP and CORBA, can be beneficial for the infosec community, since no many examples of vulnerabilities in such applications are available or published on the Internet.

Actually, I would like to be proven wrong when stating that this is probably the only blog post documenting an exploit against a CORBA/GIOP based application. I will leave my readers to prove me wrong...

However, this does not mean that such technologies are no longer in use. Consider that Java includes CORBA support in their package (see class ORB). Also, a lot of critical and often "legacy" applications and systems do make use of such technologies, so I assume it is important to understand them and look for an exploitation angle. Hopefully, this will inspire other people to share their similar attacks or exploits.

In a Twitter survey that I ran some time ago, I was also curios to see how many people are familiar with such technologies, but even though the survey sample is limited, the statistics are clear:
So enough with introduction, let's now dive into the vulnerability - for those of you who want to skip the theory, then just jump to video and PoC exploit sections, at the bottom of this blog post. As usual, comments and feedback are more than welcome. Enjoy and if you like this blog post, then re-tweet it!

So what is CORBA and GIOP?

OMG (Object Management Group) designed the CORBA (Common Object Request Broker Architecture) standard to allow interoperability between different hardware and software. The Omnivista product takes advantage of such design to ensure its "universal" compatibility as central management network solution. The CORBA architecture is similar to the remote procedure call architecture from the eighties, with the support of ORBs (Object Request Brokers).

For those of you unfamiliar with this technology and terminology, then just imagine a client/server model with exposed objects that can be invoked from different machines.

To better explain, here is a simple high-level diagram which shows a CORBA architecture:

ORB is an abstraction which defines the mechanisms responsible for creating, sending and locating the object references used in the remote calls. Behind an ORB, there is more and in fact an object is defined by interfaces, using the IDL language (Interface Definition Language). IDL allows CORBA to be programming language independent - imagine a Java client that can invoke a remote object written in C++. These are the "flexibility" and neutrality features of CORBA. There are also other components, such as stab, and runtime code which is not covered in this blog post (see references at the bottom for more detailed information).

Many implementations exists that support ORB architectures, such as OmniORB, used by the Omnivista solution.

The communication aspect which regards the client and server interaction for object-oriented remote procedure calls is covered by GIOP and IIOP.

GIOP (General Inter-ORB Protocol) is the general protocol that defines the network communication between a client and a server. GIOP is transport layer independent and its level of abstraction is higher that IIOP. IIOP (Internet Inter-ORB Protocol) is a specialisation of GIOP, which defines CORBA communication over TCP/IP transport layer.

To summarize again with a high-level diagram, this is what it looks like when a client and server communicates (image courtesy of User:Alksentrs):

Wireshark has a built-in decoder for GIOP packets and their structure. An example of GIOP request packet exchanged between the Omnivista client ORB and server's ORB is shown below. Highlighted elements are of interest for understanding how CORBA/GIOP works in this case.

The 30024 TCP port is the port at which the ORB is listening on the server-side.

The GIOP packet per se is defined by different elements. We see an header which includes the message type (request) and size. Then the request part itself that contains various elements, such as object key length, object key and the request operation. Then the stub data is empty in this case, but this represents the request "body" or better the parameters which might be included within the request.

The object key is used by the ORB on the server side along with the request operation. The request operation is the IDL identifier naming, within the context of the interface, basically the operation being invoked. The request operation and object key are passed to the ORB on the server-side, by providing the call and the arguments to the listening service.

For a full technical specification of the GIOP protocol packet, which is beyond the scope of this blog post, the following paper is recommended.

The Omnivista server makes use of multiple OmniORB ORBs listening on different ports. A full network scan of the Omnivista shows multiple "omniORB and CORBA naming services". Below, the result of an nmap scan filtered on GIOP ports:

Where is the bug and how it can be exploited?

The bug derives from the fact that determined ORBs are exposed and they can be invoked without authentication. Also, the ORBs allow access to interfaces on the server which can be abused or misused to achieve code execution. The attacker only needs to reproduce a sequence of requests/responses in order to abuse such ORBs and execute arbitrary code on the server.

Let's see step by step where the vulnerability lies and how it was discovered. First, by using the Omnivista client itself I tried to understand how it works, what it is possible to do and what features/things can be invoked.

This is a screen shot of the GUI, after successful authentication:

Under the setup tab, the scheduler component attracted my attention. I then noticed that a user can create a job, add a task and then the possibility to add a reference to an executable on the server's system.

Once the task is added, a job can be executed, leading to the launching of an executable. For instance, I created a job task which would execute "C:\windows\system32\cmd.exe" with an argument as "/c notepad.exe".

Then I executed the job to see how the feature works.

On the server, I observed the task which is indeed executed and notepad.exe is launched:

As authenticated administrators these operations might be "acceptable", but what if an attacker is able to do the same from a remote position and without authentication?

When facing unusual technologies, the best recommendation is to analyze traffic between client and server while using all the functionality provided by the target software. In this case, the Omnvista client (a Java thick-client) was connecting to determined ports using the GIOP protocol. By examining packets, it is possible to understand what requests and responses occur between the client and server.

One of the major drawbacks in the way Omnivista has implemented CORBA/GIOP is the fact that replay attacks are possible, due to the lack of a proper session mechanism, although security and authentication has been implemented within the Omnivista product itself.

My first attempt to prove this point was to replay a request/action that can only be performed post authentication. For instance, among the sniffed GIOP packets, I picked the "addJob" request and see if replayed from a different machine with a different IP address without authenticating, would lead to the same result/response.

By first analysing the packet, I noticed that no session token/nonce or challenge seems to be in the payload so I thought I was going in the right direction.

I removed the BBBBB task using a valid session just to ensure that my action would re-create the task with the same name. I extracted the packet and sent the single packet and got the same response from the server! Went back to check the client and the task was back there!

That sounded extremely promising, now I had to understand the entire attack flow and prepare the exploit chain.

Exploit chain

So after analysis of the entire sequence, the conclusion is that it is possible to achieve unauthenticated remote code execution, by performing a mounted attack using respectively three different operations, such as AddJobSet, AddJob and ExecuteNow. These operations must be executed in sequence by sending valid GIOP packets to the OmniVista server, on TCP port 30024.

Let's now dive into each step:

1st step - AddJobSet

The AddJobSet packet is sent – an example below – this packet uses the SchedulerInterface to add a Job set on the server.

The SchedulerInterface is the object key of this action and this can be seen in Wireshark too:

The response contains now an object key that has to be used in the following requests. In our case, the response contains the object key: 00 00 00 00 36 32 81 55 F8 F4 08 00 61 00 00 00. We will see this object used within the following steps of the attack flow.

2nd Step: AddJob packet

In this packet we had the specific job inside the jobset test1, using the object key obtained in the reply from the AddJobSet request. In this case, the object key is highlighted in black in the screen shot below. In this case a job named test2 is set, which would call C:\Windows\System32\cmd.exe executable with an argument, invoking a Powershell web script to download and execute a malicious script hosted on the attacker's server.

3rd step: ExecuteNow:

Once the test2 job is added, then the ExecuteNow method can be launched to execute immediately the job. Again, the same object key (highlighted in black) will be used in this request as well:

Below, the Omni Vista server connects back to the attacker’s machine, concluding our exploit chain in a sweet Meterpreter shell:

PoC - Exploit

Github - python script -


Affected versions:

Alcatel Lucent Omnivista 8770 2.0, 2.6 and 3.0.

Disclosure Timeline
  • 16/02/2016 First contact
  • 16/02/2016 Response from HSSE to contact to Alcalel Lucent
  • 26/04/2016 Report sent to PSIRT Alcatel Lucent
  • 26/04/2016 Response from Nokia PSIRT
  • 27/04/2016 New contact provided from Nokia - PSIRT Alcatel Lucent
  • 09/05/2016 PSIRT provides temporary license/and software download
  • 18 May 2016 - Vendor provides download link and temporary license to verify if also version 3.0 is affected
  • 30 June 2016 - Version 2.6 is also vulnerable
  • 1 July 2016 - Version 3.0 also confirmed as vulnerable
  • 1 August 2016 - Patch should be available on November
  • 29 October 2016 - Vendor confirms patches for SQLi and XSS vulnerabilities in the product, but no CVE or patch has been assigned for this issue. The vendor position is to refer to the technical guidelines of the product security deployment to mitigate this issue, which means applying proper firewall rules to prevent unauthorised clients to connect to the Omnivista server.
  • 2 December 2016 - Contacted Mitre to obtain CVE - CVE assigned is: CVE-2016-9796

References and interesting links: