the_open_door
coffee
ESEN
← Back to index

From version to exploit

The version scan comes back with things like Apache httpd 2.4.49, vsftpd 2.3.4 or ProFTPD 1.3.5, and whatweb or the panel itself adds the application-layer ones (Pluck 4.7.18, WP Advanced Search 3.3.9). That data is not report decoration: it is what decides the next step. Going from "there is service X version N" to "there is an exploit for this" is a search, not a hunch, and it is worth always doing it the same way.

Why the exact version is what matters. A vulnerability does not affect a product, it affects a range of versions: when an advisory says <= 3.3.9, it means the flaw was fixed in the next one. That is why 3.3.9 is exploitable and 3.3.9.2 is not, even though it is the same product. A version number without the third digit, or a vague "roughly this branch", is not enough to decide on.

Where to look. The first stop is the local Exploit-DB mirror, because it is instant and works offline:

searchsploit vsftpd 2.3.4          # search by product and version
searchsploit -x unix/remote/17491.rb   # READ the exploit before running it
searchsploit -m unix/remote/17491.rb   # copy it into the working directory
searchsploit -w vsftpd             # return the exploit-db URL instead of the path

If nothing shows up there, widen the search: the CVE on NVD (to read the description and the affected range), a GitHub search for the identifier (CVE-2021-43857), the vendor's changelog or security advisory (sometimes the fix is documented before any public PoC exists), and for WordPress a wpscan, which already cross-references plugins and themes against its own database.

Search by component, not just by server. The flaw is almost never in the nginx sitting in front, but in the application or in one of its plugins. A site with a perfectly patched nginx 1.18.0 may be running a WordPress plugin with an unauthenticated SQLi. The version to enumerate is that of each piece, not that of the container.

Read the exploit before firing it. It is third-party code that runs as our own user and against a system we are responsible for. Opening it (searchsploit -x, or just an editor) serves three purposes at once: checking that it does what it claims, understanding the mechanism of the flaw (which is what remains once the exploit stops being useful) and spotting what needs adapting. There is usually something: an IP or port hardcoded in the source, a python2 that is no longer installed, an offset computed for a different build, a URL carrying the original lab's path.

A vulnerable version does not guarantee a working exploit. These are two different claims, and mixing them up costs hours:

That is why a scanner saying VULNERABLE is a hint; the proof is the exploit run with a result. When it fails, the right move is not to insist but to read why it failed (the message usually says so) and go back to enumeration with that information.

Why it matters. This is the point where reconnaissance turns into access, and also where people improvise the most. Doing it methodically (exact version → affected range → exploit read → adapted → run) avoids the two classic ways of getting stuck: assuming something is exploitable when it is not, and writing off a service because an exploit copied blindly did not work first time.

Defence. Keep a software inventory with versions and patch by range, not by gut feeling. Minimising banners slows this search down but does not prevent it (the application's fingerprint gives the version away anyway), so it is no substitute for patching. And since the window between a public advisory and a PoC is usually days, what really reduces risk is shortening the update time of exposed components, including the third-party plugins nobody remembers are installed.

ToolsnmapsearchsploitNiktoJoomScansslscanNessusOpenVAS / GVMODAT

Machines where it's used