rpcbomb: remote rpcbind denial-of-service + patches

UPDATE: A CVE number has been assigned, it’s: CVE-2017-8779.

This vulnerability allows an attacker to allocate any amount of bytes (up to 4 gigabytes per attack) on a remote rpcbind host, and the memory is never freed unless the process crashes or the administrator halts or restarts the rpcbind service.

Attacking a system is trivial; a single attack consists of sending a specially crafted payload of around 60 bytes through a UDP socket.

This can slow down the system’s operations significantly or prevent other services (such as a web server) from spawning processes entirely.

This vulnerability may also be conducive in exploiting unrelated software running on the target system; there is a class of bugs that become exploitable (using uninitialized buffers, double frees, out-of-bounds writes, what have you) when there is insufficient memory; a call to malloc() fails and the software starts behaving in a way that was not foreseen. Resource shortage is an otherwise rare situation, so a lot of software is not equipped to safely deal with this situation.

It might not be easy to turn this constellation of factors into a practical exploit, but this class of bugs is a real thing, and it is the reason why a project like OpenSSL is now simulating allocation failures in their fuzzing framework, while applications like Tor will immediately terminate upon an allocation failure.

Suffice it to say that this is a potentially severe vulnerability.

I’ve developed a fix for this bug. This involves patching both rpcbind and libtirpc. I’ve been in touch with the maintainer of both packages but communication is slow so I’ve decided to go ahead and publish my findings. I see no reason to withhold them any longer because I’m including the remedy which distributions can consume and push to their users. You are encouraged to verify the correctness of the patches yourself before merging.

Exploit and patches can be found here: https://github.com/guidovranken/rpcbomb

shodan_rpcbind

Shodan reports 1.8 million hosts serving on port 111 (rpcbind). Many of those appear to be Amazon AWS instances and other mass hosting services where the owner is presumably using their default Linux distribution configuration that leaves rpcbind open to the internet. I assume there’s also a large amount of rpcbind services running behind internet firewalls (so they go undetected by Shodan) but accessible via their local networks or within a VPN.

Patch today or better yet, unless you really need it, remove the rpcbind service entirely from your system. If you really need it, it might be wise to apply some access limitation to port 111 in your firewall. I’ve scrutinized rpcbind and libtirpc to the best of my ability, but it is possible that this old software still hides vulnerabilities of equal or even greater severity.

A question to my readers

With regards to the class of vulnerabilities mentioned earlier, where resource shortage can lead to, I’d like to ask my dear readers a question: should memory-corrupting or memory-divulging bugs, which only exist under memory shortage that is non-trivial (assume a failure to allocate a couple of hundred kilobytes or more is the lower bound required to trigger the bug), be taken seriously and treated as proper vulnerabilities? The reason I’m asking this is because instances of this class of bugs are usually met with some ambivalence; let’s make a fix because who knows, and bury it in the endless stream of other nondescript commits, and let’s not issue an advisory because the prerequisites are outlandish. Failing to allocate 500 kilobytes on systems that are not a Commodore 64 is unusual,  but obviously and inevitably there is a limit to the free memory that can be consumed. The amount of memory that is free at any given moment is largely outside the software’s purview; ultimately, memory is a shared and limited resource, and every concurrent process can affect the others’ stability.

Actual exploit development is not my forte nor my objective, so I’ve put up this survey to collect the opinions of those who are perhaps better versed in this area.

Take into account the fact that some systems like embedded devices operate in a state (default memory consumption, upper bound of memory consumption, processes running at any given moment) that is more or less known to the attacker, which may benefit the precision and reliability of an exploit.

I will post the results of this survey!

A script to find call recursions in binaries

https://github.com/guidovranken/binloop

This is a script I’ve slapped together to find potential call recursions in binaries. A call recursion occurs when functions comprise a loop; for instance, function a() calls function b(), and function b() calls function a(). If the recursion depth isn’t properly curtailed, this can lead to a stack overflow, which crashes the program and is essentially a denial-of-service. Especially for server software that can enter a deep recursion upon the instigation of an untrusted client, this is problematic, as it essentially constitutes a remote DoS. Thanks to this program I once found a remote DoS vulnerability in Apache: CVE-2015-0228.
An other way to do this is to use a static C/C++ analyzer to parse the entire source code and find recursion loops on the resulting invocation tree, but this approach saves you the parsing overhead and operates on the end product (the binary) instead.
This script implements my own algorithm to find loops in a graph. I believe scipy offers such an algorithm out-of-the-box, so you may use that instead if it is faster.
The script does not find loops that involve function pointers; this is far more difficult to detect as it requires a semantic understanding of the code.
It is configured to output 25 loops at most, to prevent that excessive output is generated (this happens for some software, try Python or Tor). Change it to suit your needs.
You will probably need to alter it a bit if you’re going to use it for non-x64 binaries.