diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.exe" "b/eicar/\074img src=x onError=alert\0501\051\076.exe" new file mode 100644 index 0000000..9daeafb --- /dev/null +++ "b/eicar/\074img src=x onError=alert\0501\051\076.exe" @@ -0,0 +1 @@ +test diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.exe" "b/eicar/\074img src=x onError=alert\0501\051\076.exe" new file mode 100644 index 0000000..9daeafb --- /dev/null +++ "b/eicar/\074img src=x onError=alert\0501\051\076.exe" @@ -0,0 +1 @@ +test diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" "b/eicar/\074img src=x onError=alert\0501\051\076.jpg" deleted file mode 100644 index 9daeafb..0000000 --- "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.exe" "b/eicar/\074img src=x onError=alert\0501\051\076.exe" new file mode 100644 index 0000000..9daeafb --- /dev/null +++ "b/eicar/\074img src=x onError=alert\0501\051\076.exe" @@ -0,0 +1 @@ +test diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" "b/eicar/\074img src=x onError=alert\0501\051\076.jpg" deleted file mode 100644 index 9daeafb..0000000 --- "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/htb2trilium.py b/htb2trilium.py deleted file mode 100644 index ac579ca..0000000 --- a/htb2trilium.py +++ /dev/null @@ -1,214 +0,0 @@ -''' -######################## -# SETUP -######################## - > pip3 install trilium-py - > pip3 install pyhackthebox - - - get trilium token in trilium options->ETAPI and "create new token" - - get trilium_htb_folder click on note to become folder -> "note info". Note ID is there. - - set the folder's owned attributes to: - #label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0 - - - create a note named "HTBMachineTemplate" and set it's "owned attributes" to: - #template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text - - - get this page's ID and put in "trilium_template_id" - - to get "in progress" todo colour - add to taskmanager/implementation/CSS: - - span.fancytree-node.inprogress .fancytree-title { - color: orange !important; - } -''' - -######################## -# IGNORE THESE -######################## - -import requests -from bs4 import BeautifulSoup -from datetime import timezone -from hackthebox import HTBClient -from trilium_py.client import ETAPI - -######################## -# EDIT BELOW HERE -######################## - -htb_email = '' -htb_pass = '' -trilium_server_url = '' -trilium_token = '' -trilium_htb_folder = '' -trilium_template_id = '' - -######################## -# LEAVE BELOW HERE -######################## - -def generate_newpage(machine): - no = "No" - yes = "Yes" - user_colour = no - if machine.user_owned: - user_colour = yes - root_colour = no - if machine.root_owned: - root_colour = yes - - status = "Active" - if machine.retired: - status = "Retired" - - html = """ -
- -
-

- OS: {os}
- Difficulty: {difficulty}
- Rating: {rating} / 5
- Points: {points}
- User / Root: {user_colour} / {root_colour}
- Released: {release_date}
- State: {status} -

-
-

Notes

-

 

