mirror of
https://github.com/nmap/nmap.git
synced 2025-12-22 23:49:03 +00:00
Update some code excerpts in docs/scripting.xml. Make small changes to
scripts/showOwner.nse for the purpose of better presentation. Remove the subtle bug in the portrule example. We shouldn't put bad examples in print.
This commit is contained in:
@@ -1490,7 +1490,7 @@ try(socket:send(result))
|
|||||||
<indexterm><primary sortas="Service Owner script">“<literal>Service Owner</literal>” script</primary></indexterm>
|
<indexterm><primary sortas="Service Owner script">“<literal>Service Owner</literal>” script</primary></indexterm>
|
||||||
<indexterm><primary sortas="id script variable">“<varname>id</varname>” script variable</primary></indexterm>
|
<indexterm><primary sortas="id script variable">“<varname>id</varname>” script variable</primary></indexterm>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
id = "Service Owner"
|
id = "Service owner"
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@@ -1499,30 +1499,30 @@ id = "Service Owner"
|
|||||||
<para>
|
<para>
|
||||||
<indexterm><primary sortas="description script variable">“<varname>description</varname>” script variable</primary></indexterm>
|
<indexterm><primary sortas="description script variable">“<varname>description</varname>” script variable</primary></indexterm>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
description = "Opens a connection to the scanned port, opens a connection to \
|
description = [[
|
||||||
port 113, queries the owner of the service on the scanned port and prints it."
|
Attempts to find the owner of a scanned port.
|
||||||
|
|
||||||
|
The script makes a connection to the auth port (113) and queries the owner of
|
||||||
|
an open port.
|
||||||
|
]]
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
|
|
||||||
Users must tell the Lua interpreter that the string
|
The author of a script must decide what categories it belongs
|
||||||
continues on the following line by ending the line with a
|
to. This script is
|
||||||
backslash (‘<literal>\</literal>’). They must also decide what
|
<literal>safe</literal><indexterm><primary><literal>safe</literal>
|
||||||
categories the script belongs to. This script is a good
|
script category</primary></indexterm> because we are not using
|
||||||
example of a script which cannot be categorized clearly. It is
|
the service for anything it was not intended for. Because this
|
||||||
<literal>safe</literal><indexterm><primary><literal>safe</literal> script category</primary></indexterm>
|
script is one that should run by default it is also in the
|
||||||
because we are not using the service
|
<literal>default</literal><indexterm><primary><literal>default</literal>
|
||||||
for anything it was not intended for. On the other hand, it
|
script category</primary></indexterm>
|
||||||
is <literal>intrusive</literal><indexterm><primary><literal>intrusive</literal> script category</primary></indexterm>
|
category.
|
||||||
because we connect to a
|
|
||||||
service on the target and therefore potentially give out
|
|
||||||
information about us. To solve this dilemma we will place our
|
|
||||||
script in two categories:
|
|
||||||
|
|
||||||
</para>
|
</para>
|
||||||
<indexterm><primary sortas="categories script variable">“<varname>categories</varname>” script variable</primary></indexterm>
|
<indexterm><primary sortas="categories script variable">“<varname>categories</varname>” script variable</primary></indexterm>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
categories = {"safe", "intrusive"}
|
categories = {"default", "safe"}
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
@@ -1537,13 +1537,13 @@ categories = {"safe", "intrusive"}
|
|||||||
that. To decide whether to run the identification script on a
|
that. To decide whether to run the identification script on a
|
||||||
given port we need to know if there is an identification
|
given port we need to know if there is an identification
|
||||||
server running on the target machine. Or more formally: the
|
server running on the target machine. Or more formally: the
|
||||||
script should be run if (and only if) the currently scanned TCP port is open and
|
script should be run only if the currently scanned TCP port is open and
|
||||||
TCP port 113 is also open. For now we will rely on the fact that
|
TCP port 113 is also open. For now we will rely on the fact that
|
||||||
identification servers listen on TCP port 113. Unfortunately NSE
|
identification servers listen on TCP port 113. Unfortunately NSE
|
||||||
only gives us information about the currently scanned port.
|
only gives us information about the currently scanned port.
|
||||||
|
|
||||||
To find out if port 113 is open we are going to use the
|
To find out if port 113 is open we are going to use the
|
||||||
<literal>nmap.get_port_state()</literal> method. If the identd
|
<literal>nmap.get_port_state()</literal> function. If the identd
|
||||||
port was not scanned, the <literal>get_port_state</literal>
|
port was not scanned, the <literal>get_port_state</literal>
|
||||||
function returns <literal>nil</literal>. So we need to make
|
function returns <literal>nil</literal>. So we need to make
|
||||||
sure that the table is not <literal>nil</literal>. We also
|
sure that the table is not <literal>nil</literal>. We also
|
||||||
@@ -1555,10 +1555,15 @@ categories = {"safe", "intrusive"}
|
|||||||
<indexterm><primary sortas="portrule script variable">“<varname>portrule</varname>” script variable</primary></indexterm>
|
<indexterm><primary sortas="portrule script variable">“<varname>portrule</varname>” script variable</primary></indexterm>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
portrule = function(host, port)
|
portrule = function(host, port)
|
||||||
local ident_port = { number=113, protocol="tcp" }
|
local auth_port = { number=113, protocol="tcp" }
|
||||||
local identd = nmap.get_port_state(host, ident_port)
|
local identd = nmap.get_port_state(host, auth_port)
|
||||||
|
|
||||||
if identd ~= nil and identd.state == "open" and port.state == "open" then
|
if
|
||||||
|
identd ~= nil
|
||||||
|
and identd.state == "open"
|
||||||
|
and port.protocol == "tcp"
|
||||||
|
and port.state == "open"
|
||||||
|
then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
@@ -1567,22 +1572,6 @@ end
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
This rule is <emphasis>almost</emphasis> correct, but still
|
|
||||||
slightly buggy. Can you find the bug? It is a pretty subtle
|
|
||||||
one. The problem is that this script fires on any kind of open
|
|
||||||
port, TCP or UDP. The <literal>connect()</literal> method on
|
|
||||||
the other hand assumes a TCP protocol unless it is explicitly
|
|
||||||
told to use another protocol. Since the identification service
|
|
||||||
is only defined for TCP connections, we need to narrow down
|
|
||||||
the range of ports which fire our script. Our new rule only
|
|
||||||
runs the script if the port is open, we are looking at a TCP
|
|
||||||
port, and TCP port 113 is open. Writing the new and
|
|
||||||
improved port rule is left as an exercise to the reader (or
|
|
||||||
peek at the script in the latest Nmap distribution).
|
|
||||||
</para>
|
|
||||||
|
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
|
|
||||||
<sect2 id="nse-tutorial-action">
|
<sect2 id="nse-tutorial-action">
|
||||||
@@ -1615,43 +1604,42 @@ end
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
<indexterm><primary sortas="action script variable">“<varname>action</varname>” script variable</primary></indexterm>
|
<indexterm><primary sortas="action script variable">“<varname>action</varname>” script variable</primary></indexterm>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
action = function(host, port)
|
action = function(host, port)
|
||||||
local owner = ""
|
local owner = ""
|
||||||
|
|
||||||
local client_ident = nmap.new_socket()
|
local client_ident = nmap.new_socket()
|
||||||
local client_service = nmap.new_socket()
|
local client_service = nmap.new_socket()
|
||||||
|
|
||||||
local catch = function()
|
local catch = function()
|
||||||
client_ident:close()
|
client_ident:close()
|
||||||
client_service:close()
|
client_service:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
local try = nmap.new_try(catch)
|
local try = nmap.new_try(catch)
|
||||||
|
|
||||||
try(client_ident:connect(host.ip, 113))
|
try(client_ident:connect(host.ip, 113))
|
||||||
try(client_service:connect(host.ip, port.number))
|
try(client_service:connect(host.ip, port.number))
|
||||||
|
|
||||||
local localip, localport, remoteip,
|
local localip, localport, remoteip, remoteport =
|
||||||
remoteport = client_service:get_info()
|
try(client_service:get_info())
|
||||||
|
|
||||||
local request = port.number .. ", " .. localport .. "\n"
|
local request = port.number .. ", " .. localport .. "\n"
|
||||||
|
|
||||||
try(client_ident:send(request))
|
try(client_ident:send(request))
|
||||||
|
|
||||||
owner = try(client_ident:receive_lines(1))
|
owner = try(client_ident:receive_lines(1))
|
||||||
|
|
||||||
if string.match(owner, "ERROR") then
|
if string.match(owner, "ERROR") then
|
||||||
owner = nil
|
owner = nil
|
||||||
-- owner = "Service owner could not be determined: " .. owner
|
else
|
||||||
else
|
|
||||||
owner = string.match(owner, "USERID : .+ : (.+)\n", 1)
|
owner = string.match(owner, "USERID : .+ : (.+)\n", 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
try(client_ident:close())
|
try(client_ident:close())
|
||||||
try(client_service:close())
|
try(client_service:close())
|
||||||
|
|
||||||
return owner
|
return owner
|
||||||
end
|
end
|
||||||
</programlisting>
|
</programlisting>
|
||||||
</para>
|
</para>
|
||||||
@@ -1662,10 +1650,10 @@ return values of <literal>client_service:get_info()</literal> like
|
|||||||
this:</para>
|
this:</para>
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
local localip, localport = client_service:get_info()
|
local localip, localport = try(client_service:get_info())
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
<para>In this example we avoided telling the user if the service responded with an error. Instead we commented that line out and assigned <literal>nil</literal> to the owner variable. NSE scripts generally only return messages when they succeed.</para>
|
<para>In this example we avoided telling the user if the service responded with an error. Instead we assigned <literal>nil</literal> to the <varname>owner</varname> variable. NSE scripts generally only return messages when they succeed.</para>
|
||||||
|
|
||||||
</sect2>
|
</sect2>
|
||||||
<indexterm class="endofrange" startref="nse-tutorial-indexterm"/>
|
<indexterm class="endofrange" startref="nse-tutorial-indexterm"/>
|
||||||
@@ -1759,13 +1747,14 @@ local localip, localport = client_service:get_info()
|
|||||||
--- Common communication functions for network discovery tasks like
|
--- Common communication functions for network discovery tasks like
|
||||||
-- banner grabbing and data exchange.
|
-- banner grabbing and data exchange.
|
||||||
--
|
--
|
||||||
-- These functions may be passed a table of options, but it's not
|
-- These functions may be passed a table of options, but it's not required. The
|
||||||
-- required. The keys for the options table are "bytes", "lines",
|
-- keys for the options table are <code>"bytes"</code>, <code>"lines"</code>,
|
||||||
-- "proto", and "timeout". "bytes" sets a minimum number of bytes to
|
-- <code>"proto"</code>, and <code>"timeout"</code>. <code>"bytes"</code> sets
|
||||||
-- read. "lines" does the same for lines. "proto" sets the protocol to
|
-- a minimum number of bytes to read. <code>"lines"</code> does the same for
|
||||||
-- communicate with, defaulting to "tcp" if not provided. "timeout" sets
|
-- lines. <code>"proto"</code> sets the protocol to communicate with,
|
||||||
-- the socket timeout (see the socket function
|
-- defaulting to <code>"tcp"</code> if not provided. <code>"timeout"</code>
|
||||||
-- <code>set_timeout()</code> for details).
|
-- sets the socket timeout (see the socket function <code>set_timeout()</code>
|
||||||
|
-- for details).
|
||||||
-- @author Kris Katterjohn 04/2008
|
-- @author Kris Katterjohn 04/2008
|
||||||
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
|
-- @copyright Same as Nmap--See http://nmap.org/book/man-legal.html
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@@ -1800,13 +1789,13 @@ Maps IP addresses to autonomous system (AS) numbers.
|
|||||||
|
|
||||||
The script works by sending DNS TXT queries to a DNS server which in
|
The script works by sending DNS TXT queries to a DNS server which in
|
||||||
turn queries a third-party service provided by Team Cymru
|
turn queries a third-party service provided by Team Cymru
|
||||||
(team-cymru.org) using an in-addr.arpa style zone set-up especially for
|
(team-cymru.org) using an in-addr.arpa style zone set up especially for
|
||||||
use by Nmap.
|
use by Nmap.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
---
|
---
|
||||||
-- @usage
|
-- @usage
|
||||||
-- nmap --script ASN.nse [--script-args dns=<dns server>] <target>
|
-- nmap --script ASN.nse [--script-args dns=<DNS server>] <target>
|
||||||
-- @args dns The address of a recursive nameserver to use (optional).
|
-- @args dns The address of a recursive nameserver to use (optional).
|
||||||
-- @output
|
-- @output
|
||||||
-- Host script results:
|
-- Host script results:
|
||||||
|
|||||||
@@ -44,7 +44,8 @@ action = function(host, port)
|
|||||||
try(client_ident:connect(host.ip, 113))
|
try(client_ident:connect(host.ip, 113))
|
||||||
try(client_service:connect(host.ip, port.number))
|
try(client_service:connect(host.ip, port.number))
|
||||||
|
|
||||||
local localip, localport, remoteip, remoteport = try(client_service:get_info())
|
local localip, localport, remoteip, remoteport =
|
||||||
|
try(client_service:get_info())
|
||||||
|
|
||||||
local request = port.number .. ", " .. localport .. "\n"
|
local request = port.number .. ", " .. localport .. "\n"
|
||||||
|
|
||||||
@@ -54,7 +55,6 @@ action = function(host, port)
|
|||||||
|
|
||||||
if string.match(owner, "ERROR") then
|
if string.match(owner, "ERROR") then
|
||||||
owner = nil
|
owner = nil
|
||||||
-- owner = "Service owner could not be determined: " .. owner
|
|
||||||
else
|
else
|
||||||
owner = string.match(owner, "USERID : .+ : (.+)\n", 1)
|
owner = string.match(owner, "USERID : .+ : (.+)\n", 1)
|
||||||
end
|
end
|
||||||
@@ -64,4 +64,3 @@ action = function(host, port)
|
|||||||
|
|
||||||
return owner
|
return owner
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user