NSE LIB

Back to library
Unofficial safe Default

http-vuln-cve-2020-0688

Check for OWA and checks banner of Exchange server for CVE-2020-0688. Original source code here : https://github.com/onSec-fr/CVE-2020-0688-Scanner/

Ports

Any

Protocols

n/a

Attribution

k4nfr3 (upstream: k4nfr3/nmap-scripts)

Usage

No example usage is currently available for this script entry.

Example usage has not been added for this script yet.
Script Source Toggle

The full script source is stored with this entry and is hidden by default to keep the page easier to scan.

local http = require "http"
local nmap = require "nmap"
local shortport = require "shortport"
local strbuf = require "strbuf"

description = [[
Check for OWA and checks banner of Exchange server for CVE-2020-0688.
Original source code here : https://github.com/onSec-fr/CVE-2020-0688-Scanner/
]]

---
--@output
--PORT    STATE SERVICE
--443/tcp open  https
--|_cve-2020-0688: (14.3.487) Exchange 2010 if < 496 then = vulnerable

author = "k4nfr3"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "safe", "exploit"}

portrule = shortport.http

local last_len = 0

function split(source, delimiters)
    local elements = {}
    local pattern = '([^'..delimiters..']+)'
    string.gsub(source, pattern, function(value) elements[#elements + 1] =     value;  end);
    return elements
end

local function checkversion(w)
  local output = w .. "\n"
  local	mytable = split(w, ".")

  if w:find("^6.5.*") ~= nil then
		output = "Exchange 2003 - VULNERABLE !!!"
		
  elseif w:find("^8.*") ~= nil then
		output = "Exchange 2007 - VULNERABLE !!!"
		
  elseif w:find("^14.*") ~= nil then
		if tonumber(mytable[3]) < 496 then
			output = "Exchange 2010 VULNERABLE !!! (< 14.*.496)"
		else
			output = "Exchange 2010 not vulnerable (>= 14.*.496)"
		end
			
  elseif w:find("^15.0.*") ~= nil then
		if tonumber(mytable[3]) < 1497 then
			output = "Exchange 2013 VULNERABLE !!! (< 15.0.1496)"
		elseif	tonumber(mytable[3]) == 1497 then
			output = "Exchange 2013 maybe vulnerable (only 15.0.1497.6 is patched)"
		else
			output = "Exchange 2013 not vulnerable (>15.0.1497)"
		end

  elseif w:find("^15.1.*") ~= nil then
		if tonumber(mytable[3]) == 1913 or tonumber(mytable[3]) == 1847 then
			output = "Exchange 2016 maybe vulnerable (only 15.1.1913.7 and 15.1.1847.7 are patched)"
		elseif tonumber(mytable[3]) < 1913 then
			output = "Exchange 2016 VULNERABLE !!! (< 15.1.1913)"
		else
			output = "Exchange 2016 not vulnerable (> 15.1.1913)"
		end
		
  elseif w:find("^15.2.*") ~= nil then
		if tonumber(mytable[3]) == 529 or tonumber(mytable[3]) == 464 then
			output = "Exchange 2019 maybe vulnerable (only 15.2.529.8 and 15.2.464.11 are patched)"
		elseif tonumber(mytable[3]) < 529 then
			output = "Exchange 2019 VULNERABLE !!! (< 15.2.529)"
		else	
			output = "Exchange 2019 not vulnerable (> 15.2.529)"
		end
  else 
		output = "Exchange " .. w
  end
  return "(" .. w .. ") " .. output
end

-- parse all disallowed entries in body and add them to a strbuf
local function parse_answer(body)
  local found = false
  for line in body:gmatch("[^\r\n]+") do
    for w in line:gmatch('/owa/%d+.%d.%d+') do
      w = string.gsub(w,"/owa/","")
      found = true
	  return checkversion(w)
    end
    for w in line:gmatch('/owa/auth/%d+.%d.%d+') do
      w = string.gsub(w,"/owa/auth/","")
      found = true
	  return checkversion(w)
    end
	
  end
  if found == false then
	 return "no owa version found"
  end
end

action = function(host, port)
  local dis_count, noun
  options = {header={}}    options['header']['User-Agent'] = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/86.0.4240.0 Safari/537.36" 
  local answer = http.get(host, port, "/owa", options )

  if answer.status == 302 then
    return "Error 302 " .. answer.location 
  elseif answer.status ~= 200 then
    return "Error " .. tostring(answer.status) .. " for /owa"
  end

  local v_level = nmap.verbosity() + (nmap.debugging()*2)
  local output = strbuf.new()
  local detail = 15

  output = parse_answer(answer.body)
  
  return output
end

Overview

Imported from the upstream repository k4nfr3/nmap-scripts. repository containing some nmap scripts

download the script to the script folder “C:\Program Files (x86)\Nmap/scripts/” on Windows or /usr/share/nmap/scripts/ on some Linux

don’t forget to update the db if you want the script to be registered as exploit category for example

nmap —script-updatedb