예제 #1
0
def report_ope(ope, scan_id, file_id):
    # インスタンス初期化
    client = TenableIOClient()
    # 一時レポートCSVファイル名
    todaynow = datetime.today().strftime('%Y%m%d%H%M%S')
    tenable_csv_folder = 'csv_report/'
    tenable_csv_file = tenable_csv_folder + str(todaynow) + '_scanid_' + str(scan_id) + '.csv'
    # ローカル環境適用
    #if os.path.isdir(tenable_csv_folder):
    #    pass
    #else:
    #    os.makedirs(tenable_csv_folder)
    if ope == 'status':
        request_uri = 'scans/' + str(scan_id) + '/export/' + str(file_id) + '/status'
        resp = client.get(request_uri, path_params={'scan_id':scan_id, 'file_id':file_id})
        obj_msg = json.loads(resp.text)
        str_msg = obj_msg.get('status')
        return render_template('index.html', message=str_msg)
    elif ope == 'download':
        request_uri = 'scans/' + str(scan_id) + '/export/' + str(file_id) + '/download'
        resp = client.get(request_uri, path_params={'scan_id':scan_id, 'file_id':file_id}, stream=True)
        # ローカル環境適用
        #iter_content = resp.iter_content(chunk_size=1024)
        #with open(tenable_csv_file, mode='wb') as fd:
        #    for ck in iter_content:
        #        fd.write(ck)
        #str_msg = u'https://tenable-io.herokuapp.com/' + tenable_csv_file 
        #return render_template('index.html', message=str_msg)
        # AWS S3に保存する
        s3 = S3Api()
        response = s3.response(tenable_csv_file, resp.text)
        return response
        #return render_template('index.html', message=resp.text)
    else:
        return render_template('index.html', message=u"REPORT_OPE|不正アクセスを記録しました。")
예제 #2
0
def s3_api(scan_id, file_id):
    
    # インスタンス初期化
    client = TenableIOClient()
    request_uri = 'scans/' + str(scan_id) + '/export/' + str(file_id) + '/download'
    resp = client.get(request_uri, path_params={'scan_id':scan_id, 'file_id':file_id}, stream=True)
    
    s3 = S3Api()
    response = s3.response('20170213_tenable.csv', resp.text)
    
    return response
예제 #3
0
def downloadVulnsFromTio(filename, cust):
    DEBUG = True

    #Open the connection to Tio  for the particular customer
    print("Connecting to Tenable.io for:", cust['name'])
    try:
        tioconn = TenableIOClient(access_key=cust['_id'],
                                  secret_key=cust['secretkey'])
    except:
        print("Problem connecting to Tenable.io")
        return (False)

    #Download a CSV file

    # Make the request for the file.
    requesturl = "workbenches/export?format=csv&report=vulnerabilities&chapter=vuln_by_plugin&date_range=0"
    resp = tioconn.get(requesturl)

    if DEBUG:
        print("Raw response text:", resp.text)
    respdata = json.loads(resp.text)

    downloadid = ""
    try:
        downloadid = str(respdata['file'])
    except:
        print("Unable to start download")
        return (False)

    statusurl = "workbenches/export/" + downloadid + "/status"
    downloadurl = "workbenches/export/" + downloadid + "/download"

    if DEBUG:
        print("Waiting for download ID", downloadid)
        print("status URL  :", statusurl)

    downloadstatus = ""
    while (downloadstatus != "ready"):
        resp = tioconn.get(statusurl)
        respdata = json.loads(resp.text)
        downloadstatus = respdata['status']
        if DEBUG:
            print("Raw response", resp.text)
        time.sleep(2)

    resp = tioconn.get(downloadurl)
    if DEBUG:
        print("Raw response", resp)
    with open(filename, 'wb') as fp:
        for chunk in resp.text:
            fp.write(chunk.encode('utf-8'))
    fp.close()
    sys.stdout.flush()
    return (True)
예제 #4
0
def report_request(scan_id):
    
    if scan_id:
        # インスタンス初期化
        client = TenableIOClient()
        # レポートRAWデータをCSV形式で出力する要求をする
        request_uri = 'scans/' + str(scan_id) + '/export'
        resp = client.post(request_uri, ScanExportRequest(format=u'csv'), path_params={'scan_id':scan_id})
        if resp.status_code == 200:
            obj_msg = json.loads(resp.text)
            str_msg = str(obj_msg.get('file')) + u'|レポート要求が正常に受信できました。'
            return render_template('index.html', message=str_msg)
        else:
            return render_template('index.html', message=u"REPORT_REQUEST_ERROR|レポート要求時エラーが発生しています。")
    else:
        return render_template('index.html', message=u"REPORT_REQUEST|不正アクセスを記録しました。")
