Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated to add arg to specify x509 keysize. #39

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
34 changes: 25 additions & 9 deletions Certify/Commands/Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public void Execute(Dictionary<string, string> arguments)
var template = "User";
var machineContext = false;
var install = false;
var keySize = 2048;

if (arguments.ContainsKey("/ca"))
{
Expand All @@ -33,7 +34,22 @@ public void Execute(Dictionary<string, string> arguments)
Console.WriteLine("[X] A /ca:CA is required! (format SERVER\\CA-NAME)");
return;
}
if (arguments.ContainsKey("/keysize"))
{

if (arguments["/keysize"].Equals("512") || arguments["/keysize"].Equals("1024") ||
arguments["/keysize"].Equals("2048") || arguments["/keysize"].Equals("4096") )
{
keySize = Int32.Parse(arguments["/keysize"]);
}
else
{
Console.WriteLine("[X] /keysize must be either 512, 1024, 2048 (default) or 4096");
return;

}

}
if (arguments.ContainsKey("/template"))
{
template = arguments["/template"];
Expand All @@ -49,13 +65,13 @@ public void Execute(Dictionary<string, string> arguments)
altName = arguments["/altname"];
}

if(arguments.ContainsKey("/sidextension"))
{
sidExtension = arguments["/sidextension"];
if(arguments.ContainsKey("/sidextension"))
{
sidExtension = arguments["/sidextension"];
}
if (arguments.ContainsKey("/sid"))
{
sidExtension = arguments["/sid"];
if (arguments.ContainsKey("/sid"))
{
sidExtension = arguments["/sid"];
}

if (arguments.ContainsKey("/install"))
Expand Down Expand Up @@ -90,12 +106,12 @@ public void Execute(Dictionary<string, string> arguments)
return;
}

Cert.RequestCertOnBehalf(CA, template, arguments["/onbehalfof"], arguments["/enrollcert"], enrollCertPassword, machineContext);
Cert.RequestCertOnBehalf(CA, template, arguments["/onbehalfof"], arguments["/enrollcert"], enrollCertPassword, machineContext,keySize);
}
else
{
Cert.RequestCert(CA, machineContext, template, subject, altName, sidExtension, install);
Cert.RequestCert(CA, machineContext, template, subject, altName, sidExtension, install,keySize);
}
}
}
}
}
4 changes: 4 additions & 0 deletions Certify/Info.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ public static void ShowUsage()

Certify.exe request /ca:SERVER\ca-name /machine [/subject:X] [/template:Y] [/install]

Request a new certificate using the current machine context, specifying x509 key length:

Certify.exe request /ca:SERVER\ca-name /machine /keysize 4096 [/subject:X] [/template:Y] [/install]

Request a new certificate using the current user context but for an alternate name (if supported):

Certify.exe request /ca:SERVER\ca-name /template:Y /altname:USER
Expand Down
49 changes: 25 additions & 24 deletions Certify/Lib/Cert.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public CertificateRequest(string request, string privateKeyPem)
}

// create a certificate request message from a given enterprise template name
private static CertificateRequest CreateCertRequestMessage(string templateName, bool machineContext = false, string subjectName = "", string altName = "", string sidExtension = "")
private static CertificateRequest CreateCertRequestMessage(string templateName, bool machineContext = false, string subjectName = "", string altName = "", string sidExtension = "",int keySize= 2048)
{
if (String.IsNullOrEmpty(subjectName))
{
Expand All @@ -68,13 +68,13 @@ private static CertificateRequest CreateCertRequestMessage(string templateName,
if (!String.IsNullOrEmpty(altName))
{
Console.WriteLine($"[*] AltName : {altName}");
}
}
if (!String.IsNullOrEmpty(sidExtension))
{
Console.WriteLine($"[*] SidExtension : {sidExtension}");
}

var privateKey = CreatePrivateKey(machineContext);
var privateKey = CreatePrivateKey(machineContext,keySize);

// export the private key and transform it into a .pem
var privateKeyBase64 = privateKey.Export("PRIVATEBLOB", EncodingType.XCN_CRYPT_STRING_BASE64);
Expand Down Expand Up @@ -119,16 +119,16 @@ private static CertificateRequest CreateCertRequestMessage(string templateName,
// format 2 - required for the EDITF_ATTRIBUTESUBJECTALTNAME2 scenario
var altNamePair = new CX509NameValuePair();
altNamePair.Initialize("SAN", $"upn={altName}");
objPkcs10.NameValuePairs.Add(altNamePair);
if(!String.IsNullOrEmpty(sidExtension)) {
var extBytes = Certify.Lib.CertSidExtension.EncodeSidExtension(new SecurityIdentifier(sidExtension));
var oid = new CObjectId();
oid.InitializeFromValue("1.3.6.1.4.1.311.25.2");
var sidExt = new CX509Extension();
sidExt.Initialize(oid, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(extBytes));
objPkcs10.X509Extensions.Add(sidExt);
}
objPkcs10.NameValuePairs.Add(altNamePair);

if(!String.IsNullOrEmpty(sidExtension)) {
var extBytes = Certify.Lib.CertSidExtension.EncodeSidExtension(new SecurityIdentifier(sidExtension));
var oid = new CObjectId();
oid.InitializeFromValue("1.3.6.1.4.1.311.25.2");
var sidExt = new CX509Extension();
sidExt.Initialize(oid, EncodingType.XCN_CRYPT_STRING_BASE64, Convert.ToBase64String(extBytes));
objPkcs10.X509Extensions.Add(sidExt);
}
}

var objEnroll = new CX509Enrollment();
Expand All @@ -138,14 +138,15 @@ private static CertificateRequest CreateCertRequestMessage(string templateName,
return new CertificateRequest(base64request, privateKeyPEM);
}

private static IX509PrivateKey CreatePrivateKey(bool machineContext)
private static IX509PrivateKey CreatePrivateKey(bool machineContext, int keySize)
{
var cspInfo = new CCspInformations();
cspInfo.AddAvailableCsps();

var privateKey = new CX509PrivateKey
{
Length = 2048,
Length = keySize,

KeySpec = X509KeySpec.XCN_AT_SIGNATURE,
KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES,
MachineContext = machineContext,
Expand All @@ -159,7 +160,7 @@ private static IX509PrivateKey CreatePrivateKey(bool machineContext)


// create a certificate request message from a given enterprise template name on behalf of another user
private static CertificateRequest CreateCertRequestOnBehalfMessage(string templateName, string onBehalfUser, string signerCertPath, string signerCertPassword, bool machineContext = false)
private static CertificateRequest CreateCertRequestOnBehalfMessage(string templateName, string onBehalfUser, string signerCertPath, string signerCertPassword, bool machineContext = false, int keySize = 2048)
{
if (String.IsNullOrEmpty(signerCertPath))
throw new Exception("signerCertPath is empty");
Expand All @@ -172,7 +173,7 @@ private static CertificateRequest CreateCertRequestOnBehalfMessage(string templa

X509Certificate2? cert = null;

var privateKey = CreatePrivateKey(machineContext);
var privateKey = CreatePrivateKey(machineContext,keySize);

// export the private key and transform it into a .pem
var privateKeyBase64 = privateKey.Export("PRIVATEBLOB", EncodingType.XCN_CRYPT_STRING_BASE64);
Expand Down Expand Up @@ -313,19 +314,19 @@ public static string DownloadAndInstallCert(string CA, int requestId, X509Certif


// request a user/machine certificate
public static void RequestCert(string CA, bool machineContext = false, string templateName = "User", string subject = "", string altName = "", string sidExtension = "", bool install = false)
public static void RequestCert(string CA, bool machineContext = false, string templateName = "User", string subject = "", string altName = "", string sidExtension = "", bool install = false,int keySize =2048)
{
if (machineContext && !WindowsIdentity.GetCurrent().IsSystem)
{
Console.WriteLine("[*] Elevating to SYSTEM context for machine cert request");
Elevator.GetSystem(() => RequestCert(CA, machineContext, templateName, subject, altName, sidExtension, install));
Elevator.GetSystem(() => RequestCert(CA, machineContext, templateName, subject, altName, sidExtension, install, keySize));
return;
}

var userName = WindowsIdentity.GetCurrent().Name;
Console.WriteLine($"\r\n[*] Current user context : {userName}");

var csr = CreateCertRequestMessage(templateName, machineContext, subject, altName, sidExtension);
var csr = CreateCertRequestMessage(templateName, machineContext, subject, altName, sidExtension,keySize);


Console.WriteLine($"\r\n[*] Certificate Authority : {CA}");
Expand Down Expand Up @@ -370,19 +371,19 @@ public static void RequestCert(string CA, bool machineContext = false, string te


// request a certificate on behalf of another user
public static void RequestCertOnBehalf(string CA, string templateName, string onBehalfUser, string signerCertPath, string signerCertPassword, bool machineContext = false)
public static void RequestCertOnBehalf(string CA, string templateName, string onBehalfUser, string signerCertPath, string signerCertPassword, bool machineContext = false, int keySize = 2048 )
{
if (machineContext && !WindowsIdentity.GetCurrent().IsSystem)
{
Console.WriteLine("[*] Elevating to SYSTEM context for machine cert request");
Elevator.GetSystem(() => RequestCertOnBehalf(CA, templateName, onBehalfUser, signerCertPath, signerCertPassword, machineContext));
Elevator.GetSystem(() => RequestCertOnBehalf(CA, templateName, onBehalfUser, signerCertPath, signerCertPassword, machineContext, keySize));
return;
}

var userName = WindowsIdentity.GetCurrent().Name;
Console.WriteLine($"\r\n[*] Current user context : {userName}");

var csr = CreateCertRequestOnBehalfMessage(templateName, onBehalfUser, signerCertPath, signerCertPassword, machineContext);
var csr = CreateCertRequestOnBehalfMessage(templateName, onBehalfUser, signerCertPath, signerCertPassword, machineContext,keySize);

Console.WriteLine($"\r\n[*] Certificate Authority : {CA}");

Expand Down Expand Up @@ -549,4 +550,4 @@ private static string GetCurrentComputerDN()
return $"CN={System.Net.Dns.GetHostEntry("").HostName}";
}
}
}
}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ Certify is a C# tool to enumerate and abuse misconfigurations in Active Director

Certify.exe request /ca:SERVER\ca-name /machine [/subject:X] [/template:Y] [/install]

Request a new certificate using the current machine context, specifying x509 key length:

Certify.exe request /ca:SERVER\ca-name /machine /keysize 4096 [/subject:X] [/template:Y] [/install]

Request a new certificate using the current user context but for an alternate name (if supported):

Certify.exe request /ca:SERVER\ca-name /template:Y /altname:USER
Expand Down