diff --git a/pentest_tool/src/info_controls.rs b/pentest_tool/src/info_controls.rs index 474363a..40bd90f 100644 --- a/pentest_tool/src/info_controls.rs +++ b/pentest_tool/src/info_controls.rs @@ -1,28 +1,163 @@ +use std::collections::HashMap; use std::fs; use std::fs::read_to_string; use std::io::BufReader; use std::io::Write; use std::path::PathBuf; use std::process; +use std::process::Command; use std::thread; use std::time::Duration; use std::io::stdin; +use std::thread::JoinHandle; use walkdir::WalkDir; use clearscreen::clear; use clearscreen; use rodio::{Decoder, OutputStream, Sink}; +use crate::get_user_input; use crate::Project; pub fn run_initial_enum(project: &Project){ - let mut csv = String::new(); - println!("path to the csv?"); - std::io::stdin().read_line(&mut csv).unwrap(); - let status = process::Command::new("initial_recon").arg(&csv).arg(&project.customer).arg(&project.project_name).status().expect("error running initial_recon program"); - if status.success(){ - println!("execllent! hosts should be imported to {}/host_notes.md", &project.notes_folder.display()); + #[derive(Clone)] + struct Target { + address: String, + ports: Vec } - else{ - println!("ooof something went wrong, host notes may not have saved correctly!"); + + let mut targets:Vec = Vec::new(); + println!("log into nessus and export a report, only checking the host, protocol, and port boxes"); + let mut host_notes_path = project.notes_folder.clone(); + let mut attack_notes_path = project.notes_folder.clone(); + host_notes_path.push("host_notes.md"); + attack_notes_path.push("attacks"); + let csv_path = get_user_input("path to nessus report CSV?"); + let csv_read_res = fs::read_to_string(&csv_path); + if csv_read_res.is_err(){ + let error = csv_read_res.err().unwrap(); + println!("error reading csv!"); + println!("{}", error); + return; + } + let csv_data = csv_read_res.unwrap(); + for line in csv_data.split("\n").collect::>(){ + if line.len() > 1{ + let data: Vec<&str> = line.split(",").collect(); + let address = data[0].replace("\"", "").trim().to_owned(); + let port = data[2].replace("\"", "").trim().to_owned(); + let protocol = data[1].replace("\"", "").trim().to_owned(); + if &address == &"Host"{ + continue; + } + else if &port == &"0"{ + continue; + } + let port_entry = format!("{}:{}", &protocol, &port); + let mut is_new = true; + for target in &mut targets{ + if target.address == address{ + if !target.ports.contains(&port_entry){ + target.ports.push(port_entry.clone()); + } + is_new = false; + } + } + if is_new{ + let new_target = Target{address: address.to_owned(), ports: vec![port_entry.clone()]}; + targets.push(new_target); + } + } + } + for target in &targets{ + let host_notes_open_res = fs::OpenOptions::new().append(true).create(true).open(&host_notes_path); + if host_notes_open_res.is_err(){ + let error = host_notes_open_res.err().unwrap(); + println!("error opening host notes file!"); + println!("{}", error); + return; + } + let host_notes = host_notes_open_res.unwrap(); + let attack_notes_open_res = fs::OpenOptions::new().append(true).create(true).open(&attack_notes_path); + if attack_notes_open_res.is_err(){ + let error = attack_notes_open_res.err().unwrap(); + println!("error opening attack notes!"); + println!("{}", error); + return; + } + for target in targets.clone(){ + let mut output = format!("# {}\n## Ports\n| port | service | attack notes |\n| ----- | ------- | ------------ |\n", target.address); + for port in target.ports{ + output.push_str(format!("| {} | | [[attacks]]\n", port).as_str()); + } + output.push_str("\n"); + write!(&host_notes, "{}", output).expect("error writing host_notes"); + println!("{} notes written!", target.address); + } + } +} + +pub fn build_external_attack_notes(project: &Project){ + + #[derive(Clone)] + struct Port{ + number: String, + hosts: Vec, + } + + let mut ports: Vec = Vec::new(); + let mut host_notes_path = project.notes_folder.clone(); + let mut attack_notes_path = host_notes_path.clone(); + host_notes_path.push("host_notes.md"); + attack_notes_path.push("attacks.md"); + let host_notes_read_res = fs::read_to_string(host_notes_path); + if host_notes_read_res.is_err(){ + let error = host_notes_read_res.err().unwrap(); + println!("error reading host notes!"); + println!("{}", error); + return; + } + let host_notes = host_notes_read_res.unwrap(); + let attack_open_res = fs::OpenOptions::new().append(true).create(true).open(attack_notes_path); + if attack_open_res.is_err(){ + let error = attack_open_res.err().unwrap(); + println!("error opening attack notes!"); + println!("{}", error); + return; + } + let attack_notes = attack_open_res.unwrap(); + for line in host_notes.split("\n").collect::>(){ + let mut current_host = String::new(); + if line.len() > 1{ + if line.contains("#"){ + if !line.contains("##"){ + current_host = line.split_whitespace().collect::>()[1].trim().to_owned(); + } + } + if line.contains("|"){ + let table_data:Vec <&str> = line.split("|").collect(); + for item in table_data{ + let mut is_new = true; + if item.contains(":"){ + for port in &mut ports{ + if port.number == item.trim(){ + if port.hosts.contains(¤t_host){ + port.hosts.push(current_host.clone()); + } + is_new = false; + } + } + if is_new{ + let new_port = Port{number: line.trim().to_owned(), hosts:vec![current_host.clone()]}; + } + } + } + } + } + } + for port in ports{ + let output = format!("# {}\nHOSTS:\n", port.number); + for host in port.hosts{ + // output.push_str("## {}"); + } } } @@ -581,4 +716,63 @@ pub fn crack_hashes(cracking_rig: &String, project: &Project, terminal: &String, } } } +} + + +pub fn get_mssql_column_names(project: &Project) -> Option>{ + let mut notes_file = project.notes_folder.clone(); + notes_file.push("l00t/db_stuff"); + println!("NOTE: this funtion relies on netexec, make sure its installed properly!"); + let mut servers = Vec::new(); + let username = get_user_input("username for the databases?"); + let password = get_user_input("password for the databases?"); + let local_auth = get_user_input("Will you be using Windows Authentication for this?").to_lowercase(); + loop{ + for server in &servers{ + println!("{}", server); + } + let new_server = get_user_input("server to add? (enter DONE when you're finished)"); + if new_server == "DONE".to_owned(){ + break; + } + servers.push(new_server); + } + let db_handle = thread::spawn(move ||{ + for server in servers{ + let mut db_notes_path = notes_file.clone(); + let mut dbs = Vec::new(); + if local_auth.contains("n"){ + let netexec_cmd_res = Command::new("proxychains") + .arg("netexec") + .arg("mssql") + .arg(&server) + .arg("-u") + .arg(&username) + .arg("-p") + .arg(&password) + .arg("--local-auth") + .arg("-q") + .arg("\"SELECT name FROM master.sys.databases\"") + .output(); + if netexec_cmd_res.is_err(){ + let error = netexec_cmd_res.err().unwrap(); + println!("error running netexec command!"); + println!("{}", error); + } + else{ + let output_string = String::from_utf8(netexec_cmd_res.unwrap().stdout).unwrap(); + let words: Vec<&str> = output_string.split_whitespace().collect(); + for word in words { + if word.contains("name:"){ + let db = word.split(":").collect::>()[1].to_owned(); + db_notes_path.push(&db); + dbs.push(db); + fs::create_dir_all(&db_notes_path).unwrap(); + } + } + } + } + } + }); + return Some(db_handle); } \ No newline at end of file diff --git a/pentest_tool/src/install.rs b/pentest_tool/src/install.rs index 02a65dd..2898341 100644 --- a/pentest_tool/src/install.rs +++ b/pentest_tool/src/install.rs @@ -178,47 +178,23 @@ fn configure_distrobox(){ let home = user_dirs_result.unwrap().home_dir().to_path_buf(); dbrcpath.push(home); dbrcpath.push(".distroboxrc"); - let box_config_string_result = fs::read_to_string("/usr/etc/distrobox/distrobox.conf"); - if box_config_string_result.is_err(){ - println!("error reading distrobox config file"); - } + let box_config_string = String::from("container_always_pull=\"0\"\ncontainer_generate_entry=1\ncontainer_manager=\"podman\"\ncontainer_name_default=\"ubuntu\"\ncontainer_image_default=\"ghcr.io/ublue-os/ubuntu-toolbox:latest\"\nnon_interactive=\"1\"\nxhost +si:localuser:$USER >/dev/null\nexport PIPEWIRE_RUNTIME_DIR=/dev/null\nexport PATH=$PATH:$HOME/.local/bin\n"); + let dbrc_file_res = fs::OpenOptions::new().write(true).create(true).open(dbrcpath); + if dbrc_file_res.is_err(){ + let error = dbrc_file_res.err().unwrap(); + println!("error opening distroboxrc file!"); + println!("{}", error); + } else{ - let box_rc_file_res = fs::File::create(&dbrcpath); - if box_rc_file_res.is_err(){ - println!("error creating {}", &dbrcpath.display()); + let mut dibrc_file = dbrc_file_res.unwrap(); + let dbrc_write_res = write!(dibrc_file, "{}",box_config_string); + if dbrc_write_res.is_err(){ + println!("error writing config to distroboxrc file!"); + println!("{}", dbrc_write_res.err().unwrap()); } else{ - let mut box_rc_file = box_rc_file_res.unwrap(); - let box_config_string = box_config_string_result.unwrap(); - let box_config_lines: Vec<&str> = box_config_string.split("\n").collect(); - let mut line_write_result = true; - while line_write_result{ - for line in &box_config_lines{ - let mut _outline = String::new(); - if line.contains("container_always_pull"){ - _outline = "container_always_pull=\"0\"".to_owned(); - } - else{ - _outline = line.to_string(); - } - let box_rc_file_result = box_rc_file.write(_outline.as_bytes()); - if box_rc_file_result.is_ok(){ - box_rc_file_result.unwrap(); - line_write_result = true; - } - else{ - line_write_result = false; - } - } - if line_write_result == false{ - success = false; - break; - } - else{ - success = true; - break; - } - } + let _dbrc_write = dbrc_write_res.unwrap(); + success = true; } } }