Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- login as: admin
- Using keyboard-interactive authentication.
- Password:
- Access denied
- Using keyboard-interactive authentication.
- Password:
- Access denied
- Using keyboard-interactive authentication.
- Password:
- login as: admin
- Using keyboard-interactive authentication.
- Password:
- Last login: Tue Jan 14 08:03:52 UTC 2020 from jump.dcloud.local on pts/0
- Copyright 2004-2019, Cisco and/or its affiliates. All rights reserved.
- Cisco is a registered trademark of Cisco Systems, Inc.
- All other trademarks are property of their respective owners.
- Cisco Fire Linux OS v6.5.0 (build 4)
- Cisco Firepower Threat Defense for VMWare v6.5.0 (build 115)
- > expert
- **************************************************************
- NOTICE - Shell access will be deprecated in future releases
- and will be replaced with a separate expert mode CLI.
- **************************************************************
- admin@ngfw2:~$ sudo su
- We trust you have received the usual lecture from the local System
- Administrator. It usually boils down to these three things:
- #1) Respect the privacy of others.
- #2) Think before you type.
- #3) With great power comes great responsibility.
- Password:
- root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctft/firepower.py
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta http-equiv="Pragma" content="no-cache" />
- <title>Item does not exist. | Web File Transfer Server</title>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta name="description" content="" />
- <meta name="author" content="" />
- <link rel="shortcut icon" href="/__chsps__/images/favicon.ico" />
- <!-- Le styles -->
- <link href="/__chsps__/libs/bootstrap/css/bootstrap.min.css"
- rel="stylesheet" type="text/css" />
- <link href="/__chsps__/css/main.css" rel="stylesheet" type="text/css" />
- <link href="/__chsps__/theme/main.css" rel="stylesheet" type="text/css" />
- </head>
- <body class="full-height">
- <div class="container-fluid pad-after-navbar full-height">
- <div class="row-fluid display-table full-height">
- <div class="span6 center center-vertical">
- <h1 class="heading-large pad-bottom">
- <i class="icon-html-entity icon-large round margin-right">
- &#9988;
- </i>
- Item does not exist.
- </h1>
- <div class="separator"></div>
- <p class="lead pad-top">
- The requested URL is not associated with any file or folder.
- </p>
- <a
- href="/home/"
- class="btn btn-primary btn-huge"
- >
- Go to home page
- </a>
- </div>
- </div>
- </div> <!-- Fluid container -->
- </body>
- <script src="/__chsps__/libs/jquery/jquery-1.11.1.js"></script>
- <script src="/__chsps__/libs/bootstrap/js/bootstrap.min.js"></script>
- <script src="/__chsps__/theme/main.js"></script>
- root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py
- #!/usr/bin/python
- __author__ = "CXD First Responder Team"
- __copyright__ = "Copyright 2019, Cisco Systems Inc."
- __version__ = "1.0"
- __maintainer__ = "first-responder@cisco.com"
- __status__ = "Production"
- import os
- import sys
- import glob
- import time
- import logging
- import tarfile
- import argparse
- import datetime
- import subprocess
- from distutils.version import LooseVersion
- import json
- '''
- ----------------
- ARGUMENT PARSING
- ----------------
- '''
- # Create and argument parser
- parser = argparse.ArgumentParser()
- # Define the allowable arguments to be used with this script
- parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
- parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
- parser.add_argument("--core-days", help="Specify number of days back to search for core files (Default 30 days)")
- parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_tru")
- # Parse the provided arguments to update run-time variables
- args = parser.parse_args()
- # Set the run-time variables
- case = str(args.case)
- token = str(args.token)
- # If core-days was specified, use the specified value. Otherwise, set to 30 days.
- if args.core_days:
- core_days = int(args.core_days)
- else:
- core_days = 30
- # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
- if args.auto_upload:
- verbose = False
- else:
- verbose = True
- '''
- --------------------------
- CONSTANT / LOG DEFINITIONS
- --------------------------
- '''
- # A logger used to log information to file for auto-upload mode
- logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %')
- # Constant used to convert raw bytes into a human readable format
- suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
- '''
- --------------------
- FUNCTION DEFINITIONS
- --------------------
- '''
- # This function uploads a file to cxd.cisco.com
- def upload_file(username, token, file):
- # Define the command to upload
- command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
- try:
- # Attempt to run the upload command
- subprocess.check_output(command)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered while trying to run the upload command
- print e.output
- # Print to screen or logs to a file depending on whether or not --auto-upload was used
- def smart_print(msg,color=None,level='info'):
- if verbose:
- # Format message to output in "red"
- if color == 'red':
- print('\033[91m%s \033[00m' % msg)
- # Format message to output in "green"
- elif color == 'green':
- print('\033[92m%s \033[00m' % msg)
- # Print message normally (no colors)
- else:
- print(msg)
- else:
- # Log with INFO level severity
- if level == 'info':
- logging.info(msg)
- # Log with WARNING level severity
- elif level == 'warn':
- logging.warn(msg)
- # Scan all possible core file directories and returns files that match the file structure for core files
- def scan_core_files():
- # Define an empty list to store our matching core files
- core_glob = []
- # Make sure the directory exists before trying to read it
- if os.path.isdir('/ngfw/var/common/'):
- # Gather core files from this directory
- core_glob.extend(glob.glob('/ngfw/var/common/core_*'))
- # Make sure the directory exists before trying to read it
- elif os.path.isdir('/var/common/'):
- # Gather core files from this directory
- core_glob.extend(glob.glob('/var/common/core_*'))
- # Make sure the directory exists before trying to read it
- if os.path.isdir('/ngfw/var/data/cores/'):
- # Gather core files from this directory
- core_glob.extend(glob.glob('/ngfw/var/data/cores/core.*.gz'))
- return core_glob
- # Takes a list of files, determines their create time, and only returns files created within the last X days
- def get_recent_files(file_glob):
- # Define an empty list to store our files to return
- recent_files = []
- # Get the comparison time by subtracting X number of days from current date
- start_time = datetime.datetime.now() + datetime.timedelta(-core_days)
- # Loop through the passed in list of files
- for core in file_glob:
- # Get the create time for the file
- c_time = datetime.datetime.utcfromtimestamp(os.path.getctime(core))
- # Compare the create time to our start_time
- if c_time >= start_time:
- # Add the file to the list if it was recent
- recent_files.append(core)
- else:
- # Do nothing if the file is older than our start time
- continue
- return recent_files
- # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
- def yes_or_no(question, default="yes"):
- valid = {"yes": True, "y": True, "ye": True,
- "no": False, "n": False}
- if default is None:
- prompt = " [y/n] "
- elif default == "yes":
- prompt = " [Y/n] "
- elif default == "no":
- prompt = " [y/N] "
- else:
- raise ValueError("invalid default answer: '%s'" % default)
- while True:
- sys.stdout.write(question + prompt)
- choice = raw_input().lower()
- if default is not None and choice == '':
- return valid[default]
- elif choice in valid:
- return valid[choice]
- else:
- sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
- # Takes a file size in bytes and returns a file size in a more human readable format
- def humansize(nbytes):
- if nbytes == 0: return '0 B'
- count = 0
- while nbytes >= 1024 and count < len(suffixes_humansize) - 1:
- nbytes /= 1024.
- count += 1
- f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
- return '%s %s' % (f, suffixes_humansize[count])
- # Notify First Responder about the script running.
- def notify_first_responder(username, token):
- # Creat variable file_handler and file_path to hold file handler and path objects respectivly.
- # Initialise handler to None
- file_handler = None
- file_path = '/var/common/first_responder_notify'
- # Check if /var/common/ exists
- if os.path.exists('/var/common/'):
- # If /var/common does exist, creat the file, and assign object to file_handler.
- file_handler = open(file_path, 'wb+')
- # Check if the file_handler is not None, i.e. the file handler object was created.
- if file_handler is not None:
- # If the file_handler was created, write the data.
- file_handler.write('')
- # Close the file handler.
- file_handler.close()
- # Upload the file to First Responder.
- upload_file(username, token, file_path)
- # Builds a manifest file for the core bundle with information required to decode them, returns the file path
- def build_core_manifest(cores):
- uuid = modelnumber = sw_version = sw_build = full_version = snort_conf = snort_version = manager_version = None
- data = {'device_info': [], 'cores': []}
- with open('/etc/sf/ims.conf') as ims:
- for line in ims:
- #Gets the UUID of the device to match the cores to a specific troubleshoot file
- if "APPLIANCE_UUID" in line:
- uuid = line.split('=')[1].strip()
- #Gets the device modelnumber
- elif "MODELNUMBER" in line:
- modelnumber = line.split('=')[1].strip()
- #Gets the device model
- elif "MODEL=" in line:
- model = line.split('=')[1].strip()
- #Gets Software Version
- elif "SWVERSION" in line:
- sw_version = line.split('=')[1].strip()
- #Gets Software Build
- elif "SWBUILD" in line:
- sw_build = line.split('=')[1].strip()
- #Builds a full version in the format sw_version-sw_build
- if sw_version and sw_build:
- full_version = sw_version + "-" + sw_build
- else:
- smart_print('Unable to determine version.', 'red', 'warn')
- #Builds the device_info data structure to dump to the manifest file
- data['device_info'].append({'uuid': uuid,
- 'model': model,
- 'modelnumber': modelnumber,
- 'version': full_version})
- #Gets the Path to snort.conf, FMCs will not have this file
- if modelnumber != '66':
- if os.path.isdir('/var/sf/detection_engines/'):
- snort_conf = glob.glob("/var/sf/detection_engines/*/snort.conf")[0]
- smart_print('Located snort.conf file at %s' %snort_conf, 'green')
- elif os.path.isdir('/ngfw/var/sf/detection_engines/'):
- snort_conf = glob.glob("/ngfw/var/sf/detection_engines/*/snort.conf")[0]
- smart_print('Located snort.conf file at %s' %snort_conf, 'green')
- else:
- smart_print('Did not locate snort.conf file', 'red', 'warn')
- #If snort.conf was found take the snort version from it
- if snort_conf:
- try:
- with open(''.join(snort_conf)) as snort:
- for line in snort:
- if "# Snort" in line:
- snort_version = line.split(':')[1].strip()
- if "# DC Version" in line:
- manager_version = line.split(':')[1].strip()
- # Appends the snort version
- data['device_info'][0]['snort_version'] = snort_version
- data['device_info'][0]['manager_version'] = manager_version
- except:
- smart_print('Cannot open file %s' % snort_conf, 'red', 'warn')
- else:
- smart_print('No snort.conf file found', 'red', 'warn')
- #Adds the list of cores to the manifest file
- for core in recent_cores:
- data['cores'].extend({core})
- # Creates the Manifest file in /var/tmp and writes to it
- with open("/var/tmp/first_responder_firepower_core.mf", 'w') as manifest:
- json.dump(data, manifest, indent=4, sort_keys=True)
- manifest.close()
- return manifest.name
- '''
- -----------
- SCRIPT BODY
- -----------
- '''
- # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
- if os.path.isfile('/etc/sf/ims.conf'):
- os_version = None
- with open('/etc/sf/ims.conf') as ims:
- for line in ims:
- if "OSVERSION" in line:
- os_version = line.split('=')[1].strip()
- # Check to make sure the device we are running on is at least version 6.2.3
- if os_version:
- # Compare the running OS Version against a static value of 6.2.3
- if LooseVersion(os_version) < LooseVersion('6.2.3'):
- # Warn the user if the device is a version lower than 6.2.3
- smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
- else:
- # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
- smart_print('Device version is greater than or equal to 6.2.3.', 'green')
- else:
- # Catch all if we fail to set os_version. Warn the user anyway.
- smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- else:
- # Catch all if ims.conf does not exist. Warn the user anyway.
- smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- # Run the troubleshoot
- try:
- notify_first_responder(case, token)
- smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
- # Open devnull in order to redirect stderr to /dev/null and avoid output
- with open(os.devnull, 'w') as devnull:
- # Set the tshoot variable to the resulting file name
- tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
- # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
- smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
- # Notify the user that upload is being attempted
- smart_print('Attempting troubleshoot upload...')
- # Call the upload function with the credentials and troubleshoot file as the upload file
- upload_file(case, token, tshoot)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered and exit
- print e.output
- exit()
- # Scan for the existence of core files
- core_files = scan_core_files()
- # Check to see if the scan returned any core files
- if core_files:
- # Take the core files, pull out the recent ones only
- recent_cores = get_recent_files(core_files)
- # If there are recent core files start processing
- if recent_cores:
- # Notify user that recent core files were found
- smart_print("Found the following core files:")
- # Iterate through the list to show the file names of the relevant core file matches
- for recent in recent_cores:
- # Get the size of the core file to show to the user
- size = humansize(os.path.getsize(recent))
- # Display the filesize and file-name to the user
- smart_print("\t(%s) - %s" % (size,recent))
- # Check to see if we should prompt the user for input (i.e if --auto-upload is specified or not)
- if verbose:
- # Prompt user if they want to upload core files as well.
- core_answer = yes_or_no("Would you like to upload these core files as well?")
- else:
- # If auto-upload is specified, then just set the answer to yes.
- core_answer = True
- # Check users answer to make sure we should proceed
- if core_answer:
- # Define the file location and structure of the tarball that will store the compressed core files
- core_tar = "/var/tmp/cores_%s-%s.tar.gz" % (case, int(time.time()))
- # Gets Data to build the Manifest File
- manifest = build_core_manifest(recent_cores)
- # Open a new tarfile with write permissions and gzip compression
- tar = tarfile.open(core_tar, "w:gz")
- #Adds Manifest file to the tarball root
- tar.add(manifest, arcname="first_responder_firepower_core.mf")
- # Iterate through the core files and add them to the tarball
- for core in recent_cores:
- # Notify the user of the file we are currently adding
- smart_print("\t+Adding %s to tarball" % core)
- # Add the file to the tarball
- tar.add(core)
- # Close the tarball and save the file to the /var/tmp/ directory
- tar.close()
- # Notify the user of the successful creation of the tarball
- smart_print('Successfully created %s' % core_tar, 'green')
- # Notify the user that an upload is being attempted for the core file tarball
- smart_print('Attempting core file upload...')
- # Upload the core file bundle
- upload_file(case, token, core_tar)
- else:
- # Notify user that core files are on the system, but were old / not recent
- smart_print('Core files located, but they are more than %s day(s) old. Skipping core file processing' % core_days)
- else:
- # Notify user that core files were found on the device
- smart_print('No core files found. Skipping core file processing')root@ngfw2:/home/admin#
- root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688276537 -t 5hUIcTKwPIPljVPd --auto-upload
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 15816 100 15816 0 0 2378 0 0:00:06 0:00:06 --:--:-- 9585
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 175 100 175 0 0 25 0 0:00:07 0:00:06 0:00:01 97
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 0 78.2M 0 0 0 0 0 0 --:--:-- 0:00:06 --:--:-- 0
- root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 15816 100 15816 0 0 2413 0 0:00:06 0:00:06 --:--:-- 10190
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 79.6M 0 0 100 79.6M 0 2537k 0:00:32 0:00:32 --:--:-- 2802k
- root@ngfw2:/home/admin# ls
- first-responder.log
- root@ngfw2:/home/admin# mkdir shakeeb
- root@ngfw2:/home/admin# cd shakeeb
- root@ngfw2:/home/admin/shakeeb# cat > auto_uploadpy
- ^C
- root@ngfw2:/home/admin/shakeeb# cat > auto_upload.py
- #!/usr/bin/python
- __author__ = "CXD First Responder Team"
- __copyright__ = "Copyright 2019, Cisco Systems Inc."
- __version__ = "1.0"
- __maintainer__ = "first-responder@cisco.com"
- __status__ = "Production"
- import os
- import sys
- import glob
- import time
- import logging
- import tarfile
- import argparse
- import datetime
- import subprocess
- from distutils.version import LooseVersion
- import json
- '''
- ----------------
- ARGUMENT PARSING
- ----------------
- '''
- # Create and argument parser
- parser = argparse.ArgumentParser()
- # Define the allowable arguments to be used with this script
- parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
- parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
- parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_tru")
- # Parse the provided arguments to update run-time variables
- args = parser.parse_args()
- # Set the run-time variables
- case = str(args.case)
- token = str(args.token)
- # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
- if args.auto_upload:
- verbose = False
- else:
- verbose = True
- '''
- --------------------------
- CONSTANT / LOG DEFINITIONS
- --------------------------
- '''
- # A logger used to log information to file for auto-upload mode
- logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %')
- # Constant used to convert raw bytes into a human readable format
- suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
- '''
- --------------------
- FUNCTION DEFINITIONS
- --------------------
- '''
- # This function uploads a file to cxd.cisco.com
- def upload_file(username, token, file):
- # Define the command to upload
- command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
- try:
- # Attempt to run the upload command
- print "Uploading STart"
- print "Running command %s"%command
- subprocess.check_output(command)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered while trying to run the upload command
- print e.output
- # Print to screen or logs to a file depending on whether or not --auto-upload was used
- def smart_print(msg,color=None,level='info'):
- if verbose:
- # Format message to output in "red"
- if color == 'red':
- print('\033[91m%s \033[00m' % msg)
- # Format message to output in "green"
- elif color == 'green':
- print('\033[92m%s \033[00m' % msg)
- # Print message normally (no colors)
- else:
- print(msg)
- else:
- # Log with INFO level severity
- if level == 'info':
- logging.info(msg)
- # Log with WARNING level severity
- elif level == 'warn':
- logging.warn(msg)
- # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
- def yes_or_no(question, default="yes"):
- valid = {"yes": True, "y": True, "ye": True,
- "no": False, "n": False}
- if default is None:
- prompt = " [y/n] "
- elif default == "yes":
- prompt = " [Y/n] "
- elif default == "no":
- prompt = " [y/N] "
- else:
- raise ValueError("invalid default answer: '%s'" % default)
- while True:
- sys.stdout.write(question + prompt)
- choice = raw_input().lower()
- if default is not None and choice == '':
- return valid[default]
- elif choice in valid:
- return valid[choice]
- else:
- sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
- # Takes a file size in bytes and returns a file size in a more human readable format
- # Notify First Responder about the script running.
- def notify_first_responder(username, token):
- # Creat variable file_handler and file_path to hold file handler and path objects respectivly.
- # Initialise handler to None
- file_handler = None
- file_path = '/var/common/first_responder_notify'
- # Check if /var/common/ exists
- if os.path.exists('/var/common/'):
- # If /var/common does exist, creat the file, and assign object to file_handler.
- file_handler = open(file_path, 'wb+')
- # Check if the file_handler is not None, i.e. the file handler object was created.
- if file_handler is not None:
- # If the file_handler was created, write the data.
- file_handler.write('')
- # Close the file handler.
- file_handler.close()
- # Upload the file to First Responder.
- upload_file(username, token, file_path)
- '''
- -----------
- SCRIPT BODY
- -----------
- '''
- # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
- if os.path.isfile('/etc/sf/ims.conf'):
- os_version = None
- with open('/etc/sf/ims.conf') as ims:
- for line in ims:
- if "OSVERSION" in line:
- os_version = line.split('=')[1].strip()
- # Check to make sure the device we are running on is at least version 6.2.3
- if os_version:
- # Compare the running OS Version against a static value of 6.2.3
- if LooseVersion(os_version) < LooseVersion('6.2.3'):
- # Warn the user if the device is a version lower than 6.2.3
- smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
- else:
- # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
- smart_print('Device version is greater than or equal to 6.2.3.', 'green')
- else:
- # Catch all if we fail to set os_version. Warn the user anyway.
- smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- else:
- # Catch all if ims.conf does not exist. Warn the user anyway.
- smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- # Run the troubleshoot
- try:
- notify_first_responder(case, token)
- smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
- # Open devnull in order to redirect stderr to /dev/null and avoid output
- with open(os.devnull, 'w') as devnull:
- # Set the tshoot variable to the resulting file name
- #tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
- tshoot="/ngfw/var/common/results-01-22-2020--85847.tar.gz"
- # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
- smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
- # Notify the user that upload is being attempted
- smart_print('Attempting troubleshoot upload...')
- # Call the upload function with the credentials and troubleshoot file as the upload file
- upload_file(case, token, tshoot)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered and exit
- print e.output
- exit()
- ^C
- root@ngfw2:/home/admin/shakeeb# ls
- auto_upload.py auto_uploadpy
- root@ngfw2:/home/admin/shakeeb# rm *dy
- rm: cannot remove '*dy': No such file or directory
- root@ngfw2:/home/admin/shakeeb# rm a*dy
- rm: cannot remove 'a*dy': No such file or directory
- root@ngfw2:/home/admin/shakeeb# rm auto_uploadpy
- root@ngfw2:/home/admin/shakeeb# vim auto_upload.py
- root@ngfw2:/home/admin/shakeeb# ls
- auto_upload.py
- root@ngfw2:/home/admin/shakeeb# python auto_upload.py
- usage: auto_upload.py [-h] -c CASE -t TOKEN [--auto-upload]
- auto_upload.py: error: argument -c/--case is required
- root@ngfw2:/home/admin/shakeeb# history
- 1 exit
- 2 curl -k https://cxd.cisco.com/public/ctft/firepower.py
- 3 curl -k https://cxd.cisco.com/public/ctfr/firepower.py
- 4 curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688276537 -t 5hUIcTKwPIPljVPd --auto-upload
- 5 curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
- 6 ls
- 7 mkdir shakeeb
- 8 cd shakeeb
- 9 cat > auto_uploadpy
- 10 cat > auto_upload.py
- 11 ls
- 12 rm *dy
- 13 rm a*dy
- 14 rm auto_uploadpy
- 15 vim auto_upload.py
- 16 ls
- 17 python auto_upload.py
- 18 history
- root@ngfw2:/home/admin/shakeeb# python auto_upload.py -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
- Uploading STart
- Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/var/common/first_responder_notify']
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
- Uploading STart
- Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-27-2020--110418.tar.gz']
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 79.6M 0 0 100 79.6M 0 2779k 0:00:29 0:00:29 --:--:-- 2929k
- root@ngfw2:/home/admin/shakeeb#
- root@ngfw2:/home/admin/shakeeb#
- root@ngfw2:/home/admin/shakeeb# vi auto_upload.py
- root@ngfw2:/home/admin/shakeeb# ls
- auto_upload.py first-responder.log
- root@ngfw2:/home/admin/shakeeb# vi first-responder.log
- root@ngfw2:/home/admin/shakeeb# vi first-responder.log
- root@ngfw2:/home/admin/shakeeb# rm first-responder.log
- root@ngfw2:/home/admin/shakeeb# ls
- auto_upload.py
- root@ngfw2:/home/admin/shakeeb# vi auto_upload.py
- root@ngfw2:/home/admin/shakeeb# python auto_upload.py -c 688278694 -t t4XUaMss4Pa8BHxs
- Device version is greater than or equal to 6.2.3.
- Uploading STart
- Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/var/common/first_responder_notify']
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
- Running sf_troubleshoot.pl to create troubleshooting file...
- Troubleshoot file successfully generated at /ngfw/var/common/results-01-27-2020--111114.tar.gz
- Attempting troubleshoot upload...
- Uploading STart
- Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-27-2020--111114.tar.gz']
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 79.7M 0 0 100 79.7M 0 2583k 0:00:31 0:00:31 --:--:-- 2829k
- root@ngfw2:/home/admin/shakeeb# la
- sh: la: command not found
- root@ngfw2:/home/admin/shakeeb# ls
- auto_upload.py first-responder.log
- root@ngfw2:/home/admin/shakeeb# mv auto_upload.py tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# cat first-responder.log
- root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# ls
- first-responder.log tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py
- usage: tshoot_uploader.py [-h] -c CASE -t TOKEN [--auto-upload]
- tshoot_uploader.py: error: argument -c/--case is required
- root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py ^C
- root@ngfw2:/home/admin/shakeeb# cat /var/common/first_responder_notify
- root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py -c 688278694 -t t4XUaMss4Pa8BHxs
- Device version is greater than or equal to 6.2.3.
- Running sf_troubleshoot.pl to create troubleshooting file...
- Troubleshoot file successfully generated at /ngfw/var/common/results-01-28-2020--81452.tar.gz
- Attempting troubleshoot upload...
- Starting Upload
- Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-28-2020--81452.tar.gz']
- % Total % Received % Xferd Average Speed Time Time Time Current
- Dload Upload Total Spent Left Speed
- 100 80.5M 0 0 100 80.5M 0 2308k 0:00:35 0:00:35 --:--:-- 2952k
- root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
- root@ngfw2:/home/admin/shakeeb# cat tshoot_uploader.py
- #!/usr/bin/python
- __author__ = "CXD First Responder Team"
- __copyright__ = "Copyright 2019, Cisco Systems Inc."
- __version__ = "1.0"
- __maintainer__ = "first-responder@cisco.com"
- __status__ = "Production"
- import os
- import sys
- import glob
- import time
- import logging
- import tarfile
- import argparse
- import datetime
- import subprocess
- from distutils.version import LooseVersion
- import json
- '''
- ----------------
- ARGUMENT PARSING
- ----------------
- '''
- # Create and argument parser
- parser = argparse.ArgumentParser()
- # Define the allowable arguments to be used with this script
- parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
- parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
- parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_true")
- # Parse the provided arguments to update run-time variables
- args = parser.parse_args()
- # Set the run-time variables
- case = str(args.case)
- token = str(args.token)
- # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
- if args.auto_upload:
- verbose = False
- else:
- verbose = True
- '''
- --------------------------
- CONSTANT / LOG DEFINITIONS
- --------------------------
- '''
- # A logger used to log information to file for auto-upload mode
- logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
- # Constant used to convert raw bytes into a human readable format
- suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
- '''
- --------------------
- FUNCTION DEFINITIONS
- --------------------
- '''
- # This function uploads a file to cxd.cisco.com
- def upload_file(username, token, file):
- # Define the command to upload
- command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
- try:
- # Attempt to run the upload command
- smart_print("Starting Upload")
- smart_print("Running command %s"%command)
- subprocess.check_output(command)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered while trying to run the upload command
- print e.output
- # Print to screen or logs to a file depending on whether or not --auto-upload was used
- def smart_print(msg,color=None,level='info'):
- if verbose:
- # Format message to output in "red"
- if color == 'red':
- print('\033[91m%s \033[00m' % msg)
- # Format message to output in "green"
- elif color == 'green':
- print('\033[92m%s \033[00m' % msg)
- # Print message normally (no colors)
- else:
- print(msg)
- else:
- # Log with INFO level severity
- if level == 'info':
- logging.info(msg)
- # Log with WARNING level severity
- elif level == 'warn':
- logging.warn(msg)
- # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
- def yes_or_no(question, default="yes"):
- valid = {"yes": True, "y": True, "ye": True,
- "no": False, "n": False}
- if default is None:
- prompt = " [y/n] "
- elif default == "yes":
- prompt = " [Y/n] "
- elif default == "no":
- prompt = " [y/N] "
- else:
- raise ValueError("invalid default answer: '%s'" % default)
- while True:
- sys.stdout.write(question + prompt)
- choice = raw_input().lower()
- if default is not None and choice == '':
- return valid[default]
- elif choice in valid:
- return valid[choice]
- else:
- sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
- '''
- -----------
- SCRIPT BODY
- -----------
- '''
- # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
- if os.path.isfile('/etc/sf/ims.conf'):
- os_version = None
- with open('/etc/sf/ims.conf') as ims:
- for line in ims:
- if "OSVERSION" in line:
- os_version = line.split('=')[1].strip()
- # Check to make sure the device we are running on is at least version 6.2.3
- if os_version:
- # Compare the running OS Version against a static value of 6.2.3
- if LooseVersion(os_version) < LooseVersion('6.2.3'):
- # Warn the user if the device is a version lower than 6.2.3
- smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
- else:
- # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
- smart_print('Device version is greater than or equal to 6.2.3.', 'green')
- else:
- # Catch all if we fail to set os_version. Warn the user anyway.
- smart_print('Unab/printle to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- else:
- # Catch all if ims.conf does not exist. Warn the user anyway.
- smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
- # Run the troubleshoot
- try:
- smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
- # Open devnull in order to redirect stderr to /dev/null and avoid output
- with open(os.devnull, 'w') as devnull:
- # Set the tshoot variable to the resulting file name
- tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
- # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
- smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
- # Notify the user that upload is being attempted
- smart_print('Attempting troubleshoot upload...')
- # Call the upload function with the credentials and troubleshoot file as the upload file
- upload_file(case, token, tshoot)
- except subprocess.CalledProcessError as e:
- # Print any errors that were encountered and exit
- print e.output
- exit()
- root@ngfw2:/home/admin/shakeeb#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement