diff --git a/pentest_tool/src/main.rs b/pentest_tool/src/main.rs index bba8092..bd79ea6 100644 --- a/pentest_tool/src/main.rs +++ b/pentest_tool/src/main.rs @@ -3,9 +3,7 @@ use std::fs; use std::io::Write; use std::path::PathBuf; use std::process; -use std::time; -use std::time::Duration; -use std::time::SystemTime; +use std::str::FromStr; use clearscreen::clear; use directories::UserDirs; use clearscreen; @@ -16,8 +14,6 @@ struct Project{ project_name: String, notes_folder: PathBuf, files_folder: PathBuf, - activativation_time: SystemTime, - hour_count: Duration, active: bool, boxname: String, id: i32, @@ -29,22 +25,45 @@ fn install(config_path: &PathBuf){ let mut config_folder_path: PathBuf = config_path.clone(); config_folder_path.pop(); let mut projects_conf_path = config_folder_path.clone(); + let del_on_fail = config_folder_path.clone(); projects_conf_path.push("projects.conf"); fs::create_dir_all(config_folder_path).expect("error creating config dir"); let mut config_file = fs::File::create(config_path).expect("error creating file"); let mut projects_conf_file = fs::File::create(projects_conf_path).expect("error creating projects config file"); - projects_conf_file.write_all(b"customer:name:time").expect("error writing default project info"); + projects_conf_file.write_all(b"customer:name:notes:files:active:box_name\n").expect("error writing default project info"); let mut notes_response = String::new(); let mut files_response = String::new(); let mut tools_response = String::new(); + let mut template_name = String::new(); + let mut have_template = String::new(); println!("path to save project notes?"); std::io::stdin().read_line(&mut notes_response).unwrap(); println!("path to save project files?"); std::io::stdin().read_line(&mut files_response).unwrap(); println!("path to folder with your custom tools?"); std::io::stdin().read_line(&mut tools_response).unwrap(); + 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. +Do you have a distrobox set up to function as your template for all new projects? +"); + std::io::stdin().read_line(&mut have_template).unwrap(); + if have_template.contains("n"){ + println!("please set up a distrobox with root as a template and re-run this tool"); + println!("example distrobox setup command:"); + println!("distrobox create --root --image archlinux --name template"); + println!("then enter that distrobox and install all the tools you want and do what ever setup you need"); + println!("and re-run this tool."); + process::Command::new("rm").arg(del_on_fail).spawn().expect("ERROR deleting config folder, please manually clean up"); + std::process::exit(1); + } + 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:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.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"); println!("config file generated and saved to {}\n", config_path.display()); println!("please make sure to install distrobox:\nhttps://github.com/89luca89/distrobox\n\nthis will require either docker or podman as well.\n\n"); println!("please rerun the program"); @@ -52,7 +71,7 @@ fn install(config_path: &PathBuf){ } -fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut PathBuf) -> Vec{ +fn get_projects(config_path: &mut PathBuf) -> Vec{ config_path.pop(); config_path.push("projects.conf"); let mut projects = Vec::new(); @@ -66,22 +85,17 @@ fn get_projects(base_notes: &PathBuf, base_files: &PathBuf, config_path: &mut Pa let settings: Vec<&str> = line.split(":").collect(); let customer = settings[0].to_owned(); let project = settings[1].to_owned(); - let folder_name = format!("{}/{}", customer, project); - let mut notes_folder = base_notes.clone(); - let mut project_folder = base_files.clone(); - notes_folder.push(&folder_name); - project_folder.push(&folder_name); - let hours_count:u64 = settings[3].trim_end().parse().expect("error converting to u64"); - let secs_count = hours_count * 60; - let hours = Duration::from_secs(secs_count); + let notes_string = settings[2].to_owned(); + let folder_string = settings[3].to_owned(); + let notes_folder = PathBuf::from_str(¬es_string.trim_end()).expect("error reading notes string"); + let project_folder = PathBuf::from_str(&folder_string.trim_end()).expect("error reading folding sering"); let mut active = false; - let boxname = settings[4].to_owned(); - if settings[2] == "yes"{ + let boxname = settings[5].to_owned(); + if settings[4] == "yes"{ env::set_var("CURRENT_PROJECT_BOX", boxname.clone()); active = true; } - let time = SystemTime::now(); - let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, activativation_time: time, hour_count: hours, active: active, id: first, boxname: boxname}; + let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname}; println!("{} {} LOADED!", &new_project.customer, &new_project.project_name); projects.push(new_project); } @@ -127,16 +141,15 @@ fn save_projects(projects: &Vec, config_path: &PathBuf){ save_file_path.pop(); save_file_path.push("projects.conf"); let mut save_file = fs::File::create(save_file_path).expect("error creating save_file"); - save_file.write_all(b"customer:name:active:hours:box_name\n").expect("error writing first line to file"); + save_file.write_all(b"customer:name:notes:files:active:time:box_name\n").expect("error writing first line to file"); for project in projects{ - let default = format!{"{}:{}:", project.customer, project.project_name}; + let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()}; let mut _outline = String::new(); if project.active{ - let hours = project.hour_count.as_secs()/60 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/60; - _outline = format!("{}yes:{}:{}\n", default, hours, project.boxname); + _outline = format!("{}yes:{}\n", default, project.boxname); } else{ - _outline = format!("{}no:{}:{}\n", default, project.hour_count.as_secs()/60, project.boxname); + _outline = format!("{}no:{}\n", default, project.boxname); } save_file.write_all(_outline.as_bytes()).expect("error writing outline"); } @@ -231,6 +244,10 @@ fn new_project(projects: &mut Vec, project_dir: &PathBuf, notes_dir: &P else{ println!("failed to copy the notes folder, try to move it manually!"); } + new_project_dir.push(&customer_name); + new_note_dir.push(&customer_name); + new_project_dir.push(&project_name); + new_note_dir.push(&project_name); } else{ @@ -240,9 +257,12 @@ fn new_project(projects: &mut Vec, project_dir: &PathBuf, notes_dir: &P new_note_dir.push(&project_name); fs::create_dir_all(&new_project_dir).expect("error creating new files folder"); fs::create_dir_all(&new_note_dir).expect("error creating new notes folder"); - } let box_name = format!("atarchbox_{}", customer_name); + let mut box_name_path = new_project_dir.clone(); + box_name_path.push("boxname"); + let mut box_name_file = fs::File::create(box_name_path).expect("Error creating box name file"); + box_name_file.write_all(&box_name.as_bytes()).expect("error writing boxname to box file"); let pentest_volume = format!("{}:/pentest:rw", new_project_dir.display()); let toold_volume = format!("{}:/tools:rw", tools_dir.display()); println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name); @@ -265,6 +285,13 @@ fn new_project(projects: &mut Vec, project_dir: &PathBuf, notes_dir: &P .arg("enter") .arg("--root") .arg(&box_name) + .arg("--") + .arg("sudo") + .arg("-s") + .arg("ln") + .arg("-sf") + .arg("/pentest/boxname") + .arg("/etc/boxname") .status() .expect("error getting response from distrobox start"); if distrobox_start_result.success(){ @@ -281,8 +308,6 @@ fn new_project(projects: &mut Vec, project_dir: &PathBuf, notes_dir: &P project_name: project_name.trim_end().to_owned(), notes_folder: new_note_dir, files_folder:new_project_dir, - activativation_time: SystemTime::now(), - hour_count: Duration::new(1, 1), active: false, id: new_id, boxname: box_name, @@ -307,11 +332,12 @@ fn remove_project(projects: &mut Vec){ if project.id == remove_id{ println!("will remove {} {}", project.customer, project.project_name); project_set = true; + let _distrobox_stop_status = process::Command::new("distrobox").arg("stop").arg("--root").arg(&project.boxname).status().expect("error stopping distrobox"); let distrobox_rm_status = process::Command::new("distrobox") .arg("rm") .arg("--root") .arg("-f") - .arg(project.boxname) + .arg(&project.boxname) .status().expect("error calling distrobox"); if distrobox_rm_status.success(){ println!("Distrobox Removal Successful!!!"); @@ -410,14 +436,6 @@ fn print_report_information(project: Project){ } -fn reset_hour_counters(projects: &mut Vec){ - println!("Clearing Counters, please esure these times are in sales force..."); - for project in projects{ - println!("{} {}: {}", project.customer, project.project_name, project.hour_count.as_secs()/60/60); - project.hour_count = Duration::ZERO; - } -} - fn project_standalone_terminal(project: Project){ @@ -430,6 +448,32 @@ fn project_inline_terminal(project: Project){ } +fn gnerate_userpass(project: &Project){ + let mut outlines = Vec::new(); + let mut notes_file = project.notes_folder.clone(); + notes_file.push("l00t/creds.md"); + let loot_string = fs::read_to_string(notes_file).expect("error reading creds note"); + let clear_text = loot_string.split("# hashed").collect::>()[0]; + let clear_text_table = clear_text.split("| ----------------------------------- | ------------- | ----------------------------- |").collect::>()[1]; + let table_vec: Vec<&str> = clear_text_table.split("\n").collect(); + for line in table_vec{ + if line.len() > 1{ + let split_line: Vec<&str> = line.split("|").collect(); + let user = split_line[2].trim_end().trim_start(); + let password = split_line[3].trim_end().trim_start(); + let outline = format!("{}:{}\n", user, password); + outlines.push(outline); + } + } + let mut out_file_path = project.files_folder.clone(); + out_file_path.push("working/userpass_fromnotes.txt"); + let mut out_file = fs::File::create(out_file_path).expect("error creating userpass file"); + for line in outlines{ + out_file.write_all(line.as_bytes()).expect("error writing to userpass file"); + } +} + + fn main_menu(mut projects: Vec, config_path: &PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String){ let mut loopize = true; loop { @@ -487,27 +531,24 @@ NOTE SAVE PROJECT INFO BEFORE STOPPING THE APPLICATION, OR HOUR TRACKIGN WON'T B NOTE OPTION 10 WILL SAVE YOUR PROJECTS BEFORE QUITTING Current Project: {} {} -Current Minutes: {} minutes Main Menu: 1 .) Show Active Project 2 .) List Projects 3 .) Switch Active Project - 4 .) Print Active Project Time - 5 .) Print All Proejct Times - 6 .) create new project with Pyro's default tool - 7 .) Save Project Information - 8 .) Import New Project - and setup new Distrobox - 9 .) Remove Project - 10.) Open A New Terminal in Current Active Project - 11.) Open A Terminal In this windows for the current active project - 12.) Open Project Files Folder In Dolphin - 13.) Open Project Notes Folder In Dolphin - 14.) Print Project Info For Report - 15.) Stop All Distroboxes - 16.) Reset Hour Counters - 17.) Quit Application -\n", active_project.customer, active_project.project_name, SystemTime::now().duration_since(active_project.activativation_time).unwrap().as_secs() / 60); + 4 .) create new project with Pyro's default tool + 5 .) Save Project Information + 6 .) Import New Project - and setup new Distrobox + 7 .) Remove Project + 8 .) Open A New Terminal in Current Active Project + 9 .) Open A Terminal In this windows for the current active project + 10.) Open Project Files Folder In Dolphin + 11.) Open Project Notes Folder In Dolphin + 12.) generate userpass file from your obsidian notes + 13.) Print Project Info For Report + 14.) Stop All Distroboxes + 15.) Quit Application +\n", active_project.customer, active_project.project_name); std::io::stdin().read_line(&mut response).expect("error getting menu input"); clear().expect("error clearing screen"); match response.as_str().trim_end(){ @@ -517,30 +558,18 @@ Current Minutes: {} minutes println!("++{}|{}++",project.customer ,project.project_name)} println!("++++++++++++++++++++")}, "3" => switch_project(&mut projects), - "4" => println!("current Hour Count: {}", active_project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(active_project.activativation_time).expect("error caclucating hours").as_secs()/3600), - "5" => {println!("++++++++++++++++++++"); - for project in &projects{ - if project.active == true{ - println!("++{} {}: {}++", project.customer, project.project_name, project.hour_count.as_secs()/3600 + time::SystemTime::now().duration_since(project.activativation_time).expect("error caclucating hours").as_secs()/3600); - } - else{ - println!("++{} {}:{}++", project.customer, project.project_name, project.hour_count.as_secs()/3600); - } - } - println!("++++++++++++++++++++") - }, - "6" => start_pentest(), - "7" => save_projects(&projects, &config_path), - "8" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate), - "9" => remove_project(&mut projects), - "10" => project_standalone_terminal(active_project.clone()), - "11" => project_inline_terminal(active_project.clone()), - "12" => open_in_dolphin("files", active_project.clone()), - "13" => open_in_dolphin("notes", active_project.clone()), - "14" => print_report_information(active_project.clone()), - "15" => stop_all_boxes(&projects), - "16" => reset_hour_counters(&mut projects), - "17" => {save_projects(&projects, &config_path); + "4" => start_pentest(), + "5" => save_projects(&projects, &config_path), + "6" => new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate), + "7" => remove_project(&mut projects), + "8" => project_standalone_terminal(active_project.clone()), + "9" => project_inline_terminal(active_project.clone()), + "10" => open_in_dolphin("files", active_project.clone()), + "11" => open_in_dolphin("notes", active_project.clone()), + "12" => gnerate_userpass(&active_project), + "13" => print_report_information(active_project.clone()), + "14" => stop_all_boxes(&projects), + "15" => {save_projects(&projects, &config_path); let mut stop = String::new(); println!("stop all boxes?\ny/n"); std::io::stdin().read_line(&mut stop).unwrap(); @@ -613,7 +642,7 @@ fn main() { distrobox template: {}\n ", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template); println!("loading project configs..."); - let projects = get_projects(&project_base_notes, &project_base_folder, &mut config_path); + let projects = get_projects(&mut config_path); println!("Enter to start main menu"); let mut enter = String::new(); std::io::stdin().read_line(&mut enter).unwrap();