CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/spec/lib/rex/exploit/view_state_spec.rb
Views: 11783
1
require 'spec_helper'
2
require 'rex/version'
3
4
require 'rex/text'
5
6
# rubocop:disable Lint/DeprecatedGemVersion
7
RSpec.describe Rex::Exploit::ViewState do
8
let(:data) { Random.new.bytes(rand(10..100)) }
9
let(:key) { Random.new.bytes(20) }
10
11
context 'when the algorithm is SHA-1' do
12
let(:algo) { 'sha1' }
13
14
describe '.decode_viewstate' do
15
let(:encoded) { described_class.generate_viewstate(data, algo: algo, key: key) }
16
17
it 'returns the data and HMAC' do
18
decoded = described_class.decode_viewstate(encoded, algo: algo)
19
expect(decoded).to be_a Hash
20
expect(decoded[:data]).to eq data
21
expect(decoded[:hmac]).to eq described_class.generate_viewstate_hmac(data, algo: algo, key: key)
22
end
23
end
24
25
describe '.generate_viewstate' do
26
it 'generates the HMAC signature' do
27
expect(described_class).to receive(:generate_viewstate_hmac).with(data, algo: algo, key: key).and_call_original
28
described_class.generate_viewstate(data, algo: algo, key: key)
29
end
30
31
it 'generates a Base64 encoded blob' do
32
viewstate = described_class.generate_viewstate(data, algo: algo, key: key)
33
debase64ed = Rex::Text.decode_base64(viewstate)
34
expect(debase64ed).to eq data + described_class.generate_viewstate_hmac(data, algo: algo, key: key)
35
end
36
end
37
38
describe '.generate_viewstate_hmac' do
39
it 'delegates to OpenSSL::HMAC' do
40
expect(OpenSSL::HMAC).to receive(:digest).with(algo, key,data)
41
described_class.generate_viewstate_hmac(data, algo: algo, key: key)
42
end
43
44
it 'generates a 20 byte HMAC' do
45
hmac = described_class.generate_viewstate_hmac(data, algo: algo, key: key)
46
expect(hmac.bytesize).to eq 20
47
end
48
end
49
50
describe '.is_viewstate_valid?' do
51
let(:encoded) { described_class.generate_viewstate(data, algo: algo, key: key) }
52
53
it 'raises an Error when it can not be decoded' do
54
# use key.length / 2 to guarantee there is not enough data for the key to be found
55
expect { described_class.is_viewstate_valid?(Rex::Text.encode_base64('A' * (key.length / 2))) }.to raise_error(described_class::Error)
56
end
57
58
it 'returns true for the correct key' do
59
expect(described_class.is_viewstate_valid?(encoded, algo: algo, key: key)).to be_truthy
60
end
61
62
it 'returns false for the incorrect key' do
63
expect(described_class.is_viewstate_valid?(encoded, algo: algo, key: key + '#')).to be_falsey
64
end
65
end
66
end
67
end
68
69