Skip to main content

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)
servport
int
default:"137"
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)
nbname
str
required
NetBIOS name to resolve
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
scope
str
NetBIOS scope identifier (rarely used)
timeout
int
default:"1"
Query timeout in seconds
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)
nbname
str
required
NetBIOS name to query (use '*' for any name)
destaddr
str
IP address to send query to. If None, uses broadcast or nameserver.
type
int
default:"TYPE_WORKSTATION"
NetBIOS name type
scope
str
NetBIOS scope
timeout
int
default:"1"
Query timeout in seconds
return
list[NODE_NAME_ENTRY]
List of NetBIOS name entries registered by the node

getnetbiosname()

Get the NetBIOS name for an IP address.
name = nb.getnetbiosname(ip)
ip
str
required
IP address to query
return
str
NetBIOS name of the server type (0x20)

getmacaddress()

Get MAC address from last node status query.
mac = nb.getmacaddress()
return
str
MAC address in format 'AA-BB-CC-DD-EE-FF'

set_nameserver()

Set a specific NetBIOS nameserver.
nb.set_nameserver('192.168.1.10')
nameserver
str
required
IP address of NetBIOS nameserver

set_broadcastaddr()

Set the broadcast address for queries.
nb.set_broadcastaddr('192.168.1.255')
broadcastaddr
str
required
Broadcast address

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)
myname
str
required
Local NetBIOS name
remote_name
str
required
Remote NetBIOS name
remote_host
str
required
Remote IP address
remote_type
int
default:"TYPE_SERVER"
Remote NetBIOS name type
sess_port
int
default:"139"
Session port (139 for NetBIOS, 445 for direct SMB)
timeout
int
Connection timeout

send_packet()

Send a NetBIOS session packet.
session.send_packet(data)
data
bytes
required
Data to send

recv_packet()

Receive a NetBIOS session packet.
packet = session.recv_packet(timeout=None)
timeout
int
Receive timeout in seconds
return
NetBIOSSessionPacket
Received packet

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
bytes
NetBIOS name (15 bytes)
TYPE
int
Name type suffix (0x00, 0x20, etc.)
NAME_FLAGS
int
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}")
entries
list[str]
List of IP addresses

NetBIOSSessionPacket

Represents a NetBIOS session packet.
get_type()
int
Packet type (MESSAGE, REQUEST, RESPONSE, etc.)
get_trailer()
bytes
Packet data payload
get_length()
int
Payload length

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)
name
str
required
NetBIOS name (max 15 characters)
nametype
int
required
Name type suffix
scope
str
NetBIOS scope
return
bytes
Encoded NetBIOS name

decode_name()

Decode an encoded NetBIOS name.
from impacket.nmb import decode_name

offset, name, scope = decode_name(encoded_data)
name
bytes
required
Encoded name data
offset
int
Bytes consumed
name
str
Decoded name
scope
str
Scope identifier

See Also

Build docs developers (and LLMs) love