Exploit in the wild:

Analysis:

Hi,Welcome to my blog!In this post, I will analyze CVE-2019-16278 , how to exploit and why it vulnerable. This CVE is about the Nostromo web server , aka nhttpd, an open-source web server that is very popular on Unix system like FreeBSD, OpenBSD,...Nostromo fails to verify a URL that leads to path traversal to any file in the system. An unauthenticated attacker can force the server points to a shell file like /bin/sh and execute arbitrary commands. It's critical due to all Nostromo's versions, include the lasted release 1.9.6, are vulnerable. Even its developers' website, www.nazgul.ch, is exploitable.In the past, Nostromo had also a path traversal which could lead to unauthenticated remote code execution named CVE-2011-0751 . The web server checked for the stringbefore decoded escaped characters in the URI and the RedTeam Pentesting GmbH found it. They just encoded the charactertoand passed it to the server like this:Although Nostromo fixed CVE-2011-0751 in version 1.9.4 by decoding escaped characters before checking for the string, it's still bypassed by sp0re and we have CVE-2019-16278, the return of path traversal in Nostromo.Searching on Shodan , you can find about 2000 Nostromo web servers exposed to the Internet by using the query:Let's use my PoC written in Python to check some servers. In fact, all of them are vulnerable,.If you look at my exploit, you can see I send a request within the URI. Compare to CVE-2011-0751, I just changeto, which is not checked by Nostromo. You may wonder how the system can traverse to the upper directory by a path contains the carriage return (CR) like this, instead of. Actually, the system receiveswithout any CR characters. So, where those CR characters have gone?Let's take a look at the source code of Nostromo version 1.9.6 First, when a request header comes, it is verified and then processed.In the function, the header is URL decoded and then check for the existing of. The header now will be:Next, in the function, the header is passed to the functionThe root cause is here, in the function, it parses the header by the functionTake a look inside the function, you can see it take a string and return it with(carriage return) is cut off.Now the path is. So, the path traversal part is done, how it can be executed?Because of the functionin the function. It executes, which is indeed the pathNow, we have a path traversal to RCE!If you find it valuable, please share it with other people.If you have any questions, please don't hesitate to ask me on Twitter or leave a comment.Thank you for reading!