@@ -50,6 +50,8 @@ def initialize(info = {})
50
50
51
51
register_advanced_options ( [
52
52
OptString . new ( 'FILEPREFIX' , [ false , 'Add a custom prefix to the temporary files' , '' ] ) ,
53
+ OptInt . new ( 'DELAY' , [ true , 'Wait this many seconds before reading output and cleaning up' , 0 ] ) ,
54
+ OptInt . new ( 'RETRY' , [ true , 'Retry this many times to check if the process is complete' , 0 ] ) ,
53
55
] , self . class )
54
56
55
57
deregister_options ( 'RHOST' )
@@ -70,9 +72,21 @@ def run_host(ip)
70
72
print_error ( "#{ peer } - Unable to authenticate with given credentials: #{ autherror } " )
71
73
return
72
74
end
73
- if execute_command ( text , bat )
75
+ res = execute_command ( text , bat )
76
+
77
+ if res
78
+ for i in 0 ..( datastore [ 'RETRY' ] )
79
+ Rex . sleep ( datastore [ 'DELAY' ] )
80
+ # if the output file is still locked then the program is still likely running
81
+ if ( exclusive_access ( text ) )
82
+ break
83
+ elsif ( i == datastore [ 'RETRY' ] )
84
+ print_error ( "Command seems to still be executing. Try increasing RETRY and DELAY" )
85
+ end
86
+ end
74
87
get_output ( text )
75
88
end
89
+
76
90
cleanup_after ( text , bat )
77
91
disconnect
78
92
end
@@ -103,10 +117,42 @@ def get_output(file)
103
117
print_status ( "#{ peer } - Command finished with no output" )
104
118
return
105
119
end
106
- print_good ( "#{ peer } - Command completed successfuly! Output:" )
107
- print_line ( "#{ output } " )
120
+
121
+ # Report output
122
+ print_good ( "#{ peer } - Command completed successfuly!" )
123
+ if datastore [ 'VERBOSE' ]
124
+ print_status ( "Output for \" #{ datastore [ 'COMMAND' ] } \" :" )
125
+ print_line ( "#{ output } " )
126
+ end
127
+
128
+ report_note (
129
+ :rhost => datastore [ 'RHOSTS' ] ,
130
+ :rport => datastore [ 'RPORT' ] ,
131
+ :type => "psexec_command" ,
132
+ :name => datastore [ 'COMMAND' ] ,
133
+ :data => output
134
+ )
135
+
108
136
end
109
137
138
+ #check if our process is done using these files
139
+ def exclusive_access ( *files )
140
+ simple . connect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
141
+ files . each do |file |
142
+ begin
143
+ print_status ( "checking if the file is unlocked" )
144
+ fd = smb_open ( file , 'rwo' )
145
+ fd . close
146
+ rescue Rex ::Proto ::SMB ::Exceptions ::ErrorCode => accesserror
147
+ print_status ( "#{ peer } - Unable to get handle: #{ accesserror } " )
148
+ return false
149
+ end
150
+ simple . disconnect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
151
+ end
152
+ return true
153
+ end
154
+
155
+
110
156
# Removes files created during execution.
111
157
def cleanup_after ( *files )
112
158
simple . connect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
0 commit comments