Class InteractshClient
- Namespace
- Kuestenlogik.Bowire.Oast
- Assembly
- Kuestenlogik.Bowire.Oast.dll
An IOastClient speaking the interactsh wire protocol, so
--oast-server points at any compatible instance — Küstenlogik's, a
self-hosted one, or a third party's. No third-party dependency: HttpClient
plus BCL crypto only.
public sealed class InteractshClient : IOastClient, IAsyncDisposable
- Inheritance
-
InteractshClient
- Implements
- Inherited Members
Remarks
The exchange, per the reference implementation:
- Generate an RSA keypair.
POST /registerwith{PublicKey (base64 of the PEM), SecretKey (uuid), CorrelationID}. - Plant
<correlationId><nonce>.<domain>hosts in probes — 20 + 13 characters by default, the length the server slices on. GET /poll?id=&secret=returnsaes_key(the AES key, RSA-OAEP/SHA-256 wrapped to our public key) anddata(each item AES-CTR encrypted, IV = the first 16 bytes).extra/tld_dataarrive as plaintext JSON.
The server never learns the AES key's plaintext from us and we never send the private key — the point of the RSA wrap is that a shared/hosted instance cannot read interactions belonging to other sessions.
Constructors
InteractshClient(string, string?, HttpMessageHandler?)
Create a client for the interaction server at serverUrl
(e.g. https://oast.example.com). Pass token to
authenticate against a gated instance (one started with
bowire oast serve --token); it is sent verbatim as the
Authorization header, matching the interactsh convention.
Pass httpHandler to drive the exchange in tests
without a live server.
public InteractshClient(string serverUrl, string? token = null, HttpMessageHandler? httpHandler = null)
Parameters
serverUrlstringtokenstringhttpHandlerHttpMessageHandler
Properties
ServerDomain
The interaction-server domain callbacks are addressed under (e.g.
oast.example.com). Surfaced so findings can name where the
evidence was collected.
public string ServerDomain { get; }
Property Value
Methods
Allocate()
Reserve a fresh callback host for one probe. Cheap + local after the session is registered — allocation does not round-trip per call.
public OastAllocation Allocate()
Returns
DisposeAsync()
public ValueTask DisposeAsync()
Returns
PollAsync(CancellationToken)
Fetch the interactions the server has recorded for this session since the last poll. Returns only new ones; correlate them to a probe via FullId / UniqueId.
public Task<IReadOnlyList<OastInteraction>> PollAsync(CancellationToken ct = default)
Parameters
Returns
RegisterAsync(CancellationToken)
Register this session's public key with the server. Called once, lazily, by the first PollAsync(CancellationToken); exposed so a caller can fail fast (e.g. a bad --oast-server URL) before running a whole scan.
public Task RegisterAsync(CancellationToken ct = default)