The Yaptest run_test API

This page documents how to use the run_test API from your own home-brew yaptest scripts.

 

Examples

Before we dig into the details of how to use the API, it’s worth poining out that there are lots of examples in the yaptest tar ball.  This documentation is provided for completeness, not because I think it’s particularly needed.

Most of the pentesters I’ve seen use Yaptest have been able to copy existing yaptest scripts and modify them to do their bidding.  The following scripts demonstrate different capabilities of yaptest, so pick one that demonstrates the feature you’re interested in, copy it, then modify it:

  • yaptest-nmap-udp.pl demonstrates how to run a command against every IP address in the database, and to provide that IP as an option to the tool (in this can nmap -sU).
  • yaptest-nbtscan.pl demonstrates how to run a command against every IP address in the database, and to provide a file of IP addresses as an option to the tool (in this can nbtscan).
  • yaptest-tftp.pl demonstrates how to run a command against particular UDP ports (in this case 69/UDP).
  • yaptest-showmount.pl demonstrates how to run a tool against all hosts who have a certain string contained in their ‘rpcinfo -p’ output (in this case run showmount against hosts which have ‘100003’ in their rpcinfo output).
  • yaptest-nikto.pl demonstrates how to run a tool against ports based on nmap’s fingerprint of that port (in this case run nikto on ports that nmap thinks are HTTP).
  • yaptest-amap-tcp.pl demonstrates how to run a tool against all TCP ports.
  • yaptest-httprint.pl demonstrates how to run a tool against only SSL / non-SSL ports.
  • yaptest-tnscmd.pl demonstrates how to set a hard-timeout that kills a script after a certain period of time.
  • yaptest-oscanner.pl demonstrates how to set a softer timeout that only kills a script if it’s produced no output for a certain period of time.
  • yaptest-smtpscan.pl demonstrates how to kill a script if it produces too many lines of output.
  • yaptest-nxscan.pl demonstrates how to run 20 copies of a script in parallel to speed up testing.

API Documentation

The run_test API is the main (and recommended) way of running external tools against hosts in the yaptest database.

my $y = yaptest->new();
$y->run_test(
        command => "external-program -h ::IP:: -p ::PORT::",
        filter => { filter_key => filter_value, filter_key2 => filter_value2 },
        next_parameter_key => next_parameter_value,
        ...
);

The follows sections discuss each of the parameters that may be passed via the run_test API.

Command

The command parameter is mandatory – the only mandatory parameter in fact.  The value of “command” must be a string that contains a template for the command you want to run:

    command => "mycommand -h ::IP:: -p ::PORT::"

The command template if formed by writing the exact command you’d normally run, but replacing certain parts of the command this a special mark-up.  Replace:

  • The target IP address with ::IP::
  • The target port (if any) with ::PORT::
  • A file of target IP addresses with ::IPFILE::
  • A list of comma-separated target ports with ::PORTLIST::
  • A list of space-separated target ports with ::PORTLIST-SPACE::
  • A file of target ports with ::PORTFILE::

So if you’d normally run your nmap scan like this:

nmap -sS 10.0.0.1

your template would be:

nmap -sS ::IP::

However, if you run your nmap scans like this:

nmap -sS 10.0.0.1 -iL ips.txt

your template would be:

nmap -sS 10.0.0.1 -iL ::IPFILE::

If you run nikto like this:

nikto -h 10.0.0.1 -p 80

your template would be:

nikto -h ::IP:: -p::PORT::

“But exactly what are ::IP:: and ::PORT:: going to be replaced with?” I hear you ask.  Check out the “Filter” parameter below…

Filter

This option lets you restrict the hosts / ports your external tool with run against.  It is not mandatory.  If omitted, your external tool will be run against everything.

    filter => { key => value, key => value}

The comma above is interpretted as AND, i.e. only hosts / ports matching ALL of the supplied key => value pairs will be selected by the filter.  Read on and it’ll all make sense…

Possible “key”s are:

port.  This lets you run your tool only against specific ports.  The “value” is either a port number or an array of port numbers:

    filter => { port => 22 }
    filter => { port => [80, 443, 8080] }

Note that you can only have one filter line and the commas above are obviously interpretted as OR.  Any mathing port is selected by the filter.

transport_protocol.  This lets you run your tool only against specific transport protocols.  The value is a string “TCP” or “UDP”.  It’s commonly used with ‘port’:

    filter => { port => 22, transport_protocol => 'TCP' }

port_info.  This lets you run your tool only against ports that have certain attributes.  These attributes are stored in yaptest’s port_info table.  The “value” is a string.  Typically you’ll use this run a tool against all ports that nmap has identified as HTTP (or SSH or oracle-tns or whatever).

    filter => { port_info => "nmap_service_name = http" }

ssl.  This lets you run your tool only SSL ports.  The “value” is 0 or 1.

    filter => { port_info => "nmap_service_name = http", ssl => 0 }

ip.  This lets you run your tool only against a specific IP address.  The “value” is a string.  I don’t know why you’d use this feature.  I never have.

    filter => { ip => "127.0.0.1" }

Output File

This parameter tells yaptest where to store the output from the external tool.  It is not mandatory.  It defaults to a name based on the tool name.  If you were to run something like this:

    command => "ping -c 1 ::IP::"

The output file would be called “ping.out”. Next time you run it, the output file will not be overwritten, it will be called “ping.out.1”, then “ping.out.2”, etc.

My output files are not going to be particularly self-documenting are they? Can’t I store the target IP in the file name? Of course you can:

    output_file => "ping-::IP::.out"

You can use the same mark-up as for “command”, but some doesn’t make sense (like ::IPFILE::). ::IP:: and ::PORT:: are typically the only ones you’ll use in output file names.

Parallel Processes

Yaptest can fork off several copies of the external tool to speed up testing.  It is not mandatory and defaults to 1.

    parallel_processes => 5

This option is useful for lots of tools, for example on an internal network if you nikto on each website in turn you may never complete your test.  You probably want to run (say) 5 in parallel.

Timeout

Yaptest can kill external tools if they take too long.  This option is not mandatory.  The default is no timeout – tools can run forever.

Some tools misbehave by just hanging forever.  You don’t want this delaying the rest of your test, so specify a timeout in seconds like this:

    timeout => 60

Inactivity Timeout

If the “timeout” option above seems a little too harsh, this option may suit you better.  It kills external tools only if they produce no output for a certain period of time:

    inactivity_timeout => 60

If you ran a command like “ping 127.0.0.1” that kept producing a line of output each second forever, yaptest would never kill the external tool. Sometimes this is what you want, sometimes it isn’t. Choose carefully.

Maximum Lines

Yaptest is able to kill your external tools if they produce too much output (e.g. 1000 lines of “connection refused”).  By default yaptest will not kill tools that produce a lot of output.

    max_lines => 4000

Parser

This lets you call a parsing script automatically on the output file created by yaptest.  The output file contains output of the external tool an may contain information that needs to be parsed into the database.  It’s not mandatory, though.  If you have a parser for your tool’s output, you should use the auto-parse feature.  If you don’t, then don’t worry.

    parser => "yaptest-parse-nbtscan.pl"

 

 

 


Leave a Reply