Skip to content

Commit

Permalink
Merge pull request #64 from CCob/master
Browse files Browse the repository at this point in the history
Initial support for PKINIT TGT's
  • Loading branch information
HarmJ0y committed Oct 2, 2020
2 parents 0754532 + 3746efd commit afa7ca1
Show file tree
Hide file tree
Showing 33 changed files with 3,930 additions and 80 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Rubeus is a C# toolset for raw Kerberos interaction and abuses. It is **heavily*

Rubeus also uses a C# ASN.1 parsing/encoding library from [Thomas Pornin](https://github.com/pornin) named [DDer](https://github.com/pornin/DDer) that was released with an "MIT-like" license. Huge thanks to Thomas for his clean and stable code!

PKINIT code heavily adapted from [@SteveSyfuhs](https://twitter.com/SteveSyfuhs)'s [Bruce](https://github.com/dotnet/Kerberos.NET) tool. Bruce made RFC4556 (PKINIT) a lot easier to understand. Huge thanks to Steve!

The [KerberosRequestorSecurityToken.GetRequest](https://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.kerberosrequestorsecuritytoken.getrequest(v=vs.110).aspx) method for Kerberoasting was contributed to PowerView by [@machosec](https://twitter.com/machosec).

[Elad Shamir](https://twitter.com/elad_shamir) contribute some essential work for resource-based constrained delegation.
Expand Down Expand Up @@ -81,6 +83,12 @@ Rubeus is licensed under the BSD 3-Clause license.
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]

Retrieve a TGT using a PCKS12 certificate store, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER /certificate:C:\temp\leaked.pfx </password:STOREPASSWORD> /createnetonly:C:\Windows\System32\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/nowrap]
Retrieve a TGT using a certificate from the users keystore (Smartcard) specifying certificate thumbprint or subject, start a /netonly process, and to apply the ticket to the new process/logon session:
Rubeus.exe asktgt /user:USER /certificate:f063e6f4798af085946be6cd9d82ba3999c7ebac /createnetonly:C:\Windows\System32\cmd.exe [/show] [/domain:DOMAIN] [/dc:DOMAIN_CONTROLLER] [/nowrap]

Retrieve a service ticket for one or more SPNs, optionally saving or applying the ticket:
Rubeus.exe asktgs </ticket:BASE64 | /ticket:FILE.KIRBI> </service:SPN1,SPN2,...> [/enctype:DES|RC4|AES128|AES256] [/dc:DOMAIN_CONTROLLER] [/outfile:FILENAME] [/ptt] [/nowrap]

Expand Down
47 changes: 47 additions & 0 deletions Rubeus/Asn1/Asn1Extensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;

namespace Rubeus.Asn1 {
public static class Asn1Extensions {

public static byte[] DepadLeft(this byte[] data) {

int leadingZeros = 0;
for (var i = 0; i < data.Length; i++) {
if (data[i] == 0) {
leadingZeros++;
} else {
break;
}
}

byte[] result = new byte[data.Length - leadingZeros];
Array.Copy(data, leadingZeros, result, 0, data.Length - leadingZeros);
return result;
}

public static byte[] PadLeft(this byte[] data, int totalSize) {

if(data.Length == totalSize) {
return data;
}

if(totalSize < data.Length) {
throw new ArgumentException("data bigger than totalSize, cannot pad with 0's");
}

byte[] result = new byte[totalSize];
data.CopyTo(result, totalSize - data.Length);
return result;
}

public static byte[] PadRight(this byte[] data, int length) {
if (data.Length == length) {
return data;
}

var copy = new byte[length];
data.CopyTo(copy, length - data.Length);
return copy;
}
}
}
56 changes: 29 additions & 27 deletions Rubeus/Commands/Asktgt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public void Execute(Dictionary<string, string> arguments)
string hash = "";
string dc = "";
string outfile = "";
string certificate = "";

bool ptt = false;
LUID luid = new LUID();
Interop.KERB_ETYPE encType = Interop.KERB_ETYPE.subkey_keymaterial;
Expand Down Expand Up @@ -49,34 +51,26 @@ public void Execute(Dictionary<string, string> arguments)
outfile = arguments["/outfile"];
}

encType = Interop.KERB_ETYPE.rc4_hmac; //default is non /enctype is specified
if (arguments.ContainsKey("/enctype")) {
string encTypeString = arguments["/enctype"].ToUpper();

if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM")) {
encType = Interop.KERB_ETYPE.rc4_hmac;
} else if (encTypeString.Equals("AES128")) {
encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1;
} else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES")) {
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
} else if (encTypeString.Equals("DES")) {
encType = Interop.KERB_ETYPE.des_cbc_md5;
}
}

if (arguments.ContainsKey("/password"))
{
password = arguments["/password"];

string salt = String.Format("{0}{1}", domain.ToUpper(), user);
encType = Interop.KERB_ETYPE.rc4_hmac; //default is non /enctype is specified

if (arguments.ContainsKey("/enctype"))
{
string encTypeString = arguments["/enctype"].ToUpper();

if (encTypeString.Equals("RC4") || encTypeString.Equals("NTLM"))
{
encType = Interop.KERB_ETYPE.rc4_hmac;
}
else if (encTypeString.Equals("AES128"))
{
encType = Interop.KERB_ETYPE.aes128_cts_hmac_sha1;
}
else if (encTypeString.Equals("AES256") || encTypeString.Equals("AES"))
{
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
}
else if (encTypeString.Equals("DES"))
{
encType = Interop.KERB_ETYPE.des_cbc_md5;
}
}
string salt = String.Format("{0}{1}", domain.ToUpper(), user);
hash = Crypto.KerberosPasswordHash(encType, password, salt);
}

Expand Down Expand Up @@ -105,6 +99,10 @@ public void Execute(Dictionary<string, string> arguments)
hash = arguments["/aes256"];
encType = Interop.KERB_ETYPE.aes256_cts_hmac_sha1;
}

if (arguments.ContainsKey("/certificate")) {
certificate = arguments["/certificate"];
}

