Impacket exchanger.py
Back to the Category Index / Back to the Command Index
Overview
Section titled “Overview”Connects to Exchange NSPI over RPC to enumerate the address book and search by GUID or DNT.
| Item | Details |
|---|---|
| Implementation | examples/exchanger.py |
| Category | MSSQL / Exchange / MQTT |
| Size | 1078 lines |
| Distribution | Installed as a script through scripts=examples/*.py in setup.py |
CLI and Inputs
Section titled “CLI and Inputs”Check python examples/exchanger.py -h for the current option definitions.
Subcommands: nspi, list-tables, dump-tables, guid-known, dnt-lookup
| Argument | Description |
|---|---|
target | [[domain/]username[:password]@]<targetName or address> |
-debug | Enable debug and extended output. |
-ts | Add timestamps to log output. |
-rpc-hostname | Server name in GUID format (preferred) or as a NetBIOS name; see the description at the start of the script. |
-hashes | NTLM hashes in LMHASH:NTHASH format. |
-count | Request the total number of records in each table. |
-basic | Use Basic authentication instead of NTLM. |
-lookup-type | Lookup type: MINIMAL requests limited fields (default); EXTENDED requests more fields; FULL requests all fields for each row; GUIDS requests GUIDs only (choices: MINIMAL, EXTENDED, FULL, GUIDS). |
-rows-per-request | Maximum rows per request (default: 50). |
-guid | Dump the table with the specified GUID. |
-output-type | Binary-object output format (choices: hex, base64; default: hex). |
-output-file | Output filename. |
-guid-file | Dump objects using GUIDs from a file. |
-start-dnt | Starting DNT (default: 500000). |
-stop-dnt | DNT at which to stop the lookup. |
-name | Dump the table with the specified name, including the GAL. |
Detailed Processing Flow
Section titled “Detailed Processing Flow”The command builds an RPC transport from autodiscovery or an explicit hostname and credentials, then binds to NSPI and initializes STAT. nspi list-tables, dump-tables, guid-known, and dnt-lookup select tables or containers. It retrieves property rows in pages and writes them as tables, hex, CSV, or other formats.
How It Works
Section titled “How It Works”NSPI exposes the Exchange Address Book’s table and property model over RPC.
Exchanger determines the RPC endpoint and HTTP proxy information through
autodiscovery or a specified hostname, then sets credentials on the transport.
After NSPI bind, the STAT structure is a cursor containing the current container, code page, and row position.
list-tables reads the hierarchy/container table and maps address book
container IDs to names. dump-tables specifies a property-tag set for the
selected container and repeats QueryRows in pages. Each property is
decoded according to its MAPI type as a string, integer, binary value,
multivalue, or other form. Failing to advance the row count and STAT position repeats the same page.
GUID and DNT lookups use NSPI requests and identifiers that differ from ordinary table scans. When converting between GUID, DN, and DNT, account for absent properties and code pages returned by the server. Keep output type and file handling separate from the protocol layer so binary properties remain available for later analysis, rather than becoming only lossy display strings.
Key Implementation Elements
Section titled “Key Implementation Elements”| Symbol | Location | Entry Point for Tracing Behavior |
|---|---|---|
Exchanger | 63 | __init__(), conenct_mapi(), connect_rpc(), load_autodiscover(), set_credentials(), set_extended_output(), set_output_type(), set_output_file(), print() |
NSPIAttacks | 135 | __init__(), connect_rpc(), update_stat(), load_htable(), load_htable_stat(), load_htable_containerid(), print_htable(), disconnect(), print_row(), load_props(), req_print_table_rows(), req_print_guid(), and others |
ExchangerHelper | 721 | __init__(), run(), nspi_run(), nspi_check(), nspi_list_tables(), nspi_dump_tables(), nspi_guid_known(), nspi_dnt_lookup() |
Dependencies
Section titled “Dependencies”Internal Impacket Modules
Section titled “Internal Impacket Modules”| Module | Main Names Used |
|---|---|
impacket | uuid, version |
impacket.http | AUTH_BASIC |
impacket.examples | logger |
impacket.examples.utils | parse_target |
impacket.structure | parse_bitmask |
impacket.dcerpc.v5 | nspi, transport |
impacket.mapi_constants | MAPI_PROPERTIES, PR_CONTAINER_FLAGS_VALUES |
impacket.dcerpc.v5.nspi | CP_TELETEX, ExchBinaryObject, get_dn_from_guid, get_guid_from_dn |
impacket.dcerpc.v5.rpch | RPC_PROXY_CONN_A1_0X6BA_ERR, RPC_PROXY_CONN_A1_401_ERR, RPC_PROXY_CONN_A1_404_ERR, RPC_PROXY_HTTP_IN_DATA_401_ERR, RPC_PROXY_REMOTE_NAME_NEEDED_ERR, RPC_PROXY_RPC_OUT_DATA_404_ERR |
External Packages (Direct Use)
Section titled “External Packages (Direct Use)”| Import Name | Distribution Package | Usage / Declaration Status |
|---|---|---|
six | six | Imported directly; declared dependency |
Output, Side Effects, and Required Privileges
Section titled “Output, Side Effects, and Required Privileges”- Primarily queries and authentication attempts. Repeated runs can affect audit logs, account lockouts, and target load.
- Depending on options, creates or updates a local file. Check how existing files are handled and the permissions on output containing secrets.
Failure Paths and Cleanup
Section titled “Failure Paths and Cleanup”- On failure, use protocol status to determine whether name resolution, connection, authentication, service state, or permissions stopped the operation.
disconnect()handles cleanup. Check that new early returns and exception paths still reach it.
When Changing the Implementation
Section titled “When Changing the Implementation”This command depends on dcerpc.v5.nspi / transport / rpch, mapi_constants, and HTTP Basic/NTLM. Exchanger handles connections, NSPIAttacks handles requests and row parsing, and ExchangerHelper dispatches CLI subcommands.
Verification
Section titled “Verification”- Syntax:
python -m py_compile examples/exchanger.py - CLI:
python examples/exchanger.py -h - Related test:
tests/SMB_RPC/test_rpch.py - Related test:
tests/misc/test_dcerpc_v5_ndr.py - Related test:
tests/misc/test_structure.py

