(Polish) LapSec – Hispasec

July 29th, 2010 Icewall No comments

Sorry, this entry is only available in Polish.

(Polish) Błąd logiczny w <= gmer.sys [1, 0, 15, 4809 built by: WinDDK]

July 22nd, 2010 Icewall No comments

Błąd logiczny w <= gmer.sys [1, 0, 15, 4809 built by: WinDDK]

Przy okazji badań opisanych w ostatnim poście, odkryłem w sterowniku gmer’a pewien błąd logiczny mogący powodować nieprawidłowe działanie losowych aplikacji.
Żeby przybliżyć sobie kwestię, o której będę pisał polecam zajrzeć do punktu drugiego poprzedniego postu, a dokładnie do implementacji rozwiązanie w ring0.
Do rzeczy, naszym obiektem zainteresowań jest najnowszy sterownik gmer’a na dzień 22.07.2010:
FileVersion : 1, 0, 15, 4809 built by: WinDDK

[+]Lokalizacja problemu
Jeśli jakiś plik nie może zostać usunięty w standardowy sposób, gmer stara się zamknąć wszystkie otwarte handlery odwołujące się do tego pliku, a następnie go usunąć. Moim zdaniem, niestety implementacja tej procedury przez twórcę gmer’a nie została do końca dobrze przemyślana.
Rzućmy okiem na tą prockę:
[asm]
.text:0001B488 ; int __stdcall sub_1B488(wchar_t *filePath, int a2)
.text:0001B488 sub_1B488 proc near ; CODE XREF: sub_1CB32+299 p
.text:0001B488
.text:0001B488 PFILE_OBJECT = dword ptr -30h
.text:0001B488 var_2C = dword ptr -2Ch
.text:0001B488 var_28 = dword ptr -28h
.text:0001B488 PSYSTEM_HANDLE_INFORMATION= dword ptr -24h
.text:0001B488 pEPROCESS = dword ptr -20h
.text:0001B488 index = dword ptr -1Ch
.text:0001B488 ms_exc = CPPEH_RECORD ptr -18h
.text:0001B488 filePath = dword ptr 8
.text:0001B488 a2 = dword ptr 0Ch
.text:0001B488
.text:0001B488 push 20h
.text:0001B48A push offset stru_1EED0
.text:0001B48F call __SEH_prolog
.text:0001B494 xor esi, esi
.text:0001B496 mov [ebp+pEPROCESS], esi
.text:0001B499 lea eax, [ebp+var_28]
.text:0001B49C push eax ; int
.text:0001B49D push 10h ; SystemHandleInformation
.text:0001B49F call wrap_NtQuerySystemInformation
.text:0001B4A4 mov [ebp+PSYSTEM_HANDLE_INFORMATION], eax
.text:0001B4A7 cmp eax, esi
.text:0001B4A9 jz error
.text:0001B4AF mov [ebp+ms_exc.disabled], esi
.text:0001B4B2 mov [ebp+index], esi
.text:0001B4B5 mov ebx, ds:NtClose
.text:0001B4BB
.text:0001B4BB loc_1B4BB: ; CODE XREF: sub_1B488+119 j
.text:0001B4BB mov ecx, [ebp+index]
.text:0001B4BE cmp ecx, [eax] ; eax = NumberOfHandles
.text:0001B4C0 jnb end_of_SYSTEM_HANDLE_INFORMATION
.text:0001B4C6 shl ecx, 4
.text:0001B4C9 lea edi, [ecx+eax+4]
.text:0001B4CD mov [ebp+var_2C], edi
.text:0001B4D0 mov esi, [edi+8]
.text:0001B4D3 mov [ebp+PFILE_OBJECT], esi
.text:0001B4D6 test esi, esi
.text:0001B4D8 jz next_struct
.text:0001B4DE push esi ; VirtualAddress
.text:0001B4DF call ds:MmIsAddressValid
.text:0001B4E5 test al, al
.text:0001B4E7 jz next_struct
.text:0001B4ED cmp word ptr [esi], 5
.text:0001B4F1 jnz next_struct
.text:0001B4F7 mov eax, [esi+34h]
.text:0001B4FA test eax, eax
.text:0001B4FC jz next_struct
.text:0001B502 push eax ; VirtualAddress
.text:0001B503 call ds:MmIsAddressValid
.text:0001B509 test al, al
.text:0001B50B jz next_struct
.text:0001B511 push [ebp+filePath] ; VirtualAddress
.text:0001B514 call ds:MmIsAddressValid
.text:0001B51A test al, al
.text:0001B51C jz short next_struct
.text:0001B51E push [ebp+filePath] ; wchar_t *
.text:0001B521 call ds:wcslen
.text:0001B527 pop ecx
.text:0001B528 sub eax, 6
.text:0001B52B mov [ebp+a2], eax
.text:0001B52E movzx ecx, word ptr [esi+30h] ; fileObject->FileName.Length
.text:0001B532 shr ecx, 1
.text:0001B534 cmp ecx, eax
.text:0001B536 jnz short next_struct
.text:0001B538 push eax ; size_t
.text:0001B539 mov eax, [ebp+filePath]
.text:0001B53C add eax, 0Ch
.text:0001B53F push eax ; wchar_t *
.text:0001B540 push dword ptr [esi+34h] ; fileObject->FileName.Buffer
.text:0001B543 call ds:_wcsnicmp
.text:0001B549 add esp, 0Ch
.text:0001B54C test eax, eax
.text:0001B54E jnz short next_struct
.text:0001B550 lea eax, [ebp+pEPROCESS]
.text:0001B553 push eax
.text:0001B554 push dword ptr [edi]
.text:0001B556 call ds:PsLookupProcessByProcessId
.text:0001B55C mov status, eax
.text:0001B561 test eax, eax
.text:0001B563 jnz short next_struct
.text:0001B565 mov eax, [ebp+pEPROCESS]
.text:0001B568 cmp eax, current_process_EPROCESS
.text:0001B56E jz short handleBelongsToCurrentProcess
.text:0001B570 push eax
.text:0001B571 call ds:KeAttachProcess
.text:0001B577 movzx eax, word ptr [edi+6]
.text:0001B57B push eax ; Handle
.text:0001B57C call ebx ; NtClose
.text:0001B57E mov status, eax
.text:0001B583 call ds:KeDetachProcess
.text:0001B589 jmp short loc_1B592
.text:0001B58B ; —————————————————————————
.text:0001B58B
.text:0001B58B handleBelongsToCurrentProcess: ; CODE XREF: sub_1B488+E6 j
.text:0001B58B movzx eax, word ptr [edi+6]
.text:0001B58F push eax ; Handle
.text:0001B590 call ebx ; NtClose
.text:0001B592
.text:0001B592 loc_1B592: ; CODE XREF: sub_1B488+101 j
.text:0001B592 mov ecx, [ebp+pEPROCESS] ; Object
.text:0001B595 call ds:ObfDereferenceObject
.text:0001B59B
.text:0001B59B next_struct: ; CODE XREF: sub_1B488+50 j
.text:0001B59B ; sub_1B488+5F j …
.text:0001B59B inc [ebp+index]
.text:0001B59E mov eax, [ebp+PSYSTEM_HANDLE_INFORMATION]
.text:0001B5A1 jmp loc_1B4BB
.text:0001B5A6 ; —————————————————————————
.text:0001B5A6
.text:0001B5A6 _end: ; DATA XREF: .rdata:stru_1EED0 o
.text:0001B5A6 xor eax, eax
.text:0001B5A8 inc eax
.text:0001B5A9 retn
[asm]

