利用openVuln API自动化查询思科产品漏洞

利用openVuln API自动化查询思科产品漏洞
B站视频

一、背景

安全自动化是目前一个比较热门的话题,网络安全问题往往是由软件自身的安全漏洞被利用导致,所以及时修复已知安全漏洞,是抵御网络攻击非常重要的一环。这个文档介绍一下,如何利用思科openVuln API,自动化的查询特定思科产品的安全漏洞,并且通过Excel的方式展现这些漏洞信息。

先看一下最后代码输出的Excel截图,代码可以根据提供的软件版本CVE编号产品名称来查询漏洞信息,每次查询的漏洞信息会存储为一个CSV文件,最后将所有的CSV信息合并到一个Excel文件中,每个Excel Sheet就是一个CSV文件中的信息,Excel列宽会根据内容自动调整。image-20221206155308324

除了利用API的方式查询,另外也可以通过思科提供的图形化界面来查询漏洞信息,可以登录https://tools.cisco.com/security/center/publicationListing.x 网站查询思科设备的漏洞信息。
image-20221206004226273

也可以查询特定版本的漏洞信息,链接:https://tools.cisco.com/security/center/softwarechecker.x

image-20221206004913323

例如这里查询IOS 15.2(7)E2的漏洞信息。
image-20221206004921527

二、Cisco PSIRT openVuln API 简介

思科产品安全事件响应小组(Cisco Product Security Incident Response Team,PSIRT)是一个专门的全球团队,负责接收、调查和公开报告与思科产品和网络有关的安全漏洞信息 [1]。

思科PSIRT团队提供了openVuln API[2],允许用户查询思科产品的漏洞信息,漏洞信息支持多种格式的行业安全标准:

  • CVE:通用漏洞枚举(Common Vulnerability Enumeration),它就像是所有公开漏洞的字典表,对已公开的漏洞进行统一编号。由Mitre公司(非盈利机构)建立与维护,网址:https://cve.org/

  • CWE:常见弱点枚举 (Common Weakness Enumeration) 是MITRE公司继CVE之后的又一个安全漏洞词典,主要针对开发社区和安全从业人员社区,列出了架构、设计、代码或实施中可能出现的常见软件和硬件弱点,这些弱点可能导致可利用的安全漏洞 [3] ,网址:https://cwe.mitre.org

  • CVSS:通用漏洞评分系统 (Common Vulnerability Scoring System) 提供了一种评估漏洞严重性的方法,企业在修复漏洞时,可以根据这个优先级来修复。CVSS现在的版本是V3.1,漏洞评分为0~10分,漏洞分为4个等级:LOW(0.1~3.9)MEDIUM(4.0~6.9)HIGH(7.0~8.9)CRITICAL(9.0~10.0) [4],网址:https://first.org/cvss

  • CSAF:通用安全咨询框架 (Common Security Advisory Framework) 是结构化机器可读漏洞相关咨询的规范。CSAF 是通用漏洞报告框架 (CVRF) 的新名称和替代品。网址:https://csaf.io/

三、获取思科openVuln API访问凭证

思科openVuln API使用OAuth2进行认证,所以需要认证获得授权之后才能查询。

登录思科网站,创建凭证信息,网址https://apiconsole.cisco.com/apps/myapps

image-20221205142053019

创建一个应用名称,选择OAuth2.0的凭证类型,这里我选择客户端凭证。image-20221205142105693

勾选Cisco PSIRT openVuln API的权限,注意这个API的速率限制,每秒5次请求,每分钟30次请求。image-20221205142117035

创建完成。image-20221205142131223

查看产生的凭证信息,记录这个信息,KEY:djshucbvmpu4cmcsgufwt36w,CLIENT SECRET:TVJxz72ADUBKdb7ySjTzzcQp,注意不要泄露这个凭证信息(我会在演示完后销毁这个凭证)。image-20221205142142208

四、测试访问openVuln API

4.1 通过Postman软件测试

在Postman软件中选择配置OAuth 2.0的凭证信息,设置Token名称,设置凭证类型为Client Credentials,令牌URL为https://cloudsso.cisco.com/as/token.oauth2,Client ID为djshucbvmpu4cmcsgufwt36w,Client Secret:TVJxz72ADUBKdb7ySjTzzcQp,填写完信息之后,点击产生新的Token信息,然后使用这个Token。image-20221205144102631

