@@ -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,40 @@ 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
+ vprint_status ( "Output for \" #{ datastore [ 'COMMAND' ] } \" :" )
124
+ vprint_line ( "#{ output } " )
125
+
126
+ report_note (
127
+ :rhost => datastore [ 'RHOSTS' ] ,
128
+ :rport => datastore [ 'RPORT' ] ,
129
+ :type => "psexec_command" ,
130
+ :name => datastore [ 'COMMAND' ] ,
131
+ :data => output
132
+ )
133
+
134
+ end
135
+
136
+ #check if our process is done using these files
137
+ def exclusive_access ( *files )
138
+ simple . connect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
139
+ files . each do |file |
140
+ begin
141
+ print_status ( "checking if the file is unlocked" )
142
+ fd = smb_open ( file , 'rwo' )
143
+ fd . close
144
+ rescue Rex ::Proto ::SMB ::Exceptions ::ErrorCode => accesserror
145
+ print_status ( "#{ peer } - Unable to get handle: #{ accesserror } " )
146
+ return false
147
+ end
148
+ simple . disconnect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
149
+ end
150
+ return true
108
151
end
109
152
153
+
110
154
# Removes files created during execution.
111
155
def cleanup_after ( *files )
112
156
simple . connect ( "\\ \\ #{ @ip } \\ #{ @smbshare } " )
0 commit comments