1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 13:11:28 +00:00
Files
nmap/nselib/anyconnect.lua
patrik c950dcb154 Squashed commit of the following:
commit a78b6142449b71ccd1cd7061b5363f6882b2e00b
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sun May 25 21:19:22 2014 -0400

    fix indentation

commit 5e61eba30f98343fb172687bd377acae6cb9e242
Merge: d446fa7 9696dd5
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sun May 25 21:15:50 2014 -0400

    Merge branch 'master' into anyconnect

commit d446fa76181d97287604b48719dd3f714987b775
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sun May 25 21:15:09 2014 -0400

    Update CHANGELOG

commit 1590b8a8598bfd06c767c31312dc56c8e306c556
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sun May 25 21:13:27 2014 -0400

    update script.db

commit 93eb927e21d3e3702da36668628b70c42f14f0db
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sun May 25 21:09:51 2014 -0400

    update anyconnect library to better capture version
    add missing libraries http-cisco-anyconnect.nse
    add new scripts to detect vulnerabilities cve2014-2126 through 2129

commit 92fecad07d340e60abbe502a4541d6e4f71af224
Author: Patrik Karlsson <patrik@cqure.net>
Date:   Sat May 24 09:09:14 2014 -0400

    initial commit
2014-05-26 01:28:38 +00:00

146 lines
4.3 KiB
Lua

---
-- This library implements HTTP requests used by the Cisco AnyConnect VPN Client
--
-- @author "Patrik Karlsson <patrik@cqure.net>"
--
-- @args anyconnect.group AnyConnect tunnel group (default: VPN)
-- @args anyconnect.mac MAC address of connecting client (default: random MAC)
-- @args anyconnect.version Version of connecting client (default: 3.1.05160)
-- @args anyconnect.ua User Agent of connecting client (default: AnyConnect Darwin_i386 3.1.05160)
local http = require('http')
local stdnse = require('stdnse')
local url = require('url')
local math = require('math')
local table = require('table')
local os = require('os')
local string = require('string')
local args_group= stdnse.get_script_args('anyconnect.group') or "VPN"
local args_mac= stdnse.get_script_args('anyconnect.mac')
local args_ver = stdnse.get_script_args('anyconnect.version') or "3.1.05160"
local args_ua = stdnse.get_script_args('anyconnect.ua') or ("AnyConnect Darwin_i386 %s"):format(args_ver)
_ENV = stdnse.module("anyconnect", stdnse.seeall)
Cisco = {
Util = {
generate_mac = function()
math.randomseed(os.time())
local mac = {}
for i=1,6 do
mac[#mac + 1] = (("%x"):format(math.random(255))):gsub(' ', '0');
end
return table.concat(mac,':')
end,
},
AnyConnect = {
new = function(self, host, port)
local o = { host = host, port = port }
setmetatable(o, self)
self.__index = self
return o
end,
-- generate a random hex-string of length 'length'
--
generate_random = function(length)
local rnd = ""
for i=1, length do
rnd = rnd .. string.format("%.2X", math.random(255))
end
return rnd
end,
connect = function(self)
args_mac = args_mac or Cisco.Util.generate_mac()
local headers = {
['User-Agent'] = args_ua,
['Accept'] = '*/*',
['Accept-Encoding'] = 'identity',
['X-Transcend-Version'] = 1,
['X-Aggregate-Auth'] = 1,
['X-AnyConnect-Platform'] = 'mac-intel'
}
local data = ([[<?xml version="1.0" encoding="UTF-8"?>
<config-auth client="vpn" type="init" aggregate-auth-version="2">
<version who="vpn">%s</version>
<device-id device-type="MacBookAir4,1" platform-version="10.9.2" unique-id="%s">mac-intel</device-id>
<mac-address-list>
<mac-address>%s</mac-address></mac-address-list>
<group-select>%s</group-select>
<group-access>https://%s:%s</group-access>
</config-auth>]]):format(args_ver, self.generate_random(64), args_mac, args_group, self.host.ip, self.port.number)
local options = { header=headers , no_cache=true, redirect_ok = function(host,port)
local c = 5
return function(url)
if ( c==0 ) then return false end
c = c - 1
return true
end
end
}
local response = http.head(self.host, self.port, '/', options)
-- account for redirects
if not response.status == 200 then
return false, "Failed to connect to SSL VPN server"
elseif response.location then
local u = url.parse(response.location[#response.location])
self.host = u.host
end
response = http.post(self.host, self.port, '/', options, nil, data)
if response.status ~= 200 or response.body == nil then
return false, "Error in SSL VPN server response"
end
local xmltags = {
'version',
'tunnel-group',
'group-alias',
'config-hash',
'host-scan-ticket',
'host-scan-token',
'host-scan-base-uri',
'host-scan-wait-uri',
'banner'
}
self.conn_attr = {}
for _, tag in ipairs(xmltags) do
local body = response.body:gsub('\r?\n', '')
local filter = ("<%s.->(.*)</%s>"):format(tag:gsub('-', '%%-'), tag:gsub('-', '%%-'))
local m = body:match(filter)
if m then
self.conn_attr[tag] = m
end
end
-- in case we were redirected
self.conn_attr['host'] = stdnse.get_hostname(self.host)
return true
end,
---
-- Returns the version of the remote SSL VPN concentrator
-- @return table containing major, minor and rev numeric values
get_version = function(self)
local ver = {}
ver['major'], ver['minor'], ver['rev'] = self.conn_attr['version']:match('^(%d-)%.(%d-)%((.*)%)$')
return ver
end
}
}
return _ENV