cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2310
Views
0
Helpful
0
Comments
AdvocateRick
Cisco Employee
Cisco Employee

When managing Cisco Vulnerability Management systems, there are situations where you want to remove an asset, which could be a server, router, or laptop. One reason to manually remove an asset can be to show risk score changes without waiting for the configurable Asset Inactivity Limit to take effect.  

All assets remain marked as active unless configured otherwise.  This means that the risk score will continue to be calculated on the active assets.  When assets are not active, their vulnerabilities are listed and included in your risk score.  Thus the calculated risk score could be considered inaccurate, which would skew your view of risk within the business or prompt you to spend time remediating vulnerabilities on an asset that isn’t critical. 

And of course you don’t want to report an inaccurate risk score to management.

You might consider deleting the asset, but deleting an asset requires a call to Kenna (now Cisco Vulnerability Management) support. However, marking an asset inactive is just an API invocation.  You can mark an asset inactive in the UI as well.

This blog will present how to inactivate and reactivate an asset via the Kenna Security REST API; but first, let’s see how to list assets.

How to list active assets

The list_assets.py program lists assets’ ID, host name, and a note. Asset results can be filtered by a status parameter.  Valid values are “active” or “inactive.”  If no parameter is specified, then information on both “active” and “inactive” assets are returned from the API invocation.

The list assets API retrieves active assets with open vulnerabilities. Since this is the first time we’re going over some API code, let’s look at some basic bits of code.  This code does not contain pagination; therefore only the first 500 assets can be listed.  Pagination will be covered in a future blog.

All Kenna APIs use an API token or Key for authentication.  Here the API key is obtained from an environmental shell variable.

 21 # KENNA_API_KEY is an environment variable.
 22 api_key = os.getenv('KENNA_API_KEY')
 23 if api_key is None:
 24     print("Environment variable KENNA_API_KEY is non-existent")
 25     sys.exit(1)

Next the HTTP header is initialized with the Accept and X-Risk-Token keys. The Accept key advertises we will accept JSON.  The customized key, X-Risk-Token, passes the API key to verify who you are.

27 # HTTP header.
28 headers = {'Accept': 'application/json',
29      'X-Risk-Token': api_key}

Recall that this program can list separately or both active and inactive assets.  We won’t discuss command line inputs, and proceed directly to function, list_assets(), which takes the parameters url and context.  The url is used to invoke the API and context for annotating which assets are being displayed.

The list asset API is invoked and the assets are obtained.

34 # List assets depending on the URL. Context is displayed.
35 def list_assets(url, context):
36     response = requests.get(url, headers=headers)
37     if response.status_code != 200:
38         print("List Asset Error: " + str(response.status_code))
39         sys.exit(1)
40
41     resp_json = response.json()
42     #print(resp_json)
43
44     assets = resp_json['assets']

Assets are sorted by asset ID.  Then, asset ID, host name, and note are extracted for each asset and displayed if the asset’s status matches the script input parameters.  Finally the number of assets are displayed.

 48     # Run through all the assets and print asset ID, asset hostname, and asset note.
 49     assets.sort(key=sortFunc)
 50     for asset in assets:
 51         if asset['id'] is None:
 52             continue
 53 
 54         hostname = "no hostname" if asset['hostname'] is None else asset['hostname']
 55         notes = "" if asset['notes'] is None or asset['notes'] == "" else " : " + asset['notes']
 56 
 57         out_buf = str(asset['id']) + " : " + asset['status'] + " ; " + hostname + notes
 58         print(out_buf)
 58 
 60     print("Number of " + context + ": " + str(len(assets)))

Let’s take a look at the URLs that are used.  For active assets, the URL is:

62 list_active_assets_url = "https://api.kennasecurity.com/assets"

And for inactive assets, the URL is:

70     list_inactive_assets_url = list_active_assets_url + "?filter=inactive"

This sums to: https://api.kennasecurity.com/assets?filter=inactive.

With these URLs, list_assets() is called for each URL if applicable.

 62 # List active assets.
 63 list_active_assets_url = "https://api.kennasecurity.com/assets"
 64 if (status_opt == "both") or (status_opt == "active"):
 65     list_assets(list_active_assets_url, "Active Assets")
 66 
 67     print("")
 68 
 69 # List inactive assets.
 70 if (status_opt == "both") or (status_opt == "inactive"):
 71     list_inactive_assets_url = list_active_assets_url + "?filter=inactive"
 72     list_assets(list_inactive_assets_url, "Inactive Assets")

How to inactivate an asset

Now that we know how to list assets, let’s see how to manually inactivate an asset.  Setting the status manually inactive means that no matter what information Kenna (now Cisco Vulnerability Management) has on the asset, the status will be inactive.

Since we’ve gone over the basics in the list assets example, let’s look at the important bits of code in set_asset_inactive.py.  The set_asset_inactive.py program can take two parameters, the asset ID, which is required, and an optional note so that you can notate why or when the asset is made ‘inactive’. If there is no note, it is cleared.

Since the code is modifying the asset, we use the update asset API, and it requires a body.  The body is in JSON. As you can see the asset key in the JSON body contains the inactive flag and notes.  This code only modifies the inactive flag and notes.  The URL is forged with the server and asset ID to be modified.

 32 # Forge the update asset URL by adding the asset ID.
 33 url = "https://api.kennasecurity.com/assets"
 34 update_asset_url = url + "/" + str_asset_id
 35 
 36 # This will reset notes if notes is not specified.
 37 asset_info = {
 38     'asset': {
 39         'inactive': True,
 40         'notes' : note
 41     }
 42 }
 43 
 44 # main
 45 # Invoke the update asset API.
 46 try:
 47     response = requests.put(update_asset_url, headers=headers, data=json.dumps(asset_info))
 48 except Exception as exp:
 49     print("Update Asset Error: " + exp.__str__())
 50     sys.exit(1)

How to reactivate an asset

If for some reason (reassigning the IP address), you want to reactivate the asset, you need to remove the manual override.  Just manually setting the asset’s status to “active” means that Kenna (now Cisco) will always see the asset active, which may not be what you want. Instead by setting the remove_override flag, the asset reverts to its natural state: able to transition automatically from active/inactive in response to activity or lack thereof.

The code in reactivate_asset.py is very similar to set_asset_inactive.py. The important difference is in the body that will be sent to update the asset.

 37 # This will reset notes if notes is not specified.
 38 asset_info = {
 39     'asset': {
 40         'remove_override': True,
 41         'notes' : note
 42     }
 43 }

As you can see, the only difference is the remove_override flag that is set instead of the inactive flag.

Execute

First let’s list some assets:

% python list_assets.py
List Assets
Active Assets
1 : active ; leto-laptop
2 : active ; paul-laptop
3 : active ; stilgar-laptop
4 : active ; building-5-router
5 : active ; cherry-server
. . .
140 : active ; jessica-laptop
141 : active ; building-3-router
142 : active ; b3-r302-c8-server
143 : active ; b3-r301-d8-server
Number of Active Assets: 143

Inactive Assets
Number of Inactive Assets: 0
%

Now inactive asset with asset ID 3 and a note on when it was compromised.

% python set_asset_inactive.py 3 "Compromised on 2020-02-14"
Set Asset Inactive on 3
Asset ID 3 set to inactive
%

List again to verify.  You might have to wait approximately 30 seconds before the change can be seen.

% python list_assets.py                                    
List Assets
Active Assets
1 : active ; leto-laptop
2 : active ; paul-laptop
4 : active ; building-5-router
5 : active ; cherry-server
. . .
140 : active ; jessica-laptop
141 : active ; building-3-router
142 : active ; b3-r302-c8-server
143 : active ; b3-r301-d8-server
Number of Active Assets: 142

Inactive Assets
3 : inactive ; stilgar-laptop : Compromised on 2020-02-14
Number of Inactive Assets: 1
%

The vulnerability has been fixed, and now reactivate the asset with the asset ID. A note was added to state when the asset was reactivated.

% python reactivate_asset.py 3 "Reactivated on 2020-02-16"
Set Asset Remove Override on 3
Asset ID 3 override removed.
%

List the assets to verify. You might have to wait approximately 30 seconds before the change can be seen.

% python list_assets.py
List Assets
Active Assets
1 : active ; leto-laptop
2 : active ; paul-laptop
3 : active ; stilgar-laptop : Reactivated on 2020-02-16
4 : active ; building-5-router
5 : active ; cherry-server
. . .
140 : active ; jessica-laptop
141 : active ; building-3-router
142 : active ; b3-r302-c8-server
143 : active ; b3-r301-d8-server
Number of Active Assets: 143

Inactive Assets
Number of Inactive Assets: 0
%

Conclusion

So now you know how to list, inactivate, and reactivate assets via Kenna Security’s REST APIs.  Developing a program might be more user friendly than clicking through the Kenna (now Cisco) GUI.  The code could be modified to take in multiple assets to inactivate, thus saving GUI clicks.  If you’re interested in playing with these samples, they’re located in a Kenna Security blog_samples repo in the assets directory.

Rick Ehrhart - Apr 6, 2021

API Evangelist

This blog was originally written for Kenna Security, which has been acquired by Cisco Systems.
Learn more about Cisco Vulnerability Management.

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: