12 July, 2023
Unlocking the Secrets of Code: An In-depth Exploration of White Box Security Testing
This blog post is written by Emil Kylander Edwartz, Security Consultant at Sentor with multiple years of experience within white box penetration testing. The article is going to contain what white box penetration testing is, how to get started and how to build a methodology for it.
White box is when you’re conducting a penetration test whilst having access to the source code of the application. The benefits of this method is having the ability to quickly validate potential vulnerabilities in an application, but also being able to add additional logging and debugging to understand the logic of the application. The counterpart of this is black box, where you typically only get the application without access to the source code. For example, it could be an API endpoint, a typical web application, or an executable.
So what can a white box assignment look like? Well, I’m giving access to a source code, this can either be downloaded with a guide on how to install it or I’m given access to an environment where the source code and the application co-exist. This is convenient if the application is not compiled. Then I move on to my methodology.
Methodology
Once I have access to the source code and an environment where the application is running, either remote or locally - I start my methodology. My first approach is the same as with black box; I start browsing the application alongside Burp Suite with the intention to identify various interesting functionality. This can be the login, register, file uploads, admin functionality, identify roles, et cetera. But also understanding what this application is about and familiarizing with the business logic.
The next step is to get a deeper understanding of how these functionalities work on a concrete level, for example; is the filter on the file upload actually sufficient? Or could a creative attacker bypass this? I do this on all of the critical components as well as other components that I see could pose a risk to the application. This is one of the main benefits of conducting a white box assessment compared to a standalone black box assessment, as these creative bypasses potentially could be missed.
My next approach is to focus on the source code instead. Depending on what programming language is used for the application, there’s a list of dangerous functions listed online. For example, PHP applications this one is sufficient: https://gist.github.com/mccabe615/b0907514d34b2de088c4996933ea1720
Then I add those functions to a yaml file in a tool called Drek which is a static code analysis tool. There are various alternatives for this tool, but I’m using it for this example: https://github.com/chrisallenlane/drek.
I run the following command to get a HTML document where all of these dangerous functions are called. Like the following:
drek /var/www/html/ -s '/path/to/signatures/php.yml' -p 'Customer Pentest Assignment' > drek.html
I will then receive a HTML document that I can open in the web browser of my choice, which will display all the places where these dangerous functions are executed.
Let’s say for example that Drek identified this function:
Function getUser($con, $id) {
$res = mysqli_query($con, “SELECT * FROM users WHERE id=’$id’ LIMIT 1”); Return mysqli_fetch_assoc($res);
}
This function is vulnerable to a SQL injection vulnerability. But now I need to identify where this function is actually called, and from what context to understand how we can reach it. So I’m identifying the call stack of it. I can either do this manually by going up the chain in the source code, or add a function to it that dumps the callstack of the function every time it’s run. For example, if I search on “getUser(“ in the source code I’ll find that the file users.php uses it. But here the code looks like:
$user = getUser($con, (intval)$_GET[“user_id”]);
Then I can’t abuse this function, because although the function isn’t secure against SQL injection itself, the caller of it sanitized the input by forcing the GET parameter to be an integer.
So users.php was a dead end, let’s see if the function is called somewhere else. I start by searching “getUser(“ again, only to find out that it’s used in another endpoint instead, called user_contact_information.php. This is what it could look like:
$user = getUser($con, $_POST[“user_id”]);
$contact_information = getContactInformation($user);
echo json_encode($contact_information);
As I can see the getUser function is called with user-supplied data, and as previously stated the getUser function does not escape the inputs in the arguments by itself. Hence, we have found a potential SQL vulnerability. In the next step I go back to the application and validate it for the report. For simplicity let’s say that www.website.com/user_contact_information.php is the endpoint. Then I send a POST request to this endpoint with the data user_id=1’ to see if the application returns an error, which indicates an injection. Then I validate it further by attempting to extract information from the database that the user is not allowed to see, for example passwords or other sensitive information.
How can you get better at white box testing as a penetration tester?
A great way of practicing white boxtesting is doing it through websites such as wpscan and huntr.dev. WPScan issues CVEs for Wordpress plugins and themes. You can download most of these for free. Another tip is to check out huntr.dev, which allows you to audit any repository on Github and get CVEs from it as well as a small bounty. There’s also some bug bounty scopes on Hackerone that gives you the source code, for example Matomo. You can also get an account on Pentesterlab, which has a few code audit challenges.
An additional option is to get the Offensive Security Web Expert certificate by Offensive Security.
Doesn’t this sound like a lot of fun?
Apply to our recruitment page and talk to Michelle. Not only do we offer you to work with security with great colleagues, we also offer you conferences, flexible work, and a healthy workplace!