📎Merging and Module Extensions

The ax scan tool supports downloading and merging scan outputs in various formats, determined by the extension specified in the module (e.g., txt, oG, xml, dir, none, csv, and, jsonl) and the output argument passed to ax scan at runtime. The specified extension guides how ax scan will merge the results. Let's consider the nmap module as an example:

[
  {
    "command": "sudo nmap -iL input -oN output",
    "ext": "txt"
  },
  {
    "command": "sudo nmap -iL input -oG output",
    "ext": "oG"
  },
  {
    "command": "sudo nmap -iL input -oX output",
    "ext": "xml"
  },
  {
    "command": "sudo nmap -iL input -oA output/output",
    "ext": "dir"
  },
  {
    "command": "mkdir output ; sudo nmap -iL input -oA output/output",
    "ext": "none"
  }
]

The "default" extension is always the first one mentioned in the module. In this case, the default is "txt" since "ext": "txt" is the first listed.

If no output argument is specified, ax scan uses the first command and extension in the JSON object and assigns a unique name for the output file.

ax scan input -m nmap --quiet && cat /home/user/scan+1722134430

If you add the output argument -o, you can specify your own output filename. However, even when using -o, ax scan will still use the first JSON object in the module by default.

ax scan input -m nmap --quiet -o my-custom-filename.txt

txt

But what if "ext": "txt" wasn't the first JSON object in the module, but you still wanted to use it? You could explicitly tell ax scan to use the JSON object with "ext": "txt" (and corresponding module command) by specifying the appropriate output argument in the ax scan command at runtime. For text, you can use either -oT or -txt as the ax scan output argument.

ax scan input -m nmap --quiet -oT my-explicit-text-output.txt
[
  {
    "command": "sudo nmap -iL input -oN output",
    "ext": "txt"
  },
..snip..

oG (grepable)

Outputting as grepable is very similar to "ext": "txt", the only difference is that "ext": "oG" sorts unique (sort -u).

To use any JSON object in the module along with the corresponding command and extension, specify the correct output argument in the ax scan command. For example, to output in grepable format with "ext": "oG", use -oG in the ax scan command at runtime. Here's how to do it:

For example:

ax scan input -m nmap --quiet -oG my-grepable-output.txt

The above ax scan command will use the corresponding JSON object's command and extension in the module, which in this case is:

 ..snip..
 {
    "command": "sudo nmap -iL input -oG output",
    "ext": "oG"
 },
 ..snip..

The "command":.." key in the JSON key:value pair must output to the appropriate file type ("command":" ...-oG output"). The extension must also be specified in the object's "ext" value (in this case "ext": "oG"). Finally, the ax scan command needs to include the appropriate output argument so it knows which extension (and command) to use:

ax scan input -m nmap --quiet -oG my-grepable-output.txt

xml

Outputting as xml is supported for only nmap and masscan at the moment, and uses nMap_Merger.py to merge xmls.

For XML output with "ext": "xml", use the output argument -oX in the ax scan command

..snip..
   {
    "command": "sudo nmap -iL input -oX output",
    "ext": "xml"
  },
..snip..
ax scan input -m nmap --quiet -oX my-xml-output.xml

dir

The directory extension "ext": "dir" behaves a bit differently compared to other extensions. When ax scan detects this extension, it automatically creates an additional directory in the remote instance's scan working directory (mkdir /home/op/$module+$timestamp/output/). This step prevents terminal errors that would occur if the additional output directory didn't exist.

..snip..
  {
    "command": "sudo nmap -iL input -oA output/output",
    "ext": "dir"
  },
..snip..

Outputting as a directory consolidates the results from each local log directory, named after the instances (~/.axiom/logs/$module+$timestamp/output/$instance_names/), into a single folder, effectively "flattening" the directory structure.

To avoid overwriting files with the same filename during directory flattening, a ~$n~ suffix is added to each file. In this case, each instance saves three files (output.xml, output.gnmap, and output.nmap) using nmap's -oA option in the module. The added ~$n~ suffix ensures unique filenames during consolidation.

To use the directory extension, you must also specify the appropriate ax scan output argument at runtime (-oD/-oA).

ax scan input -m nmap --quiet -oD my-directory-output/

none

Outputting as none takes the results from each local log directory named after the instance ~/.axiom/logs/$module+$timestamp/output/$instances_names/ , and copies those directories to a user provided output directory (preserving the directory structure).

This JSON object has the extension "ext": "none". When using this extension, ax scan ignores merging locally and instead returns unmerged results. Notice the mkdir output in the module command.

..snip..
  {
    "command": "mkdir output ; sudo nmap -iL input -oA output/output",
    "ext": "none"
  }
]

