Skip to content

Commit

Permalink
Merge pull request #3 from LimberDuck/develop
Browse files Browse the repository at this point in the history
v. 0.0.3
  • Loading branch information
damian-krawczyk authored Aug 31, 2021
2 parents 42c31c9 + a099e78 commit 09dee5d
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ dist
*.egg-info
__pycache__
*.pyc
test_files
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to [**TNSCM** *(Tenable Nessus CLI Manager)* by LimberDuck][
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.3] - 2021-08-31

### Added

- new format option to display data - `--format csv`
- data filtering possibility using [JMESPath](https://jmespath.org), see [Example filters](https://github.com/LimberDuck/tnscm#example-filters).

## [0.0.2] - 2021-08-25

### Added
Expand All @@ -19,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- initial release

[0.0.3]: https://github.com/LimberDuck/tnscm/compare/v0.0.2...v0.0.3
[0.0.2]: https://github.com/LimberDuck/tnscm/compare/v0.0.1...v0.0.2
[0.0.1]: https://github.com/LimberDuck/tnscm/releases/tag/v0.0.1

Expand Down
51 changes: 35 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
[![PyPI - Downloads](https://img.shields.io/pypi/dm/tnscm?logo=PyPI)](https://pypi.org/project/tnscm/) [![License](https://img.shields.io/github/license/LimberDuck/tnscm.svg)](https://github.com/LimberDuck/tnscm/blob/main/LICENSE) [![Repo size](https://img.shields.io/github/repo-size/LimberDuck/tnscm.svg)](https://github.com/LimberDuck/tnscm) [![Code size](https://img.shields.io/github/languages/code-size/LimberDuck/tnscm.svg)](https://github.com/LimberDuck/tnscm) [![Supported platform](https://img.shields.io/badge/platform-windows%20%7C%20macos%20%7C%20linux-lightgrey.svg)](https://github.com/LimberDuck/tnscm)


Main features
=============
## Main features

Initial version of **TNSCM** lets you get Nessus:

* plugin family list
* policy list
* scan list
* user list
* server info
* status
* licensed IPs
* version
* user list

Additionaly, list items can by filtered using [JMESPath](https://jmespath.org).

How to
======
## How to

1. Install

Expand All @@ -30,29 +30,48 @@ How to

`tnscm`

Meta
====
### Example filters

To get only name and id columns:

`--filter "[].{id: id, name: name}"`

To sort by `id` column:

`--filter "sort_by([], &id)[].{id: id, name: name}"`

To filter returned data to these items which `name` contain `exampl`:

`--filter "[? contains(name, 'exampl')].{id: id, name: name}"`

To filter returned data to these items which `name` contain `exampl1` or `exampl2`:

Change log
----------
`--filter "[? contains(name, 'exampl1') || contains(name, 'exampl2')].{id: id, name: name}"`

To filter returned data to item which `id` is equal to number `10`:

``--filter '[?id==`10`].{id: id, name: name}'``

To filter returned data to item which `name` is equal to number `test name`:

`--filter "[?name == 'test name'].{id: id, name: name}"`

## Meta

### Change log

See [CHANGELOG].


Licence
-------
### Licence

MIT: [LICENSE].


Authors
-------
### Authors

[Damian Krawczyk] created **TNSCM** *(Tenable Nessus CLI Manager)* by LimberDuck.

[Damian Krawczyk]: https://damiankrawczyk.com

[CHANGELOG]: https://github.com/LimberDuck/tnscm/blob/main/CHANGELOG.md
[LICENSE]: https://github.com/LimberDuck/tnscm/blob/main/LICENSE


3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ keyring>=23.0.1
oauthlib>=3.1.1
requests>=2.25.1
pandas>=1.3.2
tabulate>=0.8.9
tabulate>=0.8.9
jmespath>=0.10.0
128 changes: 94 additions & 34 deletions tnscm/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import sys
from oauthlib.oauth2.rfc6749.errors import CustomOAuth2Error
import datetime
import jmespath

os_user = getpass.getuser().lower()

Expand All @@ -34,8 +35,10 @@
click.option('--insecure', '-k', is_flag=True,
help="perform insecure SSL connections and transfers"),
click.option('--format', '-f', default='table',
help='data format to display [table,json]',
show_default="table")
help='data format to display [table,json,csv]',
show_default="table"),
click.option('--filter', '-f',
help='filter data with JMESPath. See https://jmespath.org/ for more information and examples.'),
]

_general_options = [
Expand Down Expand Up @@ -183,8 +186,9 @@ def server(address, port, username, password, insecure, format, status, ips, ver
+ ' = ' + '{0:}'.format(left_ips) + ' (' + left_ips_percentage + '%) remaining IPs')

if version:
nessus_type = tnscon.server_properties_get()['nessus_type']
server_version = tnscon.server_properties_get()['server_version']
print(one_address, server_version)
print(one_address, nessus_type, server_version)

tnscon.logout()

Expand All @@ -194,7 +198,7 @@ def server(address, port, username, password, insecure, format, status, ips, ver
@add_options(_general_options)
@click.option('--list', is_flag=True,
help="Get user list")
def user(address, port, username, password, insecure, format, list, verbose):
def user(address, port, username, password, insecure, format, filter, list, verbose):
"""get Nessus user info"""

for one_address in address:
Expand All @@ -214,14 +218,28 @@ def user(address, port, username, password, insecure, format, list, verbose):
if list:
print(one_address)
users_on_nessus = tnscon.users_get()
users_on_nessus = [{
'id': k['id'],
'username': k['username'],
'name': k['name'],
'lastlogin': datetime.datetime.fromtimestamp(0 if k['lastlogin'] is None else k['lastlogin']),
} for k in users_on_nessus]

for user_on_nessus in users_on_nessus:
if 'lastlogin' in user_on_nessus:
user_on_nessus.update({'lastlogin': datetime.datetime.fromtimestamp(0 if user_on_nessus['lastlogin'] is None else user_on_nessus['lastlogin'])})

default_filter = '[].{' \
'id: id, ' \
'username: username, ' \
'name: name, ' \
'lastlogin: lastlogin}'

if filter:
expression = jmespath.compile(filter)
else:
expression = jmespath.compile(default_filter)

users_on_nessus = expression.search(users_on_nessus)

if format == 'table':
print(dataframe_table(users_on_nessus))
elif format == 'csv':
print(dataframe_table(users_on_nessus).to_csv(index=False), '\n')
else:
print(users_on_nessus)

Expand All @@ -236,7 +254,7 @@ def user(address, port, username, password, insecure, format, list, verbose):
@add_options(_general_options)
@click.option('--list', is_flag=True,
help="Get scan policy list")
def policy(address, port, username, password, insecure, format, list, verbose):
def policy(address, port, username, password, insecure, format, filter, list, verbose):
"""get Nessus policy info"""

for one_address in address:
Expand All @@ -256,16 +274,32 @@ def policy(address, port, username, password, insecure, format, list, verbose):
if list:
print(one_address)
scan_policies_on_nessus = tnscon.policies_get()
scan_policies_on_nessus = [{
'id': k['id'],
'name': k['name'],
'owner': k['owner'],
'creation_date': datetime.datetime.fromtimestamp(int(k['creation_date'])),
'last_modification_date': datetime.datetime.fromtimestamp(int(k['last_modification_date'])),
} for k in scan_policies_on_nessus]

for scan_policy_on_nessus in scan_policies_on_nessus:
if 'creation_date' in scan_policy_on_nessus:
scan_policy_on_nessus.update({'creation_date': datetime.datetime.fromtimestamp(int(scan_policy_on_nessus['creation_date']))})
if 'last_modification_date' in scan_policy_on_nessus:
scan_policy_on_nessus.update({'last_modification_date': datetime.datetime.fromtimestamp(int(scan_policy_on_nessus['last_modification_date']))})

default_filter = '[].{' \
'id: id, ' \
'name: name, ' \
'owner: owner, ' \
'creation_date: creation_date, ' \
'last_modification_date: last_modification_date}'

if filter:
expression = jmespath.compile(filter)
else:
expression = jmespath.compile(default_filter)

scan_policies_on_nessus = expression.search(scan_policies_on_nessus)

if scan_policies_on_nessus is not None:
if format == 'table':
print(dataframe_table(scan_policies_on_nessus))
elif format == 'csv':
print(dataframe_table(scan_policies_on_nessus).to_csv(index=False), '\n')
else:
print(scan_policies_on_nessus)
else:
Expand All @@ -281,7 +315,7 @@ def policy(address, port, username, password, insecure, format, list, verbose):
@add_options(_general_options)
@click.option('--list', is_flag=True,
help="Get scan list")
def scan(address, port, username, password, insecure, format, list, verbose):
def scan(address, port, username, password, insecure, format, filter, list, verbose):
"""get Nessus scan info"""

for one_address in address:
Expand All @@ -301,16 +335,32 @@ def scan(address, port, username, password, insecure, format, list, verbose):
if list:
print(one_address)
scans_on_nessus = tnscon.scans_get()
scans_on_nessus = [{
'folder_id': k['folder_id'],
'id': k['id'],
'name': k['name'],
'owner': k['owner'],
'creation_date': datetime.datetime.fromtimestamp(int(k['creation_date'])),
'last_modification_date': datetime.datetime.fromtimestamp(int(k['last_modification_date'])),
} for k in scans_on_nessus]

for scan_on_nessus in scans_on_nessus:
if 'creation_date' in scan_on_nessus:
scan_on_nessus.update({'creation_date': datetime.datetime.fromtimestamp(int(scan_on_nessus['creation_date']))})
if 'last_modification_date' in scan_on_nessus:
scan_on_nessus.update({'last_modification_date': datetime.datetime.fromtimestamp(int(scan_on_nessus['last_modification_date']))})

default_filter = '[].{' \
'folder_id: folder_id, ' \
'id: id, ' \
'name: name, ' \
'owner: owner, ' \
'creation_date: creation_date, ' \
'last_modification_date: last_modification_date}'

if filter:
expression = jmespath.compile(filter)
else:
expression = jmespath.compile(default_filter)

scans_on_nessus = expression.search(scans_on_nessus)

if format == 'table':
print(dataframe_table(scans_on_nessus))
elif format == 'csv':
print(dataframe_table(scans_on_nessus).to_csv(index=False), '\n')
else:
print(scans_on_nessus)

Expand All @@ -325,7 +375,7 @@ def scan(address, port, username, password, insecure, format, list, verbose):
@add_options(_general_options)
@click.option('--family-list', is_flag=True,
help="Get plugins familieslist")
def plugin(address, port, username, password, insecure, format, family_list, verbose):
def plugin(address, port, username, password, insecure, format, filter, family_list, verbose):
"""get Nessus plugin info"""

for one_address in address:
Expand All @@ -345,13 +395,23 @@ def plugin(address, port, username, password, insecure, format, family_list, ver
if family_list:
print(one_address)
plugins_families_on_nessus = tnscon.plugins_families_get()
plugins_families_on_nessus = [{
'id': k['id'],
'name': k['name'],
'count': k['count'],
} for k in plugins_families_on_nessus]

default_filter = '[].{' \
'id: id, ' \
'name: name, ' \
'count: count}'

if filter:
expression = jmespath.compile(filter)
else:
expression = jmespath.compile(default_filter)

plugins_families_on_nessus = expression.search(plugins_families_on_nessus)

if format == 'table':
print(dataframe_table(plugins_families_on_nessus, sortby='id'))
print(dataframe_table(plugins_families_on_nessus))
elif format == 'csv':
print(dataframe_table(plugins_families_on_nessus).to_csv(index=False), '\n')
else:
print(plugins_families_on_nessus)

Expand Down
2 changes: 1 addition & 1 deletion tnscm/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.0.2"
__version__ = "0.0.3"

0 comments on commit 09dee5d

Please sign in to comment.