Land #22, Implement XOR with variable-length key

This commit is contained in:
asoto-r7 2019-07-22 16:15:42 -05:00
commit a5d2e9b021
No known key found for this signature in database
GPG Key ID: F531810B7FE55396
2 changed files with 52 additions and 27 deletions

View File

@ -1,28 +1,38 @@
# -*- coding: binary -*-
module Rex
module Text
# Returns a XOR'd string.
#
# @param key [String] XOR key.
# @param value [String] The string to XOR.
# @return [String] An XOR'd string.
def self.xor(key, value)
xor_key = key.kind_of?(Integer) || key.nil? ? key.to_i : key.to_i(16)
unless xor_key.between?(0, 255)
raise ArgumentError, 'XOR key should be between 0x00 to 0x0f'
end
buf = ''
value.each_byte do |byte|
xor_byte = byte ^ xor_key
buf << [xor_byte].pack('c')
end
buf
module Rex::Text
# XOR a string against a variable-length key
#
# @param key [String] XOR key
# @param value [String] String to XOR
# @return [String] XOR'd string
def self.xor(key, value)
unless key && value
raise ArgumentError, 'XOR key and value must be supplied'
end
xor_key =
case key
when String
if key.empty?
raise ArgumentError, 'XOR key must not be empty'
end
key
when Integer
unless key.between?(0x00, 0xff)
raise ArgumentError, 'XOR key must be between 0x00 and 0xff'
end
# Convert integer to string
[key].pack('C')
end
# Get byte arrays for key and value
xor_key = xor_key.bytes
xor_value = value.bytes
# XOR value against cycled key
xor_value.zip(xor_key.cycle).map { |v, k| v ^ k }.pack('C*')
end
end
end

View File

@ -18,9 +18,24 @@ describe Rex::Text do
expect(Rex::Text.xor(xor_key, hello_world_str)).to eq(xor_hello_world_str)
end
it 'XORs with a string type key' do
xor_key = "0x0f"
expect(Rex::Text.xor(xor_key, hello_world_str)).to eq(xor_hello_world_str)
it 'XORs with a variable-length key' do
xor_key = "\x00\x00\x00\x00\x00\x0c"
expect(Rex::Text.xor(xor_key, hello_world_str)).to eq('hello,world')
end
it 'XORs with itself' do
xor_key = hello_world_str
expect(Rex::Text.xor(xor_key, hello_world_str)).to eq("\x00" * hello_world_str.length)
end
it 'raises an ArgumentError due to a nil key' do
bad_key = nil
expect { Rex::Text.xor(bad_key, hello_world_str) }.to raise_error(ArgumentError)
end
it 'raises an ArgumentError due to an empty key' do
bad_key = ''
expect { Rex::Text.xor(bad_key, hello_world_str) }.to raise_error(ArgumentError)
end
it 'raises an ArgumentError due to an out of range key' do
@ -29,4 +44,4 @@ describe Rex::Text do
end
end
end
end