My take on the OSCP exam

Although programming has been my area of professional focus for the past 20 years, security has always been one of my primary areas of research and experimentation in my spare time. The field requires both breadth and depth of knowledge and offers complex and exciting challenges. During the christmas holidays of 2019, I decided it was time to fortify my foundational knowledge and prove my skills in this area: I wanted to take the OSCP challenge and see where life would take me from there.

I decided to buy the 90 day labtime package with an included exam attempt and really wanted to pass the exam within that timeframe. I had no prior pentesting experience but did have a broad technical background. Reading stories about the course and exam and getting feedback from people who had already failed the exam before, the closer I was getting to my exam date the more I felt that I wouldn’t be able to pull it off. However, I passed the exam quite easily. While it should definitely not be taken lightly, with the right motivation, dedication and mindset, it is certainly doable.

The course

The general idea behind the course is that you get a PDF with theory and exercises, a set of videos that accompany the theory and access to a virtual lab where you can practice on realistic machines. The virtual lab can be accessed through a VPN connection and is shared with other students, but there are various copies of the labs and they loadbalance students among them. Within 120 days of course completion (i.e. when your lab access ends) you must take your exam.

The exam is entirely hands-on and challenges you to compromise 5 targets in a private exam lab within 24 hours. After that, you have 24 hours more to write a professional penetration testing report and submit it. The challenge itself is proctored, meaning your screens are shared with the proctor and you will be watched through a webcam constantly (this sounds worse than it is). Machines vary in difficulty and associated points they’re worth. You need to obtain at least 70 points out of 100 to pass the exam.

I bought the package where you get 90 days of lab access and one take on the exam.

The theory

The email with download links to the theory and videos landed in my mailbox at 02:00 in the morning on the 9th of February, as promised. After almost a week, when I had already made some good progress with the theory, Offensive Security released the 2020 version of the very course I was doing, promising more content in the theory, more lab machines, etc. It was possible to upgrade to the 2020 version of the course by paying only the difference between the new course price and the old, which seemed fair to me.

Still, I was a bit shocked at first and it felt like I was already doing something outdated, plus it meant I would have to start over, without getting any extra lab time; not ideal in your first week of an already stressful plan. However, so much new stuff was added and original content massively revised, that I decided to just go for it. So, I took the loss and started from scratch, which was definitely worth it in retrospect.

The theory and videos were of high quality and even though the PDF was over 800 pages long, it never really felt like a drag, because you’re constantly introduced to new concepts and tools (with some exceptions of course, depending on your background). I spent almost two months (2/3rds of my labtime) on the theory and exercises, because I reported and documented everything. If you submit a lab report containing 10 machines from the lab and all the exercises, you get 5 bonus points with your exam. It seems like a lot of work for 5 points, but it may just mean the difference between passing and failing.

The theory also contains optional extra miles, which I really recommend doing. You get to practice different buffer overflow scenarios and have some additional web applications to practice with.

The labs

The lab network is comprised of several subnets: a public one that everyone starts in and departments that you have to unlock by finding network keys on certain machines.

All of the machines encountered in the lab are intentionally vulnerable and your job is to find these vulnerabilities and compromise them. The machines and the vulnerabilities are quite realistic (albeit a bit outdated at times) and you won’t find any lame, purposefully placed hints anywhere as encountered on easy machines in other labs sometimes. In addition, dependencies between machines exist and it is also necessary to pivot from an already compromised host to reach other subnets, which is also good practice.

Machines vary in difficulty and there is a top four of hard machines. I started off with the lab machines that sounded like people (like Alice) as it just felt as if they would be easier to start with than something called Sufferance. The harder boxes (and exam boxes) typically have at least one rabbit hole; I wasted a lot of time learning this the hard way.

I only spent about a month in the lab, because that was all I had left after the theory. Once you start rooting machines, it gets addictive and doing the labs was definitely the best part of the course. Before I took my exam, I had rooted over 30 boxes in the lab.

Methodology

Documentation and tooling

