def test_get_artifacts_by_tags(): db_path = Path("tests","data","kb_art_tags.db") conn = db.create_connection(db_path) db.create_kb_database(db_path) db.insert_artifact(conn, path="cheatsheet/pentest_smb", title="pentest_smb", category="procedure", tags=['pt','smb'], status="ok", author="gnc") db.insert_artifact(conn, path="guides/ftp", title="ftp", category="cheatsheet", tags=[], status="draft", author="elektroniz") db.insert_artifact(conn, path="guides/http", title="http", category="cheatsheet", status="OK", author="elektroniz") db.insert_artifact(conn, path="guides/irc", title="irc", category="cheatsheet", tags=["protocol"], status="draft", author="elektroniz") db.insert_artifact(conn, path="cheatsheet/pentest_ftp", title="pentest_ftp", category="cheatsheet", tags=["pt"], status="draft", author="elektroniz") rows = db.get_artifacts_by_tags(conn, tags=["pt"], is_strict=False) assert len(rows) == 2 rows = db.get_artifacts_by_tags(conn, tags=["p"], is_strict=False) assert len(rows) == 3 rows = db.get_artifacts_by_tags(conn, tags=["pt"], is_strict=True) assert len(rows) == 2 db_path.unlink()
def add_file_to_kb(conn, args: Dict[str, str], config: Dict[str, str], fname: str) -> None: """ Adds a file to the kb knowledge base. Arguments: conn - the connection to the database object args - the args dictionary passed to the add command, it must contain at least the following keys: title, category, tags, status, author config - the configuration dictionary that must contain at least the following key: PATH_KB_DATA, the path to where artifact are stored """ title = args["title"] or fs.get_basename(fname) category = args["category"] or "default" category_path = Path(config["PATH_KB_DATA"], category) category_path.mkdir(parents=True, exist_ok=True) fs.copy_file(fname, Path(category_path, title)) if not db.is_artifact_existing(conn, title, category): fs.copy_file(fname, Path(category_path, title)) new_artifact = Artifact(id=None, title=title, category=category, path=str(Path(category, title)), tags=args["tags"], status=args["status"], author=args["author"]) db.insert_artifact(conn, new_artifact)
def test_is_artifact_existing(): db_path = Path("tests", "data", "newdb.db") db.create_kb_database(db_path) conn = db.create_connection(db_path) db.insert_artifact( conn, Artifact(id=None, path="pentest/smb", title="pentest_smb", category="procedure", tags='pt;smb', status="OK", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="protocol/ftp", title="ftp", category="cheatsheet", status="Draft", author="elektroniz")) assert db.is_artifact_existing(conn, title="pentest_smb", category="procedure") assert db.is_artifact_existing(conn, title="ftp", category="cheatsheet") assert not db.is_artifact_existing( conn, title="pentest_smb", category="nonexist") assert not db.is_artifact_existing( conn, title="nonexist", category="procedure") assert not db.is_artifact_existing(conn, title="", category="cheatsheet") assert not db.is_artifact_existing(conn, title="", category="") db_path.unlink()
def test_delete_artifact_by_name(): db_path = Path("tests","data","newdb.db") db.create_kb_database(db_path) conn = db.create_connection(db_path) db.insert_artifact(conn, path="pentest/smb", title="pentest_smb", category="procedure", tags=['pt','smb'], status="OK", author="gnc") db.insert_artifact(conn, path="protocol/ftp", title="ftp", category="cheatsheet", tags=[], status="Draft", author="elektroniz") db.delete_artifact_by_name(conn, title="pentest_smb", category="") sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() assert len(rows) == 2 db.delete_artifact_by_name(conn, title="pentest_smb", category="procedure") sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() assert len(rows) == 1 assert set(rows) == {(2, 'ftp', 'cheatsheet', 'protocol/ftp', '', 'Draft', 'elektroniz')} db_path.unlink()
def add(args: Dict[str, str], config: Dict[str, str]): """ Adds a list of artifacts to the knowledge base of kb. Arguments: args: - a dictionary containing the following fields: file -> a list of files to add to kb title -> the title assigned to the artifact(s) category -> the category assigned to the artifact(s) tags -> the tags assigned to the artifact(s) author -> the author to assign to the artifact status -> the status to assign to the artifact config: - a configuration dictionary containing at least the following keys: PATH_KB_DB - the database path of KB PATH_KB_DATA - the data directory of KB EDITOR - the editor program to call """ # Check if the add command has proper arguments/options is_valid_add = args["file"] or args["title"] if not is_valid_add: print("Please, either specify a file or a title for the new artifact") sys.exit(1) # Check initialization initializer.init(config) conn = db.create_connection(config["PATH_KB_DB"]) if args["file"]: for fname in args["file"]: if fs.is_directory(fname): continue add_file_to_kb(conn, args, config, fname) else: # Get title for the new artifact title = args["title"] # Assign a "default" category if not provided category = args["category"] or "default" # Create "category" directory if it does not exist category_path = Path(config["PATH_KB_DATA"], category) category_path.mkdir(parents=True, exist_ok=True) if not db.is_artifact_existing(conn, title, category): # If a file is provided, copy the file to kb directory # otherwise open up the editor and create some content shell_cmd = shlex.split( config["EDITOR"]) + [str(Path(category_path, title))] call(shell_cmd) new_artifact = Artifact(id=None, title=title, category=category, path="{category}/{title}".format( category=category, title=title), tags=args["tags"], status=args["status"], author=args["author"]) db.insert_artifact(conn, new_artifact)
def test_get_artifacts_by_tags(): db_path = Path("tests", "data", "kb_art_tags.db") conn = db.create_connection(str(db_path)) with conn: schema_version = 1 db.create_kb_database(str(db_path), schema_version) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_smb", title="pentest_smb", category="procedure", tags='pt;smb', status="ok", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="guides/ftp", title="ftp", category="cheatsheet", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/http", title="http", category="cheatsheet", status="OK", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/irc", title="irc", category="cheatsheet", tags="protocol", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_ftp", title="pentest_ftp", category="cheatsheet", tags="pt", status="draft", author="elektroniz")) rows = db.get_artifacts_by_tags(conn, tags=["pt"], is_strict=False) assert len(rows) == 2 rows = db.get_artifacts_by_tags(conn, tags=["p"], is_strict=False) assert len(rows) == 3 rows = db.get_artifacts_by_tags(conn, tags=["pt"], is_strict=True) assert len(rows) == 2
def test_get_artifacts_by_title(): db_path = Path("tests", "data", "kb_filter_title.db") conn = db.create_connection(db_path) db.create_kb_database(db_path) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_smb", title="pentest_smb", category="procedure", tags='pt;smb', status="ok", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="guides/ftp", title="ftp", category="cheatsheet", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/http", title="http", category="cheatsheet", status="OK", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/irc", title="irc", category="cheatsheet", tags="protocol", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_ftp", title="pentest_ftp", category="cheatsheet", tags="pt", status="draft", author="elektroniz")) rows = db.get_artifacts_by_title(conn, query_string="", is_strict=False) assert len(rows) == 5 rows = db.get_artifacts_by_title(conn, query_string="", is_strict=True) assert len(rows) == 0 db_path.unlink()
def test_get_artifacts_by_filter(): db_path = Path("tests","data","kb_filter.db") conn = db.create_connection(db_path) db.create_kb_database(db_path) db.insert_artifact(conn, path="", title="pentest_smb", category="procedure", tags=['pt','smb'], status="ok", author="gnc") db.insert_artifact(conn, path="", title="ftp", category="cheatsheet", tags=["protocol"], status="draft", author="elektroniz") db.insert_artifact(conn, path="", title="pentest_ftp", category="procedure", tags=["pt","ftp"], status="draft", author="elektroniz") db.insert_artifact(conn, path="general/CORS", title="CORS", category="general", tags=["web"], status="draft", author="elektroniz") rows = db.get_artifacts_by_filter(conn, title="pentest", category="cheatsheet", tags=["pt"], is_strict=False) assert len(rows) == 0 rows = db.get_artifacts_by_filter(conn, category="procedure", tags=["pt"], is_strict=False) print(rows) assert set(rows) == {(1,"pentest_smb","procedure","","pt;smb","ok","gnc"), (3,"pentest_ftp","procedure","","pt;ftp","draft", "elektroniz")} rows = db.get_artifacts_by_filter(conn, title="OR") assert set(rows) == {(4,"CORS","general","general/CORS","web", "draft","elektroniz")} rows = db.get_artifacts_by_filter(conn, category="cheatsheet", is_strict=False) assert set(rows) == {(2,"ftp","cheatsheet","","protocol", "draft", "elektroniz")} rows = db.get_artifacts_by_filter(conn, category="sheet", is_strict=False) assert set(rows) == {(2,"ftp","cheatsheet","","protocol", "draft", "elektroniz")} rows = db.get_artifacts_by_filter(conn, category="cheatsheet", is_strict=True) assert set(rows) == {(2,"ftp","cheatsheet","","protocol", "draft", "elektroniz")} rows = db.get_artifacts_by_filter(conn, category="sheet", is_strict=True) assert len(rows) == 0 db_path.unlink()
def test_delete_artifact_by_name(): db_path = Path("tests", "data", "test_name.db") schema_version = 1 db.create_kb_database(str(db_path), schema_version) conn = db.create_connection(str(db_path)) with conn: db.insert_artifact( conn, Artifact(id=None, path="pentest/smb", title="pentest_smb", category="procedure", tags='pt;smb', status="OK", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="protocol/ftp", title="ftp", category="cheatsheet", status="Draft", author="elektroniz")) db.delete_artifact_by_name(conn, title="pentest_smb", category="") sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() assert len(rows) == 2 db.delete_artifact_by_name(conn, title="pentest_smb", category="procedure") sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() assert len(rows) == 1 assert set(rows) == {(2, 'ftp', 'cheatsheet', 'protocol/ftp', None, 'Draft', 'elektroniz', None)}
def add_file_to_kb( conn, args: Dict[str, str], config: Dict[str, str], fname: str ) -> None: """ Adds a file to the kb knowledge base. Arguments: conn - the connection to the database object args - the args dictionary passed to the add command, it must contain at least the following keys: title, category, tags, status, author config - the configuration dictionary that must contain at least the following key: PATH_KB_DATA, the path to where artifact are stored fname - the path of the file to add to kb """ title = args["title"] or fs.get_basename(fname) category = args["category"] or "default" template = args["template"] or "default" category_path = Path(config["PATH_KB_DATA"], category) category_path.mkdir(parents=True, exist_ok=True) try: fs.copy_file(fname, Path(category_path, title)) except FileNotFoundError: print("Error: The specified file does not exist!".format(fname=fname)) sys.exit(1) if not db.is_artifact_existing(conn, title, category): fs.copy_file(fname, Path(category_path, title)) new_artifact = Artifact( id=None, title=title, category=category, path="{category}/{title}".format(category=category, title=title), tags=args["tags"], status=args["status"], author=args["author"], template=template) db.insert_artifact(conn, new_artifact)
def test_insert_artifact(): db_path = Path("tests", "data", "test_insert.db") schema_version = 1 db.create_kb_database(str(db_path), schema_version) conn = db.create_connection(str(db_path)) with conn: db.insert_artifact( conn, Artifact(id=None, path="pentest/smb", title="pentest_smb", category="procedure", tags='pt;smb', status="OK", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="protocol/ftp", title="ftp", category="cheatsheet", status="Draft", author="elektroniz")) kb_tables = _list_tables(conn) assert len(kb_tables) == 2 assert kb_tables == [("artifacts", ), ("tags", )] sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() print(rows) assert set(rows) == {(1, 'pentest_smb', 'procedure', 'pentest/smb', 'pt;smb', 'OK', 'gnc', None), (2, 'ftp', 'cheatsheet', 'protocol/ftp', None, 'Draft', 'elektroniz', None)}
def test_insert_artifact(): db_path = Path("tests","data","newdb.db") db.create_kb_database(db_path) conn = db.create_connection(db_path) db.insert_artifact(conn, path="pentest/smb", title="pentest_smb", category="procedure", tags=['pt','smb'], status="OK", author="gnc") db.insert_artifact(conn, path="protocol/ftp", title="ftp", category="cheatsheet", tags=[], status="Draft", author="elektroniz") kb_tables = _list_tables(conn) assert len(kb_tables) == 2 assert kb_tables == [("artifacts",),("tags",)] sql = "SELECT * FROM artifacts;" cur = conn.cursor() cur.execute(sql) rows = cur.fetchall() assert set(rows) == {(1, 'pentest_smb', 'procedure', 'pentest/smb', 'pt;smb', 'OK', 'gnc'), (2, 'ftp', 'cheatsheet', 'protocol/ftp', '', 'Draft', 'elektroniz')} db_path.unlink()
def test_get_artifacts_by_category(): db_path = Path("tests","data","kb_filter_cat.db") conn = db.create_connection(db_path) db.create_kb_database(db_path) db.insert_artifact(conn, path="cheatsheet/pentest_smb", title="pentest_smb", category="procedure", tags=['pt','smb'], status="ok", author="gnc") db.insert_artifact(conn, path="guides/ftp", title="ftp", category="cheatsheet", tags=[], status="draft", author="elektroniz") db.insert_artifact(conn, path="guides/http", title="http", category="cheatsheet", status="OK", author="elektroniz") db.insert_artifact(conn, path="guides/irc", title="irc", category="cheatsheet", tags=["protocol"], status="draft", author="elektroniz") db.insert_artifact(conn, path="cheatsheet/pentest_ftp", title="pentest_ftp", category="cheatsheet", tags=["pt"], status="draft", author="elektroniz") db.insert_artifact(conn, path="sheet/math", title="math_formulas", category="sheet", tags=["math"], status="draft", author="gnc") db.insert_artifact(conn, path="sheet/math2", title="geometry_formulas", category="sheet", tags=["math"], status="draft", author="gnc") rows = db.get_artifacts_by_category(conn, query_string="", is_strict=False) assert len(rows) == 7 rows = db.get_artifacts_by_category(conn, query_string="", is_strict=True) assert len(rows) == 0 rows = db.get_artifacts_by_category(conn, query_string="sheet", is_strict=True) assert len(rows) == 2 db_path.unlink()
def test_get_artifacts_by_filter(): db_path = Path("tests", "data", "kb_filter.db") conn = db.create_connection(str(db_path)) with conn: schema_version = 1 db.create_kb_database(str(db_path), schema_version) db.insert_artifact( conn, Artifact(id=None, path="", title="pentest_smb", category="procedure", tags='pt;smb', status="ok", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="", title="ftp", category="cheatsheet", tags="protocol", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="", title="pentest_ftp", category="procedure", tags="pt;ftp", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="general/CORS", title="CORS", category="general", tags="web", status="draft", author="elektroniz")) rows = db.get_artifacts_by_filter(conn, title="pentest", category="cheatsheet", tags=["pt"], is_strict=False) assert len(rows) == 0 rows = db.get_artifacts_by_filter(conn, category="procedure", tags=["pt"], is_strict=False) assert sorted(list(set(rows)), key=lambda i: i.id) == [ Artifact(1, "pentest_smb", "procedure", "procedure/pentest_smb", "pt;smb", "ok", "gnc", None), Artifact(3, "pentest_ftp", "procedure", "procedure/pentest_ftp", "pt;ftp", "draft", "elektroniz", None) ] rows = db.get_artifacts_by_filter(conn, title="OR") assert set(rows) == { Artifact(4, "CORS", "general", "general/CORS", "web", "draft", "elektroniz", None) } rows = db.get_artifacts_by_filter(conn, category="cheatsheet", is_strict=False) assert set(rows) == { Artifact(2, "ftp", "cheatsheet", "cheatsheet/ftp", "protocol", "draft", "elektroniz", None) } rows = db.get_artifacts_by_filter(conn, category="sheet", is_strict=False) assert set(rows) == { Artifact(2, "ftp", "cheatsheet", "cheatsheet/ftp", "protocol", "draft", "elektroniz", None) } rows = db.get_artifacts_by_filter(conn, category="cheatsheet", is_strict=True) assert set(rows) == { Artifact(2, "ftp", "cheatsheet", "cheatsheet/ftp", "protocol", "draft", "elektroniz", None) } rows = db.get_artifacts_by_filter(conn, category="sheet", is_strict=True) assert len(rows) == 0
def test_get_artifacts_by_category(): db_path = Path("tests", "data", "kb_filter_cat.db") conn = db.create_connection(str(db_path)) with conn: schema_version = 1 db.create_kb_database(str(db_path), schema_version) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_smb", title="pentest_smb", category="procedure", tags='pt;smb', status="ok", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="guides/ftp", title="ftp", category="cheatsheet", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/http", title="http", category="cheatsheet", status="OK", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="guides/irc", title="irc", category="cheatsheet", tags="protocol", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="cheatsheet/pentest_ftp", title="pentest_ftp", category="cheatsheet", tags="pt", status="draft", author="elektroniz")) db.insert_artifact( conn, Artifact(id=None, path="sheet/math", title="math_formulas", category="sheet", tags="math", status="draft", author="gnc")) db.insert_artifact( conn, Artifact(id=None, path="sheet/math2", title="geometry_formulas", category="sheet", tags="math", status="draft", author="gnc")) rows = db.get_artifacts_by_category(conn, query_string="", is_strict=False) assert len(rows) == 7 rows = db.get_artifacts_by_category(conn, query_string="", is_strict=True) assert len(rows) == 0 rows = db.get_artifacts_by_category(conn, query_string="sheet", is_strict=True) assert len(rows) == 2