This command outputs as XML, Normal, and Grepable formats, since its using nmap's -oA, and because we don’t automatically create an output directory when using "ext": "none" (like we do for "ext": "dir"), we need to create the output directory as part of the command. This is for cases where someone wants to use "ext": "none" but still output on the remote instances to a file instead of a directory. When the scan finishes, the local results are stored in subfolders named after the instances names.

To use the none extension, you must also specify the appropriate ax scan output argument at runtime (-none).

ax scan input -m nmap --quiet -none my-unmerged-results-directory/

If this is confusing, just use modules without multiple JSON objects. Make sure the "command":..." outputs to the correct"ext":, then just use the default output argument in the ax scan command (i.e:ax scan ... -o my-results)

csv

Outputting as CSV, extracts the CSV header from the results and merges the rows (preserving the CSV header).

One-Shot Module: Warning the following example is a One-Shot Module. While One-Shot modules can use any module extension (e.g., "ext": "csv" in the below example), every One-Shot"command:" must output to a directory named output. In the module below, the output is output/_cleantarget_

The extra output directory on the remote instances (/home/op/scan/$module+$timestamp/output) are automatically created for you when using One-Shot modules.

For an example, lets look at the ffuf module to help explain "ext": "csv".

[
  {
    "command": "/home/op/go/bin/ffuf -w _wordlist_ -u _target_/FUZZ -of csv -o output/_cleantarget_ -ac",
    "wordlist": "/home/op/lists/seclists/Discovery/Web-Content/big.txt",
    "ext": "csv",
    "threads": "1"
  }
]

Since this is the first (and in this case the only) extension in the module, and because the "command":"... in the module outputs to csv (-of csv -o output/_cleantarget_), we can use -o in our ax scan command to output as csv.

ax scan input -m ffuf -o my-csv-output.csv

If you don't add any output argument, this module will still output to csv, since its the default (first) ext mentioned in the module.

ax scan input -m ffuf

If you wanted to be explicit about the output (if you had multiple JSON objects in the same module), you could use -csv in the ax scan command:

ax scan input -m ffuf -o my-csv-output.csv

jsonl

The jsonl (JSON lines) module extension is quite literally the same as "ext": "oG", which is very similar to "ext": "txt". Handling JSON Lines is very simple, since results are returned one line per target without needing to be in a specific order, making them easy to merge.

Lets look at the nuclei module for an example of "ext": "jsonl":

[
  {
    "command": "/home/op/go/bin/nuclei -update -silent ; cat input | /home/op/go/bin/nuclei -t _folder_ -o output",
    "ext": "txt",
    "folder": "/home/op/nuclei-templates"
  },
  {
    "command": "/home/op/go/bin/nuclei -update -silent ; cat input | /home/op/go/bin/nuclei -t _folder_ -jsonl output",
    "ext": "jsonl",
    "folder": "/home/op/nuclei-templates"
  }
]

As always, the module command "command": "... -jsonl output" needs to output in the same format as the module extension "ext": "jsonl". To use this, specify the appropriate ax scan output argument at runtime. For JSON Lines, the ax scan output argument is -oJ.

ax scan input -m nuclei -oJ my-json-lines-output.json

More Info

In conclusion, the ax scan tool offers flexible options for downloading and merging scan outputs based on the specified extension. By understanding how to use the different extensions and corresponding commands, you can effectively manage and customize your scan results to fit your specific needs.

Last updated