def create(): """Create a job to remove the debugger file in some time (2 hours by default) Decorators: app.route catch_custom_exception Returns: str -- JSON string containing the success of the job creation and additional message. """ domain = request.form['domain'] if 'path' in request.form: path = request.form['path'] # replacement of the file field elif 'file' in request.form: path = '/' + request.form['file'] # legacy field else: path = None validated_inputs = check_inputs({'domain': domain, 'path': path}) if all(x is True for x in validated_inputs.values()): # If a job with this domain is not created yet, create a new one. # The new job will access domain.com?selfDesctruct in two hours # and will analyze output from it. success, message = JobManager.add_job(domain, path) else: success, message = process_failed_inputs(validated_inputs) return jsonify({ 'success': success, 'message': message, })
def delete(domain): """Delete a job from the "atq" queue. Decorators: app.route catch_custom_exception Arguments: domain {str} -- Domain from which the job creation request was sent. Returns: str -- JSON string containing the success of the job removal and an additional message. """ result_dict = {} if 'path' in request.form: path = request.form['path'] elif 'file' in request.form: path = '/' + request.form['file'] # paths must start with slash else: path = None if path: validated_inputs = check_inputs({'domain': domain, 'path': path}) else: validated_inputs = check_inputs({'domain': domain}) if all(x is True for x in validated_inputs.values()): if path: job_ids = JobManager.find_jobs(domain, path) if job_ids: job_id = job_ids[0] result_dict['success'], result_dict[ 'message'] = JobManager.delete_job(job_id) else: result_dict['success'] = False result_dict[ 'message'] = "There are no jobs for these domain and path." else: job_ids = JobManager.find_jobs(domain) if job_ids: for job_id in job_ids: # remove all debugger files for this domain path_found, path = JobManager.find_path_in_job(job_id) if path_found: result_dict[path] = JobManager.delete_job(job_id) else: result_dict[job_id] = JobManager.delete_job(job_id) else: result_dict['success'] = False result_dict['message'] = "There are no jobs for this domain." else: result_dict['success'], result_dict['message'] = process_failed_inputs( validated_inputs) return jsonify(result_dict)
def create(): """Create a job to remove the debugger file in some time (2 hours by default) Decorators: app.route catch_custom_exception Returns: str -- JSON string containing the success of the job creation and additional message. """ domain = request.form['domain'] if 'path' in request.form: path = request.form['path'] # replacement of the file field elif 'file' in request.form: path = '/' + request.form['file'] # legacy field # add the old debugger file to the database, so it can be later reported by Debugger Bot old_version = OldVersionFile.query.filter_by(link=domain+path).first() if not old_version: old_version_file = OldVersionFile(link=domain+path) db.session.add(old_version_file) db.session.commit() else: path = None validated_inputs = check_inputs({'domain': domain, 'path': path}) if all(x is True for x in validated_inputs.values()): # If a job with this domain is not created yet, create a new one. # The new job will access domain.com?selfDesctruct in two hours # and will analyze output from it. success, message = JobManager.add_job(domain, path) else: success, message = process_failed_inputs(validated_inputs) return jsonify({ 'success': success, 'message': message, })
def analyze(): """Try removing the debugger file and report the error if it occurs. Decorators: app.route catch_custom_exception Returns: str -- JSON string containing the success of the file removal, short description of the error and an additional message. """ domain = request.form['domain'] path = request.form['path'] validated_inputs = check_inputs({'domain': domain, 'path': path}) error = False if all(x is True for x in validated_inputs.values()): try: response = requests.get('http://' + domain + path, params={ 'selfDestruct': '1', 'silent': '1', }) if response.status_code == 200: if response.json() == {'success': True}: success = True message = "The file was removed successfully." else: success = False error = 'no output' message = "Link responded with 200 but didn't return any JSON." elif response.status_code == 404: success = True message = "The file has already been removed." else: success = False error = str(response.status_code) message = "The link returned " + error + " status code." except Timeout: success = False error = 'timeout' message = "Timeout occurred when accessing the link." except TooManyRedirects: success = False error = 'too many redirects' message = "There is a redirection loop at the link." except RequestException: success = False error = 'unknown' message = "Unknown exception occurred when trying to access the link." else: # if no domain or the domain wasn't validated against the regex success, message = process_failed_inputs(validated_inputs) if not success: try: link_without_query = response.url.split('?')[0] except UnboundLocalError: # response variable was not defined because of exception link_without_query = 'http://' + domain + path if app.config['FAILED_URL_HANDLER'] == 'all' or \ app.config['FAILED_URL_HANDLER'] == 'email': failed_link = FailedLink(link=link_without_query, error=error, message=message) db.session.add(failed_link) db.session.commit() if app.config['FAILED_URL_HANDLER'] == 'all' or \ app.config['FAILED_URL_HANDLER'] == 'bot': flock_message = "I failed to remove the following debugger file: " +\ link_without_query + "<br/>" + message +\ "<br/>Please make sure the file is removed and like this message." FlockAPI.send_message(flock_message, color='#FF0000') response = { 'success': success, 'message': message, } if error: response['error'] = error return jsonify(response)
def analyze(): """Try removing the debugger file and report the error if it occurs. Decorators: app.route catch_custom_exception Returns: str -- JSON string containing the success of the file removal, short description of the error and an additional message. """ domain = request.form['domain'] path = request.form['path'] validated_inputs = check_inputs({'domain': domain, 'path': path}) error = False if all(x is True for x in validated_inputs.values()): # Check if the file is of an old version. If so, an additional # line will be added to the message in Flock. old_version = OldVersionFile.query.filter_by(link=domain+path).first() if old_version: db.session.delete(old_version) # Try removing debugger file at domain.com/path_to_debugger. # Since old versions of debugger submit only filename and not # the path, it is necessary to check the wp-admin/debugger.php # path as well. success, error, message = send_self_destruct_request(domain, path) if not success: success = check_404_on_debugger(domain, path) if success: message = 'Debugger returned error when trying to be removed, ' +\ 'but was removed successfully.' if (error == '403' or error == 'unknown') and old_version: success, error, message = send_self_destruct_request( domain, '/wp-admin'+path) else: # if no domain or the domain wasn't validated against the regex success, message = process_failed_inputs(validated_inputs) error = False if not success: link = 'http://' + domain + path if app.config['FAILED_URL_HANDLER'] == 'all' or \ app.config['FAILED_URL_HANDLER'] == 'email': failed_link = FailedLink( link=link, error=error, message=message) db.session.add(failed_link) db.session.commit() if app.config['FAILED_URL_HANDLER'] == 'all' or \ app.config['FAILED_URL_HANDLER'] == 'bot': flock_message = "I failed to remove the following debugger file: " +\ link + "<br/>" + message +\ '<br/>Please try removing it via this <a href="' + link +\ '?selfDestruct">link</a> or delete it manually, and like this message.' FlockAPI.send_message(flock_message, color='#FF0000') response = { 'success': success, 'message': message, } if error: response['error'] = error return jsonify(response)