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/lib/rex/exploit/view_state.rb
Views: 11779
1
# -*- coding: binary -*-
2
3
module Rex
4
module Exploit
5
class ViewState
6
class Error < Rex::RuntimeError
7
end
8
9
def self.decode_viewstate(encoded_viewstate, algo: 'sha1')
10
viewstate = Rex::Text.decode_base64(encoded_viewstate)
11
12
unless Rex::Text.encode_base64(viewstate) == encoded_viewstate
13
raise Error.new('Could not decode ViewState')
14
end
15
16
hmac_len = OpenSSL::Digest.new(algo).digest_length
17
18
if (data = viewstate[0...-hmac_len]).empty?
19
data = nil
20
end
21
22
hmac = viewstate[-hmac_len..-1]
23
unless hmac&.length == hmac_len
24
raise Error.new('Could not decode ViewState')
25
end
26
27
{ data: data, hmac: hmac }
28
end
29
30
def self.generate_viewstate(data, extra: '', algo: 'sha1', key: '')
31
# Generate ViewState HMAC from known values and validation key
32
hmac = generate_viewstate_hmac(data + extra, algo: algo, key: key)
33
34
# Append HMAC to provided data and Base64-encode the whole shebang
35
Rex::Text.encode_base64(data + hmac)
36
end
37
38
def self.generate_viewstate_hmac(data, algo: 'sha1', key: '')
39
OpenSSL::HMAC.digest(algo, key, data)
40
end
41
42
def self.is_viewstate_valid?(encoded_viewstate, extra: '', algo: 'sha1', key: '')
43
viewstate = decode_viewstate(encoded_viewstate)
44
45
unless viewstate[:data]
46
raise Error.new('Could not retrieve ViewState data')
47
end
48
49
unless (their_hmac = viewstate[:hmac])
50
raise Error.new('Could not retrieve ViewState HMAC')
51
end
52
53
our_hmac = generate_viewstate_hmac(
54
viewstate[:data] + extra,
55
algo: algo,
56
key: key
57
)
58
59
# Do we have what it takes?
60
our_hmac == their_hmac
61
end
62
63
class << self
64
alias_method :can_sign_viewstate?, :is_viewstate_valid?
65
end
66
end
67
end
68
end
69
70