Gdzie tu jest problem?
Przyjrzyjmy się samej kwesti odnalezienia przez gmer’a uchwytu, który jest powiązany z plikiem do którego handlery chcemy pozamykać. Autor gmer’a postanowił tutaj skorzystać z dostarczonego w
strukturze SYSTEM_HANDLE_INFORMATION FILE_OBJECT’u i slusznie,no ale…

Sprawdzenie rozpoczyna się od zbadania długości scieżki podanej jako argument i tej zawartej w file object’e.

[asm]
.text:0001B51E push [ebp+filePath] ; wchar_t *
.text:0001B521 call ds:wcslen
.text:0001B527 pop ecx
.text:0001B528 sub eax, 6
.text:0001B52B mov [ebp+a2], eax
.text:0001B52E movzx ecx, word ptr [esi+30h] ; fileObject->FileName.Length
.text:0001B532 shr ecx, 1
.text:0001B534 cmp ecx, eax
.text:0001B536 jnz short next_struct
[asm]
Jeśli długości są identyczne przechodzimy do następnego testu. Zanim jednak przejde dalej odczuwam wielką potrzebe czepienia się jednej kwestii związaną z dobrymi praktykami jak i optymalizacją kodu.
Chodzi dokładnie o ten fragment:
[asm]
.text:0001B51E push [ebp+filePath] ; wchar_t *
.text:0001B521 call ds:wcslen
[asm]
Ten fragment znajduję się wewnątrz pętli i przy każdej iteracji, kiedy obiektem okazuje się plikiem, wywoływana jest zupełnie bez sensownie funkcja wcslen na zmiennej filePath, która została podana jako parametr do sub_1B488!!! Takie wielokrotne wyliczanie tej samej wartości wewnątrz pętli prowadzi do niczego innego niż zmniejszenia wydajności kodu a w tym przypadku wydajność będzie mala wręcz wprost proporcjonalnie do długości stringu. Także, nie polecam takich konstrukcji ;) (btw: jak zobaczyłem ten twór to przypomniał mi się post Malcom’a „Programowanie wymaga myślenia!” http://blog.malcom.pl/2009/09/09/programowanie-wymaga-myslenia/, polecam).

Kontynuujmy:
[asm]
.text:0001B538 push eax ; length
.text:0001B539 mov eax, [ebp+filePath]
.text:0001B53C add eax, 0Ch
.text:0001B53F push eax ; wchar_t *
.text:0001B540 push dword ptr [esi+34h] ; fileObject-&amp;amp;amp;gt;FileName.Buffer
.text:0001B543 call ds:_wcsnicmp
[/asm]
Tutaj dokonywane jest już porównanie stringów reprezentujących ścieżki do plików.
Ale, ale !!! Nie jest to porównanie zawierające litery partycji, na której dany plik się znajduje!!!
Ścieżki mają tu postać:
„\folder\file.ext”

Tylko i wyłącznie takie porównanie doprowadza do sytuacji, w której handler powiązany z plikiem o takiej samej scieżce jak scieżka podana jako parametr funkcji, lecz znajdujący się na innej partycji zostanie zamknięty!!!

[+]Przykład
Na potrzeby testów stworzyłem niewielką aplikację, która otwiera handler do pliku bez praw do usunięcia( bez FILE_SHARE_DELETE, w celu zmuszenia gmer’a do wywołania powyżej omawianej procki). Kod tej aplikacji jest następujący:

int main(int argc, char* argv[])
{

	HANDLE h = CreateFileA(argv[1],
				GENERIC_READ,
				FILE_SHARE_READ | FILE_SHARE_WRITE,
				0,
				OPEN_EXISTING,
				FILE_ATTRIBUTE_NORMAL,
				0);
	if(h == INVALID_HANDLE_VALUE)
	{
		cout&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;quot;[+]INVALID_HANDLE_VALUE&amp;amp;amp;amp;quot;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;endl;
		cout&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;hex&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;GetLastError();
		return 0;
	}
	cout&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;quot;[+]File opened!&amp;amp;amp;amp;quot;&amp;amp;amp;amp;lt;&amp;amp;amp;amp;lt;endl;
	getchar();
}

oraz narzędzia Handle v3.42, do wylistowania wszystkich otwartych handlerów przez dany proces. Na dwóch konsolach odpaliłem swój kod skompilowany do pliku zlo.exe z następującymi parametrami:

Console_1:
zlo.exe C:\install.exe

oraz

Console_2:
zlo.exe E:\install.exe

Po odpaleniu aplikacji wylistowałem otwarte przez nie handler:

// Przed proba usuniecia C:\install.exe [+]
c:\Documents and Settings\virtual&amp;amp;amp;amp;gt;handle.exe -p zlo.exe

Handle v3.42
Copyright (C) 1997-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

------------------------------------------------------------------------------
zlo.exe pid: 1928 SLAVE\virtual
    C: File  (RW-)   C:\Documents and Settings\virtual
  7E8: File  (RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375
  7F4: File  (RW-)   C:\install.exe
------------------------------------------------------------------------------
zlo.exe pid: 932 SLAVE\virtual
    C: File  (RW-)   C:\Documents and Settings\virtual
  7E8: File  (RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375
  7F4: File  (RW-)   E:\install.exe

Następnie przy pomocy gmer’a usunąłem plik C:\install.exe i ponownie wylistowałem handlery:

//Po usunieciu przez gmer'a C:\install.exe
c:\Documents and Settings\virtual&amp;amp;amp;amp;gt;handle.exe -p zlo.exe

Handle v3.42
Copyright (C) 1997-2008 Mark Russinovich
Sysinternals - www.sysinternals.com

------------------------------------------------------------------------------
zlo.exe pid: 1928 SLAVE\virtual
    C: File  (RW-)   C:\Documents and Settings\virtual
  7E8: File  (RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375
------------------------------------------------------------------------------
zlo.exe pid: 932 SLAVE\virtual
    C: File  (RW-)   C:\Documents and Settings\virtual
  7E8: File  (RW-)
C:\WINDOWS\WinSxS\x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375

Efekt potwierdził moją teorie, tak jak widać uchwyt do E:\install.exe również został zamknięty.

[+]Rada
Dodanie pełnego badania ścieżek do plików m.in z wykorzystaniem np. IoQueryFileDosDeviceName.

No i chyba tyle;)

(Polish) Tochę o usuwaniu plików

July 21st, 2010 Icewall 4 comments

Sorry, this entry is only available in Polish.

(Polish) Opera – Null Pointer Dereference

May 14th, 2010 Icewall No comments

Sorry, this entry is only available in Polish.

VBox,Virtual PC,VMware and IDT Hooking

October 27th, 2009 Icewall 4 comments

It’s gonna be quite light version of post about “anomaly” which I had pleasure to notice during tests of IDT hooking under virtual machines mentioned in this post title. Why light? Because in order to present all details related with cases that I’m going to show in letter part of post, it would required a deeply research regarding to internal manner of work each virtual machine
( I guess so :P ). My suggestion is to treat this post like a curiosity/(vector to research) and not like a result of deeply research.

Entire story begins from the moment when I decided to test the simplest hook on KiSystemService procedure through modification its address in IDT table. It’s a piece of code responsible of hook installation:

void IDTHook()
{
IDTINFO idtInfo;
IDTENTRY *idt_entries;
IDTENTRY *int2e_entry;
DbgPrint([+] IDTHook);
//pobranie IDTINFO
idtInfo = getIDTInfo();
//pobranie *tablicy IDT
idt_entries = getIDTEntries(&idtInfo);

//zapisanie oryginalnego IDTENTRY_2E
orgIDTEntry_2e = idt_entries[KiSystemService_INDEX];
//zapisanie DWORD'a na potrzeby funkcji hookujacej
orgKiSystemService = MAKELONG(orgIDTEntry_2e.LowOffset,orgIDTEntry_2e.HiOffset);
__asm cli;//wylacz obsluge maskowalnych przerwan
idt_entries[KiSystemService_INDEX].LowOffset = (unsigned short)(&MySystemService);
idt_entries[KiSystemService_INDEX].HiOffset  = (unsigned short)(((unsigned long)(&MySystemService))<<16);
__asm lidt idtInfo;
__asm sti;//wlacz obsluge maskowalnych przerwan

}

‘code MySystemService has been rewritten from „Subverting Windows Kernel”‘

__declspec(naked) MySystemService()
{

__asm{
pushad
pushfd
push fs
mov bx,0x30
mov fs,bx
push ds
push es
//do something

//Finish:
pop es
pop ds
pop fs
popfd
popad

jmp	orgKiSystemService;
}
}
/* __asm { sysenter VPC } */

Without bigger doubts and not necessary thinking I decided to test obtained driver under
Virtual PC(ver. 6.0.192.0 + additions)[OS: Windows XP SP3 Eng], which I mostly used to use. To my great surprise (because I counted on BSOD :P ) during attempt to hook installation, occurred internal VPC error:
vpc_crash_error

Hymm…strange issue I thought. Meanwhile I remind to myself that operation system doesn’t need to use IDT table if our processor supports sysenter/syscall instruction. Eye throw under vpc on call to one of mostly used native api: ZwOpenFile, dispelled my doubts:
vpc_syscalls_handler

Error “triggered” by VPC pointed that it’s not strict related problem with OS, rather with vm, and now additionally we know that sense of hook installation on IDT under VPC isn’t too big(by what should be harmless) ;) . I decided to perform test again after uninstallation additions from system. Another surprise here, system acted like it should act, that is:
- hook have been installed successfully
and neither of breakpoints (after quite long time), which I had set on MySystemService wasn’t triggered. We will see now how to cases look under VirtualBox.

/* __asm { INT VirtualBox } */

Ver. 3.0.8 r53138 + additions
OS stays without changes under each vm.

First issue which I have checked under this vm is manner on what process steps from r3 to r0.
vbox_syscalls_handler

Delicious! Like you can see on attached screenshot without any doubts we can test hooks on IDT. It seemed as such to me …
I’m loading driver ,I’m passing proper IOCTL code to my driver which is going to trigger hook installation and … :

vbox_crash

entire action is ending with unexpected VBox crash.
Don’t wondering too much I have uninstalled additions from system and I repeated test. Success! Hook installation have been made without any problems, but after couple another attempts I’ve had situations where system crashed with BSOD unambiguously saying, that occurred access attempt to paged memory region. Windbg was pointing following line of code as source of all evil:

idt_entries[KiSystemService_INDEX].LowOffset = (unsigned short)(&amp;amp;MySystemService);

Hymm…a little strange. IDT in paged memory region o_0 ?
I have modified a little source code to eliminate this problem by mapping IDT table under NON-PAGED memory area. Code presents now in the following way :

void IDTHook()
{
IDTINFO idtInfo;
IDTENTRY *idt_entries;
IDTENTRY *int2e_entry;
DbgPrint("[+] IDTHook");
//pobranie IDTINFO
idtInfo = getIDTInfo();
//pobranie *tablicy IDT
idt_entries = getIDTEntries(&amp;idtInfo);

//try to map it
idt_entries = mapMemory(idt_entries,idtInfo.IDTLimit);// NOWA LINIA
//update idtinfo struct
idtInfo.HiIDTbase  = HIWORD(idt_entries);
idtInfo.LowIDTbase = LOWORD(idt_entries);

//zapisanie oryginalnego IDTENTRY_2E
orgIDTEntry_2e = idt_entries[KiSystemService_INDEX];
//zapisanie DWORD'a na potrzeby funkcji hookujacej
orgKiSystemService = MAKELONG(orgIDTEntry_2e.LowOffset,orgIDTEntry_2e.HiOffset);
__asm cli;//wylacz obsluge maskowalnych przerwan
idt_entries[KiSystemService_INDEX].LowOffset = (unsigned short)(&amp;amp;MySystemService);
idt_entries[KiSystemService_INDEX].HiOffset  = (unsigned short)(((unsigned long)(&amp;MySystemService))&gt;&gt;16);
__asm lidt idtInfo;
__asm sti;//wlacz obsluge maskowalnych przerwan

}

This simple “patch” eliminated occurrence of BSOD’s.

/* __asm { VMware sysenter } */

VMware Workstation
6.5.3 build-185404

Quick look on transition r3 – > r0:
vmware_syscalls_handler
As we can see sysenter has been used here. I won’t dwell on vmware and at the beginning I’m going to say that there is no problems with hook installation, with or without installed additions in system.

As summary I prepared the following table:
table

Like always comments and any kind of suggestions are welcome ;) .

(Polish) SecDay 2009 – Video

October 14th, 2009 Icewall 2 comments

Sorry, this entry is only available in Polish.

(Polish) Nowa odsłona

October 1st, 2009 Icewall 2 comments

Sorry, this entry is only available in Polish.

Categories: Ogólne Tags:

SecDay 2009

September 24th, 2009 Icewall No comments

Wczoraj, to jest 22.09.2009r zakończyła się dwu dniowa konferencja SecDay 2009 organizowana przez Lukasz Błażys’a, która odbyła się we Wrocławiu, a jak nie trudno się domyślić była ona związana z ogólno pojętym bezpieczeństwem w IT. Z wielką przyjemnością muszę przyznać, że pierwszy raz ….UWAGA…….UWAGA miałem okazję:
brać czynny udział == być prelegentem!
na tego typu event’e.
LGIM0042

Emocje były wielkie …… ale jak dokładnie było możecie przeczytać poniżej:
Na wstępie powiem, że nie będę w żaden sposób komentował prezentacji Team’u HSPL w składzie (chronologicznie względem kolejności wystąpień):

Mateusz “j00ru” Jurczyk
Adam “pi3″ Zabrocki
Gynvael Coldwind

Żeby nikt nie zarzucał mi, że cukruje kolegą z pracy to tylko powiem, że każda prezentacja była petardą i warto na nie rzucić okiem :P ..Heheh.
More details below…

/* SecDay 2009 dzień pierwszy */
Jako, że obecnie mieszkam we Wrocławiu to kwestie dotarcia na konferencje pominę ponieważ nie było w niej nic nadzwyczajnego(15min taxi)….taaa to nie to samo co 5h spędzonych w pociągu w drodze na confidence :P .

Konferencje rozpoczął :
Dariusz Puchalak
prezentując temat:
„Bezpieczeństwo czy wydajność pracy?”
Niestety muszę się przyznać, że delikatnie się spóźniłem na ten wykład(sorry Darek :P ).
Już parę razy miałem okazje słuchać prezentacji Darka i także tym razem była ona prowadzona na wysokim poziomie. Ze względu na porę dnia długo nie zastanawiałem się
nad propozycją jaką Dariusz umieścił w swoim temacie i wybrałem …..NIEBEZPIECZEŃSTWO.:D.

Przemysław Świercz
Bezpieczeństwo Bluetooth
Na wstępie trzeba wspomnieć, że był to debiut Przemka co moim zdaniem po wysłuchaniu jego prelekcji jest jak najbardziej na plus. Temat myślę, że jak najbardziej na czasie, bo przecież bluetooth można spotkać teraz praktycznie w każdym telefonie komórkowym, większości nowych TV,itd. Prezentacja była mocno techniczna (a takie właśnie uwielbiam) + zabawne anegdoty prowadzącego działające silnie na wyobraźnie ;) .
Jeżeli ktoś jest zainteresowany bezpieczeństwo Bluetooth to myślę, że warto prześledzić tą prezentacje.