예제 #5
0
def perform_nessus_scan(target, outpath):

    logger.info("[+] Attempting to run Nessus scan on the target...")
    domain = urlparse(target[0]).netloc
    # Reference file: https://github.com/tenable/Tenable.io-SDK-for-Python/blob/master/examples/scans.py
    try:
        # According to documentation TenableIO client can be initialised
        # in a number of ways. I choose here the environment variable option.
        # On the same tty, the user needs to set TENABLEIO_ACCESS_KEY and
        # TENABLEIO_SECRET_KEY variables. I prefer this over storing keys
        # in a config file on disk.
        client = TenableIOClient()

        # Run a basic network scan
        nessus_scan = client.scan_helper.create(name='Scan_for_ ' + target[0],
                                                text_targets=target[0],
                                                template='basic')

        # Let's allow up to 45 minutes for the scan to run and finish
        nessus_scan.launch().wait_or_cancel_after(45)
        # Downloading the results in .nessus format
        # We will likely need to post this to somewhere else too
        nessus_scan.download(os.path.join(outpath, domain + '.nessus'),
                             nessus_scan.histories()[0].history_id,
                             format=ScanExportRequest.FORMAT_NESSUS)
    except TenableIOApiException as TIOException:
        logger.warning("[!] Nessus scan could not run. Make sure you have "
                       "provided API keys to communicate with Tenable.io.")
        return False

    return True
예제 #6
0
    def scan(self, hostname):
        # If not passed at the time of object instantiation
        if not self.tio_access_key or not self.tio_secret_key:
            try:
                # See if we can load the API keys from SSM
                self.tio_access_key, self.tio_secret_key = self.__getAPIKey()
            except Exception:
                self.logger.error(
                    "Cannot obtain Tenable.io API key(s), skipping Tenable.io scan"
                )
                return False

        # Here, we have the keys, either from SSM or from instantiation
        self.client = TenableIOClient(access_key=self.tio_access_key,
                                      secret_key=self.tio_secret_key)
        # Reference: https://github.com/tenable/Tenable.io-SDK-for-Python/blob/master/examples/scans.py
        try:
            # Run a basic network scan on the target
            scan_name = "VA for " + hostname
            nscan = self.client.scan_helper.create(name=scan_name,
                                                   text_targets=hostname,
                                                   template='basic')
            return nscan

        except Exception as TIOException:
            self.logger.error(
                "Tenable.io scan failed: {}".format(TIOException))
            return False
def test_nessus():
    req_data = request.get_json()
    testUrl = req_data['url']
    scanName = req_data['name']
    device_token = req_data['reg_token']
    hashToken = hashlib.md5(device_token).hexdigest()
    testIp = gethostbyname(testUrl)
    reportName = scanName + ".pdf"
    reportName = hashToken + '_' + reportName
    path_report = "/home/tejas/Desktop/website/" + reportName
    client = TenableIOClient(
        access_key=
        '135b739644f7f56f6e39fa6f45d00ccdc199fb15793ddf324a7ad0e4526e1b95',
        secret_key=
        'ff6d61f566c11479154f68dc8f0a6ebf35aa961d65329a01a41349638face336')
    scan = client.scan_helper.create(name=scanName,
                                     text_targets=testIp,
                                     template='basic')
    scan.launch().download(path_report, scan.histories()[0].history_id)
    #path_from_pdf="/home/ubuntu/website/"+reportName
    path_to_pdf = "/home/tejas/Desktop/website/static/reports/nessus/" + reportName
    subprocess.call(["mv", path_report, path_to_pdf])
    push_service = FCMNotification(
        api_key="AIzaSyB4BBdlKyxQaB9ZBL1U4ynZz3nDNW9vsmo")
    data = {
        "title":
        "Nessus Report",
        "message":
        "Your report " + req_data['name'] + " for Nessus has been generated"
    }
    #message_title = "Nessus Report"
    #message_body = "Your report has been generated"
    result = push_service.notify_single_device(registration_id=device_token,
                                               data_message=data)
    return jsonify(reportGenerated=True)
def example(test_file):

    # Generate unique name and file.
    test_vulns_json_file = test_file(u'example_export_vulns_%(chunk_id)s.json')
    test_assets_json_file = test_file(
        u'example_export_assets_%(chunk_id)s.json')
    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()
    '''
    Export and download vulnerabilities.
    Note: The file name can be optionally parameterized with "%(chunk_id)s" to allow multiple chunks. Otherwise the
        chunk ID will be append to the file name.
    '''
    chunks_available = client.export_helper.download_vulns(
        test_vulns_json_file)
    for chunk_id in chunks_available:
        chunk_file = test_vulns_json_file % {'chunk_id': chunk_id}
        assert os.path.isfile(chunk_file)
        os.remove(chunk_file)
    '''
    Export and download assets.
    Note: The file name can be optionally parameterized with "%(chunk_id)s" to allow multiple chunks. Otherwise the
        chunk ID will be append to the file name.
    '''
    chunks_available = client.export_helper.download_assets(
        test_assets_json_file, chunk_size=100)
    for chunk_id in chunks_available:
        chunk_file = test_assets_json_file % {'chunk_id': chunk_id}
        assert os.path.isfile(chunk_file)
        os.remove(chunk_file)
def example():

    test_asset_file = u'asset.nessus'
    test_vulnerability_file = u'vulnerability.nessus'

    date_range = 7

    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()

    '''
    Get recent assets in the past 7 days.
    Note: assets returns an iterator. An iterator that return pages of assets.
    '''
    assets_iter = client.workbench_helper.assets(date_range)
    assets = [a for page in assets_iter for a in page]

    '''
    Get recent vulnerabilities in the past 7 days.
    Note: vulnerabilities returns an iterator. An iterator that return pages of vulnerabilities.
    '''
    vulnerabilities_iter = client.workbench_helper.vulnerabilities(date_range)
    vulnerabilities = [v for page in vulnerabilities_iter for v in page]

    if len(vulnerabilities) < 1:
        return

    '''
    Get recent assets found for a plugin.
    '''
    plugin_id = vulnerabilities[0].plugin_id
    vulnerability_assets_iter = client.workbench_helper.assets(date_range, plugin_id=plugin_id)
    vulnerability_assets = [a for page in vulnerability_assets_iter for a in page]

    assert len(vulnerability_assets) > 0
    assert plugin_id in [v.plugin_id for v in vulnerability_assets[0].vulnerabilities]

    '''
    Get recent vulnerabilities found for an asset.
    '''
    asset_id = vulnerability_assets[0].asset.host_uuid
    asset_vulnerabilities_iter = client.workbench_helper.vulnerabilities(date_range, asset_id=asset_id)
    asset_vulnerabilities = [v for page in asset_vulnerabilities_iter for v in page]

    assert len(asset_vulnerabilities) > 0
    assert plugin_id in [v.plugin_id for v in asset_vulnerabilities]

    '''
    Export reports for a given asset or vulnerability.
    '''
    client.workbench_helper.export(test_asset_file, asset_id=assets[0].asset.host_uuid)
    client.workbench_helper.export(test_vulnerability_file, plugin_id=vulnerabilities[0].plugin_id)

    assert os.path.isfile(test_asset_file)
    assert os.path.isfile(test_vulnerability_file)
    os.remove(test_asset_file)
    os.remove(test_vulnerability_file)
    def test_client_retries(self):
        mock_error = Mock(side_effect=TenableIORetryableApiException(Mock()))
        retry_mock_error = TenableIOClient._retry(mock_error)
        retry_header = {u'X-Tio-Retry-Count': '3'}

        with pytest.raises(TenableIOApiException):
            retry_mock_error()

        assert mock_error.call_count == int(TenableIOClient._TOTAL_RETRIES) + 1, \
            u'Invalid retry  count: ' + str(mock_error.call_count)
        mock_error.assert_called_with(headers=retry_header)
예제 #11
0
def example(test_name, test_file):

    # Generate unique file.
    policy_name = test_name(u'my test policy')
    test_file_output = test_file(u'my_exported_policy.tenable_io')
    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()
    '''
    Create a policy.
    '''
    policy = client.policy_helper.create(name=policy_name,
                                         template='discovery')
    assert policy.name() == policy_name
    '''
    Export a policy into a NESSUS file.
    '''
    policy.download(test_file_output)
    assert os.path.isfile(test_file_output)
    '''
    Import a policy from a NESSUS file and get the detail.
    '''
    imported_policy = client.policy_helper.import_policy(test_file_output)
    assert imported_policy.details().uuid == policy.details().uuid
    os.remove(test_file_output)
    '''
    Create a new policy by copying a policy.
    '''
    policy_copy = policy.copy()
    assert policy_copy.id != policy.id
    '''
    Delete policies.
    '''
    policy.delete()
    imported_policy.delete()
    policy_copy.delete()
    try:
        policy.details()
        assert False
    except TenableIOApiException:
        pass
    try:
        imported_policy.details()
        assert False
    except TenableIOApiException:
        pass
    try:
        policy_copy.details()
        assert False
    except TenableIOApiException:
        pass
def GenerateAssetCSV(accesskey, secretkey, filename):
    #Create the connection to Tenable.io
    client = TenableIOClient(access_key=accesskey, secret_key=secretkey)

    #Gather the list of assets
    resp = client.get("assets")
    respdata = json.loads(resp.text)

    #Open the file that will become a CSV
    with open(filename, "w") as csvfile:
        #Create the header of the CSV file
        fieldnames = [
            'id', 'has_agent', 'last_seen', 'sources', 'ipv4', 'ipv6', 'fqdn',
            'netbios_name', 'operating_system'
        ]

        #Create a CSV writer and associate with the file handle
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
        #Write the CSV headers
        writer.writeheader()

        #Loop through all the downloaded assets and write them into the CSV file
        for i in respdata['assets']:
            rowdict = {
                'id': i['id'],
                'has_agent': i['has_agent'],
                'last_seen': i['last_seen'],
                'sources': i['sources'],
                'ipv4': i['ipv4'],
                'ipv6': i['ipv6'],
                'fqdn': i['fqdn'],
                'netbios_name': i['netbios_name'],
                'operating_system': i['operating_system']
            }
            writer.writerow(rowdict)

    #Close the file
    csvfile.close()
    return (True)
예제 #13
0
def test_s3(scan_id, file_id):
    
    # インスタンス初期化
    client = TenableIOClient()
    request_uri = 'scans/' + str(scan_id) + '/export/' + str(file_id) + '/download'
    resp = client.get(request_uri, path_params={'scan_id':scan_id, 'file_id':file_id}, stream=True)
    #iter_content = resp.iter_content()
    
    S3_BUCKET = os.environ.get('S3_BUCKET')
    s3 = boto3.resource('s3')
    bucket = s3.Bucket(S3_BUCKET)
    
    PUT_OBJECT_KEY_NAME = '20170212_test.csv'
    obj = bucket.Object(PUT_OBJECT_KEY_NAME)

    response = obj.put(
        Body=resp.text,
        ContentEncoding='utf-8',
        ContentType='text/csv'
    )
    
    return jsonify(response)