I documented everything. I created a private repo in GitHub where I would create or extend cheatsheets and howtos each and every time I learned something new. I also created Bash extensions that would allow me to set a target, and quickly run common scripts and tools against this target without having to type it out every time. I intentionally did not want to automate my scans any further, because I wanted to be in control and properly check each step of the way.

Each time I started a new target, my script would create a folder structure for this target and all my scans automatically teed (piped through tee -a) their output so I could always refer to them later. Additionally, I created templates for my notes, depending on the type of service I found in my initial scan. There was one “master” notes file that summarized the target and specialized notes files for each encountered service, with sections tailored to that specific service.

In addition, I had a wwwroot folder in my repo that contained relevant scripts and binaries, such as shells, with a webserver.sh and ftpserver.sh to serve them through either HTTP or FTP quickly. Each time I encountered something that could help me in the future, I added it.

It is of key importance to keep good notes. There is no worse feeling while working on a target than vaguely remembering you saw something that is now probably relevant, but you can’t exactly remember what. Apart from that, good notes are essential to your reporting, especially after doing multiple targets (like in the exam) and only reporting on them later.

Enumeration

Enumeration is the single most important aspect of your methodology. Knock on each door, try basic things like anonymous FTP, check the website and source (don’t forget plugins!), try common/default credentials, etc. Also, don’t forget nmap scripts, they definitely come in handy. My initial nmap scan would always run the default scripts, so I could quickly identify things like anonymous FTP, writable shares, etc.

I always started with a quick nmap scan that wouldn’t take too long but only scanned a subset of the ports, so that I could already get started with what I found while running a full scan on all ports (which takes longer, obviously). Always run a full scan. You don’t want to waste time with rabbit holes while the vulnerable service was actually running on a high port that you missed before.

I also tried to avoid Metasploit as much as possible. While it is great software, you learn a lot more from manually exploiting things, plus it is only allowed for a single target on the exam (I did not use it at all during my exam). Learning to do everything manually will serve you better.

Time management

Time management is something equally important. For the labs and the exam, you should definitely set time limits for yourself, so you don’t spend more than say 30 to 45 minutes on a single attack vector that might be a rabbit hole. This may be a bit hard, especially since your gut feeling might tell you you’re on the right track, but do make sure you don’t waste too much time pursuing a dead end.

Also, don’t forget to have a plan of attack for your exam: it is essential, because you can make yourself stick to it. Move on to the next box if you’re stuck for a while.

The exam

As I got closer to my exam date, I started getting nervous, because I didn’t feel ready. I felt like there was much more to gain from the labs and seeing how I suffered with some of the boxes in the lab, there was no way I would pass my exam. I even tried postponing it, but everything was fully booked and it would be well into July before I’d get another chance. So, I decided that the worst thing that could happen was that I would fail and had to spend another $150 for an exam retake. At least I would have the experience of the proctored exam in my pocket already.

Things turned out quite differently. After setting everything up with the proctor 15 minutes prior to my exam start time at 10:00 AM, I received an email with exam instructions. It contained the IP addresses and the requirements of all the targets I was expected to compromise.

And so it began…

The buffer overflow

A week before, I had already created an attack plan, in which I would do the buffer overflow first. Although the concept came quite naturally to me as a programmer, I practiced on them some more a week prior to the exam to make sure these would be 25 easy points to start with.

I just performed my regular steps for a BOF, taking screenshots of every step along the way, and it worked right away 40 minutes into the exam; this was a good start.

The “easy” box

I decided in my attack plan that it would be a good warmup if I started with the 10 point machine after the BOF, assuming the lower number of points meant it would be easier. I already knew this would be a boot to root machine, meaning there would be no privilege escalation involved. Within 45 minutes, I had a reverse administrative shell at my disposal and, according to my own calculations including the 5 bonus points for my lab report, I was at 40 points already after less than 2 hours; 30 more to go!

Hmm…

Next in line was a 20 point machine. This was where I started to get nervous after about an hour, seeing as I was literally making 0 progress on it after my enumeration. After 30 more minutes without progress, I made the best decision I could have made: move on with the next box and save this one for later.

Restoring my confidence

