Responder
Responder is a LLMNR, NBT-NS, and mDNS poisoner with built-in rogue servers (SMB, HTTP, LDAP, and more) that answers broadcast and multicast name-resolution requests so Windows clients try to authenticate to your listener, revealing usernames and NetNTLM hashes in a controlled lab. It exists because legacy Windows name resolution trusts whoever answers first, and Responder makes that behavior visible so you can learn it, demonstrate it, and then help fix it.
You will see Responder in Active Directory CTF boxes, in homelab AD environments, and in the early credential-gathering phase of an authorized internal assessment. It is powerful and loud, so it belongs on networks you own or are explicitly cleared to test, and nowhere else.
What you will learn#
- How to install, update, and verify Responder
- When to use it, and when a quieter or different tool fits better
- How to start in analyze mode before you ever poison anything
- How to read captured hashes, logs, and analyze output without fooling yourself
- Realistic examples for interface selection, server toggles, and log review
- The mistakes that cause out-of-scope impact, and how to avoid them
- A commented cheat sheet you can paste into your notes
Legal and scope reminder#
Only run Responder on systems and networks you own or are explicitly authorized to test. It does not just listen: it actively answers other hosts’ name-resolution requests, which can disrupt traffic and capture other users’ credentials. CTF platforms, your own isolated homelab, and dedicated practice VMs are fair game. Anything else needs written permission, an agreed scope, and a defined interface or VLAN. Keep a short note of the target network, the authorization, the interface, and the date next to your capture output. This section is the boring part that keeps the fun part legal.
Prerequisites#
- A Linux host is expected (Kali, Parrot, or any Ubuntu/Debian box). Responder is a Python tool and is packaged on Kali.
- Root/administrator rights are required, since Responder binds low ports (53, 88, 445, 389, and others) and listens on raw broadcast/multicast traffic.
- Basic comfort with the terminal, IP addresses, network interfaces, and the idea of LLMNR/NBT-NS/mDNS name resolution.
- A network you are allowed to test, ideally a dedicated lab VLAN. The examples below use placeholder interfaces and private IPs only.
- A way to crack or relay what you capture later (
hashcatorjohn), kept inside the same authorized scope.
Lab setup#
Keep every engagement in its own folder so captures, notes, and loot never mix.
# One folder per lab, with room for captured material and notes
mkdir -p ~/labs/responder-demo/{captures,notes,loot}
cd ~/labs/responder-demo
Use a private, isolated range for practice targets (10.0.0.0/8,
172.16.0.0/12, 192.168.0.0/16) and ideally a separate VLAN so no real users sit
on the same broadcast domain. Throughout this guide, IFACE means the lab interface
you are authorized to listen on (for example eth0), TARGET_IP means one host you
are testing, and DOMAIN means your lab Active Directory domain.
Installation#
Pick the method that matches your environment.
# Debian / Ubuntu / Kali (preferred on Kali, where it is packaged)
sudo apt update && sudo apt install -y responder
# Git clone (latest upstream, when you need newer features)
git clone https://github.com/lgandx/Responder.git ~/tools/Responder
cd ~/tools/Responder
# Run directly from the clone with python3
sudo python3 Responder.py -h
The packaged build is the simplest on Kali and is usually current enough for lab
work. Clone from upstream when you need a recently added server type or a fix that
has not landed in the package yet. The git clone keeps its own Responder.conf and
logs/ directory inside the clone folder, which is handy for isolation.
Update process#
# Packaged install: upgrade through apt
sudo apt update && sudo apt install --only-upgrade -y responder
# Git clone install: pull the latest
cd ~/tools/Responder && git pull
Responder changes behavior and server options between releases, so check the upstream
README or -h output after updating. New versions adjust which servers default to on
and how poisoning is throttled, which matters for noise control.
Check if installed and available#
command -v responder # prints the path if Responder is on your PATH
responder --version # confirm the version (or check the help banner)
responder -h | less # skim the option groups
If command -v prints nothing, either the package did not install or you are running
from a git clone, in which case call it as sudo python3 /path/to/Responder.py -h.
If the help banner errors out, you are likely missing a Python dependency from the
clone; install its requirements.txt first.
First safe test#
List your interfaces, then start Responder in analyze mode. Analyze mode listens and reports who would be poisoned but does not answer any requests, so it touches nothing on the network.
# 1. Find the right lab interface
ip addr
# 2. Listen passively on that interface (no poisoning)
sudo responder -I IFACE -A
Expected: a startup banner showing which servers are enabled, followed by
[Analyze mode] lines reporting any LLMNR/NBT-NS/mDNS requests it sees. Success looks
like a clean start with your chosen interface and [+] Listening for events....
Failure looks like command not found (install problem), a permissions error (you
forgot sudo), or a bind error like Address already in use (another service holds
port 53 or 445).
Core concepts#
- Name-resolution poisoning is the core trick: when DNS fails, Windows falls back to LLMNR, NBT-NS, and mDNS broadcasts, and Responder answers them with your IP.
- Analyze mode (
-A) listens and reports without answering. Always start here. - Poisoning mode (default, no
-A) actively answers requests so clients connect to Responder’s rogue servers. - Rogue servers (SMB, HTTP, LDAP, MSSQL, FTP, and more) collect authentication when a poisoned client connects. Each can be toggled on or off in the config.
- NetNTLMv1 / NetNTLMv2 hashes are what you usually capture: challenge-response material, not plaintext, that you crack offline or relay.
- Interface (
-I) is mandatory and decides which broadcast domain you affect. The wrong interface means the wrong network. - Responder.conf controls which servers run and which features (like WPAD or
Force-WPAD-Auth) are enabled. - Logs persist every capture and event to a logs directory; the hashes go into per-type files ready for cracking.
- Relay vs capture: Responder captures; for relaying you typically pair it with a separate relay tool and disable the overlapping rogue servers.
When this tool is useful#
- CTFs and AD labs: capture a NetNTLMv2 hash from a chatty Windows client, then crack it offline to move forward.
- Homelab AD inventory: see which of your own machines still broadcast LLMNR and NBT-NS, so you know what to disable.
- Authorized internal assessments: early credential gathering on networks where LLMNR/NBT-NS are still enabled and in scope.
- Defensive validation: prove that disabling LLMNR and NBT-NS actually stops the captures, by re-running analyze mode before and after the change.
- Training and demos: show a team exactly why legacy name resolution is risky.
When not to use this tool#
- On any shared, production, or out-of-scope network: it answers other hosts' requests and can capture unrelated users’ credentials.
- When you only need to observe traffic: use a sniffer like
tcpdumpinstead of an active poisoner. - When stealth is critical and you have not scoped it: poisoning is inherently noisy and easy to detect.
- When DNS is healthy and clients never fall back: there may be nothing to poison, so analyze mode first saves wasted noise.
- When the goal is relaying and you have not disabled the SMB/HTTP rogue servers: conflicting listeners will break the relay tool.
Command anatomy#
sudo responder -I [interface] [mode] [server toggles] [options]
# -I eth0 -A -wF / -dwv -v / -F
- interface (
-I): the lab interface to listen on. Required. - mode:
-Afor analyze (passive) or default for active poisoning. - server toggles: enable extras like WPAD (
-w), or downgrade options, depending on version. Most servers default on and are tuned inResponder.conf. - options: verbosity (
-v), force authentication on rogue servers, and similar behavior switches.
Common flags and options#
| Option | Meaning | When to use it | Example |
|---|---|---|---|
-I | Select the listening interface | Always required | sudo responder -I IFACE |
-A | Analyze mode (listen, do not poison) | Always start here | sudo responder -I IFACE -A |
-h | Show help for the installed version | Check version-specific options | responder -h |
-v | Verbose output | See more detail while testing | sudo responder -I IFACE -v |
-w | Start the WPAD rogue proxy server | When testing WPAD behavior in scope | sudo responder -I IFACE -w |
-F | Force NTLM auth on the WPAD server | When clients ignore unauthenticated WPAD | sudo responder -I IFACE -wF |
-d | Answer DHCP-related requests | Lab DHCP poisoning tests only | sudo responder -I IFACE -d |
-f | Fingerprint hosts that issue requests | Identify who is broadcasting | sudo responder -I IFACE -A -f |
-P | Force proxy auth | WPAD/proxy auth testing | sudo responder -I IFACE -wPF |
Flag availability changes between releases, so confirm with responder -h on the
exact version you have before relying on any toggle.
Practical examples#
Each command below explains what it does and what to expect. Every one targets a lab interface you are authorized to use.
# List interfaces first so you pick the correct lab network
ip addr
# Output: interface names and IPs. Note the one bound to your lab VLAN as IFACE.
# Analyze mode: listen and report, never answer (safest first step)
sudo responder -I IFACE -A
# Output: [Analyze mode] lines naming hosts that broadcast LLMNR/NBT-NS/mDNS.
# Analyze mode with host fingerprinting
sudo responder -I IFACE -A -f
# Output: adds OS/host guesses for the machines issuing requests. Recon only.
# Active poisoning on an authorized lab interface (loud)
sudo responder -I IFACE
# Output: [*] [LLMNR] poisoned answers and any captured NetNTLM hashes.
# Verbose poisoning to watch each event as it happens
sudo responder -I IFACE -v
# Output: detailed per-request lines, useful for understanding client behavior.
# Enable the WPAD rogue server and force authentication
sudo responder -I IFACE -wF
# Output: WPAD proxy served; browsers that honor it may send credentials.
# Tail the live log file while Responder runs in another pane
tail -f /usr/share/responder/logs/Responder-Session.log
# Output: a running feed of events without scrolling the main window.
# Find captured NetNTLMv2 hashes after a lab run
ls /usr/share/responder/logs/ | grep NTLMv2
# Output: per-host hash files ready to hand to a cracker (in scope).
# Copy captures into your engagement folder (handle as sensitive)
cp /usr/share/responder/logs/*NTLMv2* ~/labs/responder-demo/loot/
# Output: nothing on success. Keep loot scoped to this authorized lab only.
# Crack a captured NetNTLMv2 hash offline in your lab
hashcat -m 5600 ~/labs/responder-demo/loot/captured-ntlmv2.txt WORDLIST
# Output: cracked plaintext if the password is in WORDLIST. Lab use only.
Example workflow#
A realistic beginning-to-end pass on one authorized lab network.
# 1. Prepare and confirm scope
mkdir -p ~/labs/adlab/{captures,notes,loot} && cd ~/labs/adlab
echo "scope: IFACE on lab VLAN, authorized $(date -I)" > notes/scope.txt
# 2. Pick the correct interface
ip addr
# 3. Listen passively first to see if poisoning is even relevant
sudo responder -I IFACE -A -f | tee notes/analyze.txt
# 4. If clients are broadcasting and it is in scope, poison
sudo responder -I IFACE -v
# 5. Collect captured hashes into loot (handle as sensitive)
cp /usr/share/responder/logs/*NTLMv2* loot/
# 6. Crack offline inside the lab
hashcat -m 5600 loot/*NTLMv2* WORDLIST | tee notes/crack.txt
From here, a cracked credential leads to authenticated enumeration with a tool like
NetExec, and an uncracked hash may lead to a relay path if the environment allows
it and it is in scope.
Reading and interpreting output#
[Analyze mode]lines tell you who is broadcasting and whether poisoning would catch anything. No requests means nothing to poison.[*] [LLMNR]/[NBT-NS]/[MDNS] Poisoned answer sentmeans you answered a client. That is the loud, active behavior.- Captured
[SMB] NTLMv2-SSP Hashlines are your action items: challenge-response material to crack offline, not plaintext passwords. - NetNTLMv1 vs NetNTLMv2 matters for cracking: they use different hashcat modes
(
5500vs5600). - No captures can mean the network is hardened (LLMNR/NBT-NS disabled), no clients triggered fallback, or you are on the wrong interface.
- Bind errors mean another service already owns a port Responder wants; nothing was captured because Responder did not fully start.
- Treat every capture as sensitive evidence and verify the source host is in scope before using it.
Common mistakes#
- Running active poisoning on a production or shared network without explicit approval.
- Choosing the wrong interface and affecting a network you never intended to touch.
- Skipping analyze mode, so you poison loudly when there was nothing to capture.
- Leaving the SMB and HTTP rogue servers on while trying to relay with another tool, which causes port conflicts.
- Treating captured hashes casually in notes or leaving them in the default logs dir.
- Assuming a captured hash is plaintext; it still has to be cracked or relayed.
- Forgetting
sudo, so Responder cannot bind its ports and silently does little. - Using flags from an old tutorial that changed or were removed in your version.
Troubleshooting#
| Problem | Likely cause | Fix |
|---|---|---|
command not found | Not installed / running from clone | Reinstall, or call sudo python3 Responder.py |
Permission denied / cannot bind | Missing root for low ports | Prefix with sudo |
Address already in use | Another service holds 53/445/etc. | Stop the conflicting service or toggle that server off in Responder.conf |
| No requests in analyze mode | Hardened network or wrong interface | Confirm IFACE; verify clients still use LLMNR/NBT-NS |
| Poisoning but no hashes | Clients not falling back, or wrong VLAN | Recheck interface; confirm DNS actually fails for clients |
| Servers you did not want are on | Defaults in config | Disable unused servers in Responder.conf to lower noise |
| Relay tool will not start | Responder owns SMB/HTTP ports | Turn off SMB/HTTP in Responder.conf before relaying |
| Results differ from a tutorial | Version/flag changes | Check responder -h and the upstream README |
Tools that pair well#
- tcpdump: observe raw LLMNR/NBT-NS/mDNS traffic to confirm what Responder reports before you poison anything.
- hashcat / john: crack captured NetNTLMv1 (
-m 5500) and NetNTLMv2 (-m 5600) hashes offline inside the lab. - NetExec: validate a cracked credential against in-scope hosts for authenticated enumeration.
- Impacket: protocol-level lab workflows, including relay tooling that pairs with Responder when its overlapping servers are disabled.
- tee / grep: capture analyze output and pull hash files into tidy, scoped notes.
Automation and note taking#
# Timestamped analyze run, saved and echoed to the terminal at once
sudo responder -I IFACE -A -f \
2>&1 | tee "captures/analyze-$(date +%Y%m%d-%H%M).txt"
Keep a one-line scope note per network (interface, VLAN, authorization, date), copy
hash files out of the default logs directory into a per-engagement loot/ folder, and
treat every capture as sensitive. Screenshot the analyze-mode summary if you will
reference “who was broadcasting” in a report, and never paste real captured hashes
into shared notes.
Blue-team visibility#
Defenders can see Responder clearly, and that is part of the lesson. Poisoned answers appear as a single host suddenly resolving many different names; SMB and HTTP rogue servers show up as unexpected listeners and connection attempts. Expect Windows Security and System event logs to record the odd authentications, IDS/IPS signatures to flag LLMNR/NBT-NS spoofing, and EDR to notice a workstation answering broadcast name queries. The simplest detections are an alert when a non-DNS host answers LLMNR, and a baseline check for machines still using NBT-NS. As a defender, the durable fix is to disable LLMNR and NBT-NS and rely on properly configured DNS, then re-run analyze mode to confirm the captures stop.
Safer or lower-noise usage#
- Always start in analyze mode (
-A) and only poison if there is something to catch. - Listen on one dedicated lab interface or VLAN, never a shared broadcast domain.
- Disable rogue servers you do not need in
Responder.confto reduce footprint. - Confirm scope and authorization before the first packet, and write it down.
- Run for a bounded window rather than leaving it listening indefinitely.
- Test one network segment before widening, and stop as soon as you have what you need.
Alternatives#
- tcpdump / Wireshark: passive only. Better when you just want to see name- resolution traffic without affecting any host. Worse when you actually need to capture authentication.
- Inveigh: a Windows-based LLMNR/NBT-NS spoofer. Better when your foothold is a Windows host and you cannot run Linux tooling. Similar concept, different platform.
- mitm6: poisons IPv6 DNS instead of legacy name resolution. Better in IPv6-enabled AD environments; pairs with relay tooling. Use it when LLMNR/NBT-NS are disabled but IPv6 is on.
- Responder remains the standard for LLMNR/NBT-NS/mDNS work on Linux; the alternatives win on platform fit or on the IPv6 angle, while Responder wins on breadth of rogue servers and ease of capture.
Deprecated and legacy notes#
- Older guides reference
Responder.pyas the only entry point; packaged installs now expose arespondercommand, while git clones still runpython3 Responder.py. - The
Responder.conffile has gained and renamed server toggles across versions, so a config snippet from an old tutorial may not match your file. - Some standalone helper scripts that once shipped alongside Responder have moved or been folded into other projects, so check the current upstream repo if one is missing.
- A few flags changed names or defaults between releases; always confirm with
responder -hon your version.
Quick reference cheat sheet#
# --- Pick the interface ---
ip addr # find the lab interface, set it as IFACE
# --- Verify install ---
command -v responder # path if installed via package
responder -h # version-specific options
sudo python3 Responder.py -h # when running from a git clone
# --- Always start passive ---
sudo responder -I IFACE -A # analyze mode: listen, do not poison
sudo responder -I IFACE -A -f # analyze + fingerprint who is broadcasting
# --- Active poisoning (authorized lab only, loud) ---
sudo responder -I IFACE # default poisoning
sudo responder -I IFACE -v # verbose, watch each event
sudo responder -I IFACE -wF # WPAD rogue server, force auth
# --- Watch and collect ---
tail -f /usr/share/responder/logs/Responder-Session.log # live event feed
ls /usr/share/responder/logs/ | grep NTLMv2 # find captured hashes
cp /usr/share/responder/logs/*NTLMv2* loot/ # move loot (sensitive)
# --- Crack offline in the lab ---
hashcat -m 5600 loot/captured-ntlmv2.txt WORDLIST # NetNTLMv2
hashcat -m 5500 loot/captured-ntlmv1.txt WORDLIST # NetNTLMv1
# --- Save analyze output to notes ---
sudo responder -I IFACE -A 2>&1 | tee captures/analyze.txt
Mini decision tree#
- Not sure if poisoning is relevant: start with
-Aanalyze mode and read who broadcasts. - Clients are broadcasting and it is in scope: drop
-Ato poison, add-vto watch. - Captured a hash: copy it to
loot/, then crack withhashcat -m 5600(v2) or-m 5500(v1). - Want to relay instead of capture: disable SMB/HTTP in
Responder.conffirst. - LLMNR/NBT-NS are off but IPv6 is on: consider
mitm6instead. - Need low noise: stay in analyze mode, listen on one VLAN, and stop early.
Final checklist#
- Scope, interface, and authorization noted next to the captures
- Started in analyze mode before any poisoning
- Listened on a dedicated lab interface or VLAN only
- Unneeded rogue servers disabled to reduce noise
- Captured hashes treated as sensitive and moved into scoped loot
- No real third-party networks or credentials used
Final summary#
Responder is best when you use it deliberately: analyze first, confirm there is
something to catch and that it is in scope, then poison only on a network you control.
The fastest way to start is sudo responder -I IFACE -A, which shows you who is
broadcasting without touching anyone. The most expensive mistake is running active
poisoning on the wrong interface or a shared network, because it captures credentials
that were never yours to see. Learn hashcat next, since cracking the NetNTLMv2 hashes
Responder hands you is the natural follow-up step.