Port fingerprinting can detect specific services running on a network, which makes it useful during penetration tests. It expands visibility into potential attack surfaces and vulnerabilities within the network environment. Over the summer, our interns worked towards developing a new tool for port fingerprinting services: Fingerprintx
Fingerprintx is a port fingerprinting utility tool useful for fingerprinting common services for both TCP and UDP protocols, and includes features for performance control and metadata collection. Existing tools such as Nmap have provided port scanning and active fingerprinting functionality, but also have inherent drawbacks. Some of the areas for improvement include service limitations, lack of options for speed/efficiency tradeoffs, and metadata collection. Consequently, Praetorian’s goal in developing a new tool was to offer high functionality while addressing these downsides.
Fingerprintx is inspired by Project Discovery ’s httpx tool, which fingerprints HTTP services on given host/port pairs. However, the ability to fingerprint non-HTTP services in a similar fashion is a valid use-case. Fingerprintx aims to address this limitation with an ability to support fingerprinting services beyond HTTP, such as SSH, RDP, DHCP, etc.
Additional areas on which Fingerprintx expands are performance and metadata collection. Fingerprintx provides different operating modes based on speed and efficiency tradeoffs. It includes an opt-in fast mode, which only checks mapping of default ports to default services. This is useful in cases where the user just needs to quickly determine common services running on a network.
Fingerprintx further adds value by also supporting metadata collection for services. Nmap does have NSE scripts which can collect metadata for different services but also present some limitations. For example, some NSE scripts are outdated and unable to accurately fingerprint the target correctly, and others lack the desired output formats such as JSON. Fingerprintx provides simple parseable output format options for metadata collection, allowing for convenient results processing after a fingerprint scan.
Pair with existing tools
Fingerprintx is designed for use alongside existing tools, such as Naabu ,and passes input in a way that other tools can leverage, as in Figure 1.
Figure 1: Discover open TCP ports using Naabu, and fingerprint discovered ports using Fingerprintx
Pairing it this way allows for similar usage as the httpx utility but across a broader range of protocols/services. Fingerprintx also can fingerprint services when passed a list of target hosts (IP address or subdomain) and port pairs via a file or piped standard input, as in Figure 2.
Figure 2: Enumerate subdomains using Subfinder first before using Naabu + Fingerprintx
Service Fingerprinting Library
Fingerprintx is designed to serve as a Go library, providing a fingerprinting functionality API for use within applications as demonstrated by the following code snippet:
Fingerprint(config Config) (ReportedResult, error) Scan(ips netip.Prefix, ports utils.PortRange, config Config) (ReportedResult, error) ScanTargets(targets netip.AddrPort, config Config) (ReportedResult, error)
Source: Fingerprintx API (version: 0.2.0)
Fingerprintx’s modular plugin structure allows a user to create a plugin to fingerprint a specific service type. This allows for flexibility in adding/removing fingerprinting for a specific service, along with service-specific fingerprint configurations such as timeout values. The structure of results from a plugin run supports collection of metadata during the fingerprinting process. It also reports errors from plugins for debugging purposes in the case of unexpected errors.
Fingerprintx performs some optimizations for speeding up the fingerprinting process. During scans, Fingerprintx skips the fingerprint process for connection based protocols based on previous unsuccessful connection attempts. Fastlane mode is another optional optimization, which only checks mapping of default ports to default services. Users can modify the configuration for other speed optimizers, such as specifying custom timeout values per service fingerprint.
Fingerprintx makes extensive use of Go channels to handle concurrency, following the Go style of “sharing memory by communicating.” The channels transmit signals and data between goroutines, establish happens-before relationships, and rate-limit various components.
The developers also incorporated utility functions, including a generic iterator interface and broadcasting channels. Though these utilities are used primarily in the scan package, users can export documented methods and functions for use in other applications. Additionally, test utilities for performing unit tests on Fingerprintx plugins allow users to define test cases for Fingerprintx using Docker services in a standard manner.
Further improvements, such as the following ideas, would enhance Fingerprintx’s functionality:
Add Service Plugins
Currently Fingerprintx contains service plugins for many common services across TCP and UDP, but it does not yet cover them all. When writing new service plugins, developers can reference documentation for the plugin structure and guidelines, and review the existing plugins.
Improve Existing Plugins
Developers could refine existing service plugins to fingerprint additional aspects for their services. For example, a plugin could expand to include different versions of its service, or collect additional metadata for comprehensive enumeration.
Augment and Add Protocols
Adding the ability to collect fingerprints at the protocol layer would improve existing protocols. For example, scans for TLS services also could collect the JA3S fingerprints of the TLS handshake. Developers also could add support for additional protocols, like QUIC. These additional protocols can serve as a foundation for new plugins in the future, allowing Fingerprintx to stay relevant as the internet changes.
Password Spraying Feature
Fingerprintx could extend to support password brute-forcing for various services. A more generic feature may be to support running arbitrary user-specified code on every host and port pair provided.
User Space Networking
While many optimizations have improved the performance of fingerprintx, implementing the network stack in user space may allow the tool to maximize its use of the host’s networking capabilities.
Real work, real tools, and real world application are the hallmarks of our internship program. This summer’s interns worked alongside our experienced security engineers across multiple cybersecurity disciplines, including with the developers in our lab under whose mentorship they built Fingerprintx.