So, I moved on to the other 20 point machine. After an hour, I obtained a local shell and half an hour after that, I had escalated my privileges for the full points and a grand total of 60. Glad I hadn’t lost my touch :)

Passing the threshold

Now, I needed 10 more points for the required minimum of 70 points and had one 20 point machine and one 25 point machine left. This meant that I only needed local access to either one of them to pass the exam (point wise, at least).

Since I had already failed the 20 point one before, I thought it would be better to move on with the 25 point machine first. An hour later, I had local access that added 12.5 points to my grand total. Half an hour after that, I rooted the box for another 12.5.

6 hours into the exam I had already rooted 4 out of 5 machines. This was a huge relief, as per my own calculations, I had 85 points already. Of course, getting full points is always better. I had 18 hours left for that final machine I failed earlier; sounds doable, right?

Retrying the missing box

I went back to the final machine and decided to start from scratch (plenty of time, right?). 2 hours later, at 18:30, I still had no foothold on this machine. What was going on? Certain that I was overlooking something, I decided to go for dinner, then relax a bit, go to bed early and wake up at 03:00 the next morning so I would have 7 hours for a final attempt. Surely, that would lead to new insights.

When the alarm went off at 03:00, I spent another 3 hours without any luck on this box and then decided that either the machine was flawed or my enumeration on this target was lacking (the latter is more likely). If this weren’t an exam, you would step away, rethink your methodology and try again some other time, but of course that was not an option now with the time pressure. I really could not come up with anything I was doing wrong, probably also because my mindset had slowly migrated from “highly stressed and focussed” to “relieved I made it already”. So, instead, I reread all my notes, checked all my screenshots and really made sure I had everything I needed, then asked the proctor to close my exam early so I could start reporting.

This machine will forever haunt me…

The report

Even if you root all machines, without a quality penetration testing report, it isn’t worth anything. This is why notes and screenshots are so important. Offensive Security offers a template they recommend using for your report, but you are free to use whatever you like, as long as it contains everything and looks professional.

Since day one, I had been reporting everything using markdown. Fortunately for me, a friend of mine had created a tool that would take markdown files, take a template (the one supplied by offsec) and then create a PDF from that. Brilliant! At least that would save me the trouble of transforming my reports into a PDF. It missed some things that I needed here and there that I had to add, but it was a real timesaver.

I submitted my exam report and lab report at 17:00 on the second day. It had taken me about 10 hours to write, generate, finetune and zip according to the submission standards set by Offensive Security.

Then, it was time for a drink.

The days after

You typically get an email saying you passed or failed within 10 working days after submitting your report. They don’t tell you how many points you earned, what you did right or wrong, or anything else. Just a pass or fail.

I still had many doubts about whether or not I had made it, despite the good progress I made during the exam. I was constantly asking all kinds of questions and revisiting the exam, my exam report, my lab report, etc. All these questions were left unanswered, but four days after submitting my reports, I got an email saying I passed:

Confirmation mail

Key takeaways

Kali VM

Stick to the Kali VM supplied by Offensive Security and use it during your course and exam. Don’t update anything unless absolutely necessary. Everything in the labs and exam has been tested with this VM so it’s your safest bet. Once you passed, do whatever you like :)

Find support at home

I have a full time job and a family to run and did everything in my spare time (spending about 20 hours a week at night and in weekends). I was fortunate to have a very supportive wife who took care of the kids and the house so I could properly focus during these months. Without that, please allow yourself more time.

Practice the BOF

Especially if you don’t have a programming background, but even if you do: practice the BOF. It’d be a real waste to miss out on these 25 points that are easy to obtain if you learn the theory and practice with them.

Structure your work

The more structured you are, the easier this job will be. Work on a good methodology, keep notes during a target, make screenshots, work on your own knowledge base, etc.

Enumerate

Enumeration is the most important aspect of your test. Make sure you enumerate everything: scan all ports, connect to all the open ones, find the version of the services that are running. Don’t forget the plugins involved in a service, they are typically more vulnerable than the core software itself.

Manage your time

If you’re stuck with an attack vector: it may be a rabbit hole so move on to another. If you’re stuck with a box for too long: move on to the next. It may be wise to set a time limit for yourself.