- """.format( - os=machine.os, - difficulty=machine.difficulty, - rating=machine.stars, - points=machine.points, - release_date=machine.release_date.strftime("%d %B %Y"), - user_colour=user_colour, - root_colour=root_colour, - status = status, - avatar = machine.avatar, - ) - - return html - -def get_timestamp(machine): - dt = machine.release_date - timestamp = dt.replace(tzinfo=timezone.utc).timestamp() - return timestamp - -print("[+] connecting to HTB") -client = HTBClient(email=htb_email, password=htb_pass) -print("[+] connecting to trilium") -ea = ETAPI(trilium_server_url, trilium_token) - -print("[i] HTB User:",client.user.id, "-", client.user.name) -print("[i] user owns:", client.user.user_owns, "| Root owns:", client.user.root_owns, "| Respect:", client.user.respects) - -master_folder = ea.get_note(trilium_htb_folder) -for attribute in master_folder['attributes']: - if attribute['name'] == "user": - if attribute['value'] != str(client.user.user_owns): - print("[+] updating user owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.user_owns)) - if attribute['name'] == "root": - if attribute['value'] != str(client.user.root_owns): - print("[+] updating root owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.root_owns)) - if attribute['name'] == "respect": - if attribute['value'] != str(client.user.respects): - print("[+] updating respect (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.respects)) - -print("[+] gathering machines info") - -machines = client.get_machines() -machines += client.get_machines(None, True) -machines.sort(key=get_timestamp) -# starts with oldest, ends with newest... - -machine_count = 0 -completed_count = 0 -for machine in machines: - machine_count += 1 - print('processing: ',machine_count, "/", len(machines), "("+machine.name+") " , end='\r') - - res = ea.search_note( - search="\""+machine.name+"\"", - ancestorNoteId=trilium_htb_folder, - ancestorDepth='eq1', - limit=1, - fastSearch=True, - ) - - if res['results'] and machine.name == res['results'][0]['title']: - # page exists - lets check if the details have changed - - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - current_paragraph = current_soup.find_all('p')[0].text - - new_html = generate_newpage(machine) - new_soup = BeautifulSoup(new_html, 'html.parser') - new_paragraph = new_soup.find_all('p')[0].text - - # current page contains first paragraph of "blank" (useful for when it doesnt create or find the note properly.. shouldnt get here) - if current_paragraph == "blank": - ea.update_note_content(noteId=res['results'][0]['noteId'], content=new_html) - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="todo") - # re-get the current content - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - - if current_paragraph != new_paragraph: - - # details have updated! - print("[+] updating page:",machine.name, "-> "+res['results'][0]['title']+" ") - replacement = current_soup.find('p') - replacement.replace_with( new_soup.find_all('p')[0] ) - ea.update_note_content(noteId=res['results'][0]['noteId'], content=current_soup) - - # now to update the label - for attribute in res['results'][0]['attributes']: - if attribute['name'] == "cssClass": - if machine.user_owned and machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="done") - else: - if machine.user_owned or machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="inprogress") - else: - ea.patch_attribute(attributeId=attribute['attributeId'], value="todo") - - else: - # title does not exist - create the note - html = generate_newpage(machine) - new_note = ea.create_note( - parentNoteId=trilium_htb_folder, - type="text", - title=machine.name, - content=html, - ) - print("[+] created note:", machine.name, " ") - - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="todo") - - if machine.user_owned and machine.root_owned: - completed_count += 1 - -print("[+] updating folder name ") -ea.patch_note(noteId=trilium_htb_folder,title="Machines - "+str(completed_count)+" / "+str(len(machines))) - -print("[=] processed", machine_count) - diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.exe" "b/eicar/\074img src=x onError=alert\0501\051\076.exe" new file mode 100644 index 0000000..9daeafb --- /dev/null +++ "b/eicar/\074img src=x onError=alert\0501\051\076.exe" @@ -0,0 +1 @@ +test diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" "b/eicar/\074img src=x onError=alert\0501\051\076.jpg" deleted file mode 100644 index 9daeafb..0000000 --- "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/htb2trilium.py b/htb2trilium.py deleted file mode 100644 index ac579ca..0000000 --- a/htb2trilium.py +++ /dev/null @@ -1,214 +0,0 @@ -''' -######################## -# SETUP -######################## - > pip3 install trilium-py - > pip3 install pyhackthebox - - - get trilium token in trilium options->ETAPI and "create new token" - - get trilium_htb_folder click on note to become folder -> "note info". Note ID is there. - - set the folder's owned attributes to: - #label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0 - - - create a note named "HTBMachineTemplate" and set it's "owned attributes" to: - #template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text - - - get this page's ID and put in "trilium_template_id" - - to get "in progress" todo colour - add to taskmanager/implementation/CSS: - - span.fancytree-node.inprogress .fancytree-title { - color: orange !important; - } -''' - -######################## -# IGNORE THESE -######################## - -import requests -from bs4 import BeautifulSoup -from datetime import timezone -from hackthebox import HTBClient -from trilium_py.client import ETAPI - -######################## -# EDIT BELOW HERE -######################## - -htb_email = '' -htb_pass = '' -trilium_server_url = '' -trilium_token = '' -trilium_htb_folder = '' -trilium_template_id = '' - -######################## -# LEAVE BELOW HERE -######################## - -def generate_newpage(machine): - no = "No" - yes = "Yes" - user_colour = no - if machine.user_owned: - user_colour = yes - root_colour = no - if machine.root_owned: - root_colour = yes - - status = "Active" - if machine.retired: - status = "Retired" - - html = """ -
- -
-

- OS: {os}
- Difficulty: {difficulty}
- Rating: {rating} / 5
- Points: {points}
- User / Root: {user_colour} / {root_colour}
- Released: {release_date}
- State: {status} -

-
-

Notes

-

 