在软件中发起HTTP GET请求,通过CVE信息查询受影响的产品 [5],HTTP GET测试URL为:https://api.cisco.com/security/advisories/v2/cve/CVE-2021-44228![image-20221205144109107](/content/images/mypost/cisco-openvuln-api/image-20221205144109107.png)

4.2 通过Terminal运行测试

通过pip3 install openVulnQuery安装openVulnQuery模块 [6]后,可以在Linux terminal使用命令行测试。

[root@centos8 ~]# pip3 install openVulnQuery

安装之后创建一个凭证文件,输入CLIENT_IDCLIENT_SECRET信息。

也可以将这个凭证信息配置在环境变量中,例如:export CLIENT_ID="djshucbvmpu4cmcsgufwt36w",export CLIENT_SECRET="TVJxz72ADUBKdb7ySjTzzcQp"

[root@centos8 ~]# vim Credentials.json
{
    "CLIENT_ID": "djshucbvmpu4cmcsgufwt36w",
    "CLIENT_SECRET": "TVJxz72ADUBKdb7ySjTzzcQp"
}

调用凭证信息,查询2022年8月份所有critical级别的漏洞。

[root@centos8 ~]# openVulnQuery --config Credentials.json --severity critical --first_published 2022-08-01:2022-08-30
[
    {
        "advisory_id": "cisco-sa-sb-mult-vuln-CbVp4SUR",
        "advisory_title": "Cisco Small Business RV Series Routers Vulnerabilities",
        "bug_ids": [
            "CSCwb58268",
            "CSCwb58273",
            "CSCwb98961",
            "CSCwb98964",
            "CSCwc00210"
        ],
        "cves": [
            "CVE-2022-20827",
            "CVE-2022-20841",
            "CVE-2022-20842"
        ],
        "cvrfUrl": "https://tools.cisco.com/security/center/contentxml/CiscoSecurityAdvisory/cisco-sa-sb-mult-vuln-CbVp4SUR/cvrf/cisco-sa-sb-mult-vuln-CbVp4SUR_cvrf.xml",
        "cvss_base_score": "9.8",
        "cwe": [
            "CWE-120",
            "CWE-77",
            "CWE-78"
        ],
        "first_published": "2022-08-03T23:00:00",
        "ips_signatures": [
            "NA"
        ],
        "last_updated": "2022-08-03T23:00:00",
        "product_names": [
            "Cisco Small Business RV Series Router Firmware "
        ],
        "publication_url": "https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sb-mult-vuln-CbVp4SUR",
        "sir": "Critical",
        "summary": "<p>Multiple vulnerabilities in Cisco&nbsp;Small Business RV160, RV260, RV340, and RV345 Series Routers could allow an unauthenticated, remote attacker to execute arbitrary code or cause a denial of service (DoS) condition on an affected device.</p>\n<p>For more information about these vulnerabilities, see the&nbsp;<a href=\"#ds\">Details</a>&nbsp;section of this advisory.</p>\n<p>Cisco&nbsp;has released software updates that address these vulnerabilities. There are no workarounds that address these vulnerabilities.</p>\n<p>This advisory is available at the following link:<br><a href=\"https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sb-mult-vuln-CbVp4SUR\">https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sb-mult-vuln-CbVp4SUR</a></p>"
    }

4.3 将OpenVulnQuery做为库(Library)测试

创建一个python测试脚本,填入client_idclient_secret。这里查询特IOS 15.2(7)E5这个版本漏洞信息。

[root@centos8 ~]# vim prist_demo.py

from openVulnQuery import query_client
query_client = query_client.OpenVulnQueryClient(client_id="djshucbvmpu4cmcsgufwt36w", client_secret="TVJxz72ADUBKdb7ySjTzzcQp")
advisories = query_client.get_by_ios(adv_format='default', ios_version='15.2(7)E5')

for x in advisories:
    print(f'advisory_id:{x.advisory_id}')
    print(f'sir:{x.sir}')
    print(f'first_published:{x.first_published}')
    print(f'last_updated:{x.last_updated}')
    print(f'cves:{x.cves}')
    print(f'bug_ids:{x.bug_ids}')
    print(f'cvss_base_score:{x.cvss_base_score}')
    print(f'advisory_title:{x.advisory_title}')
    print(f'publication_url:{x.publication_url}')
    print(f'cwe:{x.cwe}')
    # print(f'product_names:{x.product_names}')
    # print(f'summary:{x.summary}')
    print('-'*30)

下面是所有可以获取的字段信息,可以根据需求自行过滤。

advisory_id
advisory_title
bug_ids
csafUrl
cves
cvrfUrl
cvss_base_score
cwe
filter
first_published
ips_signatures
last_updated
platforms
product_names
publication_url
sir
summary

运行测试脚本的输出信息。

[root@centos8 ~]# python3 prist_demo.py
advisory_id:cisco-sa-ssh-excpt-dos-FzOBQTnk
sir:High
first_published:2022-09-28T16:00:00
last_updated:2022-09-28T16:00:00
cves:['CVE-2022-20920']
bug_ids:['CSCvx63027']
cvss_base_score:7.7
advisory_title:Cisco IOS and IOS XE Software SSH Denial of Service  Vulnerability
publication_url:https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-ssh-excpt-dos-FzOBQTnk
cwe:['CWE-755']
------------------------------
advisory_id:cisco-sa-ikev2-ebFrwMPr
sir:High
first_published:2021-09-22T16:00:00
last_updated:2021-09-22T16:00:00
cves:['CVE-2021-1620']
bug_ids:['CSCvw25564']
cvss_base_score:7.7
advisory_title:Cisco IOS and IOS XE Software IKEv2 AutoReconnect Feature Denial of Service Vulnerability
publication_url:https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-ikev2-ebFrwMPr
cwe:['CWE-563']
------------------------------

五、Python最终代码

5.1 使用openVulnQuery API 2.0

思科PSIRT在2022年8月1日发布了新的API接口,并通告旧的API接口将会下线。但是目前通过pip install安装的Python库使用的是旧API接口,如果想要在Python代码中使用新的API接口,可以在pip install安装模块后,从Github下载最新的代码,替换整个_library目录中的所有内容。下面演示一下这个过程。

首先正常安装openVulnQuery模块。

[root@centos8 ~]# pip3 install openVulnQuery

安装之后,查询openVulnQuery模块的安装目录。

[root@centos8 _library]# find / -name "advisory.py"
/usr/local/lib64/python3.6/site-packages/openVulnQuery/_library/advisory.py

可以查看目录中的config.py文件,关注最后一行的API_URL信息,新的API_URL链接为:API_URL = "https://api.cisco.com/security/advisories/v2"。所以可以确认通过pip install安装的模块,使用的是旧的API接口。

[root@centos8 _library]# more /usr/local/lib64/python3.6/site-packages/openVulnQuery/_library/config.py
# There are four prerequisites needed before a user can initiate the API service calls and obtain access to the underlying Cisco security vulnerability information
.
#  - Sign-in with your CCO ID
#  - Register a client application to create a “unique client identifier” that will identify your client application to the Cisco Token services. Registration crea
tes the client credentials along with name assignment, description, and subscribes the client application to one or more of the OAuth v2.0 grant types requested fo
r their client  application.
#  - Get Access Tokens - utilize Cisco's Token services to acquire an OAuth v2.0 access-token(s).
#  - Make API Calls

# Enter your client ID and client secret below.

CLIENT_ID = ""
CLIENT_SECRET = ""

REQUEST_TOKEN_URL = "https://cloudsso.cisco.com/as/token.oauth2"
API_URL = "https://api.cisco.com/security/advisories"

从Github下载最新的代码。

[root@centos8 ~]# git clone https://github.com/CiscoPSIRT/openVulnQuery.git
正克隆到 'openVulnQuery'...
remote: Enumerating objects: 294, done.
remote: Counting objects: 100% (121/121), done.
remote: Compressing objects: 100% (94/94), done.
remote: Total 294 (delta 58), reused 44 (delta 24), pack-reused 173
接收对象中: 100% (294/294), 152.18 KiB | 763.00 KiB/s, 完成.
处理 delta 中: 100% (129/129), 完成.

将Github中_library目录的所有文件拷贝到原有的_library目录中,并覆盖原有文件。

cp -r /root/openVulnQuery/openVulnQuery/_library/ /usr/local/lib64/python3.6/site-packages/openVulnQuery/

5.2 Python查询思路

这个代码的主要目的是:根据提供的软件版本CVE编号产品名称来查询漏洞信息,并将所有漏洞信息整合到Excel中。

首先是根据什么信息来查询漏洞,最准确的是根据系统加版本来查询,可以明确的获取当前版本的所有漏洞信息。但是可惜的是,并不是所有思科产品都支持这个查询方式,只有下面这些系统可以通过软件版本的方式查询。

Cisco IOS Software (ios)
Cisco IOS XE Software (iosxe)
Cisco NX-OS Software (nxos)
Cisco NX-OS Software in ACI mode (aci)
Cisco Adaptive Security Appliance (ASA) Software (asa)
Cisco Firepower Threat Defense (FTD) Software (ftd)
Cisco Secure Firewall Management Center (FMC) Software (fmc)
Cisco Firepower eXtensible Operating System (FXOS) (fxos)

其他不支持软件版本方式查询的系统,可以通过产品名称来查询,例如WLCISE等。如果你想了解产品的全称,可以访问https://tools.cisco.com/security/center/productBoxData.x?prodType=CISCO获取思科的所有产品名称。

通过CVE编号查询受影响的产品,也是一个比较实用的查询方式。例如最近突发了一个Log4j2漏洞,已知CVE编号是CVE-2021-44228,想了解有哪些思科产品受到影响,可以通过这种方式来查询,列出所有受到影响的产品。

查询完成后,就是用什么样的格式来输出这些信息。我将每个查询的结果生成一个CSV文件,因为CSV是一个纯文本文件,所以可以直接使用文本编辑器查看。但是如果查询很多产品的漏洞后,想在一个文件中查看,Excel是更加合适的格式。Excel可以将每个CSV文件作为一个Sheet,这样查看起来更加清晰。所有代码最终会输出两类文件,一类是基于每次查询产生的CSV文件,一个是所有CSV合并起来的Excel文件。另外将CSV合并到Excel时,默认列的宽度默认较小,可以根据列的内容动态的来调整Excel列宽,这样可读性更好。

5.3 Python 最终代码

创建一个文件夹,用于存放查询结果的CSV文件。

[root@centos8 ~]# mkdir cisco_vuln_csv_folder

安装这次代码所需的Python模块pandasopenpyxlXlsxWriteropenVulnQuery

注意openVulnQuery模块已经在5.1部分替换了最新的代码文件,使用了API 2.0接口。

[root@centos8 ~]# pip3 install pandas openpyxl XlsxWriter

创建Python代码文件,请自行替换client_idclient_secret。处于安全性考虑,账号信息可以放到另外的配置文件中来调用,这里为了简化代码,我直接放在源文件中了。另外这个代码也有很多重复性的部分可以优化,这里只是给大家提供一个思路,可以根据需要自行修改。如果有想要更好的查询方式,也欢迎联系我 :)

