mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Add tftp-enum.nse by Alexander Rudakov.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
# Nmap Changelog ($Id$); -*-text-*-
|
||||
|
||||
o [NSE] Added tftp-enum by Alexander Rudakov.
|
||||
|
||||
o [NSE] Added openlookup-info by Toni Ruottu.
|
||||
|
||||
o [NSE] Added amqp-info.nse by Sebastian Dragomir.
|
||||
|
||||
90
nselib/data/tftplist.txt
Normal file
90
nselib/data/tftplist.txt
Normal file
@@ -0,0 +1,90 @@
|
||||
000000000000.cfg
|
||||
000000000000-directory~.xml
|
||||
323tosip1_1.bin
|
||||
4601_02_readme_R2_3.txt
|
||||
4601dbte1_82.bin
|
||||
4602_02SWSIPreadme_R1_1.txt
|
||||
4602dbte1_82.bin
|
||||
4602sbte1_82.bin
|
||||
4610_20_readme_R2_3.txt
|
||||
4610_20_readme_SIP_R2_2.txt
|
||||
4624_12_06readme_1_8_3.txt
|
||||
4625_readme_2_5.txt
|
||||
4690_010707.bin
|
||||
4690_readme_1_7_7.txt
|
||||
46xxreadme_111405.txt
|
||||
46xxsettings.txt
|
||||
46xxupgrade.scr
|
||||
a01d01b2_3.bin
|
||||
a02d01b2_3.bin
|
||||
a10d01b2_3.bin
|
||||
a20d01a2_3.bin
|
||||
a20d01b2_3.bin
|
||||
a25d01a2_5.bin
|
||||
b01d01b2_3.bin
|
||||
b02d01b2_3.bin
|
||||
b10d01b2_3.bin
|
||||
b20d01a2_3.bin
|
||||
b20d01b2_3.bin
|
||||
b25d01a2_5.bin
|
||||
bbla0_83.bin
|
||||
bootrom.ld
|
||||
cisco_util
|
||||
CP7912010301SIP050608A.sbin
|
||||
cvt01_2_3.bin
|
||||
cvt02_2_3.bin
|
||||
cvt02sw_2_3.bin
|
||||
def06r1_8_3.bin
|
||||
def24r1_8_3.bin
|
||||
dialplan.xml
|
||||
gkdefault.cfg
|
||||
infrared.txt
|
||||
merlin2.pcm
|
||||
OS79XX.TXT
|
||||
P003-07-5-00.bin
|
||||
P003-07-5-00.sbn
|
||||
P0S3-07-5-00.bin
|
||||
P0S3-07-5-00.loads
|
||||
P0S3-07-5-00.sb2
|
||||
phbook00e011010455.txt
|
||||
phone1.cfg
|
||||
release.xml
|
||||
RINGLIST.DAT
|
||||
s10d01b2_2.bin
|
||||
s20d01b2_2.bin
|
||||
SEP000F34118045.cnf
|
||||
SEP001562EA69E8.cnf
|
||||
SEPDefault.cnf
|
||||
SIP000F34118045.cnf
|
||||
SIPinsertMAChere.cnf
|
||||
SIP000F34118045.cnf
|
||||
SIPinsertMAChere.cnf
|
||||
SIPinsertMAChere.cnf
|
||||
sip_4602ap1_1.ebin
|
||||
sip_4602bt1_1.ebin
|
||||
sip_4602D01A.txt
|
||||
sip_4602D02A.txt
|
||||
sip.cfg
|
||||
SIPDefault.cnf
|
||||
sip.ld
|
||||
sipto323_1_1.ebin
|
||||
sip.ver
|
||||
SoundPointIPLocalization
|
||||
SoundPointIPWelcome.wav
|
||||
syncinfo.xml
|
||||
test
|
||||
test.txt
|
||||
uip200_463enc.pac
|
||||
uniden00e011030397.txt
|
||||
unidencom.txt
|
||||
XMLDefault.cnf.xml
|
||||
router-confg
|
||||
cisco-confg
|
||||
gateway-confg
|
||||
gw-confg
|
||||
bridge-confg
|
||||
admin-confg
|
||||
vip-confg
|
||||
sip-confg
|
||||
voip-confg
|
||||
myrouter-confg
|
||||
@@ -237,6 +237,7 @@ Entry { filename = "targets-ipv6-multicast-slaac.nse", categories = { "broadcast
|
||||
Entry { filename = "targets-sniffer.nse", categories = { "broadcast", "discovery", "safe", } }
|
||||
Entry { filename = "targets-traceroute.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "telnet-brute.nse", categories = { "brute", "intrusive", } }
|
||||
Entry { filename = "tftp-enum.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "upnp-info.nse", categories = { "default", "discovery", "safe", } }
|
||||
Entry { filename = "vnc-brute.nse", categories = { "brute", "intrusive", } }
|
||||
Entry { filename = "vnc-info.nse", categories = { "default", "discovery", "safe", } }
|
||||
|
||||
201
scripts/tftp-enum.nse
Normal file
201
scripts/tftp-enum.nse
Normal file
@@ -0,0 +1,201 @@
|
||||
description = [[
|
||||
Enumerates filenames at tftp server.
|
||||
|
||||
This script is implementation of tftptheft python utility written by Sandro Gauci <sandro@enablesecurity.com>
|
||||
Original utility can be found at http://code.google.com/p/tftptheft/
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage nmap -sU -p 69 --script tftp-enum.nse --script-args="tftp-enum.filelist=customlist.txt" <host>
|
||||
--
|
||||
-- @args filelist - file name with list of filenames to enumerate at tftp server
|
||||
--
|
||||
--
|
||||
|
||||
author = "Alexander Rudakov"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = { "discovery", "intrusive" }
|
||||
|
||||
require'bin'
|
||||
require'stdnse'
|
||||
require'shortport'
|
||||
require'datafiles'
|
||||
|
||||
local REQUEST_ERROR = -1
|
||||
local FILE_FOUND = 1
|
||||
local FILE_NOT_FOUND = 2
|
||||
|
||||
portrule = shortport.portnumber(69, "udp")
|
||||
|
||||
-- return a new array containing the concatenation of all of its
|
||||
-- parameters. Scaler parameters are included in place, and array
|
||||
-- parameters have their values shallow-copied to the final array.
|
||||
-- Note that userdata and function values are treated as scalar.
|
||||
local function array_concat(...)
|
||||
local t = {}
|
||||
for n = 1, select("#", ...) do
|
||||
local arg = select(n, ...)
|
||||
if type(arg) == "table" then
|
||||
for _, v in ipairs(arg) do
|
||||
t[#t + 1] = v
|
||||
end
|
||||
else
|
||||
t[#t + 1] = arg
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
|
||||
local generate_cisco_address_confg = function(base_address)
|
||||
local filenames = {}
|
||||
local octets = stdnse.strsplit("%.", base_address)
|
||||
|
||||
for i = 0, 255 do
|
||||
local address_confg = octets[1] .. "." .. octets[2] .. "." .. octets[3] .. "." .. i .. "-confg"
|
||||
table.insert(filenames, address_confg)
|
||||
end
|
||||
|
||||
return filenames
|
||||
end
|
||||
|
||||
local generate_filenames = function(host)
|
||||
local customlist = stdnse.get_script_args('tftp-enum.filelist')
|
||||
local status, default_filenames = datafiles.parse_file(customlist or "nselib/data/tftplist.txt" , {})
|
||||
if not status then
|
||||
stdnse.print_debug(1, "Can not open file with tftp file names list")
|
||||
return {}
|
||||
end
|
||||
|
||||
local cisco_address_confg_filenames = generate_cisco_address_confg(host.ip)
|
||||
|
||||
return array_concat(default_filenames, cisco_address_confg_filenames)
|
||||
end
|
||||
|
||||
|
||||
local create_tftp_file_request = function(filename)
|
||||
return bin.pack('CC', 0x00, 0x01) .. filename .. bin.pack('C', 0x00) .. 'octet' .. bin.pack('C', 0x00)
|
||||
end
|
||||
|
||||
local check_file_present = function(host, port, filename)
|
||||
stdnse.print_debug(1, ("checking file %s"):format(filename))
|
||||
|
||||
local file_request = create_tftp_file_request(filename)
|
||||
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
socket:connect(host.ip, port.number, "udp")
|
||||
local status, lhost, lport, rhost, rport = socket:get_info()
|
||||
|
||||
|
||||
if (not (status)) then
|
||||
stdnse.print_debug(1, ("error %s"):format(lhost))
|
||||
socket:close()
|
||||
return REQUEST_ERROR
|
||||
end
|
||||
|
||||
|
||||
local bind_socket = nmap.new_socket("udp")
|
||||
stdnse.print_debug(1, ("local port = %d"):format(lport))
|
||||
|
||||
socket:send(file_request)
|
||||
socket:close()
|
||||
|
||||
local bindOK, error = bind_socket:bind(nil, lport)
|
||||
|
||||
|
||||
stdnse.print_debug(1, "starting listener")
|
||||
|
||||
if (not (bindOK)) then
|
||||
stdnse.print_debug(1, ("Error in bind %s"):format(error))
|
||||
bind_socket:close()
|
||||
return REQUEST_ERROR
|
||||
end
|
||||
|
||||
|
||||
local recvOK, data = bind_socket:receive()
|
||||
|
||||
if (not (recvOK)) then
|
||||
stdnse.print_debug(1, ("Error in receive %s"):format(data))
|
||||
bind_socket:close()
|
||||
return REQUEST_ERROR
|
||||
end
|
||||
|
||||
if (data:byte(1) == 0x00 and data:byte(2) == 0x03) then
|
||||
bind_socket:close()
|
||||
return FILE_FOUND
|
||||
elseif (data:byte(1) == 0x00 and data:byte(2) == 0x05) then
|
||||
bind_socket:close()
|
||||
return FILE_NOT_FOUND
|
||||
else
|
||||
bind_socket:close()
|
||||
return REQUEST_ERROR
|
||||
end
|
||||
|
||||
return FILE_NOT_FOUND
|
||||
end
|
||||
|
||||
--- Generates a random string of the requested length. This can be used to check how hosts react to
|
||||
-- weird username/password combinations.
|
||||
-- @param length (optional) The length of the string to return. Default: 8.
|
||||
-- @param set (optional) The set of letters to choose from. Default: upper, lower, numbers, and underscore.
|
||||
-- @return The random string.
|
||||
local function get_random_string(length, set)
|
||||
if (length == nil) then
|
||||
length = 8
|
||||
end
|
||||
|
||||
if (set == nil) then
|
||||
set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"
|
||||
end
|
||||
|
||||
local str = ""
|
||||
|
||||
-- Seed the random number, if we haven't already
|
||||
if (not (nmap.registry.oracle_enum_users) or not (nmap.registry.oracle_enum_users.seeded)) then
|
||||
math.randomseed(os.time())
|
||||
nmap.registry.oracle_enum_users = {}
|
||||
nmap.registry.oracle_enum_users.seeded = true
|
||||
end
|
||||
|
||||
for i = 1, length, 1 do
|
||||
local random = math.random(#set)
|
||||
str = str .. string.sub(set, random, random)
|
||||
end
|
||||
|
||||
return str
|
||||
end
|
||||
|
||||
local check_open_tftp = function(host, port)
|
||||
local random_name = get_random_string()
|
||||
local ret_value = check_file_present(host, port, random_name)
|
||||
if (ret_value == FILE_FOUND or ret_value == FILE_NOT_FOUND) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
if (not (check_open_tftp(host, port))) then
|
||||
stdnse.print_debug(1, "tftp seems not active")
|
||||
nmap.set_port_state(host, port, "closed")
|
||||
return
|
||||
end
|
||||
|
||||
stdnse.print_debug(1, "tftp detected")
|
||||
|
||||
nmap.set_port_state(host, port, "open")
|
||||
|
||||
local results = {}
|
||||
filenames = generate_filenames(host)
|
||||
|
||||
for i, filename in ipairs(filenames) do
|
||||
local request_status = check_file_present(host, port, filename)
|
||||
if (request_status == FILE_FOUND) then
|
||||
table.insert(results, filename .. " found")
|
||||
end
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, results)
|
||||
end
|
||||
Reference in New Issue
Block a user