Advertisement
anatoxin_dust

Untitled

Jan 28th, 2020
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 39.64 KB | None | 0 0
  1. login as: admin
  2. Using keyboard-interactive authentication.
  3. Password:
  4. Access denied
  5. Using keyboard-interactive authentication.
  6. Password:
  7. Access denied
  8. Using keyboard-interactive authentication.
  9. Password:
  10. login as: admin
  11. Using keyboard-interactive authentication.
  12. Password:
  13. Last login: Tue Jan 14 08:03:52 UTC 2020 from jump.dcloud.local on pts/0
  14.  
  15. Copyright 2004-2019, Cisco and/or its affiliates. All rights reserved.
  16. Cisco is a registered trademark of Cisco Systems, Inc.
  17. All other trademarks are property of their respective owners.
  18.  
  19. Cisco Fire Linux OS v6.5.0 (build 4)
  20. Cisco Firepower Threat Defense for VMWare v6.5.0 (build 115)
  21.  
  22. > expert
  23. **************************************************************
  24. NOTICE - Shell access will be deprecated in future releases
  25. and will be replaced with a separate expert mode CLI.
  26. **************************************************************
  27. admin@ngfw2:~$ sudo su
  28.  
  29. We trust you have received the usual lecture from the local System
  30. Administrator. It usually boils down to these three things:
  31.  
  32. #1) Respect the privacy of others.
  33. #2) Think before you type.
  34. #3) With great power comes great responsibility.
  35.  
  36. Password:
  37. root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctft/firepower.py
  38. <!DOCTYPE html>
  39. <html>
  40. <head>
  41. <meta charset="utf-8" />
  42. <meta http-equiv="Pragma" content="no-cache" />
  43.  
  44. <title>Item does not exist. | Web File Transfer Server</title>
  45.  
  46. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  47. <meta name="description" content="" />
  48. <meta name="author" content="" />
  49.  
  50. <link rel="shortcut icon" href="/__chsps__/images/favicon.ico" />
  51.  
  52. <!-- Le styles -->
  53. <link href="/__chsps__/libs/bootstrap/css/bootstrap.min.css"
  54. rel="stylesheet" type="text/css" />
  55. <link href="/__chsps__/css/main.css" rel="stylesheet" type="text/css" />
  56. <link href="/__chsps__/theme/main.css" rel="stylesheet" type="text/css" />
  57.  
  58. </head>
  59.  
  60. <body class="full-height">
  61.  
  62.  
  63.  
  64. <div class="container-fluid pad-after-navbar full-height">
  65.  
  66.  
  67. <div class="row-fluid display-table full-height">
  68. <div class="span6 center center-vertical">
  69. <h1 class="heading-large pad-bottom">
  70. <i class="icon-html-entity icon-large round margin-right">
  71. &amp;#9988;
  72. </i>
  73. Item does not exist.
  74. </h1>
  75. <div class="separator"></div>
  76. <p class="lead pad-top">
  77. The requested URL is not associated with any file or folder.
  78. </p>
  79.  
  80. <a
  81. href="/home/"
  82. class="btn btn-primary btn-huge"
  83. >
  84. Go to home page
  85. </a>
  86.  
  87. </div>
  88. </div>
  89.  
  90.  
  91. </div> <!-- Fluid container -->
  92.  
  93. </body>
  94.  
  95. <script src="/__chsps__/libs/jquery/jquery-1.11.1.js"></script>
  96. <script src="/__chsps__/libs/bootstrap/js/bootstrap.min.js"></script>
  97. <script src="/__chsps__/theme/main.js"></script>
  98.  
  99. root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py
  100. #!/usr/bin/python
  101.  
  102. __author__ = "CXD First Responder Team"
  103. __copyright__ = "Copyright 2019, Cisco Systems Inc."
  104. __version__ = "1.0"
  105. __maintainer__ = "first-responder@cisco.com"
  106. __status__ = "Production"
  107.  
  108. import os
  109. import sys
  110. import glob
  111. import time
  112. import logging
  113. import tarfile
  114. import argparse
  115. import datetime
  116. import subprocess
  117. from distutils.version import LooseVersion
  118. import json
  119.  
  120. '''
  121. ----------------
  122. ARGUMENT PARSING
  123. ----------------
  124. '''
  125. # Create and argument parser
  126. parser = argparse.ArgumentParser()
  127. # Define the allowable arguments to be used with this script
  128. parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
  129. parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
  130. parser.add_argument("--core-days", help="Specify number of days back to search for core files (Default 30 days)")
  131. parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_tru")
  132.  
  133. # Parse the provided arguments to update run-time variables
  134. args = parser.parse_args()
  135.  
  136. # Set the run-time variables
  137. case = str(args.case)
  138. token = str(args.token)
  139. # If core-days was specified, use the specified value. Otherwise, set to 30 days.
  140. if args.core_days:
  141. core_days = int(args.core_days)
  142. else:
  143. core_days = 30
  144. # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
  145. if args.auto_upload:
  146. verbose = False
  147. else:
  148. verbose = True
  149. '''
  150. --------------------------
  151. CONSTANT / LOG DEFINITIONS
  152. --------------------------
  153. '''
  154.  
  155. # A logger used to log information to file for auto-upload mode
  156. logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %')
  157.  
  158. # Constant used to convert raw bytes into a human readable format
  159. suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  160.  
  161. '''
  162. --------------------
  163. FUNCTION DEFINITIONS
  164. --------------------
  165. '''
  166. # This function uploads a file to cxd.cisco.com
  167. def upload_file(username, token, file):
  168. # Define the command to upload
  169. command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
  170. try:
  171. # Attempt to run the upload command
  172. subprocess.check_output(command)
  173. except subprocess.CalledProcessError as e:
  174. # Print any errors that were encountered while trying to run the upload command
  175. print e.output
  176.  
  177. # Print to screen or logs to a file depending on whether or not --auto-upload was used
  178. def smart_print(msg,color=None,level='info'):
  179. if verbose:
  180. # Format message to output in "red"
  181. if color == 'red':
  182. print('\033[91m%s \033[00m' % msg)
  183. # Format message to output in "green"
  184. elif color == 'green':
  185. print('\033[92m%s \033[00m' % msg)
  186. # Print message normally (no colors)
  187. else:
  188. print(msg)
  189. else:
  190. # Log with INFO level severity
  191. if level == 'info':
  192. logging.info(msg)
  193. # Log with WARNING level severity
  194. elif level == 'warn':
  195. logging.warn(msg)
  196.  
  197. # Scan all possible core file directories and returns files that match the file structure for core files
  198. def scan_core_files():
  199. # Define an empty list to store our matching core files
  200. core_glob = []
  201. # Make sure the directory exists before trying to read it
  202. if os.path.isdir('/ngfw/var/common/'):
  203. # Gather core files from this directory
  204. core_glob.extend(glob.glob('/ngfw/var/common/core_*'))
  205. # Make sure the directory exists before trying to read it
  206. elif os.path.isdir('/var/common/'):
  207. # Gather core files from this directory
  208. core_glob.extend(glob.glob('/var/common/core_*'))
  209. # Make sure the directory exists before trying to read it
  210. if os.path.isdir('/ngfw/var/data/cores/'):
  211. # Gather core files from this directory
  212. core_glob.extend(glob.glob('/ngfw/var/data/cores/core.*.gz'))
  213. return core_glob
  214.  
  215. # Takes a list of files, determines their create time, and only returns files created within the last X days
  216. def get_recent_files(file_glob):
  217. # Define an empty list to store our files to return
  218. recent_files = []
  219. # Get the comparison time by subtracting X number of days from current date
  220. start_time = datetime.datetime.now() + datetime.timedelta(-core_days)
  221. # Loop through the passed in list of files
  222. for core in file_glob:
  223. # Get the create time for the file
  224. c_time = datetime.datetime.utcfromtimestamp(os.path.getctime(core))
  225. # Compare the create time to our start_time
  226. if c_time >= start_time:
  227. # Add the file to the list if it was recent
  228. recent_files.append(core)
  229. else:
  230. # Do nothing if the file is older than our start time
  231. continue
  232. return recent_files
  233.  
  234. # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
  235. def yes_or_no(question, default="yes"):
  236. valid = {"yes": True, "y": True, "ye": True,
  237. "no": False, "n": False}
  238. if default is None:
  239. prompt = " [y/n] "
  240. elif default == "yes":
  241. prompt = " [Y/n] "
  242. elif default == "no":
  243. prompt = " [y/N] "
  244. else:
  245. raise ValueError("invalid default answer: '%s'" % default)
  246.  
  247. while True:
  248. sys.stdout.write(question + prompt)
  249. choice = raw_input().lower()
  250. if default is not None and choice == '':
  251. return valid[default]
  252. elif choice in valid:
  253. return valid[choice]
  254. else:
  255. sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
  256.  
  257. # Takes a file size in bytes and returns a file size in a more human readable format
  258. def humansize(nbytes):
  259. if nbytes == 0: return '0 B'
  260. count = 0
  261. while nbytes >= 1024 and count < len(suffixes_humansize) - 1:
  262. nbytes /= 1024.
  263. count += 1
  264. f = ('%.2f' % nbytes).rstrip('0').rstrip('.')
  265. return '%s %s' % (f, suffixes_humansize[count])
  266.  
  267. # Notify First Responder about the script running.
  268. def notify_first_responder(username, token):
  269. # Creat variable file_handler and file_path to hold file handler and path objects respectivly.
  270. # Initialise handler to None
  271. file_handler = None
  272. file_path = '/var/common/first_responder_notify'
  273. # Check if /var/common/ exists
  274. if os.path.exists('/var/common/'):
  275. # If /var/common does exist, creat the file, and assign object to file_handler.
  276. file_handler = open(file_path, 'wb+')
  277. # Check if the file_handler is not None, i.e. the file handler object was created.
  278. if file_handler is not None:
  279. # If the file_handler was created, write the data.
  280. file_handler.write('')
  281. # Close the file handler.
  282. file_handler.close()
  283. # Upload the file to First Responder.
  284. upload_file(username, token, file_path)
  285.  
  286. # Builds a manifest file for the core bundle with information required to decode them, returns the file path
  287. def build_core_manifest(cores):
  288. uuid = modelnumber = sw_version = sw_build = full_version = snort_conf = snort_version = manager_version = None
  289. data = {'device_info': [], 'cores': []}
  290. with open('/etc/sf/ims.conf') as ims:
  291. for line in ims:
  292. #Gets the UUID of the device to match the cores to a specific troubleshoot file
  293. if "APPLIANCE_UUID" in line:
  294. uuid = line.split('=')[1].strip()
  295. #Gets the device modelnumber
  296. elif "MODELNUMBER" in line:
  297. modelnumber = line.split('=')[1].strip()
  298. #Gets the device model
  299. elif "MODEL=" in line:
  300. model = line.split('=')[1].strip()
  301. #Gets Software Version
  302. elif "SWVERSION" in line:
  303. sw_version = line.split('=')[1].strip()
  304. #Gets Software Build
  305. elif "SWBUILD" in line:
  306. sw_build = line.split('=')[1].strip()
  307. #Builds a full version in the format sw_version-sw_build
  308. if sw_version and sw_build:
  309. full_version = sw_version + "-" + sw_build
  310. else:
  311. smart_print('Unable to determine version.', 'red', 'warn')
  312. #Builds the device_info data structure to dump to the manifest file
  313. data['device_info'].append({'uuid': uuid,
  314. 'model': model,
  315. 'modelnumber': modelnumber,
  316. 'version': full_version})
  317. #Gets the Path to snort.conf, FMCs will not have this file
  318. if modelnumber != '66':
  319. if os.path.isdir('/var/sf/detection_engines/'):
  320. snort_conf = glob.glob("/var/sf/detection_engines/*/snort.conf")[0]
  321. smart_print('Located snort.conf file at %s' %snort_conf, 'green')
  322.  
  323. elif os.path.isdir('/ngfw/var/sf/detection_engines/'):
  324. snort_conf = glob.glob("/ngfw/var/sf/detection_engines/*/snort.conf")[0]
  325. smart_print('Located snort.conf file at %s' %snort_conf, 'green')
  326. else:
  327. smart_print('Did not locate snort.conf file', 'red', 'warn')
  328. #If snort.conf was found take the snort version from it
  329. if snort_conf:
  330. try:
  331. with open(''.join(snort_conf)) as snort:
  332. for line in snort:
  333. if "# Snort" in line:
  334. snort_version = line.split(':')[1].strip()
  335. if "# DC Version" in line:
  336. manager_version = line.split(':')[1].strip()
  337. # Appends the snort version
  338. data['device_info'][0]['snort_version'] = snort_version
  339. data['device_info'][0]['manager_version'] = manager_version
  340. except:
  341. smart_print('Cannot open file %s' % snort_conf, 'red', 'warn')
  342. else:
  343. smart_print('No snort.conf file found', 'red', 'warn')
  344. #Adds the list of cores to the manifest file
  345. for core in recent_cores:
  346. data['cores'].extend({core})
  347. # Creates the Manifest file in /var/tmp and writes to it
  348. with open("/var/tmp/first_responder_firepower_core.mf", 'w') as manifest:
  349. json.dump(data, manifest, indent=4, sort_keys=True)
  350. manifest.close()
  351. return manifest.name
  352.  
  353. '''
  354. -----------
  355. SCRIPT BODY
  356. -----------
  357. '''
  358. # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
  359. if os.path.isfile('/etc/sf/ims.conf'):
  360. os_version = None
  361. with open('/etc/sf/ims.conf') as ims:
  362. for line in ims:
  363. if "OSVERSION" in line:
  364. os_version = line.split('=')[1].strip()
  365. # Check to make sure the device we are running on is at least version 6.2.3
  366. if os_version:
  367. # Compare the running OS Version against a static value of 6.2.3
  368. if LooseVersion(os_version) < LooseVersion('6.2.3'):
  369. # Warn the user if the device is a version lower than 6.2.3
  370. smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
  371. else:
  372. # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
  373. smart_print('Device version is greater than or equal to 6.2.3.', 'green')
  374. else:
  375. # Catch all if we fail to set os_version. Warn the user anyway.
  376. smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  377. else:
  378. # Catch all if ims.conf does not exist. Warn the user anyway.
  379. smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  380.  
  381. # Run the troubleshoot
  382. try:
  383. notify_first_responder(case, token)
  384. smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
  385. # Open devnull in order to redirect stderr to /dev/null and avoid output
  386. with open(os.devnull, 'w') as devnull:
  387. # Set the tshoot variable to the resulting file name
  388. tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
  389. # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
  390. smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
  391. # Notify the user that upload is being attempted
  392. smart_print('Attempting troubleshoot upload...')
  393. # Call the upload function with the credentials and troubleshoot file as the upload file
  394. upload_file(case, token, tshoot)
  395. except subprocess.CalledProcessError as e:
  396. # Print any errors that were encountered and exit
  397. print e.output
  398. exit()
  399.  
  400. # Scan for the existence of core files
  401. core_files = scan_core_files()
  402. # Check to see if the scan returned any core files
  403. if core_files:
  404. # Take the core files, pull out the recent ones only
  405. recent_cores = get_recent_files(core_files)
  406. # If there are recent core files start processing
  407. if recent_cores:
  408. # Notify user that recent core files were found
  409. smart_print("Found the following core files:")
  410. # Iterate through the list to show the file names of the relevant core file matches
  411. for recent in recent_cores:
  412. # Get the size of the core file to show to the user
  413. size = humansize(os.path.getsize(recent))
  414. # Display the filesize and file-name to the user
  415. smart_print("\t(%s) - %s" % (size,recent))
  416. # Check to see if we should prompt the user for input (i.e if --auto-upload is specified or not)
  417. if verbose:
  418. # Prompt user if they want to upload core files as well.
  419. core_answer = yes_or_no("Would you like to upload these core files as well?")
  420. else:
  421. # If auto-upload is specified, then just set the answer to yes.
  422. core_answer = True
  423. # Check users answer to make sure we should proceed
  424. if core_answer:
  425. # Define the file location and structure of the tarball that will store the compressed core files
  426. core_tar = "/var/tmp/cores_%s-%s.tar.gz" % (case, int(time.time()))
  427. # Gets Data to build the Manifest File
  428. manifest = build_core_manifest(recent_cores)
  429. # Open a new tarfile with write permissions and gzip compression
  430. tar = tarfile.open(core_tar, "w:gz")
  431. #Adds Manifest file to the tarball root
  432. tar.add(manifest, arcname="first_responder_firepower_core.mf")
  433. # Iterate through the core files and add them to the tarball
  434. for core in recent_cores:
  435. # Notify the user of the file we are currently adding
  436. smart_print("\t+Adding %s to tarball" % core)
  437. # Add the file to the tarball
  438. tar.add(core)
  439. # Close the tarball and save the file to the /var/tmp/ directory
  440. tar.close()
  441. # Notify the user of the successful creation of the tarball
  442. smart_print('Successfully created %s' % core_tar, 'green')
  443. # Notify the user that an upload is being attempted for the core file tarball
  444. smart_print('Attempting core file upload...')
  445. # Upload the core file bundle
  446. upload_file(case, token, core_tar)
  447. else:
  448. # Notify user that core files are on the system, but were old / not recent
  449. smart_print('Core files located, but they are more than %s day(s) old. Skipping core file processing' % core_days)
  450. else:
  451. # Notify user that core files were found on the device
  452. smart_print('No core files found. Skipping core file processing')root@ngfw2:/home/admin#
  453. root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688276537 -t 5hUIcTKwPIPljVPd --auto-upload
  454. % Total % Received % Xferd Average Speed Time Time Time Current
  455. Dload Upload Total Spent Left Speed
  456. 100 15816 100 15816 0 0 2378 0 0:00:06 0:00:06 --:--:-- 9585
  457. % Total % Received % Xferd Average Speed Time Time Time Current
  458. Dload Upload Total Spent Left Speed
  459. 100 175 100 175 0 0 25 0 0:00:07 0:00:06 0:00:01 97
  460. % Total % Received % Xferd Average Speed Time Time Time Current
  461. Dload Upload Total Spent Left Speed
  462. 0 78.2M 0 0 0 0 0 0 --:--:-- 0:00:06 --:--:-- 0
  463. root@ngfw2:/home/admin# curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
  464. % Total % Received % Xferd Average Speed Time Time Time Current
  465. Dload Upload Total Spent Left Speed
  466. 100 15816 100 15816 0 0 2413 0 0:00:06 0:00:06 --:--:-- 10190
  467. % Total % Received % Xferd Average Speed Time Time Time Current
  468. Dload Upload Total Spent Left Speed
  469. 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
  470. % Total % Received % Xferd Average Speed Time Time Time Current
  471. Dload Upload Total Spent Left Speed
  472. 100 79.6M 0 0 100 79.6M 0 2537k 0:00:32 0:00:32 --:--:-- 2802k
  473. root@ngfw2:/home/admin# ls
  474. first-responder.log
  475. root@ngfw2:/home/admin# mkdir shakeeb
  476. root@ngfw2:/home/admin# cd shakeeb
  477. root@ngfw2:/home/admin/shakeeb# cat > auto_uploadpy
  478. ^C
  479. root@ngfw2:/home/admin/shakeeb# cat > auto_upload.py
  480. #!/usr/bin/python
  481.  
  482. __author__ = "CXD First Responder Team"
  483. __copyright__ = "Copyright 2019, Cisco Systems Inc."
  484. __version__ = "1.0"
  485. __maintainer__ = "first-responder@cisco.com"
  486. __status__ = "Production"
  487.  
  488. import os
  489. import sys
  490. import glob
  491. import time
  492. import logging
  493. import tarfile
  494. import argparse
  495. import datetime
  496. import subprocess
  497. from distutils.version import LooseVersion
  498. import json
  499.  
  500. '''
  501. ----------------
  502. ARGUMENT PARSING
  503. ----------------
  504. '''
  505. # Create and argument parser
  506. parser = argparse.ArgumentParser()
  507. # Define the allowable arguments to be used with this script
  508. parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
  509. parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
  510. parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_tru")
  511.  
  512. # Parse the provided arguments to update run-time variables
  513. args = parser.parse_args()
  514.  
  515. # Set the run-time variables
  516. case = str(args.case)
  517. token = str(args.token)
  518. # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
  519. if args.auto_upload:
  520. verbose = False
  521. else:
  522. verbose = True
  523. '''
  524. --------------------------
  525. CONSTANT / LOG DEFINITIONS
  526. --------------------------
  527. '''
  528.  
  529. # A logger used to log information to file for auto-upload mode
  530. logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %')
  531.  
  532. # Constant used to convert raw bytes into a human readable format
  533. suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  534.  
  535. '''
  536. --------------------
  537. FUNCTION DEFINITIONS
  538. --------------------
  539. '''
  540. # This function uploads a file to cxd.cisco.com
  541. def upload_file(username, token, file):
  542. # Define the command to upload
  543. command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
  544. try:
  545. # Attempt to run the upload command
  546. print "Uploading STart"
  547. print "Running command %s"%command
  548. subprocess.check_output(command)
  549. except subprocess.CalledProcessError as e:
  550. # Print any errors that were encountered while trying to run the upload command
  551. print e.output
  552.  
  553. # Print to screen or logs to a file depending on whether or not --auto-upload was used
  554. def smart_print(msg,color=None,level='info'):
  555. if verbose:
  556. # Format message to output in "red"
  557. if color == 'red':
  558. print('\033[91m%s \033[00m' % msg)
  559. # Format message to output in "green"
  560. elif color == 'green':
  561. print('\033[92m%s \033[00m' % msg)
  562. # Print message normally (no colors)
  563. else:
  564. print(msg)
  565. else:
  566. # Log with INFO level severity
  567. if level == 'info':
  568. logging.info(msg)
  569. # Log with WARNING level severity
  570. elif level == 'warn':
  571. logging.warn(msg)
  572.  
  573.  
  574.  
  575. # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
  576. def yes_or_no(question, default="yes"):
  577. valid = {"yes": True, "y": True, "ye": True,
  578. "no": False, "n": False}
  579. if default is None:
  580. prompt = " [y/n] "
  581. elif default == "yes":
  582. prompt = " [Y/n] "
  583. elif default == "no":
  584. prompt = " [y/N] "
  585. else:
  586. raise ValueError("invalid default answer: '%s'" % default)
  587.  
  588. while True:
  589. sys.stdout.write(question + prompt)
  590. choice = raw_input().lower()
  591. if default is not None and choice == '':
  592. return valid[default]
  593. elif choice in valid:
  594. return valid[choice]
  595. else:
  596. sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
  597.  
  598. # Takes a file size in bytes and returns a file size in a more human readable format
  599.  
  600.  
  601. # Notify First Responder about the script running.
  602. def notify_first_responder(username, token):
  603. # Creat variable file_handler and file_path to hold file handler and path objects respectivly.
  604. # Initialise handler to None
  605. file_handler = None
  606. file_path = '/var/common/first_responder_notify'
  607. # Check if /var/common/ exists
  608. if os.path.exists('/var/common/'):
  609. # If /var/common does exist, creat the file, and assign object to file_handler.
  610. file_handler = open(file_path, 'wb+')
  611. # Check if the file_handler is not None, i.e. the file handler object was created.
  612. if file_handler is not None:
  613. # If the file_handler was created, write the data.
  614. file_handler.write('')
  615. # Close the file handler.
  616. file_handler.close()
  617. # Upload the file to First Responder.
  618. upload_file(username, token, file_path)
  619.  
  620.  
  621. '''
  622. -----------
  623. SCRIPT BODY
  624. -----------
  625. '''
  626. # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
  627. if os.path.isfile('/etc/sf/ims.conf'):
  628. os_version = None
  629. with open('/etc/sf/ims.conf') as ims:
  630. for line in ims:
  631. if "OSVERSION" in line:
  632. os_version = line.split('=')[1].strip()
  633. # Check to make sure the device we are running on is at least version 6.2.3
  634. if os_version:
  635. # Compare the running OS Version against a static value of 6.2.3
  636. if LooseVersion(os_version) < LooseVersion('6.2.3'):
  637. # Warn the user if the device is a version lower than 6.2.3
  638. smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
  639. else:
  640. # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
  641. smart_print('Device version is greater than or equal to 6.2.3.', 'green')
  642. else:
  643. # Catch all if we fail to set os_version. Warn the user anyway.
  644. smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  645. else:
  646. # Catch all if ims.conf does not exist. Warn the user anyway.
  647. smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  648.  
  649. # Run the troubleshoot
  650. try:
  651. notify_first_responder(case, token)
  652. smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
  653. # Open devnull in order to redirect stderr to /dev/null and avoid output
  654. with open(os.devnull, 'w') as devnull:
  655. # Set the tshoot variable to the resulting file name
  656. #tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
  657. tshoot="/ngfw/var/common/results-01-22-2020--85847.tar.gz"
  658. # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
  659. smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
  660. # Notify the user that upload is being attempted
  661. smart_print('Attempting troubleshoot upload...')
  662. # Call the upload function with the credentials and troubleshoot file as the upload file
  663. upload_file(case, token, tshoot)
  664. except subprocess.CalledProcessError as e:
  665. # Print any errors that were encountered and exit
  666. print e.output
  667. exit()
  668. ^C
  669. root@ngfw2:/home/admin/shakeeb# ls
  670. auto_upload.py auto_uploadpy
  671. root@ngfw2:/home/admin/shakeeb# rm *dy
  672. rm: cannot remove '*dy': No such file or directory
  673. root@ngfw2:/home/admin/shakeeb# rm a*dy
  674. rm: cannot remove 'a*dy': No such file or directory
  675. root@ngfw2:/home/admin/shakeeb# rm auto_uploadpy
  676. root@ngfw2:/home/admin/shakeeb# vim auto_upload.py
  677. root@ngfw2:/home/admin/shakeeb# ls
  678. auto_upload.py
  679. root@ngfw2:/home/admin/shakeeb# python auto_upload.py
  680. usage: auto_upload.py [-h] -c CASE -t TOKEN [--auto-upload]
  681. auto_upload.py: error: argument -c/--case is required
  682. root@ngfw2:/home/admin/shakeeb# history
  683. 1 exit
  684. 2 curl -k https://cxd.cisco.com/public/ctft/firepower.py
  685. 3 curl -k https://cxd.cisco.com/public/ctfr/firepower.py
  686. 4 curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688276537 -t 5hUIcTKwPIPljVPd --auto-upload
  687. 5 curl -k https://cxd.cisco.com/public/ctfr/firepower.py | python - -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
  688. 6 ls
  689. 7 mkdir shakeeb
  690. 8 cd shakeeb
  691. 9 cat > auto_uploadpy
  692. 10 cat > auto_upload.py
  693. 11 ls
  694. 12 rm *dy
  695. 13 rm a*dy
  696. 14 rm auto_uploadpy
  697. 15 vim auto_upload.py
  698. 16 ls
  699. 17 python auto_upload.py
  700. 18 history
  701. root@ngfw2:/home/admin/shakeeb# python auto_upload.py -c 688278694 -t t4XUaMss4Pa8BHxs --auto-upload
  702. Uploading STart
  703. Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/var/common/first_responder_notify']
  704. % Total % Received % Xferd Average Speed Time Time Time Current
  705. Dload Upload Total Spent Left Speed
  706. 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
  707.  
  708.  
  709. Uploading STart
  710. Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-27-2020--110418.tar.gz']
  711. % Total % Received % Xferd Average Speed Time Time Time Current
  712. Dload Upload Total Spent Left Speed
  713. 100 79.6M 0 0 100 79.6M 0 2779k 0:00:29 0:00:29 --:--:-- 2929k
  714. root@ngfw2:/home/admin/shakeeb#
  715. root@ngfw2:/home/admin/shakeeb#
  716. root@ngfw2:/home/admin/shakeeb# vi auto_upload.py
  717. root@ngfw2:/home/admin/shakeeb# ls
  718. auto_upload.py first-responder.log
  719. root@ngfw2:/home/admin/shakeeb# vi first-responder.log
  720. root@ngfw2:/home/admin/shakeeb# vi first-responder.log
  721. root@ngfw2:/home/admin/shakeeb# rm first-responder.log
  722. root@ngfw2:/home/admin/shakeeb# ls
  723. auto_upload.py
  724. root@ngfw2:/home/admin/shakeeb# vi auto_upload.py
  725. root@ngfw2:/home/admin/shakeeb# python auto_upload.py -c 688278694 -t t4XUaMss4Pa8BHxs
  726. Device version is greater than or equal to 6.2.3.
  727. Uploading STart
  728. Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/var/common/first_responder_notify']
  729. % Total % Received % Xferd Average Speed Time Time Time Current
  730. Dload Upload Total Spent Left Speed
  731. 0 0 0 0 0 0 0 0 --:--:-- 0:00:07 --:--:-- 0
  732. Running sf_troubleshoot.pl to create troubleshooting file...
  733. Troubleshoot file successfully generated at /ngfw/var/common/results-01-27-2020--111114.tar.gz
  734. Attempting troubleshoot upload...
  735. Uploading STart
  736. Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-27-2020--111114.tar.gz']
  737. % Total % Received % Xferd Average Speed Time Time Time Current
  738. Dload Upload Total Spent Left Speed
  739. 100 79.7M 0 0 100 79.7M 0 2583k 0:00:31 0:00:31 --:--:-- 2829k
  740. root@ngfw2:/home/admin/shakeeb# la
  741. sh: la: command not found
  742. root@ngfw2:/home/admin/shakeeb# ls
  743. auto_upload.py first-responder.log
  744. root@ngfw2:/home/admin/shakeeb# mv auto_upload.py tshoot_uploader.py
  745. root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
  746. root@ngfw2:/home/admin/shakeeb# cat first-responder.log
  747. root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
  748. root@ngfw2:/home/admin/shakeeb# ls
  749. first-responder.log tshoot_uploader.py
  750. root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py
  751. usage: tshoot_uploader.py [-h] -c CASE -t TOKEN [--auto-upload]
  752. tshoot_uploader.py: error: argument -c/--case is required
  753. root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py ^C
  754. root@ngfw2:/home/admin/shakeeb# cat /var/common/first_responder_notify
  755. root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
  756. root@ngfw2:/home/admin/shakeeb# python tshoot_uploader.py -c 688278694 -t t4XUaMss4Pa8BHxs
  757. Device version is greater than or equal to 6.2.3.
  758. Running sf_troubleshoot.pl to create troubleshooting file...
  759. Troubleshoot file successfully generated at /ngfw/var/common/results-01-28-2020--81452.tar.gz
  760. Attempting troubleshoot upload...
  761. Starting Upload
  762. Running command ['curl', '-k', 'https://688278694:t4XUaMss4Pa8BHxs@cxd.cisco.com/home/', '--upload-file', '/ngfw/var/common/results-01-28-2020--81452.tar.gz']
  763. % Total % Received % Xferd Average Speed Time Time Time Current
  764. Dload Upload Total Spent Left Speed
  765. 100 80.5M 0 0 100 80.5M 0 2308k 0:00:35 0:00:35 --:--:-- 2952k
  766. root@ngfw2:/home/admin/shakeeb# vi tshoot_uploader.py
  767. root@ngfw2:/home/admin/shakeeb# cat tshoot_uploader.py
  768. #!/usr/bin/python
  769.  
  770. __author__ = "CXD First Responder Team"
  771. __copyright__ = "Copyright 2019, Cisco Systems Inc."
  772. __version__ = "1.0"
  773. __maintainer__ = "first-responder@cisco.com"
  774. __status__ = "Production"
  775.  
  776. import os
  777. import sys
  778. import glob
  779. import time
  780. import logging
  781. import tarfile
  782. import argparse
  783. import datetime
  784. import subprocess
  785. from distutils.version import LooseVersion
  786. import json
  787.  
  788. '''
  789. ----------------
  790. ARGUMENT PARSING
  791. ----------------
  792. '''
  793. # Create and argument parser
  794. parser = argparse.ArgumentParser()
  795. # Define the allowable arguments to be used with this script
  796. parser.add_argument("-c", "--case", help="The case number to attach the files to", required=True)
  797. parser.add_argument("-t", "--token", help="The token to upload files to cxd.cisco.com", required=True)
  798. parser.add_argument("--auto-upload", help="Disable interactive prompt. Automatically upload data. Log output to first-responder.log", action="store_true")
  799.  
  800. # Parse the provided arguments to update run-time variables
  801. args = parser.parse_args()
  802.  
  803. # Set the run-time variables
  804. case = str(args.case)
  805. token = str(args.token)
  806. # If auto-upload was specified, set the verbosity to FALSE and log output to first-responder.log
  807. if args.auto_upload:
  808. verbose = False
  809. else:
  810. verbose = True
  811. '''
  812. --------------------------
  813. CONSTANT / LOG DEFINITIONS
  814. --------------------------
  815. '''
  816.  
  817. # A logger used to log information to file for auto-upload mode
  818. logging.basicConfig(filename='first-responder.log',level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
  819.  
  820. # Constant used to convert raw bytes into a human readable format
  821. suffixes_humansize = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
  822.  
  823. '''
  824. --------------------
  825. FUNCTION DEFINITIONS
  826. --------------------
  827. '''
  828. # This function uploads a file to cxd.cisco.com
  829. def upload_file(username, token, file):
  830. # Define the command to upload
  831. command = ["curl", "-k", "https://%s:%s@cxd.cisco.com/home/" % (username, token), "--upload-file", "%s" % file]
  832. try:
  833. # Attempt to run the upload command
  834. smart_print("Starting Upload")
  835. smart_print("Running command %s"%command)
  836. subprocess.check_output(command)
  837. except subprocess.CalledProcessError as e:
  838. # Print any errors that were encountered while trying to run the upload command
  839. print e.output
  840.  
  841. # Print to screen or logs to a file depending on whether or not --auto-upload was used
  842. def smart_print(msg,color=None,level='info'):
  843. if verbose:
  844. # Format message to output in "red"
  845. if color == 'red':
  846. print('\033[91m%s \033[00m' % msg)
  847. # Format message to output in "green"
  848. elif color == 'green':
  849. print('\033[92m%s \033[00m' % msg)
  850. # Print message normally (no colors)
  851. else:
  852. print(msg)
  853. else:
  854. # Log with INFO level severity
  855. if level == 'info':
  856. logging.info(msg)
  857. # Log with WARNING level severity
  858. elif level == 'warn':
  859. logging.warn(msg)
  860.  
  861.  
  862.  
  863. # Generic "Yes" or "No" question function. Takes a message to prompt the user with, returns True or False
  864. def yes_or_no(question, default="yes"):
  865. valid = {"yes": True, "y": True, "ye": True,
  866. "no": False, "n": False}
  867. if default is None:
  868. prompt = " [y/n] "
  869. elif default == "yes":
  870. prompt = " [Y/n] "
  871. elif default == "no":
  872. prompt = " [y/N] "
  873. else:
  874. raise ValueError("invalid default answer: '%s'" % default)
  875.  
  876. while True:
  877. sys.stdout.write(question + prompt)
  878. choice = raw_input().lower()
  879. if default is not None and choice == '':
  880. return valid[default]
  881. elif choice in valid:
  882. return valid[choice]
  883. else:
  884. sys.stdout.write("Please respond with 'yes' or 'no' (or 'y' or 'n').\n")
  885.  
  886. '''
  887. -----------
  888. SCRIPT BODY
  889. -----------
  890. '''
  891. # Use the /etc/sf/ims.conf file to determine the version of the device we are running on
  892. if os.path.isfile('/etc/sf/ims.conf'):
  893. os_version = None
  894. with open('/etc/sf/ims.conf') as ims:
  895. for line in ims:
  896. if "OSVERSION" in line:
  897. os_version = line.split('=')[1].strip()
  898. # Check to make sure the device we are running on is at least version 6.2.3
  899. if os_version:
  900. # Compare the running OS Version against a static value of 6.2.3
  901. if LooseVersion(os_version) < LooseVersion('6.2.3'):
  902. # Warn the user if the device is a version lower than 6.2.3
  903. smart_print('This script has only been tested with version 6.2.3 and above. Currently running version: %s' % os_version, 'red', 'warn')
  904. else:
  905. # Notify the user that device is on a compatible version if greater than or equal to 6.2.3
  906. smart_print('Device version is greater than or equal to 6.2.3.', 'green')
  907. else:
  908. # Catch all if we fail to set os_version. Warn the user anyway.
  909. smart_print('Unab/printle to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  910. else:
  911. # Catch all if ims.conf does not exist. Warn the user anyway.
  912. smart_print('Unable to determine version. WARNING: This script has only been tested with version 6.2.3 and above.', 'red', 'warn')
  913.  
  914. # Run the troubleshoot
  915. try:
  916. smart_print('Running sf_troubleshoot.pl to create troubleshooting file...')
  917. # Open devnull in order to redirect stderr to /dev/null and avoid output
  918. with open(os.devnull, 'w') as devnull:
  919. # Set the tshoot variable to the resulting file name
  920. tshoot = subprocess.check_output('sf_troubleshoot.pl', stderr=devnull).split('created at ')[1].strip()
  921. # Notify the user that the troubleshoot generation was successful, as well as the resultant file name
  922. smart_print('Troubleshoot file successfully generated at %s' % tshoot, 'green')
  923. # Notify the user that upload is being attempted
  924. smart_print('Attempting troubleshoot upload...')
  925. # Call the upload function with the credentials and troubleshoot file as the upload file
  926. upload_file(case, token, tshoot)
  927. except subprocess.CalledProcessError as e:
  928. # Print any errors that were encountered and exit
  929. print e.output
  930. exit()
  931. root@ngfw2:/home/admin/shakeeb#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement