Certify
Certify copied to clipboard
Crashes on Server 2012R2 - possibly related to certlib version.
As discussed on BH slack:
Compiled Certify on Win10 2004 with VS2019.
Executed via Cobalt Strike's execute-assembly on Windows Server 2012R2.
Certify.exe find /vulnerable
appeared to work fine.
Certify.exe request /ca:**REDACTED** /template:**REDACTED** /altname:**REDACTED*
threw the following exception:
System.InvalidCastException: Unable to cast COM object of type 'CERTENROLLLib.CX509PrivateKeyClass' to interface type 'CERTENROLLLib.IX509PrivateKey2'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{728AB362-217D-11DA-B2A4-000E7BBB2B09}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).
at System.StubHelpers.StubHelpers.GetCOMIPFromRCW(Object objSrc, IntPtr pCPCMD, IntPtr& ppTarget, Boolean& pfNeedsRelease)
at CERTENROLLLib.CX509PrivateKeyClass.set_Length(Int32 pValue)
at Certify.Cert.CreatePrivateKey(Boolean machineContext)
at Certify.Cert.CreateCertRequestMessage(String templateName, Boolean machineContext, String subjectName, String altName)
at Certify.Cert.RequestCert(String CA, Boolean machineContext, String templateName, String subject, String altName, Boolean install)
at Certify.Commands.Request.Execute(Dictionary`2 arguments)
at Certify.CommandCollection.ExecuteCommand(String commandName, Dictionary`2 arguments)
at Certify.Program.MainExecute(String commandName, Dictionary`2 parsedArgs)
After some trial and error I found that by changing CreatePrivateKey() to return a CX509PrivateKey instead of IX509PrivateKey (and compiling it on Server2012) I could get Certify to request a cert and receive a valid-looking pem-formatted cert back from the CA.
Unfortunately, when trying to actually use the cert with Rubeus.exe asktgt
I was getting KDC_ERR_CLIENT_NOT_TRUSTED
. On further examination of the pem-formatted cert that certify gave me back (with openssl x509 -in cert.pem -text
I noticed that the SAN field wasn't as expected, and was instead showing this:
X509v3 Subject Alternative Name:
othername:<unsupported>
Let me know if there's any other details I can provide to help troubleshoot and I'll do my best.
Same problem here (Unable to cast COM object [...]
). If you need any further details, please let me know.
Same here, any help appreciated. Tried some quick fixes (e.g., replacing Interop.CERTENROLLLib.dll) - but this was more or less trial and error... (target server is Windows Server 2012 R2 Standard)
In my experience it's pretty common when dealing with the CERTENROLLLib on older OS to have to replace stuff like this:
CX509CertificateRequestPkcs10 objPkcs10 = new CX509CertificateRequestPkcs10();
with something like this:
IX509CertificateRequestPkcs10 objPkcs10 = (IX509CertificateRequestPkcs10)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509CertificateRequestPkcs10"));
You might try something like this for CreatePrivateKey():
private static IX509PrivateKey CreatePrivateKey(bool machineContext)
{
var cspInfo = new CCspInformations();
cspInfo.AddAvailableCsps();
var privateKey = (IX509PrivateKey)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509PrivateKey"));
privateKey.Length = 2048;
privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE;
privateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_ALL_USAGES;
privateKey.MachineContext = machineContext;
privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_FLAG;
privateKey.CspInformations = cspInfo;
privateKey.Create();
return privateKey;
}
This ☝️ Many thanks!!
I also encountered this error while trying to use these new Certificate Vulnerabilities with an 2012R2 server. When changing the code to what @aseigler recommended there seems to be another error that crops up near line 115 in Cert.cs source code.
// format 2 - required for the EDITF_ATTRIBUTESUBJECTALTNAME2 scenario
var altNamePair = new CX509NameValuePair();
altNamePair.Initialize("SAN", $"upn={altName}");
objPkcs10.NameValuePairs.Add(altNamePair);
It states that the object pbjPkc10 (IX509CertificateRequestPkcs10 type) does not contain a definition for 'NameValuePairs' and no accessible extension method 'NameValuePairs' accepting a first argument of type 'IX509CertificateRequestPkcs10' can be found.
Was anybody able to get around this.
Try replacing this:
var objPkcs10 = new CX509CertificateRequestPkcs10();
With this:
IX509CertificateRequestPkcs10V3 objPkcs10 = (IX509CertificateRequestPkcs10V3)Activator.CreateInstance(Type.GetTypeFromProgID("X509Enrollment.CX509CertificateRequestPkcs10"));
var context = machineContext
? X509CertificateEnrollmentContext.ContextMachine
: X509CertificateEnrollmentContext.ContextUser;
objPkcs10.InitializeFromPrivateKey(context, privateKey, "");
CX509ExtensionTemplateName objExtensionTemplate = new CX509ExtensionTemplateName();
objExtensionTemplate.InitializeEncode(templateName);
objPkcs10.X509Extensions.Add((CX509Extension)objExtensionTemplate);
My fork has these set and worked for me on 2012R2.
This should be fixed now with 4c24a835527e5524d5fd2777fc7185422cf5fe4d. If any of you could test and verify, please let us know if it solved your problem! I tested on a 2016 server and a similar issue was fixed, so hopefully it covers the 2012 case as well (I don't have a server up to test with right now)
Ran into an issue that appears to be related, using latest build as of yesterday.
[!] Unhandled Certify exception:
System.Exception: Your certlib does not know an implementation of X509Enrollment.CX509CertificateRequestPkcs10 (in HKLM:\SOFTWARE\Classes\Interface\)!
at Certify.Cert.CreateCertRequestMessage(String templateName, Boolean machineContext, String subjectName, String altName)
at Certify.Cert.RequestCert(String CA, Boolean machineContext, String templateName, String subject, String altName, Boolean install)
at Certify.Commands.Request.Execute(Dictionary`2 arguments)
at Certify.CommandCollection.ExecuteCommand(String commandName, Dictionary`2 arguments)
at Certify.Program.MainExecute(String commandName, Dictionary`2 parsedArgs)
@leechristensen - Attempted on a Windows 2012 R2 today (proven vulnerable and exploited through other methods) and the latest version did not resolve this. Going to look into @aseigler's recommendations and will report back how it works out.
Today, faced the similar issue (as in the beginning of the post) in windows 8 machine. Compiled with the suggestion of what @aseigler mentioned. It worked for me nicely.