3632 - Pentesting Distcc
Basic Information
distcc distributes compilation jobs across networked machines. A client preprocesses source locally and sends the result to a server running distccd, which invokes a compiler and returns the output.[1]
Common port: 3632/TCP
PORT STATE SERVICE
3632/tcp open distccd
The native TCP transport is a trust boundary: unless GSS-API support is compiled in and --auth is enabled, access control is based on source IP rather than user identity. The transport also provides no confidentiality or integrity for preprocessed source and returned object files.[6][7]
Enumeration
nmap -Pn -sV -p 3632 <IP>
An open TCP port is not enough to prove command execution. In daemon mode, distccd applies IP allow rules and silently closes connections from addresses that do not match one; therefore, an immediate EOF/reset after sending a request often indicates an IP allowlist rather than a patched service. Test from the same network position as an authorized build client when the assessment scope permits it.[6]
Protocol-aware identification
The version 1 request used by common exploit tools is a fixed token stream. Every header is a four-byte ASCII token followed by an eight-character hexadecimal value; body-bearing tokens then contain exactly that many bytes. A request contains DIST (protocol version), ARGC, repeated ARGV values and DOTI (preprocessed input). The response contains DONE, STAT, SERR, SOUT and DOTO (object output). The ASCII tokens make packet captures and partial/error responses useful even when generic service detection returns no banner.[5]
# Inspect tokens and payloads in a lab capture
sudo tcpdump -ni <iface> -s0 -A 'tcp port 3632'
Exploitation
Older or explicitly insecure distccd deployments that accept the tester’s address may be vulnerable to CVE-2004-2687. The classic primitive submits a fake compilation whose argument vector starts with sh -c <command> and appends compile-looking arguments; the command output is recovered from the SOUT/SERR response fields.[2][3][5]
Nmap provides an NSE check and Metasploit provides a corresponding module. Both checks are intrusive because they confirm the issue by executing a command; the NSE argument prefix is the current script name, distcc-cve2004-2687.cmd.[3][4]
nmap -p 3632 <IP> --script distcc-cve2004-2687 \
--script-args="distcc-cve2004-2687.cmd='id'"
msfconsole
use exploit/unix/misc/distcc_exec
set RHOSTS <IP>
set RPORT 3632
check
set PAYLOAD cmd/unix/generic
set CMD id
run
For environments where those frameworks are unavailable, DarkCoderSc’s standalone Python proof of concept shows the raw command-execution exchange.[5]
Interpreting failed exploitation
Do not treat a failed sh payload as proof that the exposed build service is safe:
- Since distcc 3.3, TCP mode normally accepts only compiler names represented by masquerade links under the distcc compiler directory. The server option
--enable-tcp-insecuredisables that check and explicitly re-enables arbitrary executable names.[6] - A connection closed without a protocol response commonly means that the source address missed the effective IP allowlist (
--allow/--allow-private). A compiler-whitelist rejection instead means the client passed network authorization but the requestedargv[0]was rejected.[6] - Even a compiler-only command list is not a strong sandbox. Upstream warns that compilers process hostile arguments and inputs and recommends assuming that any client allowed to submit jobs can act with the privileges of the
distccdaccount.[7]
On-path build poisoning
Plain TCP mode neither encrypts nor signs requests or responses. A passive observer can recover preprocessed source and object code, while an active on-path attacker can change either side of the exchange. Replacing the returned object file can implant code into the final locally linked binary without needing the direct sh primitive on the server.[7]
Hardening notes
Keep TCP/3632 on a trusted build network, bind it to the build interface with --listen, use narrow --allow CIDRs plus a firewall, and run the daemon as an unprivileged dedicated account. Do not enable --enable-tcp-insecure. Where clients cannot be fully trusted at the network layer, use SSH transport or a build with GSS-API mutual authentication (--auth and principal allowlisting) rather than relying only on source IP.[6][7]
Post created by Álex B (@r1p).
References
- [1] distcc documentation - How distcc works
- [2] NIST NVD - CVE-2004-2687
- [3] Nmap NSE documentation -
distcc-cve2004-2687 - [4] Rapid7 - DistCC Daemon Command Execution module
- [5] DarkCoderSc - standalone DistCC command-execution proof of concept
- [6] distcc upstream - current
distccd(1)manual - [7] distcc upstream - security notes