An article or post

Longhorn Beta 3 i nowe syscalle

czerwiec 21st, 2007

Hi =^^=

W ramach chwili wolnego czasu rzuciłem okiem na syscalle udostępnione przez kernel Windows Longhorn’a i porównałem z tymi z Windows Vista. Może nie jest to najszczęśliwsze zestawienie, jako że Windows Vista, w przeciwieństwie do Longhorna czy np 2003, nie jest Windowsem serwerowym, ale chodziło mi bardziej o chronologiczne porównanie.

Anyway, poniżej znajdują się lista syscalli które są w Longhornie,  a nie ma ich w Vista.

NtAlpcAcceptConnectPort
NtAlpcCancelMessage
NtAlpcConnectPort
NtAlpcCreatePort
NtAlpcCreatePortSection
NtAlpcCreateResourceReserve
NtAlpcCreateSectionView
NtAlpcCreateSecurityContext
NtAlpcDeletePortSection
NtAlpcDeleteResourceReserve
NtAlpcDeleteSectionView
NtAlpcDeleteSecurityContext
NtAlpcDisconnectPort
NtAlpcImpersonateClientOfPort
NtAlpcOpenSenderProcess
NtAlpcOpenSenderThread
NtAlpcQueryInformation
NtAlpcQueryInformationMessage
NtAlpcRevokeSecurityContext
NtAlpcSendWaitReceivePort
NtAlpcSetInformation
xHalLoadMicrocode - Ciekaaawy import ;>
NtCreateKeyTransacted
NtCreatePrivateNamespace
NtCreateTransaction
NtOpenTransaction
NtQueryInformationTransaction
NtQueryInformationTransactionManager
NtPrePrepareEnlistment
NtPrepareEnlistment
NtCommitEnlistment
NtReadOnlyEnlistment
NtRollbackComplete
NtRollbackEnlistment
NtCommitTransaction
NtRollbackTransaction
NtPrePrepareComplete
NtPrepareComplete
NtCommitComplete
NtSinglePhaseReject
NtSetInformationTransaction
NtSetInformationTransactionManager
NtSetInformationResourceManager
NtCreateTransactionManager
NtOpenTransactionManager
NtRenameTransactionManager
NtRollforwardTransactionManager
NtRecoverEnlistment
NtRecoverResourceManager
NtRecoverTransactionManager
NtCreateResourceManager
NtOpenResourceManager
NtGetNotificationResourceManager
NtQueryInformationResourceManager
NtCreateEnlistment
NtOpenEnlistment
NtSetInformationEnlistment
NtQueryInformationEnlistment
NtDeletePrivateNamespace
NtEnumerateTransactionObject
NtFlushProcessWriteBuffers
NtFreezeRegistry - Huh ?
NtFreezeTransactions
NtGetNlsSectionPtr
NtInitializeNlsFiles
NtOpenKeyTransacted
NtOpenPrivateNamespace
NtOpenSession
NtReplacePartitionUnit
NtSetDriverEntryOrder
NtSetSystemEnvironmentValueEx
NtThawRegistry
NtThawTransactions
NtTraceControl
NtGetNextProcess - Czyżby jakieś nowe api do enumeracji procesów i threadów?
NtGetNextThread
NtCancelIoFileEx
NtCancelSynchronousIoFile
NtRemoveIoCompletionEx
NtRegisterProtocolAddressInformation
NtPropagationComplete
CcTestControl - Cc ? Nie Nt ?
NtCreateWorkerFactory
NtReleaseWorkerFactoryWorker
NtWaitForWorkViaWorkerFactory
NtSetInformationWorkerFactory
NtQueryInformationWorkerFactory
NtWorkerFactoryWorkerReady
NtShutdownWorkerFactory
NtCreateThreadEx
NtCreateUserProcess
NtQueryLicenseValue
NtMapCMFModule
NtIsUILanguageComitted
NtFlushInstallUILanguage
NtGetMUIRegistryInfo
NtAcquireCMFViewOwnership
NtReleaseCMFViewOwnership

Niektóre trzeba przyznać są interesujące nawet z nazwy. No nic ;> To tyle na dzisiaj, analizę nowych syscalli zostawiam na kiedyś ;>

G.C.

An article or post

Exporty z kernela a syscalle

czerwiec 19th, 2007

Hi =^^=

Pisze od kilku dni pewien driver pod Windows’a XP który, między innymi,  podmienia wybrane syscall’e na moje funkcje.  Szczerze mówiąc nigdy nie podobała mi się metoda lokalizacji określonego syscalla, np NtCreateFile, po jego numerze, jako że to zmienia się między różnymi wersjami Windowsa, a nawet w niektórych przypadkach między Service Packami (np. NtCreateFile na Windows NT miało numer 0×17, na Windows 2000 0×20, na XP 0×25, na 2003 0×27 a na Vista 0×3b). W związku z tym stwierdziłem że zrobię to następującą metodą:

1. Funkcja podmieniająca dostanie nazwę syscalla, np NtCreateFile
2. Za pomocą MmGetSystemRoutineAddress zostanie pobrany exportowy adres NtCreateFile
3. W tablicy syscalli (zlokalizowanej za pomocą KeServiceDescriptorTable[0].Base (z zastosowaniem MDL oczywiście ;>)) znajdzie się adres NtCreateFile otrzymując w ten sposób numer syscalla
4. Mając pozycje w tablicy syscalli można podmienić adres na własną funkcję

Metoda imho fajna, ładnie działała przy testach dla NtCreateFile i NtOpenFile.

Ale zaczęły się schody ;p Mianowicie okazało się że nie wszystkie syscalle są exportowane z kernela (tj ntoskrnl.exe). Nie ma na przykład NtCreateKey czy NtOpenKey.  Cóż. I cały misterny plan szlak trafił ;>

Musiałem się niestety zadowolić wykrywaniem wersji Windowsa i statyczną tablicą translacji nazwy syscalla na jego numer. Sic.

Swoją drogą ciekawe czemu nie wszystkie syscalle są exportowane…

Co do zmian w numeracji syscalli, wynikały one zawsze z tego iż syscalle są numerowane wg. ich kolejności alfabetycznej. Ale okazuje się że i od tego są wyjątki. Przykładowo 6 ostatnich syscalli z XP SP 2 to:

NtYieldExecution
NtCreateKeyedEvent
NtOpenKeyedEvent
NtReleaseKeyedEvent
NtWaitForKeyedEvent
NtQueryPortInformationProcess

Przy czym NtYieldExecution jest ostatnim alfabetycznie ułożonym syscallem. Cieeekawee ;>

Chwilowo tyle, może jeszcze dzisiaj coś napiszę ;>
G.C.

An article or post

Searching… seek and scan ;>

czerwiec 17th, 2007

Hi =^^=

Jakiś czas temu, a konkretniej 24 kwietnia 2007, na swoim prywatnym blogu stworzyłem podstronę zawierającą tylko i wyłącznie jeden adres e-mail, celem sprawdzenia kilku rzeczy takich jak:

  1. Kto skanuje internet (a konkretniej mój blog)
  2. Jak szybko spamboty dorwą mój e-mail
  3. Oraz kiedy dojdzie pierwszy spam na mój testowy e-mail

Po blisko dwóch miesiącach wyniki obserwacji owej podstrony są następujące:

  • 26 kwietnia o godzinie 2:59 podstroną zainteresował się bot Google (Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) który przybył z crawl-66-249-66-143.googlebot.com
  • Dwa dni później, 28 kwietnia 40 minut po północy przybył kolejny bot, tym razem był to (Sherlock?) Holmes, (holmes/3.10.1 (OnetSzukaj/5.0; +http://szukaj.onet.pl)) przybyły z Onetu, a konkretniej spider8.szukaj.onet.pl
  • 4 maja inny Googlebot odwiedził moją podstronkę, tym razem przybył z adresu crawl-66-249-66-168.googlebot.com
  • 9 maja odwiedził mnie pierwszy spam harvester (wg. projecthoneypot.org), czyli ISC Systems iRc Search 2.1 przybyły z 195.red-82-158-204.user.auna.net
  • 16 maja przybył kolejny taki sam spam harverster, tym z e99243.upc-e.chello.nl
  • godzinę później przybył kolejny harvester i to z podobnego adresu, d215090.upc-d.chello.nl
  • 19 maja odwiedził mnie ponownie Googlebot, z crawl-66-249-70-194.googlebot.com
  • Również 19 maja w godzinach wieczornych zainteresował się podstroną szperacz z Yahoo! (Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)) który przybył z lj611481.crawl.yahoo.net
  • 27 maja o godzinie 14:36 przeskanował mnie jakiś Wells Search II z IP 194.178.109.250
  • Również 27 maja, o godzinie 15:42 doszedł na adres testowy pierwszy spam. Spam został wysłany o 15:41 z SMTP smtp-pim.libero.it z (wg nagłówka) IP 194.178.109.250 przez (wg emaila) calllucky@libero.it
  • 29 maja zainteresowała się moją podstronką wyszukiwarka Microsoftu (msnbot-media/1.0 (+http://search.msn.com/msnbot.htm)) z adresu livebot-65-55-213-12.search.live.com
  • 5 czerwca na stronkę powrócił ISC Systems iRc Search 2.1 z 213.185.118.203
  • 9 czerwca przeskanował mnie ponownie Onetowy holmes, tym razem z hosta spider7.szukaj.onet.pl
  • 12 czerwca znowu Googlebot się pojawił, tym razem z crawl-66-249-73-251.googlebot.com
  • 13 czerwca pojawił się jakiś nowy bot (IRLbot/3.0 (compatible; MSIE 6.0; http://irl.cs.tamu.edu/crawler)) z hosta crawler4.irl.cs.tamu.edu (jakiś program badawczy uniwerku ?)
  • póki co tyle

Wnioski są następujące. Google ma dużo botów i często skanuje. Równie często ISC System iRc Search przychodzi i harvestuje =^^=. Onet skanuje raz na półtorej miesiąca, Microsoft i Yahoo! trochę rzadziej najwyraźniej. Istnieją widać boty które wysyłają spam jak tylko znają jakiegoś e-maila (noo z godzinnym opóźnieniem). Ostatnim wniosek brzmi: po miesiącu od umieszczenia e-maila dostanie się jakiś spam. Cóż. Niech żyją dobre filtry antyspamowe =^^=.

Dodam jeszcze że póki co, oprócz tego jednego spammaila, nie żadnych innych. Ciekawe co czas przyniesie =^^=.

G.C.

An article or post

Prolog i epilog kompilatora MinGW GCC/G++

czerwiec 17th, 2007

Hi =^^=

Czy zastanawialiście się kiedyś czemu prosty Hello World skompilowany MinGW GCC do exeka zajmuje 15kb (po strip 5kb), a do obiektu (COFF .o) 0.5kb ? Co takiego kompilator dodaje że 0.5kb rośnie do 15kb/5kb ? Oczywiście prolog (kod wykonywany przed “main”) oraz epilog (kod wykonywany po “main”). Dzisiejszy post poświęcę temu co prolog i epilog MinGW GCC robi ;>

Załóżmy że analizujemy proste tekstowe Hello World skompilowane MinGW GCC w wersji 3.4.5. EntryPoint exeka pokazuje na krótką funkcję:

push ebp
mov ebp, esp
sub esp, 8
mov [esp+8+var_8], 1
call ds:__set_app_type
call ___mingw_CRTStartup
nop
lea esi, [esi+0]

Pierwsze trzy linie (push ebp … sub esp, 8 ) to oczywiście standardowe stworzenie ramki stos. Następnie wywoływana jest funkcja __set_app_type(1). Funkcja ta znajduje się w msvcrt.dll i służy do zaznaczenia czy mamy do czynienia z programem konsolowym (1) czy okienkowym (2) (technicznie rzecz biorąc parametr funkcji jest zapisywana w globalnej zmiennej biblioteki msvcrt.dll). Z tej informacji korzysta później na przykład funkcja assert która, w zależności od tego czy jest to program konsolowy czy okienkowy, wyświetla wiadomość o błędnej assertacji na konsoli lub w okienku (jako zadanie domowe proponuje zrobić konsolowy program z błędem assertacji i zmienić w exeku __set_app_type(1) na __set_app_type(2) ;>). Potem następuje wywołanie ___mingw_CRTStartup. Reszta kodu w tej funkcji jest nieistotna ponieważ ___mingw_CRTStartup nigdy nie powraca.

Co ciekawe zaraz po tej funkcji wejściowej jest identyczna wersja, z tą tylko różnicą że wywołana jest __set_app_type(2). Cóż, dziwne że kompilator nie mógł tego kawałka kodu pominąć, w końcu i tak nie jest on używany.

Funckja ___mingw_CRTStartup zaczyna od ustawienia funkcji obsługi wyjątków (funkcja tłumaczy exception z terminologii Windowsa na terminologie używaną w obsłudzę wyjątków w języku C, po czym wywołuje funkcję signal) za pomocą oficjalnego API SetUnhandledExceptionFilter. Potem resetowany jest FPU (poprzez wywołania krótkiej funkcyjki z FINIT w środku), a potem następuje odwołanie do funkcji __getmainargs (z msvcrt.dll) celem pobrania przetworzonej linii polecen i zmiennych środowiskowych (czyli argc, argv i envp). Potem, w zależności od potrzeby, ustawiany jest tryb writeonly (O_WRONLY | SH_COMPAT0) na stdin oraz readonly (O_RDONLY | SH_COMPAT0) na stdout i stderr (za pomocą _set_mode z msvcrt.dll).

Dalej za pomocą funkcji __p__fmode (z msvcrt.dll) pobierany jest pointer na zmienną globalną (ulokowaną w msvcrt.dll) __fmode (defaultowy tryb operacji na plikach), do której przypisywana jest wartość 4000h (_O_BINARY). Następnie odpalany jest __pei386_runtime_relocator który jest krótką funkcją odpowiedzialną za, jak nazwa wskazuje, dokonanie pewnych relokacji. W przypadku Hello World żadnych relokacji jednak nie ma. Następnie za pomocą funkcji __p__environ (msvcrt.dll ponownie) uzyskiwany jest pointer na tablice pointerów do zmiennych środowiskowych (envp), ustawiane są wcześniej ustalone argumenty funkcji main, po czym następuje (wreszcie) skok do właściwej funkcji main().

Funkcja main() w przypadku MinGW GCC posiada jednak również pewien prolog wykonywany przed właściwym (stworzonym przez programiste) kodem main(). Ów prolog składa się z dwóch funkcji. Pierwsza z nich to ___chkstk która jest wywoływana w przypadku alokacji dużych ramek stosu (akurat w tym przypadku ramka stosu ma 16 bajtów, ale nvm) celem sprawdzenia strona po stronie czy pamięć zaalokowana na stos jest faktycznie ciągła. Po co to? Wyobraźmy sobie przeciwny przypadek gdy na adresie 0×7000 mamy jedną stronę zaalokowaną dla sekcji danych (.data) (czyli 0×7000-0×7fff == .data), a na adresie 0×9000-0×9fff mamy jedną stronę na stos. ESP powiedzmy że jest równe 0×9200, i teraz ktoś chce zaalokować na stosie 0×2000 bajtów. Normalnie ramka stosu tworzona jest za pomocą prostego odejmowania, czyli SUB ESP, 0×2000. W typ przypadku po odejmowaniu ESP było by równe 0×7200. Problemy są dwa. Po pierwsze, nie jest to już pamięć stosu (tylko .data), a po drugie, strona pod adresem 0×8000 nie istnieje, więc wszelkie próby odwołania pod adres 0×8000-0×8fff skończą się exceptionem. Taki błąd należał by do trudno wykrywalnych gdyby ramka stosu faktycznie była tak tworzona (dla małych danych umieszczanych na ramce stosu program by mógł działać ok, chyba że by coś nadpisywał w sekcji danych). W związku z czym przy alokacji większej ramki stosu sprawdzane jest (przy pomoc OR DWORD [ADRES_KOLEJNEJ_STRONY], 0) każda kolejna strona która ma się zawierać w ramce stosu.

Następną wywoływaną funkcją (nadal przed kodem właściwym main) jest funkcja która uruchamia wszystkie funkcje initujące z pewnej stałej tablicy funkcji. W przypadku Hello World jedyną funkcją w tej tablicy jest ___sjlj_init_ctor która jest wrapperem na ___do_sjlj_init, która z kolei jest wrapperem na ___w32_sharedptr_initialize (ta funkcja wydaje się ustawiać dwa pointery określane jako SHAREDPTR_TERMINATE oraz SHAREDPTR_UNEXPECTED tak aby wskazywały na funkcję abort).

I wkońcu jest wykonywany kod właściwy funkcji main() ;>

Gdy funkcja main skończy się wywoływać odpalana jest funkcja _cexit (z msvcrt.dll) która dokonuje pewnych deinicjalizacji, a następnie funkcja ExitProcess (kernel32.dll) która kończy działanie programu.

Pytanie brzmi czy wszystko powyższe jest tak na prawde wymagane do uruchomienia naszego programu. W większości przypadków jest. Jednak jeśli stwierdzimy że chcemy nasz program oprzeć o czyste WinAPI, bez żadnych dodatków z libc, to można przekonać kompilator (-nostdlib) żeby jednak pominał wszelkie prologi i epilogi, i wykompilował tylko nasz kod.

K tyle. G.C. ;>

An article or post

Działanie fopen pod WinNT

czerwiec 16th, 2007

Hi =^^=

Dzisiaj co nie co o tym jak działa funkcja fopen pod systemami z rodziny Windows NT (czyli NT, 2000, XP, 2003, Vista oraz Longhorn), a dokładniej, jak realizowane jest działanie tejże funkcji.

W ramach wstępu przypomnę że fopen jest funkcją ze standardowej biblioteki poleceń języka C (w zależności od humoru będę na tą bibliotekę mówić libc (patrz gcc i Linux), clib (patrz Watcom C) bądź crt (C runtime, patrz Windows)) która służy do “otwarcia” pliku do zapisu bądź odczytu. Deklaracja fopen wygląda następująco:

FILE *fopen(const char *filename, const char *options);

Gdzie filename to oczywiście nazwa pliku, a options to tekstowo zapisane opcje otwarcia pliku, takie jak np. “r” (read, odczyt tekstowy), “wb” (write binary, zapis binarny), czy “at” (append text, zapis tekstowy poczynając od końca pliku).

Kompilatory takie jak MinGW GCC czy Microsoft C/C++ Opt. Compiler (to ten kompilator z Microsoft Visual C++) w wygenerowanym exeku importują funkcję fopen z msvcrt.dll (lub nowszej własnej wersji tejże biblioteki).

Biblioteka msvcrt.dll jest systemową biblioteką (tj. znajduje się w spisie systemowych DLLek, więc jest wyszukiwana najpierw w katalogu systemowym) która exportuje większość (wszystkie?) funkcji ze standardowej biblioteki języka C. Dodam że jest to chyba jedyna systemowa biblioteka która exportuje taką ilość funkcji cdecl (stdcall jest standardem w pod WinNT/9x), ale co się dziwić, w końcu to funkcje języka C ;>

Wewnątrz biblioteki msvcrt.dll funkcja fopen jest tylko wrapperem (takim mega najprostszym) na funkcje __fsopen, która z kolei jest wrapperem (tym razem posiadającym również prolog i epilog SEH) wywołującym __openfile. Funkcja __openfile z kolei parsuje tekstowy parametr options po czym wywołuje funkcję __sopen która z kolei wywołuje kolejną wewnętrzną funkcję która finalnie wywołuje funkcję z WinAPI - CreateFileA.

Funkcja CreateFileA zawarta jest w bibliotece kernel32.dll i jest oczywiście funkcją stdcall. Funcjka CreateFileA posiada oczywiście swojego brata bliźniaka CreateFileW (który przyjmuje nazwę pliku w WideChar/Unicode a nie Ansi String), którego wywołuje, dokonując uprzedniej konwersji na WideChar/Unicode (patrz Basep8BitStringToStaticUnicodeString).

Funkcja CreateFileW z kolei konwertuje napis z postaci WCHAR[] na PUNICODE (jest to struktura używana bardzo popularna w kernel-mode WinNT, zawierająca wielkość tablicy WCHAR[], wielkość napisu zawartego w tej tablicy, oraz pointer na tą tablicę), przekształca ścieżkę z zapisu dosowego na zapis NT (np. jeśli byliśmy w katalogu “C:\code” i wykonaliśmy fopen(”ala.txt”, “w”), czyli de facto chcieliśmy utworzyć plik “C:\code\ala.txt”, po konwersji na zapis NT ścieżka ta wyglądać będzie tak: “\??\C:\code\ala.txt”, w tym miejscu następuje również oczywiście rozwinięcie ścieżki z relatywnej do bezwzględnej), po czym wywołuje funkcję NtCreateFile.

Funkcja NtCreateFile znajdująca się w bibliotece ntdll.dll jest wrapperem na odpowiedniego (NtCreateFile) syscall’a (np. 0×25 pod XP SP2). Syscall jest wywoływany zazwyczaj za pomocą polecenie SYSENTER. Na starszych komputerach było to realizowane za pomocą przerwania INT 0×2E (o ile mnie pamięć nie myli).

Od tego momentu sprawa przenosi się to kernel-mode oraz kernela systemu Windows, zawartego w pliku ntoskrnl.exe (lub w przypadku wersji PAE ntkrnlpa.exe). Po SYSENTER wykonanie przenosi się do funckji obsługującej SYSENTER (patrz rejestr MSR SYSENTER_EIP, numer 0×176, oraz rejestry SYSENTER_CS i SYSENTER_ESP (mogłem się w nazwach pomylić, ale jakoś tak one szły ;>)). Funkcja obsługująca wkońcu pobiera adres funkcji o numerze 0×25 (mowa o XP SP2) z tablicy syscalli (patrz export KeServiceDescriptorTable z ntoskrnl) i skacze do niej.

Funkcja NtCreateFile (\base\ntos\io\iomgr\create.c) jest wrapperem (niespodzianka) na IoCreateFile. IoCreateFile (\base\ntos\io\iomgr\iosubs.c) wywołuje finalnie IopCreateFile (ten sam plik) która to z kolei tworzy nowy pakiet (OPEN_PACKET), uzupełnia go danymi, oraz wywołuje funkcję ObOpenObjectByName (\base\ntos\ob\obref.c) której podaje uzupełniony pakiet. Teraz sprawa się troche komplikuje, więc w skrócie: sprawdzane jest czy obiekt można otworzyć (o to odpytywane są kolejne drivery, min. driver systemu plików który komunikuje się z driverem np. dysku twardego), czy są do niego odpowiednie prawa etc. Tworzony jest handle, dodawany do listy handle’i danego procesu, po czym jeśli się wszystko udało, ów handle jest zwracany. Jeśli ktoś jest zainteresowany dokładnym mechanizmem otwierania plików w kernel-mode, polecam lekturę źródeł WRK (Windows Research Kernel).

I w sumie tutaj kończy się historia. Handle jest zwracany do wszystkich poprzenich funkcji, a wkońcu user dostaje FILE*. Przychodzi tutaj taki na chwilę zastanowienia… Biedny procesor musiał przemierzyć całą masę różnych bibliotek / kernel / sterowniki, wykonać kilobajty kodu, i to tylko dlatego że my chcieliśmy utworzyć sobie plik. Yh. Strach się bać ile pracy wymagało by zapisanie czegoś do tego pliku ;>>>

K Tyle ;> G.C.

An article or post

Niejednoznaczność dodawania (?)

czerwiec 15th, 2007

Hi =^^=

Jakiś już dłuższy czas temu pisałem (od zera) kompilatorek języka obiektowego. W pewnym momencie natknąłem się na problem niejednoznaczności w zamianie prostego wyrażenia matematycznego na drzewko, z którego to potem generowany jest odpowiedni kod odpowiedzialny za obliczenia.

Rozważmy proste wyrażenie matematyczne jakim jest A+B+C. To wyrażenie może zostać obliczone w dwojaki sposób. Pierwszym sposobem jest (A+B)+C, a drugim A+(B+C). W skrajnym przypadku identyczny wynik uzyska się obliczając wyrażenie (A+C)+B. Załóżmy teraz że A i B są wyrażone przez zmienną I, a C jest funkcją od I taką że C(I) = –I (gdzie I jest globalną zmienną). Program wykonujący powyższe obliczenia w języku C mógł by wyglądać tak:
int printf(const char*, ...);
int i;
int costam(void) { i--; return i; }
int
main(void)
{
i = 5;
printf("%i\n", i + i + costam());
return 0;
}

Założenie brzmi że powyższy kod generuje różne wyniki, w zależności od użytego kompilatora. Czy tak jest na prawdę? Zrobiłem test na kilku kompilatorach (pomógł mi diabel który przekompilował powyższy kod na jeszcze kilku):

  • gcc 3.X: 14
  • gcc 4.X: 14
  • Intel C++ Compiler: 12
  • Microsoft C/C++ Opt. Compiler: 14
  • Pelles C:12
  • Borland C++: 12

Jak widać kompilatory są rozdarte pomiędzy 12 a 14. Zapewne fakt iż element C jest funkcją również ma wpływ na wynik. A jak wygląda powyższy eksperyment jeśli wziąć pod uwagę inne języki?

  • Perl: 14
  • Python: 14
  • PHP: 14
  • Java: 14
  • Pascal (FPC): 14

Inne języki wydają się być bardziej zgodne w kwestii wyniku ;>

Ja osobiście bardziej przychylam się do odpowiedzi 14 niż 12. IMHO kompilator powinien wykonywać działania w kolejności którą podał programista, a nie próbować to modyfikować. Z drugiej jednak strony programista powinien unikać sytuacji niejednoznacznych, takich jak powyższa. Cóż, co jest oczywiste dla nas, nie zawsze jest oczywiste dla innych =^^=.

K tyle ;>

G.C.

An article or post

Sesje PHP a chmod /tmp

czerwiec 15th, 2007

Hi =^^=

Zawsze byłem zdania że user nie powinien móc przeczytać na serverze więcej niż na prawdę jest to wymagane. Przykładowo moim zdaniem katalog /tmp nie powinien być listowalny dla nikogo oprócz root’a. A teraz mały przykład, z życia wzięty, dlaczego tak uważam ;>

Mechanizm sesji w PHP, służący transferowi pewnych danych między wywołaniami strony przez usera, opiera się o pliki sess_NUMERSESJI które znajdują się defaultowo w katalogu /tmp (jest to zależne od pola session.save_path w php.ini). W takim pliku, tworzonym podczas rozpoczęcia nowej sesji, zachowywana jest zserializowana wartość tablicy $_SESSION. Plik jest tworzony oczywiście z prawami Apache’a, a inne osoby nie mają do niego żadnych praw (600 aka rw——-). Część nazwy pliku którą oznaczyłem NUMERSESJI jest 128 bitową liczbą losową, którą po prostu trudno zgadnąć.

Natomiast problem zgadywania odpada jeśli można listować katalog /tmp. Załóżmy więc że Apache/PHP faktycznie zapisuje pliki sess_NUMERSESJI w katalogu /tmp i /tmp jest listowalny. Wtedy uzyskujemy całą masę aktywnych numerów sesji. No tak, ale to są sesje które należą nie do nas tylko do innych użytkowników. A przynajmniej tak mogło by się wydawać ;>. PHP, jak to mój znajomy zawsze powtarza, nie jest zaprojektowany z myślą o bezpieczeństwie, a te wszystkie rzeczy związane z bezpieczeństwem, takie jak np openbase_dir, etc są “workaroundem” zaimplementowanym na nie tym poziomie abstrakcji na którym to powinno być zrobione. Dobrym przykładem na “bezpieczeństwo” PHP jest fakt iż sesje nie są w żaden sposób związane z właścicielem (w sensie user’a na serwerze) strony, i wystarczy NUMERSESJI by dowolny inny użytkownik serwera mógł odczytać całą zawartość sesji. Jak ? A za pomocą takiego prostego skryptu:

<?php
session_id($_GET['s']);
echo(session_start() . " ");
echo("SID: ". session_id() ."\n");
var_dump($_SESSION);
?>

Skrypt, załóżmy readsess.php, przyjmuje parametr s w którym jest numer sesji, po czym otwiera tą sesje i dumpuje całą jej zawartość. Różne phpmyadmin etc lubią przechowywać hasła userów w sesji, więc dostanie się do sesji może oznaczać zdobycie pewnych wrażliwych danych należących do innego user’a, lub klienta strony innego user’a.

Jak poprawić bezpieczeństwo w tej kwestii ? Najlepiej session.save_path przenieść do jakiegoś bezpieczniejszego katalogu. Ale leniwym może wystarczyć proste chmod 0733 /tmp ;>

Kolejną kwestią jest dostęp do logów apache w których też znajdują się często numery sesji (tzn jeśli numer sesji nie jest przekazywany przez ciasteczka). Ofc tego dostępu user nie powinien mieć, ale to chyba jest bardziej oczywiste ;>

OK Tyle narazie ;>

G.C.

An article or post

Hello World!

czerwiec 15th, 2007

Hi.

Cóż, jako że to ma być techniczny blog, to zacznę od standardowego technicznego powitania: Hello World! ;>

W blogu tym będę zamieszczał pewne przemyślenia moje dotyczące działek którymi się zajmuje, czyli programowania oraz reverse engineeringu. Trochę z tzw “security” też się pewnie czasem pojawi ;>

Hmm w sumie napiszę jeszcze ze 3 słowa o sobie co by leniwi nie musieli google przepytywać ;> Jestem Gynvael “GynDream” Coldwind (tak, to jest pseudonim ;>), posiadam tytuł inżyniera który uzyskałem na Politechnice Wrocławskiej ;> W programowanie bawię się jakieś 17 lat (piszę to w roku 2007) , w RE dużo krócej ;> Pracuje obecnie w hiszpańskiej firmie zajmującej się ogólno pojętym bezpieczeństwem komputerowym. Wcześniej pracowałem w jednej z polskich firm antywirusowych, gdzie zajmowałem się tworzeniem unpackerów do plików wykonywalnych.  Po za tym należę do teamu Vexillium (http://vexillium.org). I nie pisze poprawnie po polskiemu ;p sorry ;p. Jestem zdania że jeśli komuś zależy to się domyśli o co mi chodziło ;> Nyom =^^= Tyle.

Nyom. To do następnego, już bardziej technicznego, posta ;>

G.C.

« Previous



Erp - gotowe projekty domów - Drukarki - ogłoszenia drobne - praca Mysłowice - praca Częstochowa - praca Lublin - praca Poznań - angielski Bielsko-Biała - Kominki