/* Przerwa na kafkę i po niej …*/

Mateusz Jurczyk
Bootkit vs Windows
Jako, że j00ru prowadzi własny blog to zachęcam do przeczytania jego relacji z konferencji jak i pobrania materiałów -> j00ru’s blog

/* Przerwa obiadowa */
Mówiąc krótko i kolokwialnie „obiad był bez szału”, także nie mogę tutaj przyznać ani plusa ani minusa, ale na pewno wypadł o wiele lepiej niż tegoroczny podawany na confidence’e.
Małego minusa dam za to, że dwa dni była ta sama potrawa:P,,,,gdzie kucharz „zostawił” fantazję!?

wracamy do prelekcji:

Krzysztof Maćkowiak
„Zarządzanie ryzykiem podstawą profesjonalnego podejścia do bezpieczeństwa informacji i ciągłości działania.”
Prezentacja jak najbardziej wykonana jak i poprowadzona w sposób profesjonalny, chociaż nie interesująca mnie zbytnio ze względu na obszar działań jakie poruszała. Dlatego też 3/4 jej czasu przegadałem z carstein’em o niuansach związanych z pentestingiem :P .

Grzegorz Błoński
Problem ulotu elektromagnetycznego.
Bardzo interesująca prezentacja, mocno techniczna podczas, której mogliśmy zobaczyć parę narzędzi do monitorowania ulotu elektromagnetycznego stworzonych przez autora przy wykorzystaniu popularnych kart telewizyjnych :D . Jeżeli byłeś/jesteś fanem serialu MacGyver masz zbędną kartę TV to nie czekaj tylko przeanalizuj powyższą prezentacje i rozpocznij własne badania!