import csv
import os
import pandas as pd

client_id = "djshucbvmpu4cmcsgufwt36w"
client_secret = "TVJxz72ADUBKdb7ySjTzzcQp"
csv_folder = r'./cisco_vuln_csv_folder/'


def cisco_ver_vuln_csv(ostype='ios', version='None'):
    from openVulnQuery import query_client
    query_client = query_client.OpenVulnQueryClient(client_id=client_id, client_secret=client_secret)
    if ostype == 'ios':
        advisories = query_client.get_by_ios(adv_format='default', ios_version=version)
    elif ostype == 'iosxe':
        advisories = query_client.get_by_ios_xe(adv_format='default', ios_version=version)
    elif ostype == 'asa':
        advisories = query_client.get_by_asa(adv_format='default', asa_version=version)
    elif ostype == 'fmc':
        advisories = query_client.get_by_fmc(adv_format='default', fmc_version=version)
    elif ostype == 'ftd':
        advisories = query_client.get_by_ftd(adv_format='default', ftd_version=version)
    elif ostype == 'fxos':
        advisories = query_client.get_by_fxos(adv_format='default', fxos_version=version)
    else:
        print('请输入以下支持的OS类型:ios|iosxe|asa|fmc|ftd|fxos')

    headers = ['advisory_title',
               'sir',
               'cvss_base_score',
               'first_published',
               'last_updated',
               'publication_url',
               'cves',
               'advisory_id',
               'bug_ids',
               ]

    csvfile = open(csv_folder + ostype+'_'+version+'.csv', 'w', newline='')
    advisories_info = []

    for x in advisories:
        advisories_info.append({'advisory_title': x.advisory_title,
                                'sir': x.sir,
                                'cvss_base_score': x.cvss_base_score,
                                'first_published': x.first_published,
                                'last_updated': x.last_updated,
                                'publication_url': x.publication_url,
                                'cves': x.cves,
                                'advisory_id': x.advisory_id,
                                'bug_ids': x.bug_ids
                                })

    c = csv.DictWriter(csvfile, fieldnames=headers)
    c.writeheader()
    c.writerows(advisories_info)
    csvfile.close()