예제 #14
0
    def test_client_retries(self):

        # Function that throws TenableIORetryableException
        mock_response = mock.Mock()
        foo = mock.Mock(
            side_effect=TenableIORetryableApiException(mock_response))

        # Function decoration
        retried_foo = TenableIOClient._retry(foo)

        with pytest.raises(TenableIOApiException):
            retried_foo()

        assert foo.call_count == 4, u'Should be tried 4 times (retried 3 times).'
예제 #15
0
 def test_tenable_auth_success(self):
     # See if the keys are available as env variables
     try:
         a_key = os.environ["TIOA"]
         s_key = os.environ["TIOS"]
     except Exception:
         assert False
     # See if we can use those keys to successfully
     # authenticate to Tenable.io, should be True
     try:
         TenableIOClient(a_key, s_key).session_api.get()
         assert True
     except TenableIOApiException as e:
         assert e.code is TenableIOErrorCode.UNAUTHORIZED
예제 #16
0
def example(test_file):

    # Generate a file with an unique name.
    upload_file = test_file(u'example_upload', u'example content')
    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()
    '''
    Upload a file (usually used along with another API resource method that requires a file).
    '''
    uploaded_file_name = client.file_helper.upload(upload_file)
    assert uploaded_file_name

    os.remove(upload_file)
예제 #17
0
def example(test_domain):

    test_user_name = u'example_test_user_{}'.format(random.randint(1, 100))
    test_user_username = u'{}@{}'.format(test_user_name, test_domain)
    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()
    '''
    Create a new Standard User
    '''
    user_create_request = UserCreateRequest(
        username=test_user_username,
        password='******'.format(random.randint(1, 100)),
        permissions=Permissions.User.PERMISSION_STANDARD,
        name=test_user_name,
        email=test_user_username,
        type=User.LOCAL)
    std_user_id = client.users_api.create(user_create_request)
    assert std_user_id
    '''
    Fetch user details
    '''
    std_user = client.users_api.details(std_user_id)
    assert isinstance(std_user, User)
    assert std_user.permissions == Permissions.User.PERMISSION_STANDARD
    '''
    Check that new user is included in user list
    '''
    user_list = client.users_api.list()
    assert any([u.id for u in user_list.users if u.id == std_user_id])
    '''
    Edit user
    '''
    user_edit_request = UserEditRequest(
        permissions=Permissions.User.PERMISSION_SCAN_MANAGER)
    edited_std_user = client.users_api.edit(std_user_id, user_edit_request)
    assert isinstance(edited_std_user, User)
    assert edited_std_user.permissions == Permissions.User.PERMISSION_SCAN_MANAGER
    '''
    Delete user
    '''
    assert client.users_api.delete(std_user_id)
    '''
    Check that deleted user is not included in user list
    '''
    user_list = client.users_api.list()
    assert not any([u.id for u in user_list.users if u.id == std_user_id])
    def __createClient(self):
        # If not passed at the time of object instantiation
        if not self.tio_access_key or not self.tio_secret_key:
            try:
                # See if we can load the API keys from SSM
                self.tio_access_key, self.tio_secret_key = self.__getAPIKey()
            except Exception:
                self.logger.error(
                    "Cannot obtain Tenable.io API key(s), skipping Tenable.io scan."
                )
                return False

        # Here, we have the keys, either from SSM or from instantiation
        client = TenableIOClient(access_key=self.tio_access_key,
                                 secret_key=self.tio_secret_key)
        return client
예제 #19
0
def host_reg(hostname, template):
    
    if len(hostname) != 0:
        # インスタンス初期化
        client = TenableIOClient()
        # 新規診断対象を登録する
        scan = client.scan_helper.create(
            name=hostname, 
            text_targets=hostname,
            template=template
        )
        # assert scan.name() = scan_name
        msg = str(scan.id) + "|" + scan.name() + u"が正常に登録できました。"
        return render_template('index.html', message=msg)
    else:
        return render_template('index.html', message=u"HOST_REG|不正アクセスを記録しました。")
def example(test_file):

    # Generate unique name and file.
    test_vulns_json_file = test_file(u'example_export_vulns_%(chunk_id)s.json')
    test_assets_json_file = test_file(u'example_export_assets_%(chunk_id)s.json')

    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()

    '''
    Export and load vulnerabilities to memory.
    '''
    vuln_list = client.export_helper.download_vulns()
    for vuln in vuln_list:
        assert isinstance(vuln, VulnsExport)

    '''
    Export and download vulnerabilities to disk.
    Note: The file name can be optionally parameterized with "%(chunk_id)s" to allow multiple chunks. Otherwise the
        chunk ID will be append to the file name.
    '''
    chunks_available = client.export_helper.download_vulns(path=test_vulns_json_file)
    for chunk_id in chunks_available:
        chunk_file = test_vulns_json_file % {'chunk_id': chunk_id}
        assert os.path.isfile(chunk_file)
        os.remove(chunk_file)

    '''
    Export and load assets to memory.
    '''
    asset_list = client.export_helper.download_assets()
    for asset in asset_list:
        assert isinstance(asset, AssetsExport)

    '''
    Export and download assets to disk.
    Note: The file name can be optionally parameterized with "%(chunk_id)s" to allow multiple chunks. Otherwise the
        chunk ID will be append to the file name.
    '''
    chunks_available = client.export_helper.download_assets(path=test_assets_json_file)
    for chunk_id in chunks_available:
        chunk_file = test_assets_json_file % {'chunk_id': chunk_id}
        assert os.path.isfile(chunk_file)
        os.remove(chunk_file)
