Lucene search

K
nmapPatrik KarlssonNMAP:CITRIX-ENUM-APPS.NSE
HistoryDec 14, 2009 - 7:30 a.m.

citrix-enum-apps NSE Script

2009-12-1407:30:38
Patrik Karlsson
nmap.org
159

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Extracts a list of published applications from the ICA Browser service.

Example Usage

sudo ./nmap -sU --script=citrix-enum-apps -p 1604 <host>

Script Output

PORT     STATE SERVICE
1604/udp open  unknown
1604/udp open  unknown
| citrix-enum-apps:
|   Notepad
|   iexplorer
|_  registry editor

Requires


local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"

description = [[
Extracts a list of 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 <[email protected]>
-- Revised 11/25/2009 - v0.2 - fixed multiple packet response bug

author = "Patrik Karlsson"

license = "Same as Nmap--See https://nmap.org/book/man-legal.html"

categories = {"discovery","safe"}


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 packet_len, pos = string.unpack("<I2", response)
  local app_name
  local pa_list = {}

  if packet_len < 40 then
    return
  end

  -- the list of published applications starts at offset 40
  local offset = 41

  while offset < packet_len do
    app_name, pos = string.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 its 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)

  local try = nmap.new_try(function() socket:close() end)

  try( socket:connect(host, port) )

  -- 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) ~= "\x01" 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

9.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

10 High

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

COMPLETE

Integrity Impact

COMPLETE

Availability Impact

COMPLETE

AV:N/AC:L/Au:N/C:C/I:C/A:C

0.973 High

EPSS

Percentile

99.8%

Related for NMAP:CITRIX-ENUM-APPS.NSE