File: README.md
An OOB interaction gathering server and client library
Interactsh is an open-source tool for detecting out-of-band interactions. It is a tool designed to detect vulnerabilities that cause external interactions.
Features
- DNS/HTTP(S)/SMTP(S)/LDAP Interaction
- IPv4 and IPv6 support
- CLI / Web / Burp / ZAP / Docker client
- AES encryption with zero logging
- Automatic ACME based Wildcard TLS w/ Auto Renewal
- DNS Entries for Cloud Metadata service
- Dynamic HTTP Response control
- Self-Hosted Interactsh Server
- Multiple domain support (self-hosted)
- NTLM/SMB/FTP(S)/RESPONDER Listener (self-hosted)
- Wildcard / Protected Interactions (self-hosted)
- Customizable Index / File hosting (self-hosted)
- Client file hosting for second-stage OOB payloads (self-hosted)
- Customizable Payload Length (self-hosted)
- Custom SSL Certificate (self-hosted)
Interactsh Client
Usage
interactsh-client -hThis will display help for the tool. Here are all the switches it supports.
Usage:
./interactsh-client [flags]
Flags:
INPUT:
-s, -server string interactsh server(s) to use (default "oast.pro,oast.live,oast.site,oast.online,oast.fun,oast.me")
-fl, -file string[] local file(s) to upload and host on the interactsh server
CONFIG:
-config string flag configuration file (default "$HOME/.config/interactsh-client/config.yaml")
-auth configure projectdiscovery cloud (pdcp) api key (default true)
-n, -number int number of interactsh payload to generate (default 1)
-t, -token string authentication token to connect protected interactsh server
-pi, -poll-interval int poll interval in seconds to pull interaction data (default 5)
-nf, -no-http-fallback disable http fallback registration
-cidl, -correlation-id-length int length of the correlation id preamble (min 3, default 20) (default 20)
-cidn, -correlation-id-nonce-length int length of the correlation id nonce (min 3, default 13) (default 13)
-sf, -session-file string store/read from session file
-kai, -keep-alive-interval value keep alive interval (default 1m0s)
FILTER:
-m, -match string[] match interaction based on the specified pattern
-f, -filter string[] filter interaction based on the specified pattern
-dns-only display only dns interaction in CLI output
-http-only display only http interaction in CLI output
-smtp-only display only smtp interactions in CLI output
-asn include asn information of remote ip in json output
UPDATE:
-up, -update update interactsh-client to latest version
-duc, -disable-update-check disable automatic interactsh-client update check
OUTPUT:
-o string output file to write interaction data
-json write output in JSON Lines format
-ps, -payload-store write generated interactsh payload to file
-psf, -payload-store-file string store generated interactsh payloads to given file (default "interactsh_payload.txt")
-fsf, -file-store-file string store hosted file URLs to given file (requires -file)
-v display verbose interaction
DEBUG:
-version show version of the project
-health-check, -hc run diagnostic check upInteractsh CLI Client
Interactsh Cli client requires go1.20+ to install successfully. Run the following command to get the repo -
go install -v github.com/projectdiscovery/interactsh/cmd/interactsh-client@latestConfigure PDCP_API_KEY With Interactsh CLI Client
Get your free api key by signing up at https://cloud.projectdiscovery.io
You can configure your PDCP_API_KEY in two ways:
- To configure the API key interactively, run the following command:sh
./interactsh-client -auth - If you prefer to pass the API key directly, use the -auth option followed by your API key:sh
./interactsh-client -auth=<pdcp-api-key>
Default Run
This will generate a unique payload that can be used for OOB testing with minimal interaction information in the output.
$ interactsh-client
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v0.0.5
projectdiscovery.io
[INF] Listing 1 payload for OOB Testing
[INF] c23b2la0kl1krjcrdj10cndmnioyyyyyn.oast.pro
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (A) from 172.253.226.100 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (AAAA) from 32.3.34.129 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received HTTP interaction from 43.22.22.50 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received HTTPS interaction from 43.22.22.50 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (MX) from 43.3.192.3 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (TXT) from 74.32.183.135 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received SMTP interaction from 32.85.166.50 at 2021-26-26 12:26Session File
interactsh-client with -sf, -session-file flag can be used store/read the current session information from user defined file which is useful to resume the same session to poll the interactions even after the client gets stopped or closed.
$ interactsh-client -sf interact.session
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ 1.0.3
projectdiscovery.io
[INF] Listing 1 payload for OOB Testing
[INF] c23b2la0kl1krjcrdj10cndmnioyyyyyn.oast.pro
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (A) from 172.253.226.100 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (AAAA) from 32.3.34.129 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received HTTP interaction from 43.22.22.50 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received HTTPS interaction from 43.22.22.50 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (MX) from 43.3.192.3 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received DNS interaction (TXT) from 74.32.183.135 at 2021-26-26 12:26
[c23b2la0kl1krjcrdj10cndmnioyyyyyn] Received SMTP interaction from 32.85.166.50 at 2021-26-26 12:26Verbose Mode
Running the interactsh-client in verbose mode (v) to see the whole request and response, along with an output file to analyze afterwards.
$ interactsh-client -v -o interactsh-logs.txt
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ 1.0.3
projectdiscovery.io
[INF] Listing 1 payload for OOB Testing
[INF] c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro
[c58bduhe008dovpvhvugcfemp9yyyyyyn] Received HTTPS interaction from 103.22.142.211 at 2021-09-26 18:08:07
------------
HTTP Request
------------
GET /favicon.ico HTTP/2.0
Host: c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro
Referer: https://c58bduhe008dovpvhvugcfemp9yyyyyyn.oast.pro
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36
-------------
HTTP Response
-------------
HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=utf-8
Server: oast.pro
<html><head></head><body>nyyyyyy9pmefcguvhvpvod800ehudb85c</body></html>Using Self-Hosted server
Using the server flag, interactsh-client can be configured to connect with a self-hosted Interactsh server, this flag accepts single or multiple server separated by comma.
interactsh-client -server hackwithautomation.comWe maintain a list of default Interactsh servers to use with interactsh-client:
- oast.pro
- oast.live
- oast.site
- oast.online
- oast.fun
- oast.me
Default servers are subject to change/rotate/down at any time, thus we recommend using a self-hosted interactsh server if you are experiencing issues with the default server.
Using Protected Self-Hosted server
Using the token flag, interactsh-client can connect to a self-hosted Interactsh server that is protected with authentication.
interactsh-client -server hackwithautomation.com -token XXXUsing with Notify
If you are away from your terminal, you may use notify to send a real-time interaction notification to any supported platform.
interactsh-client | notifyInteractsh Web Client
Interactsh-web is a free and open-source web client that displays Interactsh interactions in a well-managed dashboard in your browser. It uses the browser's local storage to store and display all incoming interactions. By default, the web client is configured to use oast.fun as default interactsh server, and supports other self-hosted public/authencaited interactsh servers as well.
A hosted instance of interactsh-web client is available at https://app.interactsh.com
Interactsh Docker Client
A Docker image is also provided with interactsh client that is ready to run and can be used in the following way:
docker run projectdiscovery/interactsh-client:latest$ docker run projectdiscovery/interactsh-client:latest
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.0
projectdiscovery.io
[INF] Listing 1 payload for OOB Testing
[INF] c59e3crp82ke7bcnedq0cfjqdpeyyyyyn.oast.proBurp Suite Original Extension
interactsh-collaborator is an original Burp Suite interactsh extension developed and maintained by @wdahlenb
- Download latest JAR file from releases page.
- Open Burp Suite → Extender → Add → Java → Select JAR file → Next
- New tab named Interactsh will be appeared upon successful installation.
- See the interactsh-collaborator project for more info.
Burp Suite Revised Extension
interactsh-collaborator-rev is a revised version of the original Burp Suite interactsh extension and is developed and maintained by @Arqsz
- Download latest JAR file from releases page.
- Open Burp Suite → Extender → Add → Java → Select JAR file → Next
- New tab named Interactsh will be appeared upon successful installation.
- See the interactsh-collaborator-rev project for more info.
ZAP Add-On
Interactsh can be used with ZAP via the OAST add-on for ZAP. With ZAP's scripting capabilities, you can create powerful out-of-band scan rules that leverage Interactsh's features. A standalone script template has been provided as an example (it is added automatically when you install the add-on).
- Install the OAST add-on from the ZAP Marketplace.
- Go to Tools → Options → OAST and select Interactsh.
- Configure the options for the client and click on "New Payload" to generate a new payload.
- OOB interactions will appear in the OAST Tab and you can click on any of them to view the full request and response.
- You can set Interactsh as the default for ActiveScan in the
Options>OAST>Generalmenu. - When checking the
Use Permanent Databaseoption, you can review interactions that occurred after ZAP was terminated. - See the OAST add-on documentation for more info.
Interactsh in ZAP
Caido Extension
quickssrf is Caido extension developed and maintained which allows using Interactsh from within Caido Proxy.
- Download latest zip file from releases page.
- Open Caido → Plugins → Install Package → Select zip file → Next
- New sidebar named QuickSSRF will appear upon successful installation.
- See the quickssrf project for more info.
Interactsh Server
Interactsh server runs multiple services and captures all the incoming requests. To host an instance of interactsh-server, you are required to setup:
- Domain name with custom host names and nameservers.
- Basic droplet running 24/7 in the background.
Usage
interactsh-server -hThis will display help for the tool. Here are all the switches it supports.
Usage:
./interactsh-server [flags]
Flags:
INPUT:
-d, -domain string[] single/multiple configured domain to use for server
-i, -ip string[] public IP address(es) to use for interactsh server (comma-separated, supports both IPv4 & IPv6)
-lip, -listen-ip string public ip address to listen on (default "0.0.0.0")
-e, -eviction int number of days to persist interaction data in memory (default 30)
-ne, -no-eviction disable periodic data eviction from memory
-es, -eviction-strategy string eviction strategy for interactions (sliding, fixed) (default "sliding")
-a, -auth enable authentication to server using random generated token
-t, -token string enable authentication to server using given token
-acao-url string origin url to send in acao header to use web-client) (default "*")
-sa, -skip-acme skip acme registration (certificate checks/handshake + TLS protocols will be disabled)
-se, -scan-everywhere scan canary token everywhere
-cidl, -correlation-id-length int length of the correlation id preamble (min 3, default 20) (default 20)
-cidn, -correlation-id-nonce-length int length of the correlation id nonce (min 3, default 13) (default 13)
-cert string custom certificate path
-privkey string custom private key path
-oih, -origin-ip-header string HTTP header containing origin ip (interactsh behind a reverse proxy)
CONFIG:
-r, -resolvers string[] list of resolvers to use (file or comma separated)
-config string flag configuration file (default "$HOME/.config/interactsh-server/config.yaml")
-dr, -dynamic-resp enable setting up arbitrary response data
-cr, -custom-records string custom dns records YAML file for DNS server
-hi, -http-index string custom index file for http server
-hd, -http-directory string directory with files to serve with http server
-dhr, -default-http-response string file to serve for all http requests (takes priority over other options)
-ds, -disk disk based storage
-dsp, -disk-path string disk storage path
-ru, -redis-url string redis connection URL (enables shared state for multi-instance deployments)
-rp, -redis-prefix string redis key prefix (default "interactsh:")
-csh, -server-header string custom value of Server header in response
-dv, -disable-version disable publishing interactsh version in response header
UPDATE:
-up, -update update interactsh-server to latest version
-duc, -disable-update-check disable automatic interactsh-server update check
SERVICES:
-dns-port int port to use for dns service (default 53)
-http-port int port to use for http service (default 80)
-https-port int port to use for https service (default 443)
-smtp-port int port to use for smtp service (default 25)
-smtps-port int port to use for smtps service (default 587)
-smtp-autotls-port int port to use for smtps autotls service (default 465)
-ldap-port int port to use for ldap service (default 389)
-ldap enable ldap server with full logging (authenticated)
-wc, -wildcard enable wildcard interaction for interactsh domain (authenticated)
-smb start in-process smb agent for NetNTLMv2 hash capture (authenticated)
-responder start in-process responder agent (multi-port SMB NetNTLMv2 hash capture, authenticated)
-ftp start ftp agent (authenticated)
-smb-port int port to use for smb service (default 445)
-ftp-port int port to use for ftp service (default 21)
-ftps-port int port to use for ftps service (default 990)
-ftp-dir string ftp directory - temporary if not specified
UPLOAD:
-upload enable client file upload and hosting - self-hosted servers only (authenticated)
-ud, -upload-directory string directory to host uploaded files from - temporary if not specified; interactsh creates and prunes .interactsh-user-uploads inside it
-umfs, -upload-max-file-size value maximum size of a single uploaded file (default 1mb)
-umf, -upload-max-files int maximum number of uploaded files per session (default 5)
-umts, -upload-max-total-size value maximum total size of all uploaded files on the server (default 1gb)
-ut, -upload-ttl value maximum lifetime of uploaded files (default 24h0m0s)
DEBUG:
-version show version of the project
-debug start interactsh server in debug mode
-ep, -enable-pprof enable pprof debugging server
-health-check, -hc run diagnostic check up
-metrics enable metrics endpoint
-v, -verbose display verbose interactionWe are using GoDaddy for domain name and DigitalOcean droplet for the server, a basic $5 droplet should be sufficient to run self-hosted Interactsh server. If you are not using GoDaddy, follow your registrar's process for creating / updating DNS entries.
Running Interactsh Server
$ interactsh-server -domain interact.sh
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.0
projectdiscovery.io
[INF] Listening with the following services:
[HTTPS] Listening on TCP 46.101.25.250:443
[HTTP] Listening on TCP 46.101.25.250:80
[SMTPS] Listening on TCP 46.101.25.250:587
[LDAP] Listening on TCP 46.101.25.250:389
[SMTP] Listening on TCP 46.101.25.250:25
[DNS] Listening on TCP 46.101.25.250:53
[DNS] Listening on UDP 46.101.25.250:53Interactsh Server with Multiple Domain
Multiple domain names can be given in the same way as above to run the same interactsh server across multiple configured domains.
$ interactsh-server -d oast.pro,oast.me
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ 1.0.5
projectdiscovery.io
[INF] Loading existing SSL Certificate for: [*.oast.pro, oast.pro]
[INF] Loading existing SSL Certificate for: [*.oast.me, oast.me]
[INF] Listening with the following services:
[HTTPS] Listening on TCP 46.101.25.250:443
[HTTP] Listening on TCP 46.101.25.250:80
[SMTPS] Listening on TCP 46.101.25.250:587
[LDAP] Listening on TCP 46.101.25.250:389
[SMTP] Listening on TCP 46.101.25.250:25
[DNS] Listening on TCP 46.101.25.250:53
[DNS] Listening on UDP 46.101.25.250:53Interactsh Server with IPv4 and IPv6
Interactsh server supports both IPv4 and IPv6 addresses. You can specify multiple IP addresses using the -ip flag, and the server will respond with the appropriate A (IPv4) or AAAA (IPv6) records in DNS responses.
$ interactsh-server -d oast.pro -ip 192.0.2.1,2001:db8::1
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ 1.0.5
projectdiscovery.io
[INF] Configured IP addresses: 192.0.2.1, 2001:db8::1
[INF] Listening with the following services:
[HTTPS] Listening on TCP 46.101.25.250:443
[HTTP] Listening on TCP 46.101.25.250:80
[SMTPS] Listening on TCP 46.101.25.250:587
[LDAP] Listening on TCP 46.101.25.250:389
[SMTP] Listening on TCP 46.101.25.250:25
[DNS] Listening on TCP 46.101.25.250:53
[DNS] Listening on UDP 46.101.25.250:53The server will automatically detect and categorize IPv4 and IPv6 addresses, returning appropriate DNS records based on the query type.
When the selected server publishes no AAAA records, the client prints a warning so that interactions from IPv6-only sources are not silently missed and mistaken for the absence of a vulnerability.
There are more useful capabilities supported by interactsh-server that are not enabled by default and are intended to be used only by self-hosted servers.
Interactsh Server behind a reverse proxy
interactsh-server might require custom ports for services if the default ones are already busy. If this is the case but still default ports are required as part of the payload, it's possible to configure interactsh-server behind a reverse proxy, by port-forwarding HTTP/TCP/UDP based services via http/stream proxy directive (proxy_pass).
Nginx
Assuming that interactsh-server essential services run on the following ports:
- HTTP: 8080/TCP
- HTTPS: 8440/TCP
- SMTP: 8025/TCP
- DNS: 8053/UDP
- DNS: 8053/TCP
The nginx configuration file to forward the traffic would look like the following one:
# http/https
http {
server {
listen 443 ssl;
server_name mysite.com;
ssl_certificate /etc/nginx/interactsh.pem;
ssl_certificate_key /etc/nginx/interactsh.key;
location / {
proxy_pass https://interachsh.mysite.com:80/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
stream {
# smtp
server {
listen 25;
proxy_pass interachsh.mysite.com:8025;
}
# dns
server {
listen 53;
proxy_pass interachsh.mysite.com:8053;
}
server {
listen 53 udp;
proxy_pass interachsh.mysite.com:8053;
}
}Configured Domains
$ interactsh-server -d oast.pro,oast.me
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ 1.0.5
projectdiscovery.io
[INF] Loading existing SSL Certificate for: [*.oast.pro, oast.pro]
[INF] Loading existing SSL Certificate for: [*.oast.me, oast.me]
[INF] Listening with the following services:
[HTTPS] Listening on TCP 46.101.25.250:443
[HTTP] Listening on TCP 46.101.25.250:80
[SMTPS] Listening on TCP 46.101.25.250:587
[LDAP] Listening on TCP 46.101.25.250:389
[SMTP] Listening on TCP 46.101.25.250:25
[DNS] Listening on TCP 46.101.25.250:53
[DNS] Listening on UDP 46.101.25.250:53Custom Server Index
Index page for http server can be customized while running custom interactsh server using -http-index flag.
interactsh-server -d hackwithautomation.com -http-index banner.html{DOMAIN} placeholder is also supported in index file to replace with server domain name.
Static File Hosting
Interactsh http server optionally enables file hosting to help in security testing. This capability can be used with a self-hosted server to serve files for common payloads for XSS, XXE, RCE and other attacks.
To use this feature, -http-directory flag can be used which accepts directory as input and files are served under /s/ directory.
interactsh-server -d hackwithautomation.com -http-directory ./paylodsClient File Hosting
Where -http-directory hosts operator-supplied files globally, -upload lets a client host files
against its own correlation ID. This is aimed at second-stage out-of-band vulnerabilities โ XXE with an
external DTD, XSLT includes, JNDI staging โ where the target must fetch a payload file before the
callback fires. Each fetch is recorded as an interaction, so the second stage is visible in the client
output.
[!WARNING]
-uploadis intended for self-hosted servers only. Enabling it on a public instance turns it into
anonymous file hosting on a domain with a valid wildcard certificate, which is a magnet for malware
staging, and blocklists act on the registrable domain โ one abusive sample affects every user of that
domain. It is off by default and implies authentication when enabled.
Start a server with uploads enabled:
interactsh-server -d hackwithautomation.com -upload -ftpThen point a client at it with one or more files:
interactsh-client -s https://hackwithautomation.com -t <token> -file evil.dtd[INF] Listing 1 payload for OOB Testing
[INF] c6rj61aciaeutn2ae680cndmnioyyyyyn.hackwithautomation.com
[INF] Hosting 1 file(s) for OOB Testing
[INF] https://c6rj61aciaeutn2ae680xk4tqy8pqhwmi.hackwithautomation.com/f/evil.dtd
[INF] ftp://c6rj61aciaeutn2ae680xk4tqy8pqhwmi.hackwithautomation.com/.interactsh-user-uploads/c6rj61aciaeutn2ae680/evil.dtdFiles are served over HTTP(S), and over FTP(S) as well when -ftp is enabled. Responses are alwaysContent-Type: application/octet-stream with Content-Disposition: attachment, so the server never
renders client-supplied HTML or SVG on its own domain; DTD, XSLT and JNDI consumers ignore content type,
so this costs nothing for the intended use.
When the target fetches the file, the fetch arrives in the client like any other interaction โ which is
the point: it is the evidence that the first stage of the payload actually executed. The response body
is replaced by a digest so a large payload is not copied back into the interaction stream on every
fetch:
[c6rj61aciaeutn2ae680xk4tqy8pqhwmi] Received HTTP interaction from 203.0.113.7 at 2026-08-05 15:47:19
------------
HTTP Request
------------
GET /f/evil.dtd HTTP/1.1
Host: c6rj61aciaeutn2ae680xk4tqy8pqhwmi.hackwithautomation.com
Accept: */*
User-Agent: curl/8.18.0
-------------
HTTP Response
-------------
HTTP/1.1 200 OK
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="evil.dtd"
Content-Length: 144
[body elided: 144 of 144 bytes of uploaded file "evil.dtd", sha256 0c1b960b076cdff8666f1f302dddd8f3ff0e6ed4b6c09002fbe6d1cdbb5d68f8]The two counts are "delivered of hosted": a conditional fetch answered 304 records 0 of 144, and a
ranged one records the bytes the range actually carried, so the record cannot claim a delivery that did
not happen.
Whatever second-stage callback the payload then triggers arrives as a further interaction on the same
correlation ID, so both stages land in one client.
A client asked to host files against a server that was not started with -upload says so and stops,
rather than silently continuing without the payload:
$ interactsh-client -s https://hackwithautomation.com -t <token> -file evil.dtd
[FTL] Server https://hackwithautomation.com does not accept file uploads; it must be started with -uploadThe failing server is named because the client registers with only one of the servers in -s. When
several are listed, it also says how the choice was made, since the outcome can differ between runs:
$ interactsh-client -s https://a.example,https://b.example -t <token> -file evil.dtd
[FTL] Server https://a.example does not accept file uploads; it must be started with -upload (chosen at random from the 2 servers in -s, so this may differ between runs; pass a single server with -file)Server-side options:
| Flag | Default | Description |
|---|---|---|
-upload |
off | enable client file upload and hosting |
-ud, -upload-directory |
temporary dir | directory to host uploaded files from; interactsh owns .interactsh-user-uploads inside it |
-umfs, -upload-max-file-size |
1mb |
maximum size of a single file |
-umf, -upload-max-files |
5 |
maximum files per session |
-umts, -upload-max-total-size |
1gb |
maximum total bytes across all sessions |
-ut, -upload-ttl |
24h |
maximum lifetime of uploaded files |
Files are removed when the client deregisters, when its session leaves the cache, and in any case once-upload-ttl has elapsed since the last upload for that session.
Things worth knowing before enabling it:
Hosted files are readable by anyone who learns the correlation ID. That ID is deliberately leaked
to the target โ it appears in every DNS query the target's resolver makes, and so in its DNS logs, its
WAF, and passive-DNS aggregators. A target can fetch your payload to fingerprint your tooling, and
that fetch will appear in your interaction stream. Do not upload anything you would mind a target
reading.Uploads are authenticated with the session's correlation ID and secret key, so only the client that
owns a session can attach files to it.The client uploads to the one server it registered with. If
-slists several, files are hosted
only on the elected one; its payload URLs are the ones printed. Pass a single server with-file:
the client picks one at random from-sand cannot take upload support into account, since it only
learns that after registering โ so a list mixing upload and non-upload servers fails at random.-uploadcannot be combined with-redis-url. Hosted bytes are written to a single instance's local
filesystem, so with a storage backend shared between instances the other instances would advertise
files they do not have. The server refuses to start on that combination:console$ interactsh-server -d hackwithautomation.com -upload -redis-url redis://127.0.0.1:6379/0 [FTL] -upload cannot be used with -redis-url: hosted files are stored on a single instance's local filesystemUploads refuse to travel over plaintext HTTP to a remote server, since the request carries both the
file and the session secret key. Use anhttps://server URL.The default upload directory is a temporary directory, which on many Linux distributions is
memory-backed. Set-upload-directoryexplicitly on a real deployment.Interactsh creates and prunes one directory inside the upload root. Hosted files are laid out as
<root>/.interactsh-user-uploads/<correlation-id>/<filename>, and everything under.interactsh-user-uploadsis deleted when its session ends, when-upload-ttlexpires it, and at
startup โ upload metadata lives only in memory, so nothing there survives a restart. The rest of the
root is never touched, which is what makes it safe to point-upload-directoryat a directory you
already use, or to share it with-ftp-dir.With
-ftpand no-ftp-dir, the FTP root is set to the upload root so that hosted files are
reachable over FTP with no extra configuration. If you set both flags they must name the same
directory, otherwise FTP cannot see the uploads: the server reports the mismatch at startup and stops
offeringftp://URLs to clients, so hosting degrades to HTTP only rather than handing out FTP URLs
that resolve to nothing. The uploads directory is hidden from FTP listings โLIST /shows your own content but
not.interactsh-user-uploads, and that directory refuses to list its own contents, so an anonymous
client cannot enumerate the correlation IDs that currently have hosted files.RETRof a known path
works, which is what the payload URL relies on.
Dynamic HTTP Response
Interactsh http server optionally enables responding with dynamic HTTP response by using query parameters. This feature can be enabled by using -dr or -dynamic-resp flag.
The following query parameter names are supported - body, header, status and delay. Multiple header parameters can be specified to set multiple headers.
- body (response body)
- header (response header)
- status (response status code)
- delay (response time)
$ curl -i 'https://hackwithautomation.com/x?status=307&body=this+is+example+body&delay=1&header=header1:value1&header=header1:value12'
HTTP/2 307
header1: value1
header1: value12
server: hackwithautomation.com
x-interactsh-version: 1.0.7
content-type: text/plain; charset=utf-8
content-length: 20
date: Tue, 13 Sep 2022 12:31:05 GMT
this is example bodyNote:
- Dynamic HTTP Response feature is disabled as default.
- By design, this feature lets anyone run client-side code / redirects using your interactsh domain / server
- Using this option with an isolated domain is recommended to avoid security impact on associated root/subdomains.
Wildcard Interaction
To enable wildcard interaction for configured Interactsh domain wildcard flag can be used with implicit authentication protection via the auth flag if the token flag is omitted.
$ interactsh-server -domain hackwithautomation.com -wildcard
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.0
projectdiscovery.io
[INF] Client Token: 699c55544ce1604c63edb769e51190acaad1f239589a35671ccabd664385cfc7
[INF] Listening with the following services:
[HTTPS] Listening on TCP 157.230.223.165:443
[HTTP] Listening on TCP 157.230.223.165:80
[SMTPS] Listening on TCP 157.230.223.165:587
[LDAP] Listening on TCP 157.230.223.165:389
[SMTP] Listening on TCP 157.230.223.165:25
[DNS] Listening on TCP 157.230.223.165:53
[DNS] Listening on UDP 157.230.223.165:53In wildcard mode, each connected client independently receives all interactions for the shared domain. The server keeps a buffer of recent interactions so that multiple clients can poll without missing data. By default, the buffer holds up to 10,000 interactions per shared key. This can be adjusted via the INTERACTSH_MAX_SHARED_INTERACTIONS environment variable:
$ export INTERACTSH_MAX_SHARED_INTERACTIONS=50000
$ interactsh-server -domain hackwithautomation.com -wildcardLDAP Interaction
As default, Interactsh server support LDAP interaction for the payload included in search query, additionally ldap flag can be used for complete logging.
$ interactsh-server -domain hackwithautomation.com -sa -ldap
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.0
projectdiscovery.io
[INF] Client Token: deb58fc151e6f0e53d448be3eb14cd7a11590d8950d142b9cd1abac3c2e3e7bc
[INF] Listening with the following services:
[DNS] Listening on UDP 157.230.223.165:53
[LDAP] Listening on TCP 157.230.223.165:389
[HTTP] Listening on TCP 157.230.223.165:80
[SMTP] Listening on TCP 157.230.223.165:25
[DNS] Listening on TCP 157.230.223.165:53Custom Payload Length
The length of the interactsh payload is 33 by default, consisting of 20 (unique correlation-id) + 13 (nonce token), which can be customized using the cidl and cidn flags to make shorter when required with self-hosted interacsh server.
$ interactsh-server -d hackwithautomation.com -cidl 4 -cidn 6
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.2
projectdiscovery.io
[INF] Loading existing SSL Certificate for: [*.hackwithautomation.com, hackwithautomation.com]
[INF] Listening with the following services:
[HTTPS] Listening on TCP 157.230.223.165:443
[SMTPS] Listening on TCP 157.230.223.165:587
[DNS] Listening on UDP 157.230.223.165:53
[HTTP] Listening on TCP 157.230.223.165:80
[LDAP] Listening on TCP 157.230.223.165:389
[SMTP] Listening on TCP 157.230.223.165:25
[DNS] Listening on TCP 157.230.223.165:53Note: It is important and required to use same length on both side (client and server), otherwise co-relation will not work.
$ interactsh-client -s hackwithautomation.com -cidl 4 -cidn 6
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.2
projectdiscovery.io
[INF] Listing 1 payload for OOB Testing
[INF] c8rf4e8xm4.hackwithautomation.comCustom SSL Certificate
The certmagic library is used by default by interactsh server to produce wildcard certificates for requested domain in an automatic way. To use your own SSL certificate with self-hosted interactsh server, cert and privkey flag can be used to provider required certificate files.
Note: To utilize all of the functionality of the SSL protocol, a wildcard certificate is mandatory.
$ interactsh-server -d hackwithautomation.com -cert hackwithautomation.com.crt -privkey hackwithautomation.com.key
_ __ __ __
(_)___ / /____ _________ ______/ /______/ /_
/ / __ \/ __/ _ \/ ___/ __ '/ ___/ __/ ___/ __ \
/ / / / / /_/ __/ / / /_/ / /__/ /_(__ ) / / /
/_/_/ /_/\__/\___/_/ \__,_/\___/\__/____/_/ /_/ v1.0.2
projectdiscovery.io
[INF] Listening with the following services:
[HTTPS] Listening on TCP 157.230.223.165:443
[SMTP] Listening on TCP 157.230.223.165:25
[HTTP] Listening on TCP 157.230.223.165:80
[LDAP] Listening on TCP 157.230.223.165:389
[DNS] Listening on TCP 157.230.223.165:53
[SMTPS] Listening on TCP 157.230.223.165:587
[DNS] Listening on UDP 157.230.223.165:53Supported Protocols
FTP
FTP support can be enabled with the -ftp flag and is recommended for self-hosted instances only. The FTP agent simulates a fully-functional FTP server agent with authentication that captures authentications with every file operation. By default, the agent listens for clear text FTP on port 21 (this can be changed with the -ftp-port flag) and tls FTP on port 990 (this can be changed with the -ftps-port flag) and lists in read-only mode the content of the OS default temporary directory (customizable with the -ftp-dir option). The ftp engine uses the custom certificate and private key if provided or it will extract the certificate and private key from the first acme domain if provided.
Example of starting the FTP daemon and capturing a login interaction:
$ sudo go run . -ftp -skip-acme -debug -domain localhost
...
[INF] Outbound IP: 192.168.1.16
[INF] Client Token: 6dc07e4a76c3d5e58e4bea13ce073dc403499b128c62397aff7b934a6e4822e3
[INF] Listening with the following services:
[DNS] Listening on TCP 192.168.1.16:53
[SMTP] Listening on TCP 192.168.1.16:25
[HTTP] Listening on TCP 192.168.1.16:80
[FTP] Listening on TCP 192.168.1.16:21
[DNS] Listening on UDP 192.168.1.16:53
[LDAP] Listening on TCP 192.168.1.16:389
[DBG] FTP Interaction:
{"protocol":"ftp","unique-id":"","full-id":"","raw-request":"USER test\ntest logging in","remote-address":"127.0.0.1:51564","timestamp":"2022-09-29T00:49:42.212323+02:00"}External Supported Protocols
SMB
The -smb flag enables an in-process SMB2 NetNTLMv2 hash capture server (only for self-hosted instances). It is implemented in pure Go on top of goimpacket and listens on port 445 unless changed by the -smb-port flag. No Python, impacket or docker dependencies are required.
Captured hashes are stored as smb interactions in the standard hashcat NetNTLMv2 (-m 5600) format:
USER::DOMAIN:serverChallenge:NTProofStr:NTLMv2BlobExample of enabling the samba server:
$ sudo interactsh-server -smb -skip-acme -debug -domain localhostResponder
The -responder flag enables a Responder-equivalent NTLMv2 hash capture server, also backed by goimpacket. It binds the SMB-capable TCP ports (139 and the -smb-port value, default 445) and stores any captured authentication as a responder interaction in the same hashcat NetNTLMv2 format described above. No docker or Python dependencies are required.
sudo interactsh-server -responder -d localhostNote: the legacy LLMNR / NBT-NS / MDNS broadcast poisoners that ship with the Python Responder project are not included. They are LAN-side techniques that are out of scope for an OOB-callback server reachable over the public internet, and they are not part of the goimpacket library.
Interactsh Integration
Use as library
The examples use the interactsh client library to get external interactions for a generated
URL by making an http request to the URL, and to host a file against the same session for second-stage
verification.
File hosting is an optional server capability, so a library consumer negotiates rather than assumes:Capabilities() reports what the server advertised at registration, UploadFiles returnsErrUploadUnsupported when a server cannot host files and ErrUploadNotAdvertised when it predates the
feature, and FileURL/FTPFileURL compose the URLs a target should fetch. The public oast.* servers
do not offer hosting, so the example skips it rather than failing.
Nuclei - OAST
Nuclei vulnerability scanner utilize Interactsh for automated payload generation and detection of out of band based security vulnerabilities.
See Nuclei + Interactsh Integration blog and guide document for more information.
Cloud Metadata
Interactsh server supports DNS records for cloud metadata services, which is useful for testing SSRF-related vulnerabilities.
Currently supported metadata services:
Example:
- aws.oast.fun points to 169.254.169.254
- alibaba.oast.fun points to 100.100.100.200
Acknowledgement
Interactsh is inspired from Burp Collaborator.
License
Interactsh is distributed under MIT License and made with ๐ค by the projectdiscovery team.
File: LICENSE.md
MIT License
Copyright (c) 2021 ProjectDiscovery, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
File: SECURITY.md
Security Policy
Reporting a Vulnerability
DO NOT CREATE AN ISSUE to report a security problem. Instead, please send an email to [email protected], and we will acknowledge it within 3 working days.
File: .golangci.yml
version: "2"
linters:
default: standard
File: .goreleaser.yml
version: 2
before:
hooks:
- go mod tidy
builds:
main: cmd/interactsh-client/main.go
binary: interactsh-client
id: interactsh-client
env:- CGO_ENABLED=0
goos: [windows, linux, darwin]
goarch: [amd64, '386', arm, arm64]
ignore: - goos: darwin
goarch: '386' - goos: windows
goarch: arm - goos: windows
goarch: arm64
- CGO_ENABLED=0
main: cmd/interactsh-server/main.go
binary: interactsh-server
id: interactsh-server
env:- CGO_ENABLED=0
goos: [windows, linux, darwin]
goarch: [amd64, '386', arm, arm64]
ignore: - goos: darwin
goarch: '386' - goos: windows
goarch: arm - goos: windows
goarch: arm64
- CGO_ENABLED=0
archives:
formats: [zip]
id: client
ids: [interactsh-client]
name_template: '{{ .Binary }}{{ .Version }}{{ if eq .Os "darwin" }}macOS{{ else }}{{ .Os }}{{ end }}_{{ .Arch }}'formats: [zip]
id: server
ids: [interactsh-server]
name_template: '{{ .Binary }}{{ .Version }}{{ if eq .Os "darwin" }}macOS{{ else }}{{ .Os }}{{ end }}_{{ .Arch }}'
checksum:
algorithm: sha256
announce:
slack:
enabled: true
channel: '#release'
username: GoReleaser
message_template: 'New Release: {{ .ProjectName }} {{.Tag}} is published! Check it out at {{ .ReleaseURL }}'
discord:
enabled: true
message_template: 'New Release: {{ .ProjectName }} {{.Tag}} is published! Check it out at {{ .ReleaseURL }}'
File: cmd/interactsh-server/example-custom-records.yaml
This is a reference custom DNS records file
Custom DNS records can be specified in two formats:
1. Standard format (supports multiple record types):
subdomain:
- type: RECORD_TYPE
value: "record_value"
ttl: 3600 # optional, defaults to server TTL
priority: 10 # optional, for MX records only
2. LEGACY FORMAT (Simple key-value, assumes A records):
subdomain: "ip_address"
Supported record types: A, AAAA, CNAME, MX, TXT, NS
============================================
STANDARD FORMAT EXAMPLES
============================================
A record example
api:
- type: A
value: "192.0.2.1"
ttl: 3600
Multiple A records for the same subdomain
webserver:
- type: A
value: "203.0.113.10" - type: A
value: "203.0.113.11"
AAAA record (IPv6)
ipv6:
- type: AAAA
value: "2001:db8::1"
CNAME record
cdn:
- type: CNAME
value: "example.cdn.net"
MX record (mail server)
mail:
- type: MX
value: "mail.example.com"
priority: 10
ttl: 7200
Multiple MX records with different priorities
mailserver:
- type: MX
value: "mail1.example.com"
priority: 10 - type: MX
value: "mail2.example.com"
priority: 20
TXT record (useful for SPF, DKIM, verification, etc.)
spf:
- type: TXT
value: "v=spf1 include:_spf.example.com ~all"
Multi-level subdomain example (DKIM key)
something._domainkey:
- type: TXT
value: "v=DKIM1; k=rsa; p=MIGfMA0GCS..."
NS record (nameserver)
custom-ns:
- type: NS
value: "ns1.example.com" - type: NS
value: "ns2.example.com"
Mixed record types for the same subdomain
multi:
- type: A
value: "198.51.100.1" - type: AAAA
value: "2001:db8::2" - type: TXT
value: "v=spf1 mx ~all"
============================================
LEGACY FORMAT EXAMPLES (backwards compatible)
============================================
These simple entries will be interpreted as A records
aws: "169.254.169.254"
alibaba: "100.100.100.200"
localhost: "127.0.0.1"
oracle: "192.0.0.192"
File: deploy/README.md
Prerequisites
- Install [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/
installation_distros.html) on your local machine- eg: On ubuntu
sudo apt install ansible-core - eg: On mac
brew install ansible
- eg: On ubuntu
- Install resolvelib
sudo -H pip install -Iv 'resolvelib<0.6.0' - Install ansible docker module
ansible-galaxy collection install community.docker
Using deploy.yaml
- This Playbook is responsible for deploying the application to a remote server.
- It will do the following things
- Install required system packages
- Install docker
- Start the interactsh container
Deploy
- Open deploy.yaml and change the parameters in the
varssection to match your environment/requirments. - Run
ansible-playbook deploy.yamlto deploy the application. - You can also run
ansible-playbook deploy.yaml --extra-vars "container_tag=v1.1.2"to pass the variables from the command line.
eg:bashansible-playbook deploy.yaml --extra-vars "container_tag=v1.1.2"
Add Grafana agent
- To add grafana agent to collect node metrics and logs on you project
Open grafan_agent.yaml update the variables as per your project and run following commandtextexport GRAFANA_CLOUD=**** export PROM_URL=**** export PROM_PASS==**** export PROM_USERNAME==**** ansible-playbook grafana_agent.yaml
File: deploy/deploy.yaml
- hosts: all
become: true
vars:
container_name: "interactsh"
container_tag: "v1.1.5"
container_image: "projectdiscovery/interactsh-server:{{container_tag}}"
container_command: "-dr -d {{domain_name}} -metrics"
certmagic_host_path: "/root/.local/share/certmagic"
tasks:name: Install aptitude
apt:
name: aptitude
state: latest
update_cache: true
tags:- apt
- setup
name: Install required system packages
apt:
pkg:- apt-transport-https
- ca-certificates
- curl
- software-properties-common
- python3-pip
- virtualenv
- python3-setuptools
- lsb-release
- gnupg
state: latest
update_cache: true
tags: - apt
- setup
name: Add Docker GPG apt Key
apt_key:
url: https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg
state: present
tags:- docker
- setup
name: Add Docker Repository
apt_repository:
repo: deb https://download.docker.com/linux/{{ ansible_distribution | lower }} {{ ansible_distribution_release }} stable
state: present
tags:- docker
- setup
name: Update apt and install docker-ce
apt:
name: docker-ce
state: latest
update_cache: true
tags:- docker
- setup
name: Install Docker Module for Python
pip:
name: docker
tags:- docker
- setup
name: Make sure certmagic directory is created
file:
path: "{{ item }}"
state: directory
loop:- "{{ certmagic_host_path }}"
tags: dir
- "{{ certmagic_host_path }}"
name: Pull Docker image
community.docker.docker_image:
name: "{{ container_image }}"
source: pull
tags:- deploy
- pull
name: Launch interactsh docker container
community.docker.docker_container:
name: "{{ container_name }}"
image: "{{ container_image }}"
command: "{{ container_command }}"
memory: "4g"
memory_swap: "-1"
network_mode: host
restart: true # always restart the container
restart_policy: "unless-stopped"
volumes:- "{{certmagic_host_path}}:{{certmagic_host_path}}"
state: started
tags: - deploy
- test
- "{{certmagic_host_path}}:{{certmagic_host_path}}"
File: deploy/grafana_agent.yaml
- hosts: all
become: true
vars:
env_name: "oast"
container_name: "interactsh"
grafana_agent_image: "grafana/agent:latest"
grafana_cloud_url: "{{ lookup('env', 'GRAFANA_CLOUD') }}"
prometheus_cloud_url: "{{ lookup('env', 'PROM_URL') }}"
prometheus_cloud_password: "{{ lookup('env', 'PROM_PASS') }}"
prometheus_cloud_username: "{{ lookup('env', 'PROM_USERNAME') }}"
tasks:name: create grafana directory for config
file:
path: "{{ item }}"
state: directory
loop:- /etc/grafana/
tags: dir
- /etc/grafana/
name: copy grafana agent config file
template:
src: agent.yaml.j2
dest: "/etc/grafana/agent.yaml"
tags: agentname: pull Docker image of grafana agent
community.docker.docker_image:
name: "{{ grafana_agent_image }}"
source: pull
tags: agentname: create Grafana agent container
community.docker.docker_container:
name: grafana_agent
image: "{{ grafana_agent_image }}"
restart_policy: always
restart: true
state: started
volumes:
- "/etc/grafana/agent.yaml:/etc/agent-config/agent.yaml:ro"
- "/proc:/host/proc:ro"
- "/tmp/agent:/etc/agent"
- "/var/lib/docker/:/var/lib/docker:ro"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
- "/run/containerd/containerd.sock:/run/containerd/containerd.sock:ro"
- "/var/lib/docker/containers:/var/lib/docker/containers:ro"
- "/:/rootfs:ro"
- "/var/run:/var/run:ro"
- "/sys:/sys:ro"
devices:
- "/dev/kmsg:/dev/kmsg"
privileged: true
entrypoint:
- "/bin/agent"
- "-config.file=/etc/agent-config/agent.yaml"
- "-metrics.wal-directory=/tmp/agent/wal"
- "-server.register-instrumentation=false"
network_mode: "host"
pid_mode: "host"
File: deploy/inventory.yaml
interactsh:
hosts:
oast.site:
ansible_host: 178.128.16.97
ansible_user: root
domain_name: "oast.site"
oast.pro:
ansible_host: 178.128.212.209
ansible_user: root
domain_name: "oast.pro"
oast.live:
ansible_host: 178.128.210.172
ansible_user: root
domain_name: "oast.live"
oast.fun:
ansible_host: 206.189.156.69
ansible_user: root
domain_name: "oast.fun"
oast.online:
ansible_host: 167.99.69.236
ansible_user: root
domain_name: "oast.online"
oast.me:
ansible_host: 178.128.209.14
ansible_user: root
domain_name: "oast.me"File: deploy/redis-test/docker-compose.yml
name: interactsh-redis-test
Two interactsh-server instances pointing at the same Redis to exercise
the multi-instance scenario from issue #1267. Both run with --skip-acme
(TLS disabled) and authentication so the test harness can register/poll
without dragging in real DNS or ACME.
services:
redis:
image: redis:7-alpine
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 1s
timeout: 2s
retries: 10
ish-a:
build:
context: ../..
dockerfile: deploy/redis-test/Dockerfile
command:
- "-d=oast.local"
- "-i=127.0.0.1"
- "-sa"
- "-ru=redis://redis:6379"
- "-rp=ishtest:"
- "-dns-port=5353"
- "-smtp-port=2525"
- "-smtp-autotls-port=2526"
- "-smtps-port=2527"
- "-ldap-port=3389"
- "-ftp-port=2121"
- "-ftps-port=2122"
- "-smb-port=4445"
- "-a"
- "-t=testtoken-7e2c"
ports:
- "8080:80"
depends_on:
redis:
condition: service_healthy
ish-b:
build:
context: ../..
dockerfile: deploy/redis-test/Dockerfile
command:
- "-d=oast.local"
- "-i=127.0.0.1"
- "-sa"
- "-ru=redis://redis:6379"
- "-rp=ishtest:"
- "-dns-port=5353"
- "-smtp-port=2525"
- "-smtp-autotls-port=2526"
- "-smtps-port=2527"
- "-ldap-port=3389"
- "-ftp-port=2121"
- "-ftps-port=2122"
- "-smb-port=4445"
- "-a"
- "-t=testtoken-7e2c"
ports:
- "8081:80"
depends_on:
redis:
condition: service_healthy
File: .github/dependabot.yml
To get started with Dependabot version updates, you'll need to specify which
package ecosystems to update and where the package manifests are located.
Please see the documentation for all configuration options:
https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
Maintain dependencies for go modules
- package-ecosystem: "gomod"
directory: "/"
schedule:
interval: "weekly"
target-branch: "dev"
commit-message:
prefix: "chore"
include: "scope"
labels:- "Type: Maintenance"
allow: - dependency-name: "github.com/projectdiscovery/*"
- "Type: Maintenance"
# Maintain dependencies for docker
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
target-branch: "dev"
commit-message:
prefix: "chore"
include: "scope"
labels:
- "Type: Maintenance"
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
target-branch: "dev"
commit-message:
prefix: "chore"
include: "scope"
labels:
- "Type: Maintenance"
File: .github/release.yml
changelog:
exclude:
authors:
- dependabot
categories:
- title: ๐ New Feature
labels:
- "Type: Enhancement"
- title: ๐ Bug Fixes
labels:
- "Type: Bug"
- title: ๐จ Maintenance
labels:
- "Type: Maintenance"
- title: Other Changes
labels:
- "*"
File: .github/ISSUE_TEMPLATE/config.yml
blank_issues_enabled: false
contact_links:
name: Ask an question / advise on using interactsh
url: https://github.com/projectdiscovery/interactsh/discussions/categories/q-a
about: Ask a question or request support for using interactshname: Share idea / feature to discuss for interactsh
url: https://github.com/projectdiscovery/interactsh/discussions/categories/ideas
about: Share idea / feature to discuss for interactshname: Connect with PD Team (Discord)
url: https://discord.gg/projectdiscovery
about: Connect with PD Team for direct communication
File: .github/ISSUE_TEMPLATE/feature_request.md
name: Feature request
about: Request feature to implement in this project
title: ""
labels: 'Type: Enhancement'
assignees: ''
Please describe your feature request:
Describe the use case of this feature:
File: .github/ISSUE_TEMPLATE/issue-report.md
name: Issue report
about: Create a report to help us to improve the project
labels: 'Type: Bug'
Interactsh version:
Current Behavior:
Expected Behavior:
Steps To Reproduce:
Anything else:
File: .github/workflows/auto-merge.yaml
name: ๐ Auto merge PR
on:
workflow_run:
workflows: ["โพ๏ธ Compatibility Checks"]
types: [completed]
permissions:
contents: write
pull-requests: write
jobs:
auto-merge-dependabot:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: projectdiscovery/actions/pr/approve@v1
- uses: projectdiscovery/actions/pr/merge@v1
with:
auto: "true"
File: .github/workflows/build-test.yml
name: ๐จ Build Test
on:
pull_request:
paths:
- '.go'
- '.mod'
workflow_dispatch:
jobs:
build:
name: Test Builds
if: ${{ !endsWith(github.actor, '[bot]') }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Set up Go
uses: projectdiscovery/actions/setup/go@v1
- name: Build
run: go build ./...
working-directory: .
- name: Test
run: go test ./...
working-directory: .
- name: Race Condition Tests
if: runner.os == 'Linux'
run: go test -race ./...
working-directory: .
- name: Example Code Tests
run: go build .
working-directory: examples/File: .github/workflows/codeql-analysis.yml
name: ๐จ CodeQL Analysis
on:
workflow_dispatch:
pull_request:
branches:
- dev
paths:
- '.go'
- '.mod'
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: go
- name: Autobuild
uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4File: .github/workflows/compat-checks.yaml
name: โพ๏ธ Compatibility Checks
on:
pull_request:
types: [opened, synchronize]
branches:
- dev
jobs:
compat-checks:
if: ${{ github.actor == 'dependabot[bot]' }}
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6
- uses: projectdiscovery/actions/setup/go/compat-checks@v1
with:
go-version: "stable"
release-test: true
File: .github/workflows/dockerhub-client.yml
name: ๐ฅ Docker Client
on:
workflow_run:
workflows: ["๐ Release Binary"]
types:
- completed
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest-16-cores
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Get Github tag
id: meta
run: |
curl --silent "https://api.github.com/repos/projectdiscovery/interactsh/releases/latest" | jq -r .tag_name | xargs -I {} echo TAG={} >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push client
uses: docker/build-push-action@v6
with:
context: .
file: .github/docker/client/Dockerfile
platforms: linux/amd64,linux/arm64,linux/arm
push: true
tags: projectdiscovery/interactsh-client:latest,projectdiscovery/interactsh-client:${{ steps.meta.outputs.TAG }}File: .github/workflows/dockerhub-server.yml
name: ๐ฅ Docker Server
on:
workflow_run:
workflows: ["๐ Release Binary"]
types:
- completed
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest-16-cores
steps:
- name: Checkout
uses: actions/checkout@v6
- name: Get Github tag
id: meta
run: |
curl --silent "https://api.github.com/repos/projectdiscovery/interactsh/releases/latest" | jq -r .tag_name | xargs -I {} echo TAG={} >> $GITHUB_OUTPUT
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push server
uses: docker/build-push-action@v6
with:
context: .
file: .github/docker/server/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
tags: projectdiscovery/interactsh-server:latest,projectdiscovery/interactsh-server:${{ steps.meta.outputs.TAG }}File: .github/workflows/lint-test.yml
name: ๐๐ป Lint Test
on:
pull_request:
paths:
- '.go'
- '.mod'
- '.golangci.yml'
- '.golangci-lint-version'
workflow_dispatch:
jobs:
lint:
name: Lint Test
if: ${{ !endsWith(github.actor, '[bot]') }}
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v7
- name: Set up Go
uses: projectdiscovery/actions/setup/go@v1
- name: Run golangci-lint
uses: projectdiscovery/actions/golangci-lint/v2@v1
with:
args: --timeout 5m
File: .github/workflows/manual-deploy.yml
name: ๐ฅ Manual Deploy
on:
workflow_dispatch:
inputs:
tags:
required: true
type: string
jobs:
build:
name: Ansible Deploy
runs-on: ubuntu-latest
environment: oast
steps:
- uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.9
- name: Install dependencies
run: |
sudo apt install ansible-core
sudo -H pip install -Iv 'resolvelib<0.6.0'
ansible-galaxy collection install community.docker
- name: set ansible config secrets
env:
DO_SSH_KEY: ${{ secrets.DO_SSH_KEY }}
run: |
mkdir ~/.ssh
echo "$DO_SSH_KEY" > ~/.ssh/oast
chmod 600 ~/.ssh/oast
- name: run playbook
env:
ANSIBLE_FORCE_COLOR: '1'
run: |
ansible all -m ping
ansible-playbook deploy.yaml --tags deploy --extra-vars "container_tag=${{ inputs.tags }}"
working-directory: ./deployFile: .github/workflows/release-binary.yml
name: ๐ Release Binary
on:
push:
tags:
- '*'
workflow_dispatch:
jobs:
release:
runs-on: ubuntu-latest-16-cores
steps:
- name: Check out code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go
uses: projectdiscovery/actions/setup/go@v1
- name: Create release on GitHub
uses: projectdiscovery/actions/goreleaser@v1
with:
release: true
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
SLACK_WEBHOOK: "${{ secrets.RELEASE_SLACK_WEBHOOK }}"
DISCORD_WEBHOOK_ID: "${{ secrets.DISCORD_WEBHOOK_ID }}"
DISCORD_WEBHOOK_TOKEN: "${{ secrets.DISCORD_WEBHOOK_TOKEN }}"File: .github/workflows/release-test.yml
name: ๐จ Release Test
on:
pull_request:
paths:
- '.go'
- '.mod'
- '**.yml'
workflow_dispatch:
jobs:
release-test:
runs-on: ubuntu-latest-16-cores
steps:
- name: Check out code
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go
uses: projectdiscovery/actions/setup/go@v1
- name: Release test
uses: projectdiscovery/actions/goreleaser@v1File: .github/workflows/stale.yml
name: ๐ค Stale
on:
schedule:
- cron: '0 0 * * 0' # Weekly
jobs:
stale:
runs-on: ubuntu-latest
permissions:
actions: write
contents: write # only for delete-branch option
issues: write
pull-requests: write
steps:
- uses: actions/stale@v10
with:
days-before-stale: 90
days-before-close: 7
stale-issue-label: "Status: Stale"
stale-pr-label: "Status: Stale"
stale-issue-message: >
This issue has been automatically marked as stale because it has not
had recent activity. It will be closed in 7 days if no further
activity occurs. Thank you for your contributions!
stale-pr-message: >
This pull request has been automatically marked as stale due to
inactivity. It will be closed in 7 days if no further activity
occurs. Please update if you wish to keep it open.
close-issue-message: >
This issue has been automatically closed due to inactivity. If you
think this is a mistake or would like to continue the discussion,
please comment or feel free to reopen it.
close-pr-message: >
This pull request has been automatically closed due to inactivity.
If you think this is a mistake or would like to continue working on
it, please comment or feel free to reopen it.
close-issue-label: "Status: Abandoned"
close-pr-label: "Status: Abandoned"
exempt-issue-labels: "Status: Abandoned"
exempt-pr-labels: "Status: Abandoned"