Sunday, July 24, 2011

Ochrona przed atakiem typu buffer overflow (Stack-Smashing Protector)

Jak działa metoda buffer overflow? Przyjrzyjmy się przykładowemu programowi.


Tak na marginesie to trzeba mieć talent, aby takie coś napisać. Musiałem przerobić mój przykład tak, aby atak się udał ponieważ pierwotnie nie było to możliwe.
Program działa prosto, oczekuje jako parametru hasła. Poprawnym hasłem jest "root". Autoryzacja powiedzie się tylko wtedy, gdy wpiszemy "$ ./bflow2 root". 
Cały błąd projekcyjny tego programu leży w tym, że do autoryzacji używamy w ogóle nie potrzebnej zmiennej auth. Jak by tego było małe, to jest jeszcze ona zadeklarowana przed buforem, który można przepełnić. Nie ma sprawdzania długość hasła wprowadzonego przez użytkownika.
Zanim przejdę do rzeczy wspomnę jeszcze, że najpierw skompiluję i przetestuje program na swoim systemie Debian Squeeze amd64, a później na CentOS 5. Wyniki będą różne. W systemie Debian od wersji Lenny wszystkie możliwe paczki są kompilowane z opcją ochrony stosu. Mechanizm ten stworzył IBM, to tak zwany stack-smashing protector. Dokumentacje GCC zawiera te opcje.
Do rzeczy. Najpierw uruchomimy program z parametrem, który zapełni cały bufor, następnie w debuggerze gdb sprawdzimy ile jeszcze bajtów zostało do nadpisania zmiennej auth.


Cyfrę "1" w kodzie hexadecymalnym reprezentuje liczba "31". Można to sobie sprawdzić wydając polecenie  'echo "1111111111"|hd'.
Jedynek jest 10, zapełniamy cały bufor. Podkreśliłem je na czerwono. Trzeba pamiętać, że w pamięci bajty są umieszczone w odwrotnej kolejności. Dlatego wartości "31" nie są ciągłe.
Na zielono podkreśliłem adres zmiennej auth na stosie oraz wynik działania programu.
Jeżeli słowa zawierające koniec tablicy buff i zmienną auth odwrócimy to zobaczymy ile jest między nimi bajtów:
0x00313131   0x00000000   0xffe32000
0x31313100   0x00000000   0x0020e3ff   odwrócone
Bajty stanowiące odstęp między końcem tablicy buff, a zmienną auth oznaczyłem kursywą. Natomiast samą zmienną auth pogrubiłem. Teraz nie ma już wątpliwości, należy dopisać jeszcze 6 jedynek ('1') aby nadpisać zmienną auth. (Znak '1' ani '0' nie reprezentują w pamięci liczb 1 i 0, zapisywane są odpowiednimi kodami ASCII)


Jak widać atak powiódł się. Program dotarł do końca, wypisując tekst 'end' i uzyskał dostęp. Mimo wszystko system wykrył ingerencję w stosie programu. Świadczy o tym komunikat "Segmentation fault.". Dzieje się tak ponieważ większość najważniejszych programów w systemie Debian są kompilowane, z ochroną stosu.
Po opuszczeniu debuggera wywołałem jeszcze trzy razy program. Pierwszy raz miał o jedną jedynkę za mało (15), druki 16, a trzeci raz o jedną za dużo (17). Wpisując szesnaście jedynek program sam się nie zakończył, ale kod wykonał do końca, o czym świadczy wypisanie testu 'end'.
Teraz skompilujemy program z opcją -fstack-protector.


Tym razem zamiast samych jedynek użyłem kolejnych liczb, teraz można zobaczyć jak powinno się czytać zrzut pamięci od tyłu. Jak widać kompilator odwrócił kolejność zmiennych na stosie i nie można teraz poprzez tablicę buff nadpisać zmiennej auth, ponieważ jest ona przed nią.
Nawet z opcją -fstack-protector da się nadpisac w taki sposób zmienne z funkcji main(). Aby temu zapobiec należy użyć opcji -fstack-protector-all.
Teraz przetestujemy ten sam kod na systemie CentOS 5.


