Nmap Development mailing list archives

[NSE] Script Pre-scanning and Post-scanning example


From: Djalal Harouni <tixxdz () gmail com>
Date: Fri, 6 Aug 2010 18:18:02 +0100

Hi list,

I've merged the Script Pre-scanning and Post-scanning phases to Nmap
trunk. I hope that we'll see lot of scripts that make use of them.
As you know we have introduced new rules "prerule" and "postrule" the
documentation is comming and will be merged soon, in the mean while if
you want to play with this you can update or checkout. The
dns-zone-transfer script has already been updated to use a "prerule".

Code merged as svn r19515 and r19516.


The new Script Scan phases:
---------------------------

* Script Pre-scanning: before any Nmap scan. To activate scripts during
this phase you must use the "prerule".

* Script scanning: after Nmap hosts group scan. To activate scripts
during this phase you must use the classic rules "portrule" and
"hostrule".

* Script Post-scanning: after all Nmap scans. To activate scripts during
this phase you must use the "postrule".


dns-zone-transfer script example:
---------------------------------

To be able to run the script in the Script Pre-scanning phase (with the
prerule) you must specify the necessary arguments. For
dns-zone-transfer.nse script this argument is 'dnszonetransfer.server',
this is our target.
When the script is running in the Script scanning phase (portrule or hostrule)
then this server target is provided by Nmap (part of the Nmap discovered
hosts), so the 'dnszonetransfer.server' argument is ignored in this case
and the target is provided by the classic host table.

Script code:
------------

prerule = function() return true end
portrule = shortport.portnumber(53, 'tcp')
    ...
    ...
action = function(host, port)
    ...
    ...
    if args.dnszonetransfer and args.dnszonetransfer.domain then
      domain = args.dnszonetransfer.domain
    elseif args['dnszonetransfer.domain'] then
      domain = args['dnszonetransfer.domain']
    elseif args.domain then
      domain = args.domain
    end

    -- script running at the Script Pre-scanning phase.
    if SCRIPT_TYPE == "prerule" then
      if not domain then
        stdnse.print_debug(3,
          "Skipping '%s' %s, 'dnszonetransfer.domain' argument is missing.",
          SCRIPT_NAME, SCRIPT_TYPE)
        return
      end
      if args['dnszonetransfer.server'] then
        dns_server = args['dnszonetransfer.server']
      else
        stdnse.print_debug(3,
          "Skipping '%s' %s, 'dnszonetransfer.server' argument is missing.",
          SCRIPT_NAME, SCRIPT_TYPE)
        return
      end
      if args['dnszonetransfer.port'] then
        dns_port = args['dnszonetransfer.port']
      else
        dns_port = 53
      end
    -- script running at the Script Scan phase.
    elseif SCRIPT_TYPE == "portrule" then
      if not domain then
        if host.targetname then
          domain = host.targetname
        elseif host.name ~= "" then
          domain = host.name
        else
          -- can't do anything without a hostname
          return stdnse.format_output(false,
              string.format("'%s' script needs a dnszonetransfer.domain argument.",
                  SCRIPT_TYPE))
        end
      end
      dns_server = host.ip
      dns_port = port.number
    end

        soc = nmap.new_socket()
        soc:set_timeout(4000)
        try(soc:connect(dns_server, dns_port))
    ...
    ...
end

Some Documentation:
-------------------
* The script can run now at different phases, this will let us to share
  code between tasks.
* To check the rule type that activated the script, use the new
  SCRIPT_TYPE environment variable.
  if SCRIPT_TYPE == "prerule" then
    -- Script Pre-scanning phase
  elseif SCRIPT_TYPE == "hostrule" or SCRIPT_TYPE == "portrule" then
    -- Classic Script scanning phase
  elseif SCRIPT_TYPE == "postrule" then
    -- Script Post-scanning phase
  end

* The script will run at the Pre-scanning phase only if all the
necessary script arguments are available. If these arguments are missing
then the script should print a debug message at level 3 (current
standard) and return. In general on errors print a debug message and
call return without any value.
e.g:
      if args['dnszonetransfer.server'] then
        dns_server = args['dnszonetransfer.server']
      else
        stdnse.print_debug(3,
          "Skipping '%s' %s, 'dnszonetransfer.server' argument is missing.",
          SCRIPT_NAME, SCRIPT_TYPE)
        return
      end


More documentation will be merged soon, thx.

Script output:
--------------

1) At the Script Pre-scanning phase (prerule):

***** Without the necessary argument 'dnszonetransfer.server' ******
(Note: debug is level 3 to show why the script was skipped).

$ ./nmap -d3 --datadir . --script scripts/dns-zone-transfer.nse \
--script-args="dnszonetransfer.domain=ualberta.ca" 
...
NSE: Script ./scripts/dns-zone-transfer.nse was selected by name.
NSE: Loaded 1 scripts for scanning.
NSE: Loaded 'dns-zone-transfer.nse'.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 22:35
NSE: NSE Script Threads (1) running:
NSE: Starting 'dns-zone-transfer' (thread: 0x8dc5d18).
NSE: Skipping 'dns-zone-transfer' prerule, 'dnszonetransfer.server' argument is missing.
NSE: Finished 'dns-zone-transfer' (thread: 0x8dc5d18).
...


