Documentation Index
Fetch the complete documentation index at: https://hackwithmike.com/llms.txt
Use this file to discover all available pages before exploring further.
Introduction
I passed the OffSec Web Expert (OSWE) exam a while back, and I promised to write something on it - so here it is. OSWE is a 48-hour proctored exam with 2 targets. Each target has 1 user flag for authentication bypass, and 1 root flag for remote code execution (RCE). Obtaining 3 out of 4 flags is required to pass. Each target also comes with 2 machines: a target machine with the actual flags, and a debug machine that holds an exact copy of the source code and the application. Do note that you cannot download the source code off the debugging box to your own machine. Most analysis and review will be performed on the debugging machine. Per target, you are expected to produce a single Python exploit script that chains together both the auth-bypass and RCE vulnerabilities. Since there are already a lot of great OSWE write-ups on the course structure and exam-day experience, the rest of this blog will focus more on my methodology and preparation. Here are a few references that helped me along the way:
- an00b / nayyyr’s Obligatory OSWE Retrospective
- Stefano Lanaro’s OSWE review
- saunders-jake’s oswe-resource
- sidd.sh’s OSWE review
The Methodology
The OSWE / AWAE course focuses heavily on exploitation techniques for the introduced vulnerabilities. By the time you sit the exam, you should already have a bunch of scripts and helpers ready, such as blind SQLi extractors, XSS token-theft payloads, reverse shell handlers, etc. The actual challenge of the exam is to find bugs in an unfamiliar codebase under time pressure, and to triage exploitable vulnerabilities from rabbitholes. A concatenated SQL query is a good lead, but it can also be a dead end if the input was cast to an integer upstream, or if it is being properly sanitised by a strong filter. On the other hand, custom sanitisers are always worth investigating, as the implementation can be incomplete or misconfigured. From a pure exam perspective, two ideas drive my whole approach: splitting your work into two tracks - Auth-bypass & RCE, and hunting by features & endpoints.
Two Tracks: Auth-bypass and RCE
As mentioned, each target requires an authentication bypass to get to the app admin account for the user flag, and an RCE for the root flag. Treat them as separate searches - each is usually abused through different features and vuln classes.Authentication Bypass
The Auth-bypass track is always about attacking the authentication logic. You can trick the server into believing you are someone else, or have a higher privilege (e.g.,admin=true), or break the authentication flow to skip the checks, or simply get your hands into the valid credentials. Start by understanding how the application authenticates users and assigns roles. Here are some example questions worth asking:
- Does the app use session tokens to authenticate & authorize its users? If so, how are they implemented? (e.g., Cookies? Authentication Header? Custom headers?)
- Say if the app uses cookies for authentication, are the cookies properly protected? Is
httponlyset to prevent XSS from extracting the cookie? - Is role assignment exposed in the client-side? (e.g., something like
role=adminin cookies / headers). If so, are they properly validated? - How are the session tokens (and other related tokens like password reset, temporary login codes) generated, stored, and checked? Are they vulnerable to extraction from database (SQLi), or are they predictable?
- etc.
Remote-Code Execution
On the other hand, the RCE track is about identifying where the server may parse or process our input as server-side code. The usual vectors are deserialization, server-side template injection (SSTI), custom command wrappers, file upload to an executable path, SQL injection, etc. From an exam perspective, this is easier to scope: since the RCE is expected after Auth-bypass, focus on functions and endpoints that are exposed to the admin user only. It can be something like:- An admin-only dashboard that contains a command wrapper;
- An editing function that normal users are restricted from using;
- A file upload function for administrative tasks;
- An SQL query that only the admin user is accessible;
- etc.
Vulnerability chaining is a must for the OSWE exam (and also in real-world hunting), so always ask - “what does this vulnerability unlock next?”. A file read vuln can lead to leaking of environment variables, which give further access to other services that expose another vulnerablity, etc.
Hunt by Features and Endpoints
Since we have both the source code and a working application, treat it like a grey-box test: interact with the application like a regular user, list every accessible feature and endpoint, then map them back to the source code. Using the two-track methodology, here are some features & endpoints worth looking at:Pre-admin (Auth-bypass)
- Login and registration
- Password reset
- Profile and account update
- Any user-input areas (e.g., blog post, comments, feedback forms, URL parameters, etc.)
- File upload and download (e.g., profile picture, blog post images, attachments, etc.)
- Any functions that likely pull data from the database (e.g., search function, blog post filtering, etc.)
- etc.
Post-admin (RCE)
- Admin dashboard
- File import and export
- File upload and download
- Content Templates
- User management panel
- Database management panel
- Background and cron jobs
- System command / function runners
- etc.
The Preparation
With the methodology, we can then prepare for the exam accordingly. Know the impact of each vuln class, have search patterns ready, and prepare helper scripts that were battle-tested in labs.
Vulnerability Classes by Tracks
Following the two-track approach, I classified each vulnerability class by their impacts. If it helps with becoming admin, it goes into the Auth-bypass track. If it helps turn admin access into code execution, it goes into the RCE track.Pre-admin (Auth-bypass)
For the pre-admin track, the goal is to reach the administrator context, steal or forge a privileged session, or otherwise make the application treat you as the admin user. Here is how to think about the pre-admin bugs:- SQL Injection
- XSS
- IDOR / Access Control
- Auth and Session Logic
Impact: Data extraction, auth bypass, token theft
- It may leak admin password hashes, active sessions, reset tokens, signing secrets, etc. Sometimes the login query itself can also be bypassed directly.
- Password Reset Tokens
- CSRF / CORS
- LFI / Path Traversal / XXE
Impact: Account takeover
- Check the reset token is predictable, reusable, leaked, or not properly tied to a user.
Post-admin (RCE)
For the post-admin track, the bug only becomes interesting once the feature is reachable from the admin context or clearly depends on data the admin can create. The main question is whether the vuln can actually become code execution:- Command Injection
- File Upload / File Write
- Deserialization
- SSTI / Template Injection
Impact: Direct command execution
- This is the cleanest RCE way - look out for filters & bypass though.
- Pro-tip: Validate it with a quick
wgetorcurlcommand to your controlled server to confirm if the command is actually being executed.
- SQLi to RCE
- XXE / SSRF
- LFI / Path Traversal
- Prototype Pollution
Impact: Database-level file write or command execution
- Some databases can write files, load extensions, execute commands, or leak credentials for another service. That is where SQLi becomes more than data theft.
Search Patterns
Have grep patterns ready for the languages you might see will make your life way easier. I usually start by spamming a few grep searchs, open the interesting-looking files, then trace the input properly from route -> controller -> helper/model/sink. Here are a few examples:Helpers and AI in Prep
As is the case for all OffSec exams, conversational AI tools are banned during the exam. However, that doesn’t mean you can’t use them before the exam for preparation. I used LLMs heavily during prep to make sure I covered the areas I was weaker in, such as Java and PHP. Here is an example of what my prompt looked like. Always tweak the prompt around - different lengths, structures, wordings, and focuses - until you find something useful:LLM Prompt
requests wrapper with extra steps, while all I needed was one simple line of requests.Session().get(). Definitely know your basics, so that you can call out the slop when needed.
Here are some helper snippets worth having ready and tested before exam day:
- Blind SQLi extractor with parallel worker threads (I built a very handy one!)
- Token brute-forcer
- Web server that can both serve payloads and receive callbacks (e.g., handling XSS callbacks, serving DTDs, etc.)
- Reverse shell handler with separate send and receive threads
- Argparse skeleton for new exploit scripts (all the flags & parameters for your final exploit)
- Modular PoC structure that you can easily plug in and remove the above snippets
Closing Notes
Once again, thank you for reading till the end. The methodology here is purely from my personal experience and way of thinking, so I know it may not be as intuitive to everyone. I tried my best to make it make sense, but please feel free to reach out if you have any questions or recommendations - my inbox is always open! (Tho sometimes I may reply a bit slow haha)

