Whitespace at EOL
parent
01e2e8951e
commit
c3fa62cd59
|
@ -23,25 +23,25 @@ module X86
|
|||
EDI = BH = DI = 7
|
||||
|
||||
REG_NAMES32 = [ 'eax', 'ecx', 'edx', 'ebx', 'esp', 'ebp', 'esi', 'edi' ]
|
||||
|
||||
|
||||
REG_NAMES16 = [ 'ax', 'cx', 'dx', 'bx', 'sp', 'bp', 'si', 'di' ]
|
||||
|
||||
|
||||
REG_NAMES8L = [ 'al', 'cl', 'dl', 'bl', nil, nil, nil, nil ]
|
||||
|
||||
|
||||
# Jump tp a specific register
|
||||
def self.jmp_reg(str)
|
||||
reg = reg_number(str)
|
||||
_check_reg(reg)
|
||||
"\xFF" + [224 + reg].pack('C')
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Generate a LOOP instruction (Decrement ECX and jump short if ECX == 0)
|
||||
#
|
||||
def self.loop(offset)
|
||||
"\xE2" + pack_lsb(rel_number(offset, -2))
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# This method returns the opcodes that compose a jump instruction to the
|
||||
# supplied relative offset.
|
||||
|
|
|
@ -44,7 +44,7 @@ class Nasm
|
|||
# Open the temporary file
|
||||
tmp = Tempfile.new('nasmXXXX')
|
||||
tmp.binmode
|
||||
|
||||
|
||||
tpath = tmp.path
|
||||
opath = tmp.path + '.out'
|
||||
|
||||
|
@ -76,7 +76,7 @@ class Nasm
|
|||
|
||||
tmp = Tempfile.new('nasmout')
|
||||
tmp.binmode
|
||||
|
||||
|
||||
tfd = File.open(tmp.path, "wb")
|
||||
|
||||
tfd.write(raw)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#
|
||||
# ________________________________________________________________________________
|
||||
#
|
||||
#
|
||||
# ,sSSs,,s, ,sSSSs, ALPHA 2: Zero-tolerance. (build 07)
|
||||
# SS" Y$P" SY" ,SY
|
||||
# iS' dY ,sS" Unicode-proof uppercase alphanumeric shellcode encoding.
|
||||
|
|
|
@ -31,39 +31,39 @@ class Generic
|
|||
|
||||
def Generic.encode_byte(block, badchars)
|
||||
accepted_chars = default_accepted_chars.dup
|
||||
|
||||
|
||||
badchars.each_char {|c| accepted_chars.delete(c) } if badchars
|
||||
|
||||
|
||||
# No, not nipple.
|
||||
nibble_chars = Array.new(0x10) {[]}
|
||||
accepted_chars.each {|c| nibble_chars[c.unpack('C')[0] & 0x0F].push(c) }
|
||||
|
||||
|
||||
poss_encodings = []
|
||||
|
||||
|
||||
block_low_nibble = block & 0x0F
|
||||
block_high_nibble = block >> 4
|
||||
|
||||
|
||||
# Get list of chars suitable for expressing lower part of byte
|
||||
first_chars = nibble_chars[block_low_nibble]
|
||||
|
||||
|
||||
# Build a list of possible encodings
|
||||
first_chars.each do |first_char|
|
||||
first_high_nibble = first_char.unpack('C')[0] >> 4
|
||||
|
||||
|
||||
# In the decoding process, the low nibble of the second char gets combined
|
||||
# (either ADDed or XORed depending on the encoder) with the high nibble of the first char,
|
||||
# and we want the high nibble of our input byte to result
|
||||
second_low_nibble = gen_second(block_high_nibble, first_high_nibble) & 0x0F
|
||||
|
||||
|
||||
# Find valid second chars for this first char and add each combination to our possible encodings
|
||||
second_chars = nibble_chars[second_low_nibble]
|
||||
second_chars.each {|second_char| poss_encodings.push(second_char + first_char) }
|
||||
end
|
||||
|
||||
|
||||
if poss_encodings.empty?
|
||||
raise RuntimeError, "No encoding of #{"0x%.2X" % block} possible with limited character set"
|
||||
end
|
||||
|
||||
|
||||
# Return a random encoding
|
||||
poss_encodings[rand(poss_encodings.length)]
|
||||
end
|
||||
|
|
|
@ -8,12 +8,12 @@ module Encoder
|
|||
module Alpha2
|
||||
|
||||
class UnicodeMixed < Generic
|
||||
|
||||
|
||||
def self.gen_second(block, base)
|
||||
# unicode uses additive encoding
|
||||
(block - base)
|
||||
end
|
||||
|
||||
|
||||
def self.gen_decoder_prefix(reg, offset)
|
||||
if (offset > 21)
|
||||
raise "Critical: Offset is greater than 21"
|
||||
|
@ -27,7 +27,7 @@ class UnicodeMixed < Generic
|
|||
mod = 'AA' * (offset - 14) # inc ecx
|
||||
nop = 'CP' * (14 - mod.length)
|
||||
mod += nop
|
||||
end
|
||||
end
|
||||
regprefix = { # nops ignored below
|
||||
'EAX' => 'PPYA' + mod, # push eax, pop ecx
|
||||
'ECX' => mod + "4444", # dec ecx
|
||||
|
@ -91,7 +91,7 @@ class UnicodeMixed < Generic
|
|||
"1A" + # add [ecx], dh NOP
|
||||
"IA" + # dec ecx, NOP
|
||||
"J" + # dec edx
|
||||
"Q" + # add [ecx], dl
|
||||
"Q" + # add [ecx], dl
|
||||
"YA" + # pop ecx, NOP
|
||||
"Z" + # pop edx
|
||||
"B" + # add [edx], al
|
||||
|
@ -105,10 +105,10 @@ class UnicodeMixed < Generic
|
|||
"B" + # add [edx], al |
|
||||
"kM" + # imul eax, [eax], 10 * |
|
||||
"A" + # add [edx], al |
|
||||
"G" + # inc edi |
|
||||
"G" + # inc edi |
|
||||
"B" + # add [edx], al |
|
||||
"9" + # cmp [eax], eax |
|
||||
"u" + # jnz ------------------
|
||||
"u" + # jnz ------------------
|
||||
"4JB"
|
||||
|
||||
return decoder
|
||||
|
|
|
@ -9,7 +9,7 @@ module Alpha2
|
|||
|
||||
class UnicodeUpper < Generic
|
||||
def self.default_accepted_chars ; ('B' .. 'Z').to_a + ('0' .. '9').to_a ; end
|
||||
|
||||
|
||||
def self.gen_second(block, base)
|
||||
# unicode uses additive encoding
|
||||
(block - base)
|
||||
|
@ -40,7 +40,7 @@ class UnicodeUpper < Generic
|
|||
'ESI' => 'VVYA' + mod, # push esi, pop ecx
|
||||
'EDI' => 'WWYA' + mod, # push edi, pop edi
|
||||
'[ESP]' => 'YA' + mod + '44', #
|
||||
'[ESP+4]' => 'YUYA' + mod, #
|
||||
'[ESP+4]' => 'YUYA' + mod, #
|
||||
}
|
||||
|
||||
return regprefix[reg]
|
||||
|
|
|
@ -13,12 +13,12 @@ module Encoder
|
|||
@blocks_out = []
|
||||
@block_size = 0
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
def decoder_stub( state )
|
||||
|
||||
|
||||
if( not state.decoder_stub )
|
||||
@blocks_out = []
|
||||
@block_size = 0
|
||||
|
@ -28,34 +28,34 @@ module Encoder
|
|||
# anything too big (if we knew the max size we could try something smaller if we generated a blob too big)
|
||||
#block_sizes = (1..state.buf.length).to_a.shuffle
|
||||
#block_sizes.each do | len |
|
||||
|
||||
|
||||
1.upto( state.buf.length ) do | len |
|
||||
|
||||
|
||||
# For now we ignore all odd sizes to help with performance (The rex poly machine
|
||||
# doesnt have many load/store primitives that can handle byte sizes efficiently)
|
||||
if( len % 2 != 0 )
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
blocks, size = compute_encoded( state, len )
|
||||
if( blocks and size )
|
||||
|
||||
|
||||
# We sanity check that the newly generated block ammount and the block size
|
||||
# are not in the badchar list when converted into a hex form. Helps speed
|
||||
# things up a great deal when generating a decoder stub later as these
|
||||
# values may be used throughout.
|
||||
|
||||
|
||||
if( not number_is_valid?( state, blocks.length - 1 ) or not number_is_valid?( state, ~( blocks.length - 1 ) ) )
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
if( not number_is_valid?( state, size ) or not number_is_valid?( state, ~size ) )
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
@blocks_out = blocks
|
||||
@block_size = size
|
||||
|
||||
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -64,26 +64,26 @@ module Encoder
|
|||
|
||||
state.decoder_stub = compute_decoder( state )
|
||||
end
|
||||
|
||||
|
||||
state.decoder_stub
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
def encode_block( state, data )
|
||||
|
||||
|
||||
buffer = ''
|
||||
|
||||
|
||||
@blocks_out.each do | block |
|
||||
buffer << block.pack( 'C*' )
|
||||
end
|
||||
|
||||
|
||||
buffer
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
#
|
||||
# Is a number in its byte form valid against the badchars?
|
||||
#
|
||||
|
@ -96,7 +96,7 @@ module Encoder
|
|||
end
|
||||
return Rex::Text.badchar_index( [ number ].pack( size ), state.badchars ).nil?
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Calculate Shannon's entropy.
|
||||
#
|
||||
|
@ -110,44 +110,44 @@ module Encoder
|
|||
end
|
||||
return entropy / 8
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Compute the encoded blocks (and associated seed)
|
||||
#
|
||||
def compute_encoded( state, len )
|
||||
|
||||
blocks_in = ::Array.new
|
||||
|
||||
|
||||
input = '' << state.buf
|
||||
|
||||
|
||||
block_padding = ( input.length % len ) > 0 ? len - ( input.length % len ) : 0
|
||||
|
||||
|
||||
if( block_padding > 0 )
|
||||
0.upto( block_padding-1 ) do
|
||||
input << [ rand( 255 ) ].pack( 'C' )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
while( input.length > 0 )
|
||||
blocks_in << input[0..len-1].unpack( 'C*' )
|
||||
input = input[len..input.length]
|
||||
end
|
||||
|
||||
|
||||
seed = compute_seed( blocks_in, len, block_padding, state.badchars.unpack( 'C*' ) )
|
||||
|
||||
if( not seed )
|
||||
return [ nil, nil ]
|
||||
end
|
||||
|
||||
|
||||
blocks_out = [ seed ]
|
||||
|
||||
|
||||
blocks_in.each do | block |
|
||||
blocks_out << compute_block( blocks_out.last, block )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
return [ blocks_out, len ]
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Generate the decoder stub which is functionally equivalent to the following:
|
||||
#
|
||||
|
@ -166,13 +166,13 @@ module Encoder
|
|||
# end:
|
||||
#
|
||||
def compute_decoder( state )
|
||||
|
||||
|
||||
@machine.create_variable( 'source' )
|
||||
@machine.create_variable( 'dest' )
|
||||
@machine.create_variable( 'counter' )
|
||||
@machine.create_variable( 'encoded' )
|
||||
@machine.create_variable( 'decoded' )
|
||||
|
||||
|
||||
chunk_size = Rex::Poly::Machine::BYTE
|
||||
if( @machine.native_size() == Rex::Poly::Machine::QWORD )
|
||||
if( @block_size % Rex::Poly::Machine::QWORD == 0 )
|
||||
|
@ -181,13 +181,13 @@ module Encoder
|
|||
chunk_size = Rex::Poly::Machine::DWORD
|
||||
elsif( @block_size % Rex::Poly::Machine::WORD == 0 )
|
||||
chunk_size = Rex::Poly::Machine::WORD
|
||||
end
|
||||
end
|
||||
elsif( @machine.native_size() == Rex::Poly::Machine::DWORD )
|
||||
if( @block_size % Rex::Poly::Machine::DWORD == 0 )
|
||||
chunk_size = Rex::Poly::Machine::DWORD
|
||||
elsif( @block_size % Rex::Poly::Machine::WORD == 0 )
|
||||
chunk_size = Rex::Poly::Machine::WORD
|
||||
end
|
||||
end
|
||||
elsif( @machine.native_size() == Rex::Poly::Machine::WORD )
|
||||
if( @block_size % Rex::Poly::Machine::WORD == 0 )
|
||||
chunk_size = Rex::Poly::Machine::WORD
|
||||
|
@ -202,7 +202,7 @@ module Encoder
|
|||
|
||||
# Block 3 - Set the destingation variable to the value of the source variable
|
||||
@machine.create_block_primitive( 'block3', 'set', 'dest', 'source' )
|
||||
|
||||
|
||||
# Block 4 - Set the destingation variable to the address of the 2nd encoded block
|
||||
@machine.create_block_primitive( 'block4', 'add', 'dest', @block_size )
|
||||
|
||||
|
@ -211,35 +211,35 @@ module Encoder
|
|||
|
||||
# Block 6 - Set the encoded variable to the byte pointed to by the dest variable
|
||||
@machine.create_block_primitive( 'block6', 'load', 'encoded', 'dest', chunk_size )
|
||||
|
||||
|
||||
# Block 7 - Increment the destination variable by one
|
||||
@machine.create_block_primitive( 'block7', 'add', 'dest', chunk_size )
|
||||
|
||||
|
||||
# Block 8 - Set the decoded variable to the byte pointed to by the source variable
|
||||
@machine.create_block_primitive( 'block8', 'load', 'decoded', 'source', chunk_size )
|
||||
|
||||
|
||||
# Block 9 - Xor the decoded variable with the encoded variable
|
||||
@machine.create_block_primitive( 'block9', 'xor', 'decoded', 'encoded' )
|
||||
|
||||
|
||||
# Block 10 - store the newly decoded byte
|
||||
@machine.create_block_primitive( 'block10', 'store', 'source', 'decoded', chunk_size )
|
||||
|
||||
|
||||
# Block 11 - Increment the source variable by one
|
||||
@machine.create_block_primitive( 'block11', 'add', 'source', chunk_size )
|
||||
|
||||
|
||||
# Block 12 - Jump back up to the outer_loop block while the counter variable > 0
|
||||
@machine.create_block_primitive( 'block12', 'loop', 'counter', 'block6' )
|
||||
|
||||
# Try to generate the decoder stub...
|
||||
decoder = @machine.generate
|
||||
|
||||
|
||||
if( not decoder )
|
||||
raise RuntimeError, "Unable to generate decoder stub."
|
||||
end
|
||||
|
||||
|
||||
decoder
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Compute the seed block which will successfully decode all proceeding encoded
|
||||
# blocks while ensuring the encoded blocks do not contain any badchars.
|
||||
|
@ -247,33 +247,33 @@ module Encoder
|
|||
def compute_seed( blocks_in, block_size, block_padding, badchars )
|
||||
seed = []
|
||||
redo_bytes = []
|
||||
|
||||
|
||||
0.upto( block_size-1 ) do | index |
|
||||
|
||||
|
||||
seed_bytes = (0..255).sort_by do
|
||||
rand()
|
||||
end
|
||||
|
||||
|
||||
seed_bytes.each do | seed_byte |
|
||||
|
||||
|
||||
next if( badchars.include?( seed_byte ) )
|
||||
|
||||
|
||||
success = true
|
||||
|
||||
|
||||
previous_byte = seed_byte
|
||||
|
||||
|
||||
if( redo_bytes.length < 256 )
|
||||
redo_bytes = (0..255).sort_by do
|
||||
rand()
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
blocks_in.each do | block |
|
||||
|
||||
|
||||
decoded_byte = block[ index ]
|
||||
|
||||
|
||||
encoded_byte = previous_byte ^ decoded_byte
|
||||
|
||||
|
||||
if( badchars.include?( encoded_byte ) )
|
||||
# the padding bytes we added earlier can be changed if they are causing us to fail.
|
||||
if( block == blocks_in.last and index >= (block_size-block_padding) )
|
||||
|
@ -284,31 +284,31 @@ module Encoder
|
|||
block[ index ] = redo_bytes.shift
|
||||
redo
|
||||
end
|
||||
|
||||
|
||||
success = false
|
||||
break
|
||||
end
|
||||
|
||||
|
||||
previous_byte = encoded_byte
|
||||
end
|
||||
|
||||
|
||||
if( success )
|
||||
seed << seed_byte
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
if( seed.length == block_size )
|
||||
return seed
|
||||
end
|
||||
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
#
|
||||
# Compute the next encoded block by xoring the previous
|
||||
# Compute the next encoded block by xoring the previous
|
||||
# encoded block with the next decoded block.
|
||||
#
|
||||
def compute_block( encoded, decoded )
|
||||
|
@ -318,9 +318,9 @@ module Encoder
|
|||
end
|
||||
return block
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ class NonAlpha
|
|||
if (tablelen > 255) or (block == 0x7B)
|
||||
raise RuntimeError, "BadChar"
|
||||
end
|
||||
|
||||
|
||||
if (block >= 0x41 and block <= 0x5A) or (block >= 0x61 and block <= 0x7A)
|
||||
# gen offset, return magic
|
||||
offset = 0x7b - block;
|
||||
|
|
|
@ -7,8 +7,8 @@ module Rex
|
|||
module Encoder
|
||||
|
||||
class NonUpper
|
||||
|
||||
|
||||
|
||||
|
||||
def NonUpper.gen_decoder()
|
||||
decoder =
|
||||
"\x66\xB9\xFF\xFF" +
|
||||
|
@ -26,14 +26,14 @@ class NonUpper
|
|||
"\x28\x07" + # subb [edi], al
|
||||
"\xEB\xF1" + # jmp BACK!
|
||||
"\xEB" + "B" + # jmp [shellcode]
|
||||
"\xE8\xE2\xFF\xFF\xFF"
|
||||
"\xE8\xE2\xFF\xFF\xFF"
|
||||
end
|
||||
|
||||
def NonUpper.encode_byte(badchars, block, table, tablelen)
|
||||
if (tablelen > 255) or (block == 0x40)
|
||||
raise RuntimeError, "BadChar"
|
||||
end
|
||||
|
||||
|
||||
if (block >= 0x41 and block <= 0x40) or (badchars =~ block)
|
||||
# gen offset, return magic
|
||||
offset = 0x40 - block;
|
||||
|
|
|
@ -19,7 +19,7 @@ class Generic
|
|||
|
||||
#
|
||||
# Now for some internal check methods
|
||||
#
|
||||
#
|
||||
|
||||
# hook stylies!
|
||||
# return index of offending byte or nil
|
||||
|
@ -82,7 +82,7 @@ class Generic
|
|||
if !badkeys[strip][kbyte] && !badchars[kbyte.chr]
|
||||
throw :found_kbyte
|
||||
end
|
||||
|
||||
|
||||
kbyte = (kbyte + 1) & 0xff
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ class Disk < ImageSource
|
|||
file.seek(file_offset + offset)
|
||||
file.read(len)
|
||||
end
|
||||
|
||||
|
||||
def index(search, offset = 0)
|
||||
# do a sliding window search across the disk
|
||||
while offset < size
|
||||
|
|
|
@ -39,7 +39,7 @@ class ImageSource
|
|||
end
|
||||
return string
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ module DatagramAbstraction
|
|||
attr_reader :lsock
|
||||
# The right side of the stream (remote)
|
||||
attr_reader :rsock
|
||||
|
||||
|
||||
protected
|
||||
attr_writer :lsock
|
||||
attr_writer :rsock
|
||||
|
|
|
@ -36,7 +36,7 @@ module Stream
|
|||
total_sent = 0
|
||||
total_length = buf.length
|
||||
block_size = 32768
|
||||
|
||||
|
||||
begin
|
||||
while( total_sent < total_length )
|
||||
s = Rex::ThreadSafe.select( nil, [ fd ], nil, 0.2 )
|
||||
|
@ -59,7 +59,7 @@ module Stream
|
|||
rescue ::IOError, ::Errno::EPIPE
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
total_sent
|
||||
end
|
||||
|
||||
|
@ -67,9 +67,9 @@ module Stream
|
|||
# This method reads data of the supplied length from the stream.
|
||||
#
|
||||
def read(length = nil, opts = {})
|
||||
|
||||
|
||||
begin
|
||||
return fd.read_nonblock( length )
|
||||
return fd.read_nonblock( length )
|
||||
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
||||
# Sleep for a half a second, or until we can read again
|
||||
Rex::ThreadSafe.select( [ fd ], nil, nil, 0.5 )
|
||||
|
|
|
@ -74,14 +74,14 @@ module StreamAbstraction
|
|||
def syswrite(buffer)
|
||||
lsock.syswrite(buffer)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Low-level read from the local side.
|
||||
#
|
||||
def sysread(length)
|
||||
lsock.sysread(length)
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Shuts down the local side of the stream abstraction.
|
||||
#
|
||||
|
@ -164,7 +164,7 @@ protected
|
|||
while( total_sent < total_length )
|
||||
begin
|
||||
data = buf[total_sent, buf.length]
|
||||
|
||||
|
||||
# Note that this must be write() NOT syswrite() or put() or anything like it.
|
||||
# Using syswrite() breaks SSL streams.
|
||||
sent = self.write( data )
|
||||
|
|
|
@ -156,7 +156,7 @@ protected
|
|||
|
||||
# Initialize the connection processing
|
||||
on_client_connect(cli)
|
||||
|
||||
|
||||
# Notify the client monitor
|
||||
self.client_waiter.push(cli)
|
||||
|
||||
|
@ -178,7 +178,7 @@ protected
|
|||
#
|
||||
def monitor_clients
|
||||
begin
|
||||
|
||||
|
||||
# Wait for a notify if our client list is empty
|
||||
if (clients.length == 0)
|
||||
self.client_waiter.pop
|
||||
|
|
|
@ -189,7 +189,7 @@ class JobContainer < Hash
|
|||
end
|
||||
list.each(&block)
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
attr_accessor :job_id_pool # :nodoc:
|
||||
|
|
|
@ -33,7 +33,7 @@ class Stderr
|
|||
end
|
||||
$stderr.write("[#{get_current_timestamp}] [#{code}(#{level})] #{src}: #{msg}\n")
|
||||
end
|
||||
|
||||
|
||||
$stderr.flush
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ module Oui
|
|||
return fullname
|
||||
else
|
||||
return 'UNKNOWN'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.lookup_oui_company_name(mac)
|
||||
|
@ -25,7 +25,7 @@ module Oui
|
|||
return fullname
|
||||
else
|
||||
return 'UNKNOWN'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def self.check_mac(mac)
|
||||
|
|
|
@ -4,7 +4,7 @@ module MIME
|
|||
class Part
|
||||
|
||||
require 'rex/mime/header'
|
||||
|
||||
|
||||
attr_accessor :header, :content
|
||||
|
||||
def initialize
|
||||
|
|
|
@ -61,7 +61,7 @@ class Opty2
|
|||
# Skip it if it's masked off or too large
|
||||
next if ((e & mask) != 0)
|
||||
next if (((e >> 8) & 0xff) > slen)
|
||||
|
||||
|
||||
byte = e & 0xff
|
||||
|
||||
# Skip it if it's a bad byte
|
||||
|
|
|
@ -18,7 +18,7 @@ module Opty2Tables
|
|||
66005,65750,245,248,249,252,253,359
|
||||
]
|
||||
|
||||
StateTable =
|
||||
StateTable =
|
||||
[
|
||||
# 0x00
|
||||
[[65796,66565,1048582,65804,66573,1048590,65812,66581,1048598,65820,66589,1048606,65828,66597,65575,65836,66605,65583,65844,66613,65591,316,1085,65599,65600,131137,262210,524355,1048644,2097221,4194374,8388679,65608,131145,262218,524363,1048652,2097229,4194382,8388687,1048656,1048657,1048658,1048659,1048660,1048661,1048662,1048663,1114200,1179737,1310810,1572955,1048668,3145821,5242974,9437279,1048672,1049704,1048938,368,369,370,371,372,373,374,375,376,377,378,379,380,381,382,383,144,196753,327826,589971,1114260,2162837,4259990,8454295,65688,262297,155,1048732,65695,424,1193,65968,131505,262578,524723,65972,131509,262582,524727,66744,132281,263354,525499,1049788,2098365,4195518,8389823,66005,65750,131552,131553,131554,483,491,245,248,249,252,253,358,359, 0x01018D]],
|
||||
|
|
|
@ -29,7 +29,7 @@ class Directory < DirEntry
|
|||
@num_entries = 1
|
||||
end
|
||||
|
||||
|
||||
|
||||
# woop, recursive each
|
||||
def yield_entries(de, &block)
|
||||
block.call(de)
|
||||
|
|
|
@ -8,7 +8,7 @@ module Parser
|
|||
load_nokogiri && class FusionVMDocument < Nokogiri::XML::SAX::Document
|
||||
|
||||
|
||||
include NokogiriDocMixin
|
||||
include NokogiriDocMixin
|
||||
|
||||
def start_element(name=nil,attrs=[])
|
||||
return nil if in_tag("JobOrder")
|
||||
|
@ -26,7 +26,7 @@ module Parser
|
|||
}
|
||||
thost[:host] = attrs["IPAddress"]
|
||||
thost[:name] = attrs["HostName"]
|
||||
@host = db_report(:host, thost)
|
||||
@host = db_report(:host, thost)
|
||||
when "OS"
|
||||
@state[:has_text] = true
|
||||
when "Port"
|
||||
|
@ -47,7 +47,7 @@ module Parser
|
|||
when "Title"
|
||||
@state[:has_text] = true
|
||||
when "Description"
|
||||
@state[:has_text] = true
|
||||
@state[:has_text] = true
|
||||
when "CVE"
|
||||
@state[:has_text] = true
|
||||
when "References"
|
||||
|
@ -86,13 +86,13 @@ module Parser
|
|||
when "CVE"
|
||||
@vuln[:refs] << "CVE-#{@text.strip}"
|
||||
when "References"
|
||||
unless @text.blank?
|
||||
unless @text.blank?
|
||||
@text.split(' ').each do |ref|
|
||||
next unless ref.start_with? "http"
|
||||
if ref =~ /MS\d{2}-\d{3}/
|
||||
@vuln[:refs] << "MSB-#{$&}"
|
||||
else
|
||||
@vuln[:refs] << "URL-#{ref.strip}"
|
||||
else
|
||||
@vuln[:refs] << "URL-#{ref.strip}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -106,4 +106,4 @@ module Parser
|
|||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ class Ini < Hash
|
|||
# Factories
|
||||
#
|
||||
##
|
||||
|
||||
|
||||
#
|
||||
# Creates a new class instance and reads in the contents of the supplied
|
||||
# file path.
|
||||
|
@ -52,7 +52,7 @@ class Ini < Hash
|
|||
#
|
||||
# Enumerates the groups hash keys.
|
||||
#
|
||||
def each_group(&block)
|
||||
def each_group(&block)
|
||||
self.keys.each { |k|
|
||||
yield
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ class Ini < Hash
|
|||
#
|
||||
def from_file(fpath = nil)
|
||||
fpath = path if (!fpath)
|
||||
|
||||
|
||||
read_groups(fpath)
|
||||
end
|
||||
|
||||
|
@ -167,7 +167,7 @@ protected
|
|||
|
||||
# Is it a group [bob]?
|
||||
if (md = line.match(/^\[(.+?)\]/))
|
||||
active_group = md[1]
|
||||
active_group = md[1]
|
||||
self[md[1]] = {}
|
||||
# Is it a VAR=VAL?
|
||||
elsif (md = line.match(/^(.+?)=(.*)$/))
|
||||
|
|
|
@ -7,7 +7,7 @@ module Parser
|
|||
|
||||
|
||||
class IP360ASPLXMLStreamParser
|
||||
|
||||
|
||||
@vulnid = nil
|
||||
@appid = nil
|
||||
@location = nil
|
||||
|
@ -49,7 +49,7 @@ class IP360ASPLXMLStreamParser
|
|||
@osid = attributes['id'].strip
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def text(str)
|
||||
case @state
|
||||
when :is_name
|
||||
|
|
|
@ -13,7 +13,7 @@ module Rex
|
|||
attr_reader :tests
|
||||
|
||||
NEXPOSE_HOST_DETAIL_FIELDS = %W{ nx_device_id nx_site_name nx_site_importance nx_scan_template nx_risk_score }
|
||||
NEXPOSE_VULN_DETAIL_FIELDS = %W{
|
||||
NEXPOSE_VULN_DETAIL_FIELDS = %W{
|
||||
nx_scan_id
|
||||
nx_vulnerable_since
|
||||
nx_pci_compliance_status
|
||||
|
@ -115,7 +115,7 @@ module Rex
|
|||
when "solution"
|
||||
@state[:has_text] = false
|
||||
collect_vuln_solution
|
||||
@text = nil
|
||||
@text = nil
|
||||
when "tag"
|
||||
@state[:has_text] = false
|
||||
collect_tag
|
||||
|
@ -217,20 +217,20 @@ module Rex
|
|||
# Mass update vulnerability details across the database based on conditions
|
||||
vdet_info = { :title => @report_data[:vuln]["title"] }
|
||||
vdet_info[:description] = @report_data[:vuln_description] unless @report_data[:vuln_description].to_s.empty?
|
||||
vdet_info[:solution] = @report_data[:vuln_solution] unless @report_data[:vuln_solution].to_s.empty?
|
||||
vdet_info[:solution] = @report_data[:vuln_solution] unless @report_data[:vuln_solution].to_s.empty?
|
||||
vdet_info[:nx_tags] = @report_data[:vuln_tags].sort.uniq.join(", ") if ( @report_data[:vuln_tags].kind_of?(::Array) and @report_data[:vuln_tags].length > 0 )
|
||||
vdet_info[:nx_severity] = @report_data[:vuln]["severity"].to_f if @report_data[:vuln]["severity"]
|
||||
vdet_info[:nx_pci_severity] = @report_data[:vuln]["pciSeverity"].to_f if @report_data[:vuln]["pciSeverity"]
|
||||
vdet_info[:cvss_score] = @report_data[:vuln]["cvssScore"].to_f if @report_data[:vuln]["cvssScore"]
|
||||
vdet_info[:cvss_vector] = @report_data[:vuln]["cvssVector"] if @report_data[:vuln]["cvssVector"]
|
||||
|
||||
|
||||
%W{ published added modified }.each do |tf|
|
||||
next if not @report_data[:vuln][tf]
|
||||
ts = DateTime.parse(@report_data[:vuln][tf]) rescue nil
|
||||
next if not ts
|
||||
vdet_info[ "nx_#{tf}".to_sym ] = ts
|
||||
end
|
||||
|
||||
|
||||
::Mdm::VulnDetail.where(:id => vdet_ids).update_all(vdet_info)
|
||||
|
||||
@report_data[:vuln] = nil
|
||||
|
@ -263,7 +263,7 @@ module Rex
|
|||
end
|
||||
|
||||
|
||||
def record_formatted_content(name, eattrs)
|
||||
def record_formatted_content(name, eattrs)
|
||||
attrs = attr_hash(eattrs)
|
||||
stack = nil
|
||||
|
||||
|
@ -293,7 +293,7 @@ module Rex
|
|||
when 'URLLink'
|
||||
@report_data[:formatted_link] = attrs["LinkURL"]
|
||||
else
|
||||
|
||||
|
||||
if @report_data[:formatted_indent] > 1
|
||||
data = (" " * (@report_data[:formatted_indent])) + data
|
||||
end
|
||||
|
@ -305,10 +305,10 @@ module Rex
|
|||
|
||||
if data.length > 0
|
||||
stack << data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def collect_formatted_content(name)
|
||||
def collect_formatted_content(name)
|
||||
stack = nil
|
||||
prefix = ""
|
||||
|
||||
|
@ -325,7 +325,7 @@ module Rex
|
|||
end
|
||||
|
||||
return if not stack
|
||||
|
||||
|
||||
data = @text.to_s.strip.split(/\n+/).map{|t| t.strip}.join(" ")
|
||||
@text = ""
|
||||
|
||||
|
@ -385,7 +385,7 @@ module Rex
|
|||
# This hash defines the matching criteria to overwrite an existing entry
|
||||
vkey = { :src => 'nexpose', :nx_vuln_id => @state[:test][:id] }
|
||||
|
||||
if @state[:nx_device_id]
|
||||
if @state[:nx_device_id]
|
||||
vdet[:nx_device_id] = @state[:nx_device_id]
|
||||
vkey[:nx_device_id] = @state[:nx_device_id]
|
||||
end
|
||||
|
@ -405,12 +405,12 @@ module Rex
|
|||
ts = ::DateTime.parse(@state[:test][:nx_vulnerable_since]) rescue nil
|
||||
vdet[:nx_vulnerable_since] = ts if ts
|
||||
end
|
||||
|
||||
|
||||
proof = clean_formatted_text(@report_data[:vuln_proof_stack].join.strip)
|
||||
@report_data[:vuln_proof_stack] = []
|
||||
|
||||
vuln_info[:info] = proof
|
||||
vdet[:proof] = proof
|
||||
vdet[:proof] = proof
|
||||
|
||||
# Configure the find key for vuln_details
|
||||
vdet[:key] = vkey
|
||||
|
@ -423,7 +423,7 @@ module Rex
|
|||
|
||||
# Report the vulnerability
|
||||
vuln = db.report_vuln(vuln_info)
|
||||
|
||||
|
||||
if vuln
|
||||
# Report the vulnerability details
|
||||
detail = db.report_vuln_details(vuln, vdet)
|
||||
|
@ -652,12 +652,12 @@ module Rex
|
|||
if host_object
|
||||
db.report_import_note(host_object.workspace, host_object)
|
||||
if device_id
|
||||
detail = {
|
||||
:key => { :src => 'nexpose' },
|
||||
detail = {
|
||||
:key => { :src => 'nexpose' },
|
||||
:src => 'nexpose',
|
||||
:nx_device_id => device_id
|
||||
:nx_device_id => device_id
|
||||
}
|
||||
detail[:nx_console_id] = @nx_console_id if @nx_console_id
|
||||
detail[:nx_console_id] = @nx_console_id if @nx_console_id
|
||||
|
||||
NEXPOSE_HOST_DETAIL_FIELDS.each do |f|
|
||||
v = @report_data.delete(f.to_sym)
|
||||
|
|
|
@ -102,7 +102,7 @@ module Parser
|
|||
return [] unless orig_refs
|
||||
refs = []
|
||||
orig_refs.each do |ref_hash|
|
||||
|
||||
|
||||
ref_hash_sym = Hash[ref_hash.map {|k, v| [k.to_sym, v] }]
|
||||
ref_type = ref_hash_sym[:source].to_s.strip.upcase
|
||||
ref_value = ref_hash_sym[:value].to_s.strip
|
||||
|
|
|
@ -17,7 +17,7 @@ class RetinaXMLStreamParser
|
|||
@host = { 'vulns' => [] }
|
||||
reset_audit_state
|
||||
end
|
||||
|
||||
|
||||
def reset_audit_state
|
||||
@audit = { 'refs' => [] }
|
||||
end
|
||||
|
@ -106,5 +106,5 @@ __END__
|
|||
</audit>
|
||||
</host>
|
||||
</hosts>
|
||||
</scanJob>
|
||||
</scanJob>
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ module Rex
|
|||
def report_vuln(&block)
|
||||
proto = @state[:url].split(":")[0]
|
||||
path = '/' + (@state[:url].split("/")[3..(@state[:url].split("/").length - 1)].join('/'))
|
||||
|
||||
|
||||
web_vuln_info = {}
|
||||
web_vuln_info[:web_site] = proto + "://" + @state[:host] + ":" + @state[:port]
|
||||
web_vuln_info[:path] = path
|
||||
|
@ -85,7 +85,7 @@ module Rex
|
|||
elsif param.index("alert")
|
||||
web_vuln_info[:pname] = param.split('=')[0] #xss
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
web_vuln_info[:host] = @state[:host]
|
||||
web_vuln_info[:port] = @state[:port]
|
||||
|
|
|
@ -23,7 +23,7 @@ module Recovery
|
|||
# Infinite 'hlt' loop.
|
||||
#
|
||||
def self.spin(opts = {})
|
||||
"\xf4\xeb\xfd"
|
||||
"\xf4\xeb\xfd"
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -24,11 +24,11 @@ class PeMemDump < Pe
|
|||
end
|
||||
|
||||
def self.new_from_file(filename, disk_backed = false)
|
||||
|
||||
|
||||
if filename[-4, 4] != '.rng'
|
||||
raise "Not a .rng file: #{filename}"
|
||||
end
|
||||
|
||||
|
||||
if filename[-9, 9] == "index.rng"
|
||||
raise SkipError
|
||||
end
|
||||
|
@ -51,7 +51,7 @@ class PeMemDump < Pe
|
|||
self.sections = [ self.header_section ]
|
||||
self.image_base = 0
|
||||
end
|
||||
|
||||
|
||||
def all_sections
|
||||
self.sections
|
||||
end
|
||||
|
|
|
@ -48,7 +48,7 @@ class Section
|
|||
return nil if !_section_header
|
||||
_section_header.v['Characteristics']
|
||||
end
|
||||
|
||||
|
||||
def vma
|
||||
# a section header is not required
|
||||
return nil if !_section_header
|
||||
|
@ -59,8 +59,8 @@ class Section
|
|||
# a section header is not required
|
||||
return nil if !_section_header
|
||||
_section_header.v['SizeOfRawData']
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def _check_offset(offset, len = 1)
|
||||
if offset < 0 || offset+len > size
|
||||
raise BoundsError, "Offset #{offset} outside of section", caller
|
||||
|
|
|
@ -32,7 +32,7 @@ module Scanner
|
|||
if(param['disasm'])
|
||||
#puts [msg].pack('H*').inspect
|
||||
insns = []
|
||||
|
||||
|
||||
msg.gsub!("; ", "\n")
|
||||
if msg.include?("retn")
|
||||
msg.gsub!("retn", "ret")
|
||||
|
|
|
@ -4,36 +4,36 @@ module PeScan
|
|||
module Search
|
||||
|
||||
require "rex/assembly/nasm"
|
||||
|
||||
|
||||
class DumpRVA
|
||||
attr_accessor :pe
|
||||
|
||||
|
||||
def initialize(pe)
|
||||
self.pe = pe
|
||||
end
|
||||
|
||||
|
||||
def config(param)
|
||||
@address = pe.vma_to_rva(param['args'])
|
||||
end
|
||||
|
||||
|
||||
def scan(param)
|
||||
config(param)
|
||||
|
||||
|
||||
$stdout.puts "[#{param['file']}]"
|
||||
|
||||
|
||||
# Adjust based on -A and -B flags
|
||||
pre = param['before'] || 0
|
||||
suf = param['after'] || 16
|
||||
|
||||
|
||||
@address -= pre
|
||||
@address = 0 if (@address < 0 || ! @address)
|
||||
|
||||
|
||||
begin
|
||||
buf = pe.read_rva(@address, suf)
|
||||
rescue ::Rex::PeParsey::WtfError
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
$stdout.puts pe.ptr_s(pe.rva_to_vma(@address)) + " " + buf.unpack("H*")[0]
|
||||
if(param['disasm'])
|
||||
insns = []
|
||||
|
@ -51,8 +51,8 @@ module Search
|
|||
addr = di.next_addr
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
class DumpOffset < DumpRVA
|
||||
|
@ -62,7 +62,7 @@ module Search
|
|||
rescue Rex::PeParsey::BoundsError
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,7 @@ module Windows
|
|||
HKEY_LOCAL_MACHINE
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,10 +3,10 @@ module Rex
|
|||
|
||||
module Poly
|
||||
|
||||
require 'metasm'
|
||||
require 'metasm'
|
||||
require 'rex/poly/machine/machine'
|
||||
require 'rex/poly/machine/x86'
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -2,29 +2,29 @@
|
|||
module Rex
|
||||
|
||||
module Poly
|
||||
|
||||
|
||||
#
|
||||
# A machine capable of creating a small blob of code in a metamorphic kind of way.
|
||||
# Note: this is designed to perform an exhaustive search for a solution and can be
|
||||
# slow. If you need a speedier option, the origional Rex::Polly::Block stuff is a
|
||||
# slow. If you need a speedier option, the origional Rex::Polly::Block stuff is a
|
||||
# better choice.
|
||||
#
|
||||
class Machine
|
||||
|
||||
|
||||
QWORD = 8
|
||||
DWORD = 4
|
||||
WORD = 2
|
||||
BYTE = 1
|
||||
|
||||
|
||||
#
|
||||
# A Permutation!
|
||||
#
|
||||
class Permutation
|
||||
|
||||
|
||||
attr_accessor :active, :offset
|
||||
|
||||
|
||||
attr_reader :name, :primitive, :length, :args
|
||||
|
||||
|
||||
#
|
||||
# Create a new permutation object.
|
||||
#
|
||||
|
@ -40,14 +40,14 @@ module Rex
|
|||
@offset = 0
|
||||
@children = ::Array.new
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Add in a child permutation to this one. Used to build the permutation tree.
|
||||
#
|
||||
def add_child( child )
|
||||
@children << child
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Does this permutation have children?
|
||||
#
|
||||
|
@ -62,7 +62,7 @@ module Rex
|
|||
def remove_children
|
||||
@children.clear
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Actully render this permutation into a raw buffer.
|
||||
#
|
||||
|
@ -107,12 +107,12 @@ module Rex
|
|||
end
|
||||
# Update the length to reflect the new raw buffer
|
||||
@length = raw.to_s.length
|
||||
# As the temp variable is only assigned for the duration of a single permutation we
|
||||
# As the temp variable is only assigned for the duration of a single permutation we
|
||||
# can now release it if it was used in this permutation.
|
||||
@machine.release_temp_variable
|
||||
return raw.to_s
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Test if this permutation raw buffer is valid in this machine (e.g. against the badchar list).
|
||||
#
|
||||
|
@ -132,10 +132,10 @@ module Rex
|
|||
# Should a temporary variable have been assigned we can release it here.
|
||||
@machine.release_temp_variable
|
||||
end
|
||||
end
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Try to find a solution within the solution space by performing a depth first search
|
||||
# into the permutation tree and backtracking when needed.
|
||||
|
@ -172,9 +172,9 @@ module Rex
|
|||
# No children can be made form part of the solution, return failure for this path in the tree.
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# A symbolic permutation to mark locations like the begining and end of a group of blocks.
|
||||
# Used to calculate usefull offsets.
|
||||
|
@ -189,7 +189,7 @@ module Rex
|
|||
# A symbolic block is allways active!
|
||||
@active = true
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# We block all attempts to set the active state of this permutation so as
|
||||
# it is always true. This lets us always address the offset.
|
||||
|
@ -197,76 +197,76 @@ module Rex
|
|||
def active=( value )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# A primitive is a machine defined permutation which accepts some arguments when it is called.
|
||||
#
|
||||
class Primitive
|
||||
|
||||
|
||||
#
|
||||
# Initialize this primitive with its target source procedure and the machine it belongs to.
|
||||
#
|
||||
def initialize( source )
|
||||
@source = source
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Call the primitives source procedure, passing in the arguments.
|
||||
#
|
||||
def call( name, machine, *args )
|
||||
return @source.call( name, machine, *args )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
class Block
|
||||
|
||||
|
||||
#attr_accessor :next, :previous
|
||||
attr_reader :name
|
||||
|
||||
|
||||
def initialize( name )
|
||||
@name = name
|
||||
@next = nil
|
||||
@previous = nil
|
||||
@permutations = ::Array.new
|
||||
end
|
||||
|
||||
|
||||
def shuffle
|
||||
@permutations = @permutations.shuffle
|
||||
end
|
||||
|
||||
|
||||
def solve
|
||||
@permutations.first.solve
|
||||
end
|
||||
|
||||
|
||||
def << ( permutation )
|
||||
@permutations << permutation
|
||||
end
|
||||
|
||||
|
||||
def each
|
||||
@permutations.each do | permutation |
|
||||
yield permutation
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# A class to hold a solution for a Rex::Poly::Machine problem.
|
||||
#
|
||||
class Solution
|
||||
|
||||
|
||||
attr_reader :offset
|
||||
|
||||
|
||||
def initialize
|
||||
@permutations = ::Array.new
|
||||
@reg_state = ::Array.new
|
||||
@offset = 0
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Reset this solution to an empty state.
|
||||
#
|
||||
|
@ -279,7 +279,7 @@ module Rex
|
|||
@permutations.clear
|
||||
@reg_state.clear
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Push a new permutation onto this solutions permutations list and save the associated register/variables state
|
||||
#
|
||||
|
@ -290,7 +290,7 @@ module Rex
|
|||
@permutations.push( permutation )
|
||||
@reg_state.push( [ [].concat(reg_available), [].concat(reg_consumed), {}.merge(variables) ] )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Pop off the last permutaion and register/variables state from this solution.
|
||||
#
|
||||
|
@ -342,45 +342,45 @@ module Rex
|
|||
end
|
||||
return raw
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a new machine instance.
|
||||
#
|
||||
def initialize( badchars, cpu )
|
||||
@badchars = badchars
|
||||
@cpu = cpu
|
||||
|
||||
|
||||
@reg_available = ::Array.new
|
||||
@reg_consumed = ::Array.new
|
||||
@variables = ::Hash.new
|
||||
@blocks = ::Hash.new
|
||||
@primitives = ::Hash.new
|
||||
@solution = Solution.new
|
||||
|
||||
|
||||
_create_primitives
|
||||
|
||||
|
||||
@blocks['begin'] = Block.new( 'begin' )
|
||||
@blocks['begin'] << SymbolicPermutation.new( 'begin', self )
|
||||
|
||||
|
||||
_create_variable( 'temp' )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Overloaded by a subclass to return the maximum native general register size supported.
|
||||
#
|
||||
def native_size
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Use METASM to assemble a line of asm using this machines current cpu.
|
||||
#
|
||||
def assemble( asm )
|
||||
return Metasm::Shellcode.assemble( @cpu, asm ).encode_string
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Check if a data blob is valid against the badchar list (or perform any other validation here)
|
||||
#
|
||||
|
@ -390,7 +390,7 @@ module Rex
|
|||
end
|
||||
return Rex::Text.badchar_index( data, @badchars ).nil?
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Generate a 64 bit number whoes bytes are valid in this machine.
|
||||
#
|
||||
|
@ -418,7 +418,7 @@ module Rex
|
|||
def make_safe_byte( number=nil )
|
||||
return _make_safe_number( BYTE, number ) & 0xFF
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a variable by name which will be assigned a register during generation. We can
|
||||
# optionally assign a static register value to a variable if needed.
|
||||
|
@ -430,7 +430,7 @@ module Rex
|
|||
end
|
||||
return _create_variable( name, reg )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# If the temp variable was assigned we release it.
|
||||
#
|
||||
|
@ -448,7 +448,7 @@ module Rex
|
|||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Resolve a variable name into its currently assigned register value.
|
||||
#
|
||||
|
@ -472,14 +472,14 @@ module Rex
|
|||
# resolve the register number int a string representation (e.g. 0 in x86 is EAX if size is 32)
|
||||
return _register_value( regnum, size )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Check this solution is still currently valid (as offsets change it may not be).
|
||||
#
|
||||
def solution_is_valid?
|
||||
return self.is_valid?( @solution.buffer )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# As the solution advances we save state for each permutation step in the solution. This lets
|
||||
# use rewind at a later stage if the solving algorithm wishes to perform some backtracking.
|
||||
|
@ -487,7 +487,7 @@ module Rex
|
|||
def solution_push( permutation )
|
||||
@solution.push( permutation, @reg_available, @reg_consumed, @variables )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Backtrack one step in the solution and restore the register/variable state.
|
||||
#
|
||||
|
@ -496,7 +496,7 @@ module Rex
|
|||
|
||||
@reg_available.push( @reg_available.shift )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a block by name and add in its list of permutations.
|
||||
#
|
||||
|
@ -531,7 +531,7 @@ module Rex
|
|||
end
|
||||
return _create_block_primitive( block_name, primitive_name, *args )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Get the offset for a blocks active permutation. This is easy for backward references as
|
||||
# they will already have been rendered and their sizes known. For forward references we
|
||||
|
@ -558,16 +558,16 @@ module Rex
|
|||
def block_exist?( name )
|
||||
return @blocks.include?( name )
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Does a given block exist?
|
||||
#
|
||||
def variable_exist?( name )
|
||||
return @variables.include?( name )
|
||||
end
|
||||
|
||||
|
||||
# XXX: ambiguity between variable names and block name may introduce confusion!!! make them be unique.
|
||||
|
||||
|
||||
#
|
||||
# Resolve a given value into either a number literal, a block offset or
|
||||
# a variables assigned register.
|
||||
|
@ -580,7 +580,7 @@ module Rex
|
|||
end
|
||||
return value.to_i
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Get the block previous to the target block.
|
||||
#
|
||||
|
@ -606,7 +606,7 @@ module Rex
|
|||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Try to generate a solution.
|
||||
#
|
||||
|
@ -615,7 +615,7 @@ module Rex
|
|||
if( @blocks.has_key?( 'end' ) )
|
||||
@blocks.delete( 'end' )
|
||||
end
|
||||
|
||||
|
||||
@blocks['end'] = Block.new( 'end' )
|
||||
@blocks['end'] << SymbolicPermutation.new( 'end', self, 1 )
|
||||
|
||||
|
@ -635,31 +635,31 @@ module Rex
|
|||
end
|
||||
previous = current
|
||||
end
|
||||
|
||||
|
||||
# Shuffle the order of the available registers
|
||||
@reg_available = @reg_available.shuffle
|
||||
|
||||
# We must try every permutation of the register orders, so if we fail to
|
||||
# generate a solution we rotate the available registers to try again with
|
||||
|
||||
# We must try every permutation of the register orders, so if we fail to
|
||||
# generate a solution we rotate the available registers to try again with
|
||||
# a different order. This ensures we perform and exhaustive search.
|
||||
0.upto( @reg_available.length - 1 ) do
|
||||
|
||||
@solution.reset
|
||||
|
||||
# Start from the root node in the solution space and generate a
|
||||
# Start from the root node in the solution space and generate a
|
||||
# solution by traversing the solution space's tree structure.
|
||||
if( @blocks['begin'].solve )
|
||||
# Return the solutions buffer (perform a last pass to fixup all offsets)...
|
||||
return @solution.buffer
|
||||
end
|
||||
|
||||
|
||||
@reg_available.push( @reg_available.shift )
|
||||
end
|
||||
|
||||
|
||||
# :(
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# An UndefinedPermutation exception is raised when a permutation can't render yet
|
||||
# as the conditions required are not yet satisfied.
|
||||
|
@ -669,7 +669,7 @@ module Rex
|
|||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# An UnallowedPermutation exception is raised when a permutation can't ever render
|
||||
# as the conditions supplied are impossible to satisfy.
|
||||
|
@ -679,7 +679,7 @@ module Rex
|
|||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# An InvalidPermutation exception is raised when a permutation receives a invalid
|
||||
# argument and cannot continue to render. This is a fatal exception.
|
||||
|
@ -689,19 +689,19 @@ module Rex
|
|||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
#
|
||||
# Overloaded by a subclass to resolve a register number into a suitable register
|
||||
# name for the target architecture. E.g on x64 the register number 0 with size 64
|
||||
# would resolve to RCX. Size is nil by default to indicate we want the default
|
||||
# would resolve to RCX. Size is nil by default to indicate we want the default
|
||||
# machine size, e.g. 32bit DWORD on x86 or 64bit QWORD on x64.
|
||||
#
|
||||
def _register_value( regnum, size=nil )
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Perform the actual variable creation.
|
||||
#
|
||||
|
@ -735,7 +735,7 @@ module Rex
|
|||
@variables[name] = regnum
|
||||
return name
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create a block which is based on a primitive defined by this machine.
|
||||
#
|
||||
|
@ -750,14 +750,14 @@ module Rex
|
|||
end
|
||||
return block_name
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Overloaded by a subclass to create any primitives available in this machine.
|
||||
#
|
||||
def _create_primitives
|
||||
nil
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Rex::Poly::Machine::Primitive
|
||||
#
|
||||
|
@ -771,9 +771,9 @@ module Rex
|
|||
@primitives[name] << Primitive.new( permutation )
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Helper function to generate a number whoes byte representation is valid in this
|
||||
# Helper function to generate a number whoes byte representation is valid in this
|
||||
# machine (does not contain any badchars for example). Optionally we can supply a
|
||||
# number and the resulting addition/subtraction of this number against the newly
|
||||
# generated value is also tested for validity. This helps in the assembly primitives
|
||||
|
@ -792,38 +792,38 @@ module Rex
|
|||
else
|
||||
raise RuntimeError, "Invalid size '#{bytes}' used in _make_safe_number."
|
||||
end
|
||||
|
||||
|
||||
goodchars = (0..255).to_a
|
||||
|
||||
|
||||
@badchars.unpack( 'C*' ).each do | b |
|
||||
goodchars.delete( b.chr )
|
||||
end
|
||||
|
||||
while( true ) do
|
||||
value = 0
|
||||
|
||||
|
||||
0.upto( bytes-1 ) do | i |
|
||||
value |= ( (goodchars[ rand(goodchars.length) ] << i*8) & (0xFF << i*8) )
|
||||
end
|
||||
|
||||
|
||||
if( not is_valid?( [ value ].pack(format) ) or not is_valid?( [ ~value ].pack(format) ) )
|
||||
redo
|
||||
end
|
||||
|
||||
|
||||
if( not number.nil? )
|
||||
if( not is_valid?( [ value + number ].pack(format) ) or not is_valid?( [ value - number ].pack(format) ) )
|
||||
redo
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
break
|
||||
end
|
||||
|
||||
|
||||
return value
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
module Rex
|
||||
|
||||
module Poly
|
||||
|
||||
|
||||
#
|
||||
# A subclass to represent a Rex poly machine on the x86 architecture.
|
||||
#
|
||||
|
@ -19,25 +19,25 @@ module Rex
|
|||
@reg_available << Rex::Arch::X86::EDI
|
||||
@reg_available << Rex::Arch::X86::EBP
|
||||
@reg_available << Rex::Arch::X86::ESP
|
||||
|
||||
# By default we consume the EBP register if badchars contains \x00. This helps speed
|
||||
# things up greatly as many instructions opperating on EBP introduce a NULL byte. For
|
||||
# example, a MOV instruction with EAX as the source operand is as follows:
|
||||
|
||||
# By default we consume the EBP register if badchars contains \x00. This helps speed
|
||||
# things up greatly as many instructions opperating on EBP introduce a NULL byte. For
|
||||
# example, a MOV instruction with EAX as the source operand is as follows:
|
||||
# 8B08 mov ecx, [eax]
|
||||
# but the same instruction with EBP as the source operand is as follows:
|
||||
# but the same instruction with EBP as the source operand is as follows:
|
||||
# 8B4D00 mov ecx, [ebp] ; This is assembled as 'mov ecx, [ebp+0]'
|
||||
# we can see that EBP is encoded differently with an offset included. We can still
|
||||
# try to generate a solution with EBP included and \x00 in the badchars list but
|
||||
# try to generate a solution with EBP included and \x00 in the badchars list but
|
||||
# it can take considerably longer.
|
||||
if( ( consume_base_pointer.nil? and not Rex::Text.badchar_index( "\x00", @badchars ).nil? ) or consume_base_pointer == true )
|
||||
create_variable( 'base_pointer', 'ebp' )
|
||||
end
|
||||
|
||||
|
||||
# By default we consume the ESP register to avoid munging the stack.
|
||||
if( consume_stack_pointer )
|
||||
create_variable( 'stack_pointer', 'esp' )
|
||||
end
|
||||
|
||||
|
||||
# discover all the safe FPU instruction we can use.
|
||||
@safe_fpu_instructions = ::Array.new
|
||||
Rex::Arch::X86.fpu_instructions.each do | fpu |
|
||||
|
@ -46,17 +46,17 @@ module Rex
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# The general purpose registers are 32bit
|
||||
#
|
||||
def native_size
|
||||
Rex::Poly::Machine::DWORD
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Overload this method to intercept the 'set' primitive with the 'location' keyword
|
||||
# and create the block with the '_set_variable_location'. We do this to keep a
|
||||
# and create the block with the '_set_variable_location'. We do this to keep a
|
||||
# consistent style.
|
||||
#
|
||||
def create_block_primitive( block_name, primitive_name, *args )
|
||||
|
@ -66,10 +66,10 @@ module Rex
|
|||
super
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# XXX: If we have a loop primitive, it is a decent speed bump to force the associated variable
|
||||
# of the first loop primitive to be assigned as ECX (for the x86 LOOP instruction), this is not
|
||||
# XXX: If we have a loop primitive, it is a decent speed bump to force the associated variable
|
||||
# of the first loop primitive to be assigned as ECX (for the x86 LOOP instruction), this is not
|
||||
# neccasary but can speed generation up significantly.
|
||||
#
|
||||
#def generate
|
||||
|
@ -83,7 +83,7 @@ module Rex
|
|||
# # ...go go go
|
||||
# super
|
||||
#end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
|
@ -95,7 +95,7 @@ module Rex
|
|||
if( size.nil? )
|
||||
size = native_size()
|
||||
end
|
||||
|
||||
|
||||
if( size == Rex::Poly::Machine::DWORD )
|
||||
value = Rex::Arch::X86::REG_NAMES32[ regnum ]
|
||||
elsif( size == Rex::Poly::Machine::WORD )
|
||||
|
@ -108,7 +108,7 @@ module Rex
|
|||
end
|
||||
return value
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Create the x86 primitives.
|
||||
#
|
||||
|
@ -118,7 +118,7 @@ module Rex
|
|||
# Create the '_set_variable_location' primitive. The first param it the variable to place the current
|
||||
# blocks location value in.
|
||||
#
|
||||
_create_primitive( '_set_variable_location',
|
||||
_create_primitive( '_set_variable_location',
|
||||
::Proc.new do | block, machine, variable |
|
||||
if( @safe_fpu_instructions.empty? )
|
||||
raise UnallowedPermutation
|
||||
|
@ -182,12 +182,12 @@ module Rex
|
|||
]
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'loop' primitive. The first param it the counter variable which holds the number of
|
||||
# Create the 'loop' primitive. The first param it the counter variable which holds the number of
|
||||
# times to perform the loop. The second param it the destination block to loop to.
|
||||
#
|
||||
_create_primitive( 'loop',
|
||||
_create_primitive( 'loop',
|
||||
::Proc.new do | block, machine, counter, destination |
|
||||
if( machine.variable_value( counter ) != Rex::Arch::X86::REG_NAMES32[ Rex::Arch::X86::ECX ] )
|
||||
# we raise and UndefinedPermutation exception to indicate that untill a valid register (ECX) is
|
||||
|
@ -208,12 +208,12 @@ module Rex
|
|||
]
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'xor' primitive. The first param it the variable to xor with the second param value which
|
||||
# can be either a variable, literal or block offset.
|
||||
#
|
||||
_create_primitive( 'xor',
|
||||
_create_primitive( 'xor',
|
||||
::Proc.new do | block, machine, variable, value |
|
||||
[
|
||||
"xor #{machine.variable_value( variable )}, #{machine.resolve_value( value )}"
|
||||
|
@ -230,11 +230,11 @@ module Rex
|
|||
]
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'goto' primitive. The first param is a destination block to jump to.
|
||||
#
|
||||
_create_primitive( 'goto',
|
||||
_create_primitive( 'goto',
|
||||
::Proc.new do | block, machine, destination |
|
||||
offset = -( machine.block_offset( machine.block_next( block ) ) - machine.block_offset( destination ) )
|
||||
if( ( offset > 0 and offset > 127 ) or ( offset < 0 and offset < -127 ) )
|
||||
|
@ -253,13 +253,13 @@ module Rex
|
|||
]
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'add' primitive. The first param it the variable which will be added to the second
|
||||
# param, which may either be a literal number value, a variables assigned register or a block
|
||||
# param, which may either be a literal number value, a variables assigned register or a block
|
||||
# name, in which case the block offset will be used.
|
||||
#
|
||||
_create_primitive( 'add',
|
||||
_create_primitive( 'add',
|
||||
::Proc.new do | block, machine, variable, value |
|
||||
if( machine.variable_exist?( value ) )
|
||||
raise UnallowedPermutation
|
||||
|
@ -276,7 +276,7 @@ module Rex
|
|||
]
|
||||
end,
|
||||
::Proc.new do | block, machine, variable, value |
|
||||
[
|
||||
[
|
||||
"add #{machine.variable_value( variable )}, #{machine.resolve_value( value )}"
|
||||
]
|
||||
end,
|
||||
|
@ -284,7 +284,7 @@ module Rex
|
|||
if( machine.variable_exist?( value ) )
|
||||
raise UnallowedPermutation
|
||||
end
|
||||
[
|
||||
[
|
||||
"sub #{machine.variable_value( variable )}, #{ "0x%08X" % [ ~(machine.resolve_value( value ) - 1) & 0xFFFFFFFF ] }"
|
||||
]
|
||||
end
|
||||
|
@ -311,12 +311,12 @@ module Rex
|
|||
# ]
|
||||
# end,
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'set' primitive. The first param it the variable which will be set. the second
|
||||
# param is the value to set the variable to (a variable, block or literal).
|
||||
#
|
||||
_create_primitive( 'set',
|
||||
_create_primitive( 'set',
|
||||
::Proc.new do | block, machine, variable, value |
|
||||
if( machine.variable_exist?( value ) )
|
||||
raise UnallowedPermutation
|
||||
|
@ -385,13 +385,13 @@ module Rex
|
|||
]
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
#
|
||||
# Create the 'load' primitive. The first param it the variable which will be set. The second
|
||||
# param is the value (either a variable or literal) to load from. the third param is the size
|
||||
# of the load operation, either DWORD, WORD or BYTE.
|
||||
#
|
||||
_create_primitive( 'load',
|
||||
_create_primitive( 'load',
|
||||
::Proc.new do | block, machine, variable, value, size |
|
||||
result = nil
|
||||
if( size == Rex::Poly::Machine::DWORD )
|
||||
|
@ -460,7 +460,7 @@ module Rex
|
|||
#
|
||||
# Create the 'store' primitive.
|
||||
#
|
||||
_create_primitive( 'store',
|
||||
_create_primitive( 'store',
|
||||
::Proc.new do | block, machine, variable, value, size |
|
||||
result = nil
|
||||
if( size == Rex::Poly::Machine::DWORD )
|
||||
|
@ -483,12 +483,12 @@ module Rex
|
|||
::Proc.new do | block, machine, variable, value, size |
|
||||
result = nil
|
||||
if( size == Rex::Poly::Machine::DWORD )
|
||||
result = [
|
||||
result = [
|
||||
"push #{machine.resolve_value( value )}",
|
||||
"pop [#{machine.variable_value( variable )}]"
|
||||
]
|
||||
elsif( size == Rex::Poly::Machine::WORD )
|
||||
result = [
|
||||
result = [
|
||||
"push #{machine.resolve_value( value, WORD )}",
|
||||
"pop word [#{machine.variable_value( variable )}]"
|
||||
]
|
||||
|
@ -500,9 +500,9 @@ module Rex
|
|||
end
|
||||
)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -19,31 +19,31 @@ class Dir
|
|||
def Dir.foreach(name, &block)
|
||||
entries(name).each(&block)
|
||||
end
|
||||
|
||||
|
||||
def Dir.chdir(path)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.mkdir(path)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.pwd
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.getwd
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.delete(path)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.rmdir(path)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def Dir.unlink(path)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
|
|
@ -32,7 +32,7 @@ class FileStat
|
|||
self.stathash = {}
|
||||
update(buf) if (buf and not buf.empty?)
|
||||
end
|
||||
|
||||
|
||||
def dev
|
||||
self.stathash['st_dev']
|
||||
end
|
||||
|
@ -77,7 +77,7 @@ class FileStat
|
|||
|
||||
# XXX: This needs to understand more than just 'stat' structures
|
||||
# Windows can also return _stat32, _stat32i64, _stat64i32, and _stat64 structures
|
||||
|
||||
|
||||
skeys = %W{st_dev st_ino st_mode st_wtf st_nlink st_uid st_gid st_rdev st_size st_ctime st_atime st_mtime}
|
||||
svals = buf.unpack("VvvvvvvVVVVV")
|
||||
skeys.each_index do |i|
|
||||
|
|
|
@ -133,7 +133,7 @@ class IO
|
|||
def readline(sep = $/)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def readlines(sep = $/)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
@ -141,7 +141,7 @@ class IO
|
|||
def rewind
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def seek(offset, whence = SEEK_SET)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
@ -165,12 +165,12 @@ class IO
|
|||
def syswrite(buf)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
||||
def tell
|
||||
return pos
|
||||
end
|
||||
|
||||
def ungetc(val)
|
||||
def ungetc(val)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ module Extensions
|
|||
module NetworkPug
|
||||
|
||||
TLV_TYPE_EXTENSION_NETWORKPUG = 0
|
||||
TLV_TYPE_NETWORKPUG_INTERFACE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_NETWORKPUG + TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_NETWORKPUG_INTERFACE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_NETWORKPUG + TLV_EXTENSIONS + 1)
|
||||
TLV_TYPE_NETWORKPUG_FILTER = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_NETWORKPUG + TLV_EXTENSIONS + 2)
|
||||
|
||||
end
|
||||
|
|
|
@ -39,10 +39,10 @@ class Arp
|
|||
mac_addr.each_byte { |o| macocts << o }
|
||||
macocts += [0] * (6 - macocts.size) if macocts.size < 6
|
||||
return sprintf("%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
macocts[0], macocts[1], macocts[2],
|
||||
macocts[0], macocts[1], macocts[2],
|
||||
macocts[3], macocts[4], macocts[5])
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# The ip address corresponding to the arp address.
|
||||
#
|
||||
|
|
|
@ -118,7 +118,7 @@ class Config
|
|||
netstat = []
|
||||
|
||||
response = client.send_request(request)
|
||||
|
||||
|
||||
# Build out the array of netstat
|
||||
response.each(TLV_TYPE_NETSTAT_ENTRY) { |connection|
|
||||
netstat << Netstat.new(
|
||||
|
|
|
@ -38,7 +38,7 @@ class Netstat
|
|||
self.uid = opts[:uid] || 0
|
||||
self.inode = opts[:inode] || 0
|
||||
self.pid_name = opts[:pid_name]
|
||||
|
||||
|
||||
self.local_addr_str = sprintf("%s:%d",self.local_addr, self.local_port)
|
||||
if self.remote_port == 0
|
||||
port = "*"
|
||||
|
@ -48,7 +48,7 @@ class Netstat
|
|||
self.remote_addr_str = sprintf("%s:%s",self.remote_addr, port)
|
||||
end
|
||||
|
||||
|
||||
|
||||
#
|
||||
# The local address of the connection
|
||||
#
|
||||
|
|
|
@ -74,14 +74,14 @@ class WinConstManager
|
|||
#
|
||||
# Returns an array of constant names that have a value matching "winconst"
|
||||
# and (optionally) a name that matches "filter_regex"
|
||||
#
|
||||
#
|
||||
def select_const_names(winconst, filter_regex=nil)
|
||||
matches = []
|
||||
|
||||
consts.each_pair do |name, value|
|
||||
matches << name if value == winconst
|
||||
end
|
||||
|
||||
|
||||
# Filter matches by name if a filter has been provided
|
||||
unless filter_regex.nil?
|
||||
matches.reject! do |name|
|
||||
|
|
|
@ -73,14 +73,14 @@ class Console::CommandDispatcher::Espia
|
|||
print_line("Grab a screenshot of the current interactive desktop.\n")
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
show = true
|
||||
show = false if (args[1] and args[1] =~ /^(f|n|0)/i)
|
||||
|
||||
|
||||
path = args[0] || Rex::Text.rand_text_alpha(8) + ".jpeg"
|
||||
|
||||
|
||||
data = client.espia.espia_image_get_dev_screen
|
||||
|
||||
|
||||
if( data )
|
||||
::File.open( path, 'wb' ) do |fd|
|
||||
fd.write( data )
|
||||
|
@ -89,7 +89,7 @@ class Console::CommandDispatcher::Espia
|
|||
print_line( "Screenshot saved to: #{path}" )
|
||||
Rex::Compat.open_file( path ) if show
|
||||
end
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class Console::CommandDispatcher::Incognito
|
|||
host = val
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
if (args.length < 2)
|
||||
print_line("Usage: add_user <username> <password> [options]\n")
|
||||
print_line("Attempts to add a user to a host with all accessible tokens. Terminates when successful, an error that is not access denied occurs (e.g. password does not meet complexity requirements) or when all tokens are exhausted")
|
||||
|
@ -154,7 +154,7 @@ class Console::CommandDispatcher::Incognito
|
|||
host = val
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
if (args.length < 2)
|
||||
print_line("Usage: add_localgroup_user <groupname> <username> [options]\n")
|
||||
print_line("Attempts to add a user to a local group on a host with all accessible tokens. Terminates when successful, an error that is not access denied occurs (e.g. user not found) or when all tokens are exhausted")
|
||||
|
@ -184,7 +184,7 @@ class Console::CommandDispatcher::Incognito
|
|||
host = val
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
if (args.length < 2)
|
||||
print_line("Usage: add_group_user <groupname> <username> [options]\n")
|
||||
print_line("Attempts to add a user to a global group on a host with all accessible tokens. Terminates when successful, an error that is not access denied occurs (e.g. user not found) or when all tokens are exhausted")
|
||||
|
@ -216,7 +216,7 @@ class Console::CommandDispatcher::Incognito
|
|||
print_line("[*] Snarfing token hashes...")
|
||||
client.incognito.incognito_snarf_hashes(args[0])
|
||||
print_line("[*] Done. Check sniffer logs")
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class Console::CommandDispatcher::NetworkPug
|
|||
rescue Errno::EBUSY
|
||||
next
|
||||
end
|
||||
|
||||
|
||||
ifreq = [ name ].pack("a32")
|
||||
|
||||
tapdev.ioctl(0x8927, ifreq)
|
||||
|
@ -69,7 +69,7 @@ class Console::CommandDispatcher::NetworkPug
|
|||
|
||||
return tapdev, name, mac
|
||||
}
|
||||
|
||||
|
||||
tapdev.close()
|
||||
return nil, nil, nil
|
||||
end
|
||||
|
@ -86,7 +86,7 @@ class Console::CommandDispatcher::NetworkPug
|
|||
len = len.unpack('n')[0]
|
||||
|
||||
#print_line("Got #{len} bytes from remote host's network")
|
||||
|
||||
|
||||
if(len > 1514 or len == 0)
|
||||
@tapdev.close()
|
||||
print_line("length is invalid .. #{len} ?, de-synchronized ? ")
|
||||
|
@ -187,13 +187,13 @@ class Console::CommandDispatcher::NetworkPug
|
|||
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
def cmd_networkpug_stop(*args)
|
||||
interface = args[0]
|
||||
if (interface == nil)
|
||||
print_error("Usage: networkpug_stop [interface]")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
client.networkpug.networkpug_stop(interface)
|
||||
|
||||
|
@ -208,7 +208,7 @@ class Console::CommandDispatcher::NetworkPug
|
|||
# meterpreter dies if i try to join.. not sure why.
|
||||
|
||||
@thread_stuff = nil
|
||||
|
||||
|
||||
#print_line("closing tapdev")
|
||||
@tapdev.close
|
||||
|
||||
|
@ -219,7 +219,7 @@ class Console::CommandDispatcher::NetworkPug
|
|||
print_status("Packet slinging stopped on #{interface}")
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
def name
|
||||
"NetworkPug"
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ class Console::CommandDispatcher::Priv::Passwd
|
|||
client.priv.sam_hashes.each { |user|
|
||||
print_line("#{user}")
|
||||
}
|
||||
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -267,7 +267,7 @@ class Console::CommandDispatcher::Stdapi::Net
|
|||
print_error "Invalid Subnet mask"
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
print_line("Creating route #{args[0]}/#{args[1]} -> #{args[2]}")
|
||||
|
||||
client.net.config.add_route(*args)
|
||||
|
@ -282,7 +282,7 @@ class Console::CommandDispatcher::Stdapi::Net
|
|||
print_error "Invalid Subnet mask"
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
print_line("Deleting route #{args[0]}/#{args[1]} -> #{args[2]}")
|
||||
|
||||
client.net.config.remove_route(*args)
|
||||
|
@ -397,7 +397,7 @@ class Console::CommandDispatcher::Stdapi::Net
|
|||
else
|
||||
print_error("Failed to stop TCP relay on #{lhost || '0.0.0.0'}:#{lport}")
|
||||
next
|
||||
end
|
||||
end
|
||||
|
||||
counter += 1
|
||||
end
|
||||
|
|
|
@ -20,10 +20,10 @@ module Proto
|
|||
ERRORS = %W{ no_response unknown success authenticaton_failed unit_has_address invalid_value invalid_data unsupported_command }
|
||||
WLAN_ENC_MODES = %W{ unknown none wep40 wep128 }
|
||||
WLAN_AUTH_MODES = %W{ unknown open shared_key open_shared_key }
|
||||
HWTYPES = %W{
|
||||
unknown ps3_desk8 ps3_desk16 ps3_desk32 ps3_rack16 ps2_desk16 ps2_rack16
|
||||
HWTYPES = %W{
|
||||
unknown ps3_desk8 ps3_desk16 ps3_desk32 ps3_rack16 ps2_desk16 ps2_rack16
|
||||
lets_desk1 lets_desk2 lets_desk4 dorpia_dinrail1 nubox01 nubox02 nubox04
|
||||
digione_sp digione_ia digione_em
|
||||
digione_sp digione_ia digione_em
|
||||
}
|
||||
|
||||
CMD_CONF_REQ = 1
|
||||
|
@ -35,7 +35,7 @@ module Proto
|
|||
CMD_SET_DHCP_REQ = 7
|
||||
CMD_SET_DHCP_REP = 8
|
||||
CMD_SET_WL_REQ = 9
|
||||
CMD_SET_WL_REP = 10
|
||||
CMD_SET_WL_REP = 10
|
||||
CMD_SET_WL_COUNTRIES_REQ = 11
|
||||
CMD_SET_WL_COUNTRIES_REP = 12
|
||||
CMD_EDP = 13
|
||||
|
@ -61,11 +61,11 @@ module Proto
|
|||
|
||||
def self.request_static_ip(magic, dmac, ip, mask, gw, pwd="dbps")
|
||||
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
|
||||
buf =
|
||||
buf =
|
||||
Rex::Socket.addr_aton(ip) +
|
||||
Rex::Socket.addr_aton(mask) +
|
||||
Rex::Socket.addr_aton(gw) +
|
||||
mac +
|
||||
mac +
|
||||
self.encode_password(pwd)
|
||||
|
||||
req = magic + [CMD_SET_ADDR_REQ, buf.length].pack("nn") + buf
|
||||
|
@ -74,9 +74,9 @@ module Proto
|
|||
|
||||
def self.request_dhcp(magic, dmac, enabled, pwd="dbps")
|
||||
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
|
||||
buf =
|
||||
buf =
|
||||
[ enabled ? 1 : 0 ].pack("C") +
|
||||
mac +
|
||||
mac +
|
||||
self.encode_password(pwd)
|
||||
|
||||
req = magic + [CMD_SET_DHCP_REQ, buf.length].pack("nn") + buf
|
||||
|
@ -86,11 +86,11 @@ module Proto
|
|||
def self.request_reboot(magic, dmac, pwd="dbps")
|
||||
mac = (dmac.length == 6) ? dmac : Rex::Socket.eth_aton(dmac)
|
||||
buf =
|
||||
mac +
|
||||
mac +
|
||||
self.encode_password(pwd)
|
||||
|
||||
req = magic + [CMD_REBOOT_REQ, buf.length].pack("nn") + buf
|
||||
return req
|
||||
return req
|
||||
end
|
||||
|
||||
def self.decode_reply(data)
|
||||
|
@ -185,7 +185,7 @@ module Proto
|
|||
# Store unknown responses
|
||||
res["unknown_0x#{"%.2x" % i_type}".to_sym] = i_data
|
||||
end
|
||||
|
||||
|
||||
bidx = bidx + 2 + i_len
|
||||
end
|
||||
return res
|
||||
|
@ -194,8 +194,8 @@ module Proto
|
|||
def self.reply_to_string(res)
|
||||
str = ""
|
||||
|
||||
fields = [
|
||||
:hwname, :hwtype, :hwrev, :fwrev,
|
||||
fields = [
|
||||
:hwname, :hwtype, :hwrev, :fwrev,
|
||||
:mac, :ip, :mask, :gw, :hostname, :domain, :dns, :dhcp,
|
||||
:msg, :result, :error,
|
||||
:advisory, :ports, :realport, :realport_enc,
|
||||
|
|
|
@ -5,7 +5,7 @@ module DCERPC
|
|||
module Exceptions
|
||||
|
||||
class Error < ::RuntimeError
|
||||
|
||||
|
||||
@@errors = {
|
||||
0x00000000 => "stub-defined",
|
||||
0x00000001 => "nca_s_fault_other",
|
||||
|
@ -103,7 +103,7 @@ class Error < ::RuntimeError
|
|||
0x1c010014 => "nca_server_too_busy",
|
||||
0x1c010017 => "nca_unsupported_type"
|
||||
}
|
||||
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
@ -136,7 +136,7 @@ class InvalidPacket < Error
|
|||
def initialize(message = nil)
|
||||
@message = message
|
||||
end
|
||||
|
||||
|
||||
def to_s
|
||||
str = 'Invalid packet.'
|
||||
if (@message)
|
||||
|
|
|
@ -20,7 +20,7 @@ class NDR
|
|||
warn 'should be using Rex::Encoder::NDR'
|
||||
return [string].pack('V')
|
||||
end
|
||||
|
||||
|
||||
# Encode a 2 byte short
|
||||
# use to encode:
|
||||
# short element_1;
|
||||
|
@ -28,7 +28,7 @@ class NDR
|
|||
warn 'should be using Rex::Encoder::NDR'
|
||||
return [string].pack('v')
|
||||
end
|
||||
|
||||
|
||||
# Encode a single byte
|
||||
# use to encode:
|
||||
# byte element_1;
|
||||
|
@ -53,7 +53,7 @@ class NDR
|
|||
string += "\x00" # null pad
|
||||
return long(string.length) + long(0) + long(string.length) + Rex::Text.to_unicode(string) + align(Rex::Text.to_unicode(string))
|
||||
end
|
||||
|
||||
|
||||
# Encode a string that is already unicode encoded
|
||||
# use to encode:
|
||||
# w_char *element_1;
|
||||
|
|
|
@ -129,11 +129,11 @@ class Client
|
|||
# @return [ClientRequest]
|
||||
def request_raw(opts={})
|
||||
opts = self.config.merge(opts)
|
||||
|
||||
|
||||
opts['ssl'] = self.ssl
|
||||
opts['cgi'] = false
|
||||
opts['port'] = self.port
|
||||
|
||||
|
||||
req = ClientRequest.new(opts)
|
||||
end
|
||||
|
||||
|
@ -151,7 +151,7 @@ class Client
|
|||
# @return [ClientRequest]
|
||||
def request_cgi(opts={})
|
||||
opts = self.config.merge(opts)
|
||||
|
||||
|
||||
opts['ctype'] ||= 'application/x-www-form-urlencoded'
|
||||
opts['ssl'] = self.ssl
|
||||
opts['cgi'] = true
|
||||
|
|
|
@ -27,7 +27,7 @@ class Handler::Proc < Handler
|
|||
# Returns true if the procedure is representing a virtual directory.
|
||||
#
|
||||
def relative_resource_required?
|
||||
virt_dir
|
||||
virt_dir
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -288,7 +288,7 @@ protected
|
|||
when Packet::ParseCode::Completed
|
||||
dispatch_request(cli, cli.request)
|
||||
cli.reset_cli
|
||||
|
||||
|
||||
when Packet::ParseCode::Partial
|
||||
# Return and wait for the on_client_data handler to be called again
|
||||
# The Request object tracks the state of the request for us
|
||||
|
|
|
@ -8,7 +8,7 @@ class ALaw < G711
|
|||
def self.decode(buff)
|
||||
buff.unpack("C*").map{ |x| LOOKUP_ALAW2LIN16[x] }.pack('v*')
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class MuLaw < G711
|
|||
def self.decode(buff)
|
||||
buff.unpack("C*").map{ |x| LOOKUP_ULAW2LIN16[x] }.pack('v*')
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ class Constants
|
|||
LM_MAGIC = "KGS!@\#$%"
|
||||
TIME_OFFSET = 11644473600
|
||||
MAX64 = 0xffffffffffffffff
|
||||
|
||||
|
||||
FLAGS = {
|
||||
:UNICODE => 0x00000001,
|
||||
:OEM => 0x00000002,
|
||||
|
@ -32,7 +32,7 @@ class Constants
|
|||
:KEY128 => 0x20000000,
|
||||
:KEY56 => 0x80000000
|
||||
}
|
||||
|
||||
|
||||
FLAG_KEYS = FLAGS.keys.sort{|a, b| FLAGS[a] <=> FLAGS[b] }
|
||||
|
||||
DEFAULT_FLAGS = {
|
||||
|
|
|
@ -31,7 +31,7 @@ module RFB
|
|||
##
|
||||
|
||||
class Cipher
|
||||
|
||||
|
||||
def self.mangle_password(password)
|
||||
key = ''
|
||||
key = password.dup if password
|
||||
|
|
|
@ -265,7 +265,7 @@ FILE_VOLUME_IS_COMPRESSED = 0x00008000
|
|||
# SMB Error Codes
|
||||
SMB_STATUS_SUCCESS = 0x00000000
|
||||
SMB_ERROR_BUFFER_OVERFLOW = 0x80000005
|
||||
SMB_STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016
|
||||
SMB_STATUS_MORE_PROCESSING_REQUIRED = 0xC0000016
|
||||
SMB_STATUS_ACCESS_DENIED = 0xC0000022
|
||||
SMB_STATUS_LOGON_FAILURE = 0xC000006D
|
||||
|
||||
|
|
|
@ -20,11 +20,11 @@ CONST = Rex::Proto::SMB::Constants
|
|||
}
|
||||
return access
|
||||
end
|
||||
|
||||
|
||||
# Creates a mode mask for use with the CLIENT.open() call based on a string
|
||||
def self.open_mode_to_mode(str)
|
||||
mode = 0
|
||||
|
||||
|
||||
str.each_byte { |c|
|
||||
case [c].pack('C').downcase
|
||||
when 'x' # Fail if the file already exists
|
||||
|
@ -32,7 +32,7 @@ CONST = Rex::Proto::SMB::Constants
|
|||
when 't' # Truncate the file if it already exists
|
||||
mode |= CONST::OPEN_MODE_TRUNC
|
||||
when 'c' # Create the file if it does not exist
|
||||
mode |= CONST::OPEN_MODE_CREAT
|
||||
mode |= CONST::OPEN_MODE_CREAT
|
||||
when 'o' # Just open the file, clashes with x
|
||||
mode |= CONST::OPEN_MODE_OPEN
|
||||
end
|
||||
|
@ -40,7 +40,7 @@ CONST = Rex::Proto::SMB::Constants
|
|||
|
||||
return mode
|
||||
end
|
||||
|
||||
|
||||
# Returns a disposition value for smb.create based on permission string
|
||||
def self.create_mode_to_disposition(str)
|
||||
str.each_byte { |c|
|
||||
|
@ -83,7 +83,7 @@ CONST = Rex::Proto::SMB::Constants
|
|||
end
|
||||
return encoded
|
||||
end
|
||||
|
||||
|
||||
# Convert a name from its NetBIOS equivalent
|
||||
def self.nbname_decode(str)
|
||||
decoded = ''
|
||||
|
|
|
@ -64,7 +64,7 @@ class Client
|
|||
#
|
||||
# Methods for both upload and download
|
||||
#
|
||||
|
||||
|
||||
def start_server_socket
|
||||
self.server_sock = Rex::Socket::Udp.create(
|
||||
'LocalHost' => local_host,
|
||||
|
@ -138,7 +138,7 @@ class Client
|
|||
#
|
||||
# Methods for download
|
||||
#
|
||||
|
||||
|
||||
def rrq_packet
|
||||
req = [OpRead, self.remote_file, self.mode]
|
||||
packstr = "na#{self.remote_file.length+1}a#{self.mode.length+1}"
|
||||
|
@ -231,7 +231,7 @@ class Client
|
|||
#
|
||||
# Methods for upload
|
||||
#
|
||||
|
||||
|
||||
def wrq_packet
|
||||
req = [OpWrite, self.remote_file, self.mode]
|
||||
packstr = "na#{self.remote_file.length+1}a#{self.mode.length+1}"
|
||||
|
|
|
@ -173,7 +173,7 @@ class Server
|
|||
attr_accessor :listen_host, :listen_port, :context
|
||||
attr_accessor :sock, :files, :transfers, :uploaded
|
||||
attr_accessor :thread
|
||||
|
||||
|
||||
attr_accessor :incoming_file_hook
|
||||
|
||||
protected
|
||||
|
@ -189,9 +189,9 @@ protected
|
|||
|
||||
def save_output(tr)
|
||||
self.uploaded << tr[:file]
|
||||
|
||||
|
||||
return incoming_file_hook.call(tr) if incoming_file_hook
|
||||
|
||||
|
||||
if @output_dir
|
||||
fn = tr[:file][:name].split(File::SEPARATOR)[-1]
|
||||
if fn
|
||||
|
|
|
@ -24,7 +24,7 @@ class LFBlock
|
|||
hash_offset = offset + 0x04
|
||||
|
||||
1.upto(@number_of_keys) do |h|
|
||||
|
||||
|
||||
hash = LFHashRecord.new(hive_blob, hash_offset)
|
||||
|
||||
@hash_records << hash
|
||||
|
@ -39,7 +39,7 @@ end
|
|||
class LFHashRecord
|
||||
|
||||
attr_accessor :nodekey_offset, :nodekey_name_verification
|
||||
|
||||
|
||||
def initialize(hive_blob, offset)
|
||||
@nodekey_offset = hive_blob[offset, 4].unpack('l').first
|
||||
@nodekey_name_verification = hive_blob[offset+0x04, 4].to_s
|
||||
|
|
|
@ -217,7 +217,7 @@ class RopCollect < RopBase
|
|||
|
||||
# get raw bytes
|
||||
buf = @disassembler.read_raw_data(addr, x + xtra)
|
||||
|
||||
|
||||
|
||||
# make sure disassembling forward leads to our instruction
|
||||
next if not ends_with_addr(buf, addr, ea)
|
||||
|
|
|
@ -461,14 +461,14 @@ module Socket
|
|||
def self.eth_aton(mac)
|
||||
mac.split(":").map{|c| c.to_i(16) }.pack("C*")
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Converts a 6-byte binary string into a colon-delimited MAC address
|
||||
#
|
||||
def self.eth_ntoa(bin)
|
||||
bin.unpack("C6").map{|x| "%.2x" % x }.join(":").upcase
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Converts a CIDR subnet into an array (base, bcast)
|
||||
#
|
||||
|
|
|
@ -16,7 +16,7 @@ module Socket
|
|||
module Comm
|
||||
|
||||
###
|
||||
#
|
||||
#
|
||||
# This mixin provides stubs for event notification handlers that can be
|
||||
# registered with a Comm factory to be called when various events occur,
|
||||
# such as socket instantiation.
|
||||
|
|
|
@ -48,7 +48,7 @@ class SubnetWalker
|
|||
end
|
||||
|
||||
self.curr_ip_idx += 1
|
||||
|
||||
|
||||
self.curr_ip.join('.')
|
||||
end
|
||||
|
||||
|
|
|
@ -163,12 +163,12 @@ class CStruct < SStruct
|
|||
return super(index, *other)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Produce a list of field names
|
||||
def keys
|
||||
@name_table
|
||||
end
|
||||
|
||||
|
||||
# Iterate through all fields and values
|
||||
def each_pair(&block)
|
||||
@name_table.each do |k|
|
||||
|
|
|
@ -12,7 +12,7 @@ module Struct2
|
|||
# sized arrays), and probably not a ton more.
|
||||
|
||||
class Constant
|
||||
|
||||
|
||||
require 'rex/struct2/element'
|
||||
include Rex::Struct2::Element
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ module Rex
|
|||
module Struct2
|
||||
|
||||
class Generic
|
||||
|
||||
|
||||
require 'rex/struct2/element'
|
||||
include Rex::Struct2::Element
|
||||
|
||||
|
@ -40,7 +40,7 @@ class Generic
|
|||
# example if it is nil. That should only happen for a user
|
||||
# error so that's what I want it to do...
|
||||
string = [ @value ].pack(@packspec)
|
||||
|
||||
|
||||
if restraint && restraint.max
|
||||
return string.slice(0, restraint.max)
|
||||
else
|
||||
|
|
|
@ -6,7 +6,7 @@ module Rex
|
|||
module Struct2
|
||||
|
||||
class SString
|
||||
|
||||
|
||||
require 'rex/struct2/element'
|
||||
require 'rex/struct2/constant'
|
||||
include Rex::Struct2::Element
|
||||
|
|
|
@ -50,7 +50,7 @@ class SStruct
|
|||
elements.each do |e|
|
||||
buff << e.to_s
|
||||
end
|
||||
|
||||
|
||||
if restraint && restraint.max
|
||||
return buff.slice(0, restraint.max)
|
||||
else
|
||||
|
|
|
@ -4,7 +4,7 @@ require 'timeout'
|
|||
module Rex
|
||||
|
||||
###
|
||||
#
|
||||
#
|
||||
# This module provides a set of methods for performing various blocking
|
||||
# operations in a manner that is compatible with ruby style threads.
|
||||
#
|
||||
|
|
|
@ -90,9 +90,9 @@ module Color
|
|||
#
|
||||
# Colorize if this shell supports it
|
||||
#
|
||||
def do_colorize(*color)
|
||||
def do_colorize(*color)
|
||||
supports_color?() ? ansi(*color) : ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end end end
|
||||
|
|
|
@ -34,29 +34,29 @@ class Input::Socket < Rex::Ui::Text::Input
|
|||
# Wait for a line of input to be read from a socket.
|
||||
#
|
||||
def gets
|
||||
|
||||
|
||||
# Initialize the line buffer
|
||||
line = ''
|
||||
|
||||
|
||||
# Read data one byte at a time until we see a LF
|
||||
while (true)
|
||||
|
||||
break if line.include?("\n")
|
||||
|
||||
|
||||
# Read another character of input
|
||||
char = @sock.getc
|
||||
if char.nil?
|
||||
@sock.close
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
# Telnet sends 0x04 as EOF
|
||||
if (char == 4)
|
||||
@sock.write("[*] Caught ^D, closing the socket...\n")
|
||||
@sock.close
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
# Append this character to the string
|
||||
line << char
|
||||
|
||||
|
@ -66,13 +66,13 @@ class Input::Socket < Rex::Ui::Text::Input
|
|||
@sock.write("[*] Caught ^C, closing the socket...\n")
|
||||
@sock.close
|
||||
return
|
||||
|
||||
|
||||
when /\xff\xed\xff\xfd\x06/
|
||||
@sock.write("[*] Caught ^Z\n")
|
||||
return
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return line
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
module Rex
|
||||
module Zip
|
||||
|
||||
#
|
||||
#
|
||||
# An Entry represents a logical file or directory to be stored in an Archive
|
||||
#
|
||||
class Entry
|
||||
|
|
Loading…
Reference in New Issue