예제 #21
0
def scan_ope(ope, id):
    
    if ope == 'status':
        # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        # 診断IDより診断対象取得
        scan_b = client.scan_helper.id(id)
        return render_template('index.html', message=str(scan_b.status()))    
    elif ope == 'launch':
        # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        # 診断IDより診断対象取得
        scan_b = client.scan_helper.id(id)
        scan_b.launch(id)
        return render_template('index.html', message=str(scan_b.status()))
    elif ope == 'pause':
        # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        client.scans_api.pause(id)
        # 診断IDより診断対象取得
        scan_b = client.scan_helper.id(id)
        return render_template('index.html', message=str(scan_b.status()))
    elif ope == 'stop':
         # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        client.scans_api.stop(id)
        # 診断IDより診断対象取得
        scan_b = client.scan_helper.id(id)
        return render_template('index.html', message=str(scan_b.status()))
    elif ope == 'resume':
        # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        client.scans_api.resume(id)
        # 診断IDより診断対象取得
        scan_b = client.scan_helper.id(id)
        return render_template('index.html', message=str(scan_b.status()))
    elif ope == 'delete':
        # インスタンス初期化
        client = TenableIOClient()    
        # 診断対象のID或は登録名が入力画面もしくは入力パラメータから渡される
        resp = client.scans_api.delete(id)
        # 削除結果を確認する
        if resp is True:
            return render_template('index.html', message=u"診断対象を正しく削除できました。")
        else:
            return render_template('index.html', message=u"診断対象を削除できませんでした。")
    else:
        return render_template('index.html', message=u"SCAN_OPE|不正アクセスを記録しました。")
예제 #22
0
    def runNessusScan(self):

        # First, check to see if we are provided with API keys
        if self.tio_access_key == "" or self.tio_secret_key == "":
            logger.warning("[!] Tenable.io API key(s) not provided, skipping "
                           "Tenable.io scan. Perform the scan manually.")
            return False
        else:
            self.client = TenableIOClient(access_key=self.tio_access_key,
                                          secret_key=self.tio_secret_key)

        # Reference: https://github.com/tenable/Tenable.io-SDK-for-Python/blob/master/examples/scans.py
        # Note no subprocess call is required here
        try:
            # Run a basic network scan on the target
            # Need to check if a recent scan was fired recently
            scan_name = "VA for " + self.tasktarget.targetdomain
            # We will check with both host IP and FQDN
            activities = self.client.scan_helper.activities(
                targets=self.tasktarget.targetdomain, date_range=15)
            if len(activities) > 0:
                logger.warning(
                    "[!] The target has recently been scanned by Tenable.io, retrieving results..."
                )
                old_nscans = self.client.scan_helper.scans(name=scan_name)
                for old in old_nscans:
                    if old.status() == Scan.STATUS_COMPLETED:
                        self.downloadReport(old)
                        break
                return old
            else:
                # This target was not scanned before, scan it
                # We don't want this blocking, so don't wait
                new_nscan = self.client.scan_helper.create(
                    name=scan_name,
                    text_targets=self.tasktarget.targetdomain,
                    template="basic")
                new_nscan.launch(wait=False)
                return new_nscan

        except TenableIOApiException as TIOException:
            logger.error("[-] Tenable.io scan failed: ".format(TIOException))
            return False
예제 #23
0
def example():

    date_range = 7

    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()

    '''
    Get recent assets in the past 7 days.
    Note: assets returns an iterator. An iterator that return pages of assets.
    '''
    assets_iter = client.workbench_helper.assets(date_range)
    assets = [a for page in assets_iter for a in page]

    '''
    Get recent vulnerabilities in the past 7 days.
    Note: vulnerabilities returns an iterator. An iterator that return pages of vulnerabilities.
    '''
    vulnerabilities_iter = client.workbench_helper.vulnerabilities(date_range)
    vulnerabilities = [v for page in vulnerabilities_iter for v in page]

    if len(vulnerabilities) > 0:
        '''
        Get recent assets found for a plugin.
        '''
        plugin_id = vulnerabilities[0].plugin_id
        vulnerability_assets_iter = client.workbench_helper.assets(date_range, plugin_id=plugin_id)
        vulnerability_assets = [a for page in vulnerability_assets_iter for a in page]

        assert len(vulnerability_assets) > 0
        assert plugin_id in [v.plugin_id for v in vulnerability_assets[0].vulnerabilities]

        '''
        Get recent vulnerabilities found for an asset.
        '''
        asset_id = vulnerability_assets[0].asset.host_uuid
        asset_vulnerabilities_iter = client.workbench_helper.vulnerabilities(date_range, asset_id=asset_id)
        asset_vulnerabilities = [v for page in asset_vulnerabilities_iter for v in page]

        assert len(asset_vulnerabilities) > 0
        assert plugin_id in [v.plugin_id for v in asset_vulnerabilities]