if (arguments.ContainsKey("/ptt"))
{
Expand Down Expand Up @@ -152,9 +150,9 @@ public void Execute(Dictionary<string, string> arguments)
{
domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
}
if (String.IsNullOrEmpty(hash))
if (String.IsNullOrEmpty(hash) && String.IsNullOrEmpty(certificate))
{
Console.WriteLine("\r\n[X] You must supply a /password , or a [/des|/rc4|/aes128|/aes256] hash!\r\n");
Console.WriteLine("\r\n[X] You must supply a /password, /certificate or a [/des|/rc4|/aes128|/aes256] hash!\r\n");
return;
}

Expand All @@ -165,7 +163,11 @@ public void Execute(Dictionary<string, string> arguments)
}
else
{
Ask.TGT(user, domain, hash, encType, outfile, ptt, dc, luid, true);
if (String.IsNullOrEmpty(certificate))
Ask.TGT(user, domain, hash, encType, outfile, ptt, dc, luid, true);
else
Ask.TGT(user, domain, certificate, password, encType, outfile, ptt, dc, luid, true);

return;
}
}
Expand Down
28 changes: 28 additions & 0 deletions Rubeus/Rubeus.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
Expand All @@ -49,6 +50,7 @@
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<DebugSymbols>false</DebugSymbols>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
Expand All @@ -59,6 +61,7 @@
<Reference Include="System.DirectoryServices" />
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.Security" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
Expand All @@ -69,6 +72,7 @@
<Compile Include="Asn1\AsnException.cs" />
<Compile Include="Asn1\AsnIO.cs" />
<Compile Include="Asn1\AsnOID.cs" />
<Compile Include="Asn1\Asn1Extensions.cs" />
<Compile Include="Commands\Asktgs.cs" />
<Compile Include="Commands\Asktgt.cs" />
<Compile Include="Commands\Asreproast.cs" />
Expand Down Expand Up @@ -99,11 +103,20 @@
<Compile Include="lib\Bruteforcer.cs" />
<Compile Include="lib\ConsoleTable.cs" />
<Compile Include="lib\Crypto.cs" />
<Compile Include="lib\crypto\dh\DiffieHellmanKey.cs" />
<Compile Include="lib\crypto\dh\IExchangeKey.cs" />
<Compile Include="lib\crypto\dh\IKeyAgreement.cs" />
<Compile Include="lib\crypto\dh\KeyAgreementAlgorithm.cs" />
<Compile Include="lib\crypto\dh\ManagedDiffieHellman.cs" />
<Compile Include="lib\crypto\dh\ManagedDiffieHellmanOakley14.cs" />
<Compile Include="lib\crypto\dh\ManagedDiffieHellmanOakley2.cs" />
<Compile Include="lib\crypto\dh\Oakley.cs" />
<Compile Include="lib\Harvest.cs" />
<Compile Include="lib\Helpers.cs" />
<Compile Include="lib\Interop.cs" />
<Compile Include="lib\Interop\Luid.cs" />
<Compile Include="lib\Interop\NtException.cs" />
<Compile Include="lib\KDCKeyAgreement.cs" />
<Compile Include="lib\krb_structures\AP_REQ.cs" />
<Compile Include="lib\krb_structures\AS_REP.cs" />
<Compile Include="lib\krb_structures\AS_REQ.cs" />
Expand All @@ -116,7 +129,13 @@
<Compile Include="lib\krb_structures\EncryptionKey.cs" />
<Compile Include="lib\krb_structures\KDC_REQ_BODY.cs" />
<Compile Include="lib\krb_structures\KERB_PA_PAC_REQUEST.cs" />
<Compile Include="lib\krb_structures\KrbAlgorithmIdentifier.cs" />
<Compile Include="lib\krb_structures\KrbAuthPack.cs" />
<Compile Include="lib\krb_structures\KrbCredInfo.cs" />
<Compile Include="lib\krb_structures\KrbDHRepInfo.cs" />
<Compile Include="lib\krb_structures\KrbKDCDHKeyInfo.cs" />
<Compile Include="lib\krb_structures\KrbPkAuthenticator.cs" />
<Compile Include="lib\krb_structures\KrbSubjectPublicKeyInfo.cs" />
<Compile Include="lib\krb_structures\KRB_CRED.cs" />
<Compile Include="lib\krb_structures\KRB_ERROR.cs" />
<Compile Include="lib\krb_structures\KRB_PRIV.cs" />
Expand All @@ -125,11 +144,19 @@
<Compile Include="lib\krb_structures\PA_ENC_TS_ENC.cs" />
<Compile Include="lib\krb_structures\PA_FOR_USER.cs" />
<Compile Include="lib\krb_structures\PA_PAC_OPTIONS.cs" />
<Compile Include="lib\krb_structures\PA_PK_AS_REP.cs" />
<Compile Include="lib\krb_structures\PA_PK_AS_REQ.cs" />
<Compile Include="lib\krb_structures\PrincipalName.cs" />
<Compile Include="lib\krb_structures\TGS_REP.cs" />
<Compile Include="lib\krb_structures\TGS_REQ.cs" />
<Compile Include="lib\krb_structures\Ticket.cs" />
<Compile Include="lib\LSA.cs" />
<Compile Include="lib\math\BigInteger.cs" />
<Compile Include="lib\math\ConfidenceFactor.cs" />
<Compile Include="lib\math\NextPrimeFinder.cs" />
<Compile Include="lib\math\PrimalityTest.cs" />
<Compile Include="lib\math\PrimeGeneratorBase.cs" />
<Compile Include="lib\math\SequentialSearchPrimeGeneratorBase.cs" />
<Compile Include="lib\Networking.cs" />
<Compile Include="lib\Renew.cs" />
<Compile Include="lib\Reset.cs" />
Expand All @@ -148,6 +175,7 @@
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
Loading

0 comments on commit afa7ca1

Please sign in to comment.