ethical.blue Magazine

// Cybersecurity clarified.

Nanomity z wirusa komputerowego Nanomites.w32

08.03.2022   Dawid Farbaniec
...
Termin nanomit kojarzy się z mikroskopijnym robotem. Jest to również nazwa nadana znanej od dawna, ale wciąż stosowanej metodzie przeciwko Inżynierii Odwrotnej Kodu (RCE). Technika służy również przeciwko łatwemu odbudowaniu kodu analizowanej aplikacji ze zrzutu pamięci procesu. W prostych słowach, główną ideą tej techniki jest zastąpienie określonych instrukcji (zwykle skoków - JZ, JNZ, JC itp.) w języku Asembler na polecenia przerwań INT 3h zdefiniowane jako nanomity. Podczas wykonywania programu w momencie uderzenia w nanomit, kontrola przekazywana jest do specjalnej procedury, która określa dalszą ścieżkę wykonania kodu.

Instrukcje INT 3h umieszczane są na poziomie kodu maszynowego. Podczas kompilacji programu, na przykład w C++, różne formy kodu to C++, język Asembler i wreszcie kod maszynowy. Instrukcja w Asemblerze w formie tekstowej (na przykład: INT, MOV, JNE itp.) nazywana jest mnemonikiem. Natomiast wartość liczbowa instrukcji w kodzie maszynowym nazywana jest kodem operacji - w skrócie: opcode.

Na przykład, chcemy zmienić w programie (plik .exe) instrukcję skoku JNE (skok, jeśli nie jest równe) na instrukcję JE (skok, jeśli jest równe). W architekturze x64 instrukcja JNE ma kod operacji 75h, a wartość instrukcji JE to 74h. Wartości te można znaleźć w dokumentacji procesorów lub w różnych listach opcode dostępnych w Internecie. Zmianę instrukcji Asemblera w programie .exe można dokonać poprzez zmianę określonych bajtów w pliku lub w pamięci (opkody). Dla przytoczonego wcześniej przykładu jest to zmiana z 75h na 74h. Proces wstawiania nanomitów do kodu jest bardzo podobny. Opcode konkretnej instrukcji jest zmieniany na nanomit INT 3h z opkodem 0CCh.

Implementacje tej techniki mogą się różnić. Standardowy schemat działania polega na zastąpieniu instrukcji skoku warunkowego instrukcją INT 3h (zwaną nanomitem). Podczas wymiany opkodów program zapisuje typ skoku (JE, JNE, JAE itp.), miejsce, w którym znajdowała się instrukcja skoku (offset) oraz miejsce, do którego prowadzi instrukcja skoku (offset). Można to zrobić np. dzieląc program na dwa procesy: proces kontroli i proces chronionej aplikacji. Proces kontroli miałby wtedy procedurę obsługi wykonania nanomitu. Dla prostoty i łatwej nauki wszystko może być w jednym procesie. Głównym zadaniem jest rozpoznanie, czy przerwanie INT 3h jest nanomitem, czy nie. A potem odpowiednia obsługa przerwań, na przykład: odczytanie zapisanego wcześniej typu skoku, sprawdzenie stanu rejestru flag i wykonanie skoku, jeśli warunek jest spełniony.

Przechwycenie procedury obsługi przerwań INT 3h można wykonać na kilka sposobów. Pierwszą rzeczą, która przychodzi na myśl, jest strukturalna obsługa wyjątków (SEH). Można również debugować utworzony proces (WaitForDebugEvent(...)).

Program w funkcji main ustawia procedurę obsługi wyjątków za pomocą funkcji SetUnhandledExceptionFilter. Następnie wykonuje się proste porównanie rejestru RAX z pewną wartością (cmp rax, 02h). Domyślnie po takim porównaniu powinien być skok warunkowy (np. JE, JNE itp.), ale jest nanomit. Odbywa się to za pomocą makra nanomite_here, które przyjmuje dwa parametry: typ skoku i adres do etykiety docelowej. Makro zapisuje niezbędne informacje do struktury, a następnie zgłasza wyjątek INT 3h. Zgłoszenie wyjątku przekazuje kontrolę do procedury myExceptionHandler. Ta procedura sprawdza typ skoku, warunek na podstawie zapisanego bajta z rejestru flag i decyduje, czy wykonać skok, czy też może przekazać kontrolę do następnej instrukcji po INT 3h.

Przykład edukacyjny w Asemblerze x86-64 (MASM x64)
;-------------------------------------------------+

; Nanomites anti-dump technique example           ;
; (general idea, primitive educational prototype) ;
;-------------------------------------------------+
; Code: Dawid Farbaniec                           ;
;-------------------------------------------------+

extrn ExitProcess : proc
extrn MessageBoxA : proc
extrn SetUnhandledExceptionFilter : proc

;jump types
jumpTypeJZ  equ 0
jumpTypeJNZ equ 1
jumpTypeJE  equ jumpTypeJZ
jumpTypeJNE equ jumpTypeJNZ
;(...) etc.

;jump information structure
NanomiteStruct struct
JumpType dq ?
SavedFlags db ?
JumpAddress dq ?
NextInstructionAddress dq ?
NanomiteStruct ends

;create nanomite macro
nanomite_here macro _type, _address
lahf
mov nano.JumpType, _type
mov nano.SavedFlags, ah
mov rax, offset _address
mov nano.JumpAddress, rax
mov rax, offset @f
mov nano.NextInstructionAddress, rax
int 3h ;nanomite
@@:
endm

.data
szCaption db "ethical.blue", 0
szTextYes db "Nanomite executed.", 0
szTextNo db "Nanomite NOT executed.", 0
nano NanomiteStruct <0, 0, 0, 0>

.code

;this procedure is called by int 3h
myExceptionHandler proc

cmp nano.JumpType, jumpTypeJZ
jne @f
jmp _JZ

@@:
cmp nano.JumpType, jumpTypeJNZ
jne _return

_JNZ:
mov rcx, nano.JumpAddress
mov ah, nano.SavedFlags
and ah, 40h
cmp ah, 0h
jz _go
jmp _return

_JZ:
mov rcx, nano.JumpAddress
mov ah, nano.SavedFlags
and ah, 40h
cmp ah, 40h
jz _go
jmp _return

_go:
jmp rcx
jmp _return

_return:
jmp nano.NextInstructionAddress

myExceptionHandler endp

Main proc

sub rsp, 28h
mov rcx, myExceptionHandler
call SetUnhandledExceptionFilter
add rsp, 28h

mov rax, 07h
cmp rax, 02h

nanomite_here jumpTypeJNZ, _executed

jmp _notexecuted

_executed:
lea rdx, szTextYes
jmp _msgbox

_notexecuted:
lea rdx, szTextNo

_msgbox:
sub rsp, 28h
xor r9, r9
lea r8, szCaption
;RDX ustawiony wcześniej
xor rcx, rcx
call MessageBoxA
add rsp, 28h

_exit:
sub rsp, 28h
xor rcx, rcx
call ExitProcess
Main endp

end

Jak wspomniano wcześniej, jest to tylko prosty przykład edukacyjny. W przypadku rzeczywistej implementacji tej techniki zdecydowanie należałoby dodać szyfrowanie struktury informacji nanomitu, oddzielić procedurę obsługi od innego procesu i uwzględnić inne techniki dla lepszej ochrony.

Wykaz literatury

Nanomites.w32 virus by Deroko

ethical.blue Appz

Categories

Archives


Donate to ethical.blue Magazine website maintenance with cryptocurrency or PayPal.

aspnet
Connections: 11

bitcoin diesel