Skip to content

Commit fef9c67

Browse files
author
Brent Cook
committed
Land rapid7#3175, OJ's TLV group refactoring
2 parents 6b117d7 + ecd73e5 commit fef9c67

File tree

5 files changed

+172
-26
lines changed

5 files changed

+172
-26
lines changed

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ PATH
99
json
1010
metasploit-concern (~> 0.3.0)
1111
metasploit-model (~> 0.28.0)
12-
meterpreter_bins (= 0.0.11)
12+
meterpreter_bins (= 0.0.12)
1313
msgpack
1414
nokogiri
1515
packetfu (= 1.1.9)
@@ -132,7 +132,7 @@ GEM
132132
pg
133133
railties (< 4.0.0)
134134
recog (~> 1.0)
135-
meterpreter_bins (0.0.11)
135+
meterpreter_bins (0.0.12)
136136
method_source (0.8.2)
137137
mime-types (1.25.1)
138138
mini_portile (0.6.1)

lib/rex/post/meterpreter/extensions/extapi/adsi/adsi.rb

Lines changed: 102 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,7 @@ def domain_query(domain_name, filter, max_results, page_size, fields)
4848

4949
response = client.send_request(request)
5050

51-
results = []
52-
response.each(TLV_TYPE_EXT_ADSI_RESULT) { |r|
53-
result = []
54-
r.each(TLV_TYPE_EXT_ADSI_VALUE) { |v|
55-
result << v.value
56-
}
57-
results << result
58-
}
51+
results = extract_results(response)
5952

6053
return {
6154
:fields => fields,
@@ -65,6 +58,107 @@ def domain_query(domain_name, filter, max_results, page_size, fields)
6558

6659
attr_accessor :client
6760

61+
protected
62+
63+
#
64+
# Retrieve the results of the query from the response
65+
# packet that was returned from Meterpreter.
66+
#
67+
# @param response [Packet] Reference to the received
68+
# packet that was returned from Meterpreter.
69+
#
70+
# @return [Array[Array[[Hash]]] Collection of results from
71+
# the ADSI query.
72+
#
73+
def extract_results(response)
74+
results = []
75+
76+
response.each(TLV_TYPE_EXT_ADSI_RESULT) do |r|
77+
results << extract_values(r)
78+
end
79+
80+
results
81+
end
82+
83+
#
84+
# Extract a single row of results from a TLV group.
85+
#
86+
# @param tlv_container [Packet] Reference to the TLV
87+
# group to pull the values from.
88+
#
89+
# @return [Array[Hash]] Collection of values from
90+
# the single ADSI query result row.
91+
#
92+
def extract_values(tlv_container)
93+
values = []
94+
tlv_container.get_tlvs(TLV_TYPE_ANY).each do |v|
95+
values << extract_value(v)
96+
end
97+
values
98+
end
99+
100+
#
101+
# Convert a single ADSI result value into a usable
102+
# value that also describes its type.
103+
#
104+
# @param v [TLV] The TLV item that contains the value.
105+
#
106+
# @return [Hash] The type/value pair from the TLV.
107+
#
108+
def extract_value(v)
109+
value = {
110+
:type => :unknown
111+
}
112+
113+
case v.type
114+
when TLV_TYPE_EXT_ADSI_STRING
115+
value = {
116+
:type => :string,
117+
:value => v.value
118+
}
119+
when TLV_TYPE_EXT_ADSI_NUMBER, TLV_TYPE_EXT_ADSI_BIGNUMBER
120+
value = {
121+
:type => :number,
122+
:value => v.value
123+
}
124+
when TLV_TYPE_EXT_ADSI_BOOL
125+
value = {
126+
:type => :bool,
127+
:value => v.value
128+
}
129+
when TLV_TYPE_EXT_ADSI_RAW
130+
value = {
131+
:type => :raw,
132+
:value => v.value
133+
}
134+
when TLV_TYPE_EXT_ADSI_ARRAY
135+
value = {
136+
:type => :array,
137+
:value => extract_values(v.value)
138+
}
139+
when TLV_TYPE_EXT_ADSI_PATH
140+
value = {
141+
:type => :path,
142+
:volume => v.get_tlv_value(TLV_TYPE_EXT_ADSI_PATH_VOL),
143+
:path => v.get_tlv_value(TLV_TYPE_EXT_ADSI_PATH_PATH),
144+
:vol_type => v.get_tlv_value(TLV_TYPE_EXT_ADSI_PATH_TYPE)
145+
}
146+
when TLV_TYPE_EXT_ADSI_DN
147+
values = v.get_tlvs(TLV_TYPE_ALL)
148+
value = {
149+
:type => :dn,
150+
:label => values[0].value
151+
}
152+
153+
if values[1].type == TLV_TYPE_EXT_ADSI_STRING
154+
value[:string] = value[1].value
155+
else
156+
value[:raw] = value[1].value
157+
end
158+
end
159+
160+
value
161+
end
68162
end
69163

70164
end; end; end; end; end; end

lib/rex/post/meterpreter/extensions/extapi/tlv.rb

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,31 @@ module Extapi
5454
TLV_TYPE_EXT_CLIPBOARD_MON_DUMP = TLV_META_TYPE_BOOL | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 52)
5555
TLV_TYPE_EXT_CLIPBOARD_MON_PURGE = TLV_META_TYPE_BOOL | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 53)
5656