Michał Melewski
Metodyka testów penetracjnych.
Moim zdaniem elegancko wykonana prezentacja, przejrzysta, przedstawiona na luzie, dająca do myślenia jeżeli chodzi o podejście do pentestów. Dzięki za źródło do refleksji ;) .

Leszek Miś
Rootkity w systemie Linux.
Niestety prelegent nie dotarł na konferencje, a szkoda bo z chęcią posłuchałbym jak wygląda kwestia związana z rootkit’ami na linuxach.

Janusz Żmudziński
Monitorowanie bezpieczeństwa jako istotny element skutecznego zarządzania bezpieczeństwem informacji
?

/* SecDay 2009 dzień drugi */
Jako, że miałem przyjemność rozpocząć dzień drugi to przejdę od razu do drugiej prezentacji, a o własnej wspomnę na końcu relacji.

Konrad Zuwała
Solaris jako bezpieczna platforma serwerowa.
Od strony technicznej prezentacja jak najbardziej poprowadzona bardzo dobrze. Przeznaczona raczej dla administratorów i w tym kręgu znalazła ona grono słuchaczy jak i wywołała burzliwą dyskusję.

Błażej Miga
Zagrożenia w Internecie – DNS
Muszę powiedzieć, że na opublikowanie tej prezentacji czekam ponieważ pojawiło się w niej parę smaczków, które z chęcią bym przetestował. Hehe no i pojawił się w niej kod python’owy z wykorzystaniem modułu scapy.. jak widać prelegent wie co dobre;).

/* Dinner */

Jakub Bryl
Testowanie planów ciągłości działania
?

Adam Zabrocki
Unusual bugs
Adam obiecał wystartować z nową stroną/blogiem, a wtedy na pewno będziecie mieli okazje przejrzeć jego materiały ;) .

Gynvael Coldwind
PHP Internals (not another RFI/SQLI)
Relacja Gyn’a + jego materiały. -> LINK

Robert Dąbrowski
Monitoring bezpiecznej sieci – praktyczne wykorzystanie logów.
Przepraszam, ale prezentacje komercyjnych produktów mnie nie interesują. Tu chodzi o research w dobrym klimacie tzw „piwnicznym klimacie”:D!

I tak kończy się lista prelegentów wraz ich tematami, których miałem przyjemność w większości wysłuchać.

Jeżeli chodzi o mój temat to brzmi on następująco:
Bugs in malware
Moim główny zamiarem było uświadomienie słuchaczy o tym, że w wieluuuuu przypadkach tworzony malware NIE jest doskonały, bardzo często tworzą go ludzie, którzy nie mają nawet średnich umiejętności programistycznych, a gruntowne testowanie swojego tworu jest dla nich abstrakcją. Często zdarza mi się spoglądając w kod malware’u pomyśleć o wyrażeniu : tragizm połączony z idiotyzmem. Czy taki obraz złośliwego oprogramowania przedstawiany jest w prasie i mediach? NIE. Oczywiście głównymi hasłami jakie pojawiają się są następujące:
„nowy błyskawicznie rozprzestrzeniający się worm”
„bardzo trudny do usunięcia trojan”
„trudno wykrywalny wirus”
„maszynka do wykradania poufnych danych”
itp.

Taki obraz, będący totalną generalizacją na temat malware’u, który rzekomo jest absolutnie genialny, trudny do usunięcia, napisany przez pr0 cod3r0w miałem na zamiarze usunąć z mapy rzeczywistości słuchaczy, a przynajmniej wzbogacić ją o informacje, które pokazują „troszeczke” inny obraz tych „złośliwych” aplikacji ;) . Czy mi się udało ?;]. Mam taką nadzieję;).

Jeżeli chodzi o moje materiały to możecie je pobrać stąd:
(Pliki sa oczywiscie w formacie ZIP.Przepraszam za utrudnienia w pobieraniu, ale takie są uroki korzystania z wordpress’a.)
Prezentacja -> prezentacja_Icewall_SecDay_2009.zip(ODP&PDF)
Pełna paczka(prezentacja + filmiki) -> Icewall_SecDay_2009.zip

W kwestii wyjaśnienia: Jeden z filmików zbudził delikatne kontrowersje dlatego też został odpowiednio ocenzurowany.

Hiperlinki w ODP jak i w PDF’e są ustawione w sposób relatywny, także można na nie klikać dowoli jeżeli zachowacie następująco strukturę katalogów:

Delephant
GetCodec
Zeus
prezentacja.odp
prezentacja.pdf


PS: Możliwe, że nawet do końca tygodnia pojawi się photo jaki i video relacja z konferencji dla której myśle stworze osobny post. Na video relacji będziecie mogli obejrzeć wszystkie prelekcje ludzi zarówno z HSPL jak i Vexillium. Także bądźcie czujni;),będzie co oglądać.

Pozdrawiam i zapraszam na kolejną edycje SecDay już we wrzesniu, bo warto;).

Algorytmy (de)szyfrowania wykorzystywane przez twórców trojanów bankowych – PART II

