Skip to content

Commit 667c356

Browse files
committed
Land rapid7#7209, Add functionality to pull .NET versions on Windows hosts
2 parents b37dc8e + b25b2a5 commit 667c356

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

lib/msf/core/post/windows.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ module Msf::Post::Windows
2121
require 'msf/core/post/windows/ldap'
2222
require 'msf/core/post/windows/reflective_dll_injection'
2323
require 'msf/core/post/windows/kiwi'
24+
require 'msf/core/post/windows/dotnet'
2425
end

lib/msf/core/post/windows/dotnet.rb

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# -*- coding: binary -*-
2+
require 'msf/core/post/common'
3+
require 'msf/core/post/windows/registry'
4+
5+
module Msf::Post::Windows::Dotnet
6+
include ::Msf::Post::Common
7+
include ::Msf::Post::Windows::Registry
8+
9+
def initialize(info = {})
10+
super
11+
end
12+
#
13+
# Searches the subkey for the value 'Version' which contains the
14+
# actual version, rather than the over-arching release
15+
# An alternative would be to query for it, and catch the exception.
16+
#
17+
18+
def search_for_version(dotnet_subkey)
19+
dotnet_version = nil
20+
begin
21+
subkeys = registry_enumvals(dotnet_subkey)
22+
rescue Rex::Post::Meterpreter::RequestError => e
23+
print_status("Encountered exception in search_for_version: #{e.class} #{e}")
24+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
25+
end
26+
unless subkeys.nil?
27+
subkeys.each do |subkey|
28+
if subkey == 'Version'
29+
dotnet_version = registry_getvaldata(dotnet_subkey, subkey)
30+
break
31+
end
32+
end
33+
end
34+
return dotnet_version
35+
end
36+
37+
#
38+
# Bruteforce search all subkeys in an over-arching release to
39+
# locate the actual release version.
40+
#
41+
def get_versionception(dotnet_vkey)
42+
exact_version = nil
43+
begin
44+
subkeys = registry_enumkeys(dotnet_vkey)
45+
rescue Rex::Post::Meterpreter::RequestError => e
46+
print_status("Encountered exception in get_versionception: #{e.class} #{e}")
47+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
48+
end
49+
unless subkeys.nil?
50+
subkeys.each do |subkey|
51+
exact_version = search_for_version(dotnet_vkey + '\\' + subkey)
52+
unless exact_version.nil?
53+
# if we find a version, stop looking
54+
break
55+
end
56+
end
57+
end
58+
return exact_version
59+
end
60+
61+
#
62+
# 'Public' function that returns a list of all .NET versions on
63+
# a windows host
64+
#
65+
def get_dotnet_versions
66+
ret_val = []
67+
key = 'HKLM\\SOFTWARE\\Microsoft\NET Framework Setup\\NDP'
68+
begin
69+
dotnet_keys = registry_enumkeys(key)
70+
rescue Rex::Post::Meterpreter::RequestError => e
71+
print_status("Encountered exception in get_dotnet_version: #{e.class} #{e}")
72+
elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
73+
end
74+
unless dotnet_keys.nil?
75+
dotnet_keys.each do |temp_key|
76+
if temp_key[0] == 'v'
77+
key = 'HKLM\\SOFTWARE\\Microsoft\NET Framework Setup\\NDP\\' + temp_key
78+
dotnet_version = get_versionception(key)
79+
unless dotnet_version.nil?
80+
ret_val << dotnet_version
81+
end
82+
end
83+
end
84+
end
85+
return ret_val
86+
end
87+
end
88+

0 commit comments

Comments
 (0)