Added a tablize function and did more
re coloring. The tablize function isn't quite 100% there yet. It mostly works, but I need to figure out word wrapping for cells.
This commit is contained in:
11
pentest_tool/Cargo.lock
generated
11
pentest_tool/Cargo.lock
generated
@@ -1273,6 +1273,7 @@ dependencies = [
|
|||||||
"futures-io 0.2.1",
|
"futures-io 0.2.1",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rodio",
|
"rodio",
|
||||||
|
"term_size",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -1818,6 +1819,16 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "term_size"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "terminfo"
|
name = "terminfo"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|||||||
@@ -13,4 +13,5 @@ fs_extra = "1.3.0"
|
|||||||
futures-io = { version = "0.2.0-beta" }
|
futures-io = { version = "0.2.0-beta" }
|
||||||
reqwest = {version = "0.12.12", features = ["blocking", "json"]}
|
reqwest = {version = "0.12.12", features = ["blocking", "json"]}
|
||||||
rodio = "0.20.1"
|
rodio = "0.20.1"
|
||||||
|
term_size = "0.3.2"
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
|
|||||||
@@ -18,94 +18,100 @@ use crate::victim_commands;
|
|||||||
use crate::enumeration;
|
use crate::enumeration;
|
||||||
use crate:: tool_controls;
|
use crate:: tool_controls;
|
||||||
use crate::configuration;
|
use crate::configuration;
|
||||||
|
use crate::tableize;
|
||||||
|
|
||||||
|
|
||||||
fn help(command: Option<String>){
|
fn help(command: Option<String>){
|
||||||
if command.is_some(){
|
if command.is_some(){
|
||||||
let help_cmd = command.unwrap();
|
let help_cmd = command.unwrap();
|
||||||
|
let mut lines = Vec::new();
|
||||||
|
lines.push("COMMAND||ALIASES||INFO".to_owned());
|
||||||
match help_cmd.as_str(){
|
match help_cmd.as_str(){
|
||||||
"list projects" | "lp" | "listp" | "list p" => {println!("Command: list projects\nAliases: lp, listp, list p\n\nThis command lists all projects currently tracked by the pentest_tool"); return;},
|
"list projects" | "lp" | "listp" | "list p" => lines.push("list projects||lp, listp, list p||This command lists all projects currently tracked by the pentest_tool".to_owned().to_owned()) ,
|
||||||
"switch project" | "swp" | "switch p" | "switchp" => {println!("Command: switch project\nAliases: swp, switch p, switchp\n\nThis command will switch the active project from the current one to a new on of your choosing. It will prompt you to make a selection."); return;},
|
"switch project" | "swp" | "switch p" | "switchp" => lines.push(" switch project|| swp, switch p, switchp||This command will switch the active project from the current one to a new on of your choosing. It will prompt you to make a selection.".to_owned()) ,
|
||||||
"show active project" | "show active" | "sa" | "show a" => {println!("Command: show active project\nAliases: sa, show a\n\nThis command shows information about the currently active project. NOTE the most useful information is already displayed above the CLI prompt."); return;},
|
"show active project" | "show active" | "sa" | "show a" => lines.push(" show active project|| sa, show a||This command shows information about the currently active project. NOTE the most useful information is already displayed above the CLI prompt.".to_owned()) ,
|
||||||
"create new project" | "cnp" | "new project" | "np" => {println!("Command: create new project\nAliases: cnp, new project, np\n\nThis command creates a new project and default note structure based on pyro's perferred note structure. It will prompt you for any needed information."); return;},
|
"create new project" | "cnp" | "new project" | "np" => lines.push(" create new project|| cnp, new project, np||This command creates a new project and default note structure based on pyro's perferred note structure. It will prompt you for any needed information.".to_owned()) ,
|
||||||
"save projects" | "sp" | "save" | "s" => {println!("Command: save projects\nAliases: sp save\n\nThis command saves all project information to the ~/.config/pyro_pentest_tool/projects.conf file"); return;},
|
"save projects" | "sp" | "save" | "s" => lines.push(" save projects|| sp save||This command saves all project information to the ~/.config/pyro_pentest_tool/projects.conf file".to_owned()) ,
|
||||||
"import project" | "ip" | "import" => {println!("Command: import project\nAliases: ip, import\n\nThis command will impot an existing project and set up a new distrobox for the project if it is a current project."); return;},
|
"import project" | "ip" | "import" => lines.push(" import project|| ip, import||This command will impot an existing project and set up a new distrobox for the project if it is a current project.".to_owned()) ,
|
||||||
"remove project" | "rp" | "remove" | "rmp" => {println!("Command:remove project\nAliases:rp, remove, rmp\n\nThis command removes a project from the list of projects tracked by the pentest_tool, and will destroy its distrobox. It does not remove any directories used or created by the distrobox. Run this after the report is written."); return;},
|
"remove project" | "rp" | "remove" | "rmp" => lines.push("remove project||rp, remove, rmp||This command removes a project from the list of projects tracked by the pentest_tool, and will destroy its distrobox. It does not remove any directories used or created by the distrobox. Run this after the report is written.".to_owned()) ,
|
||||||
"show upcoming projects" | "sup" | "show upcoming" => {println!("Command:show upcoming projects\nAliases:sup, show upcoming\n\nThis command shows a list of upcoming projects. Use this to verify which project you want to promote when the project enters the active phase."); return;},
|
"show upcoming projects" | "sup" | "show upcoming" => lines.push("show upcoming projects||sup, show upcoming||This command shows a list of upcoming projects. Use this to verify which project you want to promote when the project enters the active phase.".to_owned()) ,
|
||||||
"promote project" | "pp" | "promote" => {println!("Command:promote project\nAliases:pp (ha), promote\n\nThis command promotes an upcoming project to a current project. It will copy the folders that were created over to the current project space and set up a new distrobox for the project."); return;},
|
"promote project" | "pp" | "promote" => lines.push("promote project||pp (ha), promote||This command promotes an upcoming project to a current project. It will copy the folders that were created over to the current project space and set up a new distrobox for the project.".to_owned()) ,
|
||||||
"new terminal" | "enter" | "enter terminal" | "nt" | "et" => {println!("Command:new terminal\nAliases:enter, enter terminal, nt, et\n\nThis command spawns a new terminal window in the active project's distrobox. Use this to interact with your project's distrobox."); return;},
|
"new terminal" | "enter" | "enter terminal" | "nt" | "et" => lines.push("new terminal||enter, enter terminal, nt, et||This command spawns a new terminal window in the active project's distrobox. Use this to interact with your project's distrobox.".to_owned()) ,
|
||||||
"inline terminal" | "it" | "enter inline" | "ei" => {println!("Command:inline terminal\nAliases:it enter, inline, ei\n\nThis command spawns a terminal in this window using the current active project's distrobox"); return;},
|
"inline terminal" | "it" | "enter inline" | "ei" => lines.push("inline terminal||it enter, inline, ei||This command spawns a terminal in this window using the current active project's distrobox".to_owned()) ,
|
||||||
"cobalt strike" | "cs" => {println!("Command:cobalt strike\nAliases:cs\n\nThis command opens cobalt strike in the active project's distrobox, and spins it off as a new thread to ensure it doesn't block the rest of this tools operation. NOTE the cobalt strike window will need to be closed before this tool exits sucessfully."); return;},
|
"cobalt strike" | "cs" => lines.push("cobalt strike||cs||This command opens cobalt strike in the active project's distrobox, and spins it off as a new thread to ensure it doesn't block the rest of this tools operation. NOTE the cobalt strike window will need to be closed before this tool exits sucessfully.".to_owned()) ,
|
||||||
"recreate distrobox" | "rdb" | "ndb" | "new distrobox" => {println!("Command:recreate distrobox\nAliases:rdb, ndb, new distrobox\n\nThis command destroyes the existing distrobox for the currently active project, and clones a new one based on the current state of the template distrobox."); return;},
|
"recreate distrobox" | "rdb" | "ndb" | "new distrobox" => lines.push("recreate distrobox||rdb, ndb, new distrobox||This command destroyes the existing distrobox for the currently active project, and clones a new one based on the current state of the template distrobox.".to_owned()) ,
|
||||||
"generate userpass" | "userpass" | "gup" | "up" => {println!("Command:generate userpass\nAliases:userpass, gup, up\n\nThis command generates a userpass file based on the active project's notes. The file will be in the username:password format."); return;},
|
"generate userpass" | "userpass" | "gup" | "up" => lines.push("generate userpass||userpass, gup, up||This command generates a userpass file based on the active project's notes. The file will be in the username:password format.".to_owned()) ,
|
||||||
"inital enum" | "ie" | "enum" => {println!("Command:initial enum\nAliases:ie, enum\n\nThis command runs the initial enum script on a nessus csv and saves the output to the active project's notes in the host_notes.md file."); return;},
|
"inital enum" | "ie" | "enum" => lines.push("initial enum||ie, enum||This command runs the initial enum script on a nessus csv and saves the output to the active project's notes in the host_notes.md file.".to_owned()) ,
|
||||||
"build attack notes" | "ban" | "attack notes" | "hn" => {println!("Command:build attack notes\nAliases:ban, attack notes\n\nThis command builds the active project's attack note based on the active project's host notes (for external tests). It is expected that you'd run the initial enum command, then manually fill out the enumeration talbes with correct service names and ports."); return;},
|
"build attack notes" | "ban" | "attack notes" | "hn" => lines.push("build attack notes||ban, attack notes||This command builds the active project's attack note based on the active project's host notes (for external tests). It is expected that you'd run the initial enum command, then manually fill out the enumeration talbes with correct service names and ports.".to_owned()) ,
|
||||||
"host discovery" | "build host discovery" | "hd" | "bhd" => {println!("Command:host discovery\nAliases:build host discovery, hd, bhd\n\nThis command prints the host discovery ping command for the active project, based on the scope table in the general.md notes file."); return;},
|
"host discovery" | "build host discovery" | "hd" | "bhd" => lines.push("host discovery||build host discovery, hd, bhd||This command prints the host discovery ping command for the active project, based on the scope table in the general.md notes file.".to_owned()) ,
|
||||||
"cobaltstrike port scan" | "cs port scan" | "csps" => {println!("Command:port scan\nAliases:cs port scan, cobaltstrike port scan, csps, ps (tell your cat I said that)\n\nThis command prints the cobalt strike portscan command based on the active project's scope table in the general.md notes file"); return;},
|
"cobaltstrike port scan" | "cs port scan" | "csps" => lines.push("port scan||cs port scan, cobaltstrike port scan, csps, ps (tell your cat I said that)||This command prints the cobalt strike portscan command based on the active project's scope table in the general.md notes file".to_owned()) ,
|
||||||
"parse port scan" | "pps" | "parse scan" => {println!("Command:parse port scan\nAliases:pps, parse scan\n\nThis commmand parses a cobalt strike portscan TSV and saves interesting hoests to files to the active project's files folder. The host files are designated with the service that was detected that might be interesting. Use this to generate target lists for specific protocols."); return;},
|
"parse port scan" | "pps" | "parse scan" => lines.push("parse port scan||pps, parse scan||This commmand parses a cobalt strike portscan TSV and saves interesting hoests to files to the active project's files folder. The host files are designated with the service that was detected that might be interesting. Use this to generate target lists for specific protocols.".to_owned()) ,
|
||||||
"stop boxes" | "stop distroboxes" | "sdb" => {println!("Command:stop boxes\nAliases:stop distroboxes, sdb\n\nThis command stops all distroboxes for the tracked projects. Note if the distrobox isn't running you will see errors in the console, you can safely ignore these."); return;},
|
"stop boxes" | "stop distroboxes" | "sdb" => lines.push("stop boxes||stop distroboxes, sdb||This command stops all distroboxes for the tracked projects. Note if the distrobox isn't running you will see errors in the console, you can safely ignore these.".to_owned()) ,
|
||||||
"password spray" | "pass spray" | "pas" => {println!("Command:password spray\nAliases:pass spray, pas\n\nThis command iterates through the password spray note file and print the command to perform the spray, waiting the proper observation window beteen commands. It prompts you to save if needed. NOTE this will block execution for the rest of the program until it is either finished, or you save and exit the password spray function. I'm working on making this better."); return;},
|
"password spray" | "pass spray" | "pas" => lines.push("password spray||pass spray, pas||This command iterates through the password spray note file and print the command to perform the spray, waiting the proper observation window beteen commands. It prompts you to save if needed. NOTE this will block execution for the rest of the program until it is either finished, or you save and exit the password spray function. I'm working on making this better.".to_owned()) ,
|
||||||
"bloodhound" | "bh" => {println!("Command:bloodhound\nAliases:bh\n\nThis command launches bloodhound in the active project's distrobox. It will automatically start neo4j before staring bloodhound."); return;},
|
"bloodhound" | "bh" => lines.push("bloodhound||bh||This command launches bloodhound in the active project's distrobox. It will automatically start neo4j before staring bloodhound.".to_owned()) ,
|
||||||
"parse gather contacts" | "pgc" | "parse contacts" | "pc" => {println!("Command:parse gather contacts\nAliases:pgc, parse contacts, pc\n\nThis command parses output saved from the gather contacts burpsuite extension."); return;},
|
"parse gather contacts" | "pgc" | "parse contacts" | "pc" => lines.push("parse gather contacts||pgc, parse contacts, pc||This command parses output saved from the gather contacts burpsuite extension.".to_owned()) ,
|
||||||
"prune distroboxes" | "pdb" | "prune" => {println!("Command:prune distroboxes\nAliases:pdb, prune\n\nthis command prunes distroboxes for all projects that are not being tracked by this tool (frees up system storage). This will start all the currently acvtive distorboxes to ensure they don't get pruned, and then will delete all the not-started distrobox volumes and resources."); return;},
|
"prune distroboxes" | "pdb" | "prune" => lines.push("prune distroboxes||pdb, prune||this command prunes distroboxes for all projects that are not being tracked by this tool (frees up system storage). This will start all the currently acvtive distorboxes to ensure they don't get pruned, and then will delete all the not-started distrobox volumes and resources.".to_owned()) ,
|
||||||
"clear" | "clear screen" | "cls" => {println!("Command:clear\nAliases:clear screen, cls\n\nThis command clears the screen of command output."); return},
|
"clear" | "clear screen" | "cls" => lines.push("clear||clear screen, cls||This command clears the screen of command output.".to_owned()) ,
|
||||||
"exit" => {println!("Command:exit\nAliases:(none)\nThis command exits the pentest_tool, it will save all project infomation, and wait for all threads to re-join the main thread before exiting."); return;},
|
"exit" => lines.push("exit||(none)\nThis command exits the pentest_tool, it will save all project infomation, and wait for all threads to re-join the main thread before exiting.".to_owned()) ,
|
||||||
"settings" => {println!("\n\nThe settings file is located at ~/.config/pyro_pentest_tool/conf\n\nThe format is setting_name:setting_value.\n\nNeeded settings are\n project_files - the place to store current project files folders\n\n projtect_notes - the place to store current project notes\n\n tools_folder - the place to store custom tools like those downloaded from github\n\n upcoming_files - the place to store upcoming project files folders\n\n upcoming_notes - The place to store upcoming project note files\n\n box_template - the name of the distrobox you want to clone for project boxes\n\n terminal - the command you use to launch a terminal, while running a specific command: Ex: konsole -e \n\n cracking_rig - the user and host you use for a personal cracking rig in the openssh formating: Ex: pyro@cracking_rig or pyro@192.168.1.101 if you do not have a cracking rig the default is @n\n\n rockyou_location - the location on the cracking rig for the rockyou.txt file default is n\n\n rule_location - the location on the cracking rig for the one rule to rule them all file. Default is n\n\n pass_file - this is the location where you store your standard password spray file. If you do not have a custom one this tool provides one. The default is ~/.config/pyro_pentest_tool/passwordspary.md\n\n fingerprint - this is whether you want fingerprint authentication within your distroboxes, takes y/n\n\n vault_name - the name of your obsidian vault, default is notes\n\n"); return;},
|
"settings" => lines.push("||The settings file is located at ~/.config/pyro_pentest_tool/conf||The format is setting_name:setting_value.||Needed settings are\n project_files - the place to store current project files folders|| projtect_notes - the place to store current project notes|| tools_folder - the place to store custom tools like those downloaded from github|| upcoming_files - the place to store upcoming project files folders|| upcoming_notes - The place to store upcoming project note files|| box_template - the name of the distrobox you want to clone for project boxes|| terminal - the command you use to launch a terminal, while running a specific Ex: konsole -e || cracking_rig - the user and host you use for a personal cracking rig in the openssh formating: Ex: pyro@cracking_rig or pyro@192.168.1.101 if you do not have a cracking rig the default is @n|| rockyou_location - the location on the cracking rig for the rockyou.txt file default is n|| rule_location - the location on the cracking rig for the one rule to rule them all file. Default is n|| pass_file - this is the location where you store your standard password spray file. If you do not have a custom one this tool provides one. The default is ~/.config/pyro_pentest_tool/passwordspary.md|| fingerprint - this is whether you want fingerprint authentication within your distroboxes, takes y/n|| vault_name - the name of your obsidian vault, default is notes||".to_owned()) ,
|
||||||
"parse normal nmap file" | "pnnf" | "parse nmap" | "pn" => {println!("Command:parse normal nmap file\nAliases: pnnf, parse nmap, pn\n\nThis command parses the normal output of an nmap scan (like if you just tee'd or >'d it to a file) and outputs in host:port or int the coablt strike tsv format. It will attempt to find the file within the active project's files folder, and if it can't find the file it will prompt you for input.")},
|
"parse normal nmap file" | "pnnf" | "parse nmap" | "pn" => lines.push("parse normal nmap file|| pnnf, parse nmap, pn||This command parses the normal output of an nmap scan (like if you just tee'd or >'d it to a file) and outputs in host:port or int the coablt strike tsv format. It will attempt to find the file within the active project's files folder, and if it can't find the file it will prompt you for input.".to_owned()),
|
||||||
"sharpersist command" | "spc" | "sharp scheduled task" | "sst" => {println!("Command: sharpersist command\nAliases: spc, sharp scheduled task, sst\n\nThis comand prints the commands to run to use sharpersist.exe to create a scheduled task that runs hourly called FRPersist.")},
|
"sharpersist command" | "spc" | "sharp scheduled task" | "sst" => lines.push(" sharpersist command|| spc, sharp scheduled task, sst||This comand prints the commands to run to use sharpersist.exe to create a scheduled task that runs hourly called FRPersist.".to_owned()),
|
||||||
"port scan" | "ps" | "nmap" | "nmap scan" | "ns" | "nm" => {println!("Command: port scan\nAliases: ps, nmap, nmap scan, ns, nm\n\nThis command runs an nmap scan against the scope in the active projects notes, and saves the output.")},
|
"port scan" | "ps" | "nmap" | "nmap scan" | "ns" | "nm" => lines.push(" port scan|| ps, nmap, nmap scan, ns, nm||This command runs an nmap scan against the scope in the active projects notes, and saves the output.".to_owned()),
|
||||||
"show scope" | "ss" | "show s" | "s s" | "scope" => {println!("Command:show scope\nAliases:ss, show s, s s, scope\n\nThis command displays the current project's scope as just the hosts in the scope table in your notes.")},
|
"show scope" | "ss" | "show s" | "s s" | "scope" => lines.push("show scope||ss, show s, s s, scope||This command displays the current project's scope as just the hosts in the scope table in your notes.".to_owned()),
|
||||||
"port scan command" | "psc" | "nmap command" | "nmc" => {println!("command:port scan command\nAliases:psc,nmap command, nmc\n\nThis command will print the nmap command to manually run a scan to the terminal so you can copy paste it.")},
|
"port scan command" | "psc" | "nmap command" | "nmc" => lines.push("port scan command||psc,nmap command, nmc||This command will print the nmap command to manually run a scan to the terminal so you can copy paste it.".to_owned()),
|
||||||
"update git tools" | "ugt" | "update git" | "ug" => {println!("Command: update git tools\nAliases: update git, ugt, ug\n\nThis command attempts to update the git tools in your tools directory, it will attempt to update every directory as a git project. If the directory is not a git project it should just error out and continue to the next one.")},
|
"update git tools" | "ugt" | "update git" | "ug" => lines.push(" update git tools|| update git, ugt, ug||This command attempts to update the git tools in your tools directory, it will attempt to update every directory as a git project. If the directory is not a git project it should just error out and continue to the next one.".to_owned()),
|
||||||
"dns records" | "dr" => {println!("Command:dnsrecords\nAliases:dr\n\nThis command will run dns recon inside of your distrobox and save the results to your enumeration notes.")},
|
"dns records" | "dr" => lines.push("dnsrecords||dr||This command will run dns recon inside of your distrobox and save the results to your enumeration notes.".to_owned()),
|
||||||
"brute force subdomains"| "bsd" | "gobuster dns" | "gd" => {println!("Command:brute force subdomains\nAliases:bsd,gobuster dns, gd\n\nthis command will run gobuster in the project's distrobox and save the results to your notes.")},
|
"brute force subdomains"| "bsd" | "gobuster dns" | "gd" => lines.push("brute force subdomains||bsd,gobuster dns, gd||this command will run gobuster in the project's distrobox and save the results to your notes.".to_owned()),
|
||||||
"dns enumeration" | "de" | "all dns stuff" | "ads" | "dns stuff" | "ds" => {println!("Command:dns enumeration\nAliases:de, all dns stuff, ads, dns stuff, de\n\nThis command will perform both dns record enumeration with dnsrecon, and subdomain enumeration using gobster inside of your distrobox and save the output to your notes.")},
|
"dns enumeration" | "de" | "all dns stuff" | "ads" | "dns stuff" | "ds" => lines.push("dns enumeration||de, all dns stuff, ads, dns stuff, de||This command will perform both dns record enumeration with dnsrecon, and subdomain enumeration using gobster inside of your distrobox and save the output to your notes.".to_owned()),
|
||||||
"modify tool config" | "mtc" => {println!("Command: modify tool config\nAliases: mtc\n\nThis command lets you modify the tool's configuration.");}
|
"modify tool config" | "mtc" => lines.push("modify tool config|| mtc||This command lets you modify the tool's configuration.".to_owned()),
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
|
tableize(lines);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
println!("Welcom to Pyro's pentest command line!");
|
||||||
|
println!("the pentest_tool uses a configuration file to store your settings. This configuration file is located at ~/.config/pyro_pentest_tool/conf.\nYou can modify this file, but do so cautiously, incorrect formatting will cause this program to have a bruh moment.\nThe correct format is setting_name:setting_value\nExample:\nprojecT_files:/var/home/pyro/pentests/current");
|
||||||
|
println!("for help configuring the settings file run help settings");
|
||||||
|
let lines = vec!["command||aliases".to_owned(),
|
||||||
|
"menu||main menu, mm".to_owned(),
|
||||||
|
"list projects||lp, listp, list p".to_owned(),
|
||||||
|
"switch project||sp, switch p, switchp".to_owned(),
|
||||||
|
"show active project||show active, sa, show a".to_owned(),
|
||||||
|
"create new project||cnp, new project, np".to_owned(),
|
||||||
|
"save projects||sp, save, s".to_owned(),
|
||||||
|
"import project||ip, import".to_owned(),
|
||||||
|
"remove project||rp, remove, rmp".to_owned(),
|
||||||
|
"show upcoming project||sup, show upcoming".to_owned(),
|
||||||
|
"promote project||pp, promote".to_owned(),
|
||||||
|
"new terminal||enter, enter terminal, nt, et".to_owned(),
|
||||||
|
"inline terminal||it, enter inline, ei".to_owned(),
|
||||||
|
"cobalt strike||cs".to_owned(),
|
||||||
|
"recreate distrobox||rdb, ndb, new distrobox".to_owned(),
|
||||||
|
"generate userpass||userpass, gup, up".to_owned(),
|
||||||
|
"inital enum||ie, enum".to_owned(),
|
||||||
|
"host discovery ||build host discovery, hd, bhd".to_owned(),
|
||||||
|
"port scan||cs port scan, cobaltstrike port scan, csps, ps".to_owned(),
|
||||||
|
"parse port scan ||pps, parse scan".to_owned(),
|
||||||
|
"stop boxes||stop distroboxes, sdb".to_owned(),
|
||||||
|
"password spray||pass spray, pas".to_owned(),
|
||||||
|
"bloodhound||bh".to_owned(),
|
||||||
|
"parse gather contacts||pgc, parse contacts, pc".to_owned(),
|
||||||
|
"prune distroboxes||pdb, prune".to_owned(),
|
||||||
|
"clear||clear screen, cls".to_owned(),
|
||||||
|
"parse nomral nmap file||pnnf, parse nmap, pn".to_owned(),
|
||||||
|
"show scope||ss, show s, s s, scope".to_owned(),
|
||||||
|
"sharpersist command||spc, sharp scheduled task".to_owned(),
|
||||||
|
"port scan||ps, nmap, nmap scan, ns, nm".to_owned(),
|
||||||
|
"port scan command||psc, nmap command, nmc".to_owned(),
|
||||||
|
"update git tools||ugt, update git, ug".to_owned(),
|
||||||
|
"dns records||dr".to_owned(),
|
||||||
|
"brute force subdomain||bsd, gobuster dns, gd".to_owned(),
|
||||||
|
"dns enumeration||de, all dns stuff, ads, dns stuff, ds".to_owned(),
|
||||||
|
"modify tool config||mtc".to_owned(),
|
||||||
|
"help||?, -h".to_owned()];
|
||||||
|
println!("available commands:");
|
||||||
|
tableize(lines);
|
||||||
}
|
}
|
||||||
println!("Welcom to Pyro's pentest command line!");
|
|
||||||
println!("the pentest_tool uses a configuration file to store your settings. This configuration file is located at ~/.config/pyro_pentest_tool/conf.\nYou can modify this file, but do so cautiously, incorrect formatting will cause this program to have a bruh moment.\nThe correct format is setting_name:setting_value\nExample:\nprojecT_files:/var/home/pyro/pentests/current");
|
|
||||||
println!("for help configuring the settings file run help settings");
|
|
||||||
println!("available commands: name | aliases | ...");
|
|
||||||
print!("
|
|
||||||
menu | main menu | mm
|
|
||||||
list projects | lp | listp | list p
|
|
||||||
switch project | sp | switch p | switchp
|
|
||||||
show active project | show active | sa | show a
|
|
||||||
create new project | cnp | new project | np
|
|
||||||
save projects | sp | save | s
|
|
||||||
import project | ip | import
|
|
||||||
remove project | rp | remove | rmp
|
|
||||||
show upcoming project | sup | show upcoming
|
|
||||||
promote project | pp | promote
|
|
||||||
new terminal | enter | enter terminal | nt | et
|
|
||||||
inline terminal | it | enter inline | ei
|
|
||||||
cobalt strike | cs
|
|
||||||
recreate distrobox | rdb | ndb | new distrobox
|
|
||||||
generate userpass | userpass | gup | up
|
|
||||||
inital enum | ie | enum
|
|
||||||
host discovery | build host discovery | hd | bhd
|
|
||||||
port scan | cs port scan | cobaltstrike port scan | csps | ps
|
|
||||||
parse port scan | pps | parse scan
|
|
||||||
stop boxes | stop distroboxes | sdb
|
|
||||||
password spray | pass spray | pas
|
|
||||||
bloodhound | bh
|
|
||||||
parse gather contacts | pgc | parse contacts | pc
|
|
||||||
prune distroboxes | pdb | prune
|
|
||||||
clear | clear screen | cls
|
|
||||||
parse nomral nmap file | pnnf | parse nmap | pn
|
|
||||||
show scope | ss | show s | s s | scope
|
|
||||||
sharpersist command | spc | sharp scheduled task
|
|
||||||
port scan | ps | nmap | nmap scan | ns | nm
|
|
||||||
port scan command | psc | nmap command | nmc
|
|
||||||
update git tools | ugt | update git | ug
|
|
||||||
dns records | dr
|
|
||||||
brute force subdomains| bsd | gobuster dns | gd
|
|
||||||
dns enumeration | de | all dns stuff | ads | dns stuff | ds
|
|
||||||
modify tool config | mtc
|
|
||||||
help | ? | -h
|
|
||||||
")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_active_project(projects: &Vec<Project>) -> Option<&Project>{
|
pub fn get_active_project(projects: &Vec<Project>) -> Option<&Project>{
|
||||||
@@ -333,7 +339,7 @@ for help enter help or ?. for information about a specific command enter help (c
|
|||||||
|
|
||||||
|
|
||||||
", active_project.customer.green(), active_project.project_name.green(), active_project.stage.green(), active_project.files_folder.display().to_string().green(), active_project.notes_folder.display().to_string().green(), active_project.boxname.green(), "coming soon".red());
|
", active_project.customer.green(), active_project.project_name.green(), active_project.stage.green(), active_project.files_folder.display().to_string().green(), active_project.notes_folder.display().to_string().green(), active_project.boxname.green(), "coming soon".red());
|
||||||
let prompt = format!("\n{}:{}\nCommand?", active_project.customer.green(), active_project.project_name.green());
|
let prompt = format!("\n{}:{}\nCommand?", active_project.customer.custom_color((255,165,0)), active_project.project_name.custom_color((255,165,0)));
|
||||||
let command = get_user_input(&prompt);
|
let command = get_user_input(&prompt);
|
||||||
match command.as_str(){
|
match command.as_str(){
|
||||||
"exit" => loopize = false,
|
"exit" => loopize = false,
|
||||||
@@ -342,6 +348,7 @@ for help enter help or ?. for information about a specific command enter help (c
|
|||||||
"clear" | "clear screen" | "cls" => {clear().unwrap(); print_banner(banner);},
|
"clear" | "clear screen" | "cls" => {clear().unwrap(); print_banner(banner);},
|
||||||
"list threads" | "threads" | "lst" => println!("There are {} threads still running.", threads.len()),
|
"list threads" | "threads" | "lst" => println!("There are {} threads still running.", threads.len()),
|
||||||
"info" => println!("{}", current_information),
|
"info" => println!("{}", current_information),
|
||||||
|
"test_table" => {let mut lines = Vec::new(); lines.push("column1||column2||column3||column4".to_owned()); lines.push("thing1||thing2||thing3||thing4".to_owned()); lines.push("ttttttttttttttttthing5||thing6||thing7||thing8".to_owned()); tableize(lines);}
|
||||||
_ => {let thread_option = run_command(command, &mut projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if thread_option.is_some(){threads.push(thread_option.unwrap())}},
|
_ => {let thread_option = run_command(command, &mut projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if thread_option.is_some(){threads.push(thread_option.unwrap())}},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fs::{File, create_dir_all, remove_dir_all};
|
use std::fs::{self, create_dir_all, remove_dir_all, File};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::env;
|
||||||
use std::io::copy;
|
use std::io::copy;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@@ -11,7 +12,7 @@ use std::thread;
|
|||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
||||||
use crate::get_user_input;
|
use crate::{get_user_input, print_error, print_informational, print_success};
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub fn install(config_path: &PathBuf){
|
pub fn install(config_path: &PathBuf){
|
||||||
@@ -270,6 +271,35 @@ vault_name:{}"
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
password_write_res.unwrap();
|
password_write_res.unwrap();
|
||||||
println!("install completed successfully!");
|
let current_path_res = env::current_exe();
|
||||||
println!("re-run this to launch!");
|
let mut copied_to_path = false;
|
||||||
|
if current_path_res.is_ok(){
|
||||||
|
let current_path = current_path_res.unwrap();
|
||||||
|
let mut new_path = PathBuf::from("/usr/bin/pentest_tool");
|
||||||
|
print_informational("We ar going to try and copy this executable to a location on your $PATH");
|
||||||
|
print_informational("the default location is /usr/bin/pentest_tool");
|
||||||
|
if get_user_input("is this ok?").contains("n"){
|
||||||
|
new_path.clear();
|
||||||
|
new_path.push(get_user_input("ooof, ok. Please enter where you'd like to save it on your $PATH"));
|
||||||
|
if !new_path.display().to_string().contains("pentest_tool"){
|
||||||
|
new_path.push("pentest_tool");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let copy_cmd_res = Command::new("sudo").arg("cp").arg(current_path.display().to_string()).arg(new_path.display().to_string()).status();
|
||||||
|
if copy_cmd_res.is_ok(){
|
||||||
|
let copy_cmd_status = copy_cmd_res.unwrap();
|
||||||
|
if copy_cmd_status.success(){
|
||||||
|
copied_to_path = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !copied_to_path{
|
||||||
|
print_informational("we could not copy this executable to your path!");
|
||||||
|
print_informational("please copy this file to somewhere on your $PATH.");
|
||||||
|
print_informational("for example `cp pentest_tool /usr/bin/pentest_tool");
|
||||||
|
print_success("otherwise this tool is ready to go, you would just need to launch it from this folder.");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
print_success("install completed successfully!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
|
use std::collections::btree_set::Difference;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::{io::stdin, path::PathBuf, process::Command};
|
use std::{io::stdin, path::PathBuf, process::Command};
|
||||||
|
use chrono::format;
|
||||||
use directories::UserDirs;
|
use directories::UserDirs;
|
||||||
use std::process::exit;
|
use std::process::exit;
|
||||||
use std::fs::{self, File};
|
use std::fs::{self, File};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
use term_size::dimensions;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Project{
|
pub struct Project{
|
||||||
@@ -39,7 +43,88 @@ pub fn print_success<T>(message: T) where T: AsRef<str> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_informational<T>(message: T) where T: AsRef<str>{
|
pub fn print_informational<T>(message: T) where T: AsRef<str>{
|
||||||
println!("{}", message.as_ref());
|
println!("{}", message.as_ref().custom_color((255,165,0)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tableize(given_lines: Vec<String>) {
|
||||||
|
let column_count = given_lines[0].split("||").collect::<Vec<&str>>().len();
|
||||||
|
// the following code just adds a junk line in at index 1 because that gets eaten for some reason...
|
||||||
|
// I want to try to figure out why its getten eaten, but just needed to get it working for now.
|
||||||
|
let mut lines = Vec::new();
|
||||||
|
let mut junk_line = format!("{}", "junk||".repeat(column_count));
|
||||||
|
junk_line.pop();
|
||||||
|
junk_line.pop();
|
||||||
|
for line in given_lines{
|
||||||
|
lines.push(line);
|
||||||
|
}
|
||||||
|
lines.insert(1,junk_line);
|
||||||
|
// end of junk line logic.
|
||||||
|
let (terminal_width, _terminal_height) = term_size::dimensions().unwrap();
|
||||||
|
let mut column_sizes:HashMap<usize, usize> = HashMap::new();
|
||||||
|
for column_number in 0..column_count{
|
||||||
|
column_sizes.insert(column_number, 0);
|
||||||
|
}
|
||||||
|
let mut longest_column = 0;
|
||||||
|
for line in &lines{
|
||||||
|
let cells: Vec<&str> = line.split("||").collect();
|
||||||
|
let mut current_cell: usize = 0;
|
||||||
|
for cell in cells{
|
||||||
|
let cell_length = cell.len() + 2;
|
||||||
|
if column_sizes[¤t_cell] < cell_length{
|
||||||
|
column_sizes.insert(current_cell, cell_length);
|
||||||
|
}
|
||||||
|
if cell_length > longest_column{
|
||||||
|
longest_column = current_cell;
|
||||||
|
}
|
||||||
|
current_cell += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let longest_line = (column_count*2) - 1;
|
||||||
|
if longest_line > terminal_width{
|
||||||
|
let difference = longest_line - terminal_width - 3;
|
||||||
|
column_sizes.insert(longest_column, column_sizes[&longest_column] - difference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut header = String::new();
|
||||||
|
let mut outdata = String::new();
|
||||||
|
let mut count = 0;
|
||||||
|
let mut separater = String::new();
|
||||||
|
let ending = format!("{}\n", "|".green());
|
||||||
|
for line in lines{
|
||||||
|
count += 1;
|
||||||
|
//println!("{}", line);
|
||||||
|
let mut add_ending = false;
|
||||||
|
let data_vec: Vec<&str> = line.split("||").collect();
|
||||||
|
let mut column_numbers: Vec<&usize> = column_sizes.keys().collect();
|
||||||
|
column_numbers.sort_by(|a, b| a.cmp(b));
|
||||||
|
for column in column_numbers{
|
||||||
|
/*if data_vec[*column].len() > column_sizes[&longest_column]{
|
||||||
|
let split_data_vec = data_vec[*column].split_at(column_sizes[&longest_column]);
|
||||||
|
}*/
|
||||||
|
let padding = column_sizes[column] - data_vec[*column].len();
|
||||||
|
if count == 1{
|
||||||
|
let formatted_cell = format!("{} {}{}", "|".green(), data_vec[*column].bold().green(), " ".repeat(padding));
|
||||||
|
header.push_str(&formatted_cell);
|
||||||
|
}
|
||||||
|
else if count == 2 {
|
||||||
|
let formatted_cell = format!("{} {} ", "|".green(), "-".repeat(column_sizes[column] - 1).green());
|
||||||
|
separater.push_str(&formatted_cell);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
let formatted_cell = format!("{} {}{}", "|".green(), data_vec[*column], " ".repeat(padding));
|
||||||
|
outdata.push_str(&formatted_cell);
|
||||||
|
add_ending = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if add_ending{
|
||||||
|
outdata.push_str(&ending)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outdata.push_str(&separater);
|
||||||
|
outdata.push_str(&ending);
|
||||||
|
let print_output = format!("{}{}{}{}{}", header, ending, separater, ending, outdata);
|
||||||
|
println!("{}", print_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_overwrite(path: &PathBuf) -> Option<File>{
|
pub fn open_overwrite(path: &PathBuf) -> Option<File>{
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::path::PathBuf;
|
|||||||
use std::thread::JoinHandle;
|
use std::thread::JoinHandle;
|
||||||
use clearscreen::clear;
|
use clearscreen::clear;
|
||||||
use clearscreen;
|
use clearscreen;
|
||||||
|
use colored::Colorize;
|
||||||
use crate::get_user_input;
|
use crate::get_user_input;
|
||||||
use crate::Project;
|
use crate::Project;
|
||||||
use crate::cli;
|
use crate::cli;
|
||||||
@@ -66,6 +67,9 @@ pub fn main_menu(projects: &mut Vec<Project>,
|
|||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
print!("
|
print!("
|
||||||
{}
|
{}
|
||||||
|
{}
|
||||||
|
|
||||||
|
\n", banner.custom_color((255,165,0)), "
|
||||||
___ ___ _ ___ ___
|
___ ___ _ ___ ___
|
||||||
| \\/ | (_) | \\/ | _
|
| \\/ | (_) | \\/ | _
|
||||||
| . . | __ _ _ _ __ | . . | ___ _ __ _ _(_)
|
| . . | __ _ _ _ __ | . . | ___ _ __ _ _(_)
|
||||||
@@ -102,7 +106,7 @@ ___ ___ _ ___ ___
|
|||||||
28.) enter external only menu
|
28.) enter external only menu
|
||||||
29.) enter internal only menu
|
29.) enter internal only menu
|
||||||
30.) exit menu
|
30.) exit menu
|
||||||
\n", banner);
|
".custom_color((255,165,0)));
|
||||||
match get_user_input("selection?").as_str(){
|
match get_user_input("selection?").as_str(){
|
||||||
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
@@ -134,7 +138,7 @@ ___ ___ _ ___ ___
|
|||||||
"28" => {let threads_option = external_menu(banner, projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if threads_option.is_some(){for thread in threads_option.unwrap(){threads.push(thread)}}},
|
"28" => {let threads_option = external_menu(banner, projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if threads_option.is_some(){for thread in threads_option.unwrap(){threads.push(thread)}}},
|
||||||
"29" => {let threads_option = internal_menu(banner, projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if threads_option.is_some(){for thread in threads_option.unwrap(){threads.push(thread)}}},
|
"29" => {let threads_option = internal_menu(banner, projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.clone(), cracking_rig.clone(), rockyou.clone(), rule.clone(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.clone()); if threads_option.is_some(){for thread in threads_option.unwrap(){threads.push(thread)}}},
|
||||||
"30" => loopize = false,
|
"30" => loopize = false,
|
||||||
_ => println!("unknown selection, try again!"),
|
_ => println!("{}","unknown selection, try again!".red()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if threads.len() > 0{
|
if threads.len() > 0{
|
||||||
@@ -166,7 +170,9 @@ ___ ___ _ ___ ___
|
|||||||
let _enter_to_clear = get_user_input("press enter to display external project menu.");
|
let _enter_to_clear = get_user_input("press enter to display external project menu.");
|
||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
print!("
|
print!("
|
||||||
{}
|
{}
|
||||||
|
{}
|
||||||
|
\n", banner.custom_color((255,165,0)), "
|
||||||
_____ _ _ ___ ___
|
_____ _ _ ___ ___
|
||||||
| ___| | | | | | \\/ | _
|
| ___| | | | | | \\/ | _
|
||||||
| |____ _| |_ ___ _ __ _ __ __ _| | | . . | ___ _ __ _ _(_)
|
| |____ _| |_ ___ _ __ _ __ __ _| | | . . | ___ _ __ _ _(_)
|
||||||
@@ -196,7 +202,7 @@ ___ ___ _ ___ ___
|
|||||||
21.) Brute force Subdomains
|
21.) Brute force Subdomains
|
||||||
22.) Do all DNS Enumeration
|
22.) Do all DNS Enumeration
|
||||||
23.) exit menu
|
23.) exit menu
|
||||||
\n", banner);
|
".custom_color((255,165,0)));
|
||||||
match get_user_input("selection?").as_str(){
|
match get_user_input("selection?").as_str(){
|
||||||
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
@@ -221,7 +227,7 @@ ___ ___ _ ___ ___
|
|||||||
"21" => {let thread_option = cli::run_command("brute force subdomains".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"21" => {let thread_option = cli::run_command("brute force subdomains".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"22" => {let thread_option = cli::run_command("dns enumeration".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"22" => {let thread_option = cli::run_command("dns enumeration".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"23" => loopize = false,
|
"23" => loopize = false,
|
||||||
_ => println!("unknown selection, try again!"),
|
_ => println!("{}", "unknown selection, try again!".red()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if threads.len() > 0{
|
if threads.len() > 0{
|
||||||
@@ -255,7 +261,9 @@ ___ ___ _ ___ ___
|
|||||||
let _enter_to_clear = get_user_input("press enter to display internal project menu.");
|
let _enter_to_clear = get_user_input("press enter to display internal project menu.");
|
||||||
clear().expect("error clearing screen");
|
clear().expect("error clearing screen");
|
||||||
print!("
|
print!("
|
||||||
{}
|
{}
|
||||||
|
{}
|
||||||
|
\n", banner.custom_color((255,165,0)), "
|
||||||
_____ _ _ ___ ___
|
_____ _ _ ___ ___
|
||||||
|_ _| | | | | | \\/ | _
|
|_ _| | | | | | \\/ | _
|
||||||
| | _ __ | |_ ___ _ __ _ __ __ _| | | . . | ___ _ __ _ _(_)
|
| | _ __ | |_ ___ _ __ _ __ __ _| | | . . | ___ _ __ _ _(_)
|
||||||
@@ -284,7 +292,7 @@ ___ ___ _ ___ ___
|
|||||||
20.) open bloodhound in the current project's distrobox
|
20.) open bloodhound in the current project's distrobox
|
||||||
21.) prune unused distroboxes (free up system storage)
|
21.) prune unused distroboxes (free up system storage)
|
||||||
22.) exit menu
|
22.) exit menu
|
||||||
\n", banner);
|
".custom_color((255,165,0)));
|
||||||
match get_user_input("selection?").as_str(){
|
match get_user_input("selection?").as_str(){
|
||||||
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"1" => {let thread_option = cli::run_command("show active project".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"2" => {let thread_option = cli::run_command("list projects".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
@@ -308,7 +316,7 @@ ___ ___ _ ___ ___
|
|||||||
"20" => {let thread_option = cli::run_command("bloodhound".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"20" => {let thread_option = cli::run_command("bloodhound".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"21" => {let thread_option = cli::run_command("prune distroboxes".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
"21" => {let thread_option = cli::run_command("prune distroboxes".to_owned(), projects, config_path.clone(), base_files, base_notes, tools_dir, boxtemplate.clone(), terminal.to_owned(), cracking_rig.to_owned(), rockyou.to_owned(), rule.to_owned(), upcoming_files, upcoming_notes, password_spray_file, fingerprint, vault_name.to_owned()); if thread_option.is_some(){threads.push(thread_option.unwrap());}},
|
||||||
"22" => loopize = false,
|
"22" => loopize = false,
|
||||||
_ => println!("unknown selection, try again!"),
|
_ => println!("{}", "unknown selection, try again!".red()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if threads.len() > 0{
|
if threads.len() > 0{
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ pub fn build_cmd_for_host_discovery(project: &Project){
|
|||||||
let general_note_string = read_to_string(general_note_path);
|
let general_note_string = read_to_string(general_note_path);
|
||||||
let mut _note_string = String::new();
|
let mut _note_string = String::new();
|
||||||
match general_note_string{
|
match general_note_string{
|
||||||
Err(error) => {println!("error reading file to string!! {}", error); return;},
|
Err(error) => {println!("{} {}", "error reading file to string!!".green(), error.to_string().green()); return;},
|
||||||
_=> _note_string = general_note_string.unwrap()
|
_=> _note_string = general_note_string.unwrap()
|
||||||
}
|
}
|
||||||
let lines: Vec<&str> = _note_string.split("\n").collect();
|
let lines: Vec<&str> = _note_string.split("\n").collect();
|
||||||
@@ -235,7 +235,7 @@ pub fn build_cmd_for_host_discovery(project: &Project){
|
|||||||
final_command.push_str(">> ping_only_replies.txt &");
|
final_command.push_str(">> ping_only_replies.txt &");
|
||||||
}
|
}
|
||||||
final_command.pop();
|
final_command.pop();
|
||||||
println!("{}", final_command);
|
print_success(final_command);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_csportscan(project: &Project){
|
pub fn parse_csportscan(project: &Project){
|
||||||
|
|||||||
@@ -11,8 +11,12 @@ use std::str::FromStr;
|
|||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
||||||
use crate::get_user_input;
|
use crate::get_user_input;
|
||||||
|
use crate::tableize;
|
||||||
use crate::Project;
|
use crate::Project;
|
||||||
use crate::box_controls::make_box;
|
use crate::box_controls::make_box;
|
||||||
|
use crate::print_success;
|
||||||
|
use crate::print_error;
|
||||||
|
use crate::print_informational;
|
||||||
|
|
||||||
pub fn
|
pub fn
|
||||||
switch_project(projects: &mut Vec<Project>){
|
switch_project(projects: &mut Vec<Project>){
|
||||||
@@ -29,19 +33,19 @@ switch_project(projects: &mut Vec<Project>){
|
|||||||
for project in projects{
|
for project in projects{
|
||||||
if project.id == new_id{
|
if project.id == new_id{
|
||||||
project.active = true;
|
project.active = true;
|
||||||
println!("project found switching to {} {}", project.customer, project.project_name);
|
print_success(format!("project found switching to {} {}", project.customer, project.project_name));
|
||||||
env::set_var("CURRENT_PROJECT_BOX", project.boxname.clone());
|
env::set_var("CURRENT_PROJECT_BOX", project.boxname.clone());
|
||||||
}
|
}
|
||||||
else if project.id != new_id{
|
else if project.id != new_id{
|
||||||
project.active = false;
|
project.active = false;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
println!("error unknown project id");
|
print_error("error selecting new project", String::from("unknown project id selected."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
println!("error we need user input here dummy!");
|
print_error("error selecting new project", String::from("we need input here dummy!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -51,7 +55,13 @@ pub fn save_projects(projects: &Vec<Project>, config_path: &PathBuf){
|
|||||||
let mut active_set = false;
|
let mut active_set = false;
|
||||||
save_file_path.pop();
|
save_file_path.pop();
|
||||||
save_file_path.push("projects.conf");
|
save_file_path.push("projects.conf");
|
||||||
let mut save_file = fs::File::create(save_file_path).expect("error creating save_file");
|
let save_file_res = fs::File::create(save_file_path);
|
||||||
|
if save_file_res.is_err(){
|
||||||
|
let error = save_file_res.err().unwrap().to_string();
|
||||||
|
print_error("error creating save file.", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let mut save_file = save_file_res.unwrap();
|
||||||
save_file.write_all(b"customer:name:notes:files:active:time:box_name:stage\n").expect("error writing first line to file");
|
save_file.write_all(b"customer:name:notes:files:active:time:box_name:stage\n").expect("error writing first line to file");
|
||||||
for project in projects{
|
for project in projects{
|
||||||
let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()};
|
let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()};
|
||||||
@@ -66,7 +76,13 @@ pub fn save_projects(projects: &Vec<Project>, config_path: &PathBuf){
|
|||||||
else{
|
else{
|
||||||
_outline = format!("{}no:{}:{}\n", default, project.boxname, project.stage);
|
_outline = format!("{}no:{}:{}\n", default, project.boxname, project.stage);
|
||||||
}
|
}
|
||||||
save_file.write_all(_outline.as_bytes()).expect("error writing outline");
|
let write_res = save_file.write_all(_outline.as_bytes());
|
||||||
|
if write_res.is_err(){
|
||||||
|
let error = write_res.err().unwrap().to_string();
|
||||||
|
print_error("error saving projects.conf file!", error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write_res.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,11 +373,14 @@ pub fn get_projects(config_path: &PathBuf, show: bool) -> Option<Vec<Project>>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_upcoming_projects(projects: &Vec<Project>){
|
pub fn print_upcoming_projects(projects: &Vec<Project>){
|
||||||
|
let mut lines = vec![String::from("CUSTOMER||PROJECT")];
|
||||||
for project in projects{
|
for project in projects{
|
||||||
if project.stage.contains("upcoming"){
|
if project.stage.contains("upcoming"){
|
||||||
println!("{}:{}", project.customer, project.project_name);
|
let new_line = format!("{}||{}", project.customer, project.project_name);
|
||||||
|
lines.push(new_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tableize(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn promote_project(projects: &mut Vec<Project>, config_path: &PathBuf, project_dir: &PathBuf, notes_dir: &PathBuf, tools_dir: &PathBuf, boxtemplate: &String, fingerprint: bool){
|
pub fn promote_project(projects: &mut Vec<Project>, config_path: &PathBuf, project_dir: &PathBuf, notes_dir: &PathBuf, tools_dir: &PathBuf, boxtemplate: &String, fingerprint: bool){
|
||||||
@@ -418,7 +437,7 @@ pub fn promote_project(projects: &mut Vec<Project>, config_path: &PathBuf, proje
|
|||||||
println!("failed to copy the project folder, try to move it manually!");
|
println!("failed to copy the project folder, try to move it manually!");
|
||||||
}
|
}
|
||||||
if note_move_success.success(){
|
if note_move_success.success(){
|
||||||
println!("we copied the notes folder correctly!!");
|
print_success("we copied the notes folder correctly!!");
|
||||||
let mut remove_folder = PathBuf::new();
|
let mut remove_folder = PathBuf::new();
|
||||||
remove_folder.push(&project.files_folder);
|
remove_folder.push(&project.files_folder);
|
||||||
remove_folder.pop();
|
remove_folder.pop();
|
||||||
@@ -465,11 +484,15 @@ pub fn promote_project(projects: &mut Vec<Project>, config_path: &PathBuf, proje
|
|||||||
projects.clear();
|
projects.clear();
|
||||||
projects.append(&mut projects_to_save);
|
projects.append(&mut projects_to_save);
|
||||||
save_projects(&projects_to_save, config_path);
|
save_projects(&projects_to_save, config_path);
|
||||||
|
print_success("project promoted successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_projects(projects: &Vec<Project>){
|
pub fn list_projects(projects: &Vec<Project>){
|
||||||
println!("+++++++++++++++++++++");
|
let mut lines = vec!["customer||project||stage".to_owned()];
|
||||||
for project in projects{
|
for project in projects{
|
||||||
println!("++Customer: {}|Project name: {}|Stage: {}++",project.customer ,project.project_name, project.stage)}
|
let new_line = format!("{}||{}||{}", project.customer, project.project_name, project.stage);
|
||||||
println!("++++++++++++++++++++")
|
lines.push(new_line);
|
||||||
|
}
|
||||||
|
tableize(lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::{env::set_current_dir, path::PathBuf};
|
|||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
use crate::print_success;
|
||||||
|
|
||||||
|
|
||||||
pub fn update_git_tools(tools_dir: &PathBuf){
|
pub fn update_git_tools(tools_dir: &PathBuf){
|
||||||
@@ -34,7 +35,7 @@ pub fn update_git_tools(tools_dir: &PathBuf){
|
|||||||
else{
|
else{
|
||||||
let git_command = git_command_res.unwrap();
|
let git_command = git_command_res.unwrap();
|
||||||
if git_command.success(){
|
if git_command.success(){
|
||||||
println!("successfully updated {}", folder.display());
|
print_success(format!("successfully updated {}", folder.display()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use colored::Colorize;
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
use crate::get_user_input;
|
use crate::get_user_input;
|
||||||
|
use crate::print_success;
|
||||||
|
|
||||||
pub fn sharp_persist_command(tools_dir: &PathBuf){
|
pub fn sharp_persist_command(tools_dir: &PathBuf){
|
||||||
let filename = "SharPersist.exe";
|
let filename = "SharPersist.exe";
|
||||||
@@ -20,13 +22,13 @@ pub fn sharp_persist_command(tools_dir: &PathBuf){
|
|||||||
"1" => println!("execute-assembly {} -t schtask -c \"{}\" -n FRPersist -m add -o hourly", binary_path, beacon_path),
|
"1" => println!("execute-assembly {} -t schtask -c \"{}\" -n FRPersist -m add -o hourly", binary_path, beacon_path),
|
||||||
"2" => println!("inlineExecute-Assembly --dotnetassembly {} --assemblyargs -t schtask -c \"{}\" -n FRPersist -m add -o hourly --etw --amsi", binary_path, beacon_path),
|
"2" => println!("inlineExecute-Assembly --dotnetassembly {} --assemblyargs -t schtask -c \"{}\" -n FRPersist -m add -o hourly --etw --amsi", binary_path, beacon_path),
|
||||||
"3" => println!("upload {}\n\nrun .\\SharPersist.exe -t schtask -c \"{}\" -n FRPersist -m add -o hourly", binary_path, beacon_path),
|
"3" => println!("upload {}\n\nrun .\\SharPersist.exe -t schtask -c \"{}\" -n FRPersist -m add -o hourly", binary_path, beacon_path),
|
||||||
_ => println!("unknown selection")
|
_ => println!("{}","unknown selection".red())
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let file_to_run = get_user_input("path to the file you want to run for persistence?");
|
let file_to_run = get_user_input("path to the file you want to run for persistence?");
|
||||||
println!("ok then, upload the following file to the machine");
|
print_success("ok then, upload the following file to the machine");
|
||||||
println!("{}", binary_path);
|
print_success(format!("{}", binary_path));
|
||||||
println!("C:\\path\\to\\your\\sharpersist.exe -t schtask -c \"{}\" -n FRPersist -m add -o hourly", file_to_run);
|
print_success(format!("C:\\path\\to\\your\\sharpersist.exe -t schtask -c \"{}\" -n FRPersist -m add -o hourly", file_to_run));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user