68 lines
2.5 KiB
Ruby
68 lines
2.5 KiB
Ruby
require 'spec_helper'
|
|
require 'rex/version'
|
|
|
|
require 'rex/text'
|
|
|
|
# rubocop:disable Lint/DeprecatedGemVersion
|
|
RSpec.describe Rex::Exploit::ViewState do
|
|
let(:data) { Random.new.bytes(rand(10..100)) }
|
|
let(:key) { Random.new.bytes(20) }
|
|
|
|
context 'when the algorithm is SHA-1' do
|
|
let(:algo) { 'sha1' }
|
|
|
|
describe '.decode_viewstate' do
|
|
let(:encoded) { described_class.generate_viewstate(data, algo: algo, key: key) }
|
|
|
|
it 'returns the data and HMAC' do
|
|
decoded = described_class.decode_viewstate(encoded, algo: algo)
|
|
expect(decoded).to be_a Hash
|
|
expect(decoded[:data]).to eq data
|
|
expect(decoded[:hmac]).to eq described_class.generate_viewstate_hmac(data, algo: algo, key: key)
|
|
end
|
|
end
|
|
|
|
describe '.generate_viewstate' do
|
|
it 'generates the HMAC signature' do
|
|
expect(described_class).to receive(:generate_viewstate_hmac).with(data, algo: algo, key: key).and_call_original
|
|
described_class.generate_viewstate(data, algo: algo, key: key)
|
|
end
|
|
|
|
it 'generates a Base64 encoded blob' do
|
|
viewstate = described_class.generate_viewstate(data, algo: algo, key: key)
|
|
debase64ed = Rex::Text.decode_base64(viewstate)
|
|
expect(debase64ed).to eq data + described_class.generate_viewstate_hmac(data, algo: algo, key: key)
|
|
end
|
|
end
|
|
|
|
describe '.generate_viewstate_hmac' do
|
|
it 'delegates to OpenSSL::HMAC' do
|
|
expect(OpenSSL::HMAC).to receive(:digest).with(algo, key,data)
|
|
described_class.generate_viewstate_hmac(data, algo: algo, key: key)
|
|
end
|
|
|
|
it 'generates a 20 byte HMAC' do
|
|
hmac = described_class.generate_viewstate_hmac(data, algo: algo, key: key)
|
|
expect(hmac.bytesize).to eq 20
|
|
end
|
|
end
|
|
|
|
describe '.is_viewstate_valid?' do
|
|
let(:encoded) { described_class.generate_viewstate(data, algo: algo, key: key) }
|
|
|
|
it 'raises an Error when it can not be decoded' do
|
|
# use key.length / 2 to guarantee there is not enough data for the key to be found
|
|
expect { described_class.is_viewstate_valid?(Rex::Text.encode_base64('A' * (key.length / 2))) }.to raise_error(described_class::Error)
|
|
end
|
|
|
|
it 'returns true for the correct key' do
|
|
expect(described_class.is_viewstate_valid?(encoded, algo: algo, key: key)).to be_truthy
|
|
end
|
|
|
|
it 'returns false for the incorrect key' do
|
|
expect(described_class.is_viewstate_valid?(encoded, algo: algo, key: key + '#')).to be_falsey
|
|
end
|
|
end
|
|
end
|
|
end
|