pub mod adcs;
pub mod gpo;
pub mod resolver;
pub mod sessions;
use std::error::Error;
use rayon::prelude::*;
use crate::api::ADResults;
use crate::args::{CollectionMethod, Options};
use crate::modules::adcs::probe_enterpriseca_esc8;
pub async fn run_modules(common_args: &Options, ad: &mut ADResults) -> Result<(), Box<dyn Error>> {
if common_args.fqdn_resolver {
resolver::resolv::resolving_all_fqdn(
common_args.dns_tcp,
&common_args.name_server,
&mut ad.mappings.fqdn_ip,
&ad.computers,
)
.await;
}
if common_args.collection_method.does_sessions() {
sessions::run(common_args, &ad.users, &mut ad.computers).await?;
}
if !matches!(common_args.collection_method, CollectionMethod::DCOnly)
&& !matches!(common_args.collection_method, CollectionMethod::LdapOnly)
&& !ad.enterprisecas.is_empty()
{
log::info!(
"Starting ESC8 web enrollment probe on {} CA(s)...",
ad.enterprisecas.len()
);
ad.enterprisecas.par_iter_mut().for_each(|ca| {
let esc8 = probe_enterpriseca_esc8(ca.dns_host());
ca.apply_esc8(esc8.http_enrollment_endpoints);
});
}
if common_args.collection_method.does_gpo() {
let computer_scope = gpo::sysvol::ComputerGpoScope::from_gpos(&ad.gpos);
let sysvol = match collect_sysvol_targets(common_args, &computer_scope).await {
Ok(v) => v,
Err(e) => {
log::warn!("[gpo] SYSVOL collection failed: {e}");
Vec::new()
}
};
if !sysvol.is_empty() {
log::info!(
"[gpo] mapping {} GPO(s) to GPOChanges / UserRights",
sysvol.len()
);
gpo::apply_gpo(
&mut ad.ous,
&mut ad.domains,
&ad.users,
&ad.groups,
&mut ad.computers,
&sysvol,
&ad.mappings.dn_sid,
);
}
}
Ok(())
}
async fn collect_sysvol_targets(
common_args: &Options,
computer_scope: &gpo::sysvol::ComputerGpoScope,
) -> anyhow::Result<Vec<gpo::SysvolGpo>> {
use crate::transport::smb::{nt_hash_from_str, SmbAuth};
let user = common_args.username.clone().unwrap_or_default();
let password = common_args.password.clone().unwrap_or_default();
let nt = common_args.hashes.as_deref().and_then(nt_hash_from_str);
let auth = match &nt {
Some(h) => SmbAuth::Hash(h),
None => SmbAuth::Password(&password),
};
let dc_host = common_args
.ip
.as_deref()
.filter(|s| !s.is_empty())
.or(common_args.ldapfqdn.as_deref())
.map(str::to_string)
.unwrap_or_else(|| common_args.domain.clone());
if dc_host.is_empty() {
log::warn!(
"[gpo] no SMB target (ip/ldapfqdn/domain) available, skipping SYSVOL collection"
);
return Ok(Vec::new());
}
gpo::collect_sysvol(
&dc_host,
&common_args.domain,
&common_args.domain,
&user,
auth,
computer_scope,
)
.await
}