# 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](https://github.com/attacksurge/ax/blob/master/modules/nmap.json) 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
```

<figure><img src="/files/gTDRgb5QFbPWn86nQIxH" alt=""><figcaption></figcaption></figure>

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
```

<figure><img src="/files/KvgyLHsEeaiRec9LTixz" alt=""><figcaption></figcaption></figure>

### 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..
```

<figure><img src="/files/YJFesRDylvWdqHEemaTe" alt=""><figcaption></figcaption></figure>

### 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
```

<figure><img src="/files/d18ENsGQBTjDfUsjCVg2" alt=""><figcaption></figcaption></figure>

### xml

Outputting as xml is supported for only nmap and masscan at the moment, and uses [nMap\_Merger.py](https://github.com/attacksurge/ax/blob/master/interact/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
```

<figure><img src="/files/4EXuZqHX0SPGg9On77t1" alt=""><figcaption></figcaption></figure>

### 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.&#x20;

```
..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/`

<figure><img src="/files/wjP0jygVJJQkuDdd9Erj" alt=""><figcaption></figcaption></figure>

### 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).&#x20;

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.&#x20;

```
..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/
```

<figure><img src="/files/0Bp03ZM1kJDMzpGZHuHA" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
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`)
{% endhint %}

### csv

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

{% hint style="warning" %}
**One-Shot Module**: Warning the following example is a [One-Shot Module](/fundamentals/scans/modules/adding-one-shot-modules.md). While One-Shot modules can use any [module extension](/fundamentals/scans/modules/merging-and-module-extensions.md) (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.
{% endhint %}

For an example, lets look at the [ffuf](https://github.com/ffuf/ffuf) [module](https://github.com/attacksurge/ax/blob/master/modules/ffuf.json) to help explain `"ext": "csv"`.&#x20;

```
[
  {
    "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`&#x20;

### 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](https://github.com/attacksurge/ax/blob/master/modules/nuclei.json) 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.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ax.attacksurge.com/fundamentals/scans/modules/merging-and-module-extensions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
