Skip to content

Instantly share code, notes, and snippets.

@Danielg75
Created May 26, 2017 07:31
Show Gist options
  • Save Danielg75/80f722042326b10e3f371b53bac9eef0 to your computer and use it in GitHub Desktop.
Save Danielg75/80f722042326b10e3f371b53bac9eef0 to your computer and use it in GitHub Desktop.
CVE-2017-7494 nmap script
local nmap = require "nmap"
local smb = require "smb"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
author = "Igor Livshitz"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"default", "discovery", "safe"}
dependencies = {"smb-brute"}
--- Check whether or not this script should be run.
hostrule = function(host)
return smb.get_port(host) ~= nil
end
-- Some observed OS strings:
-- "Windows 5.0" (is Windows 2000)
-- "Windows 5.1" (is Windows XP)
-- "Windows Server 2003 3790 Service Pack 2"
-- "Windows Vista (TM) Ultimate 6000"
-- "Windows Server (R) 2008 Standard 6001 Service Pack 1"
-- "Windows 7 Professional 7601 Service Pack 1"
-- http://msdn.microsoft.com/en-us/library/cc246806%28v=prot.20%29.aspx has a
-- list of strings that don't quite match these.
function make_cpe(result)
local os = result.os
local parts = {}
if string.match(os, "^Windows 5%.0") then
parts = {"o", "microsoft", "windows_2000"}
elseif string.match(os, "^Windows 5%.1") then
parts = {"o", "microsoft", "windows_xp"}
elseif string.match(os, "^Windows Server.*2003") then
parts = {"o", "microsoft", "windows_server_2003"}
elseif string.match(os, "^Windows Vista") then
parts = {"o", "microsoft", "windows_vista"}
elseif string.match(os, "^Windows Server.*2008") then
parts = {"o", "microsoft", "windows_server_2008"}
elseif string.match(os, "^Windows 7") then
parts = {"o", "microsoft", "windows_7"}
elseif string.match(os, "^Windows 8%f[^%d.]") then
parts = {"o", "microsoft", "windows_8"}
elseif string.match(os, "^Windows 8.1") then
parts = {"o", "microsoft", "windows_8.1"}
elseif string.match(os, "^Windows 10%f[^%d.]") then
parts = {"o", "microsoft", "windows_10"}
elseif string.match(os, "^Windows Server.*2012") then
parts = {"o", "microsoft", "windows_server_2012"}
end
if parts[1] == "o" and parts[2] == "microsoft"
and string.match(parts[3], "^windows") then
parts[4] = ""
local sp = string.match(os, "Service Pack (%d+)")
if sp then
parts[5] = "sp" .. tostring(sp)
else
parts[5] = "-"
end
if string.match(os, "Professional") then
parts[6] = "professional"
end
end
if #parts > 0 then
return "cpe:/" .. stdnse.strjoin(":", parts)
end
end
function add_to_output(output_table, label, value)
if value then
table.insert(output_table, string.format("%s: %s", label, value))
end
end
action = function(host)
local response = stdnse.output_table()
local status, result = smb.get_os(host)
if(status == false) then
return stdnse.format_output(false, result)
end
-- Collect results.
response.os = result.os
response.lanmanager = result.lanmanager
response.domain = result.domain
response.server = result.server
if result.time and result.timezone then
response.date = stdnse.format_timestamp(result.time, result.timezone * 60 * 60)
end
response.fqdn = result.fqdn
response.domain_dns = result.domain_dns
response.forest_dns = result.forest_dns
response.workgroup = result.workgroup
response.cpe = make_cpe(result)
-- Build normal output.
local output_lines = {}
-- Augment service version detection
if result.port and response.lanmanager then
local proto
if result.port == 445 or result.port == 139 then
proto = 'tcp'
else
proto = 'udp'
end
local port = nmap.get_port_state(host,{number=result.port,protocol=proto})
local version, product
if string.match(response.lanmanager,"^Samba ") then
port.version.product = 'Samba smbd'
port.version.version = string.match(response.lanmanager,"^Samba (.*)")
if string.match(port.version.version,"^3.5") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
elseif string.match(port.version.version,"^3.6") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
elseif string.match(port.version.version,"^3.7") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
elseif string.match(port.version.version,"^3.8") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
elseif string.match(port.version.version,"^3.9") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
elseif string.match(port.version.version,"^4") then
table.insert(output_lines, string.format("State is: %s", "POTENTIALLY VULNERABLE"))
else
table.insert(output_lines, string.format("State is: %s", "Vulnerability not detected"))
end
nmap.set_port_version(host,port)
elseif smb.get_windows_version(response.os) then
port.version.product = string.format("%s %s",smb.get_windows_version(response.os), port.version.name)
nmap.set_port_version(host,port)
end
table.insert(output_lines, string.format("%s","Samba-vuln-CVE-2017-7494"))
table.insert(output_lines, string.format("Summary: %s","Remote code execution from a writable share."))
table.insert(output_lines, string.format("Description: %s","A Samba vulnerability (CVE-2017-7494) enables a malicious attacker with valid write access to a file share to upload and execute an arbitrary binary file which will run with Samba permissions."))
table.insert(output_lines, string.format("Affected Version: %s","All versions of Samba from 3.5.0 onwards."))
table.insert(output_lines, string.format("For more info: %s","https://www.guardicore.com/2017/05/samba/"))
end
return response, stdnse.format_output(true, output_lines)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment