diff --git a/certify_parser/Cargo.lock b/certify_parser/Cargo.lock new file mode 100644 index 0000000..c5387a0 --- /dev/null +++ b/certify_parser/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "certify_parser" +version = "0.1.0" diff --git a/certify_parser/Cargo.toml b/certify_parser/Cargo.toml new file mode 100644 index 0000000..9eea0be --- /dev/null +++ b/certify_parser/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "certify_parser" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/certify_parser/src/main.rs b/certify_parser/src/main.rs new file mode 100644 index 0000000..d632c07 --- /dev/null +++ b/certify_parser/src/main.rs @@ -0,0 +1,174 @@ +use std::fs; +use std::env; + +struct certificate{ + writedacl: bool, + full: bool, + client_auth: bool, + enrollee_supplies_subject: bool, + ca: String, + template_name: String, + +} + +struct enterpriseca{ + ca_name: String, + manage_ca: bool, +} + + +fn parse_enterprise_ca(certificate_texts: &str, groups: &Vec<&str>) -> enterpriseca{ + let ca_name = certificate_texts.split("Enterprise CA Name").collect::>()[1].split("\n").collect::>()[0].split(":").collect::>()[1].trim_end().trim_start().to_owned(); + println!("{ca_name}"); + let manageca_lines: Vec<&str> = certificate_texts.split("\n").collect(); + let mut manageca_groups: Vec<&str> = Vec::new(); + for line in manageca_lines{ + if line.contains("Allow"){ + if line.contains("ManageCA"){ + let group = line.split("\n").collect::>()[0].split(" ").collect::>()[24]; + manageca_groups.push(group); + } + } + } + let mut manageca = false; + for group in groups{ + if manageca_groups.contains(&group){ + manageca = true; + } + } + + let enterpriseca = enterpriseca{ca_name: ca_name, manage_ca: manageca}; + return enterpriseca; +} + +fn parse_certificates(certificate_texts: Vec<&str>, groups: &Vec<&str>) -> Vec{ + let mut certificates: Vec = Vec::new(); + for certificate in certificate_texts{ + let mut client_auth = false; + let mut enrollee_supplies_subject = false; + let mut write_owner_groups: Vec<&str> = Vec::new(); + let mut writedacl_groups: Vec<&str> = Vec::new(); + let mut fullcontrol_groups: Vec<&str> = Vec::new(); + let certificate_name = certificate.split("\n").collect::>()[0].split(":").collect::>()[0].trim_end().trim_start(); + println!("{certificate_name}"); + let ca_name = certificate.split("Template Name").collect::>()[0].split("\n").collect::>()[0].split(":").collect::>()[1].trim_end().trim_start(); + if certificate.contains("Client Authentication"){ + client_auth = true; + } + if certificate.contains("ENROLLEE_SUPPLIES_SUBJECT"){ + enrollee_supplies_subject = true; + } + let permissions = certificate.split("Permissions").collect::>()[1]; + let mut current_permission = "unknown"; + for line in permissions.split("\n"){ + if line.contains("\\"){ + if line.contains(":"){ + let line_split: Vec<&str> = line.split(":").collect(); + let group = line_split[1].split("S").collect::>()[0].trim_end().trim_start(); + current_permission = line_split[0]; + if current_permission.contains("WriteOnwer"){ + write_owner_groups.push(group); + } + else if current_permission.contains("WriteDacl"){ + writedacl_groups.push(group); + } + else if current_permission.contains("Full Control"){ + fullcontrol_groups.push(group); + } + } + } + } + let mut writedacl = false; + let mut full = false; + for group in groups{ + writedacl = write_owner_groups.contains(group) || writedacl_groups.contains(group); + full = fullcontrol_groups.contains(group); + } + let new_certificate = certificate{writedacl: writedacl, full: full, client_auth: client_auth, enrollee_supplies_subject: enrollee_supplies_subject, template_name: certificate_name.to_owned(), ca: ca_name.to_owned()}; + certificates.push(new_certificate); + } + return certificates; +} +fn main() { + print!(" +_ __ __ __ ______ __ _ ____ ____ +| | / /__ / /________ ____ ___ ___ / /_____ / ____/__ _____/ /_(_) __/_ __ / __ \\____ ______________ _____ +| | /| / / _ \\/ / ___/ __ \\/ __ `__ \\/ _ \\ / __/ __ \\ / / / _ \\/ ___/ __/ / /_/ / / / / /_/ / __ `/ ___/ ___/ _ \\/ ___/ +| |/ |/ / __/ / /__/ /_/ / / / / / / __/ / /_/ /_/ / / /___/ __/ / / /_/ / __/ /_/ / / ____/ /_/ / / (__ ) __/ / +|__/|__/\\___/_/\\___/\\____/_/ /_/ /_/\\___/ \\__/\\____/ \\____/\\___/_/ \\__/_/_/ \\__, /____/_/ \\__,_/_/ /____/\\___/_/ +"); + let args: Vec = env::args().collect(); + if args.len() < 2{ + print!(" +USAGE: +certify_parser /path/to/certify/output/text/file /path/to/list/of/user/groups + "); + } + else{ + let user_groups: Vec<&str> = Vec::new(); + let certificates: Vec = Vec::new(); + let group_string = fs::read_to_string(&args[2]).expect("error reading groups file"); + let certify_output_string = fs::read_to_string(&args[1]).expect("error reading certify file"); + let certificate_texts: Vec<&str> = certify_output_string.split("[*] Available Certificates Templates :").collect::>()[1].split("CA Name").collect(); + let enterprise_cas = certify_output_string.split("[*] Available Certificates Templates :").collect::>()[0]; + let group_string_lines: Vec<&str> = group_string.split("\n").collect(); + println!("gathering user groups from text file..."); + for line in group_string_lines{ + if line.len()>0{ + let line_split:Vec<&str> = line.split(" ").collect(); + let group_name = line_split[0]; + println!("{group_name}"); + } + } + println!("groups gathered successfully"); + println!("gathering certificate information..."); + let enterpriseca = parse_enterprise_ca(&enterprise_cas, &user_groups); + let certificates = parse_certificates(certificate_texts, &user_groups); + println!("DONE PARSING! {} Certificate Templates Discovered!!!", certificates.len()); + println!("\n\n\n\n\n\n"); + if enterpriseca.manage_ca == true{ + println!("we Can Manage The CA!!!!!!!"); + println!("{}",enterpriseca.ca_name); + println!("\n\n\n"); + } + println!("collecting certificates into useful groupings...\n\n\n"); + let mut full_control: Vec = Vec::new(); + let mut writedacl: Vec = Vec::new(); + let mut enrollee_supplies: Vec = Vec::new(); + for certificate in certificates{ + if certificate.client_auth{ + if certificate.full{ + full_control.push(certificate); + } + else if certificate.writedacl{ + writedacl.push(certificate); + } + else if certificate.enrollee_supplies_subject{ + enrollee_supplies.push(certificate); + } + + } + } + if full_control.len()>0{ + println!("here are the client auth templates we have full control over!\n"); + for certificate in full_control{ + println!("CA:{}\nName{}", certificate.ca, certificate.template_name); + } + println!("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + if writedacl.len()>0{ + println!("here are the client auth templates we have writedacl to"); + for certificate in writedacl{ + println!("CA:{}\nName{}", certificate.ca, certificate.template_name); + } + println!("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + if enrollee_supplies.len()>0{ + println!("here are the client auth templates where enrolee supplies alt name"); + for certificate in enrollee_supplies{ + println!("CA:{}\nName{}", certificate.ca, certificate.template_name); + } + println!("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); + } + } +}