57-
TLV_TYPE_EXT_ADSI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 55)
58-
TLV_TYPE_EXT_ADSI_FILTER = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 56)
59-
TLV_TYPE_EXT_ADSI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 57)
60-
TLV_TYPE_EXT_ADSI_VALUE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 58)
61-
TLV_TYPE_EXT_ADSI_RESULT = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 59)
62-
TLV_TYPE_EXT_ADSI_MAXRESULTS = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 60)
63-
TLV_TYPE_EXT_ADSI_PAGESIZE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 61)
57+
TLV_TYPE_EXT_ADSI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 54)
58+
TLV_TYPE_EXT_ADSI_FILTER = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 55)
59+
TLV_TYPE_EXT_ADSI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 56)
60+
TLV_TYPE_EXT_ADSI_RESULT = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 57)
61+
TLV_TYPE_EXT_ADSI_MAXRESULTS = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 58)
62+
TLV_TYPE_EXT_ADSI_PAGESIZE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 59)
63+
TLV_TYPE_EXT_ADSI_ARRAY = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 60)
64+
TLV_TYPE_EXT_ADSI_STRING = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 61)
65+
TLV_TYPE_EXT_ADSI_NUMBER = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 62)
66+
TLV_TYPE_EXT_ADSI_BIGNUMBER = TLV_META_TYPE_QWORD | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 63)
67+
TLV_TYPE_EXT_ADSI_BOOL = TLV_META_TYPE_BOOL | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 64)
68+
TLV_TYPE_EXT_ADSI_RAW = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 65)
69+
TLV_TYPE_EXT_ADSI_PATH = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 66)
70+
TLV_TYPE_EXT_ADSI_PATH_VOL = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 67)
71+
TLV_TYPE_EXT_ADSI_PATH_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 68)
72+
TLV_TYPE_EXT_ADSI_PATH_TYPE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69)
73+
TLV_TYPE_EXT_ADSI_DN = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70)
6474

65-
TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 65)
66-
TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 66)
67-
TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 67)
68-
TLV_TYPE_EXT_WMI_VALUE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 68)
69-
TLV_TYPE_EXT_WMI_FIELDS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69)
70-
TLV_TYPE_EXT_WMI_VALUES = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70)
71-
TLV_TYPE_EXT_WMI_ERROR = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 71)
75+
TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 90)
76+
TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 91)
77+
TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 92)
78+
TLV_TYPE_EXT_WMI_VALUE = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 93)
79+
TLV_TYPE_EXT_WMI_FIELDS = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 94)
80+
TLV_TYPE_EXT_WMI_VALUES = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 95)
81+
TLV_TYPE_EXT_WMI_ERROR = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 96)
7282

7383
end
7484
end

lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ def cmd_adsi_domain_query(*args)
176176
)
177177

178178
objects[:results].each do |c|
179-
table << c
179+
table << to_table_row(c)
180180
end
181181

182182
print_line
@@ -189,6 +189,48 @@ def cmd_adsi_domain_query(*args)
189189
return true
190190
end
191191

192+
protected
193+
194+
#
195+
# Convert an ADSI result row to a table row so that it can
196+
# be rendered to screen appropriately.
197+
#
198+
# @param result [Array[Hash]] Array of type/value pairs.
199+
#
200+
# @return [Array[String]] Renderable view of the value.
201+
#
202+
def to_table_row(result)
203+
values = []
204+
205+
result.each do |v|
206+
case v[:type]
207+
when :string, :number, :bool
208+
values << v[:value].to_s
209+
when :raw
210+
# for UI level stuff, rendering raw as hex is really the only option
211+
values << Rex::Text.to_hex(v[:value], '')
212+
when :array
213+
val = "#{to_table_row(v[:value]).join(", ")}"
214+
215+
# we'll truncate the output of the array because it could be excessive if we
216+
# don't. Users who want the detail of this stuff should probably script it.
217+
if val.length > 50
218+
val = "<#{val[0,50]}..."
219+
end
220+
221+
values << val
222+
when :dn
223+
values << "#{value[:label]}: #{value[:string] || Rex::Text.to_hex(value[:raw], '')}"
224+
when :path
225+
values << "Vol: #{v[:volume]}, Path: #{v[:path]}, Type: #{v[:vol_type]}"
226+
when :unknown
227+
values << "(unknown)"
228+
end
229+
end
230+
231+
values
232+
end
233+
192234
end
193235

194236
end

metasploit-framework.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ Gem::Specification.new do |spec|
6565
# are needed when there's no database
6666
spec.add_runtime_dependency 'metasploit-model', '~> 0.28.0'
6767
# Needed for Meterpreter on Windows, soon others.
68-
spec.add_runtime_dependency 'meterpreter_bins', '0.0.11'
68+
spec.add_runtime_dependency 'meterpreter_bins', '0.0.12'
6969
# Needed by msfgui and other rpc components
7070
spec.add_runtime_dependency 'msgpack'
7171
# Needed by anemone crawler

0 commit comments

Comments
 (0)