A primer on finding your own 0days

First published: LinkedIn on April 5, 2017

Disclaimer: This article does not show you anything you could not have found out yourself by using search engines, visiting fora, studying with a good master or using plain common sense coupled with some tenacity. You will still learn something though.

IANAL: I do not know whether possessing and/or perusing this information is legal in your geographical locality, so when in doubt, consult accredited legal council (or better yet, find a different article to read).

Notice: I will use no pretty images and graphics; one characteristic of a good hacker is tenacity in slogging through reams and reams of text without skipping parts (you could miss the critical item).

Scope: This primer will just be concerned with software 0days. It will not be about social engineering, hybrid attacks or any other Rube Goldberg style methods to gain access to something.

This is a primer. Not a lecture. Not a course. Not a presentation.

What is an 0day?

My guess is that you already have an inkling on what it means today, otherwise you would not be reading this article. I am old enough however to remember the term from BBS-es when it mind something slightly different. But that is a different story for by the campfire.

In short, the 0 refers to the number of units of time (i.e. days) the vendor or creator of the software knows about a vulnerability and is able to do something about it (i.e. patch it, close it, blame someone else... you read the news, you patch diligently, you know the drill).

This is important because it means it gives an attacker the opportunity to exploit that vulnerability without the victim either knowing and/or being able to do something about it.

But it's all very nice to 'just talk' about 0days as if they really were a thing in their own right, but actually they are nothing more than vulnerabilities with the extra attribute of 'not actively being studied and remediation being sought for by the vendor'.

The underlined part is important in that sometimes a security team actually knows about a vulnerability, but because of business constraints (patching means downtime, uses resources etc.) may not fix it in the product but rather helps mitigating it or just removes any possible attack vectors to that vulnerability. Or they might just be employing ye olde 'Security by Obscurity'.

So, finding your very own 0day actually comes down to two components:

  1. Find a vulnerability.
  2. Find it before the vendor knows about it and starts working on a fix.

As a side-note, if you are a large company, having good developers (maybe in your blue team?) that contribute on your most used Open Source is a good security concept because they can patch vulnerabilities themselves without having to wait for the vendor (and therefore minimizing the window of opportunity for 'baddies' to weaponize the vulnerability).

How to find vulnerabilities?

Mind you, find vulnerabilities not 0days (I feel the need to clarify, even if the title states so because reading comprehension seems to become a lost art, what with the video infotainment nowadays).

What is a vulnerability?

This is our starting point. After the definition you will also see that you can somewhat decide your own level of difficulty when looking for vulnerabilities. And you will see that not all bug hunters are equal when it comes to security testing.

Basically, a vulnerability is either a bug in a piece of software or a feature that works well but has unintended side effects (and as always, there can be pedantic stances on this, but I will not reply to them; find a forum and go discuss).

