Class: Rex::Post::Meterpreter::Extensions::Stdapi::Sys::Registry

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb

Overview

This class provides access to the Windows registry on the remote machine.

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.clientObject

Returns the value of attribute client


28
29
30
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 28

def client
  @client
end

Class Method Details

.check_key_exists(root_key, base_key) ⇒ Boolean

Checks if a key exists on the target registry

Parameters:

  • root_key (String)

    the root part of the key path. Ex: HKEY_LOCAL_MACHINE

  • base_key (String)

    the base part of the key path

Returns:

  • (Boolean)

    true if the key exists on the target registry, false otherwise, even it the session hasn't permissions to access the target key.

Raises:


88
89
90
91
92
93
94
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 88

def Registry.check_key_exists(root_key, base_key)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_CHECK_KEY_EXISTS)
  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  response = client.send_request(request)
  return response.get_tlv(TLV_TYPE_BOOL).value
end

.close_key(hkey) ⇒ Object

Closes the supplied registry key.


155
156
157
158
159
160
161
162
163
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 155

def Registry.close_key(hkey)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_CLOSE_KEY)

  request.add_tlv(TLV_TYPE_HKEY, hkey)

  client.send_packet(request)

  return true
end

.create_key(root_key, base_key, perm = KEY_READ) ⇒ Object

Creates the supplied registry key or opens it if it already exists.


117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 117

def Registry.create_key(root_key, base_key, perm = KEY_READ)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_CREATE_KEY)

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)

  response = client.send_request(request)

  return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryKey.new(
      client, root_key, base_key, perm, response.get_tlv(TLV_TYPE_HKEY).value)
end

.delete_key(root_key, base_key, recursive = true) ⇒ Object

Deletes the supplied registry key.


133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 133

def Registry.delete_key(root_key, base_key, recursive = true)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_DELETE_KEY)
  flags   = 0

  if (recursive)
    flags |= DELETE_KEY_FLAG_RECURSIVE
  end

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_FLAGS, flags)

  if (client.send_request(request) != nil)
    return true
  end

  return false
end

.delete_value(hkey, name) ⇒ Object

Deletes the registry value supplied in name from the supplied registry key.


305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 305

def Registry.delete_value(hkey, name)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_DELETE_VALUE)

  request.add_tlv(TLV_TYPE_HKEY, hkey)
  request.add_tlv(TLV_TYPE_VALUE_NAME, name)

  if (client.send_request(request) != nil)
    return true
  end

  return false
end

.enum_key(hkey) ⇒ Object

Enumerates the supplied registry key returning an array of key names.


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 168

def Registry.enum_key(hkey)
  keys    = []
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_ENUM_KEY)

  request.add_tlv(TLV_TYPE_HKEY, hkey)

  response = client.send_request(request)

  # Enumerate through all of the registry keys
  response.each(TLV_TYPE_KEY_NAME) { |key_name|
    keys << key_name.value
  }

  return keys
end

.enum_key_direct(root_key, base_key, perm = KEY_READ) ⇒ Object


184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 184

def Registry.enum_key_direct(root_key, base_key, perm = KEY_READ)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_ENUM_KEY_DIRECT)
  keys    = []

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)

  response = client.send_request(request)

  # Enumerate through all of the registry keys
  response.each(TLV_TYPE_KEY_NAME) do |key_name|
    keys << key_name.value
  end

  keys
end

.enum_value(hkey) ⇒ Object

Enumerates all of the values at the supplied hkey including their names. An array of RegistryValue's is returned.


337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 337

def Registry.enum_value(hkey)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_ENUM_VALUE)
  values  = []

  request.add_tlv(TLV_TYPE_HKEY, hkey)

  response = client.send_request(request)

  response.each(TLV_TYPE_VALUE_NAME) { |value_name|
    values << Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryValue.new(
        client, hkey, value_name.value)
  }

  return values
end

.enum_value_direct(root_key, base_key, perm = KEY_READ) ⇒ Object


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 353