- """.format( - os=machine.os, - difficulty=machine.difficulty, - rating=machine.stars, - points=machine.points, - release_date=machine.release_date.strftime("%d %B %Y"), - user_colour=user_colour, - root_colour=root_colour, - status = status, - avatar = machine.avatar, - ) - - return html - -def get_timestamp(machine): - dt = machine.release_date - timestamp = dt.replace(tzinfo=timezone.utc).timestamp() - return timestamp - -print("[+] connecting to HTB") -client = HTBClient(email=htb_email, password=htb_pass) -print("[+] connecting to trilium") -ea = ETAPI(trilium_server_url, trilium_token) - -print("[i] HTB User:",client.user.id, "-", client.user.name) -print("[i] user owns:", client.user.user_owns, "| Root owns:", client.user.root_owns, "| Respect:", client.user.respects) - -master_folder = ea.get_note(trilium_htb_folder) -for attribute in master_folder['attributes']: - if attribute['name'] == "user": - if attribute['value'] != str(client.user.user_owns): - print("[+] updating user owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.user_owns)) - if attribute['name'] == "root": - if attribute['value'] != str(client.user.root_owns): - print("[+] updating root owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.root_owns)) - if attribute['name'] == "respect": - if attribute['value'] != str(client.user.respects): - print("[+] updating respect (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.respects)) - -print("[+] gathering machines info") - -machines = client.get_machines() -machines += client.get_machines(None, True) -machines.sort(key=get_timestamp) -# starts with oldest, ends with newest... - -machine_count = 0 -completed_count = 0 -for machine in machines: - machine_count += 1 - print('processing: ',machine_count, "/", len(machines), "("+machine.name+") " , end='\r') - - res = ea.search_note( - search="\""+machine.name+"\"", - ancestorNoteId=trilium_htb_folder, - ancestorDepth='eq1', - limit=1, - fastSearch=True, - ) - - if res['results'] and machine.name == res['results'][0]['title']: - # page exists - lets check if the details have changed - - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - current_paragraph = current_soup.find_all('p')[0].text - - new_html = generate_newpage(machine) - new_soup = BeautifulSoup(new_html, 'html.parser') - new_paragraph = new_soup.find_all('p')[0].text - - # current page contains first paragraph of "blank" (useful for when it doesnt create or find the note properly.. shouldnt get here) - if current_paragraph == "blank": - ea.update_note_content(noteId=res['results'][0]['noteId'], content=new_html) - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="todo") - # re-get the current content - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - - if current_paragraph != new_paragraph: - - # details have updated! - print("[+] updating page:",machine.name, "-> "+res['results'][0]['title']+" ") - replacement = current_soup.find('p') - replacement.replace_with( new_soup.find_all('p')[0] ) - ea.update_note_content(noteId=res['results'][0]['noteId'], content=current_soup) - - # now to update the label - for attribute in res['results'][0]['attributes']: - if attribute['name'] == "cssClass": - if machine.user_owned and machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="done") - else: - if machine.user_owned or machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="inprogress") - else: - ea.patch_attribute(attributeId=attribute['attributeId'], value="todo") - - else: - # title does not exist - create the note - html = generate_newpage(machine) - new_note = ea.create_note( - parentNoteId=trilium_htb_folder, - type="text", - title=machine.name, - content=html, - ) - print("[+] created note:", machine.name, " ") - - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="todo") - - if machine.user_owned and machine.root_owned: - completed_count += 1 - -print("[+] updating folder name ") -ea.patch_note(noteId=trilium_htb_folder,title="Machines - "+str(completed_count)+" / "+str(len(machines))) - -print("[=] processed", machine_count) - diff --git a/htb2trilium2.py b/htb2trilium2.py new file mode 100644 index 0000000..c831574 --- /dev/null +++ b/htb2trilium2.py @@ -0,0 +1,224 @@ +''' +######################## +# SETUP +######################## + > pip3 install trilium-py + + - get trilium token in trilium options->ETAPI and "create new token" + - get trilium_htb_folder click on note to become folder -> "note info". Note ID is there. + - set the folder's owned attributes to: + #label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0 + + - create a note named "HTBMachineTemplate" and set it's "owned attributes" to: + #template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text + + - get this page's ID and put in "trilium_template_id" + - to get "in progress" todo colour - add to trilium demo/scripting/taskmanager/implementation/CSS: + + span.fancytree-node.inprogress .fancytree-title { + color: orange !important; + } +''' + +######################## +# IGNORE THESE +######################## + +import requests +from bs4 import BeautifulSoup +from datetime import datetime, timezone +from htb_client import HTBClient +from trilium_py.client import ETAPI + +######################## +# EDIT BELOW HERE +######################## + +htb_code = '' +trilium_server_url = 'https://notes.place.com' +trilium_token = '' +trilium_htb_folder = '' +trilium_template_id = '' + +######################## +# LEAVE BELOW HERE +######################## + +def generate_newpage(machine): + no = "No" + yes = "Yes" + user_colour = no + if machine['authUserInUserOwns']: + user_colour = yes + root_colour = no + if machine['authUserInRootOwns']: + root_colour = yes + + status = "Retired" + if machine['active']: + status = "Active" + + release_str = machine['release'] + release_date = datetime.strptime(release_str, "%Y-%m-%dT%H:%M:%S.%fZ") + formatted_release_date = release_date.strftime("%d %B %Y") + + html = """ +
+ +
+

+ OS: {os}
+ Difficulty: {difficultyText}
+ Rating: {rating} / 5
+ Points: {points}
+ User / Root: {user_colour} / {root_colour}
+ Released: {release_date}
+ State: {status} +

+
+

Notes

+

 

+ """.format( + os=machine['os'], + difficultyText=machine['difficultyText'], + rating=machine['star'], + points=machine['points'], + release_date=formatted_release_date, + user_colour=user_colour, + root_colour=root_colour, + status = status, + avatar = machine['avatar'], + ) + + return html + +def get_timestamp(machine): + # Parse the release date string into a datetime object + release_str = machine['release'] + dt = datetime.strptime(release_str, "%Y-%m-%dT%H:%M:%S.%fZ") + + # Set the timezone to UTC + dt = dt.replace(tzinfo=timezone.utc) + + # Get the timestamp + timestamp = dt.timestamp() + return timestamp + +print("[+] connecting to HTB") +client = HTBClient(password=htb_code) +print("[+] connecting to trilium") +ea = ETAPI(trilium_server_url, trilium_token) +print("[i] version: ", ea.app_info()['appVersion']) + +print("[i] HTB User:", client.user['id'], "-", client.user['name']) +print("[i] user owns:", client.user['user_owns'], "| Root owns:", client.user['root_owns'], "| Respect:", client.user['respects']) + +master_folder = ea.get_note(trilium_htb_folder) +for attribute in master_folder['attributes']: + if attribute['name'] == "user": + if attribute['value'] != str(client.user['user_owns']): + print("[+] updating user owns (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['user_owns'])) + if attribute['name'] == "root": + if attribute['value'] != str(client.user['root_owns']): + print("[+] updating root owns (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['root_owns'])) + if attribute['name'] == "respect": + if attribute['value'] != str(client.user['respects']): + print("[+] updating respect (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['respects'])) + +print("[+] gathering machines info") +machines = client.get_all_machines() +machines.sort(key=get_timestamp) + +print(f"[i] Retrieved {len(machines)} machines") +#for machine in machines: +# print(f" - ID: {machine['id']}, Name: {machine['name']}, OS: {machine['os']}, Difficulty: {machine['difficultyText']}") + +machine_count = 0 +completed_count = 0 +for machine in machines: + machine_count += 1 + print('processing: ',machine_count, "/", len(machines), "("+machine['name']+") " , end='\r') + + res = ea.search_note( + search="\""+machine['name']+"\"", + ancestorNoteId=trilium_htb_folder, + ancestorDepth='eq1', + limit=1, + fastSearch=True, + ) + + if res['results'] and machine['name'] == res['results'][0]['title']: + # page exists - lets check if the details have changed + + current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) + current_soup = BeautifulSoup(current_html, 'html.parser') + current_paragraph = current_soup.find_all('p')[0].text + + new_html = generate_newpage(machine) + new_soup = BeautifulSoup(new_html, 'html.parser') + new_paragraph = new_soup.find_all('p')[0].text + + # current page contains first paragraph of "blank" (useful for when it doesnt create or find the note properly.. shouldnt get here) + if current_paragraph == "blank": + ea.update_note_content(noteId=res['results'][0]['noteId'], content=new_html) + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="relation", name="template", value=trilium_template_id) + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="inprogress") + else: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="todo") + # re-get the current content + current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) + current_soup = BeautifulSoup(current_html, 'html.parser') + + if current_paragraph != new_paragraph: + + # details have updated! + print("[+] updating page:",machine['name'], "-> "+res['results'][0]['title']+" ") + replacement = current_soup.find('p') + replacement.replace_with( new_soup.find_all('p')[0] ) + ea.update_note_content(noteId=res['results'][0]['noteId'], content=current_soup) + + # now to update the label + for attribute in res['results'][0]['attributes']: + if attribute['name'] == "cssClass": + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.patch_attribute(attributeId=attribute['attributeId'], value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.patch_attribute(attributeId=attribute['attributeId'], value="inprogress") + else: + ea.patch_attribute(attributeId=attribute['attributeId'], value="todo") + + else: + # title does not exist - create the note + html = generate_newpage(machine) + new_note = ea.create_note( + parentNoteId=trilium_htb_folder, + type="text", + title=machine['name'], + content=html, + ) + print("[+] created note:", machine['name'], " ") + + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="relation", name="template", value=trilium_template_id) + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="inprogress") + else: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="todo") + + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + completed_count += 1 + +print("[+] updating folder name ") +ea.patch_note(noteId=trilium_htb_folder,title="Machines - "+str(completed_count)+" / "+str(len(machines))) + +print("[=] processed", machine_count) \ No newline at end of file diff --git a/ReportToolz/config.php b/ReportToolz/config.php index 9f247d2..c787262 100644 --- a/ReportToolz/config.php +++ b/ReportToolz/config.php @@ -6,7 +6,8 @@ // repgen templates //$template = "/mnt/hgfs/PentestOS/Misc/repgen_test/test_04/blank_template_v2.1.odt"; -$template = "templates/odt/blank_template_v3.0.odt"; +$template = "/mnt/hgfs/PentestOS/Sapphire2/repgen_template/blank_template_v3.0.odt"; +//$template = "templates/odt/blank_template_v2.1.odt"; //$CHECKtemplate = "templates/odt/blank_template_check_v0.4.odt"; $vulnTemplate = "templates/odt/vuln_template_v1.0.xml"; diff --git a/__pycache__/htb_client.cpython-311.pyc b/__pycache__/htb_client.cpython-311.pyc new file mode 100644 index 0000000..008b47f --- /dev/null +++ b/__pycache__/htb_client.cpython-311.pyc Binary files differ diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.exe" "b/eicar/\074img src=x onError=alert\0501\051\076.exe" new file mode 100644 index 0000000..9daeafb --- /dev/null +++ "b/eicar/\074img src=x onError=alert\0501\051\076.exe" @@ -0,0 +1 @@ +test diff --git "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" "b/eicar/\074img src=x onError=alert\0501\051\076.jpg" deleted file mode 100644 index 9daeafb..0000000 --- "a/eicar/\074img src=x onError=alert\0501\051\076.jpg" +++ /dev/null @@ -1 +0,0 @@ -test diff --git a/htb2trilium.py b/htb2trilium.py deleted file mode 100644 index ac579ca..0000000 --- a/htb2trilium.py +++ /dev/null @@ -1,214 +0,0 @@ -''' -######################## -# SETUP -######################## - > pip3 install trilium-py - > pip3 install pyhackthebox - - - get trilium token in trilium options->ETAPI and "create new token" - - get trilium_htb_folder click on note to become folder -> "note info". Note ID is there. - - set the folder's owned attributes to: - #label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0 - - - create a note named "HTBMachineTemplate" and set it's "owned attributes" to: - #template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text - - - get this page's ID and put in "trilium_template_id" - - to get "in progress" todo colour - add to taskmanager/implementation/CSS: - - span.fancytree-node.inprogress .fancytree-title { - color: orange !important; - } -''' - -######################## -# IGNORE THESE -######################## - -import requests -from bs4 import BeautifulSoup -from datetime import timezone -from hackthebox import HTBClient -from trilium_py.client import ETAPI - -######################## -# EDIT BELOW HERE -######################## - -htb_email = '' -htb_pass = '' -trilium_server_url = '' -trilium_token = '' -trilium_htb_folder = '' -trilium_template_id = '' - -######################## -# LEAVE BELOW HERE -######################## - -def generate_newpage(machine): - no = "No" - yes = "Yes" - user_colour = no - if machine.user_owned: - user_colour = yes - root_colour = no - if machine.root_owned: - root_colour = yes - - status = "Active" - if machine.retired: - status = "Retired" - - html = """ -
- -
-

- OS: {os}
- Difficulty: {difficulty}
- Rating: {rating} / 5
- Points: {points}
- User / Root: {user_colour} / {root_colour}
- Released: {release_date}
- State: {status} -

-
-

Notes

-

 

- """.format( - os=machine.os, - difficulty=machine.difficulty, - rating=machine.stars, - points=machine.points, - release_date=machine.release_date.strftime("%d %B %Y"), - user_colour=user_colour, - root_colour=root_colour, - status = status, - avatar = machine.avatar, - ) - - return html - -def get_timestamp(machine): - dt = machine.release_date - timestamp = dt.replace(tzinfo=timezone.utc).timestamp() - return timestamp - -print("[+] connecting to HTB") -client = HTBClient(email=htb_email, password=htb_pass) -print("[+] connecting to trilium") -ea = ETAPI(trilium_server_url, trilium_token) - -print("[i] HTB User:",client.user.id, "-", client.user.name) -print("[i] user owns:", client.user.user_owns, "| Root owns:", client.user.root_owns, "| Respect:", client.user.respects) - -master_folder = ea.get_note(trilium_htb_folder) -for attribute in master_folder['attributes']: - if attribute['name'] == "user": - if attribute['value'] != str(client.user.user_owns): - print("[+] updating user owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.user_owns)) - if attribute['name'] == "root": - if attribute['value'] != str(client.user.root_owns): - print("[+] updating root owns (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.root_owns)) - if attribute['name'] == "respect": - if attribute['value'] != str(client.user.respects): - print("[+] updating respect (folder attribute)") - ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user.respects)) - -print("[+] gathering machines info") - -machines = client.get_machines() -machines += client.get_machines(None, True) -machines.sort(key=get_timestamp) -# starts with oldest, ends with newest... - -machine_count = 0 -completed_count = 0 -for machine in machines: - machine_count += 1 - print('processing: ',machine_count, "/", len(machines), "("+machine.name+") " , end='\r') - - res = ea.search_note( - search="\""+machine.name+"\"", - ancestorNoteId=trilium_htb_folder, - ancestorDepth='eq1', - limit=1, - fastSearch=True, - ) - - if res['results'] and machine.name == res['results'][0]['title']: - # page exists - lets check if the details have changed - - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - current_paragraph = current_soup.find_all('p')[0].text - - new_html = generate_newpage(machine) - new_soup = BeautifulSoup(new_html, 'html.parser') - new_paragraph = new_soup.find_all('p')[0].text - - # current page contains first paragraph of "blank" (useful for when it doesnt create or find the note properly.. shouldnt get here) - if current_paragraph == "blank": - ea.update_note_content(noteId=res['results'][0]['noteId'], content=new_html) - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="todo") - # re-get the current content - current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) - current_soup = BeautifulSoup(current_html, 'html.parser') - - if current_paragraph != new_paragraph: - - # details have updated! - print("[+] updating page:",machine.name, "-> "+res['results'][0]['title']+" ") - replacement = current_soup.find('p') - replacement.replace_with( new_soup.find_all('p')[0] ) - ea.update_note_content(noteId=res['results'][0]['noteId'], content=current_soup) - - # now to update the label - for attribute in res['results'][0]['attributes']: - if attribute['name'] == "cssClass": - if machine.user_owned and machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="done") - else: - if machine.user_owned or machine.root_owned: - ea.patch_attribute(attributeId=attribute['attributeId'], value="inprogress") - else: - ea.patch_attribute(attributeId=attribute['attributeId'], value="todo") - - else: - # title does not exist - create the note - html = generate_newpage(machine) - new_note = ea.create_note( - parentNoteId=trilium_htb_folder, - type="text", - title=machine.name, - content=html, - ) - print("[+] created note:", machine.name, " ") - - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="relation", name="template", value=trilium_template_id) - if machine.user_owned and machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="done") - else: - if machine.user_owned or machine.root_owned: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="inprogress") - else: - ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="todo") - - if machine.user_owned and machine.root_owned: - completed_count += 1 - -print("[+] updating folder name ") -ea.patch_note(noteId=trilium_htb_folder,title="Machines - "+str(completed_count)+" / "+str(len(machines))) - -print("[=] processed", machine_count) - diff --git a/htb2trilium2.py b/htb2trilium2.py new file mode 100644 index 0000000..c831574 --- /dev/null +++ b/htb2trilium2.py @@ -0,0 +1,224 @@ +''' +######################## +# SETUP +######################## + > pip3 install trilium-py + + - get trilium token in trilium options->ETAPI and "create new token" + - get trilium_htb_folder click on note to become folder -> "note info". Note ID is there. + - set the folder's owned attributes to: + #label:user=promoted,single,text #label:root=promoted,single,text #label:respect=promoted,single,text #user=0 #root=0 #respect=0 + + - create a note named "HTBMachineTemplate" and set it's "owned attributes" to: + #template #label:User=promoted,single,text #label:Root=promoted,single,text #label:Tags=promoted,single,text + + - get this page's ID and put in "trilium_template_id" + - to get "in progress" todo colour - add to trilium demo/scripting/taskmanager/implementation/CSS: + + span.fancytree-node.inprogress .fancytree-title { + color: orange !important; + } +''' + +######################## +# IGNORE THESE +######################## + +import requests +from bs4 import BeautifulSoup +from datetime import datetime, timezone +from htb_client import HTBClient +from trilium_py.client import ETAPI + +######################## +# EDIT BELOW HERE +######################## + +htb_code = '' +trilium_server_url = 'https://notes.place.com' +trilium_token = '' +trilium_htb_folder = '' +trilium_template_id = '' + +######################## +# LEAVE BELOW HERE +######################## + +def generate_newpage(machine): + no = "No" + yes = "Yes" + user_colour = no + if machine['authUserInUserOwns']: + user_colour = yes + root_colour = no + if machine['authUserInRootOwns']: + root_colour = yes + + status = "Retired" + if machine['active']: + status = "Active" + + release_str = machine['release'] + release_date = datetime.strptime(release_str, "%Y-%m-%dT%H:%M:%S.%fZ") + formatted_release_date = release_date.strftime("%d %B %Y") + + html = """ +
+ +
+

