Created
May 26, 2017 07:31
-
-
Save Danielg75/80f722042326b10e3f371b53bac9eef0 to your computer and use it in GitHub Desktop.
CVE-2017-7494 nmap script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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