bug/bundler_fix
Stuart Morgan 2015-12-18 02:01:38 +00:00
parent 38b6ad4dbf
commit f13ca17de0
1 changed files with 104 additions and 103 deletions

View File

@ -34,16 +34,16 @@ class Metasploit3 < Msf::Post
max_search = datastore['MAX_SEARCH']
db, dbfile = create_sqlite_db
print_status "Database created: #{dbfile.to_s}"
print_status "Database created: #{dbfile}"
# Download the list of groups from Active Directory
vprint_status "Retrieving AD Groups"
begin
group_filter = '(objectClass=group)'
group_fields = ['distinguishedName','objectSid','samAccountType','sAMAccountName','whenChanged','whenCreated','description']
group_fields = ['distinguishedName', 'objectSid', 'samAccountType', 'sAMAccountName', 'whenChanged', 'whenCreated', 'description']
groups = query(group_filter, max_search, group_fields)
rescue ::RuntimeError, ::Rex::Post::Meterpreter::RequestError => e
print_error("Error(Group): #{e.message.to_s}")
print_error("Error(Group): #{e.message}")
return
end
@ -55,143 +55,144 @@ class Metasploit3 < Msf::Post
# Go through each of the groups and identify the individual users in each group
vprint_status "Retrieving AD Group Membership"
users_fields = ['distinguishedName','objectSid','sAMAccountType','sAMAccountName','displayName','description','logonCount','userAccountControl','userPrincipalName','whenChanged','whenCreated','primaryGroupID','badPwdCount']
users_fields = ['distinguishedName', 'objectSid', 'sAMAccountType', 'sAMAccountName', 'displayName', 'description', 'logonCount', 'userAccountControl', 'userPrincipalName', 'whenChanged', 'whenCreated', 'primaryGroupID', 'badPwdCount']
group_counter = 0
groups[:results].each do |individual_group|
begin
# Perform the ADSI query to retrieve the effective users in each group (recursion)
vprint_status "Retrieving members of #{individual_group[3][:value].to_s}"
users_filter = "(&(objectCategory=person)(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=#{individual_group[0][:value].to_s}))"
vprint_status "Retrieving members of #{individual_group[3][:value]}"
users_filter = "(&(objectCategory=person)(objectClass=user)(memberof:1.2.840.113556.1.4.1941:=#{individual_group[0][:value]}))"
users_in_group = query(users_filter, max_search, users_fields)
next if users_in_group.nil? || users_in_group[:results].empty?
group_sid, group_rid = sid_hex_to_string(individual_group[1][:value])
# Add the group to the database
sql_param_group = { :rid => group_rid.to_i,
:distinguishedName => individual_group[0][:value].to_s,
:sAMAccountName => individual_group[3][:value].to_s,
:whenChanged => individual_group[4][:value].to_s,
:whenCreated => individual_group[5][:value].to_s,
:description => individual_group[6][:value].to_s
sql_param_group = { rid: group_rid.to_i,
distinguishedName: individual_group[0][:value].to_s,
sAMAccountName: individual_group[3][:value].to_s,
whenChanged: individual_group[4][:value].to_s,
whenCreated: individual_group[5][:value].to_s,
description: individual_group[6][:value].to_s
}
run_sqlite_query(db, 'ad_groups',sql_param_group)
run_sqlite_query(db, 'ad_groups', sql_param_group)
# Go through each of the users in the group
users_in_group[:results].each do |group_user|
user_sid, user_rid = sid_hex_to_string(group_user[1][:value])
print_line "Group [#{individual_group[3][:value].to_s}][#{group_rid.to_s}] has member [#{group_user[3][:value].to_s}][#{user_rid.to_s}]"
print_line "Group [#{individual_group[3][:value]}][#{group_rid}] has member [#{group_user[3][:value]}][#{user_rid}]"
# Add the group to the database
sql_param_user = { :rid => user_rid.to_i,
:distinguishedName => group_user[0][:value].to_s,
:sAMAccountName => group_user[3][:value].to_s,
:displayName => group_user[4][:value].to_s,
:description => group_user[5][:value].to_s,
:logonCount => group_user[6][:value].to_i,
:userPrincipalName => group_user[8][:value].to_s,
:whenChanged => group_user[8][:value].to_s,
:whenCreated => group_user[8][:value].to_s,
:primaryGroupID => group_user[9][:value].to_i,
:badPwdCount => group_user[10][:value].to_i
sql_param_user = { rid: user_rid.to_i,
distinguishedName: group_user[0][:value].to_s,
sAMAccountName: group_user[3][:value].to_s,
displayName: group_user[4][:value].to_s,
description: group_user[5][:value].to_s,
logonCount: group_user[6][:value].to_i,
userPrincipalName: group_user[8][:value].to_s,
whenChanged: group_user[8][:value].to_s,
whenCreated: group_user[8][:value].to_s,
primaryGroupID: group_user[9][:value].to_i,
badPwdCount: group_user[10][:value].to_i
}
run_sqlite_query(db, 'ad_users',sql_param_user)
run_sqlite_query(db, 'ad_users', sql_param_user)
# Now associate the user with the group
sql_param_mapping = { :user_rid => user_rid.to_i,
:group_rid => group_rid.to_i
sql_param_mapping = { user_rid: user_rid.to_i,
group_rid: group_rid.to_i
}
run_sqlite_query(db, 'ad_mapping',sql_param_mapping)
run_sqlite_query(db, 'ad_mapping', sql_param_mapping)
group_counter += 1
end
rescue ::RuntimeError, ::Rex::Post::Meterpreter::RequestError => e
print_error("Error(Users): #{e.message.to_s}")
print_error("Error(Users): #{e.message}")
return
end
end
print_status "Enumerated #{group_counter} group(s)"
if db and db.close
f = ::File.size(dbfile.to_s)
print_status "Database closed: #{dbfile.to_s} at #{f} byte(s)"
if db && db.close
f = ::File.size(dbfile.to_s)
print_status "Database closed: #{dbfile} at #{f} byte(s)"
end
end
# Run the parameterised SQL query
def run_sqlite_query(db,table_name,values)
sql_param_columns = values.keys
sql_param_bind_params = values.keys.map {|k| ":#{k}"}
db.execute("replace into #{table_name} (#{sql_param_columns.join(',')}) VALUES (#{sql_param_bind_params.join(',')})", values)
end
# Run the parameterised SQL query
def run_sqlite_query(db, table_name, values)
sql_param_columns = values.keys
sql_param_bind_params = values.keys.map { |k| ":#{k}" }
db.execute("replace into #{table_name} (#{sql_param_columns.join(',')}) VALUES (#{sql_param_bind_params.join(',')})", values)
end
# Creat the SQLite Database
def create_sqlite_db
begin
filename = "#{::Dir::Tmpname.tmpdir}/#{::Dir::Tmpname.make_tmpname('ad', 5)}.db"
db = SQLite3::Database.new(filename)
# Creat the SQLite Database
def create_sqlite_db
begin
filename = "#{::Dir::Tmpname.tmpdir}/#{::Dir::Tmpname.make_tmpname('ad', 5)}.db"
db = SQLite3::Database.new(filename)
# Create the table for the AD Groups
db.execute('DROP TABLE IF EXISTS ad_groups')
sql_table_group = 'CREATE TABLE ad_groups ('\
'rid INTEGER PRIMARY KEY NOT NULL,'\
'distinguishedName TEXT UNIQUE NOT NULL,'\
'sAMAccountName TEXT UNIQUE NOT NULL,'\
'description TEXT,'\
'whenChanged TEXT,'\
'whenCreated TEXT)'
db.execute(sql_table_group)
# Create the table for the AD Groups
db.execute('DROP TABLE IF EXISTS ad_groups')
sql_table_group = 'CREATE TABLE ad_groups ('\
'rid INTEGER PRIMARY KEY NOT NULL,'\
'distinguishedName TEXT UNIQUE NOT NULL,'\
'sAMAccountName TEXT UNIQUE NOT NULL,'\
'description TEXT,'\
'whenChanged TEXT,'\
'whenCreated TEXT)'
db.execute(sql_table_group)
# Create the table for the AD Users
db.execute('DROP TABLE IF EXISTS ad_users')
sql_table_users = 'CREATE TABLE ad_users ('\
'rid INTEGER PRIMARY KEY NOT NULL,'\
'distinguishedName TEXT UNIQUE NOT NULL,'\
'description TEXT,'\
'displayName TEXT,'\
'sAMAccountName TEXT,'\
'logonCount INTEGER,'\
'primaryGroupID INTEGER,'\
'badPwdCount INTEGER,'\
'userPrincipalName TEXT UNIQUE,'\
'whenCreated TEXT,'\
'whenChanged TEXT)'
db.execute(sql_table_users)
# Create the table for the AD Users
db.execute('DROP TABLE IF EXISTS ad_users')
sql_table_users = 'CREATE TABLE ad_users ('\
'rid INTEGER PRIMARY KEY NOT NULL,'\
'distinguishedName TEXT UNIQUE NOT NULL,'\
'description TEXT,'\
'displayName TEXT,'\
'sAMAccountName TEXT,'\
'logonCount INTEGER,'\
'primaryGroupID INTEGER,'\
'badPwdCount INTEGER,'\
'userPrincipalName TEXT UNIQUE,'\
'whenCreated TEXT,'\
'whenChanged TEXT)'
db.execute(sql_table_users)
# Create the table for the mapping between the two (membership)
db.execute('DROP TABLE IF EXISTS ad_mapping')
sql_table_mapping = 'CREATE TABLE ad_mapping ('\
'user_rid INTEGER NOT NULL,' \
'group_rid INTEGER NOT NULL,'\
'PRIMARY KEY (user_rid, group_rid),'\
'FOREIGN KEY(user_rid) REFERENCES ad_users(rid)'\
'FOREIGN KEY(group_rid) REFERENCES ad_groups(rid))'
db.execute(sql_table_mapping)
# Create the table for the mapping between the two (membership)
db.execute('DROP TABLE IF EXISTS ad_mapping')
sql_table_mapping = 'CREATE TABLE ad_mapping ('\
'user_rid INTEGER NOT NULL,' \
'group_rid INTEGER NOT NULL,'\
'PRIMARY KEY (user_rid, group_rid),'\
'FOREIGN KEY(user_rid) REFERENCES ad_users(rid)'\
'FOREIGN KEY(group_rid) REFERENCES ad_groups(rid))'
db.execute(sql_table_mapping)
return db, filename
rescue SQLite3::Exception => e
print_error("Error(Database): #{e.message.to_s}")
return
end
end
return db, filename
rescue SQLite3::Exception => e
print_error("Error(Database): #{e.message}")
return
end
end
# Convert the SID raw data to a string. TODO fix this mess....
# THIS NEEDS FIXING FIXME FIXME
def sid_hex_to_string(data)
sid = []
sid << data[0].to_s
rid = ''
(6).downto(1) do |i|
rid += byte2hex(data[i, 1][0])
end
sid << rid.to_i.to_s
sid += data.unpack("bbbbbbbbV*")[8..-1]
final_sid = "S-" + sid.join('-')
return final_sid, sid[-1]
end
def byte2hex(b)
ret = '%x' % (b.to_i & 0xff)
ret = '0' + ret if ret.length < 2
ret
end
# Convert the SID raw data to a string. TODO fix this mess....
# THIS NEEDS FIXING FIXME FIXME
def sid_hex_to_string(data)
sid = []
sid << data[0].to_s
rid = ''
(6).downto(1) do |i|
rid += byte2hex(data[i, 1][0])
end
sid << rid.to_i.to_s
sid += data.unpack("bbbbbbbbV*")[8..-1]
final_sid = "S-" + sid.join('-')
[final_sid, sid[-1]]
end
def byte2hex(b)
ret = '%x' % (b.to_i & 0xff)
ret = '0' + ret if ret.length < 2
ret
end
end