rusthound_ce/json/parser/
mod.rs

1use std::collections::HashMap;
2use std::error::Error;
3use ldap3::SearchEntry;
4use indicatif::ProgressBar;
5use crate::objects::common::parse_unknown;
6use crate::objects::{
7    user::User,
8    computer::Computer,
9    group::Group,
10    ou::Ou,
11    container::Container,
12    gpo::Gpo,
13    domain::Domain,
14    fsp::Fsp,
15    trust::Trust,
16    ntauthstore::NtAuthStore,
17    aiaca::AIACA,
18    rootca::RootCA,
19    enterpriseca::EnterpriseCA,
20    certtemplate::CertTemplate,
21    inssuancepolicie::IssuancePolicie,
22};
23use std::convert::TryInto;
24
25use log::info;
26use crate::args::Options;
27use crate::banner::progress_bar;
28use crate::enums::ldaptype::*;
29use crate::enums::regex::{PARSER_MOD_RE1,PARSER_MOD_RE2};
30
31// use crate::modules::adcs::parser::{parse_adcs_ca,parse_adcs_template};
32
33/// Function to get type for object by object
34pub fn parse_result_type(
35    common_args:            &Options, 
36    result:                 Vec<SearchEntry>,
37    vec_users:              &mut Vec<User>,
38    vec_groups:             &mut Vec<Group>,
39    vec_computers:          &mut Vec<Computer>,
40    vec_ous:                &mut Vec<Ou>,
41    vec_domains:            &mut Vec<Domain>,
42    vec_gpos:               &mut Vec<Gpo>,
43    vec_fsps:               &mut Vec<Fsp>,
44    vec_containers:         &mut Vec<Container>,
45    vec_trusts:             &mut Vec<Trust>,
46    vec_ntauthstore:        &mut Vec<NtAuthStore>,
47    vec_aiacas:             &mut Vec<AIACA>,
48    vec_rootcas:            &mut Vec<RootCA>,
49    vec_enterprisecas:      &mut Vec<EnterpriseCA>,
50    vec_certtemplates:      &mut Vec<CertTemplate>,
51    vec_issuancepolicies:   &mut Vec<IssuancePolicie>,
52
53    dn_sid:             &mut HashMap<String, String>,
54    sid_type:           &mut HashMap<String, String>,
55    fqdn_sid:           &mut HashMap<String, String>,
56    fqdn_ip:            &mut HashMap<String, String>,
57    // adcs_templates: &mut HashMap<String, Vec<String>>,
58) -> Result<(), Box<dyn Error>> {
59    // Domain name
60    let domain = &common_args.domain;
61
62    // Needed for progress bar stats
63    let pb = ProgressBar::new(1);
64    let mut count = 0;
65    let total = result.len();
66    let mut domain_sid: String = "DOMAIN_SID".to_owned();
67
68    info!("Starting the LDAP objects parsing...");
69    for entry in result {
70        // Start parsing with Type matching
71        let cloneresult = entry.clone();
72        //println!("{:?}",&entry);
73        let atype = get_type(&entry).unwrap_or(Type::Unknown);
74        match atype {
75            Type::User => {
76                let mut user: User = User::new();
77                user.parse(
78                    cloneresult,
79                    domain,
80                    dn_sid,
81                    sid_type,
82                    &domain_sid
83                )?;
84                vec_users.push(user);
85            }
86            Type::Group => {
87                let mut group = Group::new();
88                group.parse(
89                    cloneresult,
90                    domain,
91                    dn_sid,
92                    sid_type,
93                    &domain_sid
94                )?;
95                vec_groups.push(group);
96            }
97            Type::Computer => {
98                let mut computer = Computer::new();
99                computer.parse(
100                    cloneresult,
101                    domain,
102                    dn_sid,
103                    sid_type,
104                    fqdn_sid,
105                    fqdn_ip,
106                    &domain_sid
107                )?;
108                vec_computers.push(computer);
109            }
110            Type::Ou => {
111                let mut ou = Ou::new();
112                ou.parse(
113                    cloneresult,
114                    domain,
115                    dn_sid,
116                    sid_type,
117                    &domain_sid
118                )?;
119                vec_ous.push(ou);
120            }
121            Type::Domain => {
122                let mut domain_object = Domain::new();
123                let domain_sid_from_domain = domain_object.parse(
124                    cloneresult,
125                    domain,
126                    dn_sid,
127                    sid_type,
128                )?;
129                domain_sid = domain_sid_from_domain;
130                // Only add domains with valid ObjectIdentifier (excludes DomainDnsZones, ForestDnsZones, etc.)
131                if !domain_object.object_identifier().is_empty() {
132                    vec_domains.push(domain_object);
133                }
134            }
135            Type::Gpo => {
136                let mut  gpo = Gpo::new();
137                gpo.parse(
138                    cloneresult,
139                    domain,
140                    dn_sid,
141                    sid_type,
142                    &domain_sid
143                )?;
144                vec_gpos.push(gpo);
145            }
146            Type::ForeignSecurityPrincipal => {
147                let mut security_principal = Fsp::new();
148                security_principal.parse(
149                    cloneresult,
150                    domain,
151                    dn_sid,
152                    sid_type,
153                    &domain_sid
154                )?;
155                vec_fsps.push(security_principal);
156            }
157            Type::Container => {
158                if PARSER_MOD_RE1.is_match(&cloneresult.dn.to_uppercase()) 
159                {
160                    //trace!("Container not to add: {}",&cloneresult.dn.to_uppercase());
161                    continue
162                }
163                if PARSER_MOD_RE2.is_match(&cloneresult.dn.to_uppercase()) 
164                {
165                    //trace!("Container not to add: {}",&cloneresult.dn.to_uppercase());
166                    continue
167                }
168                //trace!("Container: {}",&cloneresult.dn.to_uppercase());
169                let mut container = Container::new();
170                container.parse(
171                    cloneresult,
172                    domain,
173                    dn_sid,
174                    sid_type,
175                    &domain_sid
176                )?;
177                vec_containers.push(container);
178            }
179            Type::Trust => {
180                let mut trust = Trust::new();
181                trust.parse(
182                    cloneresult,
183                    domain
184                )?;
185                vec_trusts.push(trust);
186            }
187            Type::NtAutStore => {
188                let mut nt_auth_store = NtAuthStore::new();
189                nt_auth_store.parse(
190                    cloneresult,
191                    domain,
192                    dn_sid,
193                    sid_type,
194                    &domain_sid
195                )?;
196                vec_ntauthstore.push(nt_auth_store); 
197            }
198            Type::AIACA => {
199                let mut aiaca = AIACA::new();
200                aiaca.parse(
201                    cloneresult,
202                    domain,
203                    dn_sid,
204                    sid_type,
205                    &domain_sid
206                )?;
207                vec_aiacas.push(aiaca); 
208            }
209            Type::RootCA => {
210                let mut root_ca = RootCA::new();
211                root_ca.parse(
212                    cloneresult,
213                    domain,
214                    dn_sid,
215                    sid_type,
216                    &domain_sid
217                )?;
218                vec_rootcas.push(root_ca); 
219            }
220            Type::EnterpriseCA => {
221                let mut enterprise_ca = EnterpriseCA::new();
222                enterprise_ca.parse(
223                    cloneresult,
224                    domain,
225                    dn_sid,
226                    sid_type,
227                    &domain_sid
228                )?;
229                vec_enterprisecas.push(enterprise_ca); 
230            }
231            Type::CertTemplate => {
232                let mut cert_template = CertTemplate::new();
233                cert_template.parse(
234                    cloneresult,
235                    domain,
236                    dn_sid,
237                    sid_type,
238                    &domain_sid
239                )?;
240                vec_certtemplates.push(cert_template);
241            }
242            Type::IssuancePolicie => {
243                let mut issuance_policie = IssuancePolicie::new();
244                issuance_policie.parse(
245                    cloneresult,
246                    domain,
247                    dn_sid,
248                    sid_type,
249                    &domain_sid
250                )?;
251                vec_issuancepolicies.push(issuance_policie);
252            }
253            Type::Unknown => {
254                let _unknown = parse_unknown(cloneresult, domain);
255            }
256        }
257        // Manage progress bar
258        // Pourcentage (%) = 100 x Valeur partielle/Valeur totale
259		count += 1;
260        let pourcentage = 100 * count / total;
261        progress_bar(pb.to_owned(),"Parsing LDAP objects".to_string(),pourcentage.try_into()?,"%".to_string());
262    }
263    pb.finish_and_clear();
264    info!("Parsing LDAP objects finished!");
265    Ok(())
266}