From b2ce2ddb057d8782b54af05003e82f0dcbcef5cb Mon Sep 17 00:00:00 2001 From: rwhitcroft Date: Fri, 8 May 2015 14:17:49 -0400 Subject: [PATCH 1/4] determine the domain using env vars instead of parsing net.exe output --- .../windows/gather/enum_domain_group_users.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index 4e50ee1a7e..ccab74cfb8 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -38,15 +38,13 @@ class Metasploit3 < Msf::Post cur_domain, cur_user = client.sys.config.getuid.split("\\") ltype = "domain.group.members" ctype = "text/plain" - domain = "" # Get Data usr_res = run_cmd("net groups \"#{datastore['GROUP']}\" /domain") - dom_res = run_cmd("net config workstation") # Parse Returned data members = get_members(usr_res.split("\n")) - domain = get_domain(dom_res.split("\n")) + domain = client.sys.config.getenv("USERDOMAIN") # Show results if we have any, Error if we don't if ! members.empty? @@ -93,16 +91,6 @@ class Metasploit3 < Msf::Post return members end - def get_domain(results) - domain = '' - - results.each do |line| - if line =~ /Workstation domain \s+(.*)/ then domain = $1.strip end - end - - return domain - end - def is_member(cur_dom, cur_user, dom, users) member = false @@ -115,6 +103,7 @@ class Metasploit3 < Msf::Post return member end + def run_cmd(cmd) process = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true}) res = "" From 8c3a97667adfebe3c69d1c4c837abaeae9b99f5b Mon Sep 17 00:00:00 2001 From: rwhitcroft Date: Fri, 8 May 2015 15:25:20 -0400 Subject: [PATCH 2/4] use get_env instead of client.sys.config.getenv --- modules/post/windows/gather/enum_domain_group_users.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index ccab74cfb8..3b7b541a0b 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Post # Parse Returned data members = get_members(usr_res.split("\n")) - domain = client.sys.config.getenv("USERDOMAIN") + domain = get_env("USERDOMAIN") # Show results if we have any, Error if we don't if ! members.empty? From e9dc93f345c74e88b8e10ab61aa7ab04340254b5 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sat, 9 May 2015 10:44:02 +0100 Subject: [PATCH 3/4] Use cmd_exec --- .../windows/gather/enum_domain_group_users.rb | 23 +++++-------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index 3b7b541a0b..7d8324b265 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -40,7 +40,7 @@ class Metasploit3 < Msf::Post ctype = "text/plain" # Get Data - usr_res = run_cmd("net groups \"#{datastore['GROUP']}\" /domain") + usr_res = cmd_exec("net groups \"#{datastore['GROUP']}\" /domain") # Parse Returned data members = get_members(usr_res.split("\n")) @@ -92,28 +92,17 @@ class Metasploit3 < Msf::Post end def is_member(cur_dom, cur_user, dom, users) - member = false if cur_dom == dom users.each do |u| - if u.downcase == cur_user.downcase then member = true end + if u.downcase == cur_user.downcase + member = true + break + end end end - return member + member end - - def run_cmd(cmd) - process = session.sys.process.execute(cmd, nil, {'Hidden' => true, 'Channelized' => true}) - res = "" - while (d = process.channel.read) - break if d == "" - res << d - end - process.channel.close - process.close - return res - end - end From 028f9dd43ba8cc0a1908a0427da58edaa92b6369 Mon Sep 17 00:00:00 2001 From: Meatballs Date: Sat, 9 May 2015 10:48:07 +0100 Subject: [PATCH 4/4] Tidy and rubocop --- .../windows/gather/enum_domain_group_users.rb | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index 7d8324b265..f9c2f877a3 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -7,24 +7,23 @@ require 'msf/core' require 'rex' class Metasploit3 < Msf::Post - - def initialize(info={}) - super( update_info( info, - 'Name' => 'Windows Gather Enumerate Domain Group', - 'Description' => %q{ This module extracts user accounts from specified group - and stores the results in the loot. It will also verify if session - account is in the group. Data is stored in loot in a format that - is compatible with the token_hunter plugin. This module should be - run over as session with domain credentials.}, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'Carlos Perez ', - 'Stephen Haywood ' - ], - 'Platform' => [ 'win' ], - 'SessionTypes' => [ 'meterpreter' ] - )) + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Windows Gather Enumerate Domain Group', + 'Description' => %q( This module extracts user accounts from specified group + and stores the results in the loot. It will also verify if session + account is in the group. Data is stored in loot in a format that + is compatible with the token_hunter plugin. This module should be + run over as session with domain credentials.), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Carlos Perez ', + 'Stephen Haywood ' + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ] + )) register_options( [ OptString.new('GROUP', [true, 'Domain Group to enumerate', nil]) @@ -47,7 +46,7 @@ class Metasploit3 < Msf::Post domain = get_env("USERDOMAIN") # Show results if we have any, Error if we don't - if ! members.empty? + if !members.empty? print_status("Found users in #{datastore['GROUP']}") @@ -59,9 +58,9 @@ class Metasploit3 < Msf::Post # Is our current user a member of this domain and group if is_member(cur_domain, cur_user, domain, members) - print_status("Current sessions running as #{cur_domain}\\#{cur_user} is a member of #{datastore['GROUP']}!!") + print_good("Current sessions running as #{cur_domain}\\#{cur_user} is a member of #{datastore['GROUP']}!") else - print_error("Current session running as #{cur_domain}\\#{cur_user} is not a member of #{datastore['GROUP']}") + print_status("Current session running as #{cur_domain}\\#{cur_user} is not a member of #{datastore['GROUP']}") end # Store the captured data in the loot. @@ -70,7 +69,6 @@ class Metasploit3 < Msf::Post else print_error("No members found for #{datastore['GROUP']}") end - end def get_members(results) @@ -88,7 +86,7 @@ class Metasploit3 < Msf::Post end end - return members + members end def is_member(cur_dom, cur_user, dom, users)