diff --git a/pentest_tool/src/cli.rs b/pentest_tool/src/cli.rs index d891bfb..14f7507 100644 --- a/pentest_tool/src/cli.rs +++ b/pentest_tool/src/cli.rs @@ -15,6 +15,8 @@ use crate::get_user_input; use crate::menu; use crate::portscan_controls; use crate::victim_commands; +use crate::enumeration; +use crate:: tool_controls; fn help(command: Option){ @@ -38,7 +40,7 @@ fn help(command: Option){ "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;}, "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;}, "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;}, - "port scan" | "cs port scan" | "cobaltstrike port scan" | "csps" | "ps" => {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" => {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;}, "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;}, "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;}, "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;}, @@ -50,7 +52,9 @@ fn help(command: Option){ "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;}, "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.")}, "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.")}, + "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.")}, "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.")}, + "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.")}, _ => () } } @@ -86,7 +90,9 @@ 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 +update git tools | ugt | update git | ug help | ? | -h ") } @@ -195,6 +201,7 @@ pub fn run_command(cmd: String, "prune distroboxes" | "pdb" | "prune" => {let prune_thread = box_controls::clean_unused_boxes(&projects, &boxtemplate); return prune_thread}, "parse normal nmap file" | "pnnf" | "parse nmap" | "pn" => {portscan_controls::parse_normal_nmap_output(&active_project); return None;}, "show scope" | "ss" | "show s" | "s s" | "scope" => {let scope_res = info_controls::get_scope_entries(&active_project); if scope_res.is_some(){for host in scope_res.unwrap(){println!("{}", host)}}return None}, + "update git tools" | "ugt" | "update git" | "ug" => {tool_controls::update_git_tools(tools_dir); return None}, "port scan" | "ps" | "nmap" | "nmap scan" | "ns" | "nm" => {portscan_controls::run_nmap_portscan(&active_project); return None;}, "sharpersist command" | "spc" | "sharp scheduled task" | "sst" => {victim_commands::sharp_persist_command(&tools_dir); return None;}, _ => {help(None); println!("\n\n unknown command."); return None;} diff --git a/pentest_tool/src/enumeration.rs b/pentest_tool/src/enumeration.rs new file mode 100644 index 0000000..abb67be --- /dev/null +++ b/pentest_tool/src/enumeration.rs @@ -0,0 +1,33 @@ +use std::process::Command; +use std::thread::JoinHandle; +use std::thread::Thread; + +use crate::get_user_input; +use crate::Project; +use crate::open_append; + +pub fn run_dns_enumeration(project: &Project) -> Option>{ + let notes_folder = project.notes_folder.clone(); + let mut enumeration = notes_folder.clone(); + enumeration.push("enumeration.md"); + let mut enumeration_file = open_append(&enumeration); + if enumeration_file.is_none(){ + println!("error opening enumeration_file!"); + println!("try creating it manually."); + return None; + } + let mut domaind = Vec::new(); + loop{ + let domain = get_user_input("domain to add? enter DONE in all caps when you're finsihed"); + match domain.as_str(){ + "DONE" => break, + _ => domaind.push(domain), + } + } + /*let dns_handle = Thread::spawn(move || { + for domain in domaind{ + let outp + } + });*/ + return None; +} \ No newline at end of file diff --git a/pentest_tool/src/main.rs b/pentest_tool/src/main.rs index 2c6b53f..3dde8af 100644 --- a/pentest_tool/src/main.rs +++ b/pentest_tool/src/main.rs @@ -25,6 +25,8 @@ mod cli; mod menu; mod portscan_controls; mod victim_commands; +mod enumeration; +mod tool_controls; pub fn open_overwrite(path: &PathBuf) -> Option{ let file_create_res = fs::OpenOptions::new().create(true).write(true).open(path); diff --git a/pentest_tool/src/project_controls.rs b/pentest_tool/src/project_controls.rs index fde235c..bfacc08 100644 --- a/pentest_tool/src/project_controls.rs +++ b/pentest_tool/src/project_controls.rs @@ -12,7 +12,8 @@ use crate::get_user_input; use crate::Project; use crate::box_controls::make_box; -pub fn switch_project(projects: &mut Vec){ +pub fn +switch_project(projects: &mut Vec){ for project in projects.clone(){ if project.active == false{ println!("{} {}|{}", project.id, project.customer, project.project_name); @@ -281,11 +282,11 @@ pub fn remove_project(projects: &mut Vec, config_path: &PathBuf){ } else{ - println!("we need user in put here dummy!!"); + println!("no project selected! returning..."); } } else{ - println!("we need input here dummy!"); + println!("no project selected! returning..."); } } diff --git a/pentest_tool/src/tool_controls.rs b/pentest_tool/src/tool_controls.rs new file mode 100644 index 0000000..0939fef --- /dev/null +++ b/pentest_tool/src/tool_controls.rs @@ -0,0 +1,41 @@ +use std::{env::set_current_dir, path::PathBuf}; +use std::process::Command; +use walkdir::WalkDir; + + +pub fn update_git_tools(tools_dir: &PathBuf){ + let mut folders = Vec::new(); + for entry in WalkDir::new(tools_dir).max_depth(2){ + let entry = entry.unwrap(); + let path = entry.path(); + if path.is_dir(){ + folders.push(path.to_owned()); + } + } + for folder in folders{ + let cd_res = set_current_dir(&folder); + if cd_res.is_err(){ + let error = cd_res.err().unwrap(); + println!("error changing directory!"); + println!("{}", error); + } + else{ + let _cd = cd_res.unwrap(); + let git_command_res = Command::new("git") + .arg("pull") + .arg("--autostash") + .status(); + if git_command_res.is_err(){ + let error = git_command_res.err().unwrap(); + println!("error running git pull command!"); + println!("{}", error); + } + else{ + let git_command = git_command_res.unwrap(); + if git_command.success(){ + println!("successfully updated {}", folder.display()); + } + } + } + } +} \ No newline at end of file