diff --git a/lib/msf/base/simple/buffer.rb b/lib/msf/base/simple/buffer.rb index 23deb89168..5047ba1c49 100644 --- a/lib/msf/base/simple/buffer.rb +++ b/lib/msf/base/simple/buffer.rb @@ -146,7 +146,7 @@ module Buffer raise ArgumentError, 'Encryption key is missing' end - buf = Rex::Text.encrypt_aes256(encryption_opts[:iv], encryption_opts[:key], value) + buf = Rex::Crypto.encrypt_aes256(encryption_opts[:iv], encryption_opts[:key], value) when 'base64' buf = Rex::Text.encode_base64(value) when 'xor' @@ -160,7 +160,7 @@ module Buffer raise ArgumentError, 'Encryption key is missing' end - buf = Rex::Text.rc4(encryption_opts[:key], value) + buf = Rex::Crypto.rc4(encryption_opts[:key], value) else raise ArgumentError, "Unsupported encryption format: #{encryption_opts[:format]}", caller end diff --git a/lib/rex.rb b/lib/rex.rb index a59bd4bd4d..008ad89555 100644 --- a/lib/rex.rb +++ b/lib/rex.rb @@ -114,6 +114,10 @@ require 'rex/compat' require 'rex/sslscan/scanner' require 'rex/sslscan/result' +# Cryptography +require 'rex/crypto/aes256' +require 'rex/crypto/rc4' + # Overload the Kernel.sleep() function to be thread-safe Kernel.class_eval(" diff --git a/lib/rex/crypto/aes256.rb b/lib/rex/crypto/aes256.rb new file mode 100644 index 0000000000..036bba7c5b --- /dev/null +++ b/lib/rex/crypto/aes256.rb @@ -0,0 +1,33 @@ +# -*- coding: binary -*- + +module Rex + module Crypto + + # Returns an encrypted string using AES256-CBC. + # + # @param iv [String] Initialization vector. + # @param key [String] Secret key. + # @return [String] The encrypted string. + def self.encrypt_aes256(iv, key, value) + aes = OpenSSL::Cipher::AES256.new(:CBC) + aes.encrypt + aes.iv = iv + aes.key = key + aes.update(value) + aes.final + end + + # Returns a decrypted string using AES256-CBC. + # + # @param iv [String] Initialization vector. + # @param key [String] Secret key. + # @return [String] The decrypted string. + def self.decrypt_aes256(iv, key, value) + aes = OpenSSL::Cipher::AES256.new(:CBC) + aes.decrypt + aes.iv = iv + aes.key = key + aes.update(value) + aes.final + end + + end +end \ No newline at end of file diff --git a/lib/rex/crypto/rc4.rb b/lib/rex/crypto/rc4.rb new file mode 100644 index 0000000000..d2ae189840 --- /dev/null +++ b/lib/rex/crypto/rc4.rb @@ -0,0 +1,18 @@ +# -*- coding: binary -*- + +module Rex + module Crypto + + # Returns a decrypted or encrypted RC4 string. + # + # @param key [String] Secret key. + # @param [String] + def self.rc4(key, value) + rc4 = RC4.new(key) + + # This can also be used to decrypt + rc4.encrypt(value) + end + + end +end \ No newline at end of file diff --git a/spec/lib/rex/crypto/aes256_spec.rb b/spec/lib/rex/crypto/aes256_spec.rb new file mode 100644 index 0000000000..271c6e9053 --- /dev/null +++ b/spec/lib/rex/crypto/aes256_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' +require 'securerandom' + + +describe Rex::Crypto do + + let(:iv) { + SecureRandom.random_bytes(16) + } + + let(:key) { + SecureRandom.random_bytes(32) + } + + let(:value) { + 'Hello World' + } + + describe '#encrypt_aes256' do + it 'raises an exception due to a short IV' do + iv = SecureRandom.random_bytes(1) + # Because it could raise either a OpenSSL::Cipher::CipherError or an ArgumentError + # dependong on the environment, we will just expect it to raise an exception + expect { Rex::Crypto.encrypt_aes256(iv, key, value) }.to raise_exception + end + + it 'raises an exception due to a short key' do + key = SecureRandom.random_bytes(1) + # Because it could raise either a OpenSSL::Cipher::CipherError or an ArgumentError + # dependong on the environment, we will just expect it to raise an exception + expect { Rex::Crypto.encrypt_aes256(iv, key, value) }.to raise_exception + end + + it 'encrypts the string Hello World' do + encrypted_str = Rex::Crypto.encrypt_aes256(iv, key, value) + expect(encrypted_str).not_to eq(value) + end + end + + describe '#decrypt_aes256' do + it 'raises an exception due to a short IV' do + iv = SecureRandom.random_bytes(1) + # Because it could raise either a OpenSSL::Cipher::CipherError or an ArgumentError + # dependong on the environment, we will just expect it to raise an exception + expect { Rex::Crypto.decrypt_aes256(iv, key, value) }.to raise_exception + end + + it 'raises an exception due to a short key' do + key = SecureRandom.random_bytes(1) + # Because it could raise either a OpenSSL::Cipher::CipherError or an ArgumentError + # dependong on the environment, we will just expect it to raise an exception + expect { Rex::Crypto.decrypt_aes256(iv, key, value) }.to raise_exception + end + + it 'decrypts the value to Hello World' do + encrypted_str = Rex::Crypto.encrypt_aes256(iv, key, value) + decrypted_str = Rex::Crypto.decrypt_aes256(iv, key, encrypted_str) + expect(decrypted_str).to eq(value) + end + end + +end \ No newline at end of file diff --git a/spec/lib/rex/crypto/rc4_spec.rb b/spec/lib/rex/crypto/rc4_spec.rb new file mode 100644 index 0000000000..47e598c76e --- /dev/null +++ b/spec/lib/rex/crypto/rc4_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' +require 'securerandom' + + +describe Rex::Crypto do + + describe '#rc4' do + + let(:key) { + SecureRandom.random_bytes(32) + } + + let(:value) { + 'Hello World' + } + + it 'encrypts a string' do + expect(Rex::Crypto.rc4(key, value)).not_to eq(value) + end + + it 'decrypts a string' do + encrypted_str = Rex::Crypto.rc4(key, value) + decrypted_str = Rex::Crypto.rc4(key, encrypted_str) + expect(decrypted_str).to eq(value) + end + + end +end \ No newline at end of file