For the complete documentation index, see llms.txt. This page is also available as Markdown.
LFILINUXSENSITIVE FILE DISCLOSURESQLIWEB

Recruit

Infiltrate Recruit's new portal. Map the site, hunt for flaws, and gain unauthorised access - by talat118

The following post by 0xb0b is licensed under CC BY 4.0


Scenario

Recruit has just launched its new recruitment portal, allowing HR staff to manage candidate applications and administrators to oversee hiring decisions. While the platform appears functional, management suspects that security may have been overlooked during development. Your task is to assess the application like a real attacker, mapping its structure, abusing exposed functionality, and exploiting vulnerabilities.

Can you gain an initial foothold, escalate your access, and ultimately log in as the administrator?

Summary

Summary

In Recruit, we begin with a port swcan and identify a web-based recruitment portal backed by Apache, along with exposed DNS and SSH services. Initial web recon reveals an API endpoint capable of directly retrieving uploaded CVs, hinting at a local file inclusion vulnerability, while directory brute forcing uncovers a leaked mail log containing operational details about the HR account and application structure.

By abusing the file retrieval functionality, we successfully read the application's config.php file and recover the HR user's plaintext credentials, granting authenticated access to the internal recruitment dashboard and the first flag. Once inside, we discover that the candidate search functionality is vulnerable to SQL injection, confirmed through error-based testing on the search parameter.

Using either manual UNION-based enumeration or an automated SQLMap workflow, we enumerate the backend MySQL database, identify the recruit_db database and its users table, and extract admin credentials directly from stored records.

Recon

We use rustscan -b 500 -a recruit.thm --top -- -sC -sV -Pn to enumerate all TCP ports on the target machine, piping the discovered results into Nmap which runs default NSE scripts -sC, service and version detection -sV, and treats the host as online without ICMP echo -Pn.

A batch size of 500 trades speed for stability, the default 1500 balances both, while much larger sizes increase throughput but risk missed responses and instability.

We discover three open ports. Among those are 22 (SSH), 53 (DNS), and 80 (HTTP). SSH is running OpenSSH 8.2p1, DNS uses ISC BIND 9.16.1, and the web server is hosted via Apache 2.4.41.

First, we visit the site using our browser and are greeted by a login page. In the footer, we see a link to the API.

One interesting feature of the API is the ability to retrieve CVs. Based on the structure, it appears that files are being retrieved directly from the system. We note this as a potential attack vector: a local file inclusion LFI.

We continue the enumeration and perform a directory scan to discover any additional paths and pages. For this, we use Feroxbuster. The path to /mail/mail.log stands out here. It may contain sensitive information.

Access as hr

We visit the interesting endpoint and have indeed an email available. The email states that the HR account username is hr and its login credentials are temporarily stored in the application's config.php file, while administrator credentials are securely stored only in the backend database.

This is a big hint and strongly suggests that we might need to exploit the LFI to read the config file and, if possible, compromise the database to gain admin access.

We try to read the file /var/www/html/config.php, hoping that the web app doesn't execute PHP files. And we're in luck. The config.php file is readable, so we can extract the HR password directly from it.

We head back to the index page and submit the credentials...

... we are able to log in and get the first flag. We have a list of recruits in front of us that we can filter using a search.

Access as admin

We are checking whether the search function is vulnerable to SQL injection. We do this using the smallest payload, #. And we find that it is. We receive an SQL error, a strong indication that this field is vulnerable to SQL injection.

Automated Approach

Let’s start by keeping it simple and try to solve this using SQLMap. To do this, we’ll intercept a request using Burp Suite, which we’ll then use with SQLMap.

We are able to identify the database recruit-db.

Next, we enumerate the tables and find a users table.

Next, we dump the users table and get the admin creds.

We log out and log in as admin with the found credentials and are greeted with the final flag.

Manual Approach

First we begin identifying the total number of columns in the original SQL statement.

With ORDER BY 5 we get an error, so like the table suggests we only have 4 columns.

Next, we try to confirm if UNION-based SQL injection is possible and identify which column is reflected in the application response for displaying extracted data. Since every field is refected we move on to enumerat the database.

We enumerate all database names on the MySQL server by querying the information_schema.schemata and identify the recruit_db.

Next, we list all tables inside the recruit_db database by querying information_schema.tables. We identify the candidates and users table.

Now we try to enumerate all column names in the users table and identify the fields username and password.

Lastly we extract and concatenate the contents of the username and password columns from the users table.

We log out and log in as admin with the found credentials and are greeted with the final flag.

Last updated