Service:
Apache ZooKeeperProtocol:
TCPPort:
2181Used for:
The Apache ZooKeeper client port — the distributed coordination service that Kafka, HBase, Hadoop, Solr, and ClickHouse rely on to store cluster metadata, service configuration, and leader-election statePort 2181 is the default client port for Apache ZooKeeper, the distributed coordination service that sits underneath a huge slice of the data-infrastructure world. ZooKeeper is a hierarchical key-value store of small nodes called znodes, and clusters use it to agree on things that are hard to agree on: which node is the leader, which brokers are alive, where a service’s configuration lives, whether a distributed lock is held. Kafka (classic mode), HBase, Hadoop/YARN, Apache Solr (SolrCloud), ClickHouse Keeper deployments, Druid, NiFi, and many Kubernetes-adjacent stacks all keep their coordination state here. Applications connect to 2181 to read and write znodes; ZooKeeper servers replicate to each other over the separate quorum/election ports 2888 and 3888. The catch is that ZooKeeper ships with no authentication and no ACL enforcement by default, and it answers a family of unauthenticated “four-letter word” admin commands — so an exposed 2181 is simultaneously a recon goldmine and a lever to tamper with every cluster it coordinates.
Why It’s Open
Port 2181 is open because the systems layered on top of ZooKeeper cannot function without it — it is the coordination substrate, not an optional add-on. The port carries:
- Client coordination traffic. Kafka brokers (in ZooKeeper mode), HBase region servers, SolrCloud nodes, and application libraries (Curator, the ZooKeeper client) connect to 2181 to register themselves, watch for changes, elect leaders, and read shared configuration.
- Service metadata and config. Teams routinely store broker lists, topic and partition assignments, feature flags, service-discovery entries, and application configuration as znodes — sometimes including connection strings and credentials that were never meant to be world-readable.
zkCli.shand operator tooling. Administrators inspect and edit the tree, take backups, and debug coordination problems by connecting to 2181 directly.
ZooKeeper uses a multi-port model: 2181 is the client endpoint, 2888 is the follower→leader quorum port, and 3888 is the leader-election port. On a correctly built cluster, 2181 is reachable only from the application and control-plane nodes that need it, SASL authentication and per-znode ACLs are configured, and the “four-letter word” (4lw) admin commands are restricted to a whitelist. The problem is how often none of that is true. ZooKeeper’s out-of-the-box posture is open: no client authentication, znodes created world:anyone:cdrwa (full access for everyone), and — on older builds — every 4lw command enabled. Bundled inside Kafka, HBase, or Hadoop distributions and bootstrapped by automation, ZooKeeper frequently ends up bound to 0.0.0.0:2181 on a VM with a wide-open security group, answering to anyone who can route to it.
Common Risks
- No authentication or ACLs by default → read and modify the coordination tree. This is the headline risk. ZooKeeper does not require authentication out of the box, and znodes default to
world:anyonewith full permissions. Anyone reaching 2181 can walk the entire tree, read whatever the cluster stores there (broker lists, service config, feature flags, sometimes credentials or connection strings), and write/delete znodes — directly tampering with the state that Kafka, HBase, Solr, and every other coordinated system depends on. - Unrestricted “four-letter word” (4lw) admin commands. ZooKeeper answers a set of short diagnostic commands on 2181 with no authentication.
envileaks the Java runtime, OS, user, and full environment;confreturns the server configuration;statandconsenumerate connected client IP addresses;dumplists sessions and ephemeral nodes;wchp/wchcreveal watch registrations;mntrdumps operational metrics and internals. Together they hand an attacker a detailed map of the cluster, its clients, and its version — pure reconnaissance, for free. - Tampering with the coordinated cluster. Because ZooKeeper is the source of truth for leadership and membership, write access is not just data theft. Deleting or corrupting the right znode can knock brokers offline, force bad leader elections, redirect clients, or poison service discovery — a coordination-layer denial of service or worse against everything built on top.
- Sensitive data stored in znodes. ZooKeeper is a tempting place to stash small config values, and teams do — including, at times, database passwords, API keys, and connection strings. Unauthenticated read access turns the tree into a credential dump.
- Quorum/election ports as extra surface. A reachable 2888/3888 confirms a real ensemble and, on unauthenticated quorum setups, is its own attack surface (see the CVEs).
- Cleartext by default. The classic ZooKeeper client protocol is unencrypted; TLS on the client port is opt-in and comparatively recent, so on most deployments the tree and any credentials in it are sniffable on the wire.
Want to save time on reporting?
Let PentestPad generate, track, and export your reports - automatically.