def Registry.enum_value_direct(root_key, base_key, perm = KEY_READ)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_ENUM_VALUE_DIRECT)
  values  = []

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)

  response = client.send_request(request)

  response.each(TLV_TYPE_VALUE_NAME) do |value_name|
    values << Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryValue.new(
        client, 0, value_name.value)
  end

  values
end

.key2str(key) ⇒ Object

Return the key value associated with the supplied string. This is useful for converting HKLM as a string into its actual integer representation.


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 375

def self.key2str(key)
  if (key == 'HKLM' or key == 'HKEY_LOCAL_MACHINE')
    return HKEY_LOCAL_MACHINE
  elsif (key == 'HKCU' or key == 'HKEY_CURRENT_USER')
    return HKEY_CURRENT_USER
  elsif (key == 'HKU' or key == 'HKEY_USERS')
    return HKEY_USERS
  elsif (key == 'HKCR' or key == 'HKEY_CLASSES_ROOT')
    return HKEY_CLASSES_ROOT
  elsif (key == 'HKEY_CURRENT_CONFIG')
    return HKEY_CURRENT_CONFIG
  elsif (key == 'HKEY_PERFORMANCE_DATA')
    return HKEY_PERFORMANCE_DATA
  elsif (key == 'HKEY_DYN_DATA')
    return HKEY_DYN_DATA
  else
    raise ArgumentError, "Unknown key: #{key}"
  end
end

.load_key(root_key, base_key, hive_file) ⇒ Object

Opens the supplied registry key relative to the root key with the supplied permissions. Right now this is merely a wrapper around create_key.


43
44
45
46
47
48
49
50
51
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 43

def Registry.load_key(root_key,base_key,hive_file)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_LOAD_KEY)
  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_FILE_PATH, client.unicode_filter_decode( hive_file ))

  response = client.send_request(request)
  return response.get_tlv(TLV_TYPE_RESULT).value
end

.open_key(root_key, base_key, perm = KEY_READ) ⇒ Object


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 62

def Registry.open_key(root_key, base_key, perm = KEY_READ)
  # If no base key was provided, just return the root_key.
  if (base_key == nil or base_key.length == 0)
    return RegistrySubsystem::RegistryKey.new(client, root_key, base_key, perm, root_key)
  end

  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_OPEN_KEY)

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)

  response = client.send_request(request)

  return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryKey.new(
      client, root_key, base_key, perm, response.get_tlv(TLV_TYPE_HKEY).value)
end

.open_remote_key(target_host, root_key) ⇒ Object

Opens the supplied registry key on the specified remote host. Requires that the current process has credentials to access the target and that the target has the remote registry service running.


101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 101

def Registry.open_remote_key(target_host, root_key)

  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_OPEN_REMOTE_KEY)

  request.add_tlv(TLV_TYPE_TARGET_HOST, target_host)
  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)

  response = client.send_request(request)

  return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RemoteRegistryKey.new(
      client, target_host, root_key, response.get_tlv(TLV_TYPE_HKEY).value)
end

.query_class(hkey) ⇒ Object

Queries the registry class name and returns a string


321
322
323
324
325
326
327
328
329
330
331
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 321

def Registry.query_class(hkey)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_QUERY_CLASS)

  request.add_tlv(TLV_TYPE_HKEY, hkey)

  response = client.send_request(request)
  cls = response.get_tlv(TLV_TYPE_VALUE_DATA)
  return nil if not cls
  data = cls.value.gsub(/\x00.*/n, '')
  return data
end

.query_value(hkey, name) ⇒ Object


280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 280

def Registry.query_value(hkey, name)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_QUERY_VALUE)

  request.add_tlv(TLV_TYPE_HKEY, hkey)
  request.add_tlv(TLV_TYPE_VALUE_NAME, name)

  response = client.send_request(request)

  data = response.get_tlv(TLV_TYPE_VALUE_DATA).value
  type = response.get_tlv(TLV_TYPE_VALUE_TYPE).value

  if (type == REG_SZ)
    data = data[0..-2]
  elsif (type == REG_DWORD)
    data = data.unpack("N")[0]
  end

  return Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryValue.new(
      client, hkey, name, type, data)
end