An example of the first is the recent (at time of writing) Cloudbleed vulnerability where attackers could overflow a buffer (don't worry if that means nothing to you, there are still vulnerabilities to find for you as well) and get data from the exchange of somebody else's sessions with web servers (like passwords, messages etc.).

An example of the second is the SQL Injection in NextGen Gallery for WordPress.

The difference in these two examples is that in the first, the software design may have had (it probably did) all the security by design boxes ticked and it probably came out all of the tests fine but there was a programming error when implementing the design.

The second example did not have a programming error, but the design (or testing or whatever the procedure) is at fault.

Finding the second type is easier because you could just read a printed copy of the source code whilst on an airplane (well, at the moment you are not allowed to use your tablet or laptop).

Finding the first... well, that is what the professionals do (and they have the professional's tools; time, lots of computing power, experience, patience, tenacity, patience, good logic and patience).

How do hackers find vulnerabilities?

Most "hackers" don't. They use things like the excellent Offensive Security’s Exploit Database Archive or they click about in Metasploit, or trade things on forums (or the dark web). And there are other methods which I can not disclose here, but if you ever meet me in person... we might talk about them, depending on your profession and background.

How do I find a vulnerability?

So, how do you find a vulnerability? After all, that is why you even started reading all these letters.

Well, before reading any further and maybe getting disappointed, I must warn you that there will be nothing like learning a 'magic trick' and then you can just find vulnerabilities everywhere. It will take time and practice. Or a time and a lot of money. Either way, it will take time.

Still with me? Good, let's get to it.

Method 1 - A sysadmin can do it.

The first method is using automated tools. Remember, we are going to find a vulnerability by ourselves.

This method does not have any prerequisites other than basic computer literacy.

We are going to use fuzzing tools!

  1. Rent resources using Amazon, Google, Microsoft or any provider that can give you lots of memory and lots of CPU. And I mean lots. Or if you can afford it (or need to repurpose your cryptocoin mining gear) set it up yourself.
  2. Prepare your target software (mind you, don't be so stupid to fuzz 'live' production servers; it not only can be illegal, it is right slow as you need to do everything over all these external connections; having it all inside your own environment is so much faster. And if you rent...). This preparing depends on the manual of your fuzzing tool and exactly where you try to find the vulnerability. If you want to start easy, install a target webserver and try out various installations of CMS/CRM etc. software and fuzz the applications. If you want to be ballsy, try out American Fuzzy Lop with crypto libraries or other often used software (Linux kernel for maximum points).
  3. And now we wait.
  4. I really meant wait; what fuzzing does is trying out lots and lots of combinations (in a smart and sophisticated way) of inputs and checking if something interesting happens. To be more precise we should say it traverses the search space in an intelligent manner. But since that search space (i.e. the number of possible inputs) is so extremely large it might (luck plays a factor as well) take a long time before anything is found. If anything is found.

The biggest opponents you have in fuzzing are your wallet and your patience (or confidence). After all, you may never find anything before a new version of the software is released. But on the other hand, computers do not have problems with patience and you can have them fuzz the same thing for years and they sill won't complain (other than wear and tear).

Method 2 - Use the source Luke!

This method gives you a better quality of bragging rights (the first method bragging rights are of the 'I have' category, like 'I have a Ferrari' or 'I own an ICBM', these bragging rights are of the 'I am' category, like 'I am the girl/guy that found how to exfiltrate all american tax returns')

However... it requires you make a decision and an investment in time. Yes, there is no single way around it, an investment in time.

You need to learn programming. I am sorry, there is no way around it. But programming is good for your mind anyway.

Now, the decision to be made is 'which programming language'? You can choose anything you like, but if your main goal is to find vulnerabilities, then you should choose a popular language (the chances that software is written in such a language are obviously greater). Check something like the TIOBE IndexRedMonk Rankings or you can scrape data from job sites and calculate the most in-demand languages (this is why I always code my servers in Brainf*ck).

When you have decided which language, you need to become really good at reading the code and figuring out exactly what it does to which variable and object. You do not have to become really good at writing the code (although it does not harm the process, since you will become more adept at figuring out specific patterns and their side-effects).

To help you, you can use various IDE's for the language of choice or code analysis tools (using something like a free scan with Coverity or an alternative for open source is a very good start).

As a side note, if you want to become a proper hacker... your only allowed tools are vi (not vim), more or less, grep, find and assorted *nix shell tools. Or PowerShell and Windows tools. Basically only the tools a bare install will give you. Even better is the print of the source and a pen/pencil. I was not joking.

What you are looking for is parts of code that either are very complex, very abstracted (a pain to follow all these cyclomatically correct itty bitty functions, but hey, that is why they are such good candidates if the authors did not have <big>% code coverage; "yes boys and girls, abstraction is fine, but with great abstraction must come great test coverage"), or very rushed (i.e. error handling that is silently ignored or just unused).

Also try to find the 'stop and resume' markers; if the codebase is large then it probably is not written in a single day. The developer(s) have stopped and then resumed coding and oftentimes that also interrupts the train of thought. And since devs are human, chances are that if there is a lot of this stop-and-resume there will be ´bad emotional moments' where the devs mind is not on coding but on 'what just happened' (I am trying to automate finding these area's using ML, but that still is work in progress).

In these parts we may find programming errors, or if we enumerate all possible usages, we may find unintended uses.

The advanced may just increase knowledge of how software A approaches something and then using knowledge of how software B approaches something combine this to make a compound vulnerability.

Method 3 - Planet of the API's

This method does not require any investment upfront. It only requires patience and good reading skills (and for me, always pen and paper).

Get some extension for your browser (like TamperChrome for Chrome). For the hacker trainees, you are only allowed to use telnet, keep a vi window ready to edit your requests beforehand.

Read the API, understand what it does and read the limits. Try out the API by hand. Tentatively go outside the limits (basically, you are fuzzing the API a bit, and there are tools for that, but this is just for getting a feel of how the API responds when it is not happy).

Next, totally forget about the use case. Forget the whole context of the API (i.e. why it exists, what it provides, who provides it etc...).

Look at each function separately and try to understand that function in isolation.

Now you have building blocks to build what you want. See where that leads you.

(Notoriously, you can use API's that give you proximity of people or objects to triangulate them very accurately. Or you can get second accuracy timestamps where in the application you can only see minutes or days. This is why you should forget the context).

Method X - Level up

Obviously there is much more here than can be written down in a simple article; we could go disassembler, verilog, ABI, cryptographic errors, change registers, redirect traffic, use rainbow tables, use affinity matrices, use bi-grams, tri-grams, bell curves etc. But I leave that to all the Gods that will be berating me for having left out these obvious things. Rest assured, I stand corrected and will carry the burden of my failure in properly educating the masses with me for the rest of my life.

And now... practice, practice, practice

Using the above you should be able to get started. After all, this is just a primer. Now all you need to do is practice.

Some tips:

  • Use archives of old software with unpatched vulnerabilities (both the software and the vulnerabilities, and possibly even the exploits can easily be found using search engines). You take the old software and practice a method and see if you can find the mentioned vulnerability and why this was so. And then you can check the exploit if this corroborates your thoughts. There is tons of broken software out there to play with. Old releases on github are your friend.
  • Practice thinking in code/trees/logical reasoning. This will help your subconscious to keep on cracking on a piece of complicated code when you are doing something else, like taking a shower).
  • If you chose the programming method, try to write broken, exploitable code. Exploit that code. See what it does. Why does it do that?
  • Be patient.
  • Be curious. Be very curious.