August 29th, 2009 Icewall No comments

Tak jak wspominałem w poprzednim poście niniejszy będzie o sposobach (de)szyfrowania stosowanych w pewnej rodzinie trojanów bankowych pisanych w delphi.

Oczywiście tradycyjnie zaczniemy od przedstawienia naszego bohatera:
[=]Dane[=]

Antivirus	Version	Last Update	Result
a-squared	4.5.0.24	2009.08.28	Trojan-Spy.Win32.Bancos!IK
AhnLab-V3	5.0.0.2	2009.08.28	-
AntiVir	7.9.1.7	2009.08.28	TR/Spy.Banker.DS.5102592
Antiy-AVL	2.0.3.7	2009.08.24	-
Authentium	5.1.2.4	2009.08.28	-
Avast	4.8.1335.0	2009.08.28	Win32:Spyware-gen
AVG	8.5.0.406	2009.08.28	PSW.Banker5.IQR
BitDefender	7.2	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
CAT-QuickHeal	10.00	2009.08.28	-
ClamAV	0.94.1	2009.08.28	Trojan.Agent-119128
Comodo	2125	2009.08.28	-
DrWeb	5.0.0.12182	2009.08.28	Trojan.PWS.Banker.based
eSafe	7.0.17.0	2009.08.27	-
eTrust-Vet	31.6.6706	2009.08.28	-
F-Prot	4.5.1.85	2009.08.27	-
F-Secure	8.0.14470.0	2009.08.28	-
Fortinet	3.120.0.0	2009.08.28	W32/Banker.B!tr.pws
GData	19	2009.08.28	DeepScan:Generic.Banker.OT.4CC5D1C8
Ikarus	T3.1.1.68.0	2009.08.28	Trojan-Spy.Win32.Bancos
Jiangmin	11.0.800	2009.08.28	-
K7AntiVirus	7.10.830	2009.08.28	-
Kaspersky	7.0.0.125	2009.08.28	-
McAfee	5723	2009.08.28	PWS-Banker.gen.b
McAfee+Artemis	5723	2009.08.28	Artemis!504F1C591479
McAfee-GW-Edition	6.8.5	2009.08.28	Trojan.Spy.Banker.DS.5102592
Microsoft	1.5005	2009.08.28	TrojanSpy:Win32/Bancos.gen!C
NOD32	4378	2009.08.28	probably a variant of Win32/Spy.Banker.QEO
Norman		2009.08.28	W32/Banker.EKFF
nProtect	2009.1.8.0	2009.08.28	-
Panda	10.0.2.2	2009.08.28	Trj/CI.A
PCTools	4.4.2.0	2009.08.28	-
Prevx	3.0	2009.08.28	-
Rising	21.44.40.00	2009.08.28	Trojan.PSW.Win32.Banker.dnl
Sophos	4.45.0	2009.08.28	Mal/Generic-A
Sunbelt	3.2.1858.2	2009.08.28	-
Symantec	1.4.4.12	2009.08.28	Infostealer.Bancos
TheHacker	6.3.4.3.389	2009.08.27	-
TrendMicro	8.950.0.1094	2009.08.28	-
VBA32	3.12.10.10	2009.08.28	-
ViRobot	2009.8.28.1907	2009.08.28	-
VirusBuster	4.6.5.0	2009.08.28	TrojanSpy.Banker.CDVF
Additional information
File size: 5102592 bytes
MD5   : 504f1c5914799e5122c69620c0b892e2
SHA1  : 32980745998151bda4a9e3bab767201ebc52fc0a
SHA256: 54d974192dd53aba186d56803087224ff8f8b0aba9687604332891842bb5ef58

[=]Prolog[=]
Tak jak pewnie udało wam się zauważyć w poprzednim poście malware ten posiada np. zaszyfrowane ścieżki, do których zostaną wykonana jego kopie. Przykładowy zaszyfrowany ciąg wygląda tak:
GpfSH6zZTMrbRdHp865kP21JPNHqQMvdSrn1R6mWLNDbSdDSJMLkTI19RcbZQM5oN51oRsToOMrXSrn9RcbZQM5iQNfXSbnNQMvaRtTpCp8kPNXb

gdzie po deszyfrowaniu otrzymujemy łańcuch:
C:\Documents and Settings\All Users\Menu Iniciar\Programas\Inicializar\Windows32.exe

W jaki sposób funkcjonuje ten algorytm ? Tego dowiemy się już za chwilę.
Wcześniej jednak sprecyzuje „elementy”, które w tym malware’e wymagają deszyfrowania:

- ścieżki, do który kopiowany jest malware
- tytuły okien IE(malware używa tytułów okien do rozpoznania czy user znajduje się obecnie na stronie, dla której trojan ma przygotowany np. fałszywy panel logowania)
- treść fałszywych komunikatów mówiących o tym, że np. Internet Explorer wykonał
nieprawidłową operacje i zostanie zamknięty.

w niektórych wersjach także:
- login&hasło do serwera ftp/mysql używanego jako drop host
- adresy email na które mają zostać przesłane skradzione dane

Warto tutaj wspomnieć o różnicy, która występuje w podejściu autorów trojana obecnego i tego z poprzedniego postu. Jak pamiętamy tam autor nie dość, że stosował różnego rodzaju klucze xor’ujące to jeszcze zmieniały się w nieznacznym stopniu same procedury szyfrowania. Tutaj spoglądając na wygląd ciągów reprezentujących zaszyfrowane dane:
encrypted_strings

Można zakładać, że procedura deszyfrująca jest jedna, globalna. Po dokładnej analizie okazuje się, że faktycznie tak jest i nadszedł czas żeby przyjrzeć się jej bliżej.
Oczywiście jej lokalizację można w prosty sposób ustalić po przez przejście do kawałka kodu, który odwołuje się do jednego z zaszyfrowanych ciągów:
decryption_routine_call
Wywołanie funkcji deszyfrującej. Oczywiście argumenty, są przekazywane zgodnie z konwencja __fastcall typową dla Borlanda.

[=]Analiza[=]
Procka deszyfrująca przedstawia się następująco:
decryption_routine
gdzie:
ESI – długość zaszyfrowanego ciągu
Local.1 – pointer na zaszyfrowany ciąg

Jak widać procka jest o wiele pokaźniejsza od tych, które mogliśmy obserwować w poprzednim malware’e.
[=]Deszyfrowanie[=]
Bez większe zastanawiania się tworzymy decryptor, który w pythonie przedstawia się następująco:

import sys
#Delephant decryption script

ascii_table = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz+/"

def decrypt(encrypted):
    decrypted = []
    local_4 = 0
    edi     = 0
    for index in range(0,len(encrypted)):
        pos = ascii_table.find(encrypted[index])
        if pos < 0:
            return "Encrypted string is in unproper format"
        pos = pos + (local_4 << 6)
        local_4 = pos
        edi = edi + 6
        if edi < 8:
            continue
        edi = edi - 8
        local_4 = local_4 % ( 1 <> (edi & 0xff) ) & 0x800000ff
        if pos < 0:
            pos = ( (pos - 1) & 0xffffff00 ) + 1
        decrypted.append( chr(pos) )
    return "".join(decrypted)

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print "Usage: %s encrypted_string" % sys.argv[0]
        sys.exit(0)
    print decrypt(sys.argv[1])

Rezultat deszyfrowania losowo wybranych stringów:
result_of_decryption

Warto tutaj zauważyć jedną znacząco różnice:

MOV EAX,[Local.5] ; kolejny znak z zaszyfrowanego ciagu
MOV EDX,zloavgtr.00480BAC ; ASCI „0123456789ABCD….”
CALL StrPos
MOV EBX,EAX
DEC EBX

i odpowiednik tego kodu w Python’e:

pos = ascii_table.find(encrypted[index])

Trzeba być tutaj świadomym jednej rzeczy, a mianowicie tego ze StrPos Borlandowy indexuje pozycje znaków w stringu od 1 a find Pythonowy od 0. Dlatego też w kodzie pythona nie pojawia się dekrementacja wartości pozycji znaku do odszyfrowania.

[=]Epilog[=]
Jak można zauważyć, procedura deszyfrująca tego trojana jest objętościowa ok.3 razy większa od tych, z którymi mieliśmy do czynienie w poprzednim sampel’u co jednak nie przeszkodziło nam w stworzeniu python’ego decryptor’a.
Jeżeli chodzi o algorytmy wykorzystywanego przez ten malware’u do „szyfrowania„ skradzionych danych to są to przeważnie:
- URL Encode
- Base64

ze względu na powszechność nie zostały one tutaj opisane.

Na sam koniec dla ciekawych, chcących przeanalizować krok po kroku działanie decryptor’a pare stringów do deszyfracji:

“IKLuS6nlScK”
“IMvcRt9jOUVZRo1fRcDlSd9bT64X851oPMLkOsXX86DlSd9bT65jPMvqPI1l86DXRN1l84HfPsbqRou”
“H65aRtCWIMvZRt9oPNHlSomWK6zo86PXTczo86HfPsbqPI1kRtPXRMLkT6Kk”
“K6zo86PXTczoB21fRcPlScrb86baPMvqQMPfOs7dusyi865dPMvZQM4i86DlRdHX”
“Kt8eOIak84PXTczo86HfPsbqON8WOI1pTM4WSsLkQ64WP64WT65YPMnX86DlSd9bT65jPMvqPIu”
“LNDruN9fRoukBYukBYukBYukBZe”
“K6zo86rlT6bsRo1aPI1JPMTrSc5kvs4WSsLr84D1KbJ3Jo14HI1JHKTLKa5Enq4WP6LsPI1pPN8WKcLZOMHXStHoOMHlB21JRsnfOsbqOMrlSo1nTMKWLczZwY18OM9fR6bqPI1pPNKWGs5oTEDl86Hb85DbPtLoOMxdOI1ERtPXRMLkT6Kk”
“Gc5kOsyWINHX+Y0j84PbQNHl851XSc4WLczZwY0WBI1DQMDoRtDlPdGWIMvqPN9kPNGWHNXmR6zoPN8″

Reversowanie trojanów pisanych w Delphi/BCB.

August 7th, 2009 Icewall No comments

Jako, że kolejny post z cyklu „Algorytmy (de)szyfrowania wykorzystywane przez twórców trojanów bankowych” , który mam w planach napisać, będzie o algorytmach szyfrowania wykorzystanych w trojanach napisanych w Delphi :D (tak tak, poczekajcie jeszcze pare lat i będzie wysyp trojanów pisanych w .NET… using System.malwares.bankers; i go go go !!! :D ) , to postanowiłem wcześniej napisać co nie co o moim ogólnym podejściu do trojanów pisanych w tym właśnie języku oraz narzędzi ułatwiających ich analizę.

Nasz dzisiejszy „bohater” przedstawia się następująco:
[=]Dane[=]

Antywirus	Wersja	Ostatnia aktualizacja	Wynik
a-squared	4.5.0.24	2009.08.02	Trojan-Banker.Win32.Banker!IK
AhnLab-V3	5.0.0.2	2009.08.01	Win-Trojan/Banker.7315456.D
AntiVir	7.9.0.238	2009.08.02	TR/Agent.GGO.1
Antiy-AVL	2.0.3.7	2009.07.31	-
Authentium	5.1.2.4	2009.08.02	W32/Trojan.BZCX
Avast	4.8.1335.0	2009.08.01	Win32:Banker-CXH
AVG	8.5.0.406	2009.08.02	PSW.Banker4.AJJ
BitDefender	7.2	2009.08.02	Generic.Spy.Bank.ZWQ.720719B9
CAT-QuickHeal	10.00	2009.07.30	-
ClamAV	0.94.1	2009.08.02	-
Comodo	1840	2009.08.02	TrojWare.Win32.Spy.Banker.OHT
DrWeb	5.0.0.12182	2009.08.02	Trojan.PWS.Banker.12795
eSafe	7.0.17.0	2009.07.30	Win32.Banker.cwo
eTrust-Vet	31.6.6650	2009.08.01	-
F-Prot	4.4.4.56	2009.08.02	W32/Trojan.BZCX
F-Secure	8.0.14470.0	2009.08.01	Trojan-Banker.Win32.Banker.fgw
Fortinet	3.120.0.0	2009.08.02	Spy/Banker
GData	19	2009.08.02	Generic.Spy.Bank.ZWQ.720719B9
Ikarus	T3.1.1.64.0	2009.08.02	Trojan-Banker.Win32.Banker
Jiangmin	11.0.800	2009.08.02	-
K7AntiVirus	7.10.808	2009.08.01	-
Kaspersky	7.0.0.125	2009.08.02	Trojan-Banker.Win32.Banker.fgw
McAfee	5695	2009.08.01	PWS-Banker.gen.cb
McAfee+Artemis	5695	2009.08.01	PWS-Banker.gen.cb
McAfee-GW-Edition	6.8.5	2009.08.02	Heuristic.BehavesLike.Win32.Spyware.K
Microsoft	1.4903	2009.08.02	TrojanSpy:Win32/Banker.USW
NOD32	4299	2009.08.02	Win32/Spy.Banker.OHJ
Norman	6.01.09	2009.07.31	W32/Banker.BQZT
nProtect	2009.1.8.0	2009.08.02	-
Panda	10.0.0.14	2009.08.02	Trj/Banker.gen
PCTools	4.4.2.0	2009.08.02	TrojanSpy.Banker.ARXE
Rising	21.40.62.00	2009.08.02	Trojan.Spy.Win32.Banker.c
Sophos	4.44.0	2009.08.02	Mal/DelpBanc-A
Sunbelt	3.2.1858.2	2009.08.02	Bulk Trojan
Symantec	1.4.4.12	2009.08.02	Infostealer.Bancos
TheHacker	6.3.4.3.375	2009.08.01	Trojan/Spy.Banker.cwo
TrendMicro	8.950.0.1094	2009.07.31	-
VBA32	3.12.10.9	2009.08.02	Trojan-Spy.Win32.Banker.cwo
ViRobot	2009.7.31.1863	2009.07.31	-
VirusBuster	4.6.5.0	2009.08.02	TrojanSpy.Banker.ARXE

Dodatkowe informacje
File size: 7319552 bytes
MD5   : d9e6a8e34c8c6f33919c33889c23811c
SHA1  : 38bb2fbb82e419d044a2a9e9199eb948eb891679
SHA256: 9fe271dbe89dd60d072789f49197d217edf75d9ed5a46fc5e94e28c7522341d8
TrID  : File type identification65.9% (.EXE) InstallShield setup (43065/22/16)13.0% (.EXE) Win32 Executable Generic (8527/13/3)11.6% (.DLL) Win32 Dynamic Link Library (generic) (7583/30/2)3.1% (.EXE) Win16/32 Executable Delphi generic (2072/23)
3.0% (.EXE) Generic Win/DOS Executable (2002/3)
ssdeep: 98304:aVwdUDdAVtUSlUTE2PIEH4B4Yo1qIZtDxHw7SbrKD:anAUkQPIYA49m
PEiD  : -
RDS   : NSRL Reference Data Set