Najpierw sprawdzamy jaki jest odstęp między zmiennymi. Łoł - nie ma żadnego. Wystarczy dodać tylko jeden znak, czyli zamiast jako parametr podać 10 znaków, należy podać 11 i gotowe.
Dodałem 'x', jak widać działa pięknie. Potem kompilujemy program z ochroną stosu i również działa jak powinno - przerwał program i nie pozwolił mu dalej pracować. Różnice w zachowaniach kompilatora na obu tych systemach wynikają z kompilacji z różnymi opcjami gcc i nie tylko.
W systemie Debian opcja ochrony stosu zapobiegła atakowi, a system w całości wykonała kod programu, w CentOS program został natychmiast przerwany.

Saturday, July 23, 2011

FreeBSD vs. Linux?

Ostatnio na urlopie miałem więcej czasu niż zwykle i temat FreeBSD ponownie powrócił. FreeBSD jest lepszy od GNU/Linux czy nie? Warto poświęcać czas na uczenie się nowego systemu, czas który mógłbym poświęcić na zgłębianie tajników już dobrze znanego mi systemu z pod znaku pingwina? W tym tekście postaram się odpowiedzieć na te i wiele innych pytań z mojego punktu widzenia, co należy podkreślić.

System FreeBSD nurtował mnie od dawna, nawet można powiedzieć, że od kiedy o nim przeczytałem. Jednak poważniejsze próby podbicia tego systemu miały miejsce jakieś dwa lata temu. Jak zwykle podchodząc poważnie do tematu kupiłem książkę, która pomogłaby mi lepiej zrozumieć ten system, a co za tym idzie usprawni migrację. Szczerze mówiąc to byłem bardzo napalony na ten system, ach ten demon. Niestety lektura książki "FreeBSD 6. Księga eksperta" nie podtrzymała mojego zapału, wręcz przeciwnie, trochę nawet mnie rozczarowała. Oczywiście nie była to wina jakości samej książki, raczej argumentów jakie autor używał do udowodnienia, że FreeBSD jest lepszy od GNU/Linux.

Po wstępnym zapoznaniu się z nowym systemem i kilku podejściach przejścia z GNU/Linux na FreeBSD szybko zdałem sobie sprawę, że ten system na desktop się nie nadaje. Chyba że czyimś celem jest ciągłe bawienie się samym system. FreeBSD pozostawał nadal opcją jako system serwerowy, tylko ciężko uczyć się nowego systemu i nabierać w jego obsłudze wprawy, gdy nie używasz go na co dzień.

Tak to wyglądało te dwa lata temu. W międzyczasie próbowałem jeszcze kilka razy ale to takie trochę jakby dla zabicie nudy. Wpadła mi też w ręce książka "FreeBSD 7. Instalacja i konfiguracja" ale nie wniosła żadnych nowych rewelacji.

Teraz na nowo podszedłem do tematu. Konfigurowałem we FreeBSD te same usługi i mechanizmy co w GNU/Linux, przejrzałem chyba wszystkie dyskusje w internecie na temat wyższości BSD nad GNU/Linux i stwierdzam co następuje :)

Na celownik pozwolę sobie wziąć pewien artykuł, do którego często odsyłają zwolennicy FreeBSD na polskich forach. Ale bez obaw, w języku angielskim również pełno takich argumentów - przykład.
Oczywiście nie będę tu komentował wszystkich fragmentów, które wydały mi się nie do końca prawdą lub bliższych emocji niż logice. Wybrałem tylko te najbardziej sprzeczne z własna ideologią.

Niesłuszne zarzuty
Najpierw czytamy, że system GNU/Linux jest rozwijany przez niezorganizowaną rzeszę:
"...ludzi żyjących w różnych państwach, mówiących różnymi językami i posiadających odmienne ideologie."
Potem o tym:
"Ze względu na podział panujący w Gnu i Linux trudno wyszczególnić jednoznacznie jakąś grupę osób odpowiedzialnych za rozwój całego projektu."
Nie ma gwarancji :) ale zaraz, przecież takie są założenia licencji GPL:
"For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software."
Poza tym przeanalizujmy to dokładnie. Jeżeli instalujesz FreeBSD na serwerze i coś nie działa, to gdzie wtedy kieruje się swoje żale? Otóż pozostaje Ci tyle sam co w przypadku Linuksa, zgłosić błąd, a najprędzej zainstalować starsza wersję lub coś podobnego.
Poza tym w przypadku Linuksa można sobie wykupić taką 'odpowiedzialność'. Są nią dystrybucje komercyjne. Prawdopodobnie dlatego wiele dużych firm wybiera Linuksa.
Natomiast za rozwój całego projektu odpowiedzialni są deweloperzy danej dystrybucji.
Podobne zarzuty przeczytałem we wspomnianej książce, dlatego mnie tak rozczarowała.

Linuksowi zarzuca się również, że ma 100 różnych dystrybucji, natomiast następny fragment jest o współpracy, ale czego?
"Współpraca 
Każdy z system z rodziny BSD ma swoje własne cele i założenia, które są realizowane przez developerów. Daje to możliwość równoległego testowania różnych technologi i rozwiązań. Sprzyja to również ogólnemu rozwojowi wszystkich systemów. Ze względu na niedrastyczne różnice kodów poszczególnych BSD istnieje możliwość wymiany technologicznej. Czyli w momencie w którym jakaś technologia zostanie wprowadzona i przetestowana przez jeden z systemów może nastąpić przeportowanie jej do innego BSD przy stosunkowo niewielkim nakładzie pracy. Taka wymiana nie jest możliwa z systemem Linux a przynajmniej nie z taką łatwością."
Oto jedna z największych bzdur. Okazuje się że nie tylko Linux ma wiele dystrybucji, jest FreeBSD, OpenBSD, NetBSD, PC-BSD i DragonFly BSD, a nawet więcej. Nie ma tylko jednego FreeBSD rozwijanego przez zespół niecałych 20 programistów. Najlepsze, to to że różne odmiany *BSD potrafią się dzielić nowymi rozwiązaniami a GNU/Linux nie hehee. Dobrym ostatnim przykładem jest Upstart. Jak widać nie trafny przykład.

Teraz kolejna perła :)
Jak wiemy licencja BSD jest bardziej liberalna niż GPL. Jak to w tym artykule ładnie ujęto:
"Ideologia GPL i BSD. Niewolników wolności i prawdziwie wolnych."
Z tego też powodu FreeBSD ma taką otóż przewagę:
"Komercja

Równie ważne jak sam system jest fakt jego wykorzystania przez rynkowych liderów. Dlatego ważny jest proces komercjalizacji, nie systemu, ale produktów na nim opartych. Istnieje wiele rozwiązań komercyjnych wykorzystujących Gnu/Linux jak i BSD. To znaczy, że zarówno pierwszy jak i drugi system dają się łatwo sprzedać. Niestety dość restrykcyjna licencja GPL często odstrasza dużych graczy."
Okazuje się, że życie w tej kwestii pokazuje zupełnie co innego. Owszem, Mac OS X korzysta z tej wolności oraz wielu producentów urządzeń UTM. Jednak ostatnio największe koncerny skupiają swoje rozwiązania na platformie Linux, a nie FreeBSD. Gorący przykład do Oracle, o członkach The Linux Foundation nie wspomnę. Obecnie największą firmą wykorzystującą GNU/Linux jest Google. Ostatnio również pisałem o tym, że Yahoo! pomału migruje na GNU/Linux. Także argument bardzo nie trafny, a już na pewno nie mający wiele wspólnego z prawdą. Na ironię, to GNU/Linux posiada komercyjne wersje, a nie FreeBSD hehe

Kolejna perła :)
Tym razem o tym w czym się specjalizuję, czyli zapora ogniowa. Dlatego też nie skończę tylko na cytowaniu i komentowaniu ale także napisze trochę o moich doświadczeniach, bo testowałem zaporę we FreeBSD. Ale najpierw ironia:
"Systemy plików

Niewątpliwie Linux obsługuje największą ilość różnorakich systemów plików. Między innymi ext2, ext3, ext4, FAT, HFS, JJFS, JFS, UDF, XFS, ReiserFS, Reiser4, Tux3. Zapewne większość z nich jest bardzo dobrze przetestowana. Jednak warto zauważyć że przy tak dużej ilości systemów plików bardzo trudnym staje się dokładne przetestowanie nowej wersji jądra wraz ze wszystkimi możliwymi systemami plików. Co niekiedy zmniejsza stabilność naszej maszyny.
Z kolei systemy BSD nie obsługują tak imponującej ilości systemów plików. Są w stanie wykorzystać między innymi UFS, FAT, ext2 oraz ZFS. Dzięki małej różnorodności każdy aspekt poszczególnego systemu plików jest zbadany i należycie przetestowany co minimalizuje straty danych. 
Firewall

