Closed ingenium21 closed 1 year ago
Here is the authentication function for TenableSC in platform.py I don't understand why it's saying it's an authenticated session.
def _authenticate(self, **kwargs):
'''
This method handles authentication for both API Keys and for session
authentication.
'''
# Here we are grafting the authentication functions into the keyword
# arguments for later usage. If a function is provided in the keywords
# under the key names below, we will use those instead. This should
# essentially allow for the authentication logic to be overridden with
# minimal effort.
kwargs['key_auth_func'] = kwargs.get('key_auth_func',
self._key_auth)
kwargs['session_auth_func'] = kwargs.get('session_auth_func',
self._session_auth)
# Pull the API keys from the keyword arguments passed to the
# constructor and build the keys tuple. As API Keys will be
# injected directly into the session, there is no need to store these.
keys = kwargs.get('_key_auth_dict', {
'access_key': kwargs.get('access_key',
os.getenv(f'{self._env_base}_ACCESS_KEY')
),
'secret_key': kwargs.get('secret_key',
os.getenv(f'{self._env_base}_SECRET_KEY')
)
})
# The session authentication tuple. We will be storing these as its
# possible for the session to timeout on the user. This would require
# re-authentication.
self._auth = kwargs.get('_session_auth_dict', {
'username': kwargs.get('username',
os.getenv(f'{self._env_base}_USERNAME')
),
'password': kwargs.get('password',
os.getenv(f'{self._env_base}_PASSWORD')
)
})
# Run the desired authentication function. As API keys are generally
# preferred over session authentication, we will first check to see
# that keys have been set, as we prefer stateless auth to stateful.
if None not in [v for _, v in keys.items()]:
kwargs['key_auth_func'](**keys)
elif None not in [v for _, v in self._auth.items()]:
kwargs['session_auth_func'](**self._auth)
else:
warnings.warn('Starting an unauthenticated session',
AuthenticationWarning)
self._log.warning('Starting an unauthenticated session.')
Hi I haven't heard from anyone about this, any chance someone could take a look?
I'm now getting weirder results where it won't download the scans i launched on Tuesday, but it does grab the ones from the 30th.
Sounds like there may be partial results or scans that may have failed. Also your unauth session warning is correct as the library have been preferring authenticating at instantiation for some time now and depregating the separate login method (which is only currently being kept intact for backwards compat).
Try something more like this:
#!/usr/bin/env python3
from typing import List, Optional
from tenable.sc import TenableSC
from zipfile import ZipFile
from pathlib import Path
import arrow
def export_scans(sc: TenableSC,
downloads: Optional[Path] = None,
ignore: List[str] = []) -> None:
"""
Export scans from Tenable.sc into the specified folder
"""
tf = {'false': False, 'true': True}
if not downloads:
downloads = Path('Scans')
for scan in sc.scan_instances.list(fields=[
'id',
'name',
'status',
'downloadAvailable',
'finishTime',
]
)['usable']:
skip = False
for item in ignore:
if item.lower() in scan['name'].lower():
skip = True
if skip:
continue
scan_date = arrow.get(int(scan['finishTime']))
download_available = tf[scan['downloadAvailable']]
if download_available:
fn = f'{scan["name"]}_{scan_date.format("YYYY-MM-DD")}'
scan_path = downloads.joinpath(fn)
zfile = scan_path.joinpath(f'{fn}.zip')
scan_path.mkdir(exist_ok=True, parents=True)
with open(zfile, 'wb') as compressed:
sc.scan_instances.export_scan(scan['id'], fobj=compressed)
print(f'{scan["id"]} - {scan["name"]} Downloaded')
with ZipFile(zfile, 'r') as zipfile:
zipfile.extractall(scan_path)
print(f'{scan["id"]} - {scan["name"]} Extracted')
else:
print(f'{scan["id"]} - {scan["name"]} Download isn\'t available')
if __name__ == '__main__':
# Use the TSC_ACCESS_KEY, TSC_SECRET_KEY, and TSC_URL envvars
sc = TenableSC()
export_scans(sc, Path('Scans'), ['tedpw'])
Hi @ingenium21,
We hope you would have get rid of authentication issue with @SteveMcGrath solution, please revert us so we can close the issue.
Thanks pyTenable Team
Hi, yes, you may close this case. Thank you all for your help!
Describe the bug Having trouble downloading scans. My script does show that I am authenticating correctly, because I can retrieve a list of the scans, but when I call my function to download them, it fails with a 403 error and the error message: "Scan Result # failed". Not much else is given.
To Reproduce
relevant functions:
main function:
Steps to reproduce the behavior:
Expected behavior download the scans into zip files. unzip the files.
Screenshots If applicable, add screenshots to help explain your problem.
System Information (please complete the following information):
Additional context Add any other context about the problem here.