Skip to content

Lua/NSE math.random argument error in qscan.nse #1037

@u0m3

Description

@u0m3

The qscan.nse has an issue with the second argument in math.random being a non-integer. Example output below (some output removed):

$ nmap -v -d --script qscan --script-args qscan.confidence=0.95,qscan.delay=200ms,qscan.numtrips=10 192.168.0.1
wpcap.dll present, library version: Npcap version 0.93, based on libpcap version 1.8.1

Starting Nmap 7.60 ( https://nmap.org ) at 2017-10-15 18:39 GTB Daylight Time
PORTS: Using top 1000 ports found open (TCP:1000, UDP:0, SCTP:0)
--------------- Timing report ---------------
  hostgroups: min 1, max 100000
  rtt-timeouts: init 1000, min 100, max 10000
  max-scan-delay: TCP 1000, UDP 1000, SCTP 1000
  parallelism: min 0, max 0
  max-retries: 10, host-timeout: 0
  min-rate: 0, max-rate: 0
---------------------------------------------
NSE: Using Lua 5.3.
NSE: Arguments from CLI: qscan.confidence=0.95,qscan.delay=200ms,qscan.numtrips=10
NSE: Arguments parsed: qscan.confidence=0.95,qscan.delay=200ms,qscan.numtrips=10
NSE: Loaded 1 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 18:39
[...]
NSE: Script scanning 192.168.0.1.
NSE: Starting runlevel 1 (of 1) scan.
Initiating NSE at 18:39
NSE: Starting qscan against 192.168.0.1.
NSE: qscan against 192.168.0.1 threw an error!
C:\Program Files (x86)\Nmap/scripts\qscan.nse:489: bad argument #2 to 'random' (number has no integer representation)
stack traceback:
        [C]: in function 'math.random'
        C:\Program Files (x86)\Nmap/scripts\qscan.nse:489: in function <C:\Program Files (x86)\Nmap/scripts\qscan.nse:411>
        (...tail calls...)

[...]

The problem occurs in https://github.com/nmap/nmap/blob/master/scripts/qscan.nse#L487-L492 because delay is a non-integer (in this example, 200ms is parsed as 0.2, the value in seconds) and according to http://lua-users.org/wiki/MathLibraryTutorial all arguments of math.random are expected to be integers.

A quick fix/work-around would be to replace the calls with something like

      if rtt < (3 * delay) / 2 then
        if rtt < (delay / 2) then
          stdnse.sleep(((delay / 2) + math.random(0, delay*1000)/1000 - rtt))
        else
          stdnse.sleep(math.random(((3 * delay) / 2 - rtt)*1000)/1000)
        end

I chose 1000 as a value because according to https://github.com/nmap/nmap/blob/master/nselib/stdnse.lua#L60-L69 stdnse.sleep has millisecond resolution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions