mirror of
https://github.com/nmap/nmap.git
synced 2026-08-27 03:48:14 +00:00
Add the scripts
citrix-brute-xml citrix-enum-apps citrix-enum-apps-xml citrix-enum-servers citrix-enum-servers-xml and the citrixxml modules, all by Patrik Karlsson.
This commit is contained in:
parent
304762b07d
commit
f2ae05968b
8 changed files with 1240 additions and 0 deletions
160
scripts/citrix-brute-xml.nse
Normal file
160
scripts/citrix-brute-xml.nse
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
description = [[ Attempts to guess valid credentials for the Citrix PN Web Agent XML Service.
|
||||
The XML service authenticates against the local Windows server or the Active Directory.
|
||||
|
||||
CAUTION: This script makes no attempt of preventing account lockout.
|
||||
If the password list contains more passwords than the lockout-threshold
|
||||
accounts WILL be locked.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap --script=citrix-brute-xml --script-args=userdb=<userdb>,passdb=<passdb>,ntdomain=<domain> -p 80,443,8080 <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 8080/tcp open http-proxy syn-ack
|
||||
-- | citrix-brute-xml:
|
||||
-- | Joe:password => Must change password at next logon
|
||||
-- | Luke:summer => Login was successful
|
||||
-- |_ Jane:secret => Account is disabled
|
||||
--
|
||||
---
|
||||
|
||||
-- Version 0.2
|
||||
|
||||
-- Created 11/30/2009 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 12/02/2009 - v0.2 - Use stdnse.format_ouput for output
|
||||
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"intrusive", "auth"}
|
||||
|
||||
require 'unpwdb'
|
||||
require 'shortport'
|
||||
require 'citrixxml'
|
||||
|
||||
portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
|
||||
--- Verifies if the credentials (username, password and domain) are valid
|
||||
--
|
||||
-- @param host string, the ip against which to perform
|
||||
-- @param port number, the port number of the XML service
|
||||
-- @param username string, the username to authenticate as
|
||||
-- @param password string, the password to authenticate with
|
||||
-- @param domain string, the Windows domain to authenticate against
|
||||
--
|
||||
-- @return success, message
|
||||
--
|
||||
function verify_password( host, port, username, password, domain )
|
||||
|
||||
local response = citrixxml.request_validate_credentials(host, port, {Credentials={Domain=domain, Password=password, UserName=username}})
|
||||
local cred_status = citrixxml.parse_validate_credentials_response(response)
|
||||
|
||||
local account = {}
|
||||
|
||||
account.username = username
|
||||
account.password = password
|
||||
account.domain = domain
|
||||
|
||||
if cred_status.ErrorId then
|
||||
if cred_status.ErrorId == "must-change-credentials" then
|
||||
account.valid = true
|
||||
account.message = "Must change password at next logon"
|
||||
elseif cred_status.ErrorId == "account-disabled" then
|
||||
account.valid = true
|
||||
account.message = "Account is disabled"
|
||||
elseif cred_status.ErrorId == "account-locked-out" then
|
||||
account.valid = false
|
||||
account.message = "Account Locked Out"
|
||||
elseif cred_status.ErrorId == "failed-credentials" then
|
||||
account.valid = false
|
||||
account.message = "Incorrect Password"
|
||||
elseif cred_status.ErrorId == "unspecified" then
|
||||
account.valid = false
|
||||
account.message = "Unspecified"
|
||||
else
|
||||
print("UNKNOWN response: " .. response)
|
||||
account.valid = false
|
||||
account.message = "failed"
|
||||
end
|
||||
else
|
||||
account.message = "Login was successful"
|
||||
account.valid = true
|
||||
end
|
||||
|
||||
return account
|
||||
|
||||
end
|
||||
|
||||
--- Formats the result from the table of valid accounts
|
||||
--
|
||||
-- @param accounts table containing accounts (tables)
|
||||
-- @return string containing the result
|
||||
function create_result_from_table(accounts)
|
||||
|
||||
local result = ""
|
||||
|
||||
for _, account in ipairs(accounts) do
|
||||
result = result .. " " .. account.username .. ":" .. account.password .. " => " .. account.message .. "\n"
|
||||
end
|
||||
|
||||
return " \n" .. result
|
||||
end
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local status, nextUser, nextPass
|
||||
local username, password
|
||||
local args = nmap.registry.args
|
||||
local ntdomain = args.ntdomain
|
||||
local valid_accounts = {}
|
||||
|
||||
if not ntdomain then
|
||||
return "FAILED: No domain specified (use ntdomain argument)"
|
||||
end
|
||||
|
||||
status, nextUser = unpwdb.usernames()
|
||||
|
||||
if not status then
|
||||
return
|
||||
end
|
||||
|
||||
status, nextPass = unpwdb.passwords()
|
||||
|
||||
if not status then
|
||||
return
|
||||
end
|
||||
|
||||
username = nextUser()
|
||||
|
||||
-- iterate over userlist
|
||||
while username do
|
||||
password = nextPass()
|
||||
|
||||
-- iterate over passwordlist
|
||||
while password do
|
||||
local result = "Trying " .. username .. "/" .. password .. " "
|
||||
local account = verify_password(host.ip, port.number, username, password, ntdomain)
|
||||
|
||||
if account.valid then
|
||||
|
||||
table.insert(valid_accounts, account)
|
||||
|
||||
if account.valid then
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Correct, Info: %s", username, password, account.message)
|
||||
else
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Correct", username, password)
|
||||
end
|
||||
else
|
||||
stdnse.print_debug(1, "Trying %s/%s => Login Failed, Reason: %s", username, password, account.message)
|
||||
end
|
||||
password = nextPass()
|
||||
end
|
||||
|
||||
nextPass("reset")
|
||||
username = nextUser()
|
||||
end
|
||||
|
||||
return create_result_from_table(valid_accounts)
|
||||
end
|
||||
150
scripts/citrix-enum-apps-xml.nse
Normal file
150
scripts/citrix-enum-apps-xml.nse
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
description = [[
|
||||
Extracts a list of applications, acls and settings from Citrix XML service
|
||||
|
||||
The script returns the shorter, comma separated output per default.
|
||||
Running nmap with the verbose flag (-v) triggers the detailed output.
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap --script=citrix-enum-apps-xml -p 80,443,8080 <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 8080/tcp open http-proxy
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | Application: Notepad
|
||||
-- | Disabled: false
|
||||
-- | Desktop: false
|
||||
-- | On Desktop: false
|
||||
-- | Encryption: basic
|
||||
-- | In start menu: false
|
||||
-- | Publisher: labb1farm
|
||||
-- | SSL: false
|
||||
-- | Remote Access: false
|
||||
-- | Users: Anonymous
|
||||
-- | Application: iexplorer
|
||||
-- | Disabled: false
|
||||
-- | Desktop: false
|
||||
-- | On Desktop: false
|
||||
-- | Encryption: basic
|
||||
-- | In start menu: false
|
||||
-- | Publisher: labb1farm
|
||||
-- | SSL: false
|
||||
-- | Remote Access: false
|
||||
-- | Users: Anonymous
|
||||
-- | Application: registry editor
|
||||
-- | Disabled: false
|
||||
-- | Desktop: false
|
||||
-- | On Desktop: false
|
||||
-- | Encryption: basic
|
||||
-- | In start menu: false
|
||||
-- | Publisher: labb1farm
|
||||
-- | SSL: false
|
||||
-- | Remote Access: false
|
||||
-- | Users: WIN-B4RL0SUCJ29\Joe
|
||||
-- |_ Groups: WIN-B4RL0SUCJ29\HR, *CITRIX_BUILTIN*\*CITRIX_ADMINISTRATORS*
|
||||
--
|
||||
--
|
||||
-- PORT STATE SERVICE
|
||||
-- 8080/tcp open http-proxy
|
||||
-- | citrix-enum-apps-xml:
|
||||
-- | Application: Notepad; Users: Anonymous
|
||||
-- | Application: iexplorer; Users: Anonymous
|
||||
-- |_ Application: registry editor; Users: WIN-B4RL0SUCJ29\Joe; Groups: WIN-B4RL0SUCJ29\HR, *CITRIX_BUILTIN*\*CITRIX_ADMINISTRATORS*
|
||||
--
|
||||
---
|
||||
|
||||
-- Version 0.2
|
||||
-- Created 11/26/2009 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 12/02/2009 - v0.2 - Use stdnse.format_ouput for output
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
require "comm"
|
||||
require 'shortport'
|
||||
require 'citrixxml'
|
||||
|
||||
portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
|
||||
--- Creates a table which is suitable for use with stdnse.format_output
|
||||
--
|
||||
-- @param appdata table with results from parse_appdata_response
|
||||
-- @param mode string short or long, see usage above
|
||||
-- @return table suitable for stdnse.format_output
|
||||
function format_output(appdata, mode)
|
||||
|
||||
local result = {}
|
||||
local setting_titles = { {appisdisabled="Disabled"}, {appisdesktop="Desktop"}, {AppOnDesktop="On Desktop"},
|
||||
{Encryption="Encryption"}, {AppInStartmenu="In start menu"},
|
||||
{PublisherName="Publisher"}, {SSLEnabled="SSL"}, {RemoteAccessEnabled="Remote Access"} }
|
||||
|
||||
|
||||
if mode == "short" then
|
||||
for app_name, AppData in ipairs(appdata) do
|
||||
local line = "Application: " .. AppData.FName
|
||||
|
||||
if AppData.AccessList then
|
||||
|
||||
if AppData.AccessList.User then
|
||||
line = line .. "; Users: " .. stdnse.strjoin(", ", AppData.AccessList.User)
|
||||
end
|
||||
|
||||
if AppData.AccessList.Group then
|
||||
line = line .. "; Groups: " .. stdnse.strjoin(", ", AppData.AccessList.Group)
|
||||
end
|
||||
|
||||
table.insert(result, line)
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
for app_name, AppData in ipairs(appdata) do
|
||||
local result_part = {}
|
||||
|
||||
result_part.name = "Application: " .. AppData.FName
|
||||
|
||||
local settings = AppData.Settings
|
||||
|
||||
for _, setting_pairs in ipairs(setting_titles) do
|
||||
for setting_key, setting_title in pairs(setting_pairs) do
|
||||
local setting_value = settings[setting_key] and settings[setting_key] or ""
|
||||
table.insert(result_part, setting_title .. ": " .. setting_value )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if AppData.AccessList then
|
||||
if AppData.AccessList.User then
|
||||
table.insert(result_part, "Users: " .. stdnse.strjoin(", ", AppData.AccessList.User) )
|
||||
end
|
||||
|
||||
if AppData.AccessList.Group then
|
||||
table.insert(result_part, "Groups: " .. stdnse.strjoin(", ", AppData.AccessList.Group) )
|
||||
end
|
||||
|
||||
table.insert(result, result_part)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return result
|
||||
|
||||
end
|
||||
|
||||
|
||||
action = function(host,port)
|
||||
|
||||
local response = citrixxml.request_appdata(host.ip, port.number, {ServerAddress="",attr={addresstype="dot"},DesiredDetails={"all","access-list"} })
|
||||
local appdata = citrixxml.parse_appdata_response(response)
|
||||
|
||||
local response = format_output(appdata, (nmap.verbosity() > 1 and "long" or "short"))
|
||||
|
||||
return stdnse.format_output(true, response)
|
||||
|
||||
end
|
||||
157
scripts/citrix-enum-apps.nse
Normal file
157
scripts/citrix-enum-apps.nse
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
description = [[
|
||||
Extract published applications from the ICA Browser service
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage sudo ./nmap -sU --script=citrix-enum-apps -p 1604 <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 1604/udp open unknown
|
||||
-- 1604/udp open unknown
|
||||
-- | citrix-enum-apps:
|
||||
-- | Notepad
|
||||
-- | iexplorer
|
||||
-- |_ registry editor
|
||||
--
|
||||
|
||||
-- Version 0.2
|
||||
|
||||
-- Created 11/24/2009 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 11/25/2009 - v0.2 - fixed multiple packet response bug
|
||||
|
||||
author = "Patrik Karlsson <patrik@cqure.net>"
|
||||
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
|
||||
categories = {"discovery","intrusive"}
|
||||
|
||||
require "comm"
|
||||
require "shortport"
|
||||
require "stdnse"
|
||||
require "bin"
|
||||
|
||||
portrule = shortport.portnumber(1604, "udp")
|
||||
|
||||
|
||||
-- process the response from the server
|
||||
-- @param response string, complete server response
|
||||
-- @return string row delimited with \n containing all published applications
|
||||
function process_pa_response(response)
|
||||
|
||||
local pos, packet_len = bin.unpack("SS", response)
|
||||
local app_name
|
||||
local pa_list = {}
|
||||
|
||||
if packet_len < 40 then
|
||||
return
|
||||
end
|
||||
|
||||
-- the list of published applications starts at offset 40
|
||||
offset = 41
|
||||
|
||||
while offset < packet_len do
|
||||
pos, app_name = bin.unpack("z", response:sub(offset))
|
||||
offset = offset + pos - 1
|
||||
|
||||
table.insert(pa_list, app_name)
|
||||
end
|
||||
|
||||
return pa_list
|
||||
|
||||
end
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local packet, counter
|
||||
local query = {}
|
||||
local pa_list = {}
|
||||
|
||||
--
|
||||
-- Packets were intercepted from the Citrix Program Neighborhood client
|
||||
-- They are used to query a server for it's list of servers
|
||||
--
|
||||
-- We're really not interested in the responses to the first two packets
|
||||
-- The third response contains the list of published applications
|
||||
-- I couldn't find any documentation on this protocol so I'm providing
|
||||
-- some brief information for the bits and bytes this script uses.
|
||||
--
|
||||
-- Spec. of response to query[2] that contains a list of published apps
|
||||
--
|
||||
-- offset size content
|
||||
-- -------------------------
|
||||
-- 0 16-bit Length
|
||||
-- 12 32-bit Server IP (not used here)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 40 - null-separated list of applications
|
||||
--
|
||||
query[0] = string.char(
|
||||
0x1e, 0x00, -- Length: 30
|
||||
0x01, 0x30, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
query[1] = string.char(
|
||||
0x20, 0x00, -- Length: 32
|
||||
0x01, 0x36, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
query[2] = string.char(
|
||||
0x2a, 0x00, -- Length: 42
|
||||
0x01, 0x32, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
counter = 0
|
||||
|
||||
local socket = nmap.new_socket()
|
||||
socket:set_timeout(5000)
|
||||
|
||||
try = nmap.new_try(function() socket:close() end)
|
||||
|
||||
try( socket:connect(host.ip, port.number, port.protocol) )
|
||||
|
||||
-- send the two first packets and never look back
|
||||
repeat
|
||||
try( socket:send(query[counter]) )
|
||||
packet = try(socket:receive())
|
||||
counter = counter + 1
|
||||
until (counter>#query)
|
||||
|
||||
-- process the first response
|
||||
pa_list = process_pa_response( packet )
|
||||
|
||||
--
|
||||
-- the byte at offset 31 in the response has a really magic function
|
||||
-- if it is set to zero (0) we have more response packets to process
|
||||
-- if it is set to one (1) we have arrived at the last packet of our journey
|
||||
--
|
||||
while packet:sub(31,31) ~= string.char(0x01) do
|
||||
packet = try( socket:receive() )
|
||||
local tmp_table = process_pa_response( packet )
|
||||
|
||||
for _,v in pairs(tmp_table) do
|
||||
table.insert(pa_list, v)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- set port to open
|
||||
if #pa_list>0 then
|
||||
nmap.set_port_state(host, port, "open")
|
||||
end
|
||||
|
||||
socket:close()
|
||||
|
||||
return stdnse.format_output(true, pa_list)
|
||||
|
||||
end
|
||||
45
scripts/citrix-enum-servers-xml.nse
Normal file
45
scripts/citrix-enum-servers-xml.nse
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
description = [[ Extracts the name of the server farm and member severs from Citrix XML service
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage
|
||||
-- nmap --script=citrix-enum-servers-xml -p 80,443,8080 <host>
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE REASON
|
||||
-- 8080/tcp open http-proxy syn-ack
|
||||
-- | citrix-enum-servers-xml:
|
||||
-- | CITRIX-SRV01
|
||||
-- |_ CITRIX-SRV01
|
||||
--
|
||||
---
|
||||
|
||||
-- Version 0.2
|
||||
|
||||
-- Created 11/26/2009 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 12/02/2009 - v0.2 - Use stdnse.format_ouput for output
|
||||
|
||||
author = "Patrik Karlsson"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
require "comm"
|
||||
require 'shortport'
|
||||
require 'citrixxml'
|
||||
|
||||
portrule = shortport.portnumber({8080,80,443}, "tcp")
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local xmldata = citrixxml.request_server_data(host.ip, port.number)
|
||||
local servers = citrixxml.parse_server_data_response(xmldata)
|
||||
local response = {}
|
||||
|
||||
for _, srv in ipairs(servers) do
|
||||
table.insert(response, srv)
|
||||
end
|
||||
|
||||
return stdnse.format_output(true, response)
|
||||
|
||||
end
|
||||
141
scripts/citrix-enum-servers.nse
Normal file
141
scripts/citrix-enum-servers.nse
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
description = [[
|
||||
Extract a list of Citrix servers from the ICA Browser service
|
||||
]]
|
||||
|
||||
---
|
||||
-- @usage sudo ./nmap -sU --script=citrix-enum-servers -p 1604
|
||||
--
|
||||
-- @output
|
||||
-- PORT STATE SERVICE
|
||||
-- 1604/udp open unknown
|
||||
-- | citrix-enum-servers:
|
||||
-- | CITRIXSRV01
|
||||
-- |_ CITRIXSRV02
|
||||
--
|
||||
|
||||
-- Version 0.2
|
||||
|
||||
-- Created 11/26/2009 - v0.1 - created by Patrik Karlsson <patrik@cqure.net>
|
||||
-- Revised 11/26/2009 - v0.2 - minor packet documentation
|
||||
|
||||
|
||||
author = "Patrik Karlsson <patrik@cqure.net>"
|
||||
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
|
||||
categories = {"discovery", "safe"}
|
||||
|
||||
require "comm"
|
||||
require "shortport"
|
||||
|
||||
portrule = shortport.portnumber(1604, "udp")
|
||||
|
||||
--
|
||||
-- process the response from the server
|
||||
-- @param response string, complete server response
|
||||
-- @return string row delimited with \n containing all published applications
|
||||
--
|
||||
function process_server_response(response)
|
||||
|
||||
local pos, packet_len = bin.unpack("SS", response)
|
||||
local server_name
|
||||
local server_list = {}
|
||||
|
||||
if packet_len < 40 then
|
||||
return
|
||||
end
|
||||
|
||||
-- the list of published applications starts at offset 40
|
||||
offset = 41
|
||||
|
||||
while offset < packet_len do
|
||||
pos, server_name = bin.unpack("z", response:sub(offset))
|
||||
offset = offset + pos - 1
|
||||
table.insert(server_list, server_name)
|
||||
end
|
||||
|
||||
return server_list
|
||||
|
||||
end
|
||||
|
||||
|
||||
action = function(host, port)
|
||||
|
||||
local packet, counter, socket
|
||||
local query = {}
|
||||
local server_list = {}
|
||||
|
||||
--
|
||||
-- Packets were intercepted from the Citrix Program Neighborhood client
|
||||
-- They are used to query a server for it's list of published applications
|
||||
--
|
||||
-- We're really not interested in the responses to the first two packets
|
||||
-- The third response contains the list of published applications
|
||||
-- I couldn't find any documentation on this protocol so I'm providing
|
||||
-- some brief information for the bits and bytes this script uses.
|
||||
--
|
||||
-- Spec. of response to query[2] that contains a list of published apps
|
||||
--
|
||||
-- offset size content
|
||||
-- -------------------------
|
||||
-- 0 16-bit Length
|
||||
-- 12 32-bit Server IP (not used here)
|
||||
-- 30 8-bit Last packet (1), More packets(0)
|
||||
-- 40 - null-separated list of applications
|
||||
--
|
||||
query[0] = string.char(
|
||||
0x1e, 0x00, -- Length: 30
|
||||
0x01, 0x30, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
query[1] = string.char(
|
||||
0x2a, 0x00, -- Length: 42
|
||||
0x01, 0x32, 0x02, 0xfd, 0xa8, 0xe3, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
)
|
||||
|
||||
counter = 0
|
||||
|
||||
socket = nmap.new_socket()
|
||||
socket:set_timeout(5000)
|
||||
|
||||
try = nmap.new_try(function() socket:close() end)
|
||||
try(socket:connect(host.ip, port.number, port.protocol))
|
||||
|
||||
-- send the two first packets and never look back
|
||||
repeat
|
||||
try(socket:send(query[counter]))
|
||||
packet = try(socket:receive())
|
||||
counter = counter + 1
|
||||
until (counter>#query)
|
||||
|
||||
-- process the first response
|
||||
server_list = process_server_response( packet )
|
||||
|
||||
--
|
||||
-- the byte at offset 31 in the response has a really magic function
|
||||
-- if it is set to zero (0) we have more response packets to process
|
||||
-- if it is set to one (1) we have arrived at the last packet of our journey
|
||||
--
|
||||
while packet:sub(31,31) ~= string.char(0x01) do
|
||||
packet = try( socket:receive() )
|
||||
local tmp_table = process_server_response( packet )
|
||||
|
||||
for _, v in ipairs(tmp_table) do
|
||||
table.insert(server_list, v)
|
||||
end
|
||||
end
|
||||
|
||||
if #server_list>0 then
|
||||
nmap.set_port_state(host, port, "open")
|
||||
end
|
||||
|
||||
socket:close()
|
||||
|
||||
return stdnse.format_output(true, server_list)
|
||||
|
||||
end
|
||||
|
|
@ -2,6 +2,11 @@ Entry { filename = "asn-query.nse", categories = { "discovery", "external", "saf
|
|||
Entry { filename = "auth-owners.nse", categories = { "default", "safe", } }
|
||||
Entry { filename = "auth-spoof.nse", categories = { "malware", "safe", } }
|
||||
Entry { filename = "banner.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "citrix-brute-xml.nse", categories = { "auth", "intrusive", } }
|
||||
Entry { filename = "citrix-enum-apps-xml.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "citrix-enum-apps.nse", categories = { "discovery", "intrusive", } }
|
||||
Entry { filename = "citrix-enum-servers-xml.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "citrix-enum-servers.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "daytime.nse", categories = { "discovery", "safe", } }
|
||||
Entry { filename = "db2-info.nse", categories = { "discovery", "safe", "version", } }
|
||||
Entry { filename = "dhcp-discover.nse", categories = { "default", "discovery", "intrusive", } }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue