After looking at Plex in my previous post, it’s only fair that we take a look at XBMC. XBMC is an open source media center server, and it’s probably the most popular media server. Since XBMC is a full screen app, we’re not going to look at the web server (it’s disabled by default anyway). We’ll focus on the APIs.
XBMC has two APIs in the current Frodo release. There was an older API, called the HTTPAPI supported in previous releases, but it’s now deprecated and cannot be enabled in the current versions. The new APIs are the JSON-RPC API and the EventServer API. The JSON-RPC API is accessible via GET, POST or WebSockets on TCP port 9090. The EventServer API is accessible via UDP/9777 and is intended to be used by remote controls.
My favorite kinds of vulnerabilities aren’t. Let me explain this apparent contradiction. Let’s say you discover a complex use-after-free vulnerability in IE, use magical powers to bypass ASLR and DEP, and manage to get code execution on Windows 8 x64 remotely. Chances are the exploit will be a little unreliable, and you still have to craft a sandbox bypass and/or privilege elevation exploit to do anything useful. And if you ever try and use the exploit, someone will notice and you will have until next Tuesday until it’s patched on most systems anyone cares about.
Don’t get me wrong. You will probably win the Pwn2Own and get $100K for your troubles. And you’ll certainly have my respect and admiration. But modern exploits are often developed by teams of people working for weeks or months and I can think of better ways to make money. This sort of “blackhat math” has been done before — the carnal0wnage blog expressed a similar point in their blog series From LOW to PWNED.
The takeaway is simple: in “blackhat math” you do not get points for style. In the recent compromise of Target, the attackers used ‘leet techniques such as batch files, FTP and grepping memory for stuff. I know the marketers of the world like to pretend this stuff is called ATA/APT in order to push their snake oil, but it isn’t. Sometimes it’s the simple stuff that matters, sometimes no mind-numbingly complex 0-days are involved, only features.
Rant is over… back to XBMC.
The EventServer API
The XBMC project provides example code for the UDP messages sent to the EventServer API. Here’s an excerpt from the Python code:
Generic packet structure (maximum 1024 bytes per packet) - Header is 32 bytes long, so 992 bytes available for payload - large payloads can be split into multiple packets using H4 and H5 - H5 should contain total no. of packets in such a case - H6 contains length of P1, which is limited to 992 bytes - if H5 is 0 or 1, then H4 will be ignored (single packet msg) - H7 must be set to zeros for now ----------------------------- | -H1 Signature ("XBMC") | - 4 x CHAR 4B | -H2 Version (eg. 2.0) | - 2 x UNSIGNED CHAR 2B | -H3 PacketType | - 1 x UNSIGNED SHORT 2B | -H4 Sequence number | - 1 x UNSIGNED LONG 4B | -H5 No. of packets in msg | - 1 x UNSIGNED LONG 4B | -H7 Client's unique token | - 1 x UNSIGNED LONG 4B | -H8 Reserved | - 10 x UNSIGNED CHAR 10B |---------------------------| | -P1 payload | - Command Sequence -----------------------------
In summary, there’s a simple header which provides a mechanism to fragment messages so as to avoid IP fragmentation. The token is not used for authentication. I am unaware of any way to authenticate these messages. The token is simply a unique identifier, typically UNIX epoch time when the client is instantiated. In must be consistent throughout the session though.
The first packet must be a Hello. A hello is defined by the PacketType field being set to PT_HELO (0x01). The last packet must be a Bye packet, with PacketType of PT_BYE (0x02).
Packets transmitted during the session will specify commands such as button up, button down, send keystroke, and others using PacketType PT_BUTTON, PT_MOUSE or PT_ACTION and various sub-actions for specific events. PT_ACTION (0x0a) is very interesting, because it allows a sub-action of ACTION_EXECBUILTIN (0x01).
The ACTION_EXECBUILTIN sub-action allows a remote control to call many internal C++ functions accessible to the EventServer object. One of those functions is XBMC.system.exec(), which does what you think it does. It accepts a system command and runs it with cmd.exe or /bin/sh, depending on your OS. This call is also present in the now-deprecated HTTPAPI, but is not accessible to the JSON-RPC API (as far as I can tell).
Now this is worth repeating — this is not an exploit. No patch will be released. No CVE created. It’s a feature.
To test this out yourself, I’ve written a Metasploit module which is available here. The module uses Powershell to stage Meterpreter onto Windows-based targets. Be sure to specify the correct target to execute the correct Powershell interpreter for your shellcode.