Enumeration & Testing
The workflow on 2181 is: confirm it’s ZooKeeper, fingerprint the version with the unauthenticated admin commands, then test whether the tree is readable and writable without authentication — because that, not any single exploit, is the whole ballgame.
Confirm the port and detect the service
nmap -sV -p 2181,2888,3888 <target>Scan 2888 and 3888 alongside 2181 — reachable quorum/election ports confirm a real ZooKeeper ensemble and are themselves targets. Nmap’s version detection identifies ZooKeeper and often reports the version; there is no dedicated zookeeper-info NSE script (don’t cite one), though the hbase-master-info, hbase-region-info, and flume-master-info scripts will surface a ZooKeeper quorum when they enumerate those services.
Run the “four-letter word” admin commands (no auth required)
# Liveness and server detailsecho ruok | nc <target> 2181 # answers "imok" if upecho srvr | nc <target> 2181 # version, mode (leader/follower/standalone), node countecho stat | nc <target> 2181 # server stats + every connected client IP
# High-value reconecho envi | nc <target> 2181 # Java version, OS, user, full environmentecho conf | nc <target> 2181 # server configuration (dataDir, ports, tick, limits)echo cons | nc <target> 2181 # detailed per-connection client infoecho dump | nc <target> 2181 # sessions and ephemeral znodesecho wchp | nc <target> 2181 # watch registrations by pathecho mntr | nc <target> 2181 # operational metrics and internalsOn modern ZooKeeper (3.4.10+ / 3.5.3+) these are gated by the 4lw.commands.whitelist property, whose default allows only srvr — so on a hardened server most of these return <command> is not executed because it is not in the whitelist. When envi, conf, dump, and friends do answer, the server is running an older build or has been explicitly opened up, and every reply is unauthenticated intelligence.
Walk and test the znode tree with zkCli
# Connect interactivelyzkCli.sh -server <target>:2181
# Inside the shell:ls / # list top-level znodes (look for /kafka, /hbase, /solr, /brokers)ls -R / # recurse the whole tree (ZK 3.6+)get / # read a node's datagetAcl / # check ACLs — "world:anyone: cdrwa" means no protectionA getAcl of 'world,'anyone: cdrwa on the paths that matter means unauthenticated read and write. If you can create/set/delete a test znode, you can tamper with cluster state — do so only within an authorized engagement and with change control, since ZooKeeper writes take effect on the live coordinated systems immediately.
A note on Metasploit
There is no reliable unauthenticated ZooKeeper RCE Metasploit module — the “exploit” for the default-open case is simply nc for the 4lw commands and zkCli.sh against a tree that never asked you to authenticate, so don’t reach for a made-up MSF path. Log every open 2181/2888/3888, the ZooKeeper version, the client IPs from stat/cons, and any readable or writable znode straight into the pentest report instead of a scratch terminal you’ll lose.
What to Look For
| Checkpoint | What it means |
|---|---|
ruok returns imok |
ZooKeeper confirmed and answering unauthenticated admin commands |
srvr / stat return version and mode |
Exact version for CVE matching; stat/cons also leak connected client IPs |
envi / conf / dump answer |
4lw commands not whitelisted — full environment, config, and session recon exposed |
getAcl / shows world:anyone: cdrwa |
No ACL protection — unauthenticated read and write to the tree |
create/set/delete succeeds |
Write access — cluster-state tampering against Kafka/HBase/Solr and others |
/kafka, /brokers, /hbase, /solr znodes present |
Identifies the coordinated system whose metadata you can now read or corrupt |
| Credentials or connection strings in znode data | Sensitive data stored in ZooKeeper — a credential dump |
| Plain (non-TLS) client protocol on 2181 | Tree contents, including any secrets, sniffable on the wire |
| Quorum/election ports 2888/3888 reachable | Real ensemble exposed — additional attack surface (see CVE-2018-8012 / CVE-2023-44981) |
Known CVEs and Exploits
Be honest about the threat model: on port 2181 the dominant risk is a misconfiguration — ZooKeeper exposed with no authentication, world-writable ACLs, and unrestricted 4lw commands — not a single CVE. When the tree answers zkCli.sh and nc without asking you to authenticate, no exploit code is required; reading and rewriting znodes is the attack. That said, ZooKeeper has had genuine CVEs worth matching the fingerprinted version against, mostly in the quorum/authentication layer:
- CVE-2023-44981 — An authorization bypass in SASL Quorum Peer authentication. When SASL quorum auth is enabled, ZooKeeper checks that the instance part of the authenticated ID appears in the server list — but that part is optional, so an ID like
user@REALM(no instance) skips the check entirely, letting an unauthorized endpoint join the ensemble with full read-write access and modify data. CVSS 9.1 Critical. Affects versions before 3.7.2, 3.8.0–3.8.2, and 3.9.0; fixed in 3.7.2, 3.8.3, and 3.9.1. - CVE-2018-8012 — No authentication/authorization is enforced when a server joins the quorum in Apache ZooKeeper before 3.4.10 and in 3.5.0-alpha through 3.5.3-beta. A rogue endpoint can join the cluster and distribute false leadership/state changes. CVSS 7.5 High. The fix added the quorum authentication that CVE-2023-44981 later refined.
- CVE-2019-0201 — An information-disclosure flaw in
getACL(): the command returns the contents of a znode’s ACL Id field without checking any permission, so when Digest authentication is used, the stored authentication hash is exposed as plaintext to any unauthenticated or unprivileged caller. CVSS 5.9 Medium (CWE-862, Missing Authorization). Affects versions 1.0.0 through 3.4.13 and 3.5.0-alpha through 3.5.4-beta.
Match the version from srvr/stat against these fix levels before assuming a server is vulnerable — but remember that a fully-patched ZooKeeper left open with no ACLs is still a total compromise of the coordination layer. The configuration review is the higher-yield test here; there is no reliable public exploit binary for the default-open case because none is needed.
Mitigation
- Enable authentication and enforce ACLs. Turn on SASL client authentication (Kerberos or Digest), set
zookeeper.sessionRequireClientSASLAuthwhere supported, and lock znodes down tosasl:ordigest:principals instead of the defaultworld:anyone: cdrwa. Enable admin-sideenforce.auth.enabled/enforce.auth.schemeson newer builds so unauthenticated sessions are rejected. This is the single most important control. - Restrict the four-letter words. Set
4lw.commands.whitelistto the minimum you actually need (srvrandruokfor health checks) soenvi,conf,dump,cons,wchp, andmntrdon’t hand out reconnaissance for free. On the AdminServer (HTTP on 8080), restrict or disable the equivalent command endpoints too. - Firewall 2181, 2888, and 3888 to the ensemble and its clients only. ZooKeeper should be reachable only from the application/control-plane nodes that coordinate through it — never from untrusted networks, never from
0.0.0.0, never from the internet. Audit cloud security groups for an accidentally world-open 2181. - Enable TLS on the client and quorum ports. Use ZooKeeper’s
secureClientPort(client TLS) and quorum TLS (sslQuorum=true) so the tree and any secrets in it aren’t sniffable and so quorum members are mutually authenticated. - Don’t store secrets in znodes. Keep credentials and connection strings in a real secrets manager, not in the coordination tree; if config must live in ZooKeeper, protect those paths with tight ACLs and encrypt sensitive values.
- Patch ZooKeeper. Run a current release (3.7.2+, 3.8.3+, or 3.9.1+) to close CVE-2023-44981, CVE-2018-8012, and CVE-2019-0201.
- Protect the neighbours. ZooKeeper rarely sits alone — lock down the systems it coordinates, such as the Kafka broker on 9093, and treat an exposed ZooKeeper the same way you’d treat an exposed etcd on 2379: as a direct window into the whole cluster’s state. Any exposed 2181 you confirm belongs in the pentest report with the exact
nc/zkClievidence.
Real-World Example
The canonical port-2181 compromise needs no exploit at all. A team stands up a Kafka or HBase cluster from a bundled distribution; ZooKeeper comes up on 0.0.0.0:2181 with its defaults — no SASL, znodes created world:anyone: cdrwa, 4lw commands enabled — and the security group is left open “to get the cluster talking.” An attacker scanning cloud ranges finds 2181 answering, confirms it with echo ruok | nc <host> 2181, then fingerprints and maps it with srvr, envi, conf, and dump: version, OS, environment, configuration, connected client IPs, and live sessions, all unauthenticated. Connecting with zkCli.sh -server <host>:2181, they ls -R / and find /brokers/ids, /config, and /controller under a /kafka root — the full Kafka control plane. getAcl returns world:anyone: cdrwa, so a single delete or set on the right znode can drop brokers out of the cluster, force a controller re-election, or rewrite topic configuration — a coordination-layer takedown of everything Kafka is streaming, invisible to Kafka’s own auth because it never went through Kafka. Internet-wide scanners have repeatedly catalogued thousands of ZooKeeper instances exposed exactly this way, their stat/envi/dump output freely readable; it remains one of the most direct data-infrastructure compromises there is, on the same footing as an open Elasticsearch on 9200 or an unauthenticated Kubernetes API server on 6443.
FAQ
What is port 2181 used for?
Port 2181 is the default client port for Apache ZooKeeper, a distributed coordination service. Clients — Kafka brokers, HBase and Hadoop nodes, SolrCloud, ClickHouse Keeper, and application libraries — connect to 2181 to read and write small coordination nodes (znodes): leader election, cluster membership, distributed locks, and shared configuration. Separate ports, 2888 and 3888, carry the quorum and leader-election traffic between ZooKeeper servers.
Why is port 2181 open on my server?
Because something on the host depends on ZooKeeper for coordination — most often a Kafka, HBase, Hadoop, Solr, or Druid deployment that bundles or requires it. ZooKeeper is frequently installed as a dependency and started with defaults, which is exactly why so many instances end up listening on 0.0.0.0:2181 without authentication. If you don’t recognize a coordinated service that needs it, treat an open 2181 as something to lock down.
Is an exposed ZooKeeper on 2181 dangerous?
Very. ZooKeeper enforces no authentication and creates znodes as world:anyone with full permissions by default, so anyone who reaches 2181 can read the coordination tree — broker lists, service config, feature flags, sometimes credentials — and, with write access, delete or corrupt znodes to tamper with the clusters it coordinates. It also answers unauthenticated “four-letter word” commands (envi, conf, dump, stat, cons) that leak configuration, client IPs, and environment details. An open 2181 is both a reconnaissance goldmine and a lever over every system built on top of it.
What are ZooKeeper’s “four-letter words”?
They’re short, unauthenticated diagnostic commands you send to 2181, e.g. echo stat | nc <host> 2181. Useful ones for assessment include ruok (liveness), srvr/stat (version, mode, and connected client IPs), envi (environment), conf (configuration), cons (per-connection detail), dump (sessions/ephemeral nodes), wchp (watches), and mntr (metrics). On ZooKeeper 3.4.10+/3.5.3+ they’re gated by 4lw.commands.whitelist, whose default allows only srvr — so seeing envi or dump answer means an older or deliberately opened server.
Does port 2181 have a single big CVE?
Not really — the dominant risk is a misconfiguration (no auth, world-writable ACLs, open 4lw commands), not one exploit. There are genuine CVEs to check the version against — chiefly CVE-2023-44981 (SASL quorum authorization bypass, CVSS 9.1) and CVE-2018-8012 (no auth when a server joins the quorum, CVSS 7.5), plus CVE-2019-0201 (getACL information disclosure, CVSS 5.9) — but a patched ZooKeeper left open with no ACLs is still a full compromise of the coordination layer, so the configuration review is the higher-yield test.
How do I secure or close port 2181?
You usually don’t close it — the coordinated systems need it — you lock it down. Enable SASL client authentication and set restrictive per-znode ACLs instead of world:anyone, restrict 4lw.commands.whitelist to the minimum, enable TLS on the client and quorum ports, firewall 2181/2888/3888 to the ensemble and its clients only (never 0.0.0.0), keep secrets out of znodes, and patch to 3.7.2+/3.8.3+/3.9.1+. Then rescan and re-run getAcl to confirm unauthenticated access is rejected.
TL;DR
- Service: Apache ZooKeeper — the distributed coordination service behind Kafka, HBase, Hadoop, Solr, ClickHouse and more; 2181 is the client port, 2888/3888 are the quorum and leader-election ports
- Default port: 2181/TCP (client), with 2888/TCP and 3888/TCP for quorum and election
- Biggest risk: ZooKeeper ships with no authentication and world-writable ACLs, and answers unauthenticated “four-letter word” commands (
envi,conf,dump,stat,cons,mntr). An exposed 2181 leaks configuration, client IPs, and environment, exposes any secrets stored in znodes, and — with write access — lets an attacker tamper with the coordinated cluster’s state. It’s a misconfiguration, not a single CVE (though CVE-2023-44981, CVSS 9.1, is a real quorum-auth bypass to patch) - Mitigation: enable SASL auth and restrictive ACLs, whitelist only the 4lw commands you need, enable TLS on client and quorum ports, firewall 2181/2888/3888 to the ensemble and its clients, keep secrets out of znodes, and patch to 3.7.2+/3.8.3+/3.9.1+