added password spray help funciton, and a bell.

also added downloading the bell file to the install
This commit is contained in:
pyro57000
2025-01-09 13:54:55 -06:00
parent 37a942b8b3
commit b2822a614a
7 changed files with 2296 additions and 24 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/pentest_tool/target

2015
pentest_tool/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,11 @@ version = "0.2.0"
edition = "2021"
[dependencies]
chrono = "0.4.39"
clearscreen = "3.0.0"
directories = "5.0.1"
fs_extra = "1.3.0"
futures-io = { version = "0.2.0-beta" }
reqwest = {version = "0.12.12", features = ["blocking", "json"]}
rodio = "0.20.1"
walkdir = "2.5.0"

Binary file not shown.

View File

@@ -1,8 +1,17 @@
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;
use std::thread;
use std::time::Duration;
use std::io::stdin;
use walkdir::WalkDir;
use clearscreen::clear;
use clearscreen;
use rodio::{Decoder, OutputStream, Sink};
use crate::Project;
pub fn run_initial_enum(project: &Project){
@@ -179,4 +188,124 @@ pub fn build_cs_portscan_cmd(project: &Project){
let combined_ranges = ranges.join(",");
let final_command = portscan_cmd.replace("!!!", &combined_ranges);
println!("{}", final_command);
}
fn find_file(dir: &PathBuf, file_name: &str) -> Option<String>{
for entry in WalkDir::new(dir){
let entry = entry.unwrap();
let path = entry.path();
if path.is_file() && path.file_name().unwrap() == file_name{
return Some(path.to_str().unwrap().to_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");
let nefarious_spray_path = find_file(tools_dir, "obf-NefariousSpray.exe");
loop {
println!("how do you need to run it?");
print!("
1.) execut-assembly
2.) inlineExecute-assembly
3.) from disk with cobalt strike
4.) from disk without cobalt strike
");
let exemethod_result = stdin().read_line(&mut exemethod);
if exemethod_result.is_err(){
println!("we need input here dummy!");
}
else{
break
}
}
loop {
println!("Observation window in minutes?");
match stdin().read_line(&mut wait_time_response){
Ok(_response) => {{
let trimmed = wait_time_response.trim_end();
let time_parse_reslut = trimmed.parse::<u64>();
if time_parse_reslut.is_err(){
println!("error parsing wait time into u64!");
break;
}
else{
wait_time = time_parse_reslut.unwrap();
break;
}
}},
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 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);
if password_spray_read_result.is_err(){
println!("error reading password spray file!!!");
return;
}
else{
password_spray_string = password_spray_read_result.unwrap();
}
let mut passwords = Vec::new();
println!("loading lines to parse...");
for line in password_spray_string.split("\n"){
if line.len() > 3{
if !line.contains("[x]"){
println!("parsing {} ...", line);
let words: Vec<&str> = line.split_whitespace().collect();
let mut password = words.last().unwrap().to_string();
if password.contains("year"){
password = password.replace("year", year.to_string().as_str());
}
if password.contains("Season"){
let seasonpassword = password.replace("Season", &season);
passwords.push(seasonpassword);
let lseasonpassword = password.replace("Season", &lseason);
passwords.push(lseasonpassword);
}
if password.contains("season"){
let seasonpassword = password.replace("season", &season.to_lowercase());
passwords.push(seasonpassword);
let lseasonpassword = password.replace("season", &lseason.to_lowercase());
passwords.push(lseasonpassword);
}
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!("{} 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;}
}
for password in &passwords{
let mut _spraycontinue = String::new();
println!("\n{}\n", outline.replace("||PASSWORD||", password));
println!("press enter to start timer");
stdin().read_line(&mut _spraycontinue).unwrap();
println!("waiting for {} minutes...", wait_dur.as_secs());
thread::sleep(wait_dur * 60);
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let sink = Sink::try_new(&stream_handle).unwrap();
let bell_file = fs::File::open(&bell_path).unwrap();
let source = Decoder::new(BufReader::new(bell_file)).unwrap();
sink.append(source);
sink.sleep_until_end();
clear().unwrap();
}
}

View File

@@ -1,8 +1,113 @@
use std::collections::HashMap;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::io::stdin;
use std::io::copy;
use reqwest::blocking::get;
use std::path::PathBuf;
use std::process;
use std::process::exit;
fn setup_folders(config_path: &PathBuf) -> (String, String, String, String, String){
let mut delete_for_cleanup = config_path.clone();
delete_for_cleanup.pop();
let mut failed = false;
let mut new_files_folder = String::new();
let mut new_notes_folder = String::new();
let mut upcomming_files_folder = String::new();
let mut upcomming_notes_folder = String::new();
let mut tools_folder = 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?");
match stdin().read_line(&mut new_files_folder){
Ok(_r) => (),
Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...")
}
}
if new_notes_folder.is_empty(){
println!("path to save active project notes?");
match stdin().read_line(&mut new_notes_folder){
Ok(_r) => (),
Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...")
}
}
if tools_folder.is_empty(){
println!("path to custom tools (like github tools and what not)");
match stdin().read_line(&mut tools_folder){
Ok(_r) => (),
Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...")
}
}
if upcomming_files_folder.is_empty(){
println!("path to save upcomming project files?");
match stdin().read_line(&mut upcomming_files_folder){
Ok(_r) => (),
Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...")
}
}
if upcomming_notes_folder.is_empty(){
println!("path to save upcomming project notes?");
match stdin().read_line(&mut upcomming_notes_folder){
Ok(_r) => (),
Err(_e) => println!("we need input here dummy... We will reprompt on the next loop...")
}
}
}
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);
if new_files_path.exists() == false{
println!("active project file folder does not exist, creating...");
match fs::create_dir_all(&new_files_folder){
Ok(_r) => (),
Err(e) => {println!("Error creating active project files Folder!: {}", e);failed = true;}
}
}
if new_notes_path.exists() == false{
println!("active project notes folder does not exist creating...");
match fs::create_dir_all(new_notes_path){
Ok(_r) => (),
Err(e) => {println!("Error creating active project notes Folder!: {}", e);failed = true;}
}
}
if tools_path.exists() == false{
println!("tools folder does not exist creating...");
match fs::create_dir_all(tools_path){
Ok(_r) => (),
Err(e) => {println!("Error creating tools Folder!: {}", e);failed = true;}
}
}
if upcomming_files_path.exists() == false{
println!("upcomming project files folder does not exist creating...");
match fs::create_dir_all(upcomming_files_path){
Ok(_r) => (),
Err(e) => {println!("Error creating upcomming project files Folder!: {}", e);failed = true;}
}
}
if upcomming_notes_path.exists() == false{
println!("upcomming project notes folder does not exist creating...");
match fs::create_dir_all(upcomming_notes_path){
Ok(_r) => (),
Err(e) => {println!("Error creating upcomming project notes Folder!: {}", e);failed = true;}
}
}
if failed{
println!("install failed, cleaning up files...");
match fs::remove_dir_all(&delete_for_cleanup){
Ok(_r) => println!("cleanup successfull, please correct previously reported errors and rerun"),
Err(e) => println!("cleanup failed!: {}\nManually delete the following folder and retry\n{}", e, delete_for_cleanup.display())
}
exit(1);
}
return (new_files_folder, new_notes_folder, tools_folder, upcomming_files_folder, upcomming_notes_folder);
}
@@ -16,6 +121,14 @@ pub fn install(config_path: &PathBuf){
let mut config_folder_path: PathBuf = config_path.clone();
config_folder_path.pop();
let mut projects_conf_path = config_folder_path.clone();
let mut bell_file_path = config_folder_path.clone();
bell_file_path.push("bell.mp3");
let bell_sound_url = "https://github.com/Pyro57000/pentest_tool/raw/refs/heads/main/resources/bell.mp3";
let response = get(bell_sound_url).unwrap();
let response_length = response.content_length().unwrap_or(0);
let mut bell_file = File::create(bell_file_path).unwrap();
copy(&mut response.take(response_length), &mut bell_file).unwrap();
println!("bell notification tone sucessfully downloaded!");
let del_on_fail = config_folder_path.clone();
projects_conf_path.push("projects.conf");
fs::create_dir_all(&config_folder_path).expect("error creating config dir");
@@ -23,9 +136,6 @@ pub fn install(config_path: &PathBuf){
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");
let mut terminal_response = String::new();
let mut notes_response = String::new();
let mut files_response = String::new();
let mut tools_response = String::new();
let mut template_name = String::new();
let mut have_template = String::new();
println!("terminal you use? (example: konsole, xfce, gnome, etc)");
@@ -46,12 +156,7 @@ pub fn install(config_path: &PathBuf){
else{
_terminal_command = _terminal_commands[terminal_response.trim_end()].to_owned();
}
println!("path to save project notes?");
std::io::stdin().read_line(&mut notes_response).unwrap();
println!("path to save project files?");
std::io::stdin().read_line(&mut files_response).unwrap();
println!("path to folder with your custom tools?");
std::io::stdin().read_line(&mut tools_response).unwrap();
let (files_response, notes_response, tools_response, project_folder_path, project_note_path) = 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.
@@ -70,12 +175,18 @@ 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:{}\nterminal:{}", files_response.trim_end(), notes_response.trim_end(), tools_response.trim_end(), _terminal_command.trim_end());
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());
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());
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);
println!("active project notes: {}", &notes_response);
println!("upcomming prjoect notes: {}", &project_note_path);
println!("tools folder: {}", &tools_response);
println!("distrobox template: {}", &template_name);
println!("terminal command: {}", &_terminal_command);
println!("config file generated and saved to {}\n", config_path.display());
println!("please rerun the program");
let config_path = &config_folder_path.clone();
@@ -85,15 +196,9 @@ Do you have a distrobox set up to function as your template for all new projects
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");
let mut project_folder_path = String::new();
let mut porject_note_path = String::new();
println!("path to the project folders directory?");
std::io::stdin().read_line(&mut project_folder_path).expect("error reading project folder from stdin");
println!("path to the project notes directory");
std::io::stdin().read_line(&mut porject_note_path).expect("error reading project note folder form stdin");
write!(conf_file, "project_folder_path:{}
project_notes_path:{}
", project_folder_path.trim_end(), porject_note_path.trim_end()).expect("error writing config file");
", project_folder_path.trim_end(), project_note_path.trim_end()).expect("error writing config file");
let mut passpray_file = fs::File::create(password_spray_template_path).expect("error creating passwordspray file");
write!(passpray_file, "
- [ ] useraspass

View File

@@ -1,6 +1,9 @@
use std::path::PathBuf;
use std::process::exit;
use chrono::Datelike;
use clearscreen::clear;
use clearscreen;
use chrono::Local;
use crate::Project;
use crate::project_controls;
use crate::box_controls;
@@ -34,6 +37,18 @@ pub fn main_menu(mut projects: Vec<Project>, config_path: PathBuf, base_files: &
loop {
let active_project = get_active_project(&projects);
let mut response = String::new();
let now = Local::now();
let month = now.month();
let year = now.year();
let mut season = String::new();
let mut lseason = String::new();
match month{
12 | 01 | 02 => {season = "Winter".to_owned(); lseason = "Fall".to_owned()},
03 | 04 | 05 => {season = "Spring".to_owned(); lseason = "Winter".to_owned()},
06 | 07 | 08 => {season = "Summer".to_owned(); lseason = "Spring".to_owned()},
09 | 10 | 11 => {season = "Fall".to_owned(); lseason = "Summer".to_owned()},
_ => {println!("error getting season! Check code..."); exit(1)}
}
clear().expect("error clearing screen");
print!("
,,,;;::ccccc::;;;::c::;,;::cccccllc::::::;:::;;;;,,;,'',,;,,;;;;;;;:;;;;;,,,,,,,,,,,'''''',,,,,,''''
@@ -85,6 +100,12 @@ pub fn main_menu(mut projects: Vec<Project>, config_path: PathBuf, base_files: &
NOTE OPTION 18 WILL SAVE YOUR PROJECTS BEFORE QUITTING
Current Project: {} {}
Working Folder: {}
Notes Folder: {}
Box Name: {}
Terminal Command: {}
Current Season: {}
Year: {}
Main Menu:
1 .) Show Active Project
@@ -104,8 +125,9 @@ Current Project: {} {}
15.) Build host discovery cmd command from scope in notes
16.) build portscan command from scope in notes
17.) Stop All Distroboxes
18.) Quit Application
\n", active_project.customer, active_project.project_name);
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);
std::io::stdin().read_line(&mut response).expect("error getting menu input");
clear().expect("error clearing screen");
match response.as_str().trim_end(){
@@ -129,7 +151,8 @@ Current Project: {} {}
"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" => {project_controls::save_projects(&projects, &config_path);
"18" => info_controls::password_spray_help(&active_project, season, lseason, year, &tools_dir, &config_path),
"19" => {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();