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.
- checksums.yaml +4 -4
- data/lib/rex.rb +1 -0
- data/lib/rex/arch.rb +5 -0
- data/lib/rex/arch/x86.rb +19 -5
- data/lib/rex/arch/zarch.rb +17 -0
- data/lib/rex/compat.rb +5 -4
- data/lib/rex/constants.rb +3 -1
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
- data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
- data/lib/rex/exploitation/cmdstager.rb +1 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
- data/lib/rex/exploitation/egghunter.rb +1 -1
- data/lib/rex/google/geolocation.rb +68 -0
- data/lib/rex/io/bidirectional_pipe.rb +0 -4
- data/lib/rex/java/serialization.rb +2 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +2 -0
- data/lib/rex/java/serialization/model/annotation.rb +3 -3
- data/lib/rex/java/serialization/model/block_data.rb +3 -3
- data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
- data/lib/rex/java/serialization/model/class_desc.rb +6 -6
- data/lib/rex/java/serialization/model/contents.rb +17 -10
- data/lib/rex/java/serialization/model/field.rb +12 -11
- data/lib/rex/java/serialization/model/long_utf.rb +3 -3
- data/lib/rex/java/serialization/model/new_array.rb +22 -23
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
- data/lib/rex/java/serialization/model/new_enum.rb +5 -5
- data/lib/rex/java/serialization/model/new_object.rb +22 -17
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +4 -4
- data/lib/rex/java/serialization/model/stream.rb +7 -7
- data/lib/rex/java/serialization/model/utf.rb +3 -3
- data/lib/rex/json_hash_file.rb +94 -0
- data/lib/rex/logging/log_sink.rb +1 -0
- data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
- data/lib/rex/parser/appscan_nokogiri.rb +13 -23
- data/lib/rex/parser/fs/ntfs.rb +10 -5
- data/lib/rex/parser/nmap_nokogiri.rb +3 -1
- data/lib/rex/parser/openvas_nokogiri.rb +70 -73
- data/lib/rex/parser/winscp.rb +108 -0
- data/lib/rex/parser/x509_certificate.rb +92 -0
- data/lib/rex/payloads.rb +0 -1
- data/lib/rex/payloads/meterpreter/config.rb +154 -0
- data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
- data/lib/rex/post/meterpreter.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +26 -3
- data/lib/rex/post/meterpreter/client_core.rb +387 -75
- data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
- data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
- data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
- data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
- data/lib/rex/post/meterpreter/packet.rb +29 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
- data/lib/rex/post/meterpreter/ui/console.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/powershell.rb +62 -0
- data/lib/rex/powershell/command.rb +359 -0
- data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
- data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
- data/lib/rex/powershell/parser.rb +182 -0
- data/lib/rex/powershell/payload.rb +78 -0
- data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
- data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
- data/lib/rex/proto/dcerpc/client.rb +6 -6
- data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
- data/lib/rex/proto/http/client.rb +3 -3
- data/lib/rex/proto/http/client_request.rb +0 -5
- data/lib/rex/proto/http/response.rb +86 -0
- data/lib/rex/proto/ipmi/utils.rb +30 -26
- data/lib/rex/proto/kerberos/client.rb +1 -1
- data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
- data/lib/rex/proto/rfb/client.rb +8 -3
- data/lib/rex/proto/rfb/constants.rb +1 -1
- data/lib/rex/proto/rmi.rb +2 -0
- data/lib/rex/proto/rmi/decode_error.rb +10 -0
- data/lib/rex/proto/rmi/exception.rb +10 -0
- data/lib/rex/proto/rmi/model.rb +5 -0
- data/lib/rex/proto/rmi/model/call.rb +4 -4
- data/lib/rex/proto/rmi/model/call_data.rb +137 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/element.rb +26 -11
- data/lib/rex/proto/rmi/model/output_header.rb +4 -4
- data/lib/rex/proto/rmi/model/ping.rb +2 -2
- data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/return_data.rb +5 -5
- data/lib/rex/proto/rmi/model/return_value.rb +124 -0
- data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
- data/lib/rex/proto/steam.rb +3 -0
- data/lib/rex/proto/steam/message.rb +125 -0
- data/lib/rex/proto/tftp/client.rb +35 -14
- data/lib/rex/random_identifier_generator.rb +2 -0
- data/lib/rex/ropbuilder.rb +1 -1
- data/lib/rex/socket/parameters.rb +9 -0
- data/lib/rex/socket/ssl_tcp.rb +25 -41
- data/lib/rex/socket/ssl_tcp_server.rb +10 -21
- data/lib/rex/sslscan/result.rb +20 -1
- data/lib/rex/text.rb +241 -55
- data/lib/rex/ui/output.rb +0 -3
- data/lib/rex/ui/subscriber.rb +0 -10
- data/lib/rex/ui/text/color.rb +9 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
- data/lib/rex/ui/text/output.rb +15 -4
- data/lib/rex/ui/text/output/file.rb +1 -0
- data/lib/rex/ui/text/output/stdio.rb +0 -16
- data/lib/rex/ui/text/shell.rb +3 -0
- data/lib/rex/ui/text/table.rb +85 -19
- data/lib/rex/user_agent.rb +118 -0
- data/rex.gemspec +2 -2
- metadata +41 -14
- data/lib/rex/exploitation/powershell.rb +0 -62
- data/lib/rex/exploitation/powershell/parser.rb +0 -183
- data/lib/rex/payloads/meterpreter.rb +0 -2
- data/lib/rex/payloads/meterpreter/patch.rb +0 -136
|
@@ -51,6 +51,20 @@ class Console::CommandDispatcher::Stdapi::Net
|
|
|
51
51
|
"-p" => [ true, "The remote port to connect to." ],
|
|
52
52
|
"-L" => [ true, "The local host to listen on (optional)." ])
|
|
53
53
|
|
|
54
|
+
#
|
|
55
|
+
# Options for the netstat command.
|
|
56
|
+
#
|
|
57
|
+
@@netstat_opts = Rex::Parser::Arguments.new(
|
|
58
|
+
"-h" => [ false, "Help banner." ],
|
|
59
|
+
"-S" => [ true, "Search string." ])
|
|
60
|
+
|
|
61
|
+
#
|
|
62
|
+
# Options for ARP command.
|
|
63
|
+
#
|
|
64
|
+
@@arp_opts = Rex::Parser::Arguments.new(
|
|
65
|
+
"-h" => [ false, "Help banner." ],
|
|
66
|
+
"-S" => [ true, "Search string." ])
|
|
67
|
+
|
|
54
68
|
#
|
|
55
69
|
# List of supported commands.
|
|
56
70
|
#
|
|
@@ -107,6 +121,23 @@ class Console::CommandDispatcher::Stdapi::Net
|
|
|
107
121
|
#
|
|
108
122
|
def cmd_netstat(*args)
|
|
109
123
|
connection_table = client.net.config.netstat
|
|
124
|
+
search_term = nil
|
|
125
|
+
@@netstat_opts.parse(args) { |opt, idx, val|
|
|
126
|
+
case opt
|
|
127
|
+
when '-S'
|
|
128
|
+
search_term = val
|
|
129
|
+
if search_term.nil?
|
|
130
|
+
print_error("Enter a search term")
|
|
131
|
+
return true
|
|
132
|
+
else
|
|
133
|
+
search_term = /#{search_term}/nmi
|
|
134
|
+
end
|
|
135
|
+
when "-h"
|
|
136
|
+
@@netstat_opts.usage
|
|
137
|
+
return 0
|
|
138
|
+
|
|
139
|
+
end
|
|
140
|
+
}
|
|
110
141
|
tbl = Rex::Ui::Text::Table.new(
|
|
111
142
|
'Header' => "Connection list",
|
|
112
143
|
'Indent' => 4,
|
|
@@ -119,7 +150,8 @@ class Console::CommandDispatcher::Stdapi::Net
|
|
|
119
150
|
"User",
|
|
120
151
|
"Inode",
|
|
121
152
|
"PID/Program name"
|
|
122
|
-
]
|
|
153
|
+
],
|
|
154
|
+
'SearchTerm' => search_term)
|
|
123
155
|
|
|
124
156
|
connection_table.each { |connection|
|
|
125
157
|
tbl << [ connection.protocol, connection.local_addr_str, connection.remote_addr_str,
|
|
@@ -138,6 +170,23 @@ class Console::CommandDispatcher::Stdapi::Net
|
|
|
138
170
|
#
|
|
139
171
|
def cmd_arp(*args)
|
|
140
172
|
arp_table = client.net.config.arp_table
|
|
173
|
+
search_term = nil
|
|
174
|
+
@@arp_opts.parse(args) { |opt, idx, val|
|
|
175
|
+
case opt
|
|
176
|
+
when '-S'
|
|
177
|
+
search_term = val
|
|
178
|
+
if search_term.nil?
|
|
179
|
+
print_error("Enter a search term")
|
|
180
|
+
return true
|
|
181
|
+
else
|
|
182
|
+
search_term = /#{search_term}/nmi
|
|
183
|
+
end
|
|
184
|
+
when "-h"
|
|
185
|
+
@@arp_opts.usage
|
|
186
|
+
return 0
|
|
187
|
+
|
|
188
|
+
end
|
|
189
|
+
}
|
|
141
190
|
tbl = Rex::Ui::Text::Table.new(
|
|
142
191
|
'Header' => "ARP cache",
|
|
143
192
|
'Indent' => 4,
|
|
@@ -146,7 +195,8 @@ class Console::CommandDispatcher::Stdapi::Net
|
|
|
146
195
|
"IP address",
|
|
147
196
|
"MAC address",
|
|
148
197
|
"Interface"
|
|
149
|
-
]
|
|
198
|
+
],
|
|
199
|
+
'SearchTerm' => search_term)
|
|
150
200
|
|
|
151
201
|
arp_table.each { |arp|
|
|
152
202
|
tbl << [ arp.ip_addr, arp.mac_addr, arp.interface ]
|
|
@@ -21,61 +21,61 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
21
21
|
# Options used by the 'execute' command.
|
|
22
22
|
#
|
|
23
23
|
@@execute_opts = Rex::Parser::Arguments.new(
|
|
24
|
-
"-a" => [ true, "The arguments to pass to the command."
|
|
25
|
-
"-c" => [ false, "Channelized I/O (required for interaction)."
|
|
26
|
-
"-f" => [ true, "The executable command to run."
|
|
27
|
-
"-h" => [ false, "Help menu."
|
|
28
|
-
"-H" => [ false, "Create the process hidden from view."
|
|
29
|
-
"-i" => [ false, "Interact with the process after creating it."
|
|
30
|
-
"-m" => [ false, "Execute from memory."
|
|
31
|
-
"-d" => [ true, "The 'dummy' executable to launch when using -m."
|
|
24
|
+
"-a" => [ true, "The arguments to pass to the command." ],
|
|
25
|
+
"-c" => [ false, "Channelized I/O (required for interaction)." ],
|
|
26
|
+
"-f" => [ true, "The executable command to run." ],
|
|
27
|
+
"-h" => [ false, "Help menu." ],
|
|
28
|
+
"-H" => [ false, "Create the process hidden from view." ],
|
|
29
|
+
"-i" => [ false, "Interact with the process after creating it." ],
|
|
30
|
+
"-m" => [ false, "Execute from memory." ],
|
|
31
|
+
"-d" => [ true, "The 'dummy' executable to launch when using -m." ],
|
|
32
32
|
"-t" => [ false, "Execute process with currently impersonated thread token"],
|
|
33
|
-
"-k" => [ false, "Execute process on the meterpreters current desktop"
|
|
33
|
+
"-k" => [ false, "Execute process on the meterpreters current desktop" ],
|
|
34
34
|
"-s" => [ true, "Execute process in a given session as the session user" ])
|
|
35
35
|
|
|
36
36
|
#
|
|
37
37
|
# Options used by the 'reboot' command.
|
|
38
38
|
#
|
|
39
39
|
@@reboot_opts = Rex::Parser::Arguments.new(
|
|
40
|
-
"-h" => [ false, "Help menu."
|
|
41
|
-
"-f" => [ true, "Force a reboot, valid values [1|2]"
|
|
40
|
+
"-h" => [ false, "Help menu." ],
|
|
41
|
+
"-f" => [ true, "Force a reboot, valid values [1|2]" ])
|
|
42
42
|
|
|
43
43
|
#
|
|
44
44
|
# Options used by the 'shutdown' command.
|
|
45
45
|
#
|
|
46
46
|
@@shutdown_opts = Rex::Parser::Arguments.new(
|
|
47
|
-
"-h" => [ false, "Help menu."
|
|
48
|
-
"-f" => [ true, "Force a shutdown, valid values [1|2]"
|
|
47
|
+
"-h" => [ false, "Help menu." ],
|
|
48
|
+
"-f" => [ true, "Force a shutdown, valid values [1|2]" ])
|
|
49
49
|
|
|
50
50
|
#
|
|
51
51
|
# Options used by the 'reg' command.
|
|
52
52
|
#
|
|
53
53
|
@@reg_opts = Rex::Parser::Arguments.new(
|
|
54
|
-
"-d" => [ true, "The data to store in the registry value."
|
|
55
|
-
"-h" => [ false, "Help menu."
|
|
56
|
-
"-k" => [ true, "The registry key path (E.g. HKLM\\Software\\Foo)."
|
|
57
|
-
"-t" => [ true, "The registry value type (E.g. REG_SZ)."
|
|
58
|
-
"-v" => [ true, "The registry value name (E.g. Stuff)."
|
|
54
|
+
"-d" => [ true, "The data to store in the registry value." ],
|
|
55
|
+
"-h" => [ false, "Help menu." ],
|
|
56
|
+
"-k" => [ true, "The registry key path (E.g. HKLM\\Software\\Foo)." ],
|
|
57
|
+
"-t" => [ true, "The registry value type (E.g. REG_SZ)." ],
|
|
58
|
+
"-v" => [ true, "The registry value name (E.g. Stuff)." ],
|
|
59
59
|
"-r" => [ true, "The remote machine name to connect to (with current process credentials" ],
|
|
60
|
-
"-w" => [ false, "Set KEY_WOW64 flag, valid values [32|64]."
|
|
60
|
+
"-w" => [ false, "Set KEY_WOW64 flag, valid values [32|64]." ])
|
|
61
61
|
|
|
62
62
|
#
|
|
63
63
|
# Options for the 'ps' command.
|
|
64
64
|
#
|
|
65
65
|
@@ps_opts = Rex::Parser::Arguments.new(
|
|
66
|
+
"-S" => [ true, "String to search for (converts to regex)" ],
|
|
66
67
|
"-h" => [ false, "Help menu." ],
|
|
67
|
-
"-
|
|
68
|
-
"-
|
|
69
|
-
"-s" => [ false, "Show only SYSTEM processes" ],
|
|
68
|
+
"-A" => [ true, "Filters processes on architecture (x86 or x86_64)" ],
|
|
69
|
+
"-s" => [ false, "Show only SYSTEM processes" ],
|
|
70
70
|
"-U" => [ true, "Filters processes on the user using the supplied RegEx" ])
|
|
71
71
|
|
|
72
72
|
#
|
|
73
73
|
# Options for the 'suspend' command.
|
|
74
74
|
#
|
|
75
75
|
@@suspend_opts = Rex::Parser::Arguments.new(
|
|
76
|
-
"-h" => [ false, "Help menu."
|
|
76
|
+
"-h" => [ false, "Help menu." ],
|
|
77
77
|
"-c" => [ false, "Continues suspending or resuming even if an error is encountered"],
|
|
78
|
-
"-r" => [ false, "Resumes the target processes instead of suspending"
|
|
78
|
+
"-r" => [ false, "Resumes the target processes instead of suspending" ])
|
|
79
79
|
|
|
80
80
|
#
|
|
81
81
|
# List of supported commands.
|
|
@@ -93,7 +93,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
93
93
|
"kill" => "Terminate a process",
|
|
94
94
|
"ps" => "List running processes",
|
|
95
95
|
"reboot" => "Reboots the remote computer",
|
|
96
|
-
"reg"
|
|
96
|
+
"reg" => "Modify and interact with the remote registry",
|
|
97
97
|
"rev2self" => "Calls RevertToSelf() on the remote machine",
|
|
98
98
|
"shell" => "Drop into a system command shell",
|
|
99
99
|
"shutdown" => "Shuts down the remote computer",
|
|
@@ -105,7 +105,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
105
105
|
"clearev" => [ "stdapi_sys_eventlog_open", "stdapi_sys_eventlog_clear" ],
|
|
106
106
|
"drop_token" => [ "stdapi_sys_config_drop_token" ],
|
|
107
107
|
"execute" => [ "stdapi_sys_process_execute" ],
|
|
108
|
-
"getpid" => [ "stdapi_sys_process_getpid"
|
|
108
|
+
"getpid" => [ "stdapi_sys_process_getpid" ],
|
|
109
109
|
"getprivs" => [ "stdapi_sys_config_getprivs" ],
|
|
110
110
|
"getuid" => [ "stdapi_sys_config_getuid" ],
|
|
111
111
|
"getsid" => [ "stdapi_sys_config_getsid" ],
|
|
@@ -113,7 +113,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
113
113
|
"kill" => [ "stdapi_sys_process_kill" ],
|
|
114
114
|
"ps" => [ "stdapi_sys_process_get_processes" ],
|
|
115
115
|
"reboot" => [ "stdapi_sys_power_exitwindows" ],
|
|
116
|
-
"reg"
|
|
116
|
+
"reg" => [
|
|
117
117
|
"stdapi_registry_load_key",
|
|
118
118
|
"stdapi_registry_unload_key",
|
|
119
119
|
"stdapi_registry_open_key",
|
|
@@ -169,7 +169,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
169
169
|
interact = false
|
|
170
170
|
desktop = false
|
|
171
171
|
channelized = nil
|
|
172
|
-
hidden
|
|
172
|
+
hidden = nil
|
|
173
173
|
from_mem = false
|
|
174
174
|
dummy_exec = "cmd"
|
|
175
175
|
cmd_args = nil
|
|
@@ -422,23 +422,24 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
422
422
|
# Lists running processes.
|
|
423
423
|
#
|
|
424
424
|
def cmd_ps(*args)
|
|
425
|
+
if args.include?('-h')
|
|
426
|
+
cmd_ps_help
|
|
427
|
+
return true
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
# Init vars
|
|
425
431
|
processes = client.sys.process.get_processes
|
|
426
|
-
|
|
432
|
+
search_term = nil
|
|
433
|
+
|
|
434
|
+
# Parse opts
|
|
435
|
+
@@ps_opts.parse(args) { |opt, idx, val|
|
|
427
436
|
case opt
|
|
428
|
-
when
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
|
434
|
-
processes.each do |proc|
|
|
435
|
-
if val.nil? or val.empty?
|
|
436
|
-
print_line "You must supply a search term!"
|
|
437
|
-
return false
|
|
438
|
-
end
|
|
439
|
-
searched_procs << proc if proc["name"].match(/#{val}/)
|
|
437
|
+
when '-S'
|
|
438
|
+
search_term = val
|
|
439
|
+
if search_term.nil?
|
|
440
|
+
print_error("Enter a search term")
|
|
441
|
+
return true
|
|
440
442
|
end
|
|
441
|
-
processes = searched_procs
|
|
442
443
|
when "-A"
|
|
443
444
|
print_line "Filtering on arch..."
|
|
444
445
|
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
|
@@ -448,14 +449,14 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
448
449
|
print_line "You must select either x86 or x86_64"
|
|
449
450
|
return false
|
|
450
451
|
end
|
|
451
|
-
searched_procs << proc
|
|
452
|
+
searched_procs << proc if proc["arch"] == val
|
|
452
453
|
end
|
|
453
454
|
processes = searched_procs
|
|
454
455
|
when "-s"
|
|
455
456
|
print_line "Filtering on SYSTEM processes..."
|
|
456
457
|
searched_procs = Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessList.new
|
|
457
458
|
processes.each do |proc|
|
|
458
|
-
searched_procs << proc
|
|
459
|
+
searched_procs << proc if proc["user"] == "NT AUTHORITY\\SYSTEM"
|
|
459
460
|
end
|
|
460
461
|
processes = searched_procs
|
|
461
462
|
when "-U"
|
|
@@ -466,22 +467,25 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
466
467
|
print_line "You must supply a search term!"
|
|
467
468
|
return false
|
|
468
469
|
end
|
|
469
|
-
searched_procs << proc
|
|
470
|
+
searched_procs << proc if proc["user"].match(/#{val}/)
|
|
470
471
|
end
|
|
471
472
|
processes = searched_procs
|
|
472
473
|
end
|
|
473
|
-
|
|
474
|
+
}
|
|
475
|
+
|
|
474
476
|
if (processes.length == 0)
|
|
475
477
|
print_line("No running processes were found.")
|
|
476
478
|
else
|
|
479
|
+
tbl = processes.to_table('SearchTerm' => search_term)
|
|
477
480
|
print_line
|
|
478
|
-
print_line(
|
|
479
|
-
print_line
|
|
481
|
+
print_line(tbl.to_s)
|
|
480
482
|
end
|
|
481
483
|
return true
|
|
482
484
|
end
|
|
483
485
|
|
|
484
486
|
def cmd_ps_help
|
|
487
|
+
print_line "Usage: ps [ options ]"
|
|
488
|
+
print_line
|
|
485
489
|
print_line "Use the command with no arguments to see all running processes."
|
|
486
490
|
print_line "The following options can be used to filter those results:"
|
|
487
491
|
|
|
@@ -529,12 +533,12 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
529
533
|
end
|
|
530
534
|
|
|
531
535
|
# Initiailze vars
|
|
532
|
-
key
|
|
533
|
-
value
|
|
534
|
-
data
|
|
535
|
-
type
|
|
536
|
+
key = nil
|
|
537
|
+
value = nil
|
|
538
|
+
data = nil
|
|
539
|
+
type = nil
|
|
536
540
|
wowflag = 0x0000
|
|
537
|
-
rem
|
|
541
|
+
rem = nil
|
|
538
542
|
|
|
539
543
|
@@reg_opts.parse(args) { |opt, idx, val|
|
|
540
544
|
case opt
|
|
@@ -544,13 +548,13 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
544
548
|
"Interact with the target machine's registry.\n" +
|
|
545
549
|
@@reg_opts.usage +
|
|
546
550
|
"COMMANDS:\n\n" +
|
|
547
|
-
" enumkey
|
|
548
|
-
" createkey
|
|
549
|
-
" deletekey
|
|
551
|
+
" enumkey Enumerate the supplied registry key [-k <key>]\n" +
|
|
552
|
+
" createkey Create the supplied registry key [-k <key>]\n" +
|
|
553
|
+
" deletekey Delete the supplied registry key [-k <key>]\n" +
|
|
550
554
|
" queryclass Queries the class of the supplied key [-k <key>]\n" +
|
|
551
|
-
" setval
|
|
552
|
-
" deleteval
|
|
553
|
-
" queryval
|
|
555
|
+
" setval Set a registry value [-k <key> -v <val> -d <data>]\n" +
|
|
556
|
+
" deleteval Delete the supplied registry value [-k <key> -v <val>]\n" +
|
|
557
|
+
" queryval Queries the data contents of a value [-k <key> -v <val>]\n\n")
|
|
554
558
|
return false
|
|
555
559
|
when "-k"
|
|
556
560
|
key = val
|
|
@@ -641,11 +645,11 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
641
645
|
when "deletekey"
|
|
642
646
|
open_key = nil
|
|
643
647
|
if not rem
|
|
644
|
-
open_key = client.sys.registry.open_key(root_key,
|
|
648
|
+
open_key = client.sys.registry.open_key(root_key, nil, KEY_WRITE + wowflag)
|
|
645
649
|
else
|
|
646
650
|
remote_key = client.sys.registry.open_remote_key(rem, root_key)
|
|
647
651
|
if remote_key
|
|
648
|
-
open_key = remote_key.open_key(
|
|
652
|
+
open_key = remote_key.open_key(nil, KEY_WRITE + wowflag)
|
|
649
653
|
end
|
|
650
654
|
end
|
|
651
655
|
open_key.delete_key(base_key)
|
|
@@ -672,7 +676,7 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
672
676
|
|
|
673
677
|
open_key.set_value(value, client.sys.registry.type2str(type), data)
|
|
674
678
|
|
|
675
|
-
print_line("
|
|
679
|
+
print_line("Successfully set #{value} of #{type}.")
|
|
676
680
|
|
|
677
681
|
when "deleteval"
|
|
678
682
|
if (value == nil)
|
|
@@ -859,11 +863,11 @@ class Console::CommandDispatcher::Stdapi::Sys
|
|
|
859
863
|
args.uniq!
|
|
860
864
|
diff = args - valid_pids.map {|e| e.to_s}
|
|
861
865
|
if not diff.empty? # then we had an invalid pid
|
|
862
|
-
print_error("The following pids are not valid:
|
|
866
|
+
print_error("The following pids are not valid: #{diff.join(", ").to_s}.")
|
|
863
867
|
if continue
|
|
864
868
|
print_status("Continuing. Invalid args have been removed from the list.")
|
|
865
869
|
else
|
|
866
|
-
print_error("Quitting.
|
|
870
|
+
print_error("Quitting. Use -c to continue using only the valid pids.")
|
|
867
871
|
return false
|
|
868
872
|
end
|
|
869
873
|
end
|
|
@@ -912,4 +916,3 @@ end
|
|
|
912
916
|
end
|
|
913
917
|
end
|
|
914
918
|
end
|
|
915
|
-
|
|
@@ -89,7 +89,7 @@ class Console::CommandDispatcher::Stdapi::Ui
|
|
|
89
89
|
def cmd_uictl(*args)
|
|
90
90
|
if (args.length < 2)
|
|
91
91
|
print_line(
|
|
92
|
-
"Usage: uictl [enable/disable] [keyboard/mouse]")
|
|
92
|
+
"Usage: uictl [enable/disable] [keyboard/mouse/all]")
|
|
93
93
|
return true
|
|
94
94
|
end
|
|
95
95
|
|
|
@@ -102,6 +102,10 @@ class Console::CommandDispatcher::Stdapi::Ui
|
|
|
102
102
|
when 'mouse'
|
|
103
103
|
print_line("Enabling mouse...")
|
|
104
104
|
client.ui.enable_mouse
|
|
105
|
+
when 'all'
|
|
106
|
+
print_line("Enabling all...")
|
|
107
|
+
client.ui.enable_keyboard
|
|
108
|
+
client.ui.enable_mouse
|
|
105
109
|
else
|
|
106
110
|
print_error("Unsupported user interface device: #{args[1]}")
|
|
107
111
|
end
|
|
@@ -113,6 +117,10 @@ class Console::CommandDispatcher::Stdapi::Ui
|
|
|
113
117
|
when 'mouse'
|
|
114
118
|
print_line("Disabling mouse...")
|
|
115
119
|
client.ui.disable_mouse
|
|
120
|
+
when 'all'
|
|
121
|
+
print_line("Disabling all...")
|
|
122
|
+
client.ui.disable_keyboard
|
|
123
|
+
client.ui.disable_mouse
|
|
116
124
|
else
|
|
117
125
|
print_error("Unsupported user interface device: #{args[1]}")
|
|
118
126
|
end
|
|
@@ -12,7 +12,6 @@ module Ui
|
|
|
12
12
|
#
|
|
13
13
|
###
|
|
14
14
|
class Console::CommandDispatcher::Stdapi::Webcam
|
|
15
|
-
|
|
16
15
|
Klass = Console::CommandDispatcher::Stdapi::Webcam
|
|
17
16
|
|
|
18
17
|
include Console::CommandDispatcher
|
|
@@ -33,17 +32,16 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|
|
33
32
|
"webcam_list" => [ "webcam_list" ],
|
|
34
33
|
"webcam_snap" => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
|
|
35
34
|
"webcam_stream" => [ "webcam_start", "webcam_get_frame", "webcam_stop" ],
|
|
36
|
-
"record_mic" => [ "webcam_audio_record" ]
|
|
35
|
+
"record_mic" => [ "webcam_audio_record" ]
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
all.delete_if do |cmd,
|
|
38
|
+
all.delete_if do |cmd, _desc|
|
|
40
39
|
del = false
|
|
41
40
|
reqs[cmd].each do |req|
|
|
42
41
|
next if client.commands.include? req
|
|
43
42
|
del = true
|
|
44
43
|
break
|
|
45
44
|
end
|
|
46
|
-
|
|
47
45
|
del
|
|
48
46
|
end
|
|
49
47
|
|
|
@@ -58,23 +56,26 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|
|
58
56
|
end
|
|
59
57
|
|
|
60
58
|
def cmd_webcam_list
|
|
61
|
-
|
|
62
|
-
client.webcam.webcam_list.each_with_index { |name, indx|
|
|
63
|
-
print_line("#{indx + 1}: #{name}")
|
|
64
|
-
}
|
|
65
|
-
return true
|
|
66
|
-
rescue
|
|
59
|
+
if client.webcam.webcam_list.length == 0
|
|
67
60
|
print_error("No webcams were found")
|
|
68
|
-
return
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
client.webcam.webcam_list.each_with_index do |name, indx|
|
|
65
|
+
print_line("#{indx + 1}: #{name}")
|
|
69
66
|
end
|
|
70
67
|
end
|
|
71
68
|
|
|
72
69
|
def cmd_webcam_snap(*args)
|
|
70
|
+
if client.webcam.webcam_list.length == 0
|
|
71
|
+
print_error("Target does not have a webcam")
|
|
72
|
+
return
|
|
73
|
+
end
|
|
74
|
+
|
|
73
75
|
path = Rex::Text.rand_text_alpha(8) + ".jpeg"
|
|
74
76
|
quality = 50
|
|
75
77
|
view = true
|
|
76
78
|
index = 1
|
|
77
|
-
wc_list = []
|
|
78
79
|
|
|
79
80
|
webcam_snap_opts = Rex::Parser::Arguments.new(
|
|
80
81
|
"-h" => [ false, "Help Banner" ],
|
|
@@ -84,51 +85,44 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|
|
84
85
|
"-v" => [ true, "Automatically view the JPEG image (Default: '#{view}')" ]
|
|
85
86
|
)
|
|
86
87
|
|
|
87
|
-
webcam_snap_opts.parse(
|
|
88
|
+
webcam_snap_opts.parse(args) do |opt, _idx, val|
|
|
88
89
|
case opt
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
when "-h"
|
|
91
|
+
print_line("Usage: webcam_snap [options]\n")
|
|
92
|
+
print_line("Grab a frame from the specified webcam.")
|
|
93
|
+
print_line(webcam_snap_opts.usage)
|
|
94
|
+
return
|
|
95
|
+
when "-i"
|
|
96
|
+
index = val.to_i
|
|
97
|
+
when "-q"
|
|
98
|
+
quality = val.to_i
|
|
99
|
+
when "-p"
|
|
100
|
+
path = val
|
|
101
|
+
when "-v"
|
|
102
|
+
view = false if val =~ /^(f|n|0)/i
|
|
102
103
|
end
|
|
103
|
-
|
|
104
|
+
end
|
|
105
|
+
|
|
104
106
|
begin
|
|
105
|
-
|
|
106
|
-
|
|
107
|
+
print_status("Starting...")
|
|
108
|
+
client.webcam.webcam_start(index)
|
|
109
|
+
webcam_started = true
|
|
110
|
+
data = client.webcam.webcam_get_frame(quality)
|
|
111
|
+
print_good("Got frame")
|
|
112
|
+
ensure
|
|
113
|
+
client.webcam.webcam_stop if webcam_started
|
|
114
|
+
print_status("Stopped")
|
|
107
115
|
end
|
|
108
|
-
if wc_list.length > 0
|
|
109
|
-
begin
|
|
110
|
-
print_status("Starting...")
|
|
111
|
-
client.webcam.webcam_start(index)
|
|
112
|
-
data = client.webcam.webcam_get_frame(quality)
|
|
113
|
-
print_good("Got frame")
|
|
114
|
-
ensure
|
|
115
|
-
client.webcam.webcam_stop
|
|
116
|
-
print_status("Stopped")
|
|
117
|
-
end
|
|
118
116
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
end
|
|
123
|
-
path = ::File.expand_path( path )
|
|
124
|
-
print_line( "Webcam shot saved to: #{path}" )
|
|
125
|
-
Rex::Compat.open_file( path ) if view
|
|
117
|
+
if data
|
|
118
|
+
::File.open(path, 'wb') do |fd|
|
|
119
|
+
fd.write(data)
|
|
126
120
|
end
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
return false
|
|
121
|
+
path = ::File.expand_path(path)
|
|
122
|
+
print_line("Webcam shot saved to: #{path}")
|
|
123
|
+
Rex::Compat.open_file(path) if view
|
|
131
124
|
end
|
|
125
|
+
true
|
|
132
126
|
end
|
|
133
127
|
|
|
134
128
|
def cmd_webcam_chat(*args)
|
|
@@ -144,39 +138,42 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|
|
144
138
|
"-s" => [ false, "WebSocket server" ]
|
|
145
139
|
)
|
|
146
140
|
|
|
147
|
-
webcam_chat_opts.parse(
|
|
141
|
+
webcam_chat_opts.parse(args) do |opt, _idx, val|
|
|
148
142
|
case opt
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
143
|
+
when "-h"
|
|
144
|
+
print_line("Usage: webcam_chat [options]\n")
|
|
145
|
+
print_line("Starts a video conversation with your target.")
|
|
146
|
+
print_line("Browser Requirements:")
|
|
147
|
+
print_line("Chrome: version 23 or newer")
|
|
148
|
+
print_line("Firefox: version 22 or newer")
|
|
149
|
+
print_line(webcam_chat_opts.usage)
|
|
150
|
+
return
|
|
151
|
+
when "-s"
|
|
152
|
+
server = val.to_s
|
|
159
153
|
end
|
|
160
|
-
|
|
161
|
-
|
|
154
|
+
end
|
|
162
155
|
|
|
163
156
|
begin
|
|
164
157
|
print_status("Webcam chat session initialized.")
|
|
165
158
|
client.webcam.webcam_chat(server)
|
|
166
|
-
rescue RuntimeError => e
|
|
159
|
+
rescue RuntimeError => e
|
|
167
160
|
print_error(e.message)
|
|
168
161
|
end
|
|
169
162
|
end
|
|
170
163
|
|
|
171
164
|
def cmd_webcam_stream(*args)
|
|
165
|
+
if client.webcam.webcam_list.length == 0
|
|
166
|
+
print_error("Target does not have a webcam")
|
|
167
|
+
return
|
|
168
|
+
end
|
|
169
|
+
|
|
172
170
|
print_status("Starting...")
|
|
173
|
-
stream_path
|
|
171
|
+
stream_path = Rex::Text.rand_text_alpha(8) + ".jpeg"
|
|
174
172
|
player_path = Rex::Text.rand_text_alpha(8) + ".html"
|
|
175
173
|
duration = 1800
|
|
176
174
|
quality = 50
|
|
177
175
|
view = true
|
|
178
176
|
index = 1
|
|
179
|
-
wc_list = []
|
|
180
177
|
|
|
181
178
|
webcam_snap_opts = Rex::Parser::Arguments.new(
|
|
182
179
|
"-h" => [ false, "Help Banner" ],
|
|
@@ -188,30 +185,30 @@ class Console::CommandDispatcher::Stdapi::Webcam
|
|
|
188
185
|
"-v" => [ true, "Automatically view the stream (Default: '#{view}')" ]
|
|
189
186
|
)
|
|
190
187
|
|
|
191
|
-
webcam_snap_opts.parse(
|
|
188
|
+
webcam_snap_opts.parse(args) do |opt, _idx, val|
|
|
192
189
|
case opt
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
190
|
+
when "-h"
|
|
191
|
+
print_line("Usage: webcam_stream [options]\n")
|
|
192
|
+
print_line("Stream from the specified webcam.")
|
|
193
|
+
print_line(webcam_snap_opts.usage)
|
|
194
|
+
return
|
|
195
|
+
when "-d"
|
|
196
|
+
duration = val.to_i
|
|
197
|
+
when "-i"
|
|
198
|
+
index = val.to_i
|
|
199
|
+
when "-q"
|
|
200
|
+
quality = val.to_i
|
|
201
|
+
when "-s"
|
|
202
|
+
stream_path = val
|
|
203
|
+
when "-t"
|
|
204
|
+
player_path = val
|
|
205
|
+
when "-v"
|
|
206
|
+
view = false if val =~ /^(f|n|0)/i
|
|
210
207
|
end
|
|
211
|
-
|
|
208
|
+
end
|
|
212
209
|
|
|
213
210
|
print_status("Preparing player...")
|
|
214
|
-
html =
|
|
211
|
+
html = %|<html>
|
|
215
212
|
<head>
|
|
216
213
|
<META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
|
|
217
214
|
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
|
|
@@ -264,7 +261,7 @@ Status : <span id="status"></span>
|
|
|
264
261
|
end
|
|
265
262
|
if view
|
|
266
263
|
print_status("Opening player at: #{player_path}")
|
|
267
|
-
Rex::Compat.open_file(player_path)
|
|
264
|
+
Rex::Compat.open_file(player_path)
|
|
268
265
|
else
|
|
269
266
|
print_status("Please open the player manually with a browser: #{player_path}")
|
|
270
267
|
end
|
|
@@ -272,72 +269,70 @@ Status : <span id="status"></span>
|
|
|
272
269
|
print_status("Streaming...")
|
|
273
270
|
begin
|
|
274
271
|
client.webcam.webcam_start(index)
|
|
275
|
-
|
|
272
|
+
webcam_started = true
|
|
273
|
+
::Timeout.timeout(duration) do
|
|
276
274
|
while client do
|
|
277
275
|
data = client.webcam.webcam_get_frame(quality)
|
|
278
276
|
if data
|
|
279
277
|
::File.open(stream_path, 'wb') do |f|
|
|
280
|
-
|
|
278
|
+
f.write(data)
|
|
281
279
|
end
|
|
282
280
|
data = nil
|
|
283
281
|
end
|
|
284
282
|
end
|
|
285
|
-
|
|
283
|
+
end
|
|
286
284
|
rescue ::Timeout::Error
|
|
287
285
|
ensure
|
|
288
|
-
client.webcam.webcam_stop
|
|
286
|
+
client.webcam.webcam_stop if webcam_started
|
|
289
287
|
end
|
|
290
288
|
|
|
291
289
|
print_status("Stopped")
|
|
292
290
|
end
|
|
293
291
|
|
|
294
292
|
def cmd_record_mic(*args)
|
|
295
|
-
path
|
|
296
|
-
play
|
|
297
|
-
duration
|
|
293
|
+
path = Rex::Text.rand_text_alpha(8) + ".wav"
|
|
294
|
+
play = true
|
|
295
|
+
duration = 1
|
|
298
296
|
|
|
299
297
|
record_mic_opts = Rex::Parser::Arguments.new(
|
|
300
298
|
"-h" => [ false, "Help Banner" ],
|
|
301
299
|
"-d" => [ true, "Number of seconds to record (Default: 1)" ],
|
|
302
|
-
"-f" => [ true, "The wav file path (Default: '#{::File.expand_path(
|
|
300
|
+
"-f" => [ true, "The wav file path (Default: '#{::File.expand_path('[randomname].wav')}')" ],
|
|
303
301
|
"-p" => [ true, "Automatically play the captured audio (Default: '#{play}')" ]
|
|
304
302
|
)
|
|
305
303
|
|
|
306
|
-
record_mic_opts.parse(
|
|
304
|
+
record_mic_opts.parse(args) do |opt, _idx, val|
|
|
307
305
|
case opt
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
306
|
+
when "-h"
|
|
307
|
+
print_line("Usage: record_mic [options]\n")
|
|
308
|
+
print_line("Records audio from the default microphone.")
|
|
309
|
+
print_line(record_mic_opts.usage)
|
|
310
|
+
return
|
|
311
|
+
when "-d"
|
|
312
|
+
duration = val.to_i
|
|
313
|
+
when "-f"
|
|
314
|
+
path = val
|
|
315
|
+
when "-p"
|
|
316
|
+
play = false if val =~ /^(f|n|0)/i
|
|
319
317
|
end
|
|
320
|
-
|
|
318
|
+
end
|
|
321
319
|
|
|
322
320
|
print_status("Starting...")
|
|
323
321
|
data = client.webcam.record_mic(duration)
|
|
324
322
|
print_status("Stopped")
|
|
325
323
|
|
|
326
|
-
if
|
|
327
|
-
::File.open(
|
|
328
|
-
fd.write(
|
|
324
|
+
if data
|
|
325
|
+
::File.open(path, 'wb') do |fd|
|
|
326
|
+
fd.write(data)
|
|
329
327
|
end
|
|
330
|
-
path = ::File.expand_path(
|
|
331
|
-
print_line(
|
|
332
|
-
Rex::Compat.play_sound(
|
|
328
|
+
path = ::File.expand_path(path)
|
|
329
|
+
print_line("Audio saved to: #{path}")
|
|
330
|
+
Rex::Compat.play_sound(path) if play
|
|
333
331
|
end
|
|
334
|
-
|
|
332
|
+
true
|
|
335
333
|
end
|
|
336
|
-
|
|
337
334
|
end
|
|
338
|
-
|
|
339
335
|
end
|
|
340
336
|
end
|
|
341
337
|
end
|
|
342
338
|
end
|
|
343
|
-
|