Ważnym zabezpieczeniem systemu operacyjnego jest firewall. Dlatego też standardem stało się dołączanie zapory ogniowej do systemu. Linux standardowo dystrybuowany jest z netfilter/iptables, który zapewnia pełną dowolność w zarządzaniu naszymi portami i pakietami sieciowymi.
Natomiast systemy z rodziny BSD wykorzystują inne filtry pakietów. Są nimi PF lub IPFW w zależności od upodobań developerów. Istotną przewagę nad szeroko wykorzystywanym netfilter’em filtry BSD mają w prostocie konfiguracji. Bardzo dużą uwagę poświęcili developerzy kwestiom tworzenia reguł. Zapewniło to znaczącą poprawę czytelności wszystkich plików konfiguracyjnych, oczywiście są one human-readable. Filtry BSD w żadnej mierze nie ustępują wydajnością ani funkcjonalnością netfilter’owi, niejednokrotnie go przewyższając."
No tak, Linux obsługuje masę systemu plików, to źle, to bardzo źle ale tak się składa, że firewall to ona ma jeden a nie trzy: IPF, IPFW i PF! Ok, to który wybrać hehe? [FreeBSD Handbook: Chapter 30 Firewalls]
Jak widać minimalizm względnie pojęty.
Ale przyjrzyjmy się ostatniemu zdaniu, które twierdzi, że możliwości powyższych zapór są większe niż zapory Netfilter. G**** prawda, bo inaczej nie powiem. Gdzie w tym PF znajdę taki mechanizm jak moduł recent? A może moduł string ma któraś z tych trzech zapór ogniowych?
Znalazłem książkę o PF, jest tego dużo. Pamietam ile trzeba było czasu poświęcić na to, aby sprawnie posługiwać się zaporą Netfiltera. Skoro tyle czasu poświęciłem na naukę jednej, to teraz mam kupić książkę do drugiej i poświęcić wiele czasu na to, aby nauczyć się robić to samo tylko tyle, że na innym systemie? Czy to ma sens? Czy się opłaca? Zwłaszcza, że moduły iptables oferują coraz to więcej możliwości.
Znalazłem blog, którego autor po wieloletnim używaniu FreeBSD zachwycił się Ubuntu! Sam nie lubię Ubuntu. Jak widać upodobania dotyczące używanego systemu w przypadku FreeBSD vs. Linux nie wiele się różnią od powszechnych wojen w świecie GNU/Linux zwanych 'Która dystrybucja jest lepsza'.
Dla zaprawionego linuksiarza przesiadka na FreeBSD z praktycznego punktu widzenia nie wiele oferuje korzyści. Moim zdaniem nie opłaca mi się uczyć nowych mechanizmów jeżeli nie oferują one więcej. Wcześniej może tak było, ale obecnie GNU/Linux jest na takim etapie rozwoju, że nie wiele jest mechanizmów we FreeBSD, których nie oferowałby GNU/Linux.

Pozytywne cechy FreeBSD
Mimo iż piszę o tym, że FreeBSD wcale nie jest lepszy od GNU/Linux to nie znaczy, że nie cenię sobie pewnych rozwiązań zaimplementowanych we FreeBSD. Mało tego, wiele tych rozwiązań zostało przeniesionych do świata GNU/Linux. System portów FreeBSD został zaimplementowany w Gentoo! Jądro FreeBSD jest obecnie jedną z opcji w dystrybucji Debian!

Kiedyś FreeBSD szczyciło się mechanizmem Jali, ale teraz GNU/Linux ma LXC. National Security Agency (NSA) wybierając platformę do implementacji mechanizmu MAC (SELinux) wybrało GNU/Linux, a nie FreeBSD.

Oczywiście FreeBSD jest niemal wzorcowym systemem pod względem implementacji. Jeżeli weźmiemy pierwszą lepszą książkę poświęconą systemom operacyjnym, to rozwiązania zaimplementowane we FreeBSD są często bliższe ideałowi, niż te w GNU/Linux. Lista właściwości jądra FreeBSD naprawdę robi wrażenie. To główny powód, dla którego interesuje się tym systemem.
Należy jednak zaznaczyć, że mimo, iż implementacji np. wątków i procesów w jądrze Linux jest dosyć dziwna to nie znaczy, że są wolniejsze, czy mniej funkcjonalne w stosunku do tych wzorcowych z FreeBSD. Pisałem o tym w poprzednim roku.

Kolejną przyciągającą rzeczą do FreeBSD jest jej społeczność. Jest bardziej dojrzała i mniej w niej fanatyków, aczkolwiek jak pokazywałem wcześniej też ich tam nie brakuje. Muszę przyznać, że poruszane tematy w magazynach poświęconych *BSD są bardziej zaawansowane niż te znajdujące się w prasie poświęconej GNU/Linux. Wynika to pewnie z tego, że użytkowników *BSD jest mniej, a odsetek fanatyków w tej populacji zdecydowanie mniejszy niż w GNU/Linux. Nie przeszkadza to jednak w niczym, aby czytać z pożytkiem teksty przeznaczone dla *BSD ponieważ zdecydowana większość zawarta tam informacji ma odwzorowanie w systemach GNU/Linux. Oprogramowanie jest wspólną cechą obu tych systemów, a system to tylko ok. 20% różnicy, na którym to oprogramowanie jest uruchomione.
Nie wątpliwie FreeBSD ma znacznie lepsza dokumentację.

Tak naprawdę, to cała różnica pomiędzy FreeBSD, a GNU/Linux sprowadza się do innego jądra i innej filozofii połączenia innych komponentów systemowych. Tym drugim różnią się również poszczególne dystrybucje systemu GNU/Linux. Ważną kwestią są również mechanizmy bezpieczeństwa. Mimo, iż FreeBSD wstępnie jest lepiej skonfigurowany pod tym względem to nie znaczy, że konfiguracji tej nie da się zastosować w GNU/Linux. Oba systemy mają równoważne mechanizmy np. do ochrony przed atakiem typu buffer overflow. System przeznaczony do testów penetracyjnych dla profesjonalistów od bezpieczeństwa BackTrack bazuje na systemie Linux, a nie FreeBSD.

Wnioski
GNU/Linux jest dominującym systemem dla rozwiązań serwerowych. To sprawia, że wszelkie prace nad rozwojem tego typu systemów i rozwiązania są, i będą implementowane na tej platformie. Jak wiadomo duży może więcej.

Natomiast całą filozofie wyższości FreeBSD nad GNU/Linux można groteskowo sprowadzić do poniższej ilustracji.
Więcej argumentów za nie znalazłem :)

Na koniec wspomnę jeszcze tylko o jednej z prawd jaką odkryłem w przeszłości, gdy bardzo interesowałem się programowaniem. Jak wiadomo tam również obecna jest wieczna dyskusja na temat 'Który język programowania jest lepszy'. Otóż okazuje się, że najlepszym językiem dla danej osoby jest ten, który zna najlepiej.

Kolejną mądra zasadę, która padła podczas dyskusji FreeBSD vs. Linux na forum linuxquestions.org jest:
"Use the right tool for the job."

Thursday, July 21, 2011

Microsoft - "don't panic!"

Microsoft z okazji zbliżającego się 20-lecia systemu GNU/Linux po prostu chce powiedzieć wszystkiego najlepszego i zaproponować rozejm i współpracę?





http://h-online.com/-1282639

Thursday, July 14, 2011

Friday, July 8, 2011

Windows 7 - problem z usługą Bufor wydruku

Ostatnio w pracy miałem ciekawą usterkę. Na jednym z komputerów nagle, ni stąd, ni zowąd zniknęły wszystkie drukarki. To nie kabel, ani nic związanego z łącznością. System wyłączył usługę Bufora wydruku. Problem tylko w tym, że nawet jeżeli włączę ją ręcznie, to i tak zaraz zostanie automatycznie wyłączona. Trochę mi to zajęło zanim znalazłem sposób na naprawienie tego problemu - w końcu z systemami Windows mam teraz mniej do czynienia niż z Linuksem.
Przyczyna ponoć było zapchanie bufora wydruku. Wyczyścić go można poprze usuniecie zawartości katalogu C:\WINDOWS\system32\spool\PRINTERS - ufff, i wszystko wróciło do normy.

Dodano 23 grudnia 2011:
Opisany wyżej problem zaczął powtarzać się coraz częściej, a mianowicie czyszczenie bufora pozwalało na jednorazowe drukowanie. Nowym rozwiązaniem pogarszającego się problemu jest użycie tego narzędzia: http://windows.microsoft.com/en-US/windows-vista/Troubleshoot-printer-problems#EOD
Na razie z powodzeniem...