Overview
The nmb module provides a complete implementation of the NetBIOS Name Service (NBNS) protocol. It enables NetBIOS name resolution, node status queries, and NetBIOS session management over TCP and UDP.
Key Classes
NetBIOS
Main class for NetBIOS Name Service operations.
from impacket import nmb
nb = nmb.NetBIOS()
response = nb.gethostbyname('WORKSTATION', timeout=1)
NetBIOS Name Service port number
Methods
gethostbyname()
Resolve a NetBIOS name to IP address.
response = nb.gethostbyname(nbname, qtype=TYPE_WORKSTATION,
scope=None, timeout=1)
qtype
int
default:"TYPE_WORKSTATION"
NetBIOS name type:
TYPE_WORKSTATION (0x00) - Workstation service
TYPE_SERVER (0x20) - File server service
TYPE_DOMAIN_MASTER (0x1B) - Domain master browser
TYPE_DOMAIN_CONTROLLER (0x1C) - Domain controller
TYPE_MASTER_BROWSER (0x1D) - Master browser
NetBIOS scope identifier (rarely used)
return
NBPositiveNameQueryResponse
Object containing IP addresses for the name
getnodestatus()
Query node status information.
entries = nb.getnodestatus(nbname, destaddr=None,
type=TYPE_WORKSTATION,
scope=None, timeout=1)
NetBIOS name to query (use '*' for any name)
IP address to send query to. If None, uses broadcast or nameserver.
type
int
default:"TYPE_WORKSTATION"
NetBIOS name type
List of NetBIOS name entries registered by the node
getnetbiosname()
Get the NetBIOS name for an IP address.
name = nb.getnetbiosname(ip)
NetBIOS name of the server type (0x20)
getmacaddress()
Get MAC address from last node status query.
MAC address in format 'AA-BB-CC-DD-EE-FF'
set_nameserver()
Set a specific NetBIOS nameserver.
nb.set_nameserver('192.168.1.10')
IP address of NetBIOS nameserver
set_broadcastaddr()
Set the broadcast address for queries.
nb.set_broadcastaddr('192.168.1.255')
NetBIOSTCPSession
TCP-based NetBIOS session for SMB communication.
session = nmb.NetBIOSTCPSession(myname, remote_name, remote_host,
remote_type=TYPE_SERVER,
sess_port=139, timeout=60)
Session port (139 for NetBIOS, 445 for direct SMB)
send_packet()
Send a NetBIOS session packet.
session.send_packet(data)
recv_packet()
Receive a NetBIOS session packet.
packet = session.recv_packet(timeout=None)
Receive timeout in seconds
NetBIOSUDPSession
UDP-based NetBIOS datagram service.
session = nmb.NetBIOSUDPSession(myname, remote_name, remote_host,
remote_type=TYPE_SERVER,
sess_port=138)
Constants
Port Numbers
NETBIOS_NS_PORT = 137 # Name Service
NETBIOS_SESSION_PORT = 139 # Session Service
SMB_SESSION_PORT = 445 # Direct SMB (no NetBIOS)
Name Types
TYPE_WORKSTATION = 0x00 # Workstation service
TYPE_CLIENT = 0x03 # Messenger service
TYPE_SERVER = 0x20 # File server service
TYPE_DOMAIN_MASTER = 0x1B # Domain master browser
TYPE_DOMAIN_CONTROLLER = 0x1C # Domain controller
TYPE_MASTER_BROWSER = 0x1D # Master browser
TYPE_BROWSER = 0x1E # Browser service
TYPE_NETDDE = 0x1F # NetDDE service
TYPE_STATUS = 0x21 # Node status
Node Types
NODE_B = 0x0000 # Broadcast node
NODE_P = 0x2000 # Point-to-point node
NODE_M = 0x4000 # Mixed node
NODE_GROUP = 0x8000 # Group name
NODE_UNIQUE = 0x0 # Unique name
Supporting Classes
NODE_NAME_ENTRY
Represents a NetBIOS name entry from node status.
Name type suffix (0x00, 0x20, etc.)
Name flags (active, permanent, conflict, etc.)
NBPositiveNameQueryResponse
Response from name query containing IP addresses.
response = nb.gethostbyname('WORKSTATION')
for ip in response.entries:
print(f"IP: {ip}")
NetBIOSSessionPacket
Represents a NetBIOS session packet.
Packet type (MESSAGE, REQUEST, RESPONSE, etc.)
Exceptions
NetBIOSError
Raised when NetBIOS operations fail.
try:
response = nb.gethostbyname('UNKNOWN')
except nmb.NetBIOSError as e:
print(f"NetBIOS error: {e}")
NetBIOSTimeout
Raised when operations timeout.
try:
response = nb.gethostbyname('HOST', timeout=1)
except nmb.NetBIOSTimeout:
print("Query timed out")
Usage Examples
Name Resolution
from impacket import nmb
nb = nmb.NetBIOS()
# Resolve NetBIOS name to IP
try:
response = nb.gethostbyname('WORKSTATION',
qtype=nmb.TYPE_SERVER,
timeout=2)
print(f"Found {len(response.entries)} addresses:")
for ip in response.entries:
print(f" {ip}")
except nmb.NetBIOSTimeout:
print("Name resolution timed out")
except nmb.NetBIOSError as e:
print(f"Error: {e}")
Node Status Query
from impacket import nmb
nb = nmb.NetBIOS()
# Query node for all registered names
try:
entries = nb.getnodestatus('*', '192.168.1.100')
print(f"NetBIOS names for 192.168.1.100:")
for entry in entries:
name = entry['NAME'].decode('latin-1').strip()
name_type = entry['TYPE']
# Get human-readable type
type_str = nmb.NAME_TYPES.get(name_type, 'Unknown')
print(f" {name:<15} <{name_type:02X}> {type_str}")
# Get MAC address
mac = nb.getmacaddress()
print(f"\nMAC Address: {mac}")
except nmb.NetBIOSError as e:
print(f"Error: {e}")
Get NetBIOS Name from IP
from impacket import nmb
def get_nbname(ip):
"""
Get NetBIOS name for an IP address
"""
nb = nmb.NetBIOS()
try:
name = nb.getnetbiosname(ip)
return name
except:
return None
# Usage
ip = '192.168.1.100'
name = get_nbname(ip)
if name:
print(f"{ip} -> {name}")
else:
print(f"Could not resolve {ip}")
Network Scanning
from impacket import nmb
import ipaddress
import concurrent.futures
def scan_host(ip):
"""
Scan a single host for NetBIOS
"""
nb = nmb.NetBIOS()
try:
entries = nb.getnodestatus('*', ip, timeout=1)
# Get server name (type 0x20)
server_names = [e for e in entries if e['TYPE'] == nmb.TYPE_SERVER]
if server_names:
name = server_names[0]['NAME'].decode('latin-1').strip()
return (ip, name, nb.getmacaddress())
except:
pass
return None
# Scan subnet
network = ipaddress.ip_network('192.168.1.0/24')
hosts = [str(ip) for ip in network.hosts()]
print("Scanning for NetBIOS hosts...")
with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
results = executor.map(scan_host, hosts)
for result in results:
if result:
ip, name, mac = result
print(f"{ip:<15} {name:<15} {mac}")
Using with SMB
from impacket import nmb, smb
# First resolve NetBIOS name
nb = nmb.NetBIOS()
response = nb.gethostbyname('FILESERVER')
ip = response.entries[0]
print(f"FILESERVER is at {ip}")
# Now connect via SMB
conn = smb.SMB('FILESERVER', ip)
conn.login('user', 'password')
# List shares
tid = conn.connect_tree(f'\\\\{ip}\\IPC$')
print("Connected successfully")
conn.logoff()
Enumerating Domain Controllers
from impacket import nmb
def find_domain_controllers(domain):
"""
Find domain controllers for a domain
"""
nb = nmb.NetBIOS()
# Query for domain controller name (type 0x1C)
try:
response = nb.gethostbyname(domain,
qtype=nmb.TYPE_DOMAIN_CONTROLLER)
return response.entries
except nmb.NetBIOSError:
return []
# Usage
domain = 'CORP'
dcs = find_domain_controllers(domain)
if dcs:
print(f"Domain controllers for {domain}:")
for dc_ip in dcs:
# Get DC name
nb = nmb.NetBIOS()
try:
dc_name = nb.getnetbiosname(dc_ip)
print(f" {dc_name} ({dc_ip})")
except:
print(f" {dc_ip}")
else:
print(f"No domain controllers found for {domain}")
Custom NetBIOS Session
from impacket import nmb
# Create NetBIOS session
session = nmb.NetBIOSTCPSession(
myname='CLIENT',
remote_name='SERVER',
remote_host='192.168.1.100',
remote_type=nmb.TYPE_SERVER,
sess_port=139
)
# Send data
data = b'SMB data here'
session.send_packet(data)
# Receive response
response = session.recv_packet(timeout=5)
print(f"Received {len(response.get_trailer())} bytes")
# Close session
session.close()
Helper Functions
encode_name()
Encode a NetBIOS name.
from impacket.nmb import encode_name
encoded = encode_name('WORKSTATION', nmb.TYPE_SERVER, scope=None)
NetBIOS name (max 15 characters)
decode_name()
Decode an encoded NetBIOS name.
from impacket.nmb import decode_name
offset, name, scope = decode_name(encoded_data)
See Also