***** With the necessary argument 'dnszonetransfer.server' ******
(Note: we can run Nmap without targets)

$ ./nmap -d1 --datadir . --script scripts/dns-zone-transfer.nse \
--script-args="dnszonetransfer.server=MENAIK.CS.ualberta.ca,dnszonetransfer.domain=ualberta.ca"

...
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 22:43
NSE: NSE Script Threads (1) running:
NSE: Starting dns-zone-transfer.
NSE: Finished dns-zone-transfer.
Completed NSE at 22:44, 12.47s elapsed
Pre-scan script results:
| dns-zone-transfer:  
| ualberta.ca                                 SOA     NOM.ualberta.ca
dnsmaster.ualberta.ca  
| ualberta.ca                                 NS      NOM.ualberta.ca                        
| ualberta.ca                                 NS      NAME.ualberta.ca                       
| ualberta.ca                                 NS
MENAIK.CS.ualberta.ca                  
| ualberta.ca                                 A       129.128.98.86                          
| ualberta.ca                                 MX      ***.srv.ualberta.ca                   
| ualberta.ca                                 MX      ***.srv.ualberta.ca                  
| ualberta.ca                                 MX      ***-3.srv.ualberta.ca                
| www.100years.ualberta.ca                    CNAME  
| _msdcs.ualberta.ca                          NS      NAME.ualberta.ca                       
| _msdcs.ualberta.ca                          NS      NOM.ualberta.ca                        
| _sites.ualberta.ca                          NS      NAME.ualberta.ca                       
| _sites.ualberta.ca                          NS      NOM.ualberta.ca                        
| aahepp.ualberta.ca                          NS
MENAIK.CS.ualberta.ca                  
| aasua.ualberta.ca                           NS      NAME.ualberta.ca                       
...
...
|_ualberta.ca                                 SOA     NOM.ualberta.ca
dnsmaster.ualberta.ca  
NSE: Script Post-scanning.
Read from .: nmap-services.
WARNING: No targets were specified, so 0 hosts scanned.
Nmap done: 0 IP addresses (0 hosts up) scanned in 12.96 seconds



2) At the Script scanning phase (portrule):

$ ./nmap -d1 -PN -sT -p53 --datadir . --script scripts/dns-zone-transfer.nse \
--script-args="dnszonetransfer.domain=ualberta.ca" MENAIK.CS.ualberta.ca

...
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 19:01
NSE: NSE Script Threads (1) running:
NSE: Starting dns-zone-transfer.
NSE: Finished dns-zone-transfer.
Completed NSE at 19:01, 0.00s elapsed
mass_rdns: Using DNS server 10.0.2.3
Initiating Parallel DNS resolution of 1 host. at 19:01
mass_rdns: 0.24s 0/1 [#: 1, OK: 0, NX: 0, DR: 0, SF: 0, TR: 1]
Completed Parallel DNS resolution of 1 host. at 19:01, 0.23s elapsed
DNS resolution of 1 IPs took 0.24s. Mode: Async [#: 1, OK: 1, NX: 0, DR:
0, SF: 0, TR: 1, CN: 0]
Initiating Connect Scan at 19:01
Scanning MENAIK.CS.ualberta.ca (129.128.4.241) [1 port]
scovered open port 53/tcp on 129.128.4.241
Completed Connect Scan at 19:01, 0.32s elapsed (1 total ports)
Overall sending rates: 3.11 packets / s.
NSE: Script scanning 129.128.4.241.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 19:01
NSE: NSE Script Threads (1) running:
NSE: Starting dns-zone-transfer against 129.128.4.241:53.
NSE: Finished dns-zone-transfer against 129.128.4.241:53.
Completed NSE at 19:01, 9.90s elapsed
Nmap scan report for MENAIK.CS.ualberta.ca (129.128.4.241)
Host is up, received user-set (0.32s latency).
rDNS record for 129.128.4.241: menaik.cs.ualberta.ca
PORT   STATE SERVICE REASON
53/tcp open  domain  syn-ack
| dns-zone-transfer:  
| ualberta.ca                                 SOA     NOM.ualberta.ca
dnsmaster.ualberta.ca  
| ualberta.ca                                 NS      NOM.ualberta.ca                        
| ualberta.ca                                 NS      NAME.ualberta.ca                       
| ualberta.ca                                 NS
MENAIK.CS.ualberta.ca                  
| ualberta.ca                                 A       129.128.98.86
...
...
|_ualberta.ca                                 SOA     NOM.ualberta.ca
dnsmaster.ualberta.ca  
Final times for host: srtt: 321000 rttvar: 321000  to: 1605000

NSE: Script Post-scanning.
Read from .: nmap-payloads nmap-services.
Nmap done: 1 IP address (1 host up) scanned in 11.96 seconds


This new feature will make it easy for people that want to code network
tools or scripts (Lua language) by using the "prerule". Taking advantage
of the API provided by Nmap and NSE (low level network operations are
done by Nsock library C/C++).

Thx.

-- 
tixxdz
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: