|
|
 | |  |  | Etendre les fonctionnalités de nmap et réaliser un scan au niveau applicatif |  |
by Julien Raeis et Jean-Baptiste Aviat (02/02/10)
============================================================================
Extending nmap functionalities to perform layer 7 scans
============================================================================
.
Cet article est diponible en français à nmap-script.html.fr.
--[ 1. Introduction ]---------------------------------------------------
Nmap includes, since version 4.21, a scripting engine called NSE, based upon
the LUA programming language (http://nmap.org/nse/). This article shows how
it is possible, according to open ports revealed during scanning, to go deeper
into information discovery.
--[ 2. Scripts integration ]--------------------------------------------
On Linux systems, scripts are stored into the /usr/share/nmap/scripts/
directory and indexed into the scripts.db database, which can be updated by
the command "nmap --script-updatedb". Scripts are sorted by categories. Each
script declares the categories it belongs to by the mean of the following
line:
-- Extract from the rpcinfo.nse file:
categories = {"default","safe","discovery"}
The scripting engine is activated by using the "-sC" option with nmap. This
switch launches the scripts categorized as "intrusive" and "safe". It is
recommended, when operating on a production environment, to disable the
"intrusive" category, because some scripts in this category may for example
automatically try SQL injections. To activate different categories, nmap may be
invocated with the option "--script" as follows:
For safe scripts:
$ sudo nmap --script safe 127.0.0.1
for any available script (be careful, might be dangerous!):
$ sudo nmap --script all 127.0.0.1
A single script may also be invocated:
$ sudo nmap --script nom_du_script.nse 127.0.0.1
It is reasonable to use only scripts categorized as "safe" in order to minimize
the risk to crash applications on the tested systems.
--[ 3. Default scripts ]------------------------------------------------
By default, nmap 5.20 is shipped with 80 scripts analyzing mostly Apache and
SSH servers banners, requesting available services from RPC servers or
performing Whois queries. The script "smb-os-discovery.nse" identifies
the version of a Windows system by fingerprinting its NetBIOS/SMB stack:
$ sudo nmap -sU -sS --script smb-os-discovery.nse -p U:137,T:139 192.168.111.112 -PN
Starting Nmap 5.21 ( http://nmap.org ) at 2010-01-28 12:00 CET
NSE: Script Scanning completed.
Nmap scan report for 192.168.111.112
Host is up (0.00088s latency).
PORT STATE SERVICE
139/tcp open netbios-ssn
137/udp open netbios-ns
Host script results:
| smb-os-discovery:
| OS: Windows Server 2003 R2 3790 Service Pack 2 (Windows Server 2003 R2 5.2)
| Name: WORKGROUP\MSSQL2005
|_ System time: 2010-01-28 12:00:08 UTC+1
Nmap done: 1 IP address (1 host up) scanned in 0.42 seconds
--[ 4. Creating custom scripts ]----------------------------------------
Custom scripts can be easliy created by using the LUA language
(http://www.lua.org/), and the libraries shipped with nmap (nselibs).
For example, the following source code performs a request on a SIP device in
order to discover available SIP methods on this host:
-- -------------- Script NSE SIPOptions -------------- --
id = "SIPOptions"
description = "Attempts to extract SIP Options on SIP service"
author = "Jean-Baptiste Aviat <Jean-Baptiste.Aviat@hsc.fr>"
license = "See nmaps COPYING for licence"
categories = {"discovery", "safe"}
require "shortport"
portrule = shortport.portnumber(5060, "udp", {"open", "open|filtered"})
action = function(host, port)
local status, s, methods, socket, request
socket = nmap.new_socket()
socket:set_timeout(5000)
local catch = function()
socket:close()
end
local try = nmap.new_try(catch)
try(socket:connect(host.ip, port.number, "udp"))
request = "INFO sip:test@hsc.fr SIP/2.0"
request = request .. "Via: SIP/2.0/TCP hsc.fr:5060\r\n"
request = request .. "From: <sip:test@hsc.fr>;tag=d3f423d\r\n"
request = request .. "To: <sip:test@hsc.fr>;tag=8942\r\n"
request = request .. "Call-ID: 312352\r\n"
request = request .. "CSeq: 5 INFO\r\n"
request = request .. "Content-Length: 0\r\n\r\n"
socket:send(request)
while true do
status, s = socket:receive_lines(1)
methods = string.match(s, "Allow: *([ A-Z,]+)")
if not status or string.len(methods)> 0 then
break
end
end
socket:close()
-- inform nmap the UDP port is opened
nmap.set_port_state(host, port, "open")
return methods
end
-- ------------------------------------------------------
--[ 5. Usage ]----------------------------------------------------------
An nmap session that uses this script provides the following output (here
targeting an Asterisk SIP server):
$ sudo nmap --script=./SIPOptions.nse localhost -sU -p 5060
Starting Nmap 5.21 ( http://nmap.org ) at 2010-01-28 13:45 CET
Interesting ports on localhost (127.0.0.1):
PORT STATE SERVICE
5060/udp open sip
|_ SIPOptions: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY
Nmap done: 1 IP address (1 host up) scanned in 2.108 seconds
And here against the Ekiga softphone:
$ sudo nmap --script=./SIPOptions.nse localhost -sU -p 5060
Starting Nmap 5.21 ( http://nmap.org ) at 2010-01-28 13:47 CET
Interesting ports on dhcp2.hsc.fr (192.70.106.122):
PORT STATE SERVICE
5060/udp open unknown
|_ SIPOptions: INVITE,ACK,OPTIONS,BYE,CANCEL,NOTIFY,REFER,MESSAGE
--[ 6. References ]-----------------------------------------------------
- Nmap : http://nmap.org/
- NSE : http://nmap.org/nse/
- SIP / INFO : http://www.ietf.org/rfc/rfc2976.txt
- LUA : http://www.lua.org/
|