SEQURIST

Hacking is something that I've been fond of ever since I discovered the internet back in 1999. At that time, my first - somewhat technical - hacking attempt involved cloning the Yahoo! Mail page, changing the form method from POST to GET, setting it as start page at computers from internet cafés and later coming back and checking the browser history.

Recently, after 7 years of working as a web developer I decided it was time for a sabbatical. I started exploring new things and ended up trying bug bounties. I enjoyed the thrill of it and decided web security was something worth digging deeper into. So here it is.

Trivia: Securist was the name given to agents of the secret police of the Socialist Republic of Romania.

Blog

Exploring An Application's Past & Future

06-05-19

Years ago, when I started building web applications I would simplistically imagine them as a 2D graph of assets. It didn’t take long before I started running into race conditions, time zone discrepancies and caching issues, which made me become aware of the crucial dimension of time in which an application evolves. As I started becoming familiarized with security issues, I realized that vulnerabilities often occur at the boundaries of an application’s assets, where references to past/future assets (subdomains, links, libraries, 3rd party services etc) are often left dangling, outdated or become actual vulnerabilities themselves. What follows are some findings I stumbled upon while keeping this perspective in mind.

Digging up the past

I found that The Wayback Machine from Archive.org is a great tool for quickly surveying the public assets of a domain, allowing anyone to browse historical snapshots.

The viewer groups the site by years and shows all assets in radial-tree graph

The center circle is the domain, while the successive rings dig recursively into the directory structure. Naturally, not only the content is archived, but also things like JavaScript code, parameters and comments. On the visual sitemap explorer the juicy stuff can be found on the outer-most rings, which reveal actual files and a range of parameters. The image above reveals a ?pagename= parameter, which already hints to local file inclusion vulnerability.

Waybackurls is a tool for quickly fetching URLs from the Wayback Machine, which can give a feel of how the application is built.

Although mostly used for fuzzing, I like wfuzz because of it’s nicely structured output. This scan quickly reveals which URLs are still available, 404s and redirects, already hinting at some potential attacks

For more a more in-depth perspective, wayback_machine_downloader can be used to fetch a copy of all the historical snapshots of a website.

An interesting find: emails & reset password links.

…and activation links.

Password reset and activation links get indexed by crawlers or get leaked to 3rd parties via the Referrer header and, to make matters worse, expiration policies vary from framework to framework or has bugs, so they can occasionally be reused. Since the image above also reveals user emails, this paves the way for a targeted phishing campaign.

The Wayback Machine also stores error pages and redirects; 40* and 50* pages can provide insight into the configuration of the application’s stack while 30* redirects, conveniently highlighted, open the way to potential subdomain takeovers.

Comparing different versions of error pages can reveal when an application’s infrastructure has changed.

Modern web frameworks concatenate, minify and fingerprint assets for performance and caching purposes. This can sometimes make it hard to spot changes made to client-side code. Since it’s easy to get a list of all previously generated assets from The Wayback Machine, it becomes easy to spot different versions of the same file based on their file size.

Even though their names are obscure, similar sizes point to the same files.

Learning from others mistakes

“The future is already here — it’s just not very evenly distributed” claims William Gibson, the sci-fi author who also coined the term “cyberspace”. While the quote can be dismissed as abstract, the reality in software development is that incomplete features often get released to production - both intentional and unintentionally. Some of these features quickly get reverted. But these reversals are not always atomic operations. Artefacts get left behind, i.e. comments, which can be a treasure-trove of development credentials, sensitive links, library versions, S3 buckets.

In order to safely deploy features according to a marketing timeline feature flags are used, which provide the opportunity to test the features incrementally to selected audiences, in case anything breaks. Feature flags is why many unreleased features from popular products become leaked to the public long before their official launch. Giants like Facebook & Google implement their own feature flag service, while other websites used 3rd party services. Building on what we have explored until now, we can get insight into how a feature flag implementation may evolve.

The initial implementation is importing a local config file, while the newer implementation if fetching the configuration with an AJAX call to an external service.

The future becomes the past

In the context of web application security, an assumption I sometimes find myself making is that once a security issue is fixed, things tend to move forward and that class of bugs will not surface again. This, ofcourse, is false. From my previous work in web development, conscious and consistent effort has to be put into setting up proper testing and maintaining code quality. A high code coverage percentage is  the pride and joy of any seasoned developer, but that doesn’t prevent security bugs from sipping through.

A recent XSS was made possible in Google Search because the sanitizer was modified – essentially becoming more lenient – because of interface design issues.

Since Google’s frontend is open source, we can take a look at what exactly happened.

The commit message for the fix notes that tests were added and updated. While automated tests vouch for a programmer’s correctness at the level at which the test was introduced (unit, integration, system) and guard against violations of the application’s architecture and business logic, they do not always vouch for the overall security of the application.

We can see that the fix is actually a rollback, essentially bringing the code to a previous point in time.

To sum it up, application code moves back and forth, inherently producing side effects which can be exploited. Hacking is about finding the right time to act… and the right time to stop.

back to blog