Skip to main content

rusthound_ce/objects/
common.rs

1use std::collections::HashMap;
2
3use ldap3::SearchEntry;
4use log::trace;
5use serde_json::{json,value::Value};
6use serde::{Deserialize, Serialize};
7
8
9/// LdapObject structure
10pub trait LdapObject {
11   // Ldap object structure (User,Group,Computer...) to JSON
12   fn to_json(&self) -> Value;
13
14   // Get values
15   fn get_object_identifier(&self) -> &String;
16   fn get_is_acl_protected(&self) -> &bool;
17   fn get_aces(&self) -> &Vec<AceTemplate>;
18   fn get_spntargets(&self) -> &Vec<SPNTarget>;
19   fn get_allowed_to_delegate(&self) -> &Vec<Member>;
20   fn get_links(&self) -> &Vec<Link>;
21   fn get_contained_by(&self) -> &Option<Member>;
22   fn get_child_objects(&self) -> &Vec<Member>;
23   // Only for computer objects
24   fn get_haslaps(&self) -> &bool;
25
26   // Get mutable value
27   fn get_aces_mut(&mut self) -> &mut Vec<AceTemplate>;
28   fn get_spntargets_mut(&mut self) -> &mut Vec<SPNTarget>;
29   fn get_allowed_to_delegate_mut(&mut self) -> &mut Vec<Member>;
30
31   // Edit values
32   fn set_is_acl_protected(&mut self, is_acl_protected: bool);
33   fn set_aces(&mut self, aces: Vec<AceTemplate>);
34   fn set_spntargets(&mut self, spn_targets: Vec<SPNTarget>);
35   fn set_allowed_to_delegate(&mut self, allowed_to_delegate: Vec<Member>);
36   fn set_links(&mut self, links: Vec<Link>);
37   fn set_contained_by(&mut self, contained_by: Option<Member>);
38   fn set_child_objects(&mut self, child_objects: Vec<Member>);
39   fn set_owner_rights_flags(&mut self, _any: bool, _any_inherited: bool);
40}
41
42/// LocalGroup structure
43#[derive(Debug, Clone, Deserialize, Serialize, Default)]
44pub struct LocalGroup {
45   #[serde(rename = "ObjectIdentifier")]
46   object_identifier: String,
47   #[serde(rename = "Name")]
48   name: String,
49   #[serde(rename = "Results")]
50   results: Vec<Member>,
51   #[serde(rename = "LocalNames")]
52   local_names: Vec<String>,
53   #[serde(rename = "Collected")]
54   collected: bool,
55   #[serde(rename = "FailureReason")]
56   failure_reason: Option<String>,
57}
58
59impl LocalGroup {
60   // New Local Group.
61   pub fn new() -> Self { 
62      Self { 
63         ..Default::default()
64      }
65   }
66
67   // Immutable access.
68   pub fn object_identifier(&self) -> &String {
69      &self.object_identifier
70   }
71   pub fn results(&self) -> &Vec<Member> {
72      &self.results
73   }
74   pub fn local_names(&self) -> &Vec<String> {
75      &self.local_names
76   }
77   pub fn collected(&self) -> &bool {
78      &self.collected
79   }
80   pub fn failure_reason(&self) -> &Option<String> {
81      &self.failure_reason
82   }
83
84   // Mutable access.
85   pub fn object_identifier_mut(&mut self) -> &mut String {
86      &mut self.object_identifier
87   }
88   pub fn name_mut(&mut self) -> &mut String {
89      &mut self.name
90   }
91   pub fn results_mut(&mut self) -> &mut Vec<Member> {
92      &mut self.results
93   }
94   pub fn local_names_mut(&mut self) -> &mut Vec<String> {
95      &mut self.local_names
96   }
97   pub fn collected_mut(&mut self) -> &mut bool {
98      &mut self.collected
99   }
100   pub fn failure_reason_mut(&mut self) -> &mut Option<String> {
101      &mut self.failure_reason
102   }
103}
104
105/// Session structure
106#[derive(Debug, Clone, Deserialize, Serialize)]
107pub struct Session {
108   #[serde(rename = "Results")]
109   results: Vec<UserComputerSession>,
110   #[serde(rename = "Collected", default = "default_true")]
111   collected: bool,
112   #[serde(rename = "FailureReason")]
113   failure_reason: Option<String>,
114}
115
116impl Default for Session {
117   /// Default values for Session structure.
118   fn default() -> Session {
119      Session {
120         results: Vec::new(),
121         collected: true,
122         failure_reason: None,
123       }
124   }
125}
126
127impl Session {
128   // New session.
129   pub fn new() -> Self { 
130      Self { 
131         collected: true,
132         ..Default::default()
133      }
134   }
135
136   // Immutable access.
137   pub fn results(&self) -> &Vec<UserComputerSession> {
138      &self.results
139   }
140   pub fn collected(&self) -> &bool {
141      &self.collected
142   }
143   pub fn failure_reason(&self) -> &Option<String> {
144      &self.failure_reason
145   }
146
147   // Mutable access.
148   pub fn results_mut(&mut self) -> &mut Vec<UserComputerSession> {
149      &mut self.results
150   }
151   pub fn collected_mut(&mut self) -> &mut bool {
152      &mut self.collected
153   }
154   pub fn failure_reason_mut(&mut self) -> &mut Option<String> {
155      &mut self.failure_reason
156   }
157}
158
159/// UserSID to ComputerSID Session link structure
160#[derive(Debug, Clone, Deserialize, Serialize, Default)]
161pub struct UserComputerSession {
162   #[serde(rename = "UserSID")]
163   user_sid: String,
164   #[serde(rename = "ComputerSID")]
165   computer_sid: String,
166}
167
168impl UserComputerSession {
169   // New User Computer Session.
170   pub fn new() -> Self { 
171      Self { 
172         ..Default::default()
173      }
174   }
175
176   // Immutable access.
177   pub fn user_sid(&self) -> &String {
178      &self.user_sid
179   }
180   pub fn computer_sid(&self) -> &String {
181      &self.computer_sid
182   }
183
184   // Mutable access.
185   pub fn user_sid_mut(&mut self) -> &mut String {
186      &mut self.user_sid
187   }
188   pub fn computer_sid_mut(&mut self) -> &mut String {
189      &mut self.computer_sid
190   }
191   
192}
193
194/// Session structure
195#[derive(Debug, Clone, Deserialize, Serialize, Default)]
196pub struct UserRight {
197   #[serde(rename = "Privilege")]
198   privilege: String,
199   #[serde(rename = "Results")]
200   results: Vec<Member>,
201   #[serde(rename = "LocalNames")]
202   local_names: Vec<String>,
203   #[serde(rename = "Collected", default = "default_true")]
204   collected: bool,
205   #[serde(rename = "FailureReason")]
206   failure_reason: Option<String>,
207}
208
209impl UserRight {
210   // New User Right.
211   pub fn new() -> Self { 
212      Self { 
213         ..Default::default()
214      }
215   }
216
217   // Immutable access.
218   pub fn privilege(&self) -> &String {
219      &self.privilege
220   }
221   pub fn results(&self) -> &Vec<Member> {
222      &self.results
223   }
224   pub fn local_names(&self) -> &Vec<String> {
225      &self.local_names
226   }
227   pub fn collected(&self) -> &bool {
228      &self.collected
229   }
230   pub fn failure_reason(&self) -> &Option<String> {
231      &self.failure_reason
232   }
233
234   // Mutable access.
235   pub fn privilege_mut(&mut self) -> &mut String {
236      &mut self.privilege
237   }
238   pub fn results_mut(&mut self) -> &mut Vec<Member> {
239      &mut self.results
240   }
241   pub fn local_names_mut(&mut self) -> &mut Vec<String> {
242      &mut self.local_names
243   }
244   pub fn collected_mut(&mut self) -> &mut bool {
245      &mut self.collected
246   }
247   pub fn failure_reason_mut(&mut self) -> &mut Option<String> {
248      &mut self.failure_reason
249   }
250}
251
252
253/// DCRegistryData structure
254#[derive(Debug, Clone, Deserialize, Serialize)]
255pub struct DCRegistryData {
256   #[serde(rename = "CertificateMappingMethods")]
257   certificate_mapping_methods: Option<RegistryData>,
258   #[serde(rename = "StrongCertificateBindingEnforcement")]
259   strong_certificate_binding_enforcement: Option<RegistryData>,
260}
261
262impl Default for DCRegistryData {
263   fn default() -> DCRegistryData {
264      DCRegistryData {
265         certificate_mapping_methods: None,
266         strong_certificate_binding_enforcement: None,
267      }
268   }
269}
270
271/// IsWebClientRunning structure (issue #72).
272///
273/// `Result` is `true` when the WebClient (WebDAV) `\PIPE\DAV RPC SERVICE` pipe
274/// opened on the host, which makes it an ESC8 / coercion relay candidate.
275/// `Collected` is `false` by default so an unprobed host (DCOnly, filtered out,
276/// or unreachable) is not misread as "WebClient confirmed off".
277#[derive(Debug, Clone, Deserialize, Serialize)]
278pub struct WebClientRunning {
279   #[serde(rename = "Result")]
280   pub result: bool,
281   #[serde(rename = "Collected", default)]
282   pub collected: bool,
283   #[serde(rename = "FailureReason")]
284   pub failure_reason: Option<String>,
285}
286
287impl Default for WebClientRunning {
288   fn default() -> WebClientRunning {
289      WebClientRunning {
290         result: false,
291         collected: false,
292         failure_reason: None,
293      }
294   }
295}
296
297/// RegistryData structure
298#[derive(Debug, Clone, Deserialize, Serialize, Default)]
299pub struct RegistryData {
300   #[serde(rename = "Value")]
301   value: i8,
302   #[serde(rename = "Collected", default = "default_true")]
303   collected: bool,
304   #[serde(rename = "FailureReason")]
305   failure_reason: Option<String>,
306}
307
308impl RegistryData {
309   // New RegistryData.
310   pub fn new() -> Self { 
311      Self {
312         collected: true,
313         ..Default::default()
314      }
315   }
316}
317
318/// Function to return default value for struct.
319pub fn default_true() -> bool {
320   true
321}
322
323/// Member structure
324#[derive(Debug, Clone, Deserialize, Serialize, Default)]
325pub struct Member {
326   #[serde(rename = "ObjectIdentifier")]
327   object_identifier: String,
328   #[serde(rename = "ObjectType")]
329   object_type: String,
330}
331
332impl Member {
333   // New member.
334    pub fn new() -> Self {
335      Self {
336         object_identifier: "SID".to_string(),
337         object_type: "Base".to_string(),
338      }
339   }
340
341   // Immutable access.
342   pub fn object_identifier(&self) -> &String {
343      &self.object_identifier
344   }
345   pub fn object_type(&self) -> &String {
346      &self.object_type
347   }
348
349   // Mutable access.
350   pub fn object_identifier_mut(&mut self) -> &mut String {
351      &mut self.object_identifier
352   }
353   pub fn object_type_mut(&mut self) -> &mut String {
354      &mut self.object_type
355   }
356}
357
358/// Well-known SID of OWNER RIGHTS. An ACE granting rights to it applies to
359/// whoever currently owns the object, making ownership an escalation path.
360const OWNER_RIGHTS_SID: &str = "S-1-3-4";
361
362/// `sid_maker` prefixes well-known SIDs with the domain name, so a plain
363/// equality test is not enough.
364fn is_owner_rights_sid(sid: &str) -> bool {
365    sid == OWNER_RIGHTS_SID || sid.ends_with(&format!("-{OWNER_RIGHTS_SID}"))
366}
367
368/// AceTemplate structure
369#[derive(Debug, Clone, Deserialize, Serialize, Default)]
370pub struct AceTemplate {
371   #[serde(rename = "PrincipalSID")]
372   principal_sid: String,
373   #[serde(rename = "PrincipalType")]
374   principal_type: String,
375   #[serde(rename = "RightName")]
376   right_name: String,
377   #[serde(rename = "IsInherited")]
378   is_inherited: bool,
379   #[serde(rename = "InheritanceHash")]
380   inheritance_hash: String,
381   #[serde(rename = "IsPermissionForOwnerRightsSid")]
382   is_permission_for_owner_rights_sid: bool,
383   #[serde(rename = "IsInheritedPermissionForOwnerRightsSid")]
384   is_inherited_permission_for_owner_rights_sid: bool,
385}
386
387impl AceTemplate {
388   // New ACE object.
389   pub fn new(
390      principal_sid: String,
391      principal_type: String,
392      right_name: String,
393      is_inherited: bool,
394      inheritance_hash: String,
395   ) -> Self {
396      // Both OWNER RIGHTS flags follow from the trustee SID and the inherited
397      // bit, so they are computed here rather than in a later pass.
398      let is_owner_rights = is_owner_rights_sid(&principal_sid);
399      Self {
400         principal_sid,
401         principal_type,
402         right_name,
403         is_inherited,
404         inheritance_hash,
405         is_permission_for_owner_rights_sid: is_owner_rights,
406         is_inherited_permission_for_owner_rights_sid: is_owner_rights && is_inherited,
407      }
408   }
409
410   // Immutable access.
411   pub fn principal_sid(&self) -> &String {
412      &self.principal_sid
413   }
414   pub fn principal_type(&self) -> &String {
415      &self.principal_type
416   }
417   pub fn right_name(&self) -> &String {
418      &self.right_name
419   }
420   pub fn is_inherited(&self) -> &bool {
421      &self.is_inherited
422   }
423   pub fn inheritance_hash(&self) -> &String {
424      &self.inheritance_hash
425   }
426   pub fn is_permission_for_owner_rights_sid(&self) -> bool {
427      self.is_permission_for_owner_rights_sid
428   }
429   pub fn is_inherited_permission_for_owner_rights_sid(&self) -> bool {
430      self.is_inherited_permission_for_owner_rights_sid
431   }
432
433   // Mutable access.
434   pub fn principal_sid_mut(&mut self) -> &mut String {
435      &mut self.principal_sid
436   }
437   pub fn principal_type_mut(&mut self) -> &mut String {
438      &mut self.principal_type
439   }
440   pub fn right_name_mut(&mut self) -> &mut String {
441      &mut self.right_name
442   }
443   pub fn is_inherited_mut(&mut self) -> &mut bool {
444      &mut self.is_inherited
445   }
446   pub fn inheritance_hash_mut(&mut self) -> &mut String {
447      &mut self.inheritance_hash
448   }
449}
450
451/// Link structure
452#[derive(Debug, Clone, Deserialize, Serialize)]
453pub struct Link {
454   #[serde(rename = "IsEnforced")]
455   is_enforced: bool,
456   #[serde(rename = "GUID")]
457   guid: String,
458}
459
460impl Link {
461   // New object.
462   pub fn new(is_enforced: bool, guid: String) -> Self { Self { is_enforced, guid } }
463   
464   // Immutable access.
465   pub fn is_enforced(&self) -> &bool {
466      &self.is_enforced
467   }
468   pub fn guid(&self) -> &String {
469      &self.guid
470   }
471 
472   // Mutable access.
473   pub fn is_enforced_mut(&mut self) -> &mut bool {
474      &mut self.is_enforced
475   }
476   pub fn guid_mut(&mut self) -> &mut String {
477      &mut self.guid
478   }
479}
480
481/// GPOChange structure
482#[derive(Debug, Clone, Deserialize, Serialize, Default)]
483pub struct GPOChange {
484   #[serde(rename = "LocalAdmins")]
485   local_admins: Vec<Member>,
486   #[serde(rename = "RemoteDesktopUsers")]
487   remote_desktop_users: Vec<Member>,
488   #[serde(rename = "DcomUsers")]
489   dcom_users: Vec<Member>,
490   #[serde(rename = "PSRemoteUsers")]
491   psremote_users: Vec<Member>,
492   #[serde(rename = "AffectedComputers")]
493   affected_computers: Vec<Member>,
494}
495
496impl GPOChange {
497   // New GPOChanges.
498   pub fn new() -> Self { 
499      Self {
500         ..Default::default()
501      } 
502   }
503
504   // Imutable access.
505   pub fn local_admins(&self) -> &Vec<Member> {
506      &self.local_admins
507   }
508   pub fn remote_desktop_users(&self) -> &Vec<Member> {
509      &self.remote_desktop_users
510   }
511   pub fn dcom_users(&self) -> &Vec<Member> {
512      &self.dcom_users
513   }
514   pub fn psremote_users(&self) -> &Vec<Member> {
515      &self.psremote_users
516   }
517   pub fn affected_computers(&self) -> &Vec<Member> {
518      &self.affected_computers
519   }
520
521   // Mutable access.
522   pub fn local_admins_mut(&mut self) -> &mut Vec<Member> {
523      &mut self.local_admins
524   }
525   pub fn remote_desktop_users_mut(&mut self) -> &mut Vec<Member> {
526      &mut self.remote_desktop_users
527   }
528   pub fn dcom_users_mut(&mut self) -> &mut Vec<Member> {
529      &mut self.dcom_users
530   }
531   pub fn psremote_users_mut(&mut self) -> &mut Vec<Member> {
532      &mut self.psremote_users
533   }
534   pub fn affected_computers_mut(&mut self) -> &mut Vec<Member> {
535      &mut self.affected_computers
536   }
537}
538
539/// SPNTarget structure
540#[derive(Debug, Clone, Deserialize, Serialize)]
541pub struct SPNTarget {
542   #[serde(rename = "ComputerSID")]
543   computer_sid: String,
544   #[serde(rename = "Port")]
545   port: i32,
546   #[serde(rename = "Service")]
547   service: String,
548}
549
550impl SPNTarget {
551   // New object.
552   pub fn new() -> Self { 
553      Self { 
554         computer_sid: "SID".to_string(), 
555         port: 1433, 
556         service: "SQLAdmin".to_string()
557      } 
558   }
559
560   // Immutable access.
561   pub fn computer_sid(&self) -> &String {
562      &self.computer_sid
563   }
564   pub fn port(&self) -> &i32 {
565      &self.port
566   }
567   pub fn service(&self) -> &String {
568      &self.service
569   }
570
571   // Mutable access.
572   pub fn computer_sid_mut(&mut self) -> &mut String {
573      &mut self.computer_sid
574   }
575   pub fn port_mut(&mut self) -> &mut i32 {
576      &mut self.port
577   }
578   pub fn service_mut(&mut self) -> &mut String {
579      &mut self.service
580   }
581}
582
583/// Final JSON structure
584#[derive(Debug, Clone, Deserialize, Serialize, Default)]
585pub struct FinalJson{
586   data: Vec<Value>,
587   meta: Meta,
588}
589
590impl FinalJson  {
591   // New FinalJson.
592   pub fn new(data: Vec<Value>, meta: Meta) -> Self { 
593      Self {
594         data,
595         meta
596      }
597   }
598   // Imutable access.
599   pub fn data(&self) -> &Vec<Value> {
600      &self.data
601   }
602   pub fn meta(&self) -> &Meta {
603      &self.meta
604   }
605
606   // Mutable access.
607   pub fn data_mut(&mut self) -> &mut Vec<Value> {
608      &mut self.data
609   }
610   pub fn meta_mut(&mut self) -> &mut Meta {
611      &mut self.meta
612   }
613}
614
615/// Meta data for final JSON structure
616#[derive(Debug, Clone, Deserialize, Serialize, Default)]
617pub struct Meta {
618   methods: i32,
619   #[serde(rename = "type")]
620   mtype: String,
621   count: i32,
622   version: i8,
623   collectorversion: String
624}
625
626impl Meta {
627   // New Meta.
628   pub fn new(
629      methods: i32,
630      mtype: String,
631      count: i32,
632      version: i8,
633      collectorversion: String
634   ) -> Self { 
635      Self { 
636         methods,
637         mtype,
638         count,
639         version,
640         collectorversion
641      } 
642   }
643   
644   // Imutable access.
645   pub fn methods(&self) -> &i32 {
646      &self.methods
647   }
648   pub fn mtype(&self) -> &String {
649      &self.mtype
650   }
651   pub fn count(&self) -> &i32 {
652      &self.count
653   }
654   pub fn version(&self) -> &i8 {
655      &self.version
656   }
657
658   // Mutable access.
659   pub fn methods_mut(&mut self) -> &mut i32 {
660      &mut self.methods
661   }
662   pub fn mtype_mut(&mut self) -> &mut String {
663      &mut self.mtype
664   }
665   pub fn count_mut(&mut self) -> &mut i32 {
666      &mut self.count
667   }
668   pub fn version_mut(&mut self) -> &mut i8 {
669      &mut self.version
670   }
671}
672
673
674/// Function to parse and replace value for unknown object.
675pub fn parse_unknown(result: SearchEntry, _domain: &str) -> serde_json::value::Value  {
676
677   let _result_dn = result.dn.to_uppercase();
678   let _result_attrs: HashMap<String, Vec<String>> = result.attrs;
679   let _result_bin: HashMap<String, Vec<Vec<u8>>> = result.bin_attrs;
680   
681   let unknown_json = json!({
682       "unknown": null,
683   });
684
685   // Debug for current object
686   trace!("Parse Unknown object: {}", _result_dn);
687   // for (key, value) in &_result_attrs {
688   //    println!("  {:?}:{:?}", key, value);
689   // }
690   // //trace result bin
691   // for (key, value) in &_result_bin {
692   //    println!("  {:?}:{:?}", key, value);
693   // }
694
695   unknown_json
696}