5 Commits
2.1.6 ... 2.1.8

Author SHA1 Message Date
pyro57000
4dba68cdcf refactor for upcomming project management 2025-03-05 14:56:17 -06:00
pyro57000
7765640e0e refactor for managing upcoming and current
projects!
2025-03-05 14:55:56 -06:00
pyro57000
d50625167b added --init to distrobox creation
this will allow us to do things like docker
inside of distroboxes
2025-02-20 13:20:02 -06:00
pyro57000
a798e39461 did the distrobox stuff 2025-02-20 13:09:12 -06:00
pyro57000
4e1ab4c30f split making a distrobox into its own function
this will allow us to write more functions
like the newly added one to re-create the
current project's distrobox
2025-02-20 13:08:20 -06:00
6 changed files with 479 additions and 264 deletions

View File

@@ -1,4 +1,11 @@
use std::process;
use std::{path::PathBuf, process};
use std::env;
use std::fs;
use std::io::stdin;
use std::io::Write;
use std::thread;
use std::time::Duration;
use std::str::FromStr;
use crate::Project;
pub fn stop_all_boxes(projects: &Vec<Project>){
@@ -63,3 +70,71 @@ pub fn project_standalone_terminal(project: Project, mut terminal: String){
pub fn project_inline_terminal(project: Project){
process::Command::new("distrobox").arg("enter").arg("--root").arg(project.boxname).arg("--").arg("script").arg("-a").arg("-B").arg("/pentest/working/terminal.log").status().expect("error opeing konsole");
}
pub fn make_box(project: &Project, tools_dir: &PathBuf, boxtemplate: &String, new: bool){
if !new{
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-rm")
.arg("--root")
.arg("-f")
.arg(&project.boxname)
.status().expect("error calling distrobox");
if distrobox_rm_status.success(){
println!("Distrobox Removal Successful!!!");
}
else{
println!("Distrobox Removal Failed, manual removal required!");
}
}
let mut box_name_path = project.files_folder.clone();
let mut box_name = format!("atarchbox_{}", &project.customer);
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", &project.files_folder.display());
let toold_volume = format!("{}:/tools:rw", tools_dir.display());
println!("distrobox create --root --init --unshare-all --clone {} --volume {} --volume {} --name {}", boxtemplate, toold_volume, pentest_volume, box_name);
let distrobox_result = process::Command::new("distrobox")
.arg("create")
.arg("--root")
.arg("--init")
.arg("--unshare-all")
.arg("--clone")
.arg(boxtemplate)
.arg("--volume")
.arg(&toold_volume)
.arg("--volume")
.arg(&pentest_volume)
.arg("--name")
.arg(&box_name)
.status()
.expect("error getting distrobox status");
if distrobox_result.success(){
println!("we made a distrobox oh boy!");
let distrobox_start_result = process::Command::new("distrobox")
.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(){
println!("distrobox was started as well!!!! good job me!");
}
else{
println!("ooof did not start successfully try entering it yoruself");
println!("distrobox enter --rrot {} -- sudo -s ln -sf /pentest/boxname /etc/boxname", &box_name);
}
}
else{
println!("ooof distrobox did not work.... try creating it yourself");
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, &toold_volume, &pentest_volume, &box_name);
println!("distrobox enter --rrot {} -- sudo -s ln -sf /pentest/boxname /etc/boxname", &box_name);
}
}

View File

@@ -101,6 +101,8 @@ fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, Stri
else if have_rig.contains("n"){
println!("ooof ok freeloader");
cracking_rig = "n".to_owned();
rule = "n".to_owned();
rockyou = "n".to_owned();
}
}
}
@@ -111,10 +113,10 @@ fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, Stri
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 new_files_path = PathBuf::from(&new_files_folder.trim_end());
let new_notes_path = PathBuf::from(&new_notes_folder.trim_end());
let upcomming_files_path = PathBuf::from(&upcomming_files_folder.trim_end());
let upcomming_notes_path = PathBuf::from(&upcomming_notes_folder.trim_end());
let tools_path = PathBuf::from(&tools_folder.trim_end());
if new_files_path.exists() == false{
println!("active project file folder does not exist, creating...");
@@ -188,7 +190,7 @@ pub fn install(config_path: &PathBuf){
println!("bell notification tone sucessfully downloaded!");
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:notes:files:active:box_name\n").expect("error writing default project info");
projects_conf_file.write_all(b"customer:name:notes:files:active:box_name:stage\n").expect("error writing default project info");
let mut terminal_response = String::new();
let mut template_name = String::new();
let mut have_template = String::new();
@@ -229,9 +231,9 @@ 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:{}\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());
let config_string = format!("Project_files:{}\nProject_notes:{}\ntools_folder:{}\nupcoming_files:{}\nupcoming_notes:{}\nbox_template:{}\nterminal:{}\ncracking_rig:{}@{}\nrockyou_location:{}\nrule_location:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end(), &project_folder_path.trim_end(), &project_note_path.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:{}", &notes_response.trim_end(), &files_response.trim_end(), &template_name.trim_end());
let default_projectline = format!("default:default:{}:{}:yes:{}:current", &notes_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!("active project folders: {}", &files_response);
println!("upcomming project folders: {}", &project_folder_path);
@@ -248,7 +250,8 @@ Do you have a distrobox set up to function as your template for all new projects
let mut password_spray_template_path = install_path.clone();
install_path.push("new_projects.conf");
password_spray_template_path.push("passwordspray.md");
let password_spray_template_path = install_path.clone();
let pass_file_config_line = format!("\npass_file:{}", password_spray_template_path.display());
config_file.write_all(pass_file_config_line.as_bytes()).expect("error writing password spray setting to config file");
let mut passpray_file = fs::File::create(password_spray_template_path).expect("error creating passwordspray file");
write!(passpray_file, "
- [ ] useraspass

View File

@@ -1,5 +1,6 @@
use std::path::PathBuf;
use std::{io::stdin, path::PathBuf};
use directories::UserDirs;
use reqwest::Response;
use std::fs;
#[derive(Clone)]
@@ -10,6 +11,7 @@ pub struct Project{
pub files_folder: PathBuf,
pub active: bool,
pub boxname: String,
pub stage: String,
pub id: i32,
}
@@ -20,6 +22,22 @@ mod box_controls;
mod info_controls;
mod start_pentest;
pub fn get_user_input(prompt: &str) -> String{
let mut response = String::new();
loop{
println!("{}", prompt);
let result = stdin().read_line(&mut response);
if result.is_err(){
println!("we need input here dummy! try again...");
}
else{
result.unwrap();
break;
}
}
return response.trim_end().to_owned();
}
fn main() {
print!("
@@ -56,6 +74,9 @@ fn main() {
let mut cracking_rig = String::new();
let mut rockyou = String::new();
let mut rule = String::new();
let mut upcoming_files = PathBuf::new();
let mut upcoming_notes = PathBuf::new();
let mut pass_spray_file = PathBuf::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();
@@ -66,11 +87,14 @@ fn main() {
"Project_files" => project_base_folder.push(setting_vec[1].trim_end()),
"Project_notes" => project_base_notes.push(setting_vec[1].trim_end()),
"tools_folder" => tools_folder.push(setting_vec[1].trim_end()),
"upcoming_files" => upcoming_files.push(setting_vec[1].trim_end()),
"upcoming_notes" => upcoming_notes.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_end().to_owned(),
"rule_location" => rule = setting_vec[1].trim_end().to_owned(),
"pass_file"=> pass_spray_file.push(setting_vec[1]),
_ => println!("error unknown setting: {}", setting_vec[0])
}
}
@@ -82,11 +106,13 @@ fn main() {
distrobox template: {}
terminal_command: {}
cracking_rig: {}\n
", project_base_folder.display(), project_base_notes.display(), tools_folder.display(), box_template, terminal_command, cracking_rig);
upcoming project folders: {}
upcoming project notes: {}
", &project_base_folder.display(), &project_base_notes.display(), &tools_folder.display(), box_template, terminal_command, cracking_rig, &upcoming_files.display(), &upcoming_notes.display());
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, cracking_rig, rockyou, rule);
menu::main_menu(projects, config_path, &project_base_folder, &project_base_notes, &tools_folder, box_template, terminal_command, cracking_rig, rockyou, rule, &upcoming_files, &upcoming_notes, &pass_spray_file);
}

View File

@@ -1,3 +1,6 @@
use std::clone;
use std::path;
use std::path::Path;
use std::path::PathBuf;
use std::process::exit;
use chrono::Datelike;
@@ -31,7 +34,7 @@ fn get_active_project(projects: &Vec<Project>) -> &Project{
return active_project
}
pub fn main_menu(mut projects: Vec<Project>, config_path: PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String, terminal: String, cracking_rig: String, rockyou: String, rule: String){
pub fn main_menu(mut projects: Vec<Project>, config_path: PathBuf, base_files: &PathBuf, base_notes: &PathBuf, tools_dir: &PathBuf, boxtemplate: String, terminal: String, cracking_rig: String, rockyou: String, rule: String, upcoming_files: &PathBuf, upcoming_notes: &PathBuf, password_spray_file: &PathBuf){
let mut loopize = true;
let mut new_id = next_project_id(&config_path);
loop {
@@ -99,6 +102,8 @@ pub fn main_menu(mut projects: Vec<Project>, config_path: PathBuf, base_files: &
NOTE OPTION 18 WILL SAVE YOUR PROJECTS BEFORE QUITTING
base prject folder: {}
upcoming project folder: {}
Current Project: {} {}
Working Folder: {}
Notes Folder: {}
@@ -115,46 +120,52 @@ Year: {}
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.) run pyro's initail enum script on a nessus csv for the current project
14.) Print Project Info For Report
15.) Build host discovery cmd command from scope in notes
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.) 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);
8 .) Print upcoming projects
9. ) promote project from upcoming to current
10.) Open A New Terminal in Current Active Project
11.) Open A Terminal In this windows for the current active project
12.) re-create the distrobox for the current active project
13.) Open Project Files Folder In Dolphin
14.) Open Project Notes Folder In Dolphin
15.) generate userpass file from your obsidian notes
16.) run pyro's initail enum script on a nessus csv for the current project
17.) Print Project Info For Report
18.) Build host discovery cmd command from scope in notes
19.) build portscan command from scope in notes
20.) Stop All Distroboxes
21.) Password Spray (will print password to spray, and wait the obervation window time)
22.) crack password hashes on your cracking rig
23.) Quit Application
\n",&base_files.display(), &upcoming_files.display(), 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");
match response.as_str().trim_end(){
"1" => println!("\nclient: {}\n\nproject: {}\n\nbox: {}\n\nproject files: {}\n\nproject notes: {}\n", active_project.customer ,active_project.project_name, active_project.boxname, active_project.files_folder.display(), active_project.notes_folder.display()),
"2" => {println!("+++++++++++++++++++++");
for project in &projects{
println!("++{}|{}++",project.customer ,project.project_name)}
println!("++Customer: {}|Project name: {}|Stage: {}++",project.customer ,project.project_name, project.stage)}
println!("++++++++++++++++++++")},
"3" => project_controls::switch_project(&mut projects),
"4" => start_pentest::start_pentest(&config_path),
"4" => {new_id = new_id + 1; start_pentest::start_pentest(&config_path, &mut projects, new_id, upcoming_files, upcoming_notes, &boxtemplate, password_spray_file)},
"5" => project_controls::save_projects(&projects, &config_path),
"6" => {new_id = new_id + 1; project_controls::new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate, &config_path, new_id)},
"6" => {new_id = new_id + 1; project_controls::new_project(&mut projects, &base_files, &base_notes, &tools_dir, &boxtemplate, &config_path, new_id, &upcoming_files, &upcoming_notes)},
"7" => project_controls::remove_project(&mut projects, &config_path),
"8" => box_controls::project_standalone_terminal(active_project.clone(), terminal.clone()),
"9" => box_controls::project_inline_terminal(active_project.clone()),
"10" => info_controls::open_in_dolphin("files", active_project.clone()),
"11" => info_controls::open_in_dolphin("notes", active_project.clone()),
"12" => info_controls::generate_userpass(&active_project),
"13" => info_controls::run_initial_enum(&active_project),
"14" =>info_controls::print_report_information(active_project.clone()),
"15" => info_controls::build_cmd_for_host_discovery(&active_project),
"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" => info_controls::crack_hashes(&cracking_rig, &active_project, &terminal, &rockyou, &rule),
"20" => {project_controls::save_projects(&projects, &config_path);
"8" => project_controls::print_upcoming_projects(&projects),
"9" => project_controls::promote_project(&mut projects, &config_path, base_files, base_notes, tools_dir, &boxtemplate),
"10" => box_controls::project_standalone_terminal(active_project.clone(), terminal.clone()),
"11" => box_controls::project_inline_terminal(active_project.clone()),
"12" => box_controls::make_box(&active_project, &tools_dir, &boxtemplate, false),
"13" => info_controls::open_in_dolphin("files", active_project.clone()),
"14" => info_controls::open_in_dolphin("notes", active_project.clone()),
"15" => info_controls::generate_userpass(&active_project),
"16" => info_controls::run_initial_enum(&active_project),
"17" => info_controls::print_report_information(active_project.clone()),
"18" => info_controls::build_cmd_for_host_discovery(&active_project),
"19" => info_controls::build_cs_portscan_cmd(&active_project),
"20" => box_controls::stop_all_boxes(&projects),
"21" => info_controls::password_spray_help(&active_project, season, lseason, year, &tools_dir, &config_path),
"22" => info_controls::crack_hashes(&cracking_rig, &active_project, &terminal, &rockyou, &rule),
"23" => {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();

View File

@@ -7,7 +7,9 @@ use std::process;
use std::thread;
use std::time::Duration;
use std::str::FromStr;
use crate::Project;
use crate::box_controls::make_box;
pub fn switch_project(projects: &mut Vec<Project>){
for project in projects.clone(){
@@ -46,30 +48,62 @@ pub fn save_projects(projects: &Vec<Project>, 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:notes:files:active:time:box_name\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{
let default = format!{"{}:{}:{}:{}:", project.customer, project.project_name, project.notes_folder.display(), project.files_folder.display()};
let mut _outline = String::new();
if project.active{
if active_set == false{
_outline = format!("{}yes:{}\n", default, project.boxname);
_outline = format!("{}yes:{}:{}\n", default, project.boxname, project.stage);
active_set = true;
}
}
else{
_outline = format!("{}no:{}\n", default, project.boxname);
_outline = format!("{}no:{}:{}\n", default, project.boxname, project.stage);
}
save_file.write_all(_outline.as_bytes()).expect("error writing outline");
}
}
pub fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &PathBuf, tools_dir: &PathBuf, boxtemplate: &String, config_path: &PathBuf, new_id: i32){
let mut new_project_dir = project_dir.clone();
let mut new_note_dir = notes_dir.clone();
pub fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir: &PathBuf, tools_dir: &PathBuf, boxtemplate: &String, config_path: &PathBuf, new_id: i32, upcoming_files: &PathBuf, upcoming_notes: &PathBuf){
let mut new_project_dir = PathBuf::new();
let mut new_note_dir = PathBuf::new();
let mut existing_folders = String::new();
let mut customer_name = String::new();
let mut project_name = String::new();
let mut project_stage = String::new();
loop{
let mut stage_response = String::new();
println!("what stage is this project in?");
print!("
1.) current
2.) upcoming
");
let stage_result = stdin().read_line(&mut stage_response);
if stage_result.is_err(){
println!("we need input here dummy, try again...");
}
else{
match &stage_response.trim_end(){
&"1" => {project_stage = "current".to_owned(); break;},
&"2" => {project_stage = "upcoming".to_owned(); break;},
_ => println!("unknown option, try again...")
}
}
}
if project_stage.contains("current"){
new_project_dir = project_dir.clone();
new_note_dir = notes_dir.clone();
}
else if project_stage.contains("upcoming"){
new_project_dir = upcoming_files.clone();
new_note_dir = upcoming_notes.clone();
}
else{
println!("unknown stage!!")
}
println!("{}", new_project_dir.display());
println!("do you have an existing notes and folder structure to copy over?\ny/n");
std::io::stdin().read_line(&mut existing_folders).unwrap();
if existing_folders.contains("y") || existing_folders.contains("Y"){
@@ -183,54 +217,6 @@ pub fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir
}
thread::sleep(Duration::from_secs(2));
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);
let distrobox_result = process::Command::new("distrobox")
.arg("create")
.arg("--root")
.arg("--clone")
.arg(boxtemplate)
.arg("--volume")
.arg(&toold_volume)
.arg("--volume")
.arg(&pentest_volume)
.arg("--name")
.arg(&box_name)
.status()
.expect("error getting distrobox status");
if distrobox_result.success(){
println!("we made a distrobox oh boy!");
let distrobox_start_result = process::Command::new("distrobox")
.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(){
println!("distrobox was started as well!!!! good job me!");
}
else{
println!("ooof did not start successfully try entering it yoruself");
println!("distrobox enter --rrot {} -- sudo -s ln -sf /pentest/boxname /etc/boxname", &box_name);
}
}
else{
println!("ooof distrobox did not work.... try creating it yourself");
println!("distrobox create --root --clone {} --volume {} --volume {} --name {}", boxtemplate, &toold_volume, &pentest_volume, &box_name);
println!("distrobox enter --rrot {} -- sudo -s ln -sf /pentest/boxname /etc/boxname", &box_name);
}
let new_project = Project{customer: customer_name.trim_end().to_owned(),
project_name: project_name.trim_end().to_owned(),
notes_folder: new_note_dir,
@@ -238,7 +224,11 @@ pub fn new_project(projects: &mut Vec<Project>, project_dir: &PathBuf, notes_dir
active: false,
id: new_id,
boxname: box_name,
stage: project_stage.to_owned()
};
if project_stage.contains("current"){
make_box(&new_project, &tools_dir, &boxtemplate, true);
}
projects.push(new_project);
save_projects(projects, config_path);
@@ -312,6 +302,12 @@ pub fn get_projects(config_path: &PathBuf) -> Vec<Project>{
if first != 1{
if line.len() > 1{
let settings: Vec<&str> = line.split(":").collect();
//debug config file...
/*let mut count = 0;
for settin in &settings{
println!("{}: {}", count, settin);
count = count + 1;
}*/
let customer = settings[0].to_owned();
let project = settings[1].to_owned();
let notes_string = settings[2].to_owned();
@@ -327,7 +323,8 @@ pub fn get_projects(config_path: &PathBuf) -> Vec<Project>{
active = true;
}
}
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname};
let project_stage = settings[6].to_owned();
let new_project = Project{customer: customer, project_name: project, files_folder: project_folder, notes_folder: notes_folder, active: active, id: first, boxname: boxname, stage: project_stage};
println!("{} {} LOADED!", &new_project.customer, &new_project.project_name);
projects.push(new_project);
}
@@ -335,3 +332,73 @@ pub fn get_projects(config_path: &PathBuf) -> Vec<Project>{
}
return projects
}
pub fn print_upcoming_projects(projects: &Vec<Project>){
for project in projects{
if project.stage.contains("upcoming"){
println!("{}:{}", project.customer, project.project_name);
}
}
}
pub fn promote_project(projects: &mut Vec<Project>, config_path: &PathBuf, project_dir: &PathBuf, notes_dir: &PathBuf, tools_dir: &PathBuf, boxtemplate: &String){
let working_projects = projects.clone();
for project in &working_projects{
if project.stage.contains("upcoming"){
println!("{}.) {}:{}", project.id, project.customer, project.project_name);
}
}
println!("which project to promote?");
let mut selection = String::new();
let result = stdin().read_line(&mut selection);
if result.is_err(){
println!("we need input here dummy try again....");
}
result.unwrap();
println!("{}", project_dir.display());
let promote_id: i32 = selection.trim_end().parse().unwrap();
let mut projects_to_save = Vec::new();
for project in &working_projects{
if project.id == promote_id{
let mut promoted_project = project.clone();
let mut new_files_dir = project_dir.clone();
let mut new_notes_dir = notes_dir.clone();
new_files_dir.push(&promoted_project.customer);
new_notes_dir.push(&promoted_project.customer);
let folder_move_success = process::Command::new("mv")
.arg("-i")
.arg(&project.files_folder)
.arg(&new_files_dir.display().to_string())
.status().expect("unable to call the system mv command");
let note_move_success = process::Command::new("mv")
.arg("-i")
.arg(&project.notes_folder)
.arg(&new_notes_dir.display().to_string())
.status().expect("unable to call the system mv command");
if folder_move_success.success(){
println!("we copied the project folder correctly!!");
}
else{
println!("failed to copy the project folder, try to move it manually!");
}
if note_move_success.success(){
println!("we copied the notes folder correctly!!");
}
else{
println!("failed to copy the notes folder, try to move it manually!");
}
promoted_project.files_folder = new_files_dir;
promoted_project.notes_folder = new_notes_dir;
promoted_project.stage = "current".to_owned();
thread::sleep(Duration::from_secs(3));
make_box(&promoted_project, tools_dir, boxtemplate, true);
projects_to_save.push(promoted_project);
}
else{
projects_to_save.push(project.clone());
}
}
projects.clear();
projects.append(&mut projects_to_save);
save_projects(&projects_to_save, config_path);
}

View File

@@ -1,25 +1,54 @@
use std::fs;
use std::io::stdin;
use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use crate::Project;
use crate::project_controls;
use crate::get_user_input;
fn external(project_folder_path: String,comapny_name: &String, project_name: &String, passtemp: PathBuf){
let mut general_notes = fs::File::create(format!("{}/general.md", &project_folder_path)).expect("error creating general notes file");
let mut attack_notes = fs::File::create(format!("{}/attacks.md", &project_folder_path)).expect("error creating attack notes file");
let mut host_notes = fs::File::create(format!("{}/host_notes.md", &project_folder_path)).expect("error creating host notes file");
let mut finding_notes = fs::File::create(format!("{}/findings.md", &project_folder_path)).expect("error creating findings notes file");
// for tagging
let year = project_name.split("_").collect::<Vec<&str>>()[1];
let project_type = "External";
writeln!(&mut general_notes, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing to general notes file");
writeln!(&mut attack_notes, "#{} #{} #{} #attack", comapny_name, project_type, year).expect("error writing tags on attack notes");
writeln!(&mut host_notes, "##{} #{} #{} #host_notes", comapny_name, project_type, year).expect("error writing tag lin in host notes");
writeln!(&mut finding_notes, "#{} #{} #{} #findings", comapny_name, project_type, year).expect("error writing tag line on findings");
writeln!(&mut general_notes, "# Scope").expect("error writing to general notes file");
writeln!(&mut general_notes, "\n| IP | Third Party | Approval |").expect("error writing to general notes file");
writeln!(&mut general_notes, "| -- | ----------- | -------- |").expect("error writing to general notes file");
writeln!(&mut general_notes, "# PPC").expect("failed to write general notes");
write!(&mut general_notes, "
fn create_project_folder(path: &mut PathBuf, folder: &str){
path.push(folder);
let result = fs::create_dir_all(&path);
if result.is_err(){
println!("error creating {} directory!", folder);
}
else{
result.unwrap();
}
path.pop();
}
fn create_note_file(path: &PathBuf) -> Option<File>{
let result = fs::File::create(path);
if result.is_err(){
println!("error creating {} try manually!", path.display());
return None;
}
else{
let file = result.unwrap();
return Some(file);
}
}
fn external(passtemp: &PathBuf, project: &Project){
// using a pathbuf to create files.
let mut notes_path = project.notes_folder.clone();
notes_path.push("general.md");
let general_notes_result = fs::File::create(&notes_path);
if general_notes_result.is_err(){
println!("oof we ran into issues making the general notes! try to creat manually!");
}
else {
let mut general_notes = general_notes_result.unwrap();
// for tagging
let project_type = "External";
writeln!(&mut general_notes, "#{} #{} #general", project.customer, project_type).expect("error writing to general notes file");
writeln!(&mut general_notes, "# Scope").expect("error writing to general notes file");
writeln!(&mut general_notes, "\n| IP | Third Party | Approval |").expect("error writing to general notes file");
writeln!(&mut general_notes, "| -- | ----------- | -------- |").expect("error writing to general notes file");
writeln!(&mut general_notes, "# PPC").expect("failed to write general notes");
write!(&mut general_notes, "
Planning call notes:
* methodolgy
* whole month testing window
@@ -54,8 +83,17 @@ Planning call notes:
| IP | host notes | needs? |
| -- | ---------- | ------ |\n").expect("faile to write pentest notes");
// set up the basics for our attack notes
write!(&mut attack_notes,"
}
notes_path.pop();
notes_path.push("attacks.md");
let attack_notes_result = fs::File::create(&notes_path);
if attack_notes_result.is_err(){
println!("oof we ran into issues making the general notes! try to creat manually!");
}
else {
let mut attack_notes = attack_notes_result.unwrap();
writeln!(&mut attack_notes, "#{} #{} #attack", project.customer, "external").expect("error writing tags on attack notes");
write!(&mut attack_notes,"
# Directory Bruteforcing
- [ ] example.com
@@ -74,59 +112,85 @@ write!(&mut attack_notes,"
passwords tried:
* password\n
" ).expect("failed to write attack notes template");
let new_spray_path = format!("{}/passwordspray.md", &project_folder_path);
fs::copy(passtemp,new_spray_path).unwrap();
}
notes_path.pop();
notes_path.push("password_spray.md");
let pass_result = fs::copy(&passtemp, &notes_path);
if pass_result.is_err(){
println!("error copying password spray file! try manually");
}
else{
pass_result.unwrap();
}
notes_path.pop();
notes_path.push("host_notes.md");
let host_notes_result = fs::File::create(&notes_path);
if host_notes_result.is_err(){
println!("error creating host notes, try manually!");
}
else{
let mut host_notes = host_notes_result.unwrap();
writeln!(&mut host_notes, "##{} #{} #host_notes", project.customer, "external").expect("error writing tag lin in host notes");
}
notes_path.pop();
notes_path.push("findings.md");
let findings_notes_result = fs::File::create(notes_path);
if findings_notes_result.is_err(){
println!("error creating host findings file, try manually!");
}
else{
let mut finding_notes = findings_notes_result.unwrap();
writeln!(&mut finding_notes, "#{} #{} #findings", project.customer, "external").expect("error writing tag line on findings");
}
}
fn internal(project_folder_path: String, comapny_name: &String, project_name: &String, passtemp: PathBuf){
let loot_folder = format!("{}/l00t", project_folder_path);
fs::create_dir_all(&loot_folder).expect("error creating loot directory");
let mut general_notes = fs::File::create(format!("{}/general.md", &project_folder_path)).expect("error creating general notes file");
let mut attack_notes = fs::File::create(format!("{}/attacks.md", &project_folder_path)).expect("error creating attack notes file");
let mut finding_notes = fs::File::create(format!("{}/findings.md", &project_folder_path)).expect("error creating findings notes file");
let mut systeminfo = fs::File::create(format!("{}/systeminfo", &project_folder_path)).expect("error creating systeminfo note file");
let mut netsta = fs::File::create(format!("{}/netstat", &project_folder_path)).expect("error creating netstat file");
let mut creds_notes = fs::File::create(format!("{}/creds.md", &loot_folder)).expect("error creating creds note");
let mut todo_notes = fs::File::create(format!("{}/todo.md", &project_folder_path)).expect("error creating todo notes");
let mut cleanup_notes = fs::File::create(format!("{}/cleanup.md", &project_folder_path)).expect("error creating cleanup notes");
let mut dump_notes = fs::File::create(format!("{}/dumps.md", &loot_folder)).expect("error creating password spray notes");
let mut enum_notes = fs::File::create(format!("{}/initial_enum.md", &project_folder_path)).expect("error creating password spray notes");
let enum_obsidian_path = format!("Hack_Notes/pentest_notes/upcomming/{customer}//initial_enum.md", customer = comapny_name);
// for tagging notes
let oyear = project_name.split("_").collect::<Vec<&str>>()[0];
let year = format!("year-{}", oyear);
let project_type = "Internal";
writeln!(&mut creds_notes, "#{} #{} #{} #l00t #creds", comapny_name, project_type, year).expect("error writing creds notes");
writeln!(&mut dump_notes, "#{} #{} #{} #l00t #dumps", comapny_name, project_type, year).expect("error writing creds notes");
writeln!(&mut cleanup_notes, "#{} #{} #{} #cleanup", comapny_name, project_type, year).expect("error writing to cleanup notes");
writeln!(&mut general_notes, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing to general notes file");
writeln!(&mut attack_notes, "#{} #{} #{} #attack", comapny_name, project_type, year).expect("error writing attack note tags");
writeln!(&mut todo_notes, "#{} #{} #{} #todo", comapny_name, project_type, year).expect("error writing tag line on todo");
writeln!(&mut finding_notes, "#{} #{} #{} #findings", comapny_name, project_type, year).expect("error writing tags line on findings");
writeln!(&mut systeminfo, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing tag line for system info");
writeln!(&mut systeminfo, "#{} #{} #{} #Password_sprays", comapny_name, project_type, year).expect("error writing tag line for password spraying");
writeln!(&mut netsta, "#{} #{} #{} #general", comapny_name, project_type, year).expect("error writing tagline in the netstat file");
writeln!(&mut enum_notes, "#{} #{} #{} #enum", comapny_name, project_type, year).expect("error writing tagline in the netstat file");
writeln!(&mut creds_notes, "# CREDS").expect("error writing creds notes");
writeln!(&mut creds_notes, "\n| System | username | password |").expect("error writing creds notes");
writeln!(&mut creds_notes, "| ------ | -------- | -------- |").expect("error writing creds notes");
writeln!(&mut creds_notes, "\n\n").expect("error writing creds notes");
writeln!(&mut creds_notes, "# HASHES\n\n").expect("error writing creds notes");
writeln!(&mut creds_notes, "| TYPE | USER | HASH |").expect("error writing creds notes");
writeln!(&mut creds_notes, "| ---- | ---- | ---- |").expect("error writing creds notes");
writeln!(&mut cleanup_notes, "- [ ] Breach machine C-temp-fr").expect("error writing to cleanup notes");
writeln!(&mut cleanup_notes, "- [ ] (continue to add as needed").expect("error writing ot cleanup notes");
writeln!(&mut general_notes, "# Scope\n").expect("error writing to general notes file");
writeln!(&mut general_notes, "PASTE SCOPE FROM EXCELL HERE (THE EXCEL TO MARKDOWN TABLE PLUGIN WILL FORMAT FOR YOU").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "# SAM\n\n").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "## system name\n").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "```").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "```\n\n").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "# LSASS\n\n").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "## system name\n").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "```").expect("shouldn't ever fail");
writeln!(&mut dump_notes, "```").expect("shouldn't ever fail");
write!(&mut general_notes, "
fn internal(passtemp: &PathBuf, project: &Project){
let mut notes_path = project.notes_folder.clone();
let file_creation_res = fs::create_dir_all(&notes_path);
if file_creation_res.is_err(){
let error = file_creation_res.err().unwrap();
println!("error creating notes folder! {}", error);
}
else{
file_creation_res.unwrap();
}
notes_path.push("password_spray.md");
println!("copying from {} to {}", passtemp.display(), &notes_path.display());
let pass_result = fs::copy(&passtemp, &notes_path);
if pass_result.is_err(){
let error = pass_result.err().unwrap();
println!("error copying password spray file, try again manually! {}", error);
}
else{
pass_result.unwrap();
}
notes_path.pop();
notes_path.push("l00t");
fs::create_dir_all(&notes_path).expect("error creating loot directory");
notes_path.push("creds.md");
let creds_notes_result = create_note_file(&notes_path);
if creds_notes_result.is_some(){
let mut creds_notes = creds_notes_result.unwrap();
writeln!(&mut creds_notes, "#{} #{} #l00t #creds", project.customer, "internal").expect("error writing creds notes");
writeln!(&mut creds_notes, "# CREDS").expect("error writing creds notes");
writeln!(&mut creds_notes, "\n| System | username | password |").expect("error writing creds notes");
writeln!(&mut creds_notes, "| ------ | -------- | -------- |").expect("error writing creds notes");
writeln!(&mut creds_notes, "\n\n").expect("error writing creds notes");
writeln!(&mut creds_notes, "# HASHES\n\n").expect("error writing creds notes");
writeln!(&mut creds_notes, "| TYPE | USER | HASH |").expect("error writing creds notes");
writeln!(&mut creds_notes, "| ---- | ---- | ---- |").expect("error writing creds notes");
}
notes_path.pop();
notes_path.pop();
notes_path.push("general.md");
let general_result = create_note_file(&notes_path);
if general_result.is_some(){
let mut general_notes = general_result.unwrap();
writeln!(&mut general_notes, "#{} #{} #general", project.customer, "internal").expect("error writing to general notes file");
writeln!(&mut general_notes, "# Scope\n").expect("error writing to general notes file");
writeln!(&mut general_notes, "PASTE SCOPE FROM EXCELL HERE (THE EXCEL TO MARKDOWN TABLE PLUGIN WILL FORMAT FOR YOU").expect("shouldn't ever fail");
write!(&mut general_notes, "
On the call:
Introductions
@@ -151,7 +215,15 @@ Do they have a specific contact
Email any follow-up items from the call to the PM
").expect("error writing PPC text");
write!(&mut attack_notes,"
}
notes_path.pop();
let enum_path = format!("{}/initial_enum.md", notes_path.display());
notes_path.push("attacks.md");
let attack_result = create_note_file(&notes_path);
if attack_result.is_some(){
let mut attack_notes = attack_result.unwrap();
writeln!(&mut attack_notes, "#{} #{} #attack", project.customer, "internal").expect("error writing attack note tags");
write!(&mut attack_notes,"
# current dat (ex: 7/5)
Got Persistence via (schtasks, bat schtasks, startup folder)
@@ -206,15 +278,29 @@ powerup.ps1/sharpup.exe notes.
", enum = enum_obsidian_path).expect("error writing to attack notes for internal tests");
write!(&mut finding_notes, "
# normal findings
", enum = enum_path).expect("error writing to attack notes for internal tests");
}
notes_path.pop();
notes_path.push("findings.md");
let findings_result = create_note_file(&notes_path);
if findings_result.is_some(){
let mut finding_notes = findings_result.unwrap();
writeln!(&mut finding_notes, "#{} #{} #findings", project.customer, "internal").expect("error writing tags line on findings");
write!(&mut finding_notes, "
# normal findings
# data exfil
## [Sarting Username]
# data exfil
## [Sarting Username]
").expect("error writing to findings notes on internal");
write!(&mut todo_notes, "
").expect("error writing to findings notes on internal");
}
notes_path.pop();
notes_path.push("todo.md");
let todo_result = create_note_file(&notes_path);
if todo_result.is_some(){
let mut todo_notes = todo_result.unwrap();
writeln!(&mut todo_notes, "#{} #{} #todo", project.customer, "internal").expect("error writing tag line on todo");
write!(&mut todo_notes, "
- [ ] local checks
- [ ] find shares
@@ -227,94 +313,41 @@ powerup.ps1/sharpup.exe notes.
- [ ] passwords in AD Descriptions?
- [ ] password spray
").expect("error writing todo list");
write!(&mut netsta,"
```
```").expect("error writing code block to system info");
write!(&mut systeminfo,"
```
```").expect("error writing code block to system info");
let new_pass_path = format!("{}/passwordspray.md", &project_folder_path);
println!("{} | {}", passtemp.display(), new_pass_path);
fs::copy(passtemp, new_pass_path).unwrap();
}
notes_path.pop();
notes_path.push("cleanup.md");
let cleanup_result = create_note_file(&notes_path);
if cleanup_result.is_some(){
let mut cleanup_notes = cleanup_result.unwrap();
writeln!(&mut cleanup_notes, "#{} #{} #cleanup", project.customer, "internal").expect("error writing to cleanup notes");
writeln!(&mut cleanup_notes, "- [ ] Breach machine C-temp-fr").expect("error writing to cleanup notes");
writeln!(&mut cleanup_notes, "- [ ] (continue to add as needed").expect("error writing ot cleanup notes");
}
}
pub fn start_pentest(config_path: &PathBuf) {
let mut pentest_notes = String::new();
let mut project_files = String::new();
let mut company_name = String::new();
let mut project_name = String::new();
let mut config_file_path_buf = config_path.clone();
config_file_path_buf.pop();
let mut passpray_path = config_file_path_buf.clone();
passpray_path.push("passwordspray.md");
config_file_path_buf.push("new_projects.conf");
let config_string = fs::read_to_string(config_file_path_buf).expect("error reading ");
if config_string.contains("folder_path") && config_string.contains("notes_path"){
let config_string_vec: Vec<&str> = config_string.split("\n").collect();
for line in config_string_vec{
if line.contains("project_folder_path"){
let line_vec: Vec<&str> = line.split(":").collect();
project_files = line_vec[1].to_owned();
}
else if line.contains("project_notes_path"){
let line_vec: Vec<&str> = line.split(":").collect();
pentest_notes = line_vec[1].to_owned();
}
}
pub fn start_pentest(config_path: &PathBuf, projects: &mut Vec<Project>, id: i32, upcoming_files: &PathBuf, upcoming_notes: &PathBuf, boxtemplate: &String, password_spray_file: &PathBuf) {
let mut project_files = upcoming_files.clone();
let mut project_notes = upcoming_notes.clone();
let customer_name = get_user_input("Customer name?");
let project_name = get_user_input("Project Name?");
project_files.push(&customer_name);
project_files.push(&project_name);
project_notes.push(&customer_name);
project_notes.push(&project_name);
let mut working = project_files.clone();
create_project_folder(&mut working, "working");
create_project_folder(&mut working, "writing");
create_project_folder(&mut working, "delivery");
let project_boxname = format!("{}_{}", boxtemplate, customer_name);
let new_prject = Project{customer:customer_name.clone(), project_name:project_name.clone(), notes_folder:project_notes.clone(), files_folder:project_files.clone(),active:false, boxname:project_boxname.clone(),stage:"upcoming".to_owned(), id};
if project_name.contains("external"){
external(password_spray_file, &new_prject);
}
println!("Project files path: {}\nProject Notes path: {}", project_files, pentest_notes);
println!("Comapny Name?");
match std::io::stdin().read_line(&mut company_name){
Ok(_result) => (),
Err(_e) => {println!("we need input here dummy!"); return;}
else if project_name.contains("internal"){
internal(password_spray_file, &new_prject);
}
println!("project Name?");
match stdin().read_line(&mut project_name){
Ok(_result) => (),
Err(_e) => {println!("we need input here dummy!"); return;}
}
//remove new lines from input
company_name = company_name.trim_end().to_owned();
project_name = project_name.trim_end().to_owned();
let project_folder_path = format!("{}/{}/{}", pentest_notes, company_name,project_name);
println!("setting folder creation paths...");
let project_files_folder_path = format!("{}/{}/{}", project_files, company_name, project_name);
let working_folder = format!("{}/working", &project_files_folder_path);
let writing_folder = format!("{}/writing", &project_files_folder_path);
let screeenshot_folder = format!("{}/screenshots",&writing_folder);
let delivery_folder = format!("{}/delivery", &project_files_folder_path);
// make the folders for this project's notes and files
println!("creating directory structure for notes and file folders...");
fs::create_dir_all(&project_folder_path).expect("Error creating project folder");
fs::create_dir_all(&project_files_folder_path).expect("Error creating project file folder");
fs::create_dir_all(&working_folder).expect("error creating working directory");
fs::create_dir_all(&writing_folder).expect("Error creating writing direcotry");
fs::create_dir(&screeenshot_folder).expect("error creating screenshots folder");
fs::create_dir_all(&delivery_folder).expect("Error creating delivery direcotry");
if project_name.contains("internal"){
println!("internal pentest type detected, auto populating notes with internal layout...");
internal(project_folder_path,&company_name, &project_name, passpray_path);
}
else if project_name.contains("external") {
println!("external pentest type detected, auto populating notes with external layout...");
external(project_folder_path, &company_name, &project_name, passpray_path);
}
else if project_name.contains("webapp") {
println!("not implemented yet sorry");
println!("default file folder structure used, and empty notes folder created...")
}
else{
println!("unknown project type detected, default folder strucutre and empty note folder created...");
print!("
Known project types:
Internal Penetration Test
External Penetartion Test
If this test is actually one of these types please include the type in the project name parameter, example: 2023_internal_pentest.
If this test is a common test and you would like a default note structure implemented in this script let Kevin \"Kage\" Gunter know and supply an example markdown note sheet.");
}
projects.push(new_prject);
project_controls::save_projects(projects, config_path);
println!("project created and saved to the projects config file!");
}