rusthound_ce/json/parser/
mod.rs

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