mirror of
https://github.com/nmap/nmap.git
synced 2025-12-09 22:21:29 +00:00
merge soc07 r4896:4898 - added new scripts; made shortport.port_or_service work as intended, it now returns a function instead of a boolean
This commit is contained in:
@@ -40,15 +40,17 @@ port_in_list = function(porttab, proto, ...)
|
||||
return false
|
||||
end
|
||||
|
||||
port_or_service = function(porttab, number, service, proto, state)
|
||||
state= state or "open"
|
||||
proto = proto or "tcp"
|
||||
if (porttab.number==number or porttab.service==service)
|
||||
and porttab.protocol==proto
|
||||
and porttab.state == state
|
||||
then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
port_or_service = function(number, service, proto, state)
|
||||
return function(host, port)
|
||||
state = state or "open"
|
||||
proto = proto or "tcp"
|
||||
if (port.number==number or port.service==service)
|
||||
and port.protocol==proto
|
||||
and port.state == state
|
||||
then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
238
scripts/MSSQLm.nse
Normal file
238
scripts/MSSQLm.nse
Normal file
@@ -0,0 +1,238 @@
|
||||
-- Microsoft SQL Server information gathering script
|
||||
-- rev 1.0 (2007-06-09)
|
||||
|
||||
id = "MS SQL"
|
||||
|
||||
description = "Attempts to extract information from Microsoft SQL Server"
|
||||
|
||||
author = "Thomas Buchanan <tbuchanan@thecompassgrp.net>"
|
||||
|
||||
license = "See nmaps COPYING for licence"
|
||||
|
||||
categories = {"discovery", "intrusive"}
|
||||
|
||||
portrule = function(host, port)
|
||||
if
|
||||
( port.number == 1433
|
||||
or port.number == 1434 )
|
||||
and port.protocol == "udp"
|
||||
-- if we only run against open or open|filtered ports anyway, leave next two lines commented
|
||||
-- and ( port.state == "open"
|
||||
-- or port.state == "open|filtered" )
|
||||
then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
-- create the socket used for our connection
|
||||
local socket = nmap.new_socket()
|
||||
|
||||
-- set a reasonable timeout value
|
||||
socket:set_timeout(5000)
|
||||
|
||||
-- do some exception handling / cleanup
|
||||
local catch = function()
|
||||
socket:close()
|
||||
end
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
-- try to login to MS SQL network service, and obtain the real version information
|
||||
-- MS SQL 2000 does not report the correct version in the data sent in response to UDP probe (see below)
|
||||
local get_real_version = function(dst, dstPort)
|
||||
|
||||
local outcome
|
||||
local payload
|
||||
|
||||
local stat, resp
|
||||
|
||||
-- build a TDS packet - type 0x12
|
||||
-- copied from packet capture of osql connection
|
||||
payload = "\018\001\000\047\000\000\001\000\000\000"
|
||||
payload = payload .. "\026\000\006\001\000\032\000\001\002\000"
|
||||
payload = payload .. "\033\000\001\003\000\034\000\004\004\000"
|
||||
payload = payload .. "\038\000\001\255\009\000\011\226\000\000"
|
||||
payload = payload .. "\000\000\120\023\000\000\000"
|
||||
|
||||
socket = nmap.new_socket()
|
||||
|
||||
-- connect to the server using the tcpPort captured from the UDP probe
|
||||
try(socket:connect(dst, dstPort, "tcp"))
|
||||
|
||||
try(socket:send(payload))
|
||||
|
||||
-- read in any response we might get
|
||||
stat, resp = socket:receive_bytes(1)
|
||||
|
||||
if string.match(resp, "^\004") then
|
||||
|
||||
-- build a login packet to send to SQL server
|
||||
-- username = sa, blank password
|
||||
-- for information about packet structure, see http://www.freetds.org/tds.html
|
||||
|
||||
local query = "\016\001\000\128\000\000\001\000" -- TDS packet header
|
||||
query = query .. "\120\000\000\000\002\000\009\114" -- Login packet header = length, version
|
||||
query = query .. "\000\000\000\000\000\000\000\007" -- Login packet header continued = size, client version
|
||||
query = query .. "\140\018\000\000\000\000\000\000" -- Login packet header continued = Client PID, Connection ID
|
||||
query = query .. "\224\003\000\000\104\001\000\000" -- Login packet header continued = Option Flags 1 & 2, status flag, reserved flag, timezone
|
||||
query = query .. "\009\004\000\000\094\000\004\000" -- Login packet (Collation), then start offsets & lengths (client name, client length)
|
||||
query = query .. "\102\000\002\000\000\000\000\000" -- Login packet, offsets & lengths = username offset, username length, password offset, password length
|
||||
query = query .. "\106\000\004\000\114\000\000\000" -- Login packet, offsets & lengths = app name offset, app name length, server name offset, server name length
|
||||
query = query .. "\000\000\000\000\114\000\003\000" -- Login packet, offsets & lengths = unknown offset, unknown length, library name offset, library name length
|
||||
query = query .. "\120\000\000\000\120\000\000\000" -- Login packet, offsets & lengths = locale offset, locale length, database name offset, database name length
|
||||
query = query .. "\000\000\000\000\000\000\000\000" -- Login packet, MAC address + padding
|
||||
query = query .. "\000\000\000\000\000\000\000\000" -- Login packet, padding
|
||||
query = query .. "\000\000\000\000\000\000\078\000" -- Login packet, padding + start of client name (N)
|
||||
query = query .. "\077\000\065\000\080\000\115\000" -- Login packet = rest of client name (MAP) + username (s)
|
||||
query = query .. "\097\000\078\000\077\000\065\000" -- Login packet = username (a), app name (NMA)
|
||||
query = query .. "\080\000\078\000\083\000\069\000" -- Login packet = app name (P), library name (NSE)
|
||||
|
||||
-- send the packet down the wire
|
||||
try(socket:send(query))
|
||||
|
||||
-- read in any response we might get
|
||||
stat, resp = socket:receive_bytes(1)
|
||||
|
||||
-- successful response to login packet should contain the string "SQL Server"
|
||||
-- however, the string is UCS2 encoded, so we have to add the \000 characters
|
||||
if string.match(resp, "S\000Q\000L\000") then
|
||||
outcome = "\n sa user appears to have blank password"
|
||||
|
||||
-- since we have a successful login, send a query that will tell us what version the server is really running
|
||||
query = "\001\001\000\044\000\000\001\000" -- TDS Query packet
|
||||
query = query .. "\083\000\069\000\076\000\069\000" -- SELE
|
||||
query = query .. "\067\000\084\000\032\000\064\000" -- CT @
|
||||
query = query .. "\064\000\086\000\069\000\082\000" -- @VER
|
||||
query = query .. "\083\000\073\000\079\000\078\000" -- SION
|
||||
query = query .. "\013\000\010\000"
|
||||
|
||||
-- send the packet down the wire
|
||||
try(socket:send(query))
|
||||
|
||||
-- read in any response we might get
|
||||
stat, resp = socket:receive_bytes(1)
|
||||
|
||||
-- strip out the embedded \000 characters
|
||||
local banner = string.gsub(resp, "%z", "")
|
||||
outcome = outcome .. "\n " .. string.match(banner, "(Microsoft.-)\n")
|
||||
outcome = outcome .. "\n" .. string.match(banner, "\n.-\n.-\n(.-Build.-)\n")
|
||||
end
|
||||
|
||||
try(socket:close())
|
||||
|
||||
end -- if string.match(response, "^\004")
|
||||
|
||||
if outcome == nil then
|
||||
outcome = "\n Could not retrieve actual version information"
|
||||
end
|
||||
|
||||
return outcome
|
||||
end -- get_real_version(dst, dstPort)
|
||||
|
||||
-- connect to the potential SQL server
|
||||
try(socket:connect(host.ip, port.number, "udp"))
|
||||
|
||||
-- send a magic packet
|
||||
-- details here: http://www.codeproject.com/cs/database/locate_sql_servers.asp
|
||||
try(socket:send("\002"))
|
||||
|
||||
local status
|
||||
local response
|
||||
|
||||
-- read in any response we might get
|
||||
status, response = socket:receive_bytes(1)
|
||||
|
||||
try(socket:close())
|
||||
|
||||
if (not status) then
|
||||
return
|
||||
end
|
||||
|
||||
if (response == "TIMEOUT") then
|
||||
return
|
||||
end
|
||||
|
||||
-- since we got something back, the port is definitely open
|
||||
nmap.set_port_state(host, port, "open")
|
||||
|
||||
local result
|
||||
|
||||
-- create a lua table to hold some information
|
||||
local serverInfo = {}
|
||||
|
||||
-- do some pattern matching to exract certain key elements from the response
|
||||
-- the data comes back as a long semicolon separated list
|
||||
|
||||
-- A single server can have multiple instances, which are separated by a double semicolon
|
||||
-- cycle through each instance
|
||||
local count = 1
|
||||
for instance in string.gmatch(response, "(.-;;)") do
|
||||
result = instance
|
||||
serverInfo[count] = {}
|
||||
serverInfo[count].name = string.match(instance, "ServerName;(.-);")
|
||||
serverInfo[count].instanceName = string.match(instance, "InstanceName;(.-);")
|
||||
serverInfo[count].clustered = string.match(instance, "IsClustered;(.-);")
|
||||
serverInfo[count].version = string.match(instance, "Version;(.-);")
|
||||
serverInfo[count].tcpPort = string.match(instance, ";tcp;(.-);")
|
||||
serverInfo[count].namedPipe = string.match(instance, ";np;(.-);")
|
||||
count = count + 1
|
||||
end
|
||||
|
||||
-- do some heuristics on the version to see if we can match the major releases
|
||||
if string.match(serverInfo[1].version, "^6%.0") then
|
||||
result = "Discovered Microsoft SQL Server 6.0"
|
||||
elseif string.match(serverInfo[1].version, "^6%.5") then
|
||||
result = "Discovered Microsoft SQL Server 6.5"
|
||||
elseif string.match(serverInfo[1].version, "^7%.0") then
|
||||
result = "Discovered Microsoft SQL Server 7.0"
|
||||
elseif string.match(serverInfo[1].version, "^8%.0") then
|
||||
result = "Discovered Microsoft SQL Server 2000"
|
||||
elseif string.match(serverInfo[1].version, "^9%.0") then
|
||||
-- The Express Edition of MS SQL Server 2005 has a default instance name of SQLEXPRESS
|
||||
for _,instance in ipairs(serverInfo) do
|
||||
if string.match(instance.instanceName, "SQLEXPRESS") then
|
||||
result = "Discovered Microsoft SQL Server 2005 Express Edition"
|
||||
end
|
||||
end
|
||||
if result == nil then
|
||||
result = "Discovered Microsoft SQL Server 2005"
|
||||
end
|
||||
else
|
||||
result = "Discovered Microsoft SQL Server"
|
||||
end
|
||||
if serverInfo[1].name ~= nil then
|
||||
result = result .. "\n Server name: " .. serverInfo[1].name
|
||||
end
|
||||
if serverInfo[1].version ~= nil then
|
||||
result = result .. "\n Server version: " .. serverInfo[1].version
|
||||
-- Check for some well known release versions of SQL Server 2005
|
||||
-- for more info, see http://support.microsoft.com/kb/321185
|
||||
if string.match(serverInfo[1].version, "9.00.3042") then
|
||||
result = result .. " (SP2)"
|
||||
elseif string.match(serverInfo[1].version, "9.00.3043") then
|
||||
result = result .. " (SP2)"
|
||||
elseif string.match(serverInfo[1].version, "9.00.2047") then
|
||||
result = result .. " (SP1)"
|
||||
elseif string.match(serverInfo[1].version, "9.00.1399") then
|
||||
result = result .. " (RTM)"
|
||||
end
|
||||
end
|
||||
for _,instance in ipairs(serverInfo) do
|
||||
if instance.instanceName ~= nil then
|
||||
result = result .. "\n Instance name: " .. instance.instanceName
|
||||
end
|
||||
if instance.tcpPort ~= nil then
|
||||
result = result .. "\n TCP Port: " .. instance.tcpPort
|
||||
result = result .. get_real_version(host.ip, instance.tcpPort)
|
||||
end
|
||||
end
|
||||
|
||||
return result
|
||||
|
||||
end
|
||||
|
||||
|
||||
68
scripts/SMTPcommands.nse
Normal file
68
scripts/SMTPcommands.nse
Normal file
@@ -0,0 +1,68 @@
|
||||
-- SMTP supported commands gathering script
|
||||
-- Version History
|
||||
-- 1.0.0.0 - 2007-06-12
|
||||
|
||||
-- Cribbed heavily from Thomas Buchanan's SQL version detection
|
||||
-- script and from Arturo 'Buanzo' Busleiman's SMTP open relay
|
||||
-- detector script.
|
||||
|
||||
id = "SMTP"
|
||||
description = "Attempts to use EHLO to gather the Extended commands an SMTP server supports."
|
||||
author = "Jason DePriest <jrdepriest@gmail.com>"
|
||||
license = "See nmaps COPYING for licence"
|
||||
categories = {"discovery", "intrusive"}
|
||||
|
||||
portrule = function(host, port)
|
||||
if (port.number == 25
|
||||
or port.number == 587
|
||||
or port.number == 465
|
||||
or port.service == "smtp")
|
||||
and port.state == "open"
|
||||
and port.protocol == "tcp"
|
||||
then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
socket:set_timeout(5000)
|
||||
|
||||
local result
|
||||
local commands
|
||||
local mailservername
|
||||
local status = true
|
||||
|
||||
local catch = function()
|
||||
socket:close()
|
||||
end
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
try(socket:connect(host.ip, port.number, port.protocol))
|
||||
result = try(socket:receive_lines(1))
|
||||
|
||||
-- ASCII for "EHLO example.org\n"
|
||||
-- for some reason it wouldn't reply unless I did it like this
|
||||
local query = "\069\072\076\079\032\101\120\097"
|
||||
query = query .. "\109\112\108\101\046\111\114\103"
|
||||
query = query .. "\013\010"
|
||||
try(socket:send(query))
|
||||
result = try(socket:receive_lines(1))
|
||||
|
||||
if not string.match(result, "^250") then
|
||||
socket.close()
|
||||
-- TODO: use print_debug instead
|
||||
return "EHLO with errors or timeout. Enable --script-trace to see what is happening."
|
||||
end
|
||||
|
||||
result = string.gsub(result, "\050\053\048\032\079\075\013\010", "") -- 250 OK (needed to have the \r\n in there)
|
||||
result = string.gsub(result, "250%-", "") -- 250-
|
||||
result = "Responded to EHLO command\n" .. result
|
||||
|
||||
return result
|
||||
|
||||
end
|
||||
137
scripts/SNMPsysdesr.nse
Normal file
137
scripts/SNMPsysdesr.nse
Normal file
@@ -0,0 +1,137 @@
|
||||
-- SNMP system detection script
|
||||
-- rev 0.4 (6-11-2007)
|
||||
|
||||
id = "SNMPv1"
|
||||
|
||||
description = "Attempts to extract system information from SNMP service"
|
||||
|
||||
author = "Thomas Buchanan <tbuchanan@thecompassgrp.net>"
|
||||
|
||||
license = "See nmaps COPYING for licence"
|
||||
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
portrule = function(host, port)
|
||||
if
|
||||
port.number == 161
|
||||
and port.protocol == "udp"
|
||||
-- if we only run against open or open|filtered ports anyway, leave next two lines commented
|
||||
-- and ( port.state == "open"
|
||||
-- or port.state == "open|filtered" )
|
||||
then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
-- create the socket used for our connection
|
||||
local socket = nmap.new_socket()
|
||||
|
||||
-- set a reasonable timeout value
|
||||
socket:set_timeout(5000)
|
||||
|
||||
-- do some exception handling / cleanup
|
||||
local catch = function()
|
||||
socket:close()
|
||||
end
|
||||
|
||||
local try = nmap.new_try(catch)
|
||||
|
||||
-- connect to the potential SNMP system
|
||||
try(socket:connect(host.ip, port.number, "udp"))
|
||||
|
||||
local payload
|
||||
|
||||
-- build a SNMP v1 packet
|
||||
-- copied from packet capture of snmpget exchange
|
||||
-- get value: 1.3.6.1.2.1.1.1.0 (SNMPv2-MIB::sysDescr.0)
|
||||
payload = "\048\039\002\001\000\004\006" .. "public" -- community string = public
|
||||
payload = payload .. "\160\026\002\002\111\012\002\001"
|
||||
payload = payload .. "\000\002\001\000\048\014\048\012"
|
||||
payload = payload .. "\006\008\043\006\001\002\001\001"
|
||||
payload = payload .. "\001\000\005\000"
|
||||
|
||||
try(socket:send(payload))
|
||||
|
||||
local status
|
||||
local response
|
||||
|
||||
-- read in any response we might get
|
||||
status, response = socket:receive_bytes(1)
|
||||
|
||||
if (not status) then
|
||||
return
|
||||
end
|
||||
|
||||
if (response == "TIMEOUT") then
|
||||
return
|
||||
end
|
||||
|
||||
-- since we got something back, the port is definitely open
|
||||
nmap.set_port_state(host, port, "open")
|
||||
|
||||
local result
|
||||
result = string.match(response, "\001\001%z\004.(.*)")
|
||||
|
||||
-- build a SNMP v1 packet
|
||||
-- copied from packet capture of snmpget exchange
|
||||
-- get value: 1.3.6.1.2.1.1.3.0 (SNMPv2-MIB::sysUpTime.0)
|
||||
payload = "\048\039\002\001\000\004\006" .. "public" -- community string = public
|
||||
payload = payload .. "\160\026\002\002\101\040\002\001"
|
||||
payload = payload .. "\000\002\001\000\048\014\048\012"
|
||||
payload = payload .. "\006\008\043\006\001\002\001\001"
|
||||
payload = payload .. "\003\000\005\000"
|
||||
|
||||
try(socket:send(payload))
|
||||
|
||||
-- read in any response we might get
|
||||
status, response = socket:receive_bytes(1)
|
||||
|
||||
if (not status) then
|
||||
return result
|
||||
end
|
||||
|
||||
if (response == "TIMEOUT") then
|
||||
return result
|
||||
end
|
||||
|
||||
try(socket:close())
|
||||
|
||||
if string.find(response, "\006\001\002\001\001\003") == nil then
|
||||
return result
|
||||
end
|
||||
|
||||
local length,uptime,s1,s2,s3,s4
|
||||
|
||||
length = string.len(response)
|
||||
|
||||
s1,s2,s3,s4 = string.byte(response, length - 3, length)
|
||||
|
||||
uptime = s1*(2^24) + s2*(2^16) + s3*(2^8) + s4
|
||||
|
||||
local days, hours, minutes, seconds, htime, mtime, stime
|
||||
days = math.floor(uptime / 8640000)
|
||||
htime = math.fmod(uptime, 8640000)
|
||||
hours = math.floor(htime / 360000)
|
||||
mtime = math.fmod(htime, 360000)
|
||||
minutes = math.floor(mtime / 6000)
|
||||
stime = math.fmod(mtime, 6000)
|
||||
seconds = stime / 100
|
||||
|
||||
local dayLabel
|
||||
|
||||
if days == 1 then
|
||||
dayLabel = " day, "
|
||||
else
|
||||
dayLabel = " days, "
|
||||
end
|
||||
|
||||
result = result .. "\n System uptime: " .. days .. dayLabel .. hours .. ":" .. minutes .. ":" .. seconds
|
||||
result = result .. " (" .. tostring(uptime) .. " timeticks)"
|
||||
|
||||
return result
|
||||
end
|
||||
|
||||
@@ -13,9 +13,11 @@ categories = {"demo", "safe"}
|
||||
|
||||
require "shortport"
|
||||
|
||||
portrule = function(host, port)
|
||||
return shortport.port_or_service(port, 80, "http")
|
||||
end
|
||||
portrule = shortport.port_or_service(80, "http")
|
||||
|
||||
--portrule = function(host, port)
|
||||
-- return shortport.port_or_service(port, 80, "http")
|
||||
--end
|
||||
|
||||
action = function(host, port)
|
||||
local url, socket, request, result, status, s, title
|
||||
|
||||
Reference in New Issue
Block a user