def cisco_product_vuln_csv(product_name='wlc'):
    from openVulnQuery import query_client
    query_client = query_client.OpenVulnQueryClient(client_id=client_id, client_secret=client_secret)
    advisories = query_client.get_by_product(adv_format='default', product_name=product_name)

    headers = ['advisory_title',
               'sir',
               'cvss_base_score',
               'first_published',
               'last_updated',
               'publication_url',
               'cves',
               'advisory_id',
               'bug_ids',
               ]

    if product_name == 'Cisco Identity Services Engine Software':
        csvfile = open(csv_folder + 'product_ISE.csv', 'w', newline='')
    elif product_name == 'Cisco Unified Communications Manager':
        csvfile = open(csv_folder + 'product_CUCM.csv', 'w', newline='')
    else:
        csvfile = open(csv_folder + 'product'+'_'+product_name+'.csv', 'w', newline='')

    advisories_info = []
    for x in advisories:
        advisories_info.append({'advisory_title': x.advisory_title,
                                'sir': x.sir,
                                'cvss_base_score': x.cvss_base_score,
                                'first_published': x.first_published,
                                'last_updated': x.last_updated,
                                'publication_url': x.publication_url,
                                'cves': x.cves,
                                'advisory_id': x.advisory_id,
                                'bug_ids': x.bug_ids
                                })

    c = csv.DictWriter(csvfile, fieldnames=headers)
    c.writeheader()
    c.writerows(advisories_info)
    csvfile.close()


