From 83abf4b52327b402081792125493b3f8b45f45c5 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 2 Jul 2014 17:48:48 +0100 Subject: [PATCH 1/8] Add loot storage into the enum_service post module --- modules/post/windows/gather/enum_services.rb | 39 +++++++++++++++++--- 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 8f75d3686f..417b87b0d0 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -36,9 +36,13 @@ class Metasploit3 < Msf::Post end + def run # set vars + lootString = "" + lootString.force_encoding(Encoding::UTF_8) + credentialCount = {} qcred = datastore["CRED"] || nil qpath = datastore["PATH"] || nil if datastore["TYPE"] == "All" @@ -56,7 +60,12 @@ class Metasploit3 < Msf::Post print_status("Start Type Filter: " + qtype) end - print_status("Listing Service Info for matching services:") + if not datastore['VERBOSE'] + print_status("Detailed output is only printed when VERBOSE is set to True. Running this module can take some time.\n") + else + print_status("Listing Service Info for matching services:") + end + service_list.each do |sname| srv_conf = {} isgood = true @@ -75,13 +84,29 @@ class Metasploit3 < Msf::Post if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase isgood = false end + #count the occurance of specific credentials services are running as + serviceCred = srv_conf['Credentials'].upcase + if not serviceCred == '' + if credentialCount.has_key?(serviceCred) + credentialCount[serviceCred] += 1 + else + credentialCount[serviceCred] = 1 + #let the user know a new service account has been detected for possible lateral movement opportunities + print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'\n") + end + 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']}") + msgString = "\tName: #{sname}" + msgString << "\n\t\tStartup: #{srv_conf['Startup']}" + #remove invalid char at the end + commandString = srv_conf['Command'] + commandString.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n,"") + msgString << "\n\t\t#{commandString}" + msgString << "\n\t\tCredentials: #{srv_conf['Credentials']}\n" + vprint_good(msgString) + lootString << msgString end rescue print_error("An error occured enumerating service: #{sname}") @@ -89,8 +114,10 @@ class Metasploit3 < Msf::Post else print_error("Problem enumerating services") end - end + #store loot on completion of collection + p = store_loot("windows.services", "text/plain", session, lootString, "windows_services.txt", "Windows Services") + print_good("Loot file stored in: #{p.to_s}") end end From 9981a60b2793419bc2348531f278fc22e9ab3e39 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 2 Jul 2014 17:56:16 +0100 Subject: [PATCH 2/8] Add loot storage into the enum_service post module --- modules/post/windows/gather/enum_services.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 417b87b0d0..9cf71ad40a 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -41,7 +41,6 @@ class Metasploit3 < Msf::Post # set vars lootString = "" - lootString.force_encoding(Encoding::UTF_8) credentialCount = {} qcred = datastore["CRED"] || nil qpath = datastore["PATH"] || nil @@ -92,7 +91,7 @@ class Metasploit3 < Msf::Post else credentialCount[serviceCred] = 1 #let the user know a new service account has been detected for possible lateral movement opportunities - print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'\n") + print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'") end end From b781b87d74c0cb1016c33f75624348706c6ab724 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 12:44:17 -0500 Subject: [PATCH 3/8] Avoid unnecessary "if not" --- modules/post/windows/gather/enum_services.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 9cf71ad40a..bba1337b07 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -59,10 +59,10 @@ class Metasploit3 < Msf::Post print_status("Start Type Filter: " + qtype) end - if not datastore['VERBOSE'] - print_status("Detailed output is only printed when VERBOSE is set to True. Running this module can take some time.\n") - else + if datastore['VERBOSE'] print_status("Listing Service Info for matching services:") + else + print_status("Detailed output is only printed when VERBOSE is set to True. Running this module can take some time.\n") end service_list.each do |sname| From 1d828a951fbc22fab2d72073c3b85a0474fe7935 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 12:46:56 -0500 Subject: [PATCH 4/8] string interpolation is preferred over concatenation Please refer to https://github.com/bbatsov/ruby-style-guide --- modules/post/windows/gather/enum_services.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index bba1337b07..828440f454 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -50,13 +50,13 @@ class Metasploit3 < Msf::Post qtype = datastore["TYPE"] end if qcred - print_status("Credential Filter: " + qcred) + print_status("Credential Filter: #{qcred}") end if qpath - print_status("Executable Path Filter: " + qpath) + print_status("Executable Path Filter: #{qpath}") end if qtype - print_status("Start Type Filter: " + qtype) + print_status("Start Type Filter: #{qtype}") end if datastore['VERBOSE'] From ebeb9880a628b5ce76f7eed055d2b0e30f1d3a0b Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 12:55:13 -0500 Subject: [PATCH 5/8] Favor "unless" over "if" for negative conditions Please refer to https://github.com/bbatsov/ruby-style-guide --- modules/post/windows/gather/enum_services.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 828440f454..b13e3eee57 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -85,7 +85,7 @@ class Metasploit3 < Msf::Post end #count the occurance of specific credentials services are running as serviceCred = srv_conf['Credentials'].upcase - if not serviceCred == '' + unless serviceCred.empty? if credentialCount.has_key?(serviceCred) credentialCount[serviceCred] += 1 else From 8a513058f6bdfa975bf9cbabe2c17032a865f866 Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 12:59:10 -0500 Subject: [PATCH 6/8] Fix comments --- modules/post/windows/gather/enum_services.rb | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index b13e3eee57..e5161177de 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -16,8 +16,8 @@ class Metasploit3 < Msf::Post 'Name' => "Windows Gather Service Info Enumeration", 'Description' => %q{ This module will query the system for services and display name and configuration - info for each returned service. It allows you to optionally search the credentials, path, or start - type for a string and only return the results that match. These query operations + info for each returned service. It allows you to optionally search the credentials, path, + or start type for a string and only return the results that match. These query operations are cumulative and if no query strings are specified, it just returns all services. NOTE: If the script hangs, windows firewall is most likely on and you did not migrate to a safe process (explorer.exe for example). @@ -68,11 +68,11 @@ class Metasploit3 < Msf::Post service_list.each do |sname| srv_conf = {} isgood = true - #make sure we got a service name + # make sure we got a service name if sname begin srv_conf = service_info(sname) - #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 isgood = false end @@ -83,19 +83,20 @@ class Metasploit3 < Msf::Post if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase isgood = false end - #count the occurance of specific credentials services are running as + # count the occurance of specific credentials services are running as serviceCred = srv_conf['Credentials'].upcase unless serviceCred.empty? if credentialCount.has_key?(serviceCred) credentialCount[serviceCred] += 1 else credentialCount[serviceCred] = 1 - #let the user know a new service account has been detected for possible lateral movement opportunities + # let the user know a new service account has been detected for possible lateral + # movement opportunities print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'") end end - #if we are still good return the info + # if we are still good return the info if isgood msgString = "\tName: #{sname}" msgString << "\n\t\tStartup: #{srv_conf['Startup']}" @@ -114,7 +115,7 @@ class Metasploit3 < Msf::Post print_error("Problem enumerating services") end end - #store loot on completion of collection + # store loot on completion of collection p = store_loot("windows.services", "text/plain", session, lootString, "windows_services.txt", "Windows Services") print_good("Loot file stored in: #{p.to_s}") end From 9aa3c752341e6654ee54733affdbb1fc64676ccb Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 13:04:56 -0500 Subject: [PATCH 7/8] Do something for the shut-everything-up event handling practice --- modules/post/windows/gather/enum_services.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index e5161177de..a1a83f08f7 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -108,8 +108,12 @@ class Metasploit3 < Msf::Post vprint_good(msgString) lootString << msgString end - rescue + rescue ::Exception => e + # July 3rd 2014 wchen-r7: Not very sure what exceptions this method is trying to rescue, + # probably the typical shut-everything-up coding habit. We'll have to fix this later, + # but for now let's at least print the error for debugging purposes print_error("An error occured enumerating service: #{sname}") + print_error(e.to_s) end else print_error("Problem enumerating services") From 2c999d3099b71182a7f9f2a8b56ad3895bce0e9c Mon Sep 17 00:00:00 2001 From: sinn3r Date: Thu, 3 Jul 2014 13:06:19 -0500 Subject: [PATCH 8/8] Better describe the problem --- modules/post/windows/gather/enum_services.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index a1a83f08f7..baf89b0efe 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -116,7 +116,7 @@ class Metasploit3 < Msf::Post print_error(e.to_s) end else - print_error("Problem enumerating services") + print_error("Problem enumerating services (no service name found)") end end # store loot on completion of collection