The road to OSWE



I recently completed the Offensive Security Web Expert (OSWE) exam, and I am here including two key takeaways with famous quotes that applies both in life and in the journey towards this certification. NB: to be clear I am not revealing anything regarding the exam here and the examples are random.

Key takeaway number one
“give me six hours to chop down a tree and I will spend the first four sharpening the axe.” – Abraham Lincoln

White box security testing is all about “sharpening the axe”, and less about chopping (black box). The white box test typically “chops down the tree” in a few attempts during the vulnerability identification process, while the black box test often “chops down the three” in a couple of thousands or more attempts before a vulnerability is identified – with a blindfold on.

What I mean by this is that since you don’t have a blindfold on, you should use it to you advantage and “sharpen your axe” by researching everything you can find on the technology used by the target – including existing vulnerabilities and commonly known bypasses in the web server framework, programming language, programming framework, database management system etc. used by that target before attempting any “chopping”. Having this foundation is essential before continuing with any next steps.

Secondly, the sharpeness of your axe also applies to how good your preparation is. By having worked through all the extra miles and exercises in the material, as well as lab machines and created exploits that in a single run goes from no authentication to a full shell (and structured them well) you will have a great example toolset for all vulnerabilities in the course. By taking it one step further and creating a “chainer” for these vulnerabilities, you would significantly improve the efficiency of any exploit development, as you have a framework to work with and do not have to worry about printing results in your methods etc.

For example, the following method chainer could save you a lot of time. It declares a tuple that is used to pass input and output to and from one vulnerability to the next, together with the ip and port of a reverse shell.

def main():

result = ('result_of_function','10.10.10.1','4444')

funcs = [v_xss,o_ses,v_config,v_write,o_listen,v_load]

for func in funcs:

print "-------------------------------------------"

print "(+) Performing function: " + func.__name__

print "-------------------------------------------"

result = func(result)

print "(+) Result of function = " + result

print "(+) End of function: " + func.__name__

print "-------------------------------------------"

if __name__ == "__main__":

main()

NB: the functions declared in funcs is only an example, and code for the functions has not been scripted here, but to give an idea how this chainer would have helped, imagine that the functions did the following:

  1. The v_xss function is called and it steals the cookie for admin and return the cookie as a result.
  2. The cookie is passed to the o_session that starts a session as the admin user.
  3. The session is returned and passed to v_config to change the value of a configuration parameter that enables specific plugins. The location of the plugin is returned in the result.
  4. The location is passed to a path traversal vulnerability, exploited in the v_write function, which overwrites the plugin with a reverse shell with the ip and port stated in the result tuple.
  5. The port and ip address is passed to the o_listen which starts a netcat listener as a sub process. True is returned if the listener started successfully. If not, the program calls v_write with a with the port +1.
  6. If true, the config is reloaded in the v_load function and a shell is received.

By adding the prefix v_ we can distinguish vulnerabilities from operations with prefix _o. Maybe now its clear that we easily could change the v_write with a v_sql injection that achieves the same result but differently. Likewise we can simply change the order of vulnerabilities/operations by changing their order in the declaration of funcs. I can guarantee that using such a chainer will save you hours when writing a PoC.

If this concept is difficult to grasp, then think of the codepillar, and how chaining pieces together makes it perform different moves. By having all those pieces lying around, then with a chainer it simply becomes about putting the pieces together in the right order to have the codepillar navigating a certain path, and less about coding the content inside them from scratch. The more pieces you have lying around from the start, the sharper your axe is for chopping down that tree.

Key takeaway number two
You can do anything, but not everything.” – David Allen

As the quote by David Allen states, you cannot do everything in the time you have and it is easy to become overwhelmed by a couple of hundred files and hundred thousand lines of code. However, regex is your friend here and by using regex as a priority tool you can sort out what matters most and focus on that. It is important to think in graphs here. You want to get from point A to point B, before you can get to point F.

As an analogy, if you are located in Beijing and want to travel to New York, there is no reason to search for flight tickets from London to New York if no flight tickets are available from Beijing to London. You have to find a way to get from Beijing to London first. By doing this, maybe you find that there are no flights from Beijing to London due to some pandemic or something and you have to go through Frankfurt instead.

Likewise, there is no reason to search through lines of code that requires authentication, when you have not achieved authentication in the first place. Thus, first use regex to sort out the pages that does not require authentication and focus on the vulnerabilities in those.

Secondly, white box testing generally involves more programs and screens to keep track of than black box testing. However, even if you have a big screen (or multiple screens) you would not be able to look at what is happening in all programs concurrently, so you need to prioritize your focus.

There are typically 7 things that you should keep track of:

  1. What is happening in the Browser
  2. What is happening in Visual Code/Debugger
  3. What is happening in Burp
  4. What is happening in the DBMS
  5. What is happening in the Web server
  6. What is happening in the OS (processes etc.)
  7. What is happening on the file system

In my opinion, the focus should be in this order, but of course it depends on the vulnerability you are exploring. For example, if the vulnerability is a SQL injection, then its more important pay close attention to SQL queries in the log files of the DBMS while browsing an application or playing with Burp’s repeater, than trying to keep an eye on what is happening inside Visual Code.

Again, use what you have to your advantage. In a white box you can change the configuration of databases, web server and modify the source code. Thus its essential to switch on logging for databases and web servers and change the web application to a state that benefits your vulnerability identification process.

For example, when you identify something that could be a vulnerability candidate, add print statements in the code to print variables before and after they have been through a function or modification statement. You could even write your own function that echoes the values you want to watch into your browser console. It will help significantly having the values echoed in the browser while browsing the application, compared to navigating and watching variables inside Visual Code as you browse, while concurrently trying to keep up with what happens in the burp proxy, server logs and DBMS logs. Likewise, if you use Burp’s repeater you can also easily grep for the values in the response, but keep in mind that with the repeater you might miss how the browser behaves (especially important for client-side vulnerability identification). Keep in mind that many times you do not even have the possibility to watch the values in real time inside the debugger, because the debugger may not support real time debugging with the language you are debugging.

When you have full control of the server you can do anything, and as long as you have a backup or have the possibility to revert the machine, you shouldn’t be afraid of leveraging this to your ultimate advantage and imagination.

Leave a Reply

Your email address will not be published. Required fields are marked *