Ja kto przeważnie bywa sygnaturki, są bardzo ooooooogggggólne. Jeżeli nawet, któraś z nich wskazuje na jakiś bardziej konkretny typ trojana to analiza techniczna bardzoooooo mija się z rzeczywistością, weźmy chociażby :
Symantec – Infostealer.Bancos
Morał jest taki, że ludki pracujące nad tego typu malware’em, a m.in. są to osoby z brazylijskich slumsów oraz innych biednych krajów A.Pd, (polecam tutaj wystąpienie
Mikko Hypponen : Online Crime and Crime Online
) nie robią sobie urlopów :D .

[=]Prolog[=]
Jeżeli kiedykolwiek zdarzyło Ci się pisać w BCB/Delphi aplikację z GUI (bo na takich będziemy się skupiać) to możesz podejrzewać, a jeżeli już je reversowałeś to jesteś świadom, że narzut kodu wygenerowanego przez kompilator, który nie specjalnie nas interesuje jest dość spory. Dodatkowo mamy tu do czynienia z budową silnie obiektową (masa metod wirtualnych, delegaty [tak tak, borland dostarcza do tego celu specyfikatora „__closure”],wielodziedziczenie,itp.) przez co nasza analiza jest nieco „utrudniona”(interpretuj. utrudniać: wydłużać czas zabawy :D ). Dlatego też, pokarze parę narzędzi oraz plugin’ów do nich, które przyspieszą samą analizę kodu jak i pomogą nam na znalezienie tych fragmentów, które zastały napisane przez autora trojana.

[=]Analiza[=]
Na początku naszej analizy zastanówmy się jakie akcje są przeważnie wykonywane podczas początkowego uruchomienia trojana. Z mojego doświadczenia wynika, że są to przeważnie następujące działania :
- kopiowanie własnej instancji do katalogu systemowego
- dodanie wpisu w rejestrze pozwalającego na auto uruchomienie trojana po reboot’e systemu
- rejestracja zainfekowanej maszyny

Ok, na początek tyle ustaleń nam wystarczy teraz pojawia się kwestia jak zlokalizować ten kod?
Oczywiście niektórzy z was mogli pomyśle, od razu o rozwiązaniu w stylu ustawianiu BP na api, które w jakiś sposób są powiązane z wyżej wymienionymi akcjami. Jest to na pewno jakiś sposób, ale w przypadku aplikacji Borlandowskich warto użyć paru dodatkowych narzędzi poza disassambler’em i debugger’em żeby osiągnąć naprawdę interesujące rezultaty, ale o tym za chwilę. Obejrzyjmy wstępnie kod trojana:
ida_wstepny_kod
Na chwilę obecną powyższy kod nie daje nam zbyt wiele informacji, widać „rzetelne sprawdzanie błędów” :D , tworzenie mutex’a i wywołanie paru metod na globalnym obiekcie off_500864.Pierwszą rzeczą, która z pewnością ułatwi nam dalsze analizowanie kodu są FLIRT’y(więcej informacji TU), które dostarcza nam IDA Pro w wersji komercyjnej. Trudno mi powiedzieć jak wygląda kwestia z wersją Free, niestety nie testowałem, także jeżeli ktoś z was będzie testował lub już to zrobił to dajcie znać ;) . Załadujmy odpowiednie FLIRT’y i rzućmy okiem na kod po tym zabiegu:
flirts
code_after_flirts_load
Ahhh….na mój gust kod wygląda już znacznie lepiej ;) .
Jak widać IDA zastąpiła większość wywołań VCL’owych metod sygnaturami przez co kod jest znacznie czytelniejszy. Warto jeszcze tutaj zastosować tryb:
Options->Demangled names
I przy wyborze „Show demangled C++ names as” zaznaczyć radio box „Names” czego rezultatem będzie poniższy wynik:

code_after_flirts_load_comments_as_FunName
Wracając do kodu, osoby, które miały styczność czy to z BCB czy Delphi już na pewno rozpoznają ten fragment.Tak tak jest to standardowy kod, którego główny cel możemy określić na:
- automatyczne tworzenie form używanych w projekcie
oraz obsługę komunikatów do nich napływających.

Porównamy teraz kod z pod IDA’y z kodem jednej z moich aplikacji pisanych w RAD Studio 2007( dawne wersje nazywane były Borland C++ Builder):
code_from_RAD
Tak jak widać kod jest uderzająco podobny, z czego morał taki, że dzięki IDA’e i sygnaturką zaoszczędziliśmy czas na analizowaniu standardowych VCL’owych metod.

Ok, wszystko fajnie, ale dalej nie mamy żadnych szczegółów związanych z naszymi wcześniejszymi ustaleniami. Po listingu z IDA’y możemy stwierdzić, że przy uruchomieniu trojana tworzone są automatycznie 3 formy, co wiąże się z wywołaniem pewnych zdarzeń. Zanim jednak omówimy sobie te zdarzenia przyjrzyjmy się wszystkim formą. Do tego celu oczywiście posłużymy się resource editor’em. Wyróżnie tutaj dwa:

Komercyjny:
PE Explorer: genialny edytor zasobów i nie tylko. Umożliwia podgląd form znajdujących się w zasobach, komponentów znajdujących się na nich (Timerów,Buttonów,Obrazów,…) oraz ich właściwości.

Darmowy:
DFM Editor: autorstwa MiTeC’ka jest darmowym prawie że odpowiednikiem PE Explorer’a, jeżeli chodzi o samo edytowanie zasobów. Jedynym mankamentem tego narzędzia jest brak możliwości podglądu obrazków znajdujących się na formach co w przypadku identyfikacji przeznaczenia formy(np. dzięki umieszczonym bannerą czy imitacją form przeznaczonych do logowania, możemy określić jakich banków klienci są narażeni na atak przez danego trojana już po samym analizowaniu zasobów) jest bardzo użyteczne.
W naszych badaniach identyfikacja przeznaczania danej formy pod kątem konkretnego banku jest zbyteczna ( a nawet z paru względów zabroniona :P ). Rzućmy okiem do zasobów:
resource_preview
(Niektóre nazwy form były zbyt oczywistymi skrótami nazw banków przez co musiałem je troszeczkę ocenzurować.)

Jak widzimy trojan ten posiada sporą dawkę fałszywych form imitujących panel’e do logowania, wirtualne klawiatury, a skończywszy na oknach prezentujących imitacje crash’u IE czy nawet BSOD’a :D .
Jest jednak parę form. :
TAup – Application update?
TCMD – Commands ?
TFUNC – Functions ?

które nie posiadają charakterystycznych Bitmap, lecz np. komponenty takie jak :
TTimer
TIdSMTP
TIdMessage

i tym formą się przyjrzymy.
Przeglądając komponenty znajdujące się na wyżej wymienionych formach szybko dochodzimy do wniosku, że tak naprawdę tylko TCMD jest formą, która może nas zainteresować, ponieważ:
TAup – co prawda posiada komponent TTimer lecz nie ma on podczepionego event handler’a.
aup
Czyżby autor trojana doznał chwilowego przebłysku oraz chęci dodania kolejnej funkcjonalności po czym, po krótkie chwili porzucił tą idee, oraz wszelkie elementy z nią związane? Tego się nigdy nie dowiemy.

