Modules: For a comprehensive overview of Ax scan modules, see Modules
ax scan is an amalgamation of the various Ax scripts (~/.axiom/interact) and operations. Its designed to provide an easy way to distribute any binary or script. The only requirements are:
The tool you wish to distribute needs to be installed on the remote instances.
On the ax controller, use one of our preexisting modules or create your own. The module specifies the command to execute on the remote instances in parallel (must be a valid JSON file in ~/.axiom/modules)
When creating custom modules, make sure to add the appropriate extension to the module's ext key:value pair. This tells ax scan how to download and merge the results.
Spin-up some instances beforehand using ax fleet and make sure they are selected (ax select '\*')
Optionally use ax scan ... --spinup $N argument to specify how many instance to spin up at runtime.
Finally, execute the appropriate ax scan command, specifying the input file to distribute and the module you want to execute across the fleet ax scan my-targets.txt -m ffuf
Source Code: ax scan is written in bash making it very easy to review. For a detailed step-by-step walk-though of how ax scan works under the hood, its highly recommended to read the comments in the source code!
With ax scan, every instance executes the same command, specified in the module. Ax scan splits the user-provided target list (e.g., a list of IPs) into equal parts per instance. For example, if you have a target list of 10 IPs and 5 instances selected, the target list is divided into 5 equal parts (2 targets per instance). Each target list is uploaded to the appropriate instance using axiom-scp.
To prepare the instances before the actual scan is executed, ax scan creates a unique folder on all remote instances to store the data needed for that particular scan invocation (/home/op/scan/$module+timestamp).
A unique tmux session is created on each remote instance to handle the execution. If you ax ssh into the instance, you can attach to the tmux session (tmux a -t $module+$timestamp) in real-time (results are also automatically streamed from each remote instance and returned to the terminal).
Locally, ax scan creates a separate local scan working directory for each scan invocation, located ~/.axiom/tmp/$module+timestamp. Optional user provided command-line arguments are passed to the module (extra args) and are combined with the commands in the module. The final command is stored in a local file and then uploaded to every instance participating in the scan. Some of the data stored in the local scan working directory includes the command to run on the instances, the path of the temporary ssh sockets used for the scan, the axiom sshconfig, the input file, the results and the status of each scanner, located ~/.axiom/tmp/$module+timestamp.
Some logging operations are executed on the remote instances to redirect stdout and stderr to a file in the instances remote scan working directory. These files are collectively tailed across each instance and streamed to the ax contoller's terminal in real-time.
When any particular instance is finished with its portion of the total scan, ax creates a $(hostname) file in the instance's remote scanning working directory. During the scan, Ax checks for each $(hostname) file to know that part of the scan has completed. Once all instances have created their $(hostname), or if Ax can no longer communicate to ALL of instances in the selected fleet or if --max-runtime is exceeded, the scan is considered complete and merging starts.
Scan results are downloaded periodically during the scan and once again after the scan completes, just in case.
axiom-scan provides easy distribution of arbitrary binaries and scripts.
axiom-scan optionally splits user-provided input files (target lists), and wordlists and uploads them to a unique scan working directory on the remote instance.
axiom-scan combines user-provided command-line arguments with commands in the module (~/.axiom/modules) and executes the final command on the remote instance.
axiom-scan downloads and merges scan output in a variety of different formats, specified by the extension in the module (dir, txt, oG, csv, xml, jsonl, none).
individual scanning operations are executed from a detacted tmux session ($module+$timestamp) inside a unique scan working directory (/home/op/scan/$module+$timestamp) on the remote instances.
Usage:
axiom-scan inputfile.txt -m ffuf -w /home/op/wordlist-on-remote-instance
axiom-scan inputfile.txt -m ffuf -wL /home/localuser/local-wordlist-to-upload
axiom-scan inputfile.txt -m ffuf -wD /home/localuser/local-wordlist-to-split-and-upload
axiom-scan inputfile.txt -m nuclei --remote-folder /home/op/nuclei-templates-on-remote-instances -o outputfile.txt
axiom-scan inputfile.txt -m nuclei --local-folder /home/localuser/local-custom-nuclei-template-folder-to-upload/ -o outputfile.txt
axiom-scan inputfile.txt -m nuclei --local-config /home/localuser/local-custom-nuclei-config-file-to-upload.yaml -o outputfile.txt --anew
axiom-scan inputfile.txt -m gowitness -oD screenshots-folder --spinup 10
axiom-scan inputfile.txt -m nmapx -p- -sV -T4 -v --open -oA nampx-scan --spinup 100 --rm-when-done --regions dal13,lon06,fra05,sjc04
Flags:
INPUT:
string[] required positional first argument must always be an input file, this can be a list of URLs, IPs, hostnames, etc
--dont-shuffle do not randomize input file before uploading (default is to randomize)
--dont-split do not split input file, upload entire input file to every instance (default is to split the input file)
--expand-cidr automatically expand any subnet in the input file (default does not expand subnets)
MODULE:
-m string[] the axiom-scan module to use with the scan (must be a JSON file in ~/.axiom/modules)
--list print all available modules located in ~/.axiom/modules
WORDLIST:
-w string[] replace _wordlist_ in module with user-provided wordlist (must be a path to a remote wordlist)
-wD,--distribute-wordlist string[] replace _wordlist_ in module with user-provided local wordlist to split and upload (default does not split the wordlist)
-wL,--local-wordlist string[] replace _wordlist_ in module with user-provided local wordlist (must be a path to a local wordlist)
FOLDER:
--remote-folder string[] replace _folder_ in module with user-provided remote folder (must be a path to a remote folder)
--local-folder string[] replace _folder_ in module with user-provided local folder to upload (must be a path to a local folder)
CONFIGURATIONS:
--remote-config string[] replace _config_ in module with user-provided configuration file (must be a configuration file on the remote instances)
--local-config string[] replace _config_ in module with user-provided local configuration file to upload (must be a local configuration file)
ONE-SHOT:
--disable-oneshot by default, if a module contains the string _target_ or _safe-target_ it is executed as a one-shot module. Use this flag to force disable
--unsafe for one-shot modules only, axiom will transparently replace _target_ with _safe-target_ in modules at runtime, use this flag to force disable
--track-finished for one-shot modules only, add this flag to track finished targets (creates a file in the remote scan working directory named finished.txt)
--threads int[] specify the number of threads to use with one-shot modules (default uses "threads": $N key:value pair in the module)"
OPTIMIZATIONS:
--upload string[] before the scan, upload a file to the unique scan working directory (/home/op/scan/$module+$timestamp) on remote instances (must be a path to a local file)
--download string[] after the scan, download a file from the unique scan working directory (/home/op/scan/$module+$timestamp) on remote instances (must be a path to a remote file)
--max-runtime DURATION[] kill scan if still running after DURATION, DURATION is a floating point number with an required suffix: 'm' for minutes, 'h' for hours or 'd' for days
--preflight-timeout int[] specifies the timeout (in seconds) used when connecting to the SSH server, instead of using the default 15 seconds
--skip-preflight do not automatically remove instances that can not be reached (default removes instances from the queue that can not be reached)
--anew pipe the output to anew before creating the final output file (also requires extension "ext":"txt", "ext":"oG" or "ext":"csv" to be in the module)
OUTPUT:
-o string[] output as default (the first ext mentioned in the module)
-oT/-txt string[] output as text (must also be supplied in the module using "ext":"txt")
-oD/-oA string[] output as directory (must also be supplied in the module using "ext":"dir" or "ext":"")
-oG string[] output as greppable, merge and sort unique (must also be supplied in the module using "ext":"oG")
-oJ string[] output as json lines, newline characters are used to delimit JSON data (must also be supplied in the module using "ext":"jsonl")
-oX string[] output as XML/HTML (supported for nmap and masscan)(must also be supplied in the module using "ext":"xml")
-csv string [] output as csv, extract csv header, merge and sort unique (must also be supplied in the module using "ext":"csv")
-none string [] do not attempt to merge the output at all (must also be supplied in the module using "ext":"none")
--quiet do not display findings to terminal
--rm-logs delete remote and local logs after scan completes, except for the unmered output files in ~/.axiom/logs/$module+$timestamp/output
--no-logs do not store any logs at all, do not tail terminal output. Delete all logs even the unmerged output files in ~/.axiom/logs/$module+$timestamp/output
--stdout only display stdout results to terminal (default displays stdout and stderr to the terminal)
FLEET:
--custom-ssh string[] path to custom SSH config file (default is located at ~/.axiom/.sshconfig)
--cache do not regenerate SSH config prior to scan, instead use cached config (located at ~/.axiom/.sshconfig)
--fleet string[] supply fleet prefix to use (default uses instances in ~/.axiom/selected.conf)
--regions string[] round-robin region distribution using comma-separated regions to cycle through (default is region in ~/.axiom/axiom.json)
--rm-when-done delete the instance when finished with its job (does not wait for all instances to complete)
--shutdown-when-done shutdown the instance when finished with its job (does not wait for all instances to complete)
--spinup int[] number of instances to spin up prior to scanning (default uses instances in ~/.axiom/selected.conf)
DEBUG:
--debug run with set -xv, warning: very verbose (use with --cache for less output)
EXTRA ARGS:
string[] supply additional arguments to be passed to the module
--extra-args string[] explicitly define extra args to be passed to the module, must be wrapped single or double quotes (depending on intended variable expansion)
axiom-select'fleet*'# fleets should be already selected, but just in case, select can be a good idea# Formataxiom-scan<input>-m<module>-o<textoutfile><anyotherargs># Examplesaxiom-scanroots.txt-msubfinder-osubfinder.txt# run subfinder against all rootsaxiom-scansubfinder.txt-mdnsx-odnsx.txt# run dnsx against all subfinder resultsaxiom-scandnsx.txt-mhttpx-ohttpx.txt# run httpx against all dnsx resultsaxiom-scanhttpx.txt-mgowitness-oscreenshots-directory# run gowitness against all httpx resultsaxiom-scanhttpx.txt-mnuclei-onuclei.txt# run nuclei against all httpx resultsaxiom-scanhttpx.txt-mffuf-offuf.txt# run ffuf against all httpx resultsaxiom-scanips.txt-mnmap-oGportscan.txt# run nmap, output as greppable axiom-scanips.txt-mnmap-oXportscan# Output and merge XMLs (this also creates an HTLM report)axiom-scanips.txt-mnmap-p--sV-T4-v--open-oAnampx-scan--spinup10# run nmap, pass extra_args to nmap binary, output to a directory containing text, XML and Greppable results, spin up 10 instancesaxiom-scanips.txt-mmasscan-oGmasscan.txt# Run masscan, output as greppable