Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4dba68cdcf | ||
|
|
7765640e0e | ||
|
|
d50625167b | ||
|
|
a798e39461 | ||
|
|
4e1ab4c30f | ||
|
|
ac037a15a9 | ||
|
|
345124baf1 | ||
|
|
a9a451a8cf | ||
|
|
7081280247 | ||
|
|
2d97e81920 | ||
|
|
761f71c6c1 | ||
|
|
882afe0f67 | ||
|
|
1f47ff8229 | ||
|
|
f40c0e31c1 | ||
|
|
bf95a375fb |
@@ -75,7 +75,8 @@ Once the project is done and I'm ready to clean up the distrobox I use option 7
|
||||
1. clone this repository `git clone https://github.com/Pyro57000/pentest_tool.git`
|
||||
2. cd into the nested "pentest_tool" folder `cd pentest_tool/pentest_tool`
|
||||
3. use cargo to build the release binary `cargo build --release`
|
||||
4. follow the same installation instructions, skipping the step where you download the release binary.
|
||||
4. copy the compiled binary to a folder on your path `sudo cp ./target/release/pentest_tool /usr/bin/`
|
||||
5. follow the same installation instructions, skipping the step where you download the release binary.
|
||||
|
||||
|
||||
|
||||
|
||||
25
ToDo.md
Normal file
25
ToDo.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# planned features
|
||||
1.) finish hash cracking with a dedictated cracking rig code.
|
||||
|
||||
2.) cracte hash cracking with current computer code.
|
||||
|
||||
3.) adapt new project code to searh the upcomming folder before prompting for a path.
|
||||
|
||||
4.) create code that moves projects to a "writing" state and folder.
|
||||
|
||||
5.) create code that tracks "current, upcomming, and writing" states, maybe automatic zipping of folders after writing is done?
|
||||
|
||||
# Unplanned, but would be cool
|
||||
1.) create a "server" and "Client" infrastructure that can help manage the distrobox clients and the main server
|
||||
|
||||
2.) maybe expand this server client model to interact with cracking rigs and what not.
|
||||
|
||||
3.) implment a function to searchsploit and copy wanted exploits to the project folder.
|
||||
|
||||
4.) implement a function to execute those copied exploits.
|
||||
|
||||
|
||||
# NOTE
|
||||
if you wish to contribute, please do! just fix a bug or implement any of the above features and make a pull request!!
|
||||
|
||||
I'll keep plugging away as I have time throughout my days as well.
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
use std::fs;
|
||||
use std::fs::read_to_string;
|
||||
use std::io::BufReader;
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
@@ -201,14 +200,10 @@ fn find_file(dir: &PathBuf, file_name: &str) -> Option<String>{
|
||||
return None;
|
||||
}
|
||||
|
||||
pub fn password_spray_help(project: &Project, season: String, lseason: String, year: i32, tools_dir: &PathBuf, config_path: &PathBuf){
|
||||
let mut wait_time:u64 = 0;
|
||||
let mut wait_time_response = String::new();
|
||||
let mut exemethod = String::new();
|
||||
let mut bell_path = config_path.clone();
|
||||
bell_path.pop();
|
||||
bell_path.push("bell.mp3");
|
||||
fn nefarious_config(tools_dir: &PathBuf) -> String{
|
||||
let nefarious_spray_path = find_file(tools_dir, "obf-NefariousSpray.exe");
|
||||
let mut outline = String::new();
|
||||
let mut exemethod = String::new();
|
||||
loop {
|
||||
println!("how do you need to run it?");
|
||||
print!("
|
||||
@@ -221,6 +216,123 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
if exemethod_result.is_err(){
|
||||
println!("we need input here dummy!");
|
||||
}
|
||||
else{
|
||||
match exemethod.as_str(){
|
||||
"1\n" => outline = format!("execute-assembly {} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", nefarious_spray_path.map_or("".to_string(), |s| s)),
|
||||
"2\n" => outline = format!("inlineExecute-Assembly --dotnetassembly {} --assemblyargs spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt --etw --amsi --pipe totallyawesomepipeyo", nefarious_spray_path.map_or("".to_string(), |s| s)),
|
||||
"3\n" => outline = {let mut path = String::new(); println!("path to nefarious spray.exe"); stdin().read_line(&mut path).unwrap(); format!("run {} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", path.trim_ascii_end())},
|
||||
"4\n" => outline = {let mut path = String::new(); println!("path to nefarious spray.exe"); stdin().read_line(&mut path).unwrap(); format!("{} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", path.trim_ascii_end())},
|
||||
_ => println!("unknown exec method... try again")
|
||||
}
|
||||
return outline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn msolspray_config(tools_dir: &PathBuf) -> String{
|
||||
let mut msolspray_path = String::new();
|
||||
let mut outline = String::new();
|
||||
let mut userlist = String::new();
|
||||
let mut spray_target = String::new();
|
||||
loop{
|
||||
println!("path to your users list?");
|
||||
let result = stdin().read_line(&mut userlist);
|
||||
if result.is_err(){
|
||||
println!("we need input here dummy!");
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
loop{
|
||||
println!("target URL (probably a fireprox url)");
|
||||
let result = stdin().read_line(&mut spray_target);
|
||||
if result.is_err(){
|
||||
println!("we need input here dummy!");
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
loop {
|
||||
let mut response = String::new();
|
||||
println!("is MSOLSpray.py in your path? (for example installed via pipx or pip)");
|
||||
let path_result = stdin().read_line(&mut response);
|
||||
if path_result.is_err(){
|
||||
println!("we need input here dummy!!");
|
||||
}
|
||||
else{
|
||||
response = response.to_lowercase();
|
||||
if response.contains("y"){
|
||||
msolspray_path = "MSOLSpray".to_owned();
|
||||
}
|
||||
else if response.contains("n"){
|
||||
println!("trying to automatically find msolspray.py in your tools folder...");
|
||||
let find_result = find_file(tools_dir, "MSOLSpray.py");
|
||||
if find_result.is_some(){
|
||||
msolspray_path = find_result.unwrap();
|
||||
loop {
|
||||
let mut response = String::new();
|
||||
println!("Found it! located at {}", msolspray_path);
|
||||
println!("is that correct?");
|
||||
let result = stdin().read_line(&mut response);
|
||||
if result.is_err(){
|
||||
println!("we need input here bruv, try again...");
|
||||
continue;
|
||||
}
|
||||
response = response.to_lowercase();
|
||||
if response.contains("n"){
|
||||
loop{
|
||||
msolspray_path = "".to_owned();
|
||||
println!("ok, so where is msolspray.py then?");
|
||||
let result = stdin().read_line(&mut msolspray_path);
|
||||
if result.is_err(){
|
||||
println!("we need input here burv...");
|
||||
continue;
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
msolspray_path = format!("python {}", msolspray_path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
loop {
|
||||
println!("OOOOF we didn't find it burh... where is MSOLSpray.py located?");
|
||||
match stdin().read_line(&mut msolspray_path){
|
||||
Ok(_response) => break,
|
||||
Err(_e) => println!("we need input here bruv... try again")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
outline = format!("{} {} -p ||PASSWORD|| --url {}", msolspray_path.trim_end(), userlist.trim_end(), spray_target.trim_end());
|
||||
return outline;
|
||||
}
|
||||
|
||||
pub fn password_spray_help(project: &Project, season: String, lseason: String, year: i32, tools_dir: &PathBuf, config_path: &PathBuf){
|
||||
let mut wait_time:u64 = 0;
|
||||
let mut wait_time_response = String::new();
|
||||
let mut bell_path = config_path.clone();
|
||||
bell_path.pop();
|
||||
bell_path.push("bell.mp3");
|
||||
let mut tool_to_use = String::new();
|
||||
loop {
|
||||
println!("which tool?");
|
||||
print!("
|
||||
1.) nefarious spray
|
||||
2.) msolspray.py
|
||||
");
|
||||
let exemethod_result = stdin().read_line(&mut tool_to_use);
|
||||
if exemethod_result.is_err(){
|
||||
println!("we need input here dummy!");
|
||||
}
|
||||
else{
|
||||
break
|
||||
}
|
||||
@@ -243,12 +355,12 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
Err(_e) => println!("we need you to put in the minutes for the obervation window please!")
|
||||
}
|
||||
}
|
||||
let mut wait_dur = Duration::from_secs(wait_time);
|
||||
let wait_dur = Duration::from_secs(wait_time);
|
||||
let mut password_spray_file = project.notes_folder.clone();
|
||||
password_spray_file.push("password_spray.md");
|
||||
println!("{}", password_spray_file.display());
|
||||
let mut password_spray_string = String::new();
|
||||
let password_spray_read_result = fs::read_to_string(password_spray_file);
|
||||
let password_spray_read_result = fs::read_to_string(&password_spray_file);
|
||||
if password_spray_read_result.is_err(){
|
||||
println!("error reading password spray file!!!");
|
||||
return;
|
||||
@@ -257,6 +369,7 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
password_spray_string = password_spray_read_result.unwrap();
|
||||
}
|
||||
let mut passwords = Vec::new();
|
||||
let mut sprayed_passwords = Vec::new();
|
||||
println!("loading lines to parse...");
|
||||
for line in password_spray_string.split("\n"){
|
||||
if line.len() > 3{
|
||||
@@ -281,17 +394,21 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
}
|
||||
passwords.push(password);
|
||||
}
|
||||
else{
|
||||
let words: Vec<&str> = line.split_whitespace().collect();
|
||||
let password = words.last().unwrap().to_string();
|
||||
println!("{} already sprayed, making note...", &password);
|
||||
sprayed_passwords.push(password);
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("passwords loaded, and parsed!");
|
||||
println!("starting password display and timer operations...");
|
||||
let mut outline = String::new();
|
||||
match exemethod.as_str(){
|
||||
"1\n" => outline = format!("execute-assembly {} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", nefarious_spray_path.map_or("".to_string(), |s| s)),
|
||||
"2\n" => outline = format!("inlineExecute-Assembly --dotnetassembly {} --assemblyargs spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt --etw --amsi --pipe totallyawesomepipeyo", nefarious_spray_path.map_or("".to_string(), |s| s)),
|
||||
"3\n" => outline = {let mut path = String::new(); println!("path to nefarious spray.exe"); stdin().read_line(&mut path).unwrap(); format!("run {} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", path.trim_ascii_end())},
|
||||
"4\n" => outline = {let mut path = String::new(); println!("path to nefarious spray.exe"); stdin().read_line(&mut path).unwrap(); format!("{} spray -p ||PASSWORD|| -o C:\\temp\\fr\\||PASSWORD||.txt", path.trim_ascii_end())},
|
||||
_ => {println!("unknown exec method... try again"); return;}
|
||||
match tool_to_use.as_str(){
|
||||
"1\n" => outline = nefarious_config(tools_dir),
|
||||
"2\n" => outline = msolspray_config(tools_dir),
|
||||
_ => println!("unkown tool to use, try again...")
|
||||
}
|
||||
for password in &passwords{
|
||||
let mut _spraycontinue = String::new();
|
||||
@@ -300,8 +417,37 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
printline = printline.replace("-p useraspass", "--UserAsPass")
|
||||
}
|
||||
println!("\n{}\n", printline);
|
||||
println!("press enter to start timer");
|
||||
println!("enter s to save an return to main menu, or just enter to start timer");
|
||||
stdin().read_line(&mut _spraycontinue).unwrap();
|
||||
sprayed_passwords.push(password.to_owned());
|
||||
if _spraycontinue.contains("s"){
|
||||
let new_spray_file = fs::OpenOptions::new().write(true).truncate(true).open(&password_spray_file);
|
||||
if new_spray_file.is_err(){
|
||||
println!("error saving progress, please make note of where you are and update the file accordingly");
|
||||
}
|
||||
else{
|
||||
let mut open_spray_file = new_spray_file.unwrap();
|
||||
let mut new_file_text = String::new();
|
||||
for sprayed_pass in &sprayed_passwords{
|
||||
new_file_text = format!("{}\n- [x] {}", new_file_text, sprayed_pass);
|
||||
}
|
||||
for password in &passwords{
|
||||
if sprayed_passwords.contains(password) == false{
|
||||
new_file_text = format!("{}\n- [ ] {}", new_file_text, password);
|
||||
}
|
||||
}
|
||||
let save_result = open_spray_file.write_all(new_file_text.as_bytes());
|
||||
if save_result.is_err(){
|
||||
println!("saving failed!\nplease copy the below lines into your password spray notes!");
|
||||
println!("{}", new_file_text);
|
||||
}
|
||||
else{
|
||||
println!("password saved complete!!!");
|
||||
println!("returning to main menu...");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("waiting for {} minutes...", wait_dur.as_secs());
|
||||
thread::sleep(wait_dur * 60);
|
||||
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
|
||||
@@ -313,3 +459,126 @@ pub fn password_spray_help(project: &Project, season: String, lseason: String, y
|
||||
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::<Vec<&str>>()[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::<Vec<&str>>()[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::<Vec<&str>>()[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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,64 @@ 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...")
|
||||
}
|
||||
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);
|
||||
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();
|
||||
rule = "n".to_owned();
|
||||
rockyou = "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.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...");
|
||||
match fs::create_dir_all(&new_files_folder){
|
||||
@@ -106,7 +162,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -134,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();
|
||||
@@ -156,7 +212,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,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:{}", 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:{}\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:{}", ¬es_response.trim_end(), &files_response.trim_end(), &template_name.trim_end());
|
||||
let default_projectline = format!("default:default:{}:{}:yes:{}:current", ¬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!("active project folders: {}", &files_response);
|
||||
println!("upcomming project folders: {}", &project_folder_path);
|
||||
@@ -194,11 +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 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 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
|
||||
|
||||
@@ -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!("
|
||||
@@ -53,6 +71,12 @@ 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();
|
||||
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();
|
||||
@@ -63,8 +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])
|
||||
}
|
||||
}
|
||||
@@ -74,12 +104,15 @@ 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
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
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,44 +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.) 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" => {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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
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(¬es_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 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, "#{} #{} #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, "
|
||||
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(¬es_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,39 +112,67 @@ 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, ¬es_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(¬es_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");
|
||||
fn internal(passtemp: &PathBuf, project: &Project){
|
||||
let mut notes_path = project.notes_folder.clone();
|
||||
let file_creation_res = fs::create_dir_all(¬es_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(), ¬es_path.display());
|
||||
let pass_result = fs::copy(&passtemp, ¬es_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(¬es_path).expect("error creating loot directory");
|
||||
notes_path.push("creds.md");
|
||||
let creds_notes_result = create_note_file(¬es_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");
|
||||
@@ -114,18 +180,16 @@ fn internal(project_folder_path: String, comapny_name: &String, project_name: &S
|
||||
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");
|
||||
}
|
||||
notes_path.pop();
|
||||
notes_path.pop();
|
||||
notes_path.push("general.md");
|
||||
let general_result = create_note_file(¬es_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");
|
||||
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, "
|
||||
On the call:
|
||||
|
||||
@@ -151,6 +215,14 @@ Do they have a specific contact
|
||||
|
||||
Email any follow-up items from the call to the PM
|
||||
").expect("error writing PPC text");
|
||||
}
|
||||
notes_path.pop();
|
||||
let enum_path = format!("{}/initial_enum.md", notes_path.display());
|
||||
notes_path.push("attacks.md");
|
||||
let attack_result = create_note_file(¬es_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,14 +278,28 @@ powerup.ps1/sharpup.exe notes.
|
||||
|
||||
|
||||
|
||||
", enum = enum_obsidian_path).expect("error writing to attack notes for internal tests");
|
||||
", 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(¬es_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
|
||||
# normal findings
|
||||
|
||||
# data exfil
|
||||
## [Sarting Username]
|
||||
# data exfil
|
||||
## [Sarting Username]
|
||||
|
||||
").expect("error writing to findings notes on internal");
|
||||
}
|
||||
notes_path.pop();
|
||||
notes_path.push("todo.md");
|
||||
let todo_result = create_note_file(¬es_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
|
||||
@@ -227,93 +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(¬es_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();
|
||||
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();
|
||||
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);
|
||||
}
|
||||
else if line.contains("project_notes_path"){
|
||||
let line_vec: Vec<&str> = line.split(":").collect();
|
||||
pentest_notes = line_vec[1].to_owned();
|
||||
else if project_name.contains("internal"){
|
||||
internal(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;}
|
||||
}
|
||||
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!");
|
||||
}
|
||||
Reference in New Issue
Block a user