.query_value_direct(root_key, base_key, name, perm = KEY_READ) ⇒ Object

Queries the registry value supplied in name and returns an initialized RegistryValue instance if a match is found.


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 257

def Registry.query_value_direct(root_key, base_key, name, perm = KEY_READ)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_QUERY_VALUE_DIRECT)

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)
  request.add_tlv(TLV_TYPE_VALUE_NAME, name)

  response = client.send_request(request)

  type = response.get_tlv(TLV_TYPE_VALUE_TYPE).value
  data = response.get_tlv(TLV_TYPE_VALUE_DATA).value

  if type == REG_SZ
    data = data[0..-2]
  elsif type == REG_DWORD
    data = data.unpack('N')[0]
  end

  Rex::Post::Meterpreter::Extensions::Stdapi::Sys::RegistrySubsystem::RegistryValue.new(
      client, 0, name, type, data)
end

.set_value(hkey, name, type, data) ⇒ Object

Sets the registry value relative to the supplied hkey.


211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 211

def Registry.set_value(hkey, name, type, data)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_SET_VALUE)

  request.add_tlv(TLV_TYPE_HKEY, hkey)
  request.add_tlv(TLV_TYPE_VALUE_NAME, name)
  request.add_tlv(TLV_TYPE_VALUE_TYPE, type)

  if type == REG_SZ || type == REG_MULTI_SZ
    data += "\x00"
  elsif (type == REG_DWORD)
    data = [ data.to_i ].pack("V")
  end

  request.add_tlv(TLV_TYPE_VALUE_DATA, data)

  client.send_request(request)

  return true
end

.set_value_direct(root_key, base_key, name, type, data, perm = KEY_WRITE) ⇒ Object


231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 231

def Registry.set_value_direct(root_key, base_key, name, type, data, perm = KEY_WRITE)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_SET_VALUE_DIRECT)

  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  request.add_tlv(TLV_TYPE_PERMISSION, perm)
  request.add_tlv(TLV_TYPE_VALUE_NAME, name)
  request.add_tlv(TLV_TYPE_VALUE_TYPE, type)

  if type == REG_SZ || type == REG_MULTI_SZ
    data += "\x00"
  elsif type == REG_DWORD
    data = [data.to_i].pack('V')
  end

  request.add_tlv(TLV_TYPE_VALUE_DATA, data)

  client.send_request(request)

  true
end

.splitkey(str) ⇒ Object

Split the supplied full registry key into its root key and base key. For instance, passing HKLMSoftwareDog will return [ HKEY_LOCAL_MACHINE, 'SoftwareDog' ]


420
421
422
423
424
425
426
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 420

def self.splitkey(str)
  if (str =~ /^(.+?)[\\]{1,}(.*)$/)
    [ key2str($1), $2 ]
  else
    [ key2str(str), nil ]
  end
end

.type2str(type) ⇒ Integer

Returns the integer value associated with the supplied registry value type (like REG_SZ).

Parameters:

  • type (String)

    A Windows registry type constant name, e.g. 'REG_SZ'

Returns:

  • (Integer)

    one of the `REG_*` constants

See Also:


402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 402

def self.type2str(type)
  case type
  when 'REG_BINARY'    then REG_BINARY
  when 'REG_DWORD'     then REG_DWORD
  when 'REG_EXPAND_SZ' then REG_EXPAND_SZ
  when 'REG_MULTI_SZ'  then REG_MULTI_SZ
  when 'REG_NONE'      then REG_NONE
  when 'REG_SZ'        then REG_SZ
  else
    nil
  end
end

.unload_key(root_key, base_key) ⇒ Object


53
54
55
56
57
58
59
# File 'lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb', line 53

def Registry.unload_key(root_key,base_key)
  request = Packet.create_request(COMMAND_ID_STDAPI_REGISTRY_UNLOAD_KEY)
  request.add_tlv(TLV_TYPE_ROOT_KEY, root_key)
  request.add_tlv(TLV_TYPE_BASE_KEY, base_key)
  response = client.send_request(request)
  return response.get_tlv(TLV_TYPE_RESULT).value
end