def cisco_cve_vuln_csv(cve_id='CVE-2021-44228'):
    from openVulnQuery import query_client
    query_client = query_client.OpenVulnQueryClient(client_id=client_id, client_secret=client_secret)
    advisories = query_client.get_by_cve(adv_format='default', cve_id=cve_id)

    headers = ['advisory_title',
               'sir',
               'cvss_base_score',
               'first_published',
               'last_updated',
               'publication_url',
               'cves',
               'advisory_id',
               'bug_ids',
               ]

    csvfile = open(csv_folder + cve_id + '.csv', 'w', newline='')
    advisories_info = []

    for x in advisories:
        advisories_info.append({'advisory_title': x.advisory_title,
                                'sir': x.sir,
                                'cvss_base_score': x.cvss_base_score,
                                'first_published': x.first_published,
                                'last_updated': x.last_updated,
                                'publication_url': x.publication_url,
                                'cves': x.cves,
                                'advisory_id': x.advisory_id,
                                'bug_ids': x.bug_ids
                                })

    c = csv.DictWriter(csvfile, fieldnames=headers)
    c.writeheader()
    c.writerows(advisories_info)
    csvfile.close()


if __name__ == '__main__':
    import time
    cisco_ver_vuln_csv(ostype='ios', version='15.2(7)E5')
    cisco_ver_vuln_csv(ostype='iosxe', version='17.8.1')
    cisco_ver_vuln_csv(ostype='asa', version='9.18.1')
    cisco_ver_vuln_csv(ostype='fmc', version='7.0.2')
    time.sleep(3)
    cisco_ver_vuln_csv(ostype='ftd', version='7.2.0')
    cisco_ver_vuln_csv(ostype='fxos', version='2.12.0.31')
    cisco_cve_vuln_csv(cve_id='CVE-2021-44228')
    time.sleep(3)
    cisco_product_vuln_csv(product_name='WLC')
    cisco_product_vuln_csv(product_name='Cisco Identity Services Engine Software')
    cisco_product_vuln_csv(product_name='Cisco Unified Communications Manager')
    cisco_product_vuln_csv(product_name='Cisco TelePresence')

    # 多个CSV文件合并为一个excel
    csv_folder_name = r"./cisco_vuln_csv_folder"
    writer = pd.ExcelWriter('my_cisco_vuln.xlsx')
    csv_file_list = os.listdir(csv_folder_name)

    for csv_name in csv_file_list:
        csv_data = pd.read_csv(csv_folder_name + '/' + csv_name, encoding='UTF-8')
        csv_data.to_excel(writer, csv_name, index=False)

        df = pd.DataFrame(data=csv_data)

        for column in df:
            column_width = max(df[column].astype(str).map(len).max(), len(column))
            col_idx = df.columns.get_loc(column)
            writer.sheets[csv_name].set_column(col_idx, col_idx, column_width)
    writer.save()
    print('Excel文件已经创建完成')