+ OS: {os}
+ Difficulty: {difficultyText}
+ Rating: {rating} / 5
+ Points: {points}
+ User / Root: {user_colour} / {root_colour}
+ Released: {release_date}
+ State: {status} +

+
+

Notes

+

 

+ """.format( + os=machine['os'], + difficultyText=machine['difficultyText'], + rating=machine['star'], + points=machine['points'], + release_date=formatted_release_date, + user_colour=user_colour, + root_colour=root_colour, + status = status, + avatar = machine['avatar'], + ) + + return html + +def get_timestamp(machine): + # Parse the release date string into a datetime object + release_str = machine['release'] + dt = datetime.strptime(release_str, "%Y-%m-%dT%H:%M:%S.%fZ") + + # Set the timezone to UTC + dt = dt.replace(tzinfo=timezone.utc) + + # Get the timestamp + timestamp = dt.timestamp() + return timestamp + +print("[+] connecting to HTB") +client = HTBClient(password=htb_code) +print("[+] connecting to trilium") +ea = ETAPI(trilium_server_url, trilium_token) +print("[i] version: ", ea.app_info()['appVersion']) + +print("[i] HTB User:", client.user['id'], "-", client.user['name']) +print("[i] user owns:", client.user['user_owns'], "| Root owns:", client.user['root_owns'], "| Respect:", client.user['respects']) + +master_folder = ea.get_note(trilium_htb_folder) +for attribute in master_folder['attributes']: + if attribute['name'] == "user": + if attribute['value'] != str(client.user['user_owns']): + print("[+] updating user owns (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['user_owns'])) + if attribute['name'] == "root": + if attribute['value'] != str(client.user['root_owns']): + print("[+] updating root owns (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['root_owns'])) + if attribute['name'] == "respect": + if attribute['value'] != str(client.user['respects']): + print("[+] updating respect (folder attribute)") + ea.patch_attribute(attributeId=attribute['attributeId'], value=str(client.user['respects'])) + +print("[+] gathering machines info") +machines = client.get_all_machines() +machines.sort(key=get_timestamp) + +print(f"[i] Retrieved {len(machines)} machines") +#for machine in machines: +# print(f" - ID: {machine['id']}, Name: {machine['name']}, OS: {machine['os']}, Difficulty: {machine['difficultyText']}") + +machine_count = 0 +completed_count = 0 +for machine in machines: + machine_count += 1 + print('processing: ',machine_count, "/", len(machines), "("+machine['name']+") " , end='\r') + + res = ea.search_note( + search="\""+machine['name']+"\"", + ancestorNoteId=trilium_htb_folder, + ancestorDepth='eq1', + limit=1, + fastSearch=True, + ) + + if res['results'] and machine['name'] == res['results'][0]['title']: + # page exists - lets check if the details have changed + + current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) + current_soup = BeautifulSoup(current_html, 'html.parser') + current_paragraph = current_soup.find_all('p')[0].text + + new_html = generate_newpage(machine) + new_soup = BeautifulSoup(new_html, 'html.parser') + new_paragraph = new_soup.find_all('p')[0].text + + # current page contains first paragraph of "blank" (useful for when it doesnt create or find the note properly.. shouldnt get here) + if current_paragraph == "blank": + ea.update_note_content(noteId=res['results'][0]['noteId'], content=new_html) + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="relation", name="template", value=trilium_template_id) + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="inprogress") + else: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=res['results'][0]['noteId'], type="label", name="cssClass", value="todo") + # re-get the current content + current_html = ea.get_note_content(noteId=res['results'][0]['noteId']) + current_soup = BeautifulSoup(current_html, 'html.parser') + + if current_paragraph != new_paragraph: + + # details have updated! + print("[+] updating page:",machine['name'], "-> "+res['results'][0]['title']+" ") + replacement = current_soup.find('p') + replacement.replace_with( new_soup.find_all('p')[0] ) + ea.update_note_content(noteId=res['results'][0]['noteId'], content=current_soup) + + # now to update the label + for attribute in res['results'][0]['attributes']: + if attribute['name'] == "cssClass": + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.patch_attribute(attributeId=attribute['attributeId'], value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.patch_attribute(attributeId=attribute['attributeId'], value="inprogress") + else: + ea.patch_attribute(attributeId=attribute['attributeId'], value="todo") + + else: + # title does not exist - create the note + html = generate_newpage(machine) + new_note = ea.create_note( + parentNoteId=trilium_htb_folder, + type="text", + title=machine['name'], + content=html, + ) + print("[+] created note:", machine['name'], " ") + + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="relation", name="template", value=trilium_template_id) + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="done") + else: + if machine['authUserInUserOwns'] or machine['authUserInRootOwns']: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="inprogress") + else: + ea.create_attribute(attributeId=None, isInheritable=False, noteId=new_note['note']['noteId'], type="label", name="cssClass", value="todo") + + if machine['authUserInUserOwns'] and machine['authUserInRootOwns']: + completed_count += 1 + +print("[+] updating folder name ") +ea.patch_note(noteId=trilium_htb_folder,title="Machines - "+str(completed_count)+" / "+str(len(machines))) + +print("[=] processed", machine_count) \ No newline at end of file diff --git a/htb_client.py b/htb_client.py new file mode 100644 index 0000000..6d3631e --- /dev/null +++ b/htb_client.py @@ -0,0 +1,146 @@ +import requests +import warnings + +warnings.filterwarnings("ignore") + +class HTBClient: + def __init__(self, password): + self.password = password + self.base_url = 'https://labs.hackthebox.com/api/v4' + self.proxies = { + #"http": "http://127.0.0.1:8080", # Burp proxy for HTTP traffic + #"https": "http://127.0.0.1:8080" # Burp proxy for HTTPS traffic + } + # Fetch user info + self.user = self.get_user_info() + + # Fetch user stats and store them in self.user + user_owns, root_owns, respects = self.get_user_stats(self.user['id']) + self.user['user_owns'] = user_owns + self.user['root_owns'] = root_owns + self.user['respects'] = respects + + def get_user_info(self): + headers = { + "Authorization": f"Bearer {self.password}", + "User-Agent": None # Explicitly remove User-Agent + } + response = requests.get( + f'{self.base_url}/user/info', + headers=headers, + proxies=self.proxies, + verify=False # Disable SSL verification + ) + if response.status_code != 200: + raise Exception(f"Error fetching {self.base_url}/user/info user info: {response.status_code}, {response.text}") + + # Return the user info as a dictionary + data = response.json().get('info') + return {'id': data['id'], 'name': data['name'], 'email': data['email']} + + def get_user_stats(self, user_id): + headers = { + "Authorization": f"Bearer {self.password}", + "User-Agent": None # Explicitly remove User-Agent + } + response = requests.get( + f'{self.base_url}/user/profile/basic/{user_id}', + headers=headers, + proxies=self.proxies, + verify=False # Disable SSL verification + ) + if response.status_code != 200: + raise Exception(f"Error fetching user stats: {response.status_code}, {response.text}") + + # Extract user statistics from the response + data = response.json().get('profile') + user_owns = data['user_owns'] + root_owns = data['system_owns'] + respects = data['respects'] + return user_owns, root_owns, respects + + def get_active_machines(self): + machines = [] + seen_ids = set() # Track unique machine IDs + seen_names = set() # Track unique machine names + page = 1 + + while True: + response = requests.get( + f'{self.base_url}/machine/paginated?per_page=100&page={page}', + headers={ + "Authorization": f"Bearer {self.password}", + "User-Agent": None # Explicitly remove User-Agent + }, + proxies=self.proxies, + verify=False # Disable SSL verification + ) + + if response.status_code != 200: + raise Exception(f"Error fetching active machines: {response.status_code}, {response.text}") + + data = response.json() + for machine in data['data']: + if machine['id'] not in seen_ids and machine['name'] not in seen_names: + machines.append(machine) + seen_ids.add(machine['id']) + seen_names.add(machine['name']) + + # Check for pagination + if page >= data['meta']['last_page']: + break + page += 1 + + return machines + + def get_retired_machines(self): + machines = [] + seen_ids = set() # Track unique machine IDs + seen_names = set() # Track unique machine names + page = 1 + + while True: + response = requests.get( + f'{self.base_url}/machine/list/retired/paginated?per_page=100&page={page}', + headers={ + "Authorization": f"Bearer {self.password}", + "User-Agent": None # Explicitly remove User-Agent + }, + proxies=self.proxies, + verify=False # Disable SSL verification + ) + + if response.status_code != 200: + raise Exception(f"Error fetching retired machines: {response.status_code}, {response.text}") + + data = response.json() + for machine in data['data']: + if machine['id'] not in seen_ids and machine['name'] not in seen_names: + machines.append(machine) + seen_ids.add(machine['id']) + seen_names.add(machine['name']) + + # Check for pagination + if page >= data['meta']['last_page']: + break + page += 1 + + return machines + + def get_all_machines(self): + # Combine active and retired machines, ensuring no duplicates + active_machines = self.get_active_machines() + retired_machines = self.get_retired_machines() + + all_machines = active_machines + retired_machines + seen_ids = set() # Track unique machine IDs + seen_names = set() # Track unique machine names + unique_machines = [] + + for machine in all_machines: + if machine['id'] not in seen_ids and machine['name'] not in seen_names: + unique_machines.append(machine) + seen_ids.add(machine['id']) + seen_names.add(machine['name']) + + return unique_machines \ No newline at end of file