예제 #24
0
def test_nessus():
    req_data = request.get_json()
    testUrl = req_data['url']
    scanName = req_data['name']
    testIp = gethostbyname(testUrl)
    reportName = scanName + ".pdf"
    client = TenableIOClient(
        access_key=
        '135b739644f7f56f6e39fa6f45d00ccdc199fb15793ddf324a7ad0e4526e1b95',
        secret_key=
        'ff6d61f566c11479154f68dc8f0a6ebf35aa961d65329a01a41349638face336')
    scan = client.scan_helper.create(name=scanName,
                                     text_targets=testIp,
                                     template='basic')
    scan.launch().download(reportName, scan.histories()[0].history_id)
    path_from_pdf = "/home/ubuntu/website/" + reportName
    path_to_pdf = "/home/ubuntu/website/reports/nessus/" + reportName
    subprocess.call(["mv", path_from_pdf, path_to_pdf])
    return 'Your report has been generated'
    def test_client_throwing_retryable_exception(self):

        responses = [
            [{
                'status_code': 200
            }, False],
            [{
                'status_code': 429
            }, True],
            [{
                'status_code': 501
            }, True],
            [{
                'status_code': 502
            }, True],
            [{
                'status_code': 503
            }, True],
            [{
                'status_code': 504
            }, True],
        ]

        # Function that returns Responses with above status codes.
        foo = mock.Mock(
            side_effect=[mock.Mock(**response[0]) for response in responses])

        # Method decoration
        foo = TenableIOClient._error_handler(foo)

        for (response, retry) in responses:
            if retry:
                with pytest.raises(TenableIORetryableApiException):
                    foo()
            else:
                try:
                    foo()
                except TenableIORetryableApiException:
                    assert False, u'Response %s should not be retry-able.' % response
 def test_client_bad_keys(self):
     try:
         TenableIOClient('bad', 'key').session_api.get()
         assert False, u'TenableIOApiException should be raised for bad api and secret keys.'
     except TenableIOApiException as e:
         assert e.code is TenableIOErrorCode.UNAUTHORIZED, u'Appropriate exception is raised.'
예제 #27
0
def main():

    options, parser = get_config()

    # logger = configure_logging(options.log_file_name)

    logging.config.fileConfig('log.ini')
    logger = logging.getLogger()

    logger.info('Started')

    # Log where each of our values has come from (command line, environment,
    # config file, default)
    logger.debug(get_redacted_parser_values(parser))

    client = TenableIOClient(access_key=options.tio_access_key,
                             secret_key=options.tio_secret_key)
    '''
    Export and download vulnerabilities.
    Note: The file name can be optionally parameterized with "%(chunk_id)s" to allow multiple chunks. Otherwise the
        chunk ID will be append to the file name.
    '''
    file_name = os.path.join(options.temp_file_dir, options.temp_file_name)

    # The tenable_io library looks for the chunk_id paramater and adds it if
    # if we do that here instead it will be consistent when we try to open the
    # files nexy
    # create a version of the filename that matches the tenable_io library
    if file_name % {'chunk_id': 1} == file_name:
        file_name += '_%(chunk_id)s'

    logger.info(
        'About to export vulnerabilities from tenable.io (this may take a few moments)...'
    )
    try:
        # Use one of the tenbale_io library helper functions to start the
        # export and download each of the result files
        chunks_available = client.export_helper.download_vulns(
            path=file_name,
            state=options.vuln_state,
            severity=options.vuln_severity)
    except Exception:
        logger.error('Failed to download vulnerability data', exc_info=True)
        return

    logger.info('completed vulnerabilities export from tenable.io')

    df = ''

    for chunk_id in chunks_available:
        logger.info('Loading chunk number {0}'.format(chunk_id))
        # using old style string formatting because that's what the tenable_io
        # library expects
        chunk_file = file_name % {'chunk_id': chunk_id}
        assert (os.path.isfile(chunk_file))
        logger.info('Loading data file {0}'.format(chunk_file))
        with open(chunk_file) as data_file:
            if (df == ''):
                df = json_normalize(json.load(data_file))
            else:
                df.append(json_normalize(json.load(data_file)))

        if (options.keep_temp_files == False):
            os.remove(chunk_file)

    # replace lists of CVE with strings in semi-colon delimited format
    # requested by the spec
    df = df.applymap(collapse_list)

    if options.csv_replace_newline_character is not None:
        #df = df.replace('\n',options.csv_replace_newline_character, regex=True)
        df = df.replace('(\n|\r|\r\n)',
                        options.csv_replace_newline_character,
                        regex=True)

    if options.csv_header_row == True:
        if options.csv_column_names is None:
            header = True
        else:
            header = options.csv_column_names
    else:
        header = False

    df.to_csv(os.path.abspath(options.output_file_name),
              columns=options.csv_columns,
              header=header,
              index=False,
              line_terminator=options.csv_newline_character,
              quotechar=options.csv_quote_char,
              sep=options.csv_delimiter,
              quoting=csv.QUOTE_ALL
              if options.csv_quote_everything == True else csv.QUOTE_MINIMAL,
              na_rep=options.csv_null_value)

    logger.info('Exported {0} vulnerabilities to {1}'.format(
        len(df), os.path.abspath(options.output_file_name)))
    logger.info('Finished')
예제 #28
0
def example(test_name, test_file, test_targets):

    # Generate unique name and file.
    scan_name = test_name(u'example scan')
    test_nessus_file = test_file(u'example_report.nessus')
    test_pdf_file = test_file(u'example_report.pdf')
    '''
    Instantiate an instance of the TenableIOClient.
    '''
    client = TenableIOClient()
    '''
    Create a scan.
    '''
    scan = client.scan_helper.create(name=scan_name,
                                     text_targets=test_targets,
                                     template='basic')
    assert scan.name() == scan_name
    '''
    Retrieve a scan by ID.
    '''
    scan_b = client.scan_helper.id(scan.id)
    assert scan_b is not scan
    assert scan_b.name() == scan_name
    '''
    Select scans by name.
    '''
    scans = client.scan_helper.scans(name=scan_name)
    assert scans[0].name() == scan_name
    '''
    Select scans by name with regular expression.
    '''
    scans = client.scan_helper.scans(name_regex=r'.*example scan.*')
    assert len(scans) > 0
    '''
    Launch a scan, then download when scan is completed.
    Note: The `download` method blocks until the scan is completed and the report is downloaded.
    '''
    scan.launch().download(test_pdf_file)
    assert os.path.isfile(test_pdf_file)
    os.remove(test_pdf_file)
    '''
    Launch a scan, pause it, resume it, then stop it.
    '''
    scan.launch().pause()
    assert scan.status() == Scan.STATUS_PAUSED
    scan.resume().stop()
    assert scan.status() == Scan.STATUS_CANCELED
    '''
    Stop a running scan if it does not complete within a specific duration.
    '''
    start = time()
    scan.launch().wait_or_cancel_after(10)
    assert time() - start >= 10
    '''
    Retrieve the history of a scan since a specific date or all.
    Note: The `since` argument is optional, all the history if omitted.
    '''
    histories = scan.histories(since=datetime(2016, 12, 1))
    assert len(histories) > 0
    '''
    Download the report for a specific scan in history.
    '''
    scan.download(test_pdf_file, history_id=histories[0].history_id)
    assert os.path.isfile(test_pdf_file)
    os.remove(test_pdf_file)
    '''
    Create a new scan by copying a scan.
    '''
    scan_copy = scan.copy()
    assert scan_copy.id != scan.id
    assert scan_copy.status() == Scan.STATUS_EMPTY
    '''
    Export a scan into a NESSUS file.
    '''
    scan.download(test_nessus_file, format=ScanExportRequest.FORMAT_NESSUS)
    assert os.path.isfile(test_nessus_file)
    '''
    Create a new scan by importing a NESSUS file.
    '''
    imported_scan = client.scan_helper.import_scan(test_nessus_file)
    assert imported_scan.details().info.name == scan.details().info.name
    os.remove(test_nessus_file)
    '''
    Stop all scans.
    Note: Use with caution as this will stop all ongoing scans (including any automated test).
    '''
    # client.scan_helper.stop_all()
    '''
    Check if a target has recently been scanned (including running scans).
    '''
    activities = client.scan_helper.activities(test_targets)
    last_history_id = scan.last_history().history_id
    assert [a for a in activities if last_history_id == a.history_id]
    '''
    Delete scans.
    '''
    scan.delete()
    scan_copy.delete()
    imported_scan.delete()

    try:
        scan.details()
        assert False
    except TenableIOApiException:
        pass
    try:
        scan_copy.details()
        assert False
    except TenableIOApiException:
        pass
    try:
        imported_scan.details()
        assert False
    except TenableIOApiException:
        pass
예제 #29
0
 def test_tenable_auth_fail(self):
     try:
         TenableIOClient('test', 'test').session_api.get()
         assert False
     except TenableIOApiException as e:
         assert e.code is TenableIOErrorCode.UNAUTHORIZED
