When testing web applications, it often happens that the testing target does not openly disclose its version information. This makes looking for vulnerabilities a time consuming task, since possibly all versions could be deployed.

Last-Modified

Looking for ways around this issue, I noticed that caching metadata can be of use: Modern web servers often employ a caching mechanism, where JS, CSS or other static files (e.g., images) are served via a cache. This typically results in the "Last-Modified" header being returned, so clients can understand if they need to request a newer version or if their cached version is up to date.

Last-Modified header - HTTP | MDN
The HTTP Last-Modified response header contains a date and time when the origin server believes the resource was last modified. It is used as a validator in conditional requests (If-Modified-Since or If-Unmodified-Since) to determine if a requested resource is the same as one already stored by the client. It is less accurate than an ETag for determining file contents, but can be used as a fallback mechanism if ETags are unavailable.

This means, if you want to find the version of a framework, application or anything similar, you should look for a static file path of this software and analyze the Last-Modified response:

Example: Tiki Wiki CMS

With Tiki Wiki I attempted to find the version string via Meta Generator tags,source code comments, ?v GET parameter and half a dozen other techniques without success. Then I noticed that the target page returns a Last-Modified value which is quite old:

Last-Modified date value returns exact value of the CMS installation

Using the "after:YYYY-MM-DD" directive in Google, I then specifically searched for vulnerabilities and exploits that were released after this deployment date.

Using Google's after: directive to search for a compatible exploit

Turns out my target was vulnerable to this exact exploit.

Alternatively, you may use the "custom range" tool to filter the results for release notes and determine an approximate version that fits the Last-Modified date:

Using Google's custom date range filter to find the target's CMS version

Happy hacking ;)

Version Enumeration via Last-Modified Header

Determining exact version strings on a hardened target can be difficult. This post shows how to perform an analysis of Cache metadata to pinpoint the employed software version.