TFUNC – ta forma jest kompletnie pusta.
Nie mogę tego inaczej skomentować niż jako wyjątkowego przejawu nonszalancji :D .

func
TCMD
Rzućmy okiem na najbardziej interesujące nas komponenty oraz ich własności:

object CMD: TCMD
  OnActivate = FormActivate
  OnCreate = FormCreate
  object TPrincipal: TTimer
    OnTimer = TPrincipalTimer
    Left = 8
  end
  object Tcook: TTimer
    Interval = 100
    OnTimer = TcookTimer
    Left = 40
  end
  object Tsite: TTimer
    Enabled = False
    Interval = 50
    OnTimer = TsiteTimer
    Left = 72
  end
  object Tjanela: TTimer ;
            nie wierzcie, że event handler jest ustawiany dynamicznie:P
	To raczej kolejny przejaw wrodzonej rozrzutności autora malware’u.
    Left = 104
  end
  object Taup: TTimer
    Enabled = False
    Interval = 720000
    OnTimer = TaupTimer
    Left = 136
  end
end

resource_preview_TCMD
Jak widać forma ta posiada obsłużone dwa zdarzenia:

  OnActivate = FormActivate
  OnCreate   = FormCreate

Oba, są idealne do tego żeby podpiąć w ich obsłudze wszystkie 3 wymienione przeze mnie początkowe działania wykonywane przez większość trojanów.
W pozostałych event handler’ach:

TaupTimer
TsiteTimer
TcookTimer
TPrincipalTimer

związanych z eventem OnTimer:
można się raczej spodziewać akcji takich jak:
- aktualizacji trojana
- wysyłania skradzionych danych do twórcy malware’u
- monitorowania aktualnych procesów w systemie (i cykliczne ubijanie np. firewall’a)
czy monitorowania odwiedzanych stron.

Ok., mamy więc ustalone parę procek, których kod chcielibyśmy prześledzić. Nasuwa się pytanie:
W jaki sposób uzyskać ich VirtualAddress?
Odpowiedzią jest:
DeDe
Wszystkie informacje o DeDe jak i sam tool znajdziecie tutaj RCE Tools.

Ładujemy naszego trojana w DeDe i po parunastu sekundach otrzymujemy taki o to rezultat:
_preview_into_dede
Wspaniale! Jak możemy zaobserwować na powyższym screen’e DeDe dostarczyło nam informacji o zdeklarowanych przez użytkownika klasach (np. TCMD), Event handler’ach oraz miejscach ich lokalizacji!
Podsumowując uzyskane informacje mamy:

OnTime:

TaupTimer         = 004FD5C8
TsiteTimer          = 004FD0A0
TcookTimer 	      = 004FC834
TPrincipalTimer = 004FACE4

oraz eventy związane bezpośrednio z formą:

OnActivate = FormActivate =  004F7C44
OnCreate   = FormCreate    =  004FAC44

Oczywiście teraz nasza analiza staje się o wiele wiele prostsza, ponieważ bezpośrednio możemy zająć się interesującymi nas fragmentami kodu bez przedzierania się przez standardowe procedury.
Dla potwierdzenia wcześniejszych założeń związanych z operacjami wykonywanymi na starcie przez trojana, rzućmy okien na kod wykonywany przy event’e OnCreate, czyli:
FormCreate @ 004FAC44:
oncreate
Mhmm sporo call’i, których IDA nie rozpoznała jako standardowych wywołań, więc najprawdopodobniej, są to pomocnicze metody napisane przez „programistę”. Zanim jednak przejdziemy do ich przeglądania, skorzystamy ponownie z dobrodziejstwa informacji dostarczanych przez DeDe, a mowa tutaj dokładnie o pliku MAP.
map_export
Dzięki wyexportowaniu informacji takich jak:

- event handlers
- control references

do pliku map
map_file_preview
oraz załadowaniu go do IDA’y: (polecam plugin Fast IDB2Sig and LoadMap) disassemblowany przez nas kod staje się ponownie jeszcze bardziej czytelny:
oncreate_with_map
To co najbardziej rzuca się w oczy to fakt zamiany nazwy call’a i jego komentarza z :

loc_4FACBD:
mov     dl, 1
mov     eax, [ebx+318h] ;
call    unknown_libname_172 ; Delphi2006/BDS2006 Visual Component Librar

na

loc_4FACBD:
mov     dl, 1
mov     eax, [ebx+318h] ; Taup:N.A.
call    SetEnabled      ; ExtCtrls.TTimer.SetEnabled(TTimer;Boolean)

odrazu widać, że jest to fragment kodu aktywujący Timer : Taup.
Ok, przyjrzyjmy się którejś z metod, której sposób działania jest nam jeszcze nie znany. Sprawdźmy jako pierwszą :
sub_483BE8
add_to_registry
Ahh jak widać metoda ta wykonuje operacje na rejestrze, a po głębszej analizie okazuje się, że dodaje ona do klucza :
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
wartość : Windows32 zawierającą scieżkę do kopi trojana, czyli
sub_483BE8 możemy zaklasyfikować jako :
- dodanie wpisu w rejestrze pozwalającego na auto uruchomienie trojana po reboot’e systemu

Super!!! jedno z założeń odnalezione. Idźmy dalej:
sub_483D78:
instation_copy

Jak widać w najwyżej położonym bloku widocznym na screen’e, zostaje sprawdzona wersja systemu operacyjnego ( Windows XP/NT/98 itd.) i na tej podstawie podejmowane, są działanie takie jak:
deskrypcja stringu
pobranie parametru wywołania aplikacji
oraz wykonanie kopi pliku gdzie parametrami, są rezultaty operacji dwóch poprzednich funkcji
…czy coś wam to mówi :D ?,,,,,a teraz
CopyFile(ParamStr(),Decrypt()) :D ?
Tak jest! Oczywiście widać tutaj bloki instrukcji odpowiedzialnych za kopiowanie instancji trojana do charakterystycznych katalogów uzależnionych od wersji systemu Windows.
sub_483D78
- kopiowanie własnej instancji do katalogu systemowego

Na tym poprzestaniemy nasze dalsze dochodzenie, bo nie dokładna analiza techniczna była naszym celem, a jedynie przekonanie się o tym jaki potencjał niesie zastosowanie :
- sygnatur IDA’y
- informacji o adresach metod/obiektów uzyskanych dzięki DeDe
oraz pliku MAP

A co z naszym ulubionym Olkiem :D ? Czyż nie było by miło prowadzić dynamicznej analizy kodu mając do dyspozycji możliwości Olka ,sygnaturki IDA’y i możliwość załadowania pliku MAP ? Oczywiście byłoby, a najlepsze w tym jest to, że da się to osiągnąć!

[=]Olly’s time[=]
Żeby osiągnąć powyższe możliwości wystarczy tak naprawdę jeden plugin:
GoDup

GoDup_preview
Żeby dostrzec różnice po zastosowaniu kolejnych zabiegów w wykonaniu tego pluginu, ustawmy się na kod handler’a TPricipalTimer @ 004FACE4:
pure_olly_code
po zastosowaniu sygnatur:
sig_olly_code
dorzućmy jeszcze informacje z pliku MAP:
map_olly_code

Czyż kod nie wygląda piękniej? :D .