예제 #30
0
def main():
    """

    Main func for automatic vulnerability scan by Tenable.io of Company GCP and Cloudflare resources
    :return: none
    """
    parser = argparse.ArgumentParser(description='Provide all arguments for successful Vulnerability scan')
    parser.add_argument("-all", dest="tg_all", action="store_true", help="Scan All supported infrastructures")
    parser.add_argument("-cloudflare", dest="tg_cloudflare", action="store_true", help="Scan GCP infrastructure")
    parser.add_argument("-gcp", dest="tg_gcp", action="store_true", help="Scan Cloudflare infrastructure")
    parser.add_argument("-aws", dest="tg_aws", action="store_true", help="Scan AWS infrastructures")
    parser.add_argument("-linode", dest="tg_linode", action="store_true", help="Scan Linode infrastructures")
    parser.add_argument("-others", dest="tg_others", action="store_true", help="Scan rest of SaaS: DO, Linode, etc")
    parser.add_argument("-schedule", dest="tg_schedule", action="store_true", help="Schedule scans by Tenable.io")
    parser.set_defaults(tg_all=False)
    parser.set_defaults(tg_cloudflare=False)
    parser.set_defaults(tg_gcp=False)
    parser.set_defaults(tg_aws=False)
    parser.set_defaults(tg_linode=False)
    parser.set_defaults(tg_others=False)
    parser.set_defaults(tg_schedule=False)
    args = parser.parse_args()
    # Create dirs
    gen.create_dirs()

    # Set configuration file location
    main_script_abs = os.path.dirname(os.path.abspath(__file__))
    settings_obj = configparser.ConfigParser()
    settings_obj.read(main_script_abs + '/conf/conf.cfg')

    # Initiate an instance of TenableIOClient.
    settings = settings_obj._sections.copy()
    tenable_client = TenableIOClient(access_key=settings['TENABLE.IO']['access_key'],
                                     secret_key=settings['TENABLE.IO']['secret_key'])
    logger.info('Successfully authenticated to Tenable.io')

    # Set scheduled scan time
    scan_time = datetime.now()

    # Set time delta if you need to launch scanning job right now
    if not args.tg_schedule:
        for section in settings.keys():
            if 'time_delta' in settings[section].keys():
                settings[section]['time_delta'] = 0

    # Launch scan jobs in Tenable.io against GCP resources
    if args.tg_gcp or args.tg_all:
        # Set GCP credentials environment
        logger.info('Parsing google credentials and set ENV variables')
        gcp_api_key_json = settings_obj.get('GCP', 'gcp-api-key-json')
        # Set Service account env variable and form path to json file
        os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = main_script_abs + gcp_api_key_json

        # Configure credentials for Google API authentication
        credentials = GoogleCredentials.get_application_default()
        compute = discovery.build('compute', 'v1', credentials=credentials)
        sql = discovery.build('sqladmin', 'v1beta4', credentials=credentials)
        logger.info('Successfully authenticated to GCP services')

        # Get list of all projects via GCP Resource manager
        resource_client = resource_manager.Client()
        projects_list = list(resource_client.list_projects())
        logger.info('Successfully extracted list GCP projects and public IP addresses')
        # Retrieve all GCP organization public IP address
        target_ip_addresses = gcp.get_organization_public_ip(compute, sql, projects_list)
        # # In case you need to read from local copy of saved projects
        # target_ip_addresses = gen.read_json_file('json/20181006T104414-gcp_addresses.json')
        logger.info('Trying to create scan jobs in Tenable.io for all GCP projects')

        # Launch scan against GCP resources
        scan_time = tnb.create_tenable_scan(scan_target='TENABLE_GCP_SCAN',
                                            client=tenable_client,
                                            target=target_ip_addresses,
                                            settings=settings,
                                            logger=logger,
                                            scan_time=scan_time)
        logger.info('Successfully created scan jobs in Tenable.io')

    if args.tg_cloudflare or args.tg_all:
        # Parse CF credentials environment
        logger.info('Parsing Cloudflare credentials')
        cf_email = settings_obj.get('CLOUDFLARE', 'cf_email')
        cf_api_key = settings_obj.get('CLOUDFLARE', 'cf_api_key')

        # Create Cloudflare connection object
        cf_client = CloudFlare.CloudFlare(email=cf_email, token=cf_api_key)
        # Create targets for scanning job
        target_hostnames = cf.get_cf_website_dns(cf_client=cf_client)

        # # Test purposes (comment please when test will be finished)
        # target_hostnames = gen.read_json_file('json/20181005T185623-cf_addresses.json')
        # scan_time += timedelta(hours=90)
        cf.create_firewall_access_rule(cf_client=cf_client, settings=settings, zones=target_hostnames)
        scan_time = tnb.create_tenable_scan(scan_target='TENABLE_CF_SCAN',
                                            client=tenable_client,
                                            target=target_hostnames,
                                            settings=settings,
                                            logger=logger,
                                            scan_time=scan_time)

    if args.tg_aws or args.tg_all:
        # Create Cloudflare connection object
        target_assets = aws.get_tenables_assets(client=tenable_client)
        scan_time = tnb.create_tenable_scan(scan_target='TENABLE_AWS_SCAN',
                                            client=tenable_client,
                                            target=target_assets,
                                            settings=settings,
                                            logger=logger,
                                            scan_time=scan_time)

    if args.tg_linode or args.tg_all:
        # Get Linode targets
        linode_client = LinodeClient(settings['LINODE']['lin_api_key'])
        linode_targets = lin.get_linode_targets(client=linode_client)
        scan_time = tnb.create_tenable_scan(scan_target='TENABLE_LINODE_SCAN',
                                            client=tenable_client,
                                            target=linode_targets,
                                            settings=settings,
                                            logger=logger,
                                            scan_time=scan_time)

    if args.tg_others or args.tg_all:
        # Launch scan of Other targets
        target_assets = others.prepare_other_targets(settings['TENABLE_OTHERS_SCAN'])
        scan_time = tnb.create_tenable_scan(scan_target='TENABLE_OTHERS_SCAN',
                                            client=tenable_client,
                                            target=target_assets,
                                            settings=settings,
                                            logger=logger,
                                            scan_time=scan_time)

    logger.info('Vulnerability scan will be finished at {0}'.format(scan_time.strftime('%Y%m%dT%H%M%S')))
    logger.info('########################################  END ########################################')