added some fucntion, note the portscan fucntion

is still borked... working on it.
This commit is contained in:
pyro57000
2025-05-01 12:50:50 -05:00
parent fbd524ae7f
commit 0913703976
3 changed files with 566 additions and 415 deletions

View File

@@ -47,7 +47,8 @@ fn help(command: Option<String>){
"clear" | "clear screen" | "cls" => {println!("Command:clear\nAliases:clear screen, cls\n\nThis command clears the screen of command output."); return},
"exit" => {println!("Command:exit\nAliases:(none)\nThis command exits the pentest_tool, it will save all project infomation, and wait for all threads to re-join the main thread before exiting."); return;},
"settings" => {println!("\n\nThe settings file is located at ~/.config/pyro_pentest_tool/conf\n\nThe format is setting_name:setting_value.\n\nNeeded settings are\n project_files - the place to store current project files folders\n\n projtect_notes - the place to store current project notes\n\n tools_folder - the place to store custom tools like those downloaded from github\n\n upcoming_files - the place to store upcoming project files folders\n\n upcoming_notes - The place to store upcoming project note files\n\n box_template - the name of the distrobox you want to clone for project boxes\n\n terminal - the command you use to launch a terminal, while running a specific command: Ex: konsole -e \n\n cracking_rig - the user and host you use for a personal cracking rig in the openssh formating: Ex: pyro@cracking_rig or pyro@192.168.1.101 if you do not have a cracking rig the default is @n\n\n rockyou_location - the location on the cracking rig for the rockyou.txt file default is n\n\n rule_location - the location on the cracking rig for the one rule to rule them all file. Default is n\n\n pass_file - this is the location where you store your standard password spray file. If you do not have a custom one this tool provides one. The default is ~/.config/pyro_pentest_tool/passwordspary.md\n\n fingerprint - this is whether you want fingerprint authentication within your distroboxes, takes y/n\n\n vault_name - the name of your obsidian vault, default is notes\n\n"); return;},
"parse nomral nmap file" | "pnnf" | "parse nmap" | "pn" => {println!("Command:parse normal nmap file\nAliases: pnnf, parse nmap, pn\n\nThis command parses the normal output of an nmap scan (like if you just tee'd or >'d it to a file) and outputs in host:port or int the coablt strike tsv format. It will attempt to find the file within the active project's files folder, and if it can't find the file it will prompt you for input.")},
"parse normal nmap file" | "pnnf" | "parse nmap" | "pn" => {println!("Command:parse normal nmap file\nAliases: pnnf, parse nmap, pn\n\nThis command parses the normal output of an nmap scan (like if you just tee'd or >'d it to a file) and outputs in host:port or int the coablt strike tsv format. It will attempt to find the file within the active project's files folder, and if it can't find the file it will prompt you for input.")},
"show scope" | "ss" | "show s" | "s s" | "scope" => {println!("Command:show scope\nAliases:ss, show s, s s, scope\n\nThis command displays the current project's scope as just the hosts in the scope table in your notes.")},
_ => ()
}
}
@@ -82,6 +83,7 @@ parse gather contacts | pgc | parse contacts | pc
prune distroboxes | pdb | prune
clear | clear screen | cls
parse nomral nmap file | pnnf | parse nmap | pn
show scope | ss | show s | s s | scope
help | ? | -h
")
}
@@ -179,16 +181,18 @@ pub fn run_command(cmd: String,
"recreate distrobox" | "rdb" | "ndb" | "new distrobox" => {box_controls::make_box(&active_project, &tools_dir, &boxtemplate, false, fingerprint); return None},
"generate userpass" | "userpass" | "gup" | "up" => {info_controls::generate_userpass(&active_project); return None},
"inital enum" | "ie" | "enum" => {info_controls::run_initial_enum(&active_project); return None},
"build attack notes" | "ban" | "attack notes" | "hn" => {info_controls::build_cmd_for_host_discovery(&active_project); return None;}
"host discovery" | "build host discovery" | "hd" | "bhd" => {info_controls::build_cmd_for_host_discovery(&active_project); return None},
"port scan" | "cs port scan" | "cobaltstrike port scan" | "csps" | "ps" => {info_controls::build_cs_portscan_cmd(&active_project); return None},
"parse port scan" | "pps" | "parse scan" => {info_controls::parse_csportscan(&active_project); return None},
"build attack notes" | "ban" | "attack notes" | "hn" => {portscan_controls::build_cmd_for_host_discovery(&active_project); return None;}
"host discovery" | "build host discovery" | "hd" | "bhd" => {portscan_controls::build_cmd_for_host_discovery(&active_project); return None},
"cobaltstrike port scan" | "cs port scan" | "csps" => {portscan_controls::build_cs_portscan_cmd(&active_project); return None},
"parse port scan" | "pps" | "parse scan" => {portscan_controls::parse_csportscan(&active_project); return None},
"stop boxes" | "stop distroboxes" | "sdb" => {box_controls::stop_all_boxes(&projects); return None},
"password spray" | "pass spray" | "pas" => {info_controls::password_spray_help(&active_project, season, lseason, year, &tools_dir, &config_path); return None},
"bloodhound" | "bh" => {let bloodhound_handle = box_controls::launch_bloodhound_gui(active_project.clone()).unwrap(); return Some(bloodhound_handle);},
"parse gather contacts" | "pgc" | "parse contacts" | "pc" => {info_controls::partse_gathercontacts(&active_project); return None},
"prune distroboxes" | "pdb" | "prune" => {let prune_thread = box_controls::clean_unused_boxes(&projects, &boxtemplate); return prune_thread},
"parse nomral nmap file" | "pnnf" | "parse nmap" | "pn" => {portscan_controls::parse_normal_nmap_output(&active_project); return None;}
"parse normal nmap file" | "pnnf" | "parse nmap" | "pn" => {portscan_controls::parse_normal_nmap_output(&active_project); return None;},
"show scope" | "ss" | "show s" | "s s" | "scope" => {let scope_res = info_controls::get_scope_entries(&active_project); if scope_res.is_some(){for host in scope_res.unwrap(){println!("{}", host)}}return None},
"port scan" | "ps" | "nmap" | "nmap scan" | "ns" | "nm" => {portscan_controls::run_nmap_portscan(&active_project); return None;},
_ => {help(None); println!("\n\n unknown command."); return None;}
}
}

View File

@@ -173,67 +173,6 @@ pub fn build_external_attack_notes(project: &Project){
}
}
pub fn build_cmd_for_host_discovery(project: &Project){
let mut cobalt_strike_response = String::new();
let mut need_shell = false;
println!("will you be running this via cobalt strike? (do you need it to start with \"shell\"?");
let input_result = std::io::stdin().read_line(&mut cobalt_strike_response);
if input_result.is_err(){
println!("error getting user input... not really sure how you did this... just pressing enter would work..... wow");
return;
}
if cobalt_strike_response.to_lowercase().contains("y"){
need_shell = true;
}
let mut general_note_path = project.notes_folder.clone();
general_note_path.push("general.md");
println!("Reading from: {}", general_note_path.display());
let mut ranges = Vec::new();
let general_note_string = read_to_string(general_note_path);
let mut _note_string = String::new();
match general_note_string{
Err(error) => {println!("error reading file to string!! {}", error); return;},
_=> _note_string = general_note_string.unwrap()
}
let lines: Vec<&str> = _note_string.split("\n").collect();
for line in lines{
if line.contains("|"){
if line.contains("."){
let ip = line.split("|").collect::<Vec<&str>>()[1];
if ip .contains(","){
let ips: Vec<&str> = ip.split(",").collect();
for ip in ips{
ranges.push(ip.trim_end().trim_start());
}
}
else{
ranges.push(ip.trim_end().trim_start());
}
}
}
}
let mut _discovery_command = "";
_discovery_command = "(for /L %a IN (1,1,254) DO ping /n 1 /w 3 !!!.%a) | find \"Reply\"";
let mut final_command = String::new();
for range in ranges{
let mut network: Vec<&str> = range.split(".").collect();
network.pop();
let network_string = network.join(".");
let mut _range_command = String::new();
if need_shell{
_range_command = format!("{}{}","shell ", _discovery_command.replace("!!!", &network_string));
need_shell = false;
}
else{
_range_command = _discovery_command.replace("!!!", &network_string);
}
final_command.push_str(_range_command.as_str());
final_command.push_str(">> ping_only_replies.txt &");
}
final_command.pop();
println!("{}", final_command);
}
pub fn generate_userpass(project: &Project){
let mut outlines = Vec::new();
let mut notes_file = project.notes_folder.clone();
@@ -300,42 +239,6 @@ pub fn print_report_information(project: Project){
}
pub fn build_cs_portscan_cmd(project: &Project){
let mut general_note_path = project.notes_folder.clone();
general_note_path.push("general.md");
println!("Reading from: {}", general_note_path.display());
let mut ranges = Vec::new();
let general_note_string = read_to_string(general_note_path);
let mut _note_string = String::new();
match general_note_string{
Err(error) => {println!("error reading file to string!! {}", error); return;},
_=> _note_string = general_note_string.unwrap()
}
let lines: Vec<&str> = _note_string.split("\n").collect();
for line in lines{
if line.contains("|"){
if line.contains("."){
let ip = line.split("|").collect::<Vec<&str>>()[1];
if ip.contains(","){
let ips: Vec<&str> = ip.split(",").collect();
for ip in ips{
ranges.push(ip.trim_end().trim_start());
}
}
else{
ranges.push(ip.trim_end().trim_start());
}
}
}
}
let portscan_cmd = "portscan !!! 1-1024,1433,2222,3306,3389,5000-6000,8000,8080,8443 icmp 512";
let mut _range_command = String::new();
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();
@@ -899,317 +802,38 @@ last
}
}
pub fn parse_csportscan(project: &Project){
let mut tsv_path = project.files_folder.clone();
tsv_path.push("working/tsvs/services.tsv");
let mut outfile = tsv_path.clone();
outfile.pop();
outfile.pop();
let mut windows_hosts = Vec::new();
let mut ssh_hosts = Vec::new();
let mut ftp_hosts = Vec::new();
let mut rdp_hosts = Vec::new();
let mut dns_hosts = Vec::new();
let mut snmp_hosts = Vec::new();
let mut web_hosts = Vec::new();
let mut telnet_hosts = Vec::new();
let mut unknown_ports = Vec::new();
if !get_user_input("do you have the tsv saved in the project folder under working/tsvs/services.tsv?").to_lowercase().contains("y"){
tsv_path.clear();
tsv_path.push(get_user_input("ooof ok, please enter the full path to your tsv file."));
}
let tsv_read_res = read_to_string(tsv_path);
if tsv_read_res.is_err(){
let error = tsv_read_res.err().unwrap();
println!("ooof error reading tsv file!");
println!("{}", error);
return;
}
println!("tsv read, parsing lines...");
let tsv_string = tsv_read_res.unwrap();
let lines: Vec<&str> = tsv_string.split("\n").collect();
for line in lines{
let words: Vec<&str> = line.split("\t").collect();
if words.len() > 1{
let host = words[0].to_lowercase().to_owned();
let port = words[1].to_lowercase().to_owned();
let host_entry = format!("{}:{}", &host, &port);
match words[1]{
"135" => {if !windows_hosts.contains(&host){windows_hosts.push(host)}},
"445" => {if !windows_hosts.contains(&host){windows_hosts.push(host)}},
"22" => {if !ssh_hosts.contains(&host){ssh_hosts.push(host);}},
"21" => {if !ftp_hosts.contains(&host){ftp_hosts.push(host);}},
"23" => {if !telnet_hosts.contains(&host){telnet_hosts.push(host)}},
"3389" => {if !rdp_hosts.contains(&host){rdp_hosts.push(host);}},
"80" | "443" | "8080" | "8443" | "4433" | "8000" => {if !web_hosts.contains(&host_entry){web_hosts.push(host_entry);}},
"53" => {if !dns_hosts.contains(&host){dns_hosts.push(host);}},
"161" => {if !snmp_hosts.contains(&host){snmp_hosts.push(host);}},
_ => {
if words.len() == 3{
let banner = words[2].to_lowercase().to_owned();
if words[2].to_lowercase().contains("ssh"){
if !ssh_hosts.contains(&host_entry){
ssh_hosts.push(host_entry);
}
}
else if banner.contains("ftp"){
if !ftp_hosts.contains(&host_entry){
ftp_hosts.push(host_entry);
}
}
else if banner.contains("nginx") || banner.contains("apache"){
if !web_hosts.contains(&host_entry){
web_hosts.push(host_entry);
}
}
else{
continue;
}
}
else if words.len() == 2{
unknown_ports.push(host_entry);
}
}
}
}
}
println!("is {} where you want to save your files?", outfile.display());
if get_user_input("").to_lowercase().contains("n"){
outfile.clear();
outfile.push(get_user_input("ok, please enter the full path to the folder you want to save them to."));
}
print!("
{} Windows hosts found!
{} SSH hosts found!
{} FTP hosts found!
{} Telnet hosts found!
{} SNMP hosts found!
{} DNS hosts found!
{} RDP hosts found!
{} untagged hosts found!
", windows_hosts.len(), ssh_hosts.len(), ftp_hosts.len(), telnet_hosts.len(), snmp_hosts.len(), dns_hosts.len(), rdp_hosts.len(), unknown_ports.len());
println!("lines parsed! creating output files...");
outfile.push("windows_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut windows_file = file_option.unwrap();
for host in windows_hosts{
let write_res = write!(windows_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing windows_hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("ssh_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut ssh_file = file_option.unwrap();
for host in ssh_hosts{
let write_res = write!(ssh_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing ssh_hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("telnet_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut telnet_file = file_option.unwrap();
for host in telnet_hosts{
let write_res = write!(telnet_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("ftp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut ftp_file = file_option.unwrap();
for host in ftp_hosts{
let write_res = write!(ftp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("snmp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut snmp_file = file_option.unwrap();
for host in snmp_hosts{
let write_res = write!(snmp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("dns_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut dns_file = file_option.unwrap();
for host in dns_hosts{
let write_res = write!(dns_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("rdp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut rdp_file = file_option.unwrap();
for host in rdp_hosts{
let write_res = write!(rdp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("web_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut web_file = file_option.unwrap();
for host in web_hosts{
let write_res = write!(web_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
println!("interesting ports have been written to... writing untagged port files...");
outfile.pop();
outfile.push("untagged ports");
if !outfile.exists(){
let untagged_res = create_dir_all(&outfile);
if untagged_res.is_err(){
let error = untagged_res.err().unwrap();
println!("ooof error creating untagged folder!");
println!("{}", error);
}
else{
untagged_res.unwrap();
}
}
for line in unknown_ports{
let line_vec:Vec<&str> = line.split(":").collect();
let host = line_vec[0].to_owned();
let port = line_vec[1].to_owned();
let file_name = format!("{}_hosts.txt", port);
outfile.push(file_name);
let write_file_opt = open_append(&outfile);
if write_file_opt.is_some(){
let mut write_file = write_file_opt.unwrap();
let write_res = write!(write_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("ooof error writing to file...");
println!("{}", error);
}
}
outfile.pop();
}
println!("DONE all files saved to {}", outfile.display());
println!("note if no hosts were found for a protocol their files will be empty.");
}
/*fn get_scope(general: &PathBuf){
println!("opening general notes...");
let mut working = general.clone();
working.push("general.md");
let working_read = fs::read_to_string(working);
if working_read.is_err(){
let error = working_read.err().unwrap();
println!("error reading general notes file!");
println!("{}", error);
return
}
let general_string = working_read.unwrap();
println!("reading scop from general notes...");
let mut scope_ranges = Vec::new();
let general_lines: Vec<&str> = general_string.split("\n").collect();
for line in general_lines{
if line.contains("|"){
if !line.contains("range"){
if !line.contains("--"){
let items: Vec<&str> = line.split("|").collect();
let scop_item = items[1].trim();
println!("{} LOADED!!", scop_item);
scope_ranges.push(scop_item);
}
}
}
}
println!("scope loaded, parsing ip ranges...");
let mut ips = Vec::new();
for item in scope_ranges{
if item.contains("/"){
let network_split: Vec<&str> = item.split("/").collect();
let network_part = network_split[0];
let cidr = network_split[1];
let network_octets: Vec<&str> = network_part.split(".").collect();
let mut ip = String::new();
match cidr{
"24" => {let partial_ip = format!("{}.{}.{}.N", network_octets[0], network_octets[1], network_octets[2]);
ip.push_str(partial_ip);
},
"16" => {let partial_ip = format!("{}.{}.N.N", network_octets[0], network_octets[1]);
ip.push_str(partial_ip);},
"8" => {let partial_ip = format!("{}.N.N.N", network_octets[0]); ip.push_str(partial_ip)}
}
}
}
}
*/
pub fn get_all_host_addresses(project: &Project){
println!("to do");
}
pub fn get_scope_entries(project: &Project) -> Option<Vec<String>>{
let mut general_path = project.notes_folder.clone();
general_path.push("general.md");
let genera_read_res = read_to_string(general_path);
if genera_read_res.is_err(){
let error = genera_read_res.err().unwrap();
println!("ooof error reading your general notes file!");
println!("{}", error);
return None;
}
let general_string = genera_read_res.unwrap();
let mut read_first_entry = false;
let general_lines: Vec<&str> = general_string.split("\n").collect();
let mut hosts = Vec::new();
for line in general_lines{
if line.contains("|"){
if !line.contains("--"){
if read_first_entry{
let data: Vec<&str> = line.split("|").collect();
let scope_entry = data[1].trim();
println!("{} found!", scope_entry);
hosts.push(scope_entry.to_owned());
}
else{
read_first_entry = true;
}
}
}
}
return Some(hosts);
}

View File

@@ -1,9 +1,16 @@
use std::fs;
use std::fs::{self, OpenOptions};
use std::fs::{read_to_string, create_dir_all};
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use chrono::format::format;
use reqwest::blocking::get;
use walkdir::WalkDir;
use crate::get_user_input;
use crate::Project;
use crate::open_overwrite;
use crate::open_append;
use crate::info_controls;
pub fn parse_normal_nmap_output(project: &Project){
let mut found_file = false;
@@ -131,4 +138,520 @@ pub fn parse_normal_nmap_output(project: &Project){
println!("error writing data to the tsv file...");
}
}
}
pub fn build_cs_portscan_cmd(project: &Project){
let mut general_note_path = project.notes_folder.clone();
general_note_path.push("general.md");
println!("Reading from: {}", general_note_path.display());
let mut ranges = Vec::new();
let general_note_string = read_to_string(general_note_path);
let mut _note_string = String::new();
match general_note_string{
Err(error) => {println!("error reading file to string!! {}", error); return;},
_=> _note_string = general_note_string.unwrap()
}
let lines: Vec<&str> = _note_string.split("\n").collect();
for line in lines{
if line.contains("|"){
if line.contains("."){
let ip = line.split("|").collect::<Vec<&str>>()[1];
if ip.contains(","){
let ips: Vec<&str> = ip.split(",").collect();
for ip in ips{
ranges.push(ip.trim_end().trim_start());
}
}
else{
ranges.push(ip.trim_end().trim_start());
}
}
}
}
let portscan_cmd = "portscan !!! 1-1024,1433,2222,3306,3389,5000-6000,8000,8080,8443 icmp 512";
let mut _range_command = String::new();
let combined_ranges = ranges.join(",");
let final_command = portscan_cmd.replace("!!!", &combined_ranges);
println!("{}", final_command);
}
pub fn build_cmd_for_host_discovery(project: &Project){
let mut cobalt_strike_response = String::new();
let mut need_shell = false;
println!("will you be running this via cobalt strike? (do you need it to start with \"shell\"?");
let input_result = std::io::stdin().read_line(&mut cobalt_strike_response);
if input_result.is_err(){
println!("error getting user input... not really sure how you did this... just pressing enter would work..... wow");
return;
}
if cobalt_strike_response.to_lowercase().contains("y"){
need_shell = true;
}
let mut general_note_path = project.notes_folder.clone();
general_note_path.push("general.md");
println!("Reading from: {}", general_note_path.display());
let mut ranges = Vec::new();
let general_note_string = read_to_string(general_note_path);
let mut _note_string = String::new();
match general_note_string{
Err(error) => {println!("error reading file to string!! {}", error); return;},
_=> _note_string = general_note_string.unwrap()
}
let lines: Vec<&str> = _note_string.split("\n").collect();
for line in lines{
if line.contains("|"){
if line.contains("."){
let ip = line.split("|").collect::<Vec<&str>>()[1];
if ip .contains(","){
let ips: Vec<&str> = ip.split(",").collect();
for ip in ips{
ranges.push(ip.trim_end().trim_start());
}
}
else{
ranges.push(ip.trim_end().trim_start());
}
}
}
}
let mut _discovery_command = "";
_discovery_command = "(for /L %a IN (1,1,254) DO ping /n 1 /w 3 !!!.%a) | find \"Reply\"";
let mut final_command = String::new();
for range in ranges{
let mut network: Vec<&str> = range.split(".").collect();
network.pop();
let network_string = network.join(".");
let mut _range_command = String::new();
if need_shell{
_range_command = format!("{}{}","shell ", _discovery_command.replace("!!!", &network_string));
need_shell = false;
}
else{
_range_command = _discovery_command.replace("!!!", &network_string);
}
final_command.push_str(_range_command.as_str());
final_command.push_str(">> ping_only_replies.txt &");
}
final_command.pop();
println!("{}", final_command);
}
pub fn parse_csportscan(project: &Project){
let mut tsv_path = project.files_folder.clone();
tsv_path.push("working/tsvs/services.tsv");
let mut outfile = tsv_path.clone();
outfile.pop();
outfile.pop();
let mut windows_hosts = Vec::new();
let mut ssh_hosts = Vec::new();
let mut ftp_hosts = Vec::new();
let mut rdp_hosts = Vec::new();
let mut dns_hosts = Vec::new();
let mut snmp_hosts = Vec::new();
let mut web_hosts = Vec::new();
let mut telnet_hosts = Vec::new();
let mut unknown_ports = Vec::new();
if !get_user_input("do you have the tsv saved in the project folder under working/tsvs/services.tsv?").to_lowercase().contains("y"){
tsv_path.clear();
tsv_path.push(get_user_input("ooof ok, please enter the full path to your tsv file."));
}
let tsv_read_res = read_to_string(tsv_path);
if tsv_read_res.is_err(){
let error = tsv_read_res.err().unwrap();
println!("ooof error reading tsv file!");
println!("{}", error);
return;
}
println!("tsv read, parsing lines...");
let tsv_string = tsv_read_res.unwrap();
let lines: Vec<&str> = tsv_string.split("\n").collect();
for line in lines{
let words: Vec<&str> = line.split("\t").collect();
if words.len() > 1{
let host = words[0].to_lowercase().to_owned();
let port = words[1].to_lowercase().to_owned();
let host_entry = format!("{}:{}", &host, &port);
match words[1]{
"135" => {if !windows_hosts.contains(&host){windows_hosts.push(host)}},
"445" => {if !windows_hosts.contains(&host){windows_hosts.push(host)}},
"22" => {if !ssh_hosts.contains(&host){ssh_hosts.push(host);}},
"21" => {if !ftp_hosts.contains(&host){ftp_hosts.push(host);}},
"23" => {if !telnet_hosts.contains(&host){telnet_hosts.push(host)}},
"3389" => {if !rdp_hosts.contains(&host){rdp_hosts.push(host);}},
"80" | "443" | "8080" | "8443" | "4433" | "8000" => {if !web_hosts.contains(&host_entry){web_hosts.push(host_entry);}},
"53" => {if !dns_hosts.contains(&host){dns_hosts.push(host);}},
"161" => {if !snmp_hosts.contains(&host){snmp_hosts.push(host);}},
_ => {
if words.len() == 3{
let banner = words[2].to_lowercase().to_owned();
if words[2].to_lowercase().contains("ssh"){
if !ssh_hosts.contains(&host_entry){
ssh_hosts.push(host_entry);
}
}
else if banner.contains("ftp"){
if !ftp_hosts.contains(&host_entry){
ftp_hosts.push(host_entry);
}
}
else if banner.contains("nginx") || banner.contains("apache"){
if !web_hosts.contains(&host_entry){
web_hosts.push(host_entry);
}
}
else{
continue;
}
}
else if words.len() == 2{
unknown_ports.push(host_entry);
}
}
}
}
}
println!("is {} where you want to save your files?", outfile.display());
if get_user_input("").to_lowercase().contains("n"){
outfile.clear();
outfile.push(get_user_input("ok, please enter the full path to the folder you want to save them to."));
}
print!("
{} Windows hosts found!
{} SSH hosts found!
{} FTP hosts found!
{} Telnet hosts found!
{} SNMP hosts found!
{} DNS hosts found!
{} RDP hosts found!
{} untagged hosts found!
", windows_hosts.len(), ssh_hosts.len(), ftp_hosts.len(), telnet_hosts.len(), snmp_hosts.len(), dns_hosts.len(), rdp_hosts.len(), unknown_ports.len());
println!("lines parsed! creating output files...");
outfile.push("windows_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut windows_file = file_option.unwrap();
for host in windows_hosts{
let write_res = write!(windows_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing windows_hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("ssh_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut ssh_file = file_option.unwrap();
for host in ssh_hosts{
let write_res = write!(ssh_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing ssh_hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("telnet_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut telnet_file = file_option.unwrap();
for host in telnet_hosts{
let write_res = write!(telnet_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("ftp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut ftp_file = file_option.unwrap();
for host in ftp_hosts{
let write_res = write!(ftp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("snmp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut snmp_file = file_option.unwrap();
for host in snmp_hosts{
let write_res = write!(snmp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("dns_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut dns_file = file_option.unwrap();
for host in dns_hosts{
let write_res = write!(dns_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("rdp_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut rdp_file = file_option.unwrap();
for host in rdp_hosts{
let write_res = write!(rdp_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
outfile.pop();
outfile.push("web_hosts.txt");
let file_option = open_overwrite(&outfile);
if file_option.is_some(){
let mut web_file = file_option.unwrap();
for host in web_hosts{
let write_res = write!(web_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("oooof error writing _hosts.txt!!");
println!("{}", error);
}
else{
write_res.unwrap();
}
}
}
println!("interesting ports have been written to... writing untagged port files...");
outfile.pop();
outfile.push("untagged ports");
if !outfile.exists(){
let untagged_res = create_dir_all(&outfile);
if untagged_res.is_err(){
let error = untagged_res.err().unwrap();
println!("ooof error creating untagged folder!");
println!("{}", error);
}
else{
untagged_res.unwrap();
}
}
for line in unknown_ports{
let line_vec:Vec<&str> = line.split(":").collect();
let host = line_vec[0].to_owned();
let port = line_vec[1].to_owned();
let file_name = format!("{}_hosts.txt", port);
outfile.push(file_name);
let write_file_opt = open_append(&outfile);
if write_file_opt.is_some(){
let mut write_file = write_file_opt.unwrap();
let write_res = write!(write_file, "{}\n", host);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("ooof error writing to file...");
println!("{}", error);
}
}
outfile.pop();
}
println!("DONE all files saved to {}", outfile.display());
println!("note if no hosts were found for a protocol their files will be empty.");
}
pub fn run_nmap_portscan(project: &Project){
let files_folder = project.files_folder.clone();
let notes_folder = project.notes_folder.clone();
let mut ports_to_scan = vec![String::from("80"), String::from("443"),
String::from("161"),
String::from("22"),
String::from("21"),
String::from("23"),
String::from("8080"),
String::from("8443"),
String::from("4433"),
String::from("135"),
String::from("445"),
String::from("3389"),
String::from("5985"),
String::from("1433"),
String::from("3306"),
String::from("2222"),];
let mut save_path = files_folder.clone();
let mut general_notes = notes_folder.clone();
general_notes.push("general.md");
println!("building targets from scope in general notes...");
let targets_res = info_controls::get_scope_entries(project);
if targets_res.is_none(){
return;
}
let mut targets = targets_res.unwrap();
println!("Got targets from scope!");
for target in &targets{
println!("{}", target);
}
if get_user_input("does this list look ok?").to_lowercase().contains("n"){
let mut modified_targets = targets.clone();
let mut targets_to_remove = Vec::new();
let mut targets_ready = false;
while !targets_ready{
println!("current target list:");
for target in &modified_targets{
if &targets_to_remove.contains(target) == &false{
println!("{}", target);
}
}
let response = get_user_input("\nc to continue as is\na to add a target to the list\nr to remove a target from the list\nf to start fresh with a blank list of targets");
match response.as_str(){
"c" => targets_ready = true,
"a" => {let new_target = get_user_input("target to add?"); let _ = &mut modified_targets.push(new_target);},
"r" => {let _ = targets_to_remove.push(get_user_input("target to remove?"));},
"f" => {let _ = &mut modified_targets.clear();}
_ => println!("unknown selection"),
}
}
for target in &targets{
println!("{}", target);
}
println!("\nwill be replace with\n");
for target in &modified_targets{
println!("{}", target);
}
if get_user_input("continue?").to_lowercase().contains("n"){
println!("ok exiting this function, feel free to try again...");
return;
}
targets = modified_targets;
}
println!("the standard ports I scan are:");
for port in &ports_to_scan{
println!("{}", port);
}
if get_user_input("is this ok?").to_lowercase().contains("n"){
let mut ports_ready = false;
ports_to_scan.clear();
while !ports_ready{
let response = get_user_input("enter a port to scan in the nmap format. For example 80-100 or 80,443 Enter END in all caps when you're done.");
match response.as_str(){
"END" => ports_ready = true,
_ => ports_to_scan.push(response),
}
}
}
let proxy = get_user_input("will you be using proxychains for this scan?").to_lowercase();
println!("sweet we have what we need!");
println!("building portscan command...");
let port_string = ports_to_scan.join(",");
let hosts_string = targets.join(" ");
let mut scan_results = String::new();
if proxy.contains("y"){
println!("running command, this may take a bit of time...");
let command_res = Command::new("distrobox")
.arg("enter")
.arg("--root")
.arg(project.boxname.to_owned())
.arg("--")
.arg("proxychains")
.arg("namp")
.arg("-sT")
.arg("-p")
.arg(port_string)
.arg(hosts_string)
.output();
if command_res.is_err(){
let error = command_res.err().unwrap();
println!("error running portscan command!");
println!("{}", error);
return;
}
let output = command_res.unwrap().stdout;
scan_results = String::from_utf8_lossy(&output).into_owned();
}
else{
let command_res = Command::new("distrobox")
.arg("enter")
.arg("--root")
.arg(project.boxname.to_owned())
.arg("--")
.arg("proxychains")
.arg("namp")
.arg("-sT")
.arg("-p")
.arg(port_string)
.arg(hosts_string)
.output();
if command_res.is_err(){
let error = command_res.err().unwrap();
println!("error running portscan command!");
println!("{}", error);
return;
}
let output = command_res.unwrap().stdout;
scan_results = String::from_utf8_lossy(&output).into_owned();
}
save_path.push("working/nmap_output.txt");
println!("going to save to {}", save_path.display());
if get_user_input("is that ok?").to_lowercase().contains("n"){
save_path.clear();
save_path.push(get_user_input("where do you want to save it then? (full path)"));
}
let save_file_res = OpenOptions::new().create(true).append(true).open(save_path);
if save_file_res.is_err(){
let error = save_file_res.err().unwrap();
println!("error opening save file!");
println!("{}", error);
if get_user_input("output results to console?").to_lowercase().contains("y"){
println!("{}", &scan_results);
}
return;
}
let mut save_file = save_file_res.unwrap();
let write_res = write!(save_file, "{}", scan_results);
if write_res.is_err(){
let error = write_res.err().unwrap();
println!("error writing results to file!");
println!("{}", error);
if get_user_input("print results to console instead?").to_lowercase().contains("y"){
println!("{}", scan_results);
}
}
}