运行代码测试。

[root@centos8 ~]# python3 cisco_psirt_vuln.py
Excel文件已经创建完成

查看输出的CSV文件和Excel文件。

[root@centos8 ~]# ls cisco_vuln_csv_folder/
 asa_9.18.1.csv   ftd_7.2.0.csv       'ios_15.2(7)E5.csv'  'product_Cisco TelePresence.csv'   product_ISE.csv
 fmc_7.0.2.csv    fxos_2.12.0.31.csv   iosxe_17.8.1.csv     product_CUCM.csv                  product_WLC.csv

[root@centos8 ~]# ls my_cisco_vuln.xlsx
my_cisco_vuln.xlsx

打开Excel文件查看,通过软件版本方式的查询结果是非常准确的,对应的软件版本一定有这些漏洞。image-20221206155308324

通过产品名称的方式查询,会返回这个产品已知的所有漏洞信息,需要人工进一步的去判断,所关注的版本是否收到影响。不过可以根据first_publishded字段查看漏洞的发布时间,如果当前运行的版本是2020年发布的,那么也没有必要查看之前时间发布的漏洞。image-20221205233815929

六、运行代码可能遇见的报错

当未安装XlsxWriter模块时会遇见下面报错,可以通过安装这个模块解决,pip3 install XlsxWriter

[root@centos8 ~]# python3 cisco_psirt_vuln.py
Traceback (most recent call last):
  File "cisco_prist_vuln.py", line 129, in <module>
    writer.sheets[csv_name].set_column(col_idx, col_idx, column_width)
AttributeError: 'Worksheet' object has no attribute 'set_column'

如果使用了旧的API,可能遇见下面报错。因为通过pip install安装的openVulnQuery模块,使用的是旧的API,其中没有get_by_asa这个方法。解决方法参考5.1部分,使用最新的Github代码,代码链接https://github.com/CiscoPSIRT/openVulnQuery

[root@centos8 ~]# python3 cisco_psirt_vuln.py
Traceback (most recent call last):
  File "cisco_psirt_vuln.py", line 105, in <module>
    cisco_ver_vuln_csv(ostype='asa', version='9.18.1')
  File "cisco_psirt_vuln.py", line 18, in cisco_ver_vuln_csv
    advisories = query_client.get_by_asa(adv_format='default', asa_version=version)
AttributeError: 'OpenVulnQueryClient' object has no attribute 'get_by_asa'

当网络不稳定,或者API超过限制速率时,可能遇见下面报错。可以尝试更换主机的网络环境,或者等1分钟后再测试。API速率限制是每秒5次请求,每分钟30次请求。

requests.exceptions.ConnectionError: HTTPSConnectionPool(host='cloudsso.cisco.com', port=443): Max retries exceeded with url: /as/token.oauth2?client_id=djshucbvmpu4cmcsgufwt36w&client_secret=TVJxz72ADUBKdb7ySjTzzcQp (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x7fc2bcea1c88>: Failed to establish a new connection: [Errno 101] Network is unreachable',))

requests.exceptions.ConnectionError: HTTPSConnectionPool(host='cloudsso.cisco.com', port=443): Max retries exceeded with url: /as/token.oauth2?client_id=djshucbvmpu4cmcsgufwt36w&client_secret=TVJxz72ADUBKdb7ySjTzzcQp (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x00000214AA2EFA88>: Failed to establish a new connection: [WinError 10060] 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。'))

requests.exceptions.ProxyError: HTTPSConnectionPool(host='api.cisco.com', port=443): Max retries exceeded with url: /security/advisories/v2/OSType/ios?version=15.2%287%29E5 (Caused by ProxyError('Cannot connect to proxy.', ConnectionResetError(10054, '远程主机强迫关闭了一个现有的连接。', None, 10054, None)))

七、参考文档