From 761f71c6c1224d29cd832bfd6588896cde6ae869 Mon Sep 17 00:00:00 2001 From: pyro57000 Date: Tue, 21 Jan 2025 10:31:03 -0600 Subject: [PATCH] modified the install to avoid the newlines in folder names added hash cracking function, though this doesn't work yet... --- pentest_tool/src/info_controls.rs | 125 ++++++++++++++++++++++++++++++ pentest_tool/src/install.rs | 68 +++++++++++++--- pentest_tool/src/main.rs | 13 +++- pentest_tool/src/menu.rs | 8 +- 4 files changed, 199 insertions(+), 15 deletions(-) diff --git a/pentest_tool/src/info_controls.rs b/pentest_tool/src/info_controls.rs index a6c69fe..b7c1e79 100644 --- a/pentest_tool/src/info_controls.rs +++ b/pentest_tool/src/info_controls.rs @@ -1,3 +1,4 @@ +use core::hash; use std::fs; use std::fs::read_to_string; use std::io::BufReader; @@ -7,6 +8,7 @@ use std::path::PathBuf; use std::process; use std::result; use std::thread; +use std::thread::spawn; use std::time::Duration; use std::io::stdin; use walkdir::WalkDir; @@ -460,4 +462,127 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y sink.sleep_until_end(); clear().unwrap(); } +} + +pub fn crack_hashes(cracking_rig: &String, project: &Project, terminal: &String, rockyou: &String, rule: &String){ + let mut hash_file = String::new(); + println!("trying to automatically find hashes.txt file..."); + let find_result = find_file(&project.files_folder, "hashes.txt"); + if find_result.is_some(){ + hash_file = find_result.unwrap(); + println!("hash file found!"); + let mut res = String::new(); + println!("is {} the file you want to crack?", hash_file); + match stdin().read_line(&mut res){ + Ok(_r) => (), + Err(_e) => {println!("we need input here dummy! returning..."); return;} + } + res = res.to_lowercase(); + if res.contains("n"){ + println!("ooof ok, where is the file you want then?"); + loop{ + match stdin().read_line(&mut hash_file){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy! try again...") + } + } + } + if res.contains("y"){ + println!("nice! checking for cracking directory..."); + let listing_res = process::Command::new("ssh").arg(&cracking_rig).arg("'ls ~'").output(); + if listing_res.is_err(){ + println!("Error checking for cracking directory!"); + println!("Error: {}", listing_res.unwrap_err()); + } + else{ + let listing_stdout = listing_res.unwrap().stdout; + let listing = String::from_utf8_lossy(&listing_stdout); + if listing.contains("hash_cracking") == false{ + println!("no folder found, creating it..."); + let mkdir = process::Command::new("ssh").arg(&cracking_rig).arg("'mkdir ~/hash_cracking'").status(); + if mkdir.is_err(){ + println!("error creating directory! try again..."); + println!("Error: {}", mkdir.unwrap_err()); + return; + } + } + let scp_arg = format!("'scp {} {}:~/hash_cracking/{}'", &hash_file, cracking_rig, &hash_file); + let scp_res = process::Command::new("ssh").arg(&cracking_rig).arg(scp_arg).status(); + if scp_res.is_err(){ + println!("error uploading hashes file!"); + println!("Error: {}", scp_res.unwrap_err()); + return; + } + println!("nice, hach file uploaded! determining correct terminal command..."); + let terminal = terminal.split(" ").collect::>()[0]; + process::Command::new(terminal).arg("-e").arg("ssh").arg(&cracking_rig); + let mut hash_type_res = String::new(); + let mut cracking_arg = String::new(); + let mut crack_box = String::new(); + let mut crack_box_res = String::new(); + println!("do you use a distrobox to crack passwords?"); + loop{ + match stdin().read_line(&mut crack_box_res){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy, try again") + } + } + crack_box_res = crack_box_res.to_lowercase(); + if crack_box_res.contains("y"){ + println!("What's the distrobox's name?"); + loop{ + match stdin().read_line(&mut crack_box){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy, try again!") + } + } + } + else{ + crack_box = "no".to_owned(); + } + + if crack_box == "no".to_owned(){ + cracking_arg = format!("sudo hashcat -m ||MODE|| -a 0 -r {} /home/{}/hash_cracking/{} {}", rule, cracking_rig.split("@").collect::>()[1], &hash_file, &rockyou); + } + else{ + cracking_arg = format!("distrobox enter --root {} -- sudo -S hashcat -m ||MODE|| -a 0 -r {} /home/{}/hash_cracking/{} {}", crack_box, rule, cracking_rig.split("@").collect::>()[1], &hash_file, &rockyou); + } + loop{ + println!("Hash type?"); + print!(" + 1.) kerberos + 2.) ntlm + 3.) other + "); + let _res = stdin().read_line(&mut hash_type_res); + if _res.is_err(){ + println!("we need input here dummy! try again..."); + } + else{ + match hash_type_res.as_str(){ + "1\n" => {cracking_arg = cracking_arg.replace("||MODE||", "19700"); break;}, + "2\n" => {cracking_arg = cracking_arg.replace("||MODE||", "1000"); break;}, + "3\n" => {let mut mode = String::new(); + println!("code for the mode you want to use?"); + loop{ + match stdin().read_line(&mut mode){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy, try again...") + } + } + cracking_arg = cracking_arg.replace("||MODE||", &mode); + break; + }, + _ => println!("unknown selection... try again...") + } + } + } + let spaw_res = process::Command::new(terminal).arg("-e").arg("ssh").arg(&cracking_rig).arg(cracking_arg).spawn(); + if spaw_res.is_err(){ + println!("error spawing new terminal to ssh with!"); + println!("ERROR: {}", spaw_res.unwrap_err()); + } + } + } + } } \ No newline at end of file diff --git a/pentest_tool/src/install.rs b/pentest_tool/src/install.rs index 4b1ca40..a3d3988 100644 --- a/pentest_tool/src/install.rs +++ b/pentest_tool/src/install.rs @@ -11,7 +11,7 @@ use std::process; use std::process::exit; -fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, String){ +fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, String, String, String, String, String){ let mut delete_for_cleanup = config_path.clone(); delete_for_cleanup.pop(); let mut failed = false; @@ -20,6 +20,10 @@ fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, Stri let mut upcomming_files_folder = String::new(); let mut upcomming_notes_folder = String::new(); let mut tools_folder = String::new(); + let mut cracking_rig = String::new(); + let mut cracking_user = String::new(); + let mut rockyou = String::new(); + let mut rule = String::new(); while new_files_folder.is_empty() || new_notes_folder.is_empty() || tools_folder.is_empty(){ if new_files_folder.is_empty(){ println!("path to save active project files?"); @@ -56,12 +60,62 @@ fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, Stri Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...") } } + if cracking_rig.is_empty(){ + let mut have_rig = String::new(); + println!("do you have a separate computer that you can ssh into to crack passwords on?"); + match stdin().read_line(&mut have_rig){ + Ok(_r) => (), + Err(_e) => println!("we need input here dummy, try again...") + } + have_rig = have_rig.to_lowercase(); + if have_rig.contains("y"){ + println!("excellent! Whats the IP or hostname?"); + loop{ + match stdin().read_line(&mut cracking_rig){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy, try again...") + } + } + println!("user to ssh as for the cracking rig?"); + loop{ + match stdin().read_line(&mut cracking_user){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummy, try again...") + } + } + println!("Path to rockyou.txt on the cracking rig?"); + loop{ + match stdin().read_line(&mut rockyou){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummyu try again...") + } + } + println!("Path to one rule to rule them all on the cracking rig?"); + loop{ + match stdin().read_line(&mut rule){ + Ok(_r) => break, + Err(_e) => println!("we need input here dummyu try again...") + } + } + } + else if have_rig.contains("n"){ + println!("ooof ok freeloader"); + cracking_rig = "n".to_owned(); + } + } } + new_files_folder = new_files_folder.trim_end().to_owned(); + new_notes_folder = new_notes_folder.trim_end().to_owned(); + upcomming_files_folder = upcomming_files_folder.trim_end().to_owned(); + upcomming_notes_folder = upcomming_notes_folder.trim_end().to_owned(); + tools_folder = tools_folder.trim_end().to_owned(); + cracking_rig = cracking_rig.trim_end().to_owned(); + cracking_user = cracking_user.trim_end().to_owned(); let new_files_path = PathBuf::from(&new_files_folder); let new_notes_path = PathBuf::from(&new_notes_folder); let upcomming_files_path = PathBuf::from(&upcomming_files_folder); let upcomming_notes_path = PathBuf::from(&upcomming_notes_folder); - let tools_path = PathBuf::from(&tools_folder); + let tools_path = PathBuf::from(&tools_folder.trim_end()); if new_files_path.exists() == false{ println!("active project file folder does not exist, creating..."); match fs::create_dir_all(&new_files_folder){ @@ -106,7 +160,7 @@ fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, Stri } exit(1); } - return (new_files_folder, new_notes_folder, tools_folder, upcomming_files_folder, upcomming_notes_folder); + return (new_files_folder, new_notes_folder, tools_folder, upcomming_files_folder, upcomming_notes_folder, cracking_rig, cracking_user, rockyou, rule); } @@ -156,7 +210,7 @@ pub fn install(config_path: &PathBuf){ else{ _terminal_command = _terminal_commands[terminal_response.trim_end()].to_owned(); } - let (files_response, notes_response, tools_response, project_folder_path, project_note_path) = setup_folders(&config_path); + let (files_response, notes_response, tools_response, project_folder_path, project_note_path, cracking_rig, cracking_user, rockyou, rule) = setup_folders(&config_path); print!(" This tool is mainly to handle distrobox creation and usage. It's expecting you to have a distrobox that you will use as a template. @@ -175,7 +229,7 @@ Do you have a distrobox set up to function as your template for all new projects let _list = process::Command::new("distrobox").arg("list").arg("--root").status(); println!("distrobox template name?"); std::io::stdin().read_line(&mut template_name).unwrap(); - let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}\nbox_template:{}\nterminal:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end(),template_name.trim_end(), _terminal_command.trim_end()); + let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}\nbox_template:{}\nterminal:{}\ncracking_rig:{}@{}\nrockyou_location:{}\nrule_location:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end(),template_name.trim_end(), _terminal_command.trim_end(), cracking_user.trim_ascii_end(), cracking_rig.trim_end(), rockyou.trim_end(), rule.trim_end()); config_file.write_all(config_string.as_bytes()).expect("error writing to config file"); let default_projectline = format!("default:default:{}:{}:yes:{}", ¬es_response.trim_end(), &files_response.trim_end(), &template_name.trim_end()); projects_conf_file.write_all(default_projectline.as_bytes()).expect("error writing default project line"); @@ -195,10 +249,6 @@ Do you have a distrobox set up to function as your template for all new projects install_path.push("new_projects.conf"); password_spray_template_path.push("passwordspray.md"); let password_spray_template_path = install_path.clone(); - let mut conf_file = fs::File::create(install_path).expect("error creating config file"); - write!(conf_file, "project_folder_path:{} -project_notes_path:{} -", project_folder_path.trim_end(), project_note_path.trim_end()).expect("error writing config file"); let mut passpray_file = fs::File::create(password_spray_template_path).expect("error creating passwordspray file"); write!(passpray_file, " - [ ] useraspass diff --git a/pentest_tool/src/main.rs b/pentest_tool/src/main.rs index 857cdd7..e8f7fcd 100644 --- a/pentest_tool/src/main.rs +++ b/pentest_tool/src/main.rs @@ -53,6 +53,9 @@ fn main() { let mut tools_folder = PathBuf::new(); let mut terminal_command = String::new(); let mut box_template = String::new(); + let mut cracking_rig = String::new(); + let mut rockyou = String::new(); + let mut rule = String::new(); println!("\nconfig already generated\nloading config file...\n"); let settings_string = fs::read_to_string(&config_path).expect("error reading config file"); let settings: Vec<&str> = settings_string.split("\n").collect(); @@ -65,6 +68,9 @@ fn main() { "tools_folder" => tools_folder.push(setting_vec[1].trim_end()), "box_template" => box_template = setting_vec[1].trim_end().to_owned(), "terminal" => terminal_command = setting_vec[1].trim_end().to_owned(), + "cracking_rig" => cracking_rig = setting_vec[1].trim_end().to_owned(), + "rockyou_location" => rockyou = setting_vec[1].trim_ascii_end().to_owned(), + "rule_location" => rule = setting_vec[1].trim_end().to_owned(), _ => println!("error unknown setting: {}", setting_vec[0]) } } @@ -74,12 +80,13 @@ fn main() { Note Folders: {} Tools Folder: {} distrobox template: {} - terminal_command: {}\n -", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template, terminal_command); + terminal_command: {} + cracking_rig: {}\n +", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template, terminal_command, cracking_rig); println!("loading project configs..."); let projects = project_controls::get_projects(&config_path); println!("Enter to start main menu"); let mut enter = String::new(); std::io::stdin().read_line(&mut enter).unwrap(); - menu::main_menu(projects, config_path, &project_base_folder, &project_base_notes, &tools_folder, box_template, terminal_command); + menu::main_menu(projects, config_path, &project_base_folder, &project_base_notes, &tools_folder, box_template, terminal_command, cracking_rig, rockyou, rule); } diff --git a/pentest_tool/src/menu.rs b/pentest_tool/src/menu.rs index 62433b5..f3b5ffb 100644 --- a/pentest_tool/src/menu.rs +++ b/pentest_tool/src/menu.rs @@ -31,7 +31,7 @@ fn get_active_project(projects: &Vec) -> &Project{ return active_project } -pub fn main_menu(mut projects: Vec, config_path: PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String, terminal: String){ +pub fn main_menu(mut projects: Vec, config_path: PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String, terminal: String, cracking_rig: String, rockyou: String, rule: String){ let mut loopize = true; let mut new_id = next_project_id(&config_path); loop { @@ -126,7 +126,8 @@ Year: {} 16.) build portscan command from scope in notes 17.) Stop All Distroboxes 18.) Password Spray (will print password to spray, and wait the obervation window time) - 19.) Quit Application + 19.) crack password hashes on your cracking rig + 20.) Quit Application \n", active_project.customer, active_project.project_name, active_project.files_folder.display(), active_project.notes_folder.display(), active_project.boxname, terminal, season, year); std::io::stdin().read_line(&mut response).expect("error getting menu input"); clear().expect("error clearing screen"); @@ -152,7 +153,8 @@ Year: {} "16" => info_controls::build_cs_portscan_cmd(&active_project), "17" => box_controls::stop_all_boxes(&projects), "18" => info_controls::password_spray_help(&active_project, season, lseason, year, &tools_dir, &config_path), - "19" => {project_controls::save_projects(&projects, &config_path); + "19" => info_controls::crack_hashes(&cracking_rig, &active_project, &terminal, &rockyou, &rule), + "20" => {project_controls::save_projects(&projects, &config_path); let mut stop = String::new(); println!("stop all boxes?\ny/n"); std::io::stdin().read_line(&mut stop).unwrap();