Skip to main content

enum_trusts/
enum_trusts.rs

1//! Live probe: enumerate trusts on a target DC via MS-LSAD.
2//!
3//! Usage:
4//!
5//!   cargo run --example enum_trusts -- <host> <domain> <user> <password>
6//!
7//! Example (against the icedracon lab):
8//!
9//!   cargo run --example enum_trusts -- 192.168.91.20 testlab.local labuser 'LabPass2026$'
10//!
11//! Prints one line per enumerated trust: `<sid>  <netbios-name>`. No trusts on a
12//! stand-alone domain is a valid result (prints "0 trusts").
13
14use std::error::Error;
15
16use ms_lsad::LsadClient;
17use smb2_client::SmbClient;
18
19#[tokio::main(flavor = "current_thread")]
20async fn main() -> Result<(), Box<dyn Error>> {
21    let args: Vec<String> = std::env::args().collect();
22    if args.len() < 5 {
23        eprintln!(
24            "usage: {} <host> <domain> <user> <password>",
25            args.first().map(String::as_str).unwrap_or("enum_trusts")
26        );
27        std::process::exit(2);
28    }
29    let host = &args[1];
30    let domain = &args[2];
31    let user = &args[3];
32    let password = &args[4];
33
34    eprintln!("[+] connecting to \\\\{host}\\IPC$ as {domain}\\{user}");
35    let mut smb = SmbClient::connect(host).await?;
36    smb.login(host, domain, user, password).await?;
37    smb.tree_connect(&format!("\\\\{host}\\IPC$")).await?;
38
39    eprintln!("[+] opening \\PIPE\\lsarpc");
40    let pipe = smb.open_pipe("lsarpc").await?;
41
42    eprintln!("[+] binding MS-LSAD interface + LsarOpenPolicy2");
43    let mut client = LsadClient::bind(&mut smb, pipe).await?;
44
45    eprintln!("[+] calling LsarEnumerateTrustedDomains (opnum 13)");
46    let trusts = client.enumerate_trusts("").await?;
47
48    println!("=== {} trust(s) enumerated ===", trusts.len());
49    for t in &trusts {
50        println!("  {}  {}", t.sid, t.name);
51    }
52
53    Ok(())
54}