> For the complete documentation index, see [llms.txt](https://www.impacket.wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.impacket.wiki/reference/library-api/smb-and-netbios/smbserver.md).

# SMB Server

> SMB server implementation for creating custom SMB file servers

## Overview

The `smbserver` module provides a complete SMB server implementation that allows you to create custom SMB file servers. This is useful for penetration testing, creating honeypots, or implementing custom file sharing services.

## Key Classes

### SimpleSMBServer

Easy-to-use SMB server with minimal configuration.

```python
from impacket import smbserver

server = smbserver.SimpleSMBServer(listenAddress='0.0.0.0',
                                    listenPort=445)
server.addShare('SHARE', '/tmp/share', 'Share description')
server.setSMB2Support(True)
server.start()
```

* **Parameter `listenAddress`** **`str`:** IP address to bind the server to
* **Parameter `listenPort`** **`int`:** Port to listen on (445 for SMB, 139 for NetBIOS)

### SMBSERVER

Advanced SMB server class with full control over configuration.

```python
from impacket import smbserver
import configparser

config = configparser.ConfigParser()
config.add_section('global')
config.set('global', 'server_name', 'FILESERVER')
config.set('global', 'server_os', 'Windows 10')
config.set('global', 'log_file', '/var/log/smb.log')

server = smbserver.SMBSERVER(('0.0.0.0', 445), config_parser=config)
server.processConfigFile()
server.serve_forever()
```

* **Parameter `address`** **`tuple`:** Tuple of (host, port) to bind to
* **Parameter `config_parser`** **`ConfigParser`:** Configuration object defining server behavior and shares

## Server Configuration

### Global Settings

The global section defines server-wide settings:

```python
import configparser

config = configparser.ConfigParser()
config.add_section('global')

# Server identification
config.set('global', 'server_name', 'FILESERVER')
config.set('global', 'server_os', 'Windows 10 Pro')
config.set('global', 'server_domain', 'WORKGROUP')

# Authentication
config.set('global', 'challenge', '4141414141414141')  # 8-byte hex

# Logging
config.set('global', 'log_file', '/var/log/smb.log')
config.set('global', 'credentials_file', '/tmp/hashes.txt')

# SMB2 support
config.set('global', 'SMB2Support', 'True')
```

* **Parameter `server_name`** **`str`:** NetBIOS name of the server
* **Parameter `server_os`** **`str`:** Operating system string returned to clients
* **Parameter `server_domain`** **`str`:** Domain or workgroup name
* **Parameter `challenge`** **`str`:** NTLM challenge (16-character hex string)
* **Parameter `log_file`** **`str`:** Path to log file for server activity
* **Parameter `credentials_file`** **`str`:** Path to file where captured credentials are written
* **Parameter `SMB2Support`** **`str`:** Enable SMB2/SMB3 support ('True' or 'False')

### Share Configuration

Define shared directories:

```python
config.add_section('SHARE')
config.set('SHARE', 'comment', 'Public share')
config.set('SHARE', 'read only', 'no')
config.set('SHARE', 'share type', '0')  # Disk share
config.set('SHARE', 'path', '/tmp/share')
```

* **Parameter `comment`** **`str`:** Description of the share
* **Parameter `read only`** **`str`:** Whether the share is read-only ('yes' or 'no')
* **Parameter `share type`** **`str`:** Share type:
  * `'0'` - Disk share (SHARED\_DISK)
  * `'1'` - Print queue (SHARED\_PRINT\_QUEUE)
  * `'3'` - IPC (SHARED\_IPC)
* **Parameter `path`** **`str`:** Local filesystem path to share

## SimpleSMBServer Methods

### addShare()

Add a new share to the server.

```python
server.addShare(name, path, comment='', readOnly=False)
```

* **Parameter `name`** **`str`:** Share name (e.g., 'SHARE', 'C$')
* **Parameter `path`** **`str`:** Local filesystem path
* **Parameter `comment`** **`str`:** Share description
* **Parameter `readOnly`** **`bool`:** Whether share is read-only

### removeShare()

Remove a share from the server.

```python
server.removeShare(name)
```

* **Parameter `name`** **`str`:** Name of share to remove

### setSMB2Support()

Enable or disable SMB2/SMB3 support.

```python
server.setSMB2Support(enabled)
```

* **Parameter `enabled`** **`bool`:** `True` to enable SMB2/SMB3, `False` for SMB1 only

### setLogFile()

Set the log file path.

```python
server.setLogFile(filename)
```

* **Parameter `filename`** **`str`:** Path to log file

### addCredential()

Add authentication credentials.

```python
server.addCredential(username, password, domain='',
                      lmhash='', nthash='')
```

* **Parameter `username`** **`str`:** Username to accept
* **Parameter `password`** **`str`:** Password to accept
* **Parameter `domain`** **`str`:** Domain name
* **Parameter `lmhash`** **`str`:** LM hash
* **Parameter `nthash`** **`str`:** NT hash

### start()

Start the SMB server (blocking).

```python
server.start()
```

### stop()

Stop the SMB server.

```python
server.stop()
```

## Callback Hooks

Customize server behavior by registering callback functions.

### registerNamedPipe()

Register a handler for named pipe operations.

```python
def pipe_handler(tid, user, data):
    print(f"Pipe accessed by {user}: {data}")
    return b"Response data"

server.registerNamedPipe('srvsvc', pipe_handler)
```

* **Parameter `pipeName`** **`str`:** Name of the pipe (without `\\PIPE\\` prefix)
* **Parameter `callback`** **`callable`:** Function with signature `(tid, user, data) -> bytes`

### setSMBChallenge()

Set a custom NTLM challenge.

```python
server.setSMBChallenge('4141414141414141')  # 8-byte hex
```

* **Parameter `challenge`** **`str`:** 16-character hex string representing 8 bytes

## Usage Examples

### Simple File Server

```python
from impacket import smbserver
import os

# Create share directory
os.makedirs('/tmp/myshare', exist_ok=True)

# Create and configure server
server = smbserver.SimpleSMBServer(listenAddress='0.0.0.0',
                                    listenPort=445)

# Add shares
server.addShare('SHARE', '/tmp/myshare', 'Public Files')
server.addShare('READONLY', '/tmp/readonly', 'Read-Only Files',
                 readOnly=True)

# Enable SMB2
server.setSMB2Support(True)

# Set log file
server.setLogFile('/var/log/smbserver.log')

print("SMB Server started on 0.0.0.0:445")
try:
    server.start()
except KeyboardInterrupt:
    print("\nShutting down...")
    server.stop()
```

### Authenticated Server

```python
from impacket import smbserver

server = smbserver.SimpleSMBServer()

# Add valid credentials
server.addCredential('admin', 'P@ssw0rd', 'WORKGROUP')
server.addCredential('user', 'password123', 'WORKGROUP')

# Add share
server.addShare('FILES', '/tmp/files')

try:
    server.start()
except KeyboardInterrupt:
    server.stop()
```

### Credential Harvesting Server

```python
from impacket import smbserver
import threading

def start_smb_server():
    server = smbserver.SimpleSMBServer()

    # Set custom challenge for consistency
    server.setSMBChallenge('1122334455667788')

    # Log credentials to file
    server.setLogFile('/tmp/smb_hashes.txt')

    # Add a honey share
    server.addShare('ADMIN$', '/tmp/fake_admin', 'Admin Share')
    server.addShare('C$', '/tmp/fake_c', 'C Drive')

    # Enable SMB2 for modern clients
    server.setSMB2Support(True)

    print("[*] SMB Server listening...")
    print("[*] Captured hashes will be written to /tmp/smb_hashes.txt")

    try:
        server.start()
    except KeyboardInterrupt:
        print("\n[*] Stopping server...")
        server.stop()

# Run in separate thread if needed
server_thread = threading.Thread(target=start_smb_server)
server_thread.daemon = True
server_thread.start()

# Keep main thread alive
try:
    server_thread.join()
except KeyboardInterrupt:
    pass
```

### Advanced Configuration

```python
from impacket import smbserver
import configparser
import socket

# Create configuration
config = configparser.ConfigParser()

# Global settings
config.add_section('global')
config.set('global', 'server_name', 'FILESERVER')
config.set('global', 'server_os', 'Windows Server 2019')
config.set('global', 'server_domain', 'CORP')
config.set('global', 'log_file', '/var/log/smbserver.log')
config.set('global', 'credentials_file', '/var/log/smb_creds.txt')
config.set('global', 'SMB2Support', 'True')
config.set('global', 'challenge', 'A'*16)  # Fixed challenge

# Public share
config.add_section('PUBLIC')
config.set('PUBLIC', 'comment', 'Public file share')
config.set('PUBLIC', 'read only', 'no')
config.set('PUBLIC', 'share type', '0')
config.set('PUBLIC', 'path', '/srv/samba/public')

# Private share
config.add_section('PRIVATE')
config.set('PRIVATE', 'comment', 'Private files')
config.set('PRIVATE', 'read only', 'yes')
config.set('PRIVATE', 'share type', '0')
config.set('PRIVATE', 'path', '/srv/samba/private')

# IPC share for RPC
config.add_section('IPC$')
config.set('IPC$', 'comment', 'IPC Service')
config.set('IPC$', 'read only', 'yes')
config.set('IPC$', 'share type', '3')
config.set('IPC$', 'path', '')

# Create and start server
server = smbserver.SMBSERVER(('0.0.0.0', 445),
                              config_parser=config)
server.processConfigFile()

print(f"SMB Server started on {socket.gethostname()}")
print("Available shares: PUBLIC, PRIVATE, IPC$")

try:
    server.serve_forever()
except KeyboardInterrupt:
    print("\nShutting down...")
    server.shutdown()
```

### Custom Named Pipe Handler

```python
from impacket import smbserver
import struct

def handle_srvsvc_pipe(tid, user, data):
    """
    Custom handler for srvsvc pipe (Server Service)
    """
    print(f"[*] SRVSVC pipe accessed by {user}")
    print(f"[*] Data received ({len(data)} bytes)")

    # Parse DCE/RPC header if needed
    # Return response or empty bytes
    return b''

def handle_custom_pipe(tid, user, data):
    """
    Handler for custom named pipe
    """
    print(f"[*] Custom pipe accessed by {user}")

    # Echo back the data
    return data

# Create server
server = smbserver.SimpleSMBServer()

# Register pipe handlers
server.registerNamedPipe('srvsvc', handle_srvsvc_pipe)
server.registerNamedPipe('custom', handle_custom_pipe)

# Add IPC$ share for pipes
server.addShare('IPC$', '', 'IPC Service')

server.start()
```

### Multi-threaded Server

```python
from impacket import smbserver
import threading
import time

class ManagedSMBServer:
    def __init__(self, address='0.0.0.0', port=445):
        self.server = smbserver.SimpleSMBServer(
            listenAddress=address,
            listenPort=port
        )
        self.thread = None
        self.running = False

    def add_share(self, name, path, comment='', read_only=False):
        self.server.addShare(name, path, comment, read_only)

    def start(self):
        """Start server in background thread"""
        if self.running:
            return

        self.running = True
        self.thread = threading.Thread(target=self._run)
        self.thread.daemon = True
        self.thread.start()
        print("[+] SMB Server started")

    def _run(self):
        try:
            self.server.start()
        except Exception as e:
            print(f"[-] Server error: {e}")
            self.running = False

    def stop(self):
        """Stop the server"""
        if not self.running:
            return

        print("[*] Stopping SMB Server...")
        self.server.stop()
        self.running = False
        if self.thread:
            self.thread.join(timeout=5)
        print("[+] Server stopped")

# Usage
managed_server = ManagedSMBServer()
managed_server.add_share('FILES', '/tmp/files')
managed_server.start()

try:
    # Do other work while server runs
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    managed_server.stop()
```

## Security Considerations

> **Warning:** Running an SMB server requires root/administrator privileges to bind to port 445. Always run with appropriate security measures.

> **Note:** The credential harvesting capabilities should only be used for authorized security testing. Capturing credentials without permission is illegal.

### Best Practices

1. **Use authentication** - Always configure credentials unless running a public share
2. **Limit share access** - Only share necessary directories
3. **Monitor logs** - Regularly check log files for suspicious activity
4. **Set read-only where possible** - Minimize write access to prevent abuse
5. **Use SMB2/SMB3** - Enable modern protocol support for better security

## Helper Functions

### getShares()

Get list of configured shares.

```python
from impacket.smbserver import getShares

shares = getShares(connId, smbServer)
```

### searchShare()

Find a specific share by name.

```python
from impacket.smbserver import searchShare

share_config = searchShare(connId, 'SHARE', smbServer)
if share_config:
    print(f"Path: {share_config['path']}")
```

## See Also

* [SMBConnection](/reference/library-api/smb-and-netbios/smbconnection.md) - SMB client implementation
* [SMB](/reference/library-api/smb-and-netbios/smb.md) - Low-level SMB protocol
* [NTLM](/reference/library-api/auth-and-crypto/ntlm.md) - NTLM authentication


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://www.impacket.wiki/reference/library-api/smb-and-netbios/smbserver.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
