diff --git a/lib/msf/core/encoder.rb b/lib/msf/core/encoder.rb index 5cbafc863c..95839a3914 100644 --- a/lib/msf/core/encoder.rb +++ b/lib/msf/core/encoder.rb @@ -376,27 +376,24 @@ protected cur_key = [ ] bad_keys = find_bad_keys(buf, badchars) found = false - + allset = [*(0..255)] + # Keep chugging until we find something...right while (!found) # Scan each byte position 0.upto(decoder_key_size - 1) { |index| - cur_key[index] = rand(255) + + # Subtract the bad and leave the good + good_keys = allset-bad_keys[index].keys - # Scan all 255 bytes (wrapping around as necessary) - for cur_char in (cur_key[index] .. (cur_key[index] + 255)) - cur_char = (cur_char % 255) + 1 + # Was there anything left for this index? + if (good_keys.length == 0) + # Not much we can do about this :( + return nil + end - # If this is a known bad character at this location in the - # key or it doesn't pass the bad character check... - if (((bad_keys != nil) and - (bad_keys[index][cur_char] == true)) or - (badchars.index(cur_char) != nil)) - next - end - - key_bytes[index] = cur_char - end + # Set the appropriate key byte + key_bytes[index] = good_keys[ rand(good_keys.length) ] } # Assume that we're going to rock this shit... @@ -410,7 +407,7 @@ protected end } - found = find_key_verify(key_bytes, badchars) if found + found = find_key_verify(buf, key_bytes, badchars) if found end # Do we have all the key bytes accounted for? @@ -448,7 +445,14 @@ protected # decoder's key size and packing requirements # def key_bytes_to_integer(key_bytes) - return key_bytes.pack('C' + decoder_key_size.to_s).unpack(decoder_key_pack)[0] + return key_bytes_to_buffer(key_bytes).unpack(decoder_key_pack)[0] + end + + # + # Convert individual key bytes into a byte buffer + # + def key_bytes_to_buffer(key_bytes) + return key_bytes.pack('C' + decoder_key_size.to_s) end # @@ -462,7 +466,7 @@ protected # # Determines if the key selected by find_key is usable # - def find_key_verify(key_bytes, badchars) + def find_key_verify(buf, key_bytes, badchars) true end diff --git a/lib/msf/core/encoder/xor.rb b/lib/msf/core/encoder/xor.rb index e398ce5fe2..66d4e03ab2 100644 --- a/lib/msf/core/encoder/xor.rb +++ b/lib/msf/core/encoder/xor.rb @@ -31,9 +31,30 @@ class Msf::Encoder::Xor < Msf::Encoder byte_idx += 1 } } - + return bad_keys end + + def find_key_verify(buf, key_bytes, badchars) + ekey = key_bytes_to_buffer(key_bytes) + + out = '' + idx = 0 + while (idx < buf.length) + 0.upto(ekey.length-1) do |i| + break if ! buf[idx+i] + out << (buf[idx+i]^ekey[i]).chr + end + + idx += ekey.length + end + + badchars.each do |c| + return false if out.index(c) + end + + true + end end diff --git a/lib/msf/core/exceptions.rb b/lib/msf/core/exceptions.rb index bce3109148..278b79040d 100644 --- a/lib/msf/core/exceptions.rb +++ b/lib/msf/core/exceptions.rb @@ -123,6 +123,17 @@ class NoEncodersSucceededError < EncodingError end end +### +# +# Thrown when an encoder fails to generate a valid opcode sequence. +# +### +class BadGenerateError < EncodingError + def to_s + "A valid opcode permutation could not be found." + end +end + ## # # Exploit exceptions diff --git a/modules/encoders/x86/jmp_call_additive.rb b/modules/encoders/x86/jmp_call_additive.rb index 48f24827b3..966db0c967 100644 --- a/modules/encoders/x86/jmp_call_additive.rb +++ b/modules/encoders/x86/jmp_call_additive.rb @@ -44,7 +44,7 @@ class JmpCallAdditive < Msf::Encoder::XorAdditiveFeedback # def decoder_stub(state) if (state.decoder_stub == nil) - block = generate_decoder_stub(state) + block = generate_decoder_stub(state) || (raise BadGenerateError) state.decoder_key_offset = block.index('XORK') state.decoder_stub = block end diff --git a/modules/encoders/x86/shikata_ga_nai.rb b/modules/encoders/x86/shikata_ga_nai.rb index 91007f9fe6..a98d4b36ab 100644 --- a/modules/encoders/x86/shikata_ga_nai.rb +++ b/modules/encoders/x86/shikata_ga_nai.rb @@ -38,8 +38,7 @@ class ShikataGaNai < Msf::Encoder::XorAdditiveFeedback # If the decoder stub has not already been generated for this state, do # it now. The decoder stub method may be called more than once. if (state.decoder_stub == nil) - block = generate_shikata_block(state, state.buf.length + 4) - + block = generate_shikata_block(state, state.buf.length + 4) || (raise BadGenerateError) # Set the state specific key offset to wherever the XORK ended up. state.decoder_key_offset = block.index('XORK')