Rootnode planet
Planeta to miejsce, w którym agregujemy wpisy z najciekawszych blogów znajdujących się na Rootnode. Jeśli myślisz, że twój blog powinien się tutaj znaleźć poinformuj nas o nim. Bardzo mile widziane blogi techniczne i specjalistyczne.

Dnia 02.09.2010

Stan TCP – TIME_WAIT

Jednym ze stanów połączenia protokołu TCP jest TIME_WAIT. Jest to stan, w którym następuje oczekiwanie w celu upewnienia się, że druga strona otrzymała potwierdzenie rozłączenia. Zgodnie z dokumentem RFC 793 połączenie w takim stanie może być najdłużej przez 4 minuty. W systemie Linux najczęściej spotyka się dla tego stanu wartości 60 oraz 180 sekund. Podczas oczekiwania w stanie TIME_WAIT ponowne nawiązanie połączenia z klientem (retransmisja) kosztuje znacznie mniej niż nawiązanie nowego połączenia.

Poprzez redukcję czasu oczekiwania dla tego stanu, protokół TCP może znacznie szybciej zwalniać zamknięte połączenia tym samym szybciej udostępniając zasoby na nowe połączenia:

echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout

lub dodać wpis do /etc/sysctl.conf:

net.ipv4.tcp_fin_timeout = 30

Wszystkie połączenia w stanie TIME_WAIT możemy wyświetlić za pomocą polecenia: netstat -tapn | grep TIME_WAIT. Oprócz skrócenia czasu dla oczekiwania w tym stanie możemy dodatkowo wykorzystać mechanizm „recyklingu” tych gniazd:

echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle

lub dodać wpis do /etc/sysctl.conf:

net.ipv4.tcp_tw_recycle = 1

Z opcją tą należy obchodzić się dość ostrożnie, ponieważ w niektórych warunkach szybkie odzyskiwanie gniazd TIME_WAIT może spowodować problemy – szczególnie w warunkach, w których występuje równoważenie obciążenia (ang. load balancing) lub poprawna praca mimo awarii (ang. failover). Znacznie bezpieczniejsze z punktu widzenia protokołu jest wykorzystanie techniki ponownego użycia gniazd TIME_WAIT:

echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse

lub dodać wpis do /etc/sysctl.conf:

net.ipv4.tcp_tw_reuse = 1

Jest to bardzo przydatne ustawienie szczególnie w warunkach, w których następuje otwieranie licznych, krótkich połączeń zostawianych w stanie TIME_WAIT – np. serwery WWW. Ponowne wykorzystywanie tego rodzaju stanów dla nowych połączeń może bardzo efektywnie zmniejszyć obciążenie serwera.

Więcej informacji: Protokół TCP, man netstat, Kształtowanie Ruchu i Zaawansowany Routing

1&1 w Polsce, czyżby hosting killer? niekoniecznie

Tuż przed weekendem na łamach jednej z e-gazet (nie pamiętam której) przeczytałem o rozpoczęciu działalności na terenie Polski przez hostingowego giganta jakim jest 1&1. Na pierwszy rzut oka można się tylko cieszyć wreszcie jakiś duży hostingowy gracz wkracza na polski rynek wprowadzając powiew świeżości w zgniliznę polskich ofert. Na start 1&1 przygotował nie lada gratkę, zupełnie za darmo oferuje 10GB pojemności, 3TB transferu miesięcznie i  domenę „.pl” w pakiecie 2 letnim; bez haczyków ani małych druczków (2 razy regulamin przeczytałem) . Zachęcony powyższą ofertą postanowiłem się sprawdzić co oferuje zagraniczny gigant, i tu zaczynają się schody. Do rejestracji wymagane są nasze pełne dane teleadresowe + pesel. Problem sprawia formularz adresowy w którym pole telefon jest źle opisane (format wprowadzania danych jest nieintuicyjny) pomogło wprowadzenie numeru telefonu (komórkowego) w formacie „3cyfry / reszta”. Po rejestracji dostajemy 4 cyfrowy numer który musimy wpisać podczas autoryzacji odbywającej się telefonicznie (dzwoni do Ciebie automat i prosi o wpisanie numeru). Również ta autoryzacja sprawia problemy. Za pierwszym razem automat rozłączył się tuż po odebraniu przeze mnie telefonu, za drugim razem miał problem z rozpoznaniem wpisywanego przeze mnie kodu, ale na szczęście się udało.

Po poprawnej autoryzacji dostałem dane dostępowe do konta i tu pierwszy szok. Już przed oczami przechodziły mi obrazy stawiania nowych portali, przenoszenia bloga oraz domen, a także udostępnienia kilku większych plików znajomym. Jednak to co zastałem okazało się totalną klapą. Panel administracyjny przypomina usługi hostingowe z których korzystałem 10 lat temu; archaiczny, niewygodny, z niewielką ilością opcji które są źle poustawiane lub ukryte w nieintuicyjnym miejscu. Najważniejszą bolączką był brak możliwości podpięcia zewnętrznych domen do systemu (np. z dnsów OVH) co skutecznie odstraszyło mnie od tego usługodawcy. Problemy są również z przesyłaniem plików, serwery często zrywają transfer co skutecznie utrudnia wgrywanie. Nie wiem jak działanie serwisów po udało im się mnie skutecznie odstraszyć. Po niecałych kilkunastu minutach stwierdziłem, że to nie dla mnie i postanowiłem już nie korzystać z ich usług.

Czy w związku z tym powinno się wystrzegać tej firmy? Myślę, że nie. Jeśli po upływie 2 lat firma nadal będzie oferować niskie ceny mogą być dobrą alternatywą dla niewymagających użytkowników, Ci którzy mają firmowe strony powinni uciekać jak najdalej. Brak polskiego wsparcia (dzwonisz do call center za granicą) oraz niska jakość usług (mało opcji, zrywanie połączeń) są wystarczającymi argumentami przeciw 1&1.

Dnia 25.08.2010

Recenzja: Java EE 6. Programowanie aplikacji WWW

Największą bolączką osób chcących rozpocząć swoją przygodę z korporacyjną Javą jest a raczej był brak jakiejkolwiek książki dla początkujących. Był ponieważ od całkiem niedawna wszyscy chcący zapoznać się z podstawami tej technologii mogą nabyć książkę „Java EE 6. Programowanie aplikacji WWW” której autor Krzysztof Rychlicki-Kicior przenosi nas w świat Javy EE. Książka pomimo niewielkiej liczby stron (lekko powyżej 200) omawia wszystkie podstawowe aspekty programowania w korporacyjnej Javie oraz technologie wykorzystywane podczas tworzenia takich aplikacji, przedstawia nawet dwa w miarę kompletne przykłady. Można by powiedzieć, że książka idealnie zapełni lukę jednak tak nie jest. Pozycję tą można głównie polecić tym, którzy zainteresowani są w szczególności technologią JSF bo właśnie jej poświęcono większość książki. Ci którzy wolą korzystać z innych technologii zadowolą się jedynie pierwszymi rozdziałami, oraz ostatnim rozdziałem poświęconym dostępowi do bazy danych. Kolejnym (moim zdaniem większym) minusem książki jest jej charakter, podczas czytania dochodzimy w końcu do wrażenia, że nie czytamy nic innego jak obszerny tutorial. Jednym, takie rozwiązanie może przypaść do gustu, moim zdaniem tutorialowa forma (w tym wydaniu) źle wpływa na czytelność książki, szczególnie denerwującym (jak dla mnie) był opis integracji netbeans<=>tomcat (która jest na tyle prosta, że można ją pominąć kierując do wyszukiwarki), czy też zrzuty ekranu prezentujące środowisko Netbeans (bez specjalnej potrzeby), zabrakło natomiast diagramów UML prezentujących zasady działania danego zagadnienia.
Przechodząc do sedna sprawy, moim zdaniem:

Za książką:

  1. dobrze (choć mało wyczerpująco) opisane techniki oraz technologie J2EE,
  2. proste oraz możliwie kompletne przykłady,
  3. przystępny język oraz cena książki,

Przeciw książce:

  1. tutorialowa forma książki,
  2. niepotrzebne obszerne (zrzuty) opisy prostych czynności nie związanych bezpośrednio z technologią j2ee (integracja netbeans<=>tomcat, tworzenie projektu w netbeans),
  3. źle sformatowane kody źródłowe (w ostatnich rozdziałach, gdzie tworzone są encje z zapytaniami nazwanymi kod zlewa się co utrudnia analizę),
  4. za dużo o JSF jednak wciąż za mało by mieć mocne podstawy z tej technologii,
  5. powtarzalność (w pewnym momencie mamy wrażenie, że autor się powtarza, szczególnie odnośnie przykładowego kodu)
  6. słowo „Magikonwersja” (nie lubię takich tworów, za Potterem też nie przepadam)

Czy pomimo tylu minusów warto kupić książkę? Na to pytanie odpowiedzieć musi sobie każdy z osobna. Zapewne książka przydatna będzie zupełnym laikom którzy nie wiedzą nic odnośnie korporacyjnej javie, a chcieliby zacząć coś w niej robić.Również studenci znajdą w tej książce wiele interesujących informacji, a to za sprawą przystępnego treściwego języka oraz szeregu przykładów które dobrze przedstawiają omawiane tematy. Jeśli natomiast tworzyłeś już projekty w J2EE ta książka może jedynie nieznacznie uzupełnić Twoją wiedzę, czy jest sens ją kupować ocenisz sam.

Szkolenie ze Springa w Krakowie

Spring Source

W dniach 7-10 grudnia 2010 odbędzie się w Krakowie szkolenie z technologii Spring (w wersji 3.0). Prócz samego rdzenia tej technologii szkolenie obejmować będzie takie zagadnienia jak  Spring MVC, Spring AOP, Spring IOC, Spring JavaConfig, Spring Security, SpringSource Tool Suit i inne. Pełne zestawienie można pobrać w formacie pdf.
Dodatkowo rejestrując się do 4 września możliwe jest wykorzystanie kodu promocyjnego springup który skutkować będzie 15% rabatem. Jeśli na kurs wybieramy się z kolegą/koleżanką czeka nas rabat 10%, jeśli to będzie większa grupa, można liczyć na 20% rabat.  Po więcej informacji odsyłam na stronę kursu.

Dnia 24.08.2010

Złam hasło!

D

o niedawna hasła były wystarczającym zabezpieczeniem ważnych danych przed nieuprawnionym dostępem do nich. Czy jest tak nadal? Z całą pewnością nie. Posiadając odpowiednią wiedzę oraz oprogramowanie, użytkownik jest w stanie bez większych przeszkód uzyskać dostęp do zabezpieczonych plików.

Artykuł ten został opublikowany w numerze 01/2009 (44) magazynu hakin9.

Artykuł w formacie PDF

Dnia 23.08.2010

(D)DoS-Deflate – obrona przed floodem połączeń

S

krypt (D)DoS-Deflate jest skryptem powłoki stworzonym przez użytkownika forum Defender Hosting o nicku Zaf na potrzeby firmy hostingowej MediaLayer. W historii firmy (w 2005 roku) zapisała się karta, w której firmowe serwery stały się celem ataku bazującego na nawiązaniu bardzo dużej ilości połączeń z wielu adresów IP (Distributed Denial of Service – DDoS). Chociaż dla MediaLayer blokowanie adresów było już powszechną praktyką – to tym razem postawiono na zautomatyzowanie tego procesu.

Od 2005 roku skala ataków typu DoS i DDoS jest na tyle poważna, że prezentowany skrypt można jedynie traktować jako prostą ochronę przed floodowaniem strony (hosta), która najczęściej ma miejsce poprzez odwiedzające ją spamboty lub inne szkodliwe oprogramowanie próbujące np. złamać hasło metodą brute force. Skrypt bazuje na poleceniu:

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr

Zlicza ono liczbę wszystkich połączeń TCP/IP oraz UDP serwera z pojedynczymi hostami i przedstawia je w formie adresów IP. Dlatego nie ma mowy o możliwości zatrzymania prezentowanym skryptem ataku DDoS, którego fala uderzeniowa składała by się np. z 2.000 hostów o różnych adresach IP, a każdy z tych hostów wykonywał by po 10 połączeń. Liczba przypadająca na pojedynczy host jest bardzo mała, ale po zsumowaniu wszystkich hostów osiąga 20.000 połączeń. Instalację skryptu przeprowadzamy następująco:

wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

Skrypt instalacyjny ściągnie wszystkie, pozostałe skrypty oraz pliki konfiguracyjne umieszczając je w katalogu /usr/local/ddos. Plik konfiguracyjny odpowiadający za (D)DoS-Deflate to ddos.conf. Jego konfiguracja może przedstawiać się następująco:

PROGDIR="/usr/local/ddos"
PROG="/usr/local/ddos/ddos.sh"
IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list"
CRON="/etc/cron.d/ddos.cron"
APF="/etc/apf/apf"
IPT="/sbin/iptables"
FREQ=1
NO_OF_CONNECTIONS=200
APF_BAN=0
KILL=1
EMAIL_TO="administrator@dot.com"
BAN_PERIOD=7200

Zmienna CRON definiuje położenie pliku wywołującego, co minutę (FREQ) za pomocą programu cron – skrypt (PROG) ddos.sh, który wychwytuje hosty, których liczba połączeń jest większa niż 200 (NO_OF_CONNECTIONS) oraz za pomocą programu sterującego filtrem pakietów – iptables (APF_BAN) blokuje (KILL) danemu hostowi dostęp do naszego serwera na dwie godziny (BAN_PERIOD wyrażony w sec.) powiadamiając o tym fakcie administratora systemu (EMAIL_TO). Oprócz czystego filtra iptables istnieje również możliwość wykorzystania nakładki APF (ang. Advanced Policy Firewall) – wówczas zmienna APF_BAN przyjmuje wartość równą 1. Za wykluczenia odpowiada plik ignore.ip.list, w którym należy umieścić wszystkie adresy IP nie mające podlegać filtrowaniu przez skrypt.

Zdefiniowanie liczby dopuszczalnych połączeń hostów z naszym serwerem (w tym przykładzie 200) zależy od naszych preferencji hostingowych (sprzęt, łącze, konfiguracja serwera etc.). Jeśli, zależy nam na częstszym sprawdzaniu ilości połączeń niż raz na minutę możemy zmienić to poprzez edycję pliku ddos.cron. Na przykład dopisanie wartości:

SHELL=/bin/sh
0-59/1 * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1
0-59/1 * * * * root sleep 30; root /usr/local/ddos/ddos.sh >/dev/null 2>&1

Spowoduje uruchamianie skryptu, co 30 sekund.

Więcej informacji: (D)DoS Deflate

Dnia 16.08.2010

Botnety – zmora lat ostatnich

C

hociaż wszyscy mogą dostrzec zewnętrzne okoliczności, nikt oprócz mnie nie powinien rozumieć sposobu, w jaki zwyciężam. Dlatego po osiągnięciu zwycięstwa nie powtarzam tej samej taktyki, lecz w następnej walce odpowiadam na zaistniałe okoliczności. – Sun Tzu

Artykuł ten został opublikowany w numerze 11/2009 (53) magazynu hakin9.

Artykuł w formacie PDF

Dnia 09.08.2010

Obchodzenie ekranu logowania Windows XP/Vista/Win7

W

przypadku systemów Windows XP/Vista/Win7 nie musimy koniecznie dysponować dystrybucją Linuksa w formie LiveCD z zainstalowanym (lub możliwością ściągnięcia i zainstalowania) programem chntpw. Wystarczy dowolna płyta umożliwiająca zamontowanie i modyfikację systemu plików firmy Microsoft (NTFS / FAT). Po zamontowaniu partycji z systemem Windows należy przejść do katalogu System32 oraz podmienić plik o nazwie utilman.exe (ang. Windows Utility Manager) na cmd.exe (ang. Command Prompt):

cd /mnt/Windows/System32
mv Utilman.exe Utilman.old
cp cmd.exe Utilman.exe

Po wykonaniu w/w czynności należy zrestartować komputer uruchamiając go z oryginalnie zainstalowanego systemu. Podczas pojawienia się ekranu logowania uruchamiany podmieniony Windows Utility Manager za pomocą kombinacji klawiszy: Klawisz Windows (tzw. WinKey) + U. Zamiast WUM powinna wystartować konsola z uprawnieniami administratora, w której możemy uruchomić system za pomocą polecenia explorer lub zmienić hasło wybranego użytkownika, którego login pojawił się podczas ekranu logowania systemu Windows np.:

net user Agresor *

Po wykonaniu zmiany hasła najbezpieczniej jest ponownie uruchomić system i zalogować się na wybranego użytkownika.

Więcej informacji: Offensive Security

Dnia 08.08.2010

Hakowanie SSL

K

orzystając z bezpiecznego połączenia, użytkownik Internetu jest pewien, że nic nie grozi jego danym. Przy nowym ataku SSLStrip nie jest to takie oczywiste. Brak jednej literki „s” w zasobie URL może oznaczać kłopoty. Poniżej pokazujemy, że „https” czasami może okazać się tylko zwykłym „http”.

Artykuł ten został opublikowany w numerze 10/2009 (52) magazynu hakin9.

Artykuł w formacie PDF

Dnia 04.08.2010

Pad dla blogera – konkurs OSblog i Securitum!

Grupa OSmedia wraz z firmą Securitum zapraszają do konkursu na najciekawszego bloga poświęconego technologii. Konkurs trwa od 5 sierpnia do końca października, a żeby wziąć w nim udział wystarczy opublikować co najmniej jeden wpis w obywatelskim serwisie blogowym OSblog.pl. Jest o co walczyć, bo główną nagrodą jest tablet Apple iPad 16GB!


Zasady uczestnictwa

Aby wziąć udział w konkursie należy opublikować jeden lub więcej tekstów o tematyce związanej z szeroko pojętym IT w serwisie OSblog.pl. Opublikowane teksty zostaną automatycznie objęte licencją Creative Commons Uznanie Autorstwa. Szczegóły uczestnictwa znajdują się w regulaminie na stronie konkursu.

Kryteria oceny artykułów

Przy ocenie tekstów brane będą pod uwagę takie kryteria jak: poziom merytoryczny, unikalność tematyki (tekst nie był publikowany wcześniej), interesująca tematyka (w tym wyjątkowość poruszanego tematu), precyzja w wyrażaniu myśli, poprawność językowa, obecność zrzutów ekranowych / ilustracji.

Nagrody

Nagrody w konkursie ufundował sponsor, firma Securitum.

Pierwsza nagroda to Apple iPad 16GB, WiFi
Ipad

(lub inny wybrany sprzęt podobnej wartości lub 2000 zł w gotówce)
Drugą nagrodą jest bezpłatny udział w jednym z organizowanych przez Securitum szkoleń:

(możliwe jest przyznanie drugiej nagrody kilku blogerom)
Przewidziane są również nagrody pocieszenia w postaci gadżetów z Butiku Jakilinux.

Więcej o konkursie: http://osblog.pl/konkurs-dla-blogerow/

Informacja o organizatorach

Securitum organizuje autorskie szkolenia z bezpieczeństwa IT. Drugą specjalizacją firmy są audyty bezpieczeństwa systemów IT. Grupa OSmedia (otwarte i społecznościowe media) skupia takie witryny jak OSnews.pl, OSblog.pl, jakilinux.org, Filmaster.pl czy playr.pl. Ideą grupy jest połączenie niezależnych, obywatelskich projektów mediowych, publikujących na otwartych licencjach Creative Commons.
OSMedia
Secri

Resetowanie hasła MS Windows NT/2k/XP/Vista/Win7 za pomocą Ubuntu i Backtrack

W

celu zresetowania hasła użytkownika systemu Microsoft Windows NT / XP /Vista lub Windows 7, który posiada np. uprawnienia administratora – wystarczy fizyczny dostęp do komputera. Pierwszą czynnością jest ustawienie startowania systemu z bootowalnej płyty CD/DVD czy urządzenia typu Pendrive‘a (zależy gdzie posiadamy zapisany nasz system z Linuksem) w BIOSie lub za pomocą menu Boot Managera przy starcie komputera. Pierwsza metoda ze względu na zastosowanie dystrybucji Ubuntu (w tym przykładzie wykorzystano wersję 8.10, która posłużyła do zresetowania hasła użytkownika systemu Vista) wymaga również stałego dostępu do Internetu ze względu na konieczność pobrania dodatkowych pakietów.

Po uruchomieniu z płyty lub dysku instalacyjnego należy wybrać tryb „LiveCD” poprzez menu „Wypróbowanie Ubuntu bez wprowadzania zmian w komputerze” (ang. Try Ubuntu without any change to your computer). Wraz z zakończeniem uruchamiania systemu należy uruchomić konsolę oraz edytować listę „źródeł”, z których pobierane są pakiety:

sudo su -
nano /etc/apt/sources.list

Odblokowując repozytoria Universe poprzez usunięcie komentarza z następujących linii:

deb http://archive.ubuntu.com/ubuntu interpid universe
deb-src http://archive.ubuntu.com/ubuntu interpid universe
deb http://archive.ubuntu.com/ubuntu interpid-updates universe
deb-src http://archive.ubuntu.com/ubuntu interpid-updates universe
deb http://archive.ubuntu.com/ubuntu interpid-security universe
deb-src http://archive.ubuntu.com/ubuntu interpid-security universe

Należy przeprowadzić aktualizację listy pakietów:

apt-get update

Oraz zainstalować niezbędne narzędzia do łatwego zamontowania partycji NTFS, jak i edycji haseł w systemach Windows:

apt-get install ntfs-config
apt-get install chntpw

To właśnie narzędzie chntpw autorstwa Peter’a N Hagen’a odpowiada za resetowanie lub ustawianie haseł dowolnych użytkowników (można również przeglądać ich listę), którzy mają prawidłowe (lokalne) konta w systemie poprzez modyfikowanie zaszyfrowanych haseł w pliku rejestru SAM. Pierwszą czynnością prowadzącą do edycji w/w pliku jest zamontowanie partycji systemu Windows, która zazwyczaj używa systemu plików NTFS lub FAT32. W przypadku systemu plików NTFS wydajemy polecenie:

ntfs-config

Na naszym pulpicie powinno ukazać się okno dialogowe z informacją: „Następujące partycje zostały wykryte i mogą być skonfigurowane„. Zaznaczamy z listy partycję zawierającą system Microsoft oraz klikamy Apply. W następnym oknie dialogowym „Narzędzie konfiguracji trybu zapisu dla NTFS” zaznaczamy opcje:

[x] Włącz tryb zapisu dla napędów zewnętrznych
[x] Włącz tryb zapisu dla napędów wewnętrznych

I potwierdzamy OK. W przypadku systemu plików VFAT wydajemy polecenia:

mkdir /media/Vista
mount -t vfat /dev/sda1 /media/Vista

Kolejnym krokiem jest już sama edycja pliku z hasłami:

cd /media/Vista/Windows/System32/config

Wyświetlamy listę dostępnych użytkowników w systemie wybierając interesujący nas login:

chntpw -l SAM
chntpw -u agresor SAM

Z menu tekstowego wybieramy pozycję nr 1 zatwierdzając nasz wybór oraz zapisując zmiany w pliku rejestru:

1 - Clear (blank) user password
Password cleared!
Hives that have changed:
 # Name
 0 <SAM>
Write hive files? (y/n) [n]: y
 0 <SAM> - OK

Ostatnią czynnością jest restart systemu:

shutdown -r now

Wyciągamy płytę oraz naciskamy Enter. W opcjach BIOSu lub Boot Managera przywracamy / wybieramy pierwotny start systemu z dysku twardego oraz logujemy się na nazwę użytkownika, któremu wyczyściliśmy hasło. Druga metoda zakłada użycie dystrybucji Backtrack (w tym przykładzie wykorzystano wersję 4), która nie wymaga dostępu do Internetu, ponieważ narzędzie chntpw wchodzi w standardowe wyposażenie tej dystrybucji. Jedyną wymaganą czynnością jest odpowiednie zamontowanie partycji NTFS:

mkdir /media/Vista
mount -t ntfs-3g /dev/sda1 /media/Vista

Jeśli nie jesteśmy pewni, który dysk należy zamontować – możemy wykorzystać polecenie: blkid -L odnajdując system Windows po etykiecie dysku. Reszta czynności jest dokładnie taka sama jak w przypadku dystrybucji Ubuntu.

Więcej informacji: Offline NT Password & Registry Editor

Dnia 24.07.2010

Złodzieje danych

S

ieci informatyczne spowodowały dynamiczny rozwój zdalnych technik atakowania ofiary przy wykorzystaniu oprogramowania oraz połączenia sieciowego. Doskonalenie tego rodzaju metod ataku odbywa się cały czas. Czy w kontekście tych faktów należy lekceważyć próby ataków z wykorzystaniem socjotechniki i dostępu fizycznego do komputera?

Artykuł ten został opublikowany w numerze 11/2009 (53) magazynu hakin9.

Artykuł w formacie PDF

Dnia 20.07.2010

Recenzja: „Java. Efektywne programowanie. Wydanie II”

Kilka dni temu zakończyłem lekturę książki „Java. Efektywne programowanie. Wydanie II”. Z początku sceptycznie podchodziłem do wydania jako zbiór zasad które warto wykorzystać podczas pisania, no bo co nowego można napisać. Jednak już po kilku pierwszych tematach zdałem sobie sprawę, że książka warta jest każdej wydanej złotówki.
Autor w 78 tematach omawia zasady tworzenia obiektów, klas, metod, interfejsów, korzystania z typów ogólnych, wyliczeń, adnotacji, oraz zasady programowania, obsługi wyjątków czy też współbieżności i serializacji. Tematy opisane są zwięźle i klarownie, a tam gdzie to potrzebne autor przedstawia kod źródłowy z ew. modyfikacjami jakie należy nanieść by program był czytelny i co ważne działał poprawnie. Kod źródłowy jest dokładnie opisany, wraz z wytknięciem błędów, po czym autor wprowadza modyfikacje dokładnie je prezentując. Takie rozwiązanie pozwala łatwiej zrozumieć zamysł autora oraz lepiej przyswoić sobie rozwiązanie. Co ważne, książka była ciekawa (choć w kilku momentach nużąca) co pozwoliło mi w szybkim czasie przebrnąć przez wszystkie strony.

Niestety, nie ma rzeczy idealnych, w książce irytuje mnie częste wykorzystywanie słowa „klienty” (poprawne, ale mnie denerwuje, można by tu chyba użyć bardziej popularnego słowa „klienci”), czasami zdarza się, że bardziej rozbudowane zdania wydają się bez sensu, lub są trudne w zrozumieniu, nie wiem czy jest to problem tłumaczenia, czy może autor używa na tyle specyficznego języka, na szczęście zdarzyło się to dosłownie kilka razy.

Szczerze polecam.

Dnia 13.07.2010

Podstawy bezpieczeństwa PHP – Wyjawienie wersji

P

HP w swojej ofercie posiada jedną opcję oraz dwie funkcje, które stanowią potencjalne zagrożenie w postaci wyjawienia wersji używanego interpretera języka PHP. Ich wyłączenie pozwala na osiągnięcie niższej widoczności serwera dla ataków opierających się na prostych technikach rozpoznawczych, które pozwalają na wykrycie poziomów zagrożeń badanych celów.

Wspomnianą opcją jest expose_php. Standardowo aktywowana pozwala na użycie zjawiska Easter Eggs, które pozwalają na bliższą identyfikację wersji PHP. Na przykład fraza użyta na dowolnym pliku php:

www.strona.pl/index.php?=PHPE9568F36-D428-11d2-A769-00AA001ACF42

Zwraca odpowiedni obraz graficzny, który świadczy o odpowiedniej wersji:

  • Programista PHP z paluszkami chlebowymi w postaci zębów – 4.0.0 – 4.2.3.
  • Jamnik długowłosy na tle zielonej trawy – 4.3.0 – 4.3.10.
  • Czarny, szkocki terrier na białym tle – 4.3.11 – 4.4.6 oraz 5.0.4 – 5.1.2.
  • Królik – 5.0.0 – 5.0.3.
  • Pokolorowane, lekko zniekształcone logo PHP – 5.1.3 – 5.2.13.
  • Niebieski, pluszowy słoń z logiem PHP – 5.3.0.

Innymi możliwymi kombinacjami są:

www.strona.pl/index.php?=PHPE9568F34-D428-11d2-A769-00AA001ACF42
www.strona.pl/index.php?=PHPE9568F35-D428-11d2-A769-00AA001ACF42
www.strona.pl/index.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000

Pierwsza fraza zwraca oryginalne logo PHP, druga logo Zend oraz trzecia listę pod postacią zespołu produkcyjnego PHP. Wyłączenie opcji expose_php, usuwa również z nagłówka HTTP wpis „X-Powered-By” informujący o używanej wersji PHP. Warto również zastanowić się nad wyłączeniem funkcji phpinfo();, która wyświetla dużą ilości informacji na temat aktualnego stanu PHP. Obejmuje to informacje opcji kompilacji PHP i rozszerzeń, wersji PHP (phpversion();), informacji serwera i środowiska (jeśli skompilowano jako moduł), środowiska PHP, informacje o wersji systemu operacyjnego, ścieżek, głównych i lokalnych wartości opcji konfiguracyjnych, nagłówków HTTP, i Licencji PHP. Wyłączenie wyżej wspomnianych komponentów możemy dokonać poprzez plik konfiguracyjny php.ini:

expose_php = Off
disable_functions = phpinfo

Niestety wyłączenie funkcji phpversion(); powoduje błędy lub brak możliwości pracy popularnych systemów CMS, takich jak WordPress czy Joomla, które za pomocą tej funkcji sprawdzają, czy oferowana na serwerze wersja PHP jest zgodna z ich wymaganiami. Jeśli nasza aplikacja nie wykorzystuje tej funkcji, a serwer nie posiada użytkowników korzystających z przytoczonych rozwiązań CMS (ze względu na bogatą gamę tego typu oprogramowania należy sprawdzić zachowanie innych produktów) można ją bezpiecznie wyłączyć poprzez dodanie jej do disable_functions.

Więcej informacji: Zero PHP, Funkcja phpinfo

Dnia 10.07.2010

Wyłączenie KMS dla kart Nvidia w Slackware 13.1

K

ernel-Based Mode Setting (od jądra 2.6.29) umożliwia przełączanie się pomiędzy powłoką graficzną, a konsolą bez potrzeby ustawiania na nowo parametrów układu graficznego oraz rozdzielczości ekranu (serwer X oraz konsola obsługiwana przez KMS muszą używać tej samej rozdzielczości ekranu). KMS standardowo dla kart graficznych firmy Nvidia korzysta z stworzonego za pomocą inżynierii wstecznej sterownika Nouveau.

Mimo dołożenia wielu starań obsługa sprzętu firmy Nvidia z wykorzystaniem otwartoźródłowych sterowników pozostawia wiele do życzenia. Tyczy się to głównie obsługi usypiania i hibernacji, wykrywania poprawnych trybów rozdzielczości, czy wsparcia dla akceleracji 3D. Slackware 13.1, który korzysta z jądra 2.6.33.4 posiada standardowo włączony KMS dla kart Ati, Nvidia oraz Intel. Jeśli z jakiś względów KMS podczas startu systemu powoduje błędy kernel panic, zniekształcenie obrazu grafiki bufora ramki, braki sygnału od GPU lub błędy przy uruchamianiu serwera X można go wyłączyć (bez potrzeby rekompilacji dystrybucyjnego jądra) poprzez dodanie do pliku konfiguracyjnego bootloadera LILO (/etc/lilo.conf) następującego wpisu:

# Linux bootable partition config begins
image = /boot/vmlinuz
  root = /dev/sdX
  label = Linux
  read-only
  append="vdblacklist=nouveau nomodeset"
# Linux bootable partition config ends

Przed dokonaniem zmian w bootloaderze wyłączenie funkcji KMS dla układów Nvidia możemy przetestować poprzez dodanie linii: vdblacklist=nouveau nomodeset do opcji startu jądra.

Więcej informacji: Mode-setting

Dnia 08.07.2010

Ekstremalne środki ostrożności w sieciach publicznych

P

odłączenie przenośnego komputera do nieznanej, publicznej sieci komputerowej wiąże się z ogromnym ryzykiem. Wszystkie wykonywane operacje sieciowe mogą zostać przez kogoś podsłuchane, a nasze dane przechwycone. Zagrożenia mogą jednak zostać zminimalizowane poprzez zastosowanie kompleksowej strategii obronnej.

Artykuł ten został opublikowany w numerze 11/2009 (53) magazynu hakin9.

Artykuł w formacie PDF

Dnia 05.07.2010

Prosty mirror backup via (L)FTP

W

wielu sytuacjach przydaje się prosta kopia zapasowa, która oprócz przechowywania najważniejszych plików – trzyma ich wersję z paru dni oraz jest równolegle przechowywana na innym serwerze w przypadku poważnej awarii oryginalnego źródła. Poniższy skrypt tworzy backup wybranych katalogów – przechowując przez 20 dni ich wcześniejsze wersje oraz tworzy lustrzaną kopię plików z archiwami na serwerze FTP.

#!/bin/bash
export yesterday=`date +%d%m%Y --date='20 day ago'`
export today=`date +%d%m%Y`
if [ -e /chroot/backup/backup$yesterday.bz2 ]
then
        rm /chroot/backup/backup$yesterday.bz2
fi
tar -cvjpf /backup/backup$today.bz2 --same-owner --exclude=/etc/X11 /etc 2> /backup/error.log
lftp serwer-ftp.pl -u login,hasło << EOF
cd backup_router
lcd /backup
mirror -R -e
quit
EOF
unset yesterday
unset today
exit 0

Do poprawnego działania skryptu wymagane są takie programy jak tar, bzip2 oraz lftp. Zmienna yesterday określa ile dni wstecz będą przechowywane kopie katalogu /etc (z wykluczeniem /etc/X11) w katalogu /backup. Narzędzie lftp dzięki wykorzystaniu przeciwnego działania (-R) polecenia mirror umieszcza całą zawartość katalogu /backup na zdalnym serwerze serwer-ftp.pl w katalogu backup_router. Ze względu na przechowywanie w skrypcie danych autoryzacyjnych do serwera FTP należy nadać mu odpowiednie prawa dostępu:

chmod 700 backup.sh

Sam skrypt z powodu braku szyfrowania transmisji powinien być stosowany w sieciach wewnętrznych. Jeśli zależy nam na kopii przyrostowej, a nie jeden do jednego – należy usunąć parametr -e przy poleceniu mirror.

Więcej informacji: Kopia bezpieczeństwa, LFTP

Dnia 29.06.2010

Tęczowe tablice – przyśpiesz atak brute-force

T

ęczowe tablice pozwalają przyspieszyć ataki brute-force eliminując potrzebę wykonywania w każdym kolejnym ataku tych samych obliczeń poprzez zapamiętanie części kluczowych danych. Tablice znalezione w Internecie bywają jednak niekompletne lub płatne, dlatego zobaczymy jak je zrobić samemu.

Artykuł ten został opublikowany w numerze 12/2009 (54) magazynu hakin9.

Artykuł w formacie PDF

Dnia 19.06.2010

Free Technology Academy – Materiały

W

ramach strony Akademii FTA (ang. Free Technology Academy), która umożliwia m.in. studiowanie Open Source i otwartych standardów zostały udostępnione wszystkie materiały dydaktyczne z zakresu oferowanych kursów. FTA jest projektem stworzonym w 2008 roku przez The Free Knowledge Institute (FKI) przy współpracy z trzema europejskimi uniwersytetami: Open Universiteit (Holandia), Universitat Oberta de Catalunya (Hiszpania) oraz University of Agder (Norwegia). Projekt jest wspierany również przez Unię Europejską w ramach programu Lifelong Learning Programme (LLP).

Wszystkie materiały dostępne są na oficjalnej stronie FTA. Można pobrać je z pomocą protokołu torrent lub w formacie pdf. Na szczególną uwagę zasługuje 545′cio stronicowy podręcznik GNU/Linux Advanced Administration.

Dnia 12.06.2010

Daj Lemowi kopa w górę

Tak jak zwykle nie trawię akcji w rodzaju „zagłosuj na Iksa w ynternetowym sondażu”, tak akurat w tym przypadku czuję się w obowiązku zwrócenia uwagi pleno titulo Czytelników na chwalebną akcję wystrzelenia Lema na orbitę. No bo przecież nie Polonia Aquila, brrrr….

Lem w kosmosie, na plakacie

Dnia 10.06.2010

Zdalne łamanie haseł

P

okładanie nadziei w matematycznych gwarancjach bezpieczeństwa algorytmów szyfrujących i zabezpieczających dane to czysta naiwność. Każde hasło, każde zabezpieczenie można złamać… lub obejść. Niezmiennie najsłabsze ogniwo stanowi czynnik ludzki.

Artykuł ten został opublikowany w numerze 03/2009 (46) magazynu hakin9.

Artykuł w formacie PDF

Dnia 07.06.2010

MySQL – wyłączenie LOAD DATA LOCAL INFILE

W

yrażenie LOAD DATA LOCAL INFILE przy standardowej konfiguracji serwera MySQL potrafi wczytać do wcześniej spreparowanej tabeli dowolny plik z serwera posiadający globalne uprawnienia do odczytu. W celu skorzystania z tej możliwości wystarczy wskazać pełną ścieżkę do pliku, który musi znajdować się na tym samym serwerze, co oprogramowanie MySQL. Z powodzeniem wyrażenie to może zostać wykorzystane w jednej z technik SQL Injection (np. gdy w aplikacji webowej zostanie wykryta nowa luka) do odczytu wrażliwych z poziomu bezpieczeństwa plików konfiguracyjnych serwera i aplikacji lub wczytaniu plików konfiguracyjnych innych aplikacji na współdzielonym hostingu.

Na przykład w celu wczytania ogólnodostępnego pliku /etc/passwd zawierającego listę użytkowników systemu do tabeli shellusers wystarczy wykonać polecenia w bazie MySQL:

mysql> CREATE TABLE `shellusers` (`shellusers` VARCHAR(255));
Query OK, 0 rows affected (0.01 sec)

mysql> LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE `shellusers`;
Query OK, 29 rows affected (0.00 sec)
Records: 29  Deleted: 0  Skipped: 0  Warnings: 0

mysql> SELECT * FROM shellusers;
+------------------------------------------------------------------------------+
| shellusers                                                                   |
+------------------------------------------------------------------------------+
| root:x:0:0:root:/root:/bin/bash                                              |
| daemon:x:1:1:daemon:/usr/sbin:/bin/sh                                        |
| bin:x:2:2:bin:/bin:/bin/sh                                                   |
| (...)                                                                        |
+------------------------------------------------------------------------------+
29 rows in set (0.00 sec)

W ten sposób znając pełną ścieżkę np. do pliku konfiguracyjnego systemu WordPress (wp-config.php) innego konta na współdzielonym serwerze hostingowym możemy uzyskać pełne dane autoryzacyjne do bazy danych tego konta. Daje nam to również możliwość odczytywania plików konfiguracyjnych serwera mimo braku dostępu do jego powłoki poleceń. W celu wyłączenia możliwości użycia polecenia „LOCAL INFILE” przez wszystkich użytkowników wystarczy dodać następujący parametr w sekcji [mysqld] pliku konfiguracyjnego serwera MySQL:

set-variable=local-infile=0

Wówczas przy próbie wywołania w/w składni użytkownik otrzyma następujący komunikat:

mysql> LOAD DATA LOCAL INFILE '/etc/passwd' INTO TABLE `shellusers`;
ERROR 1148 (42000): The used command is not allowed with this MySQL version

Więcej informacji: Security Issues with LOAD DATA LOCAL

Dnia 04.06.2010

GuruPlug – krótkie info + instalacja na dysku USB

Idealnie 1 czerwca dostałem paczkę zawierającą komputer GuruPlug. Czym jest GuruPlug? Jest to mały (9,5×6,3×4,5cm) komputer posiadający 1.2Ghz procesor i 512MB RAM oraz 2 porty USB, 1Gb ethernet, wifi i bluetooth (istnieją jeszcze 2 wersje Server Plus oraz Display różniące się wyjściami). Zakupiłem to urządzenie bo potrzebowałem małego i cichego (bez wentylatorów) urządzenia które spełniać będzie rolę NFS-a, repozytorium GIT oraz serwera testowego dla aplikacji napisanych w języku Ruby.
Ponieważ urządzenie zamówiłem w formie przed sprzedażowej dostałem również tzw. JTag który jest wymagany aby połączyć się z GP poprzez serial port. Jedynym mankamentem jaki zauważyłem dotychczas jest mała ilość miejsca w pamięci NAND (pamięć masowa 512MB, na której jest już zainstalowany Debian lenny), przez co musimy uważać co instalujemy. Rozwiązaniem jest zainstalowanie systemu na zewnętrznym dysku twardym co daje nam dodatkową korzyść w postaci przyśpieszenia działania systemu (pamięć NAND wydaje się tu dość wolna). Niestety instalacja systemu nie należy do najłatwiejszych i jak napisałem wcześniej wymaga dodatkowego urządzenia w postaci JTaga.

Instalacja

Podczas instalowania korzystałem z 3 instrukcji oraz własnych eksperymentów. Wszystko składa się na kilka kroków (linki na końcu wpisu). W moim wypadku użyłem dysku zewnętrznego Seagate® Expansion™ o rozmiarze 1TB.

1) Aktualizujemy UBoot w urządzeniu korzystając z instrukcji pod linkiem nr 4.

2) Przygotowujemy instalator oraz instalujemy system korzystając z instrukcji pod adresem nr 2.

Uwagi:

a) W kroku Running the installer prócz stworzenia obrazu musiałem również stworzyć dodatkowych użytkowników, gdyż sam instalator pomimo użycia odpowiednich opcji nie zrobił tego

b) trzeba zapamiętać pod jakimi nazwami są nasze partycje, u mnie było to odpowiedni /dev/sda1 dla /boot oraz /dev/sda6 dla /

c) nie trzeba wysyłać stworzonych obrazów na zewnętrzny serwer.

d) Ponieważ jest to instalacja dla kart SD nie wykonujemy ostatniego kroku „Make the plug bootable

3) Po zainstalowaniu systemu, przygotowaniu obrazów startowych oraz dodaniu użytkowników, zrestartowałem urządzenie i przeszedłem do Uboot-a gdzie trzeba było skonfigurować start systemu co jest opisane pod linkiem 3, ponieważ system miał startować z dysku usb należy najpierw znaleźć urządzenia, potem załadować obrazy, wskazać punkt montowania dla root a potem wystartować system, w moim wypadku polecenia ustawiające opcje startu wyglądały nastepująco:


setenv bootargs_console 'root=/dev/sda6 console=ttyS0,115200'
setenv bootcmd_usb 'usb start; ext2load usb 0:1 0x01100000 /uInitrd; ext2load usb 0:1 0x00800000 /uImage;'
setenv bootcmd 'setenv bootargs $(bootargs_console);run bootcmd_usb; bootm 0x00800000 0x01100000; reset'
saveenv

Uwaga!

Przed ostatnia linia zawiera polecenie reset które notabene powoduje zresetowanie/reboot całego urządzenia, jednak w tym wypadku polecenie to zostanie wykonane tylko i wyłącznie jeśli nie uda się boot-owanie systemu, jest to miejmy nadzieję tylko tymczasowe rozwiązanie do problemu który polega na losowym (co drugi raz) niewykrywaniu dysku USB więc jeśli dysk nie zostanie wykryty robimy reset i wykrywamy podobnie i tak w kółko aż zaskoczy.

4) Wykonujemy polecenie reset i startujemy system, powinno to potrwać ok minuty.

Co zauważyłem po kilku dniach używania:

1) Wiele osób narzeka na wysoką temperaturę swojego urządzenia (głównie wersja rozszerzona Server Plus), jakkolwiek nie mam termometru by to sprawdzić wygląda na to, że moje urządzenie jest wolne od wad, jest ciepłe, ale bez przesady, można dotykać, przytulać się, co kto lubi.

2) Instalacja na zewnętrznym dysku pomimo tego, że jest kłopotliwa drastycznie zwiększa wydajność całego systemu

3) Pozainstalowaniu Nginx-a, bazy PosgreSQL, mt-daap (strumieniowanie audio), mediatomb (serwer multimedialny dla mojej PS3), repozytorium git-a (+ gitosis) mam jeszcze dużo pamięci ram, wystarczy na tomcata i jeszcze nawet zostanie.

4) Port gigabitowy nie działa, podłączając kabel sieci 1Gb urządzenie się resetuje, na szczęście mam router 100Mb więc nie ma problemu

Zdjęcia nie będzie, bo GuruPlug wylądował pod łóżkiem i ciężko się do niego dostać.

Urządzenie GuruPlug JTag

Urządzenie GuruPlug JTag


Linki

1) Jeśli uda wam się coś zepsuć (programowo) w waszym GuruPlugu polecam stronę:
http://plugcomputer.org/plugwiki/index.php/Reflashing_images_on_the_GuruPlug

2) Instalacja Debiana na urządzeniu Guruplug (karta SD):
http://bzed.de/posts/2010/05/installing_debian_on_the_guruplug_server_plus/

3) Instalacja Debiana na urządzeniu Shevaplug (dysk USB):
http://www.cyrius.com/debian/kirkwood/sheevaplug/install.html

4) Aktualizacja Uboot
http://www.cyrius.com/debian/kirkwood/sheevaplug/uboot-upgrade.html

Dnia 29.05.2010

Port knocking

Z

abezpieczenie sieci komputerowych przed niepowołanym dostępem z zewnątrz to temat bardzo rozległy i pełen rozmaitych koncepcji, z których niektóre wzajemnie się wykluczają. Są też rozwiązania uniwersalne, a – co więcej – beznakładkowe, które pozwalają utrudnić nieuprawniony dostęp. Zalicza się do nich Port knocking.

Artykuł ten został opublikowany w numerze 03/2009 (46) magazynu hakin9.

Artykuł w formacie PDF

Zapomniany klawisz SysRq

J

eśli pracujemy na developerskiej maszynie nad rozwojem jądra systemu lub sterowników urządzeń wspieranych przez jądro, lub nawet uruchamiamy testowy kod, który prawdopodobnie spowoduje tzw. błąd kernel panic – możemy wykorzystać poniżej przedstawione rozwiązanie, które przydaje się w przypadkach kiedy nasza maszyna z jakieś przyczyny zawiesza się, zamieniając się w nagromadzony stos części komputerowych (sposób ten jest bezużyteczny, gdy jądro zupełnie zamknie się na świat, pozostaje wówczas tylko twardy reset). Poprzez kombinację odpowiednich klawiszy możemy przeprowadzić synchronizację systemu plików oraz przemontować go w tryb tylko do odczytu. W ten sposób poprzez restart komputera unikniemy utraty danych oraz sesji programu fsck.

Do poprawnego zadziałania wspomnianego sposobu, niezbędne jest wkompilowanie w jądro systemu (opcja ta jest zaimplementowana od wersji 2.1.x i wyższych) funkcji „Magic SysRq key” (CONFIG_MAGIC_SYSRQ) – znajduje się ona w sekcji „Kernel hacking” (Kernel debugging). Po uruchomieniu systemu z jądrem obsługującym SysRq key, sprawdzamy, czy dodana przez nas funkcja jest standardowo włączona:

cat /proc/sys/kernel/sysrq

Jeśli powyższe polecenie zwróci nam wartość „0″, pozostaje ręczne włączenie obsługi klawisza SysRq np. poprzez dodanie do /etc/rc.d/rc.local wpisu:

echo -e "Włączam funkcję klawisza SysRq\n"
echo "1" > /proc/sys/kernel/sysrq

Dla innych dystrybucji korzystających z mechanizmu sysctl do pliku /etc/sysctl.conf należy dodać wpis:

kernel.sysrq = 1

Po aktywowaniu funkcji Magic SysRq key podczas nagłych awarii pracy systemu jesteśmy już w stanie używać kombinacji klawiszy umożliwiających nam jego uratowanie w przypadku zawieszenia. Kombinacje klawiszy używanych na każdej z platform komputerowych są trochę inne, i tak dla poszczególnych platform są to:

x86 - ALT+PrtSc+[klawisz komendy]
Laptopy - Alt+(Fn+PrtSc)+[klawisz komendy]
SPARC - ALT+STOP+[klawisz komendy]
Konsola szeregowa - ALT+Break+[klawisz komendy]
PowerPC - ALT+PrtSc (lub F13)+[klawisz komendy]
Na wszystkich - komenda: echo t > /proc/sysrq-trigger

Klawiszem SysRq w komputerach PC o architekturze x86 jest klawisz „Print Screen” (na niektórych klawiaturach widnieje podwójna etykieta: PrtSc oraz SysRq). SysRq jest klawiszem, którego obsługi w systemie Linux nie może przejąć żaden inny proces. Każde jego aktywowanie (a jest wywoływany poprzez jednoczesne przytrzymanie klawiszy ALT i PrtSc) jest przetwarzane na poziomie jądra. Użyty razem z innymi kombinacjami daje następujące efekty:

  • Alt+PrtScr+R (R’aw) – wyłącza tryb RAW klawiatury, przełączając go na XLATE. Wyłączenie trybu RAW jest bardzo pomocne, gdy serwer X lub svgalib się zawiesi. W ten sposób jesteśmy w stanie przesłać sygnał z kombinacji klawiszy Crtl+Alt+Del podczas zawieszonej sesji X.
  • Alt+PrtScr+K (sa’K) – Secure Access Key (SAK) – zabija wszystkie programy w aktualnej konsoli wirtualnej. Szczególnie przydatna kombinacja, gdy chcemy się upewnić, że na konsoli nie działa żaden koń trojański, który mógłby przechwycić nasze hasło podczas próby zalogowania się do systemu. Kombinacja ta zabije wszystkie programy na danej konsoli upewniając, że znak zachęty logowania do systemu będzie pochodził z programu uruchamianego z pozycji wpisu programu init. Innym wykorzystaniem tej kombinacji jest – System Attention Key – klawisz zwrócenia uwagi systemu, który używany jest podczas wyjścia z programu, który nie pozwala na przełączanie się między konsolami, np. ostateczne wyłączenie sesji X Window, gdy kombinacja klawiszy Ctrl+Alt+Backspace nie przynosi pożądanego efektu.
  • Alt+PrtScr+B (re’B'oot) – spowoduje natychmiastowe zresetowanie komputera, bez synchronizacji oraz odmontowania dysków. Kombinacja przydatna w przypadku, kiedy nie możemy dokonać zamknięcia systemu. Lecz przed jej użyciem należy skorzystać z klawiszy komend: S oraz U – bez tego grozi to uszkodzeniem systemu plików – ponieważ efekt tej kombinacji jest taki sam jak naciśnięci przycisku RESET na obudowie komputera.
  • Alt+PrtScr+O – (shut d’O'wn) – jeśli funkcja ta jest obsługiwana oraz skonfigurowania nastąpi wyłączenie systemu.
  • Alt+PrtScr+S – (‘S’ync) – spróbuje przeprowadzić synchronizację oraz odmontowanie wszystkich systemów plików. Bardzo dobra opcja, gdy system zamkną się w sobie, która pozwala na synchronizację dysków oraz uniknięcie utraty danych oraz sesji programu fsck. Podczas używania tej opcji należy zwrócić uwagę na ukazanie się komunikatu: „OK” lub „Done” po poprawnym przeprowadzeniu procesu, ponieważ w wypadku, gdy jądro zaliczyło nieskończoną pętle myśli komunikat taki może wcale się nie ukazać.
  • Alt+PrtScr+U (‘U’mount ) – spróbuje przemontować wszystkie zamontowane systemy plików w tryb tylko do odczytu. Kombinacja ta jest użyteczna w tych samych warunkach jak ‘S’ync. Tak samo jak w kombinacji powyżej należy poczekać na ukazanie się komunikatu: „OK” lub „Done”.
  • Alt+PrtScr+P (‘P’rint) – wyświetla aktualny stan rejestrów i flag procesora. Głównie przydatne podczas debugowaniu jądra systemu.
  • Alt+PrtScr+T (‘T’asks) – wyświetla listę aktualnych zadań systemowych oraz informacji o nich na konsolę.
  • Alt+PrtScr+M (‘M’emory) – wyświetla na konsoli informacje na temat pamięci.
  • Alt+PrtScr+V (‘V’oyager) – wyświetla informacje na temat architektury przetwarzania symetrycznego Voyager SMP na konsoli. Architektura Voyager SMP została zaprojektowana przez NCR w środku lat 80′tych, która miała być architekturą przetwarzania symetrycznego umieszczoną w chipsetach 486 Intela. Voyager został stworzony w trzech poziomach sofistyki architektonicznej: 3,4 oraz 5 – 1 i 2 nigdy nie wydostały się z prototypu. Patche na Linuksa obsługują tylko piąty poziom architektury Voyagera.
  • Alt+PrtScr+0 do 9 – ustawia poziom logowania na konsoli – kontrolując jakie komunikaty mają się pojawiać na konsoli (dla przykładu ’0′ spowoduje wyświetlanie tylko wiadomości krytycznych pochodzących od jądra systemu). Bardzo przydatna opcja, gdy nasza konsola jest zalewana wiadomościami, których nie potrzebujemy lub nie chcemy. Ustawienie np. 0 poziomu spowoduje, że tylko bardzo ważne komunikaty będą ukazywane na konsoli (nadal będą logowane przez syslogd / klogd – jeśli tylko te będą jeszcze żywe).
  • Alt+PrtScr+E (t’E'rm) – wysyła sygnał TERM do wszystkich procesów, oprócz init, prosząc o ich samounicestwienie. Przydatna kombinacja w przypadku, gdy jakiś proces wymknie się nam spod kontroli i nie daje się zamknąć w dodatku powodując rozradzanie się innych procesów.
  • Alt+PrtScr+I (k’I'll) – wysyła sygnał KILL do wszystkich procesów, oprócz init, wymuszając ich zabicie. Analogicznie jak w przypadku kombinacji z klawiszem „E”.
  • Alt+PrtScr+L (kil’L') – wysyła sygnał KILL do wszystkich procesów, włączając w to init (po tej kombinacji system staje się niefunkcjonalny).
  • Alt+PrtScr+H (‘H’elp) – wyświetla ekran pomocy.

Jeśli z jakieś przyczyny kombinacja SysRq nam nie działa, prawdopodobnie jest to spowodowane tym, że niektóre klawiatury wysyłają różne skankody, niż wcześniej zdefiniowany kod 0×54. Aktualny kod klawisza SysRq możemy sprawdzić za pomocą polecenia:

cat /proc/sys/kernel/sysrq-key

Zazwyczaj powinna zostać zwrócona wartość 84. W tym przypadku należy uruchomić program: „showkey -s” w celu wyszukania prawidłowej sekwencji skankodu. Następnie należy uruchomić program: „setkeycodes [sekwencja] 84” w celu zdefiniowania sekwencji dla zwyczajnego kodu SysRq (84 jest liczbą dziesiętną dla 0×54). Jeśli przedefiniowanie zadziała, najlepiej umieścić je w jakimś skrypcie startującym (z programu showkey wychodzi się poprzez nie pisanie czegokolwiek przez dziesięć sekund).

Przykładowe skankody dla klawiatury AT:

F1 F2    `  1  2  3  4  5  6  7  8  9  0  -  =  \ BS   ESC NUML SCRL SYSR
-----   ---------------------------------------------  ------------------
05 06   0E 16 1E 26 25 2E 36 3D 3E 46 45 4E 55 5D 66    76  77   7E   84

F3 F4   TAB   Q  W  E  R  T  Y  U  I  O  P  [  ]       Home Up  PgUp PrtSc
-----   -----------------------------------------      -------------------
04 0C    0D  15 1D 24 2D 2C 35 3C 43 44 4D 54 5B        6C  75   7D   7C

F5 F6   CNTL   A  S  D  F  G  H  J  K  L  ;  ' ENTER   Left  5  Right  -
-----   --------------------------------------------   ------------------
03 0B    14   1C 1B 23 28 34 33 38 42 4B 4C 52   5A     6B  73   74   7B

F7 F8   LSHFT    Z  X  C  V  B  N  M  ,  .  /  RSHFT   End  Dn  PgDn   +
-----   --------------------------------------------   ------------------
83 0A     12    1A 22 21 2A 32 31 3A 41 49 4A   59      69  72   7A   79

F9 F10  ALT                  SPC             CAPLOCK   Ins      Del
------  --------------------------------------------   -------------
01 09    11                   29               58       70       71

W przypadku, gdy nasza maszyna się zawiesi, a kombinacja Ctrl+Alt+Del (w trybie tekstowym dla sesji X Window jest to: Ctrl+Alt+Backspace) nie działa – najlepiej jest zabić wszystkie procesy na aktualnej konsoli kombinacją: Alt+PrtSc+K (w przypadku paranoicznego zachowania możemy używać tej kombinacji przed każdym logowaniem się do systemu), a następnie przeprowadzić bezpieczny restart komputera poprzez kolejno wydane kombinacje: R]aising E]lephants I]s S]o U]tterly B]onkers – powodująca kolejno wyłączenie klawiatury z czystego trybu, zakończenia wszystkich procesów za pomocą sygnału SIGTERM (oprócz init o PID 1), zabicia wszystkich procesów za pomocą sygnału SIGKILL (także oprócz init), zsynchronizowanie dysków, przemontowanie wszystkich systemów plików w tryb tylko do odczytu oraz ponowne uruchomienie komputera. Możemy również „skleić” klawisze Alt oraz SysRq za pomocą polecenia:

echo 1 > sysrq-sticky

Spowoduje to, odczytywanie całych kombinacji za pomocą pojedynczych klawiszy np. wówczas będzie wymagane wpisanie jedynie na klawiaturze słowa: reisub. Niestety, aby skorzystać z tej możliwości musimy posiadać możliwość przesłania za pomocą polecenia echo odpowiedniej wartości, co w przypadku zawieszenia się systemu bardzo często może być niemożliwe. Drugim sposobem, jeśli nie posiadamy bezpośredniego dostępu do klawiatury serwera lub terminala możemy wykorzystać system plików procfs do wykonania powyższych komend. Wystarczy, że przekażemy charakterystyczną końcową LITERĘ do /proc/sysrq-trigger:

echo o > /proc/sysrq-trigger

To jest równoznaczne wciśnięciem kombinacji klawiszy Alt+SysRq+o, która wyłącza komputer. Podobnie jak w przypadku kombinacji klawiszy Alt+Ctrl+Del, należy mieć również na uwadze względy bezpieczeństwa, ponieważ rozwiązanie to daje niebezpieczne możliwości manipulacji systemem każdemu, kto ma fizyczny dostęp do klawiatury lub konsoli serwera. Dlatego w środowiskach produkcyjnych klawisz SysRq powinien zostać wyłączony:

echo 0 > /proc/sys/kernel/sysrq

lub, co najmniej ograniczony do wybranego działania poprzez odpowiednie wartości np.:

echo 2 > /proc/sys/kernel/sysrq

Włącza jedynie kontrolę poziomu wyświetlania komunikatów na konsoli. Innymi dostępnymi wartościami są: 4, 8, 16, 32, 64, 128 oraz 256.

Więcej informacji: man showkey, loadkeys, /usr/src/kernel/linux/Documentation/sysrq.txt

Dnia 25.05.2010

Clickjacking – groźny link

A

rtykuł ten pokaże nową technikę web ataku. Pokazany został sposób, jak prosto można ukraść kliknięcia z witryny. Opis tej techniki pomoże zrozumieć proces sam w sobie oraz zaprezentuje problemy z zabezpieczaniem się przed tego typu atakiem.

Artykuł ten został opublikowany w numerze 07-08/2009 (50) magazynu hakin9.

Artykuł w formacie PDF

Dnia 24.05.2010

Something of a dreamer

Hello. My name is Stephen Hawking, physicist, cosmologist and something of a dreamer. Although I cannot move and I have to speak through a computer, in my mind I am free.

Znajduję pocieszającym, że człowieka zredukowanego do li tylko mózgu może szanować cały świat (w takiej Japonii na przykład popadają nawet czasami w lekką paranoję[1]). Świadczy to całkiem nieźle o cywilizacji śmierci. W dużej mierze to właśnie dzięki Hawkingowi wiemy co nieco na temat czarnych dziur, ale warto pamiętać, że to także świetny popularyzator nauki jest (o czym kiedyś już pisałem).

Najnowszym pomysłem na tą popularyzację jest wspólne przedsięwzięcie z Discovery Channel. Przedsięwzięciu dano wszystkomówiący tytuł „Into the Universe with Stephen Hawking” i podzielono na trzy odcinki. Całość jest genialna, co w przypadku Discovery nie zdarza się za często.

Kadr w filmu

Część pierwsza, „Aliens”. Dowiemy się co jest potrzebne do życia, gdzie znajdziemy odpowiednie składniki, że niekoniecznie muszą być takie, jak na Ziemi. Że życie nie musi wyglądać podobnie, choć nie powinno też różnić się w jakiś dziki, wyjęty ze space opery sposób. Usłyszymy, że Hawking w wizyty UFO nie wierzy i przy okazji poznamy historię „Sygnału Wow!”. To tutaj właśnie pada opinia, która ostatnio narobiła nieco zamieszania – że nie powinniśmy aktywnie szukać Obcych, bo mogą zrobić nam krzywdę. Lepiej poczekać aż znajdą nas sami.

So if aliens ever visit us, I think the outcome would be much as when Christopher Columbus first landed in America, which did not turn out very well for native Americans.

Odpór Hawkingowi dał, między innymi, mój drugi ulubiony astrofizyk:

Seth Shostak oczywiście też poczuł się wywołany do tablicy.

Stephen Hawking

Część druga cyklu nosi tytuł „Time Travel”. Dowiemy się w niej, że podróże w czasie są możliwe, choć tylko w przyszłość, bo Wszechświat uniemożliwia paradoksy w rodzaju zabicia samego siebie w przeszłości. Poznamy dwa sposoby na odbycie takiej podróży, oba w tej chwili niemożliwe do przeprowadzenia ze względu na niemowlęcy charakter naszej technologii. Niejako przy okazji przekonamy się, że zegarki nie zawsze muszą działać tak samo na Ziemi, jak na jej orbicie.
Stephen Hawking

„The Story of Everything”, czyli część trzecia, to prawdziwe opus magnum. Dwukrotnie dłuższa od poprzednich odcinków (półtorej godziny; poprzednie po jakieś 45 minut) opowiada o tym, co Hawkinga zajmuje teraz chyba najbardziej. Mamy początek i koniec Wszechświata (ze znakomitym wykładem na temat „jak to wszystko powstało”), anatomię czarnej dziury, mamy wszelkie sposoby, na jakie może zakończyć się życie na Ziemi, mamy wreszcie motyw wyjścia w kosmos i zasiedlania innych planet. Hawking jest stanowczym zwolennikiem aktywnej eksploracji kosmosu, eksploracji nastawionej na poszukiwanie nowej Ziemi. Mówił o tym już wcześniej, choćby w odczycie z okazji pięćdziesięciolecia NASA.

Musicie wybaczyć, że o poszczególnych odcinkach opowiadam w kilku zdaniach, choć o każdym z nich dałoby się napisać sporą blogonotkę. Powód jest prosty: nie chcę psuć apetytu, chcę go rozbudzać. Realizacja całości jest technicznie bezbłędna, większość z tych trzech godzin programu to znakomite komputerowe wizualizacje, nigdy chyba na taką skalę nie praktykowane w telewizji. Chociaż cały czas obracamy się w kręgu skomplikowanych problemów z pogranicza fizyki i astronomii, ani przez chwilę nie ma szans na zagubienie się w tym wszystkim. Hawking jest mistrzem w konstruowaniu przykładów w banalny sposób tłumaczących najbardziej zawiłe teorie. Gdy zobaczycie na przykład jak rozbiegają się metalowe kulki na podłodze jadalni Uniwersytetu w Cambridge, od razu pojmiecie jak przebiegało formowanie się materii we wczesnym Wszechświecie – absolutne edukacyjne mistrzostwo świata. Całość jest przysiadalna dla każdego, ja sam zamierzam obejrzeć to jeszcze raz, ze swoimi sześcioletnimi dziećmi, gdy tylko program trafi do polskojęzycznej edycji Discovery[2]. Przy okazji uważam, że Ministerstwo Edukacji powinno kupić prawa do tej serii i puszczać je na lekcjach fizyki. Opad szczęk u dzieciarni gwarantowany.

***

HORACJO
Na Boga, to są niepojęte dziwy!

HAMLET
Przyjmij je zatem i nie próbuj pojąć.
Więcej jest rzeczy w niebie i na ziemi,
Niż się wydaje naszym filozofom,
Drogi Horacjo.

Hawking to anty-Hamlet, przynajmniej do pewnego stopnia. Nie wiem zresztą czy i sam królewicz duński nie zmieniłby zdania, gdyby dowiedział się, że człowiek może zajrzeć w okolice czarnej dziury i cofnąć się w czasie o 13,7 miliarda lat nie ruszając się zza biurka – głównie dlatego, że nie może. Myślę, że wzruszyłby się głęboko na myśl o tym czego dokonać może ludzki umysł, gdy tylko zechce zachwycić się rozgwieżdżonym niebem i nie będzie czuł respektu przed żadną tajemnicą. Pewnie mógłby przywołać wtedy Horacja, wskazać na niepozorną, skuloną w fotelu postać i powiedzieć: Ecce homo.

Stephen Hawking


Przypisy:

  1. When I gave a lecture in Japan, I was asked not to mention the possible re-collapse of the universe, because it might affect the stock market., gdyby się komuś nie chciało szukać. []
  2. co miejmy nadzieję nastąpi jakoś jesienią []

Dnia 23.05.2010

Podstawy bezpieczeństwa PHP – Full Path Disclosure

F

ull Path Disclosure (FPD) – polega na ujawnieniu pełnej ścieżki dostępu (np. /var/www/test.php) do wadliwie skonstruowanego lub źle wywołanego skryptu. Błąd FPD najczęściej wywoływany jest poprzez wstrzykiwanie nieoczekiwanych i niefiltrowanych znaków oraz poleceń do parametrów skryptów na stronie internetowej. Skrypt, który przyjmuje określone parametry po wstrzyknięciu nieoczekiwanego znaku zwraca komunikat błędu, w którym zawarte są informacje na temat napotkanego błędu oraz pełna ścieżka dostępu do wywołanego skryptu.

Luki tego typu klasyfikowane są generalnie jako niskiego lub średniego zagrożenia, jednak mogą zostać wykorzystane pośrednio jako środki do przeprowadzania innych znacznie groźniejszych ataków np. Local File Include, czy SQL Injection z wykorzystaniem funkcji MySQL load_file(). FPD bazuje głównie na publicznym wyświetlaniu błędów programistycznych, gdzie powinny być one dostępne tylko dla oczu webdeveloperów i tylko w środowiskach testowych, a nie produkcyjnych. Na przykład wywołanie strony:

www.nfsec.pl/index.php?strona=startowa

W zmodyfikowanej wersji:

www.nfsec.pl/index.php?strona[]=startowa

Może doprowadzić do wyświetlenia komunikatu błędu w przeglądarce każdego odwiedzającego użytkownika:

Warning: opendir(Array): failed to open dir: No such file or directory in /var/www/index.php on line 84

Jedną z metod generowania błędów w źle skonstruowanych skryptach jest nie przekazanie im żadnych parametrów. Skrypt zamiast zwrócić wcześniej zdefiniowany przez programistę komunikat o jego braku od razu generuje błąd. Niestety na pierwszym miejscu w tego rodzaju atakach zawsze dominuje brak walidacji wprowadzanych danych. Przykładem braku walidacji może być tutaj masowe użycie funkcji add_action(), w platformie Wordpress (<= 2.9.2) bez jej sprawdzenia za pomocą funkcji function_exists():

www.blog.wordpress.org/wp-includes/kses.php

Zwróci błąd:

Fatal error: Call to undefined function add_action() in /var/strona/wp-includes/kses.php  on line 1196

Inną popularną i bardzo skuteczną metodą generowania błędów FPD jest przekazanie zerowej sesji PHP za pomocą wstrzyknięcia kodu Javascript. Obsługę sesji PHP możemy wychwycić za pomocą dodatku do przeglądarki Firefox LiveHTTPHeaders lub po prostu używając dość oldschoolowego narzędzia telnet łącząc się z wybranym serwerem na porcie 80 i za pomocą nagłówka HTTP zażądać treści strony. W przypadku Firefoksa w nagłówku HTTP powinniśmy wychwycić:

Set-Cookie: PHPSESSID=nkunm0leo0mnb2pgmj9kkvcsk5; path=/

Od strony sesji nawiązanej za pomocą programu telnet wygląda to następująco:

nfsec~$ telnet virtualnyhost.pl 80
Trying 1.2.3.4...
Connected to virtualnyhost.pl.
Escape character is '^]'.
GET / HTTP/1.1
Host: virtualnyhost.pl

HTTP/1.1 200 OK
Server: Apache
Content-Type: text/html
Keep-Alive: timeout=20
Set-Cookie: PHPSESSID=7ov981080nbelcpvccvii2gro2; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 1
Date: Sun, 23 May 2010 17:07:52 GMT
Connection: keep-alive

Bardzo prostym sposobem jest również użycie kodu Javascript w pasku adresu przeglądarki do wyświetlenia zawartości ciasteczka:

javascript:alert(document.cookie);

Jeśli obsługa sesji PHP jest włączona możemy przejść do kroku wstrzyknięcia zerowej sesji:

javascript:void(document.cookie="PHPSESSID=");

lub

javascript:alert(document.cookie="PHPSESSID=");

Następnie wystarczy przeładować stronę, aby zobaczyć komunikat następującej treści:

Warning: session_start() [function.session-start]: The session id contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in /var/www/virtualnyhost.pl/www/index.php on line 2

Wszystkie powyższe czynności możemy wykonać również za pomocą pojedynczej sesji telnet:

nfsec~$ telnet virtualnyhost.pl
Trying 1.2.3.4...
Connected to nfsec.pl.
Escape character is '^]'.
GET / HTTP/1.1
Host: virtualnyhost.pl
Cookie: PHPSESSID=SHOWMEYOURSISHOWYOUMY

HTTP/1.1 200 OK
Cache-Control: max-age=172800
Expires: Tue, 25 May 2010 17:30:26 GMT
Vary: Accept-Encoding
Content-Type: text/html
Content-Length: 997
Server: Apache
Date: Sun, 23 May 2010 17:30:26 GMT
Connection: keep-alive

Warning: session_start() [function.session-start]: The session id contains (...)

Obrona przed ujawnianiem pełnej ścieżki dostępu jest najprostszym procesem spośród wszystkich błędów w aplikacjach napisanych w języku PHP, gdyż sprowadza się do wyłączenia raportowania błędów i przekierowaniu ich do zdefiniowanego pliku z logami. Możemy wykonać to za pomocą głównego pliku konfiguracyjnego php.ini:

error_reporting = E_ALL & ~E_NOTICE
display_errors = Off
log_errors = On
error_log = /var/log/php/php.log

Jeśli nie posiadamy dostępu do plików konfiguracyjnych PHP np. ze względu na używanie wirtualnego hostingu, a nasz usługodawca używa serwera Apache do obsługi stron, raportowanie błędów możemy wyłączyć za pomocą pliku .htaccess:

php_flag  display_errors  off

Lub z poziomu samej aplikacji PHP:

ini_set('display_errors', false);

Full path disclosure jest głównie używane podczas technik rozpoznawania celu ze wstępnym zamiarem jego ataku. Jako półśrodek może doprowadzić do udanego ataku za pomocą innej techniki, dlatego tego rodzaju luka w podstawowej konfiguracji interpretera PHP nie powinna zostać przeoczona.

Więcej informacji: HTTP, OWASP, Hakipedia

Dnia 22.05.2010

Zacieranie śladów po włamaniu

D

la crackera włamującego się do cudzego systemu informatycznego najważniejsze jest… skuteczne zatarcie śladów po całej operacji. Nawet najbardziej spektakularne włamanie przy użyciu stworzonego przez siebie exploita nie przyniesie włamywaczowi wiele korzyści, jeśli nazajutrz pojawią się u niego agenci CBŚ.

Artykuł ten został opublikowany w numerze 05/2009 (48) magazynu hakin9.

Artykuł w formacie PDF

Dnia 20.05.2010

Tam gdzie traceroute nie może…

W

nawiązaniu to artykułu “Fire(wall)walking – spacer po zaporze ogniowej” warto również wspomnieć o narzędziu noszącym nazwę tcptraceroute. Jest to przerobiona implementacja standardowego traceroute, która używa pakietów TCP. Jak zauważył jego autor – problemem zapewnienia standardu bezpieczeństwa w Internecie jest jego niestandardowe używanie.

Większość zapór sieciowych współczesnego Internetu filtruje lub powinna filtrować pakiety wysyłane przez program traceroute, uniemożliwiając zbadanie trasy pakietu. Jednak w wielu przypadkach firewalle chroniące wybrane sieci i hosty zezwalają na nowe połączenia na określone porty za nimi nasłuchujących maszyn. Dlatego wysyłanie specjalnych* pakietów TCP SYN zamiast UDP czy ICMP ECHO pozwala na ominięcie tego rodzaju restrykcji. Mając na myśli specjalne pakiety należy rozumieć połączenia TCP, które nigdy nie nawiązują pełnych połączeń z docelowym hostem. Jeśli wybrany host nie nasłuchuje na danym porcie – zostanie zwrócony pakiet z ustawioną flagą RST – informując program, że docelowy port jest zamknięty. Natomiast w przypadku odpowiedzi pakietem SYN/ACK – port uznawany jest za otwarty – a sam program tcptraceroute wysyła pakiet RST by nigdy nie ukończyć “potrójnego uścisku dłoni” i tym samym nawiązać połączenia. Jest to ta sama metoda jaką stosuje skaner bezpieczeństwa nmap wykonując skanowanie typu półotwartego (ang. SYN scan lub half-open scan). Dla przykładu zostanie przeprowadzony wywiad następującej sieci:

[Modem ADSL/Router Linksys AG241V2] - [Router/Firewall Linux] - [Serwer WWW]

Przy badaniu zostanie uaktywniony również mechanizm wykrywający NAT (ang. Network Address Translation):

nfsec:~# tcptraceroute -w 1 --dnat target.org
Selected device eth0, address 12.12.12.12, port 58113 for outgoing packets
Tracing the path to target.org (13.13.13.13) on TCP port 80 (www), 30 hops max
 1  router1.pl (14.14.14.1)  0.287 ms  0.235 ms  0.201 ms
 2  router2.pl (14.14.14.2)  9.114 ms  9.389 ms  12.100 ms
 3  router3.pl (14.14.14.3)  8.242 ms  8.356 ms  8.426 ms
 4  * * *
      Detected DNAT to 10.10.1.250
 5  target.org (15.15.15.1)  37.728 ms  37.954 ms  37.061 ms
 6  target.org (15.15.15.1)  37.383 ms  37.646 ms  37.980 ms
 7  target.org (15.15.15.1) [open]  42.472 ms * 67.754 ms

Jak widać najsłabszym ogniwem tutaj jest modem ADSL, który oprócz ujawnienia przekazywania pakietów do sieci wewnętrznej zdradził również adres zewnętrznego interfejsu (eth0) routera linuksowego (10.10.1.250). Uchybieniem ze strony firewalla i zarazem routera opartego na Linuksie było ujawnienie dalszego przekazywania pakietów oraz przekazanie informacji o otwartym porcie 80′tym. Zastosujmy się teraz do reguł z wyżej wspomnianego artykułu na firewallu linuksowym dodatkowo dodając następujące reguły, które maskują zachowanie typowego routera.

iptables -t mangle -A PREROUTING -i eth0 -j TTL --ttl-inc 1
iptables -A OUTPUT -m state --state INVALID -j DROP

Przeprowadzony ponownie test:

nfsec:~# tcptraceroute -w 1 --dnat target.org
Selected device eth0, address 12.12.12.12, port 54610 for outgoing packets
Tracing the path to target.org (13.13.13.13) on TCP port 80 (www), 30 hops max
 1  router1.pl (14.14.14.1)  0.265 ms  0.253 ms  0.213 ms
 2  router2.pl (14.14.14.2)  9.177 ms  9.739 ms  8.696 ms
 3  router3.pl (14.14.14.3)  8.714 ms  8.260 ms  8.604 ms
 4  * * *
      Detected DNAT to 192.168.1.250
 5  target.org (15.15.15.1)  63.710 ms  38.341 ms  37.302 ms
 6  target.org (15.15.15.1)  37.599 ms !p  36.907 ms !p  38.261 ms !p

Wskazuje, że nasza zapora nie ujawnia już informacji o dalszym przekazywaniu pakietów czy otwartym porcie. Ostatnią czynnością w celu poprawy bezpieczeństwa jest wymiana modemu (lub firmware’u na alternatywny) na model obsługujący, co najmniej SPI (ang. Stateful Packet Inspection).

Więcej informacji: tcptraceroute, NAT, SPI

Dnia 19.05.2010

Spring Framework 3.0 Tutorial – cz 4 – sitemesh, menu, atrybuty kontekstu

Jak zapowiedziałem w poprzednim poście tym razem pobawimy się Sitemesh-em i atrybutami kontekstowymi w JSP, więc będzie to wpis raczej krótki. Skupimy się na rozdzieleniu szablonów (layoutu) aplikacji na 2 części. Pierwszy szblon zastosujemy do panelu administracyjnego, wyświetlać będzie listy, formularze i dane, a także umieści na każdej stronie menu administracyjne. Drugi szablon będzie wykorzystywany jedynie podczas logowania i prócz formularza  nie będzie zawierał nic więcej. Oczywiście jeśli ktoś chce może śmiało dodać więcej szablonów, np. specjalna strona dla obsługi zamówień która zawiera oddzielne menu, czy też

W pierwszej części tutorialu wspomniałem iż Sitemesh służy do składania stron w całość, dzięki niemu możemy stworzyć szablon strony, do którego będziemy doklejać wyniki stron co skutecznie  ułatwia tworzenie widoków. Co prawda biblioteka ta potrafi więcej (w wersji 2.x) ale z racji, że korzystamy z wersji alpha lepiej używać jedynie podstawowych funkcjonalności (przynajmniej w tej chwili).

Rozdzielamy szablony

Sitemesh-a skonfigurowaliśmy w pierwszej części tuorialu, miał on za zadanie składać główny szablon (default.jsp) z widokami wyników wygenerowanymi przez aplikację, teraz zajmiemy się rozdzieleniem szablonów dla widoku logowania oraz dla pozostałej części aplikacji. Jak wiadomo, konfigurację Sitemesh-a trzymamy w klasie com.darekzon.bookstore.filter.Sitemesh, i aktualnie zawiera wpis mówiący, że każdy wyniki ma być „wklejony” do szablony default.jsp. Aby utworzyć dodatkowy szablon wystarczy dopisać regułę która dla żądania /login.html będzie stosować inny szablon. Całość wygląda następująco:


package com.darekzon.bookstore.filter;

import org.sitemesh.builder.SiteMeshFilterBuilder;
import org.sitemesh.config.ConfigurableSiteMeshFilter;

public class Sitemesh extends ConfigurableSiteMeshFilter {
 protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
 builder.addDecoratorPath("/login.html", "/views/layout/login.jsp");
 builder.addDecoratorPath("/*", "/views/layout/default.jsp");
 }

}

W powyższym zapisie ważna jest kolejność wpisów (odwrotny zapis przysłaniałby nam szablon login.jsp dla wywołania strony logowania.

Teraz wystarczy stworzyć odpowiedni plik (np. bazując na wcześniejszym szablonie) i gotowe, zapytanie o stronę /login.html otrzyma własną stronę wynikową.

Tworzymy menu administracyjne

Teraz zajmiemy się tworzeniem menu, czynność z pozoru prosta, wystarczy wpisać kilka tagów i gotowe, jak jednak sprawić by nasze menu rozpoznawało gdzie aktualnie się znajdujemy i na bazie tego zaznaczało w menu naszą pozycję? W poprzednim projekcie używałem Sitemesh 2.x który w łatwy sposób odczytywał metatagi stron dzięki czemu łatwo można było określić naszą pozycję, niestety w wersji 3 nie działa to jak trzeba, a na pewno nie jest to w żaden sposób udokumentowane, więc trzeba sobie poradzić w inny sposób. Rozwiązaniem jakie wymyśliłem, jest ustawianie atrybutów strony w zależności od tego gdzie jesteśmy. Jak to działa?

Jak wszyscy wiemy, każda akcja posiada własny plik za pomącą którego generowany jest widok, w każdym z tych plików wstawiamy zapis:


<%
 pageContext.setAttribute("moduleName","content", PageContext.REQUEST_SCOPE);
 pageContext.setAttribute("pageName","index", PageContext.REQUEST_SCOPE);
%>

Powyższy kod, ustawił nam w pliku widoku 2 atrybuty, moduleName która oznaczać będzie w jakiej grupie znajduje się strona oraz pageName która oznacza jaka strona jest generowana, PageContext.REQUEST_SCOPE mówi aplikacji, że atrybuty będą widoczne tylko w zakresie aktualnego żądania (więcej nam nie trzeba).

Zabieramy się za tworzenie menu, ponieważ menu. Możemy je stworzyć w pliku szablonu albo w oddzielnym pliku który dołączymy do naszego szablonu, ponieważ nie lubię chaosu, wybieram rozwiązanie drugie.
Tworzymy plik navigation.jsp (w folderze includes) oraz dołączamy go do naszego szablonu default.jsp dyrektywą:


<%@ include file="../includes/navigation.jsp" %>

Dołączony plik ma za zadanie odczytać atrybuty ustawione w widokach (patrz wyżej) oraz oznaczenie grupy i podstron klasą active gdy są one aktywne, dzięki czemu będziemy mogli za pomącą CSS-a odpowiednio pokazywać i ukrywać nasze menu. Nasze menu zbudowane będzie z zagnieżdżonych list nieuporządkowanych według struktury:


<ul>
  <li>GRUPA
    <ul>
      <li>PODSTRONA</li>
    </ul>
  </li>
</ul>

Plik ten prezentuje się następująco:

<%@ taglib prefix="tag" uri="http://www.springframework.org/tags" %>
<%
 String moduleName = (String) pageContext.getAttribute("moduleName",PageContext.REQUEST_SCOPE);
 String pageName = (String) pageContext.getAttribute("pageName",PageContext.REQUEST_SCOPE);
%><br />
<nav>
 <ul>
 <li class="<% if(moduleName=="content"){ out.print("active"); } %>">
 <a href="<%= request.getContextPath() %>/content.html">
 <tag:message code="menu.content" />
 </a>
 </li>
 <li class="<% if(moduleName=="catalog"){ out.print("active"); } %>">
 <a href="<%= request.getContextPath() %>/catalog.html">
 <tag:message code="menu.catalog" />
 </a>
 <ul>
 <li class="<% if(moduleName=="categories"){ out.print("active"); } %>">
 <a href="<%= request.getContextPath() %>/catalog/categories.html">
 <tag:message code="menu.categories" />
 </a>
 </li>
 <li>
 <a href="<%= request.getContextPath() %>/catalog/books.html">
 <tag:message code="menu.books" />
 </a>
 </li>
 </ul>
 </li>
 <li class="<% if(moduleName=="order"){ out.print("active"); } %>">
 <a href="<%= request.getContextPath() %>/orders.html">
 <tag:message code="menu.orders" />
 </a>
 </li>
 <li class="<% if(moduleName=="client"){ out.print("active"); } %>">
 <a href="<%= request.getContextPath() %>/clients.html">
 <tag:message code="menu.clients" />
 </a>
 </li>
 <li>
 <a href="<%= request.getContextPath() %>/settings.html">
 <tag:message code="menu.settings" />
 </a>
 <ul>
 <li>
 <a href="<%= request.getContextPath() %>/settings/administrators.html">
 <tag:message code="menu.administrators" />
 </a>
 </li>
 </ul>
 </li>
 <li class="logout">
 <a href="<%= request.getContextPath() %>/wyloguj.html">
 <tag:message code="menu.logout" />
 </a>
 </li>
 </ul>
</nav>

Plik dołącza bibliotekę tagów wykorzystywaną do obsługi wiadomości, oraz odczytuje wcześniej ustawione atrybuty zapisując je do zmiennych. W kolejnych pozycjach menu następuje sprawdzenie aktualnej pozycji.
Gdy moduleName jest równe wymaganej wartości zostaje ustawiona klasa active, to samo tyczy się zmiennej pageName. Dzięki takiemu rozwiązaniu mamy nasze „dynamiczne” menu.

Jeśli ktoś zna lepsze rozwiązanie z chęcią je poznam.

PS. Jeśli chodzi o zapis request.getContextPath() to zwraca nam on ścieżkę wywołania aplikacji, tzn. jeśli nasza aplikacja działała by w folderze bookstore a jej uruchomienie wiązałoby się z  wpisanie adresu http://example.com/bookstore/ to getContextPath() zwróci nam ciąg /bookstore, dzięki czemu wszystkie linki będą poprawnie obsłużone bez względu na to, czy nasza aplikacja jest uruchomiona na własnej domenie, czy też działa „w folderze”.

Jak pobrać projekt

Projekt został umieszczony na serwerach Kenai.com. Adres bezpośredni do projektu: http://kenai.com/projects/summer-bookstore.
Dodatkowo zostało uruchomione repozytorium GIT dla wszystkich chętnych i dostępny jest pod adresem: git://kenai.com/summer-bookstore~books0re-source

Projekt umieszczony jest również w repozytorium Github pod adresem: http://github.com/darek/bookstore

Dnia 18.05.2010

Spring Framework 3.0 Tutorial – cz 3 – spring security

W drugiej części tutorialu udało nam się stworzyć mechanizm dodawania administratorów do naszego panelu, byłoby nierozsądne by każdy użytkownik miał do niego dostęp, dlatego w tej części zajmiemy się mechanizmem kontroli dostępu do naszej aplikacji. Wpis obejmie konfigurację mechanizmów uwierzytelniania oraz autoryzacji wykorzystujących Spring Security (w tym hasła użytkowników zakodowane algorytmem sha256 + z wykorzystaniem tzw. soli). Miało być też coś o Sitemeshu, ale zrobię to w następnym odcinku który pojawi się na dniach.

Zabezpieczanie aplikacji

Konfiguracja zabezpieczeń obejmuje dwa pliki, web-security.xml oraz web.xml. Pierwszy z nich zawiera już konfigurację obiektu szyfrującego hasła oraz mechanizm soli (z wcześniejszego tutorialu), tym razem musimy dodać obsługę poziomów dostępu oraz mechanizmu uwierzytelniania opartego o bazę danych. Konfiguracja taka prócz skonfigurowanych już wcześniej obiektów zawierać powinna manager uwierzytelniania, dostawcę danych uwierzytelnianych, filtr przechwytujący, oraz listę reguł które będą mówić mechanizmowi, kto gdzie ma dostęp i ew. gdzie ma się zalogować. Zmiany w tym pliku wyglądają następująco (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


<authentication-manager alias="authenticationManager">
 <authentication-provider ref="authProvider" />
 </authentication-manager>

 <beans:bean id="authProvider"
 class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
 <beans:property name="userDetailsService" ref="userService" />
 <beans:property name="passwordEncoder" ref="passwordEncoder" />
 <beans:property name="saltSource" ref="saltSource" />
 <beans:property name="includeDetailsObject" value="true" />
 </beans:bean>

 <beans:bean id="authenticationProcessingFilterEntryPoint"
 class="org.springframework.security.web.authentication.AuthenticationProcessingFilterEntryPoint">
 <beans:property name="forceHttps" value="false" />
 <beans:property name="loginFormUrl" value="/login.html" />
 </beans:bean>

 <http entry-point-ref="authenticationProcessingFilterEntryPoint" auto-config="true">
 <intercept-url pattern="/**" access="ROLE_ADMIN" />
 <intercept-url pattern="/login.html" filters="none" />
 <logout logout-url="/logout.html" />
 <anonymous granted-authority="ROLE_ANONYMOUS" />
 <form-login login-page="/login.html" login-processing-url="/j_spring_security_check.html"
 authentication-failure-url="/login.html?error=true" />
 </http>

Czyli:

authentication-manager: mechanizm odpowiedzialny za uwierzytelnianie, przekazujemy mu referencje do obiektu odpowiedzialnego za dostarczenie informacji o użytkownikach

authProvider: obiekt odpowiedzialny jest za dostarczenie użytkowników (tj, pobranie użytkownika na podstawie loginu), w naszym wypadku obiekt korzysta z bazy danych oraz dodatkowych obiektów szyfrujących. authProvider posiada również parametr userDetailsService który powinien wskazywać na obiekt odpowiedzialny za wyszukanie użytkownika, obiekt taki wskazujemy poprzez nadanie mu id userService (patrz web-data.xml).

authenticationProcessingFilterEntryPoint: obiekt rozpoczynający proces autoryzacji, przechowuje ścieżkę (w formie URL-a) do strony z formularzem logowania

<http>: najważniejsza część, tutaj ustawiamy poziomy dostępów do konkretnych zasobów, ustalamy również formularza logowania oraz adres powodujący wylogowanie. (UWAGA! jeśli ustalamy niestandardowy adres logowania należy wyłączyć mu poziom dostepu (filter=”none”) inaczej dostaniemy pętle przekierowań)

Według powyższej konfiguracji nasza aplikacja jest dostępna tylko dla użytkowników z poziomem dostępu ROLE_ADMIN, jeśli nie jesteś zalogowany zostajesz automatycznie przekierowany na stronę /login.html która wyświetla formularz i wysyła go pod adres /j_spring_security_check.html, jeśli logowanie się nie powiedzie, do adresu logowania zostanie dopisany parametr error=true, gdy natomiast podasz poprawne dane logujące zostaniesz przeniesiony na wcześniej żądaną stronę, lub na stronę główną serwisu. Aby się wylogować musisz wejść pod adres /logout.html.

W pliku web.xml ustawiamy filtr który każde żądanie kończące się rozszerzeniem .html będzie „testował” pod względem bezpieczeństwa (tzn. czy użytkownik wywołujący żądanie ma prawo je wykonać), zdefiniowany filtr wygląda tak (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


<filter>
 <filter-name>springSecurityFilterChain</filter-name>
 <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>
 <filter-mapping>
 <filter-name>springSecurityFilterChain</filter-name>
 <url-pattern>*.html</url-pattern>
 </filter-mapping>

Jak wspomniałem wcześniej gdy użytkownik nie ma praw do wykonania danego żądania, bądź nie jest zalogowany zostaje automatycznie przekierowany do strony loguj.html. Ponieważ nie jest to standardowa strona musimy sami obsłużyć to żądanie, na szczęście nie jest to trudne, wymaga tylko 2 elementów, metody w kontrolerze która obsłuży żądanie oraz widoku formularza który wyświetli pola do podania loginu i hasła. Akcja w kontrolerze dodatkowo przyjmie parametr error (o czym mówiłem wcześniej) który posłuży do wykrycia czy akcja logowania się nie powiodła i jeśli jest to prawdą wyświetli odpowiedni komunikat.

Metodę obsługującą logowanie zawarłem w kontrolerze IndexController i wygląda ona następująco (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):

@RequestMapping(value = "/login", method = RequestMethod.GET)
 public ModelAndView login(@RequestParam(value = "error", required = false, defaultValue = "false") boolean error) {
 ModelAndView mav = new ModelAndView("index/login");
 mav.addObject("isError", error);
 return mav;
 }

@RequestParam pobiera parametr przekazywany w żądaniu i przekazuje go w zmiennej error, parametr ten nie jest wymagany, więc jeśli nie istnieje do zmiennej error zostanie przypisana wartość domyślna false. Parametr error przekazywany jest do widoku który prezentuje się następująco:


<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<%@ taglib prefix="tag" uri="http://www.springframework.org/tags" %>
<html>
<head>

</head>
<body>
<c:if test="${isError eq true}">
 <div><tag:message code="login_error" /></div>
</c:if>
<div>
 <form action="<c:url value="/j_spring_security_check.html" />" method="POST">
 <div>
 <label for="login"><tag:message code="administrator.username"/></label>
 <input id="login" name="j_username"/>
 </div>
 <div>
 <label for="password"><tag:message code="administrator.password"/></label>
 <input type="password" id="password" name="j_password"/>
 </div>
 <div>
 <input type="submit"/>
 </div>
 </form>
</div>
</body>
</html>

Jak widzimy powyżej, najpierw sprawdzamy czy zmienna isError jest równa true co by oznaczało, że podaliśmy błędne dane podczas logowania, jeśli warunek jest spełnony zostaje wyświetlony komunikat. Następnie tworzymy formularz który metodą POST przesyła dane pod adres /j_spring_security_check.html który jak pamiętacie ustawiliśmy wcześniej w pliku web-security.xml. Formularz musi zawierać przynajmniej dwa pola (login i hasło) które dodatkowo powinny przyjmować odpowiednie nazwy: j_username dla nazwy użytkownika oraz j_password dla jego hasła.

Byłoby wspaniale gdyby na tym zakończyła się konfiguracja, niestety musimy zmodyfikować klasę encji Account by mogła być poprawnie przetwarzana przez Spring Security. Aby nasza klasa była poprawnie obsługiwana musi rozszerzać klasę User (z pakietu org.springframework.security.core.userdetails) oraz implementować interfejs UserDetails (z tego samego pakietu).
W naszym wypadku implementacja wygląda następująco (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


public class Account extends User implements UserDetails {

@Override
 public Collection<GrantedAuthority> getAuthorities() {
 Set<GrantedAuthority> ga = new HashSet<GrantedAuthority>();
 for (AccountRole ar : this.accountRole) {
 ga.add(new GrantedAuthorityImpl(ar.getRole()));
 }
 return ga;
 }
<pre> @Override
 public boolean isEnabled() {
 if (this.accountRole.size() > 0) {
 return true;
 }
 return false;
 }</pre>
@Override
 public boolean isAccountNonExpired() {
 return this.isEnabled();
 }

 @Override
 public boolean isAccountNonLocked() {
 return this.isEnabled();
 }

 @Override
 public boolean isCredentialsNonExpired() {
 return this.isEnabled();
 }

}

Zostały zaimplementowane metody:

public Collection<GrantedAuthority> getAuthorities() – zwraca listę poziomów dostępu jakie posiada użytkownik, czyli nasze AccountRole,
public boolean isEnabled() – zwraca true jeśli konto jest aktywne, w naszym wypadku kierujemy się zasadą „Jeśli użytkownik ma przypisaną rolę to konto jest aktywne”,
public boolean isAccountNonExpired() – zwraca true jeśli konto nie wygasło,
public boolean isAccountNonLocked() – zwraca true jeśli konto nie jest zablokowane,
public boolean isCredentialsNonExpired() – zwraca true jeśli poziomy dostępów nie wygasły

Musimy również dodać metodę loadUserByUsername która będzie wykorzystywana przez dostawcę autoryzacji do znalezienia użytkownika. Funkcja ta wykorzystuje metodę findUsername z klasy AccountDao którą wykorzystujemy podczas rejestracji, i prezentuje się ona następująco (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


@Override
 public UserDetails loadUserByUsername(String username)
 throws UsernameNotFoundException, DataAccessException {
 try {
 return (UserDetails) accountDao.findUsername(username);
 } catch (UserNotFoundException e) {
 throw new UsernameNotFoundException(username);
 }
 }

Metodę tą dodajemy do obiektu który jest wskazany w obiekcie authProvider jako parametr userDetailsService, w naszym wypadku było to dodanie identyfikatora userService do obiektu AccountServiceImpl w pliku web-data.xml (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


<bean id="userService"
class="com.darekzon.bookstore.service.AccountServiceImpl" />

I to wszystko, tak skonfigurowany mechanizm powinien działać poprawnie, pamiętajcie tylko, żeby włączyć zabezpieczenia po dodaniu użytkownika.

Jak pobrać projekt

Projekt został umieszczony na serwerach Kenai.com. Adres bezpośredni do projektu: http://kenai.com/projects/summer-bookstore.
Dodatkowo zostało uruchomione repozytorium GIT dla wszystkich chętnych i dostępny jest pod adresem: git://kenai.com/summer-bookstore~books0re-source

Projekt umieszczony jest również w repozytorium Github pod adresem: http://github.com/darek/bookstore

Dnia 11.05.2010

Uprzejmie donoszę

W związku z zasmucającą kondycją blogusia w ostatnim czasie pozwolę sobie wyjaśnić co się dzieje. Otóż:

  • Po primo życie zajmuje mnie ostatnio bardzo a będzie jeszcze gorzej, bo przede mną remont.
  • Po secundo czytam. Postanowiłem nie czekać do emerytury z przeczytaniem książek, które absolutnie przeczytać muszę i zacząłem już teraz. Im więcej czytam, tym bardziej zdaję sobie sprawę z tego, że nie mam nic sensownego do przekazania Państwu Internautom. Ot, problem.
  • Po tertio przekopuję internety w poszukiwaniu różnych naukowych nudziarstw. Co ciekawsze wrzucam sobie o, tutaj. Zainteresowanych astronomią, fizyką, biologią, chemią i innymi zajęciami jajogłowych zapraszam. Zwracam tylko uwagę, że z reguły zabawa polega na tym, żeby klikać w linki pod obrazkami, bo najczęściej odsyłam do tekstu.

Mam kilka rzeczy w kolejce do poblogowania, ale trudno mi określić kiedy się za to zabiorę. Domenę w każdym razie opłacę na następny rok, za hosting już zapłaciłem, więc niech żywi nie tracą nadziei.

Na koniec bonus: w związku ze zmianą biurka wdrożyłem coś, co kiedyś zobaczyłem w czeluściach sieci. Nawet działa.

Kabelki ujarzmione

Dnia 10.05.2010

Niekonwencjonalne ataki Wi-Fi

N

iewiele osób zna sposoby na skuteczne zakłócenie działania całej sieci bezprzewodowej pomimo, że znają pojęcia typu łamanie klucza WEP, fałszywa autentykacja MAC czy przechwycenie 4-way handshake.

Artykuł ten został opublikowany w numerze 04/2009 (47) magazynu hakin9.

Artykuł w formacie PDF

Dnia 06.05.2010

Spring Framework 3.0 Tutorial – cz 2 – baza danych, walidacja, wiadomości, encje, hibernate

W tej części tutorialu skupimy się na skonfigurowaniu połączenia z bazą danych, podłączeniu frameworka hibernate do naszej aplikacji oraz zobaczymy jak tworzyć encje i jak sprawdzać poprawność danych przed ich zapisem (walidacja).

Przygotowanie do pracy

W poprzedniej części przygotowaliśmy w ramach części klienckiej małą aplikację „witaj świecie”, ponieważ projekt nie zawierał elementów stricte przyporządkowanych części dla klienta możemy skopiować go (głównie pliki konfiguracyjne) i użyć w panelu administracyjnym (prawie jak copypasteryzm).

Aby przejść przez tą część tutoriala będziemy musieli zainstalować bazę danych PostgreSQL oraz pobrać kilka dodatkowy bibliotek (zrobimy to wykorzystując mavena).
Jak wspomniałem w pierwszym odcinku tutoriala, wspólne klasy będą trzymane w osobnym projekcie „bookstore-lib”, tam przechowywane będą klasy Encji, Dao oraz Serwisy, a także wspólne klasy które będą wykonywać specyficzne zadania (powstaną wkrótce), eclipse zadba, by dołączyć je automatycznie podczas kompilacji. Projekt „bookstore-lib” również korzysta z mavena do obsługi bibliotek wykorzystanych w projekcie, nie posiada on natomiast zintegrowanego Spring frameworka (co jest logiczne). Nad jego konfiguracją rozpisywać się nie będę, stworzyłem czysty projekt, dodałem obsługę mavena i zacząłem pisać klasy (w tym przypadku na pierwszy ogień poszły Encje), gdy eclipse wykrył, że nie mam jakiejś klasy zależnej dodałem ją do projektu ustawiając odpowiedni zakres (scope – jeśli klasa wykorzystywana jest w panelu, zakres ustawiałem na runtime, jeśli była używana stricte w bookstore-lib, zakres ustawiany był na compile).

Projekt „bookstore-admin” prócz bibliotek potrzebnych do uruchomienia Springframework-a potrzebuje również bibliotek odpowiedzialnych za obsługę bazy danych oraz walidację formularzy, do pliku pom.xml dodałem następujące biblioteki (tu również skorzystałem z zakresów – scope, dzięki czemu aplikacje nie posiadały zdublowanych bibliotek).

<dependency>
 <groupId>postgresql</groupId>
 <artifactId>postgresql</artifactId>
 <version>8.4-701.jdbc4</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-orm</artifactId>
 <version>3.0.2.RELEASE</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-core</artifactId>
 <version>3.3.2.GA</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-entitymanager</artifactId>
 <version>3.4.0.GA</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>slf4j-log4j12</artifactId>
 <version>1.5.8</version>
 <type>jar</type>
 <scope>compile</scope>
 </dependency>
<dependency>
 <groupId>org.hibernate</groupId>
 <artifactId>hibernate-validator</artifactId>
 <version>4.0.2.GA</version>
 </dependency>

Konfiguracja bazy danych

Konfiguracja bazy danych jak i wszystkich elementów związanych z obsługą zapisu do bazy danych oraz odczytu z niej znajduje się w pliku web-data.xml (trzeba być porządnym programistą i nie tworzyć śmietnika konfiguracyjnego).
Zanim skonfigurujemy połączenie z bazą danych musimy stworzyć użytkownika bazy danych oraz dodać bazę z którą będzie się łączyć, jeśli ktoś nie wie polecam google.com lub program pgAdmin. Połączenie z bazą danych możemy skonfigurować na 2 sposoby (tyle znam), pierwszy (standardowy), czyli dostęp do bazy poprzez adres serwera+port oraz dane uwierzytelniające, drugi to dostęp do bazy poprzez nazwę JNDI (czytaj więcej o Java Naming and Directory Interface API), ważną zaletą (moim zdaniem) połączenia JNDI jest niezależność ustawień autoryzacyjnych, ponieważ łączymy się z bazą nie poprzez login i hasło, a ustaloną wcześniej przez serwer nazwę, możliwe jest bezproblemowe (bez potrzeby ponownego grzebania w konfiguracji) zmienianie danych autoryzacyjnych, czy też adresu bazy danych dlatego też oprę naszą aplikację o ten typ połączenia.
Ponieważ połączenia JNDI opierają się na skonfigurowanej nazwie musimy taką konfigurację wprowadzić. W naszym przypadku (tomcat 6.0) robimy to w pliku TOMCAT_HOME/conf/context.xml1 poprzez wpisanie między tagi <context> zawartości:

<Resource auth="Container" driverClassName="org.postgresql.Driver" name="bookstore" password="bookstore" type="javax.sql.DataSource" url="jdbc:postgresql://localhost:5432/bookstore" username="bookstore"/>

Co w skrócie oznacza „przypisz nazwie bookstore połączenie do bazy o nazwie bookstore znajdującej się pod adresem localhost, na porcie 5432 wykorzystując nazwę użytkownika bookstore oraz hasło bookstore„.

Nasza aplikacja korzystać będzie z frameworka hibernate, dlatego potrzebujemy skonfigurować jego działanie. Konfiguracja taka polega na utworzeniu pliku  hibernate.cfg.xmlclasspath (np. src/META-INF; może ktoś zna polski odpowiednik classpath) i wpisujemy zawartość:

<!DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
 <session-factory>
 <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
 <property name="hibernate.hbm2ddl.auto">update</property>
 <property name="hibernate.show_sql">true</property>
 <property name="hibernate.format_sql">true</property>
 <property name="hibernate.use_sql_comments">true</property>
 <mapping
 class="com.darekzon.bookstore.domain.Account" />
 <mapping
 class="com.darekzon.bookstore.domain.AccountRole" />
 <mapping
 class="com.darekzon.bookstore.domain.Administrator" />
 </session-factory>
</hibernate-configuration>

Pliik ustawia kolejno:

  1. hibernate.dialect -  jaki język zapytań będzie wykorzystywany (w tym wypadku rozszerzenia dodane przez postgresql)
  2. hibernate.hbm2ddl.auto – automatycznie aktualizuj schemat bazy danych na podstawie class encji (super sprawa)
  3. hibernate.show_sql – pokazuje zapytania sql jakie wykonuje hibernate (dobre przy debugowaniu, czasem wprowadza chaos do konsoli)
  4. hibernate.format_sql – formatuje w/w zapytania, przydaje się
  5. hibernate.user_sql_comments – dodatkowe komentarze, pomagają zorientować się jakie zapytanie aktualnie jest wykonywane
  6. mapping class  – wskazanie jakie klasy traktowane są jako klasy encji (muszą być oznaczone adnotacją @Entity), wykorzystywane przy aktualizacji schematów

Drugim ważnym plikiem jest persistence.xml który konfiguruje nam PersistenceUnit czyli jednostę utrwalającą. Plik ten ma zawartość:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
 version="2.0">
 <persistence-unit name="bookstorePU" transaction-type="RESOURCE_LOCAL">
 <provider>org.hibernate.ejb.HibernatePersistence</provider>
 <jta-data-source>bookstore</jta-data-source>
 <class>com.darekzon.bookstore.domain.Administrator</class>
 <class>com.darekzon.bookstore.domain.Account</class>
 <class>com.darekzon.bookstore.domain.AccountRole</class>
 </persistence-unit>
</persistence>

Określamy w nim nazwę jednostki utrwalającej, typ transakcji, dostawę jednostki oraz adres naszego źródła danych, musimy również wprowadzić informacje, które klasy będą używane podczas utrwalania (więc pewne dane się zdublują z plikiem hibernate.cfg.xml). Powyższy plik możemy umieścić w tym samym miejscu co plik hibernate.cfg.xml, tak by był dostępny dla JVM podczas ładowania aplikacji.

Gdy mamy już skonfigurowanego hibernate-a oraz jednostę utrwalającą, pora zintegrować je z naszą aplikacja, polegać to będzie na utworzeniu szeregu beanów odpowiedzialnych za obsługę żądań do bazy danych. Konfiguracja ta została zapisana w pliku web-data.xml i ma zawartość:

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
 xmlns:jee="http://www.springframework.org/schema/jee"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/bookstore"
 cache="true" resource-ref="true" lookup-on-startup="false"
 proxy-interface="javax.sql.DataSource" />

<bean id="entityManagerFactory"
 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
 <property name="dataSource" ref="dataSource" />
 </bean>

 <bean id="sessionFactory"
 class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
 <property name="dataSource" ref="dataSource" />
 <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
 <property name="configLocation" value="classpath:META-INF/hibernate.cfg.xml" />
 </bean>

 <bean id="transactionManager"
 class="org.springframework.orm.jpa.JpaTransactionManager">
 <property name="sessionFactory" ref="sessionFactory" />
 </bean>

 <bean id="templateManager"
class="org.springframework.orm.hibernate3.HibernateTemplate">
 <property name="sessionFactory" ref="sessionFactory" />
 </bean>

<tx:annotation-driven transaction-manager="transactionManager" />

</beans>

Konfiguracja zawiera:

dataSource:
Wyszukuje nasze połączenie (skonfigurowane w serwerze) i binduje je do nazwy dataSource

entityManager: manager encji

sessionFactory: można powiedzieć, że sesja jest tożsama (oznacza to samo) co połączenie z bazą danych. Dzięki podaniu klasy AnnotationConfiguration do parametru configurationClass mogę używać adnotacji do konfigurowania encji zamiast pisać pliki *.hba.xml. Parametr configLocation wskazuje miejsce gdzie znajduje się plik konfiguracyjny hibernate-a.

transactionManager: manager transakcji (raczej jasne)

templateManager: posiada szereg metod upraszczających obsługę ORM (wyszukiwanie, zapisywanie, aktualizacja, kasowanie etc.), do działania wymaga sesji podawanej w parametrze sessionFactory.

tx:annotation-driven: dzięki temu zapisowi możemy używać dodatkowych adnotacji (np. @Transactional)

Należy pamiętać by dopisać ścieżkę do konfiguracji  (/WEB-INF/web-data.xml) w pliku web.xml (w miejscu konfiguracji kontekstu).

Tak skonfigurowany spring, będzie lączył się przy starcie ze zdefiniowanym serwerem bazy danych, udostępnia również szereg obiektów pomagających w dostępie do bazy. Jeśli połączenie działa poprawnie (czyt. przy starcie nie wyskakuje żadne wyjątek) bierzemy się do dalszej pracy.

Obsługa wiadomości / tłumaczenia

Jestem zwolennikiem odcinania treści od formy, nie lubię gdy w kodzie strony widzę treści takie jak, nazwy pól, komunikaty błędów, czy też nagłówki. Takie podejście sprawia problem, gdy będziemy musieli zmienić tekst znajdujący się w wielu elementach aplikacji czy też co ważniejsze udostępnić aplikację w wielu językach.  Na szczęście istnieje proste rozwiązanie jakim jest mechanizm wiadomości. Mechanizm ten składa się z 3 elementów: konfiguracji wskazującej gdzie znajdują się teksty, pliku z tekstami oraz odpowiednich wstawek w kodzie aplikacji które wskazują jaka treść ma zostać umieszczona w danym miejscu.

Konfiguracja mechanizmu jest niezwykle prosta, polega na zdefiniowaniu nowego obiektu i przekazaniu mu listy plików w której znajdują się nasze wiadomości (poniżej):


<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
 <property name="basenames">
 <list>
 <value>/WEB-INF/messages/main</value>
 </list>
 </property>
 </bean>

Pewną nieścisłością jest fakt, że obiekt ten będzie przeszukiwał katalog /WEB-INF/messages/ w poszukiwaniu pliku main.properties, a nie jak można by sadzić pliku main, o czym trzeba pamiętać.

Nasz plik z wiadomościami ma prostą budowę, składa się z zestawu   klucz = treść, gdzie klucz jest unikalnym identyfikatorem nadawanym naszej treści, będzie on również używany w kodzie strony, gdzie należy wstawiać tagi w postaci <tag:message code=”IDENTYFIKATOR” /> który zostanie zastąpiony odpowiednią treścią. Proste w wygodne.

Dodawanie administratorów

Pierwszym zadaniem z jakim się zmierzymy jest dodawanie administratorów (w następnej części tutoriala zabezpieczymy nasz system, więc potrzebujemy konta by móc się zalogować), gdzie konta powinny spełniać wymagania:

  1. hasło musi mieć przynajmniej 8 znaków, ale nie więcej jak 20 znaków
  2. hasła zaszyfrowane zostaną algorytmem SHA-2 (odmiana sha256)
  3. wykorzystana zostanie sól w postaci identyfikatora użytkownika (identyfikator nie będzie wystawiany na widok publiczny)
  4. w bazie danych przechowywani będą użytkownicy o różnych poziomach dostępu, do panelu administracyjnego dostęp będą mieli tylko i wyłącznie Ci użytkownicy, którzy posiadają poziom ROLE_ADMIN

Z powyższych krótkich wymagań można łatwo wywnioskować, że potrzebujemy obiektu który będzie szyfrować ciągi znaków, oraz jednego do tworzenia soli. Obiekty te skonfigurowane zostaną w kolejnym pliku xml zapisanym pod nazwą security.xml, z racji, że są to obiekty wykorzystywane przy funkcjach bezpieczeństwa.
Plik ten aktualnie prezentuje się jak poniżej:


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
 xmlns:jee="http://www.springframework.org/schema/jee"
 xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.0.xsd

http://www.springframework.org/schema/jee

http://www.springframework.org/schema/jee/spring-jee-3.0.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-3.0.xsd

http://www.springframework.org/schema/tx

http://www.springframework.org/schema/tx/spring-tx-3.0.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

 <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
     <constructor-arg value="256"/>
 </bean>

 <bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">
     <property name="userPropertyToUse" value="id"/>
 </bean>

</beans>

Diagram klas struktury przechowującej dane nt. administratorów wygląda następująco:

Diagram klas - konta użytkowników

Diagram klas - konta użytkowników


Klasa administratora (na razie pusta) rozszerza klasę użytkownika która posiada login oraz hasło jako dane uwierzytelniające, dodatkowo użytkownik agreguje poziom dostępu użytkownika (z racji, że w tej samej tabeli przechowywani będą administratorzy, operatorzy oraz zwykli użytkownicy) który wydelegowany jest do oddzielnej klasy.

Tworzymy Encje

Powyższy diagram musimy przepisać na klasy encji, najprościej mówiąc encja to obiekt reprezentujący jeden rekord jednej tabeli, tak więc Encja Account będzie odzwierciedleniem strukturę tabeli account.

Encje jakie utworzyliśmy podczas projektu powinny wyglądać tak:

Administrator (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


@Table(name = "administrator")
@Entity
public class Administrator extends Account { }

Account (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


@Entity
@Table(name = "account")
@Inheritance(strategy = InheritanceType.JOINED)
public class Account {

 @Id
 @GeneratedValue(generator = "account_id", strategy = GenerationType.SEQUENCE)
 @SequenceGenerator(name = "account_id", sequenceName = "account_id_seq")
 Integer id;

 public Integer getId() {
 return id;
 }

 public void setId(Integer id) {
 this.id = id;
 }

 @Basic
 @NotNull
 @Size(min = 5, max = 20)
 String username;

 public String getUsername() {
 return username;
 }

 public void setUsername(String username) {
 this.username = username;
 }

 @Basic
 @Size(min = 8, max = 20)
 String password;

 public String getPassword() {
 return password;
 }

 public void setPassword(String password) {
 this.password = password;
 }

 @Transient
 public String repeatedPassword;

 public String getRepeatedPassword() {
 return repeatedPassword;
 }

 public void setRepeatedPassword(String repeatedPassword) {
 this.repeatedPassword = repeatedPassword;
 }

 @Basic
 @DateTimeFormat(iso = ISO.DATE_TIME)
 Date addDate = new Date();

 public Date getAddDate() {
 return addDate;
 }

 public void setAddDate(Date addDate) {
 this.addDate = addDate;
 }

 @OneToMany(cascade = CascadeType.ALL, mappedBy = "account", fetch = FetchType.EAGER, targetEntity = AccountRole.class)
 List<AccountRole> accountRole = new ArrayList<AccountRole>();

 public List<AccountRole> getAccountRole() {
 return accountRole;
 }

 public void setAccountRole(List<AccountRole> accountRole) {
 for (AccountRole ar : accountRole) {
 this.addAccountRole(ar);
 }
 }

 public void addAccountRole(AccountRole accountRole) {
 if (!this.accountRole.contains(accountRole)) {
 accountRole.setAccount(this);
 this.accountRole.add(accountRole);
 }
 }
}

AccountRole (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


@Entity
@Table(name = "account_role")
public class AccountRole {

 public AccountRole() {
 this.setRole("ROLE_ANONYMOUS");
 }

 public AccountRole(String role) {
 this.setRole(role);
 }

 @Id
 @GeneratedValue(generator = "role_id", strategy = GenerationType.SEQUENCE)
 @SequenceGenerator(name = "role_id", sequenceName = "account_role_id_seq", initialValue = 1)
 Integer roleId;

 public Integer getRoleId() {
 return roleId;
 }

 public void setRoleId(Integer roleId) {
 this.roleId = roleId;
 }

 @Basic
 String role;

 public String getRole() {
 return role;
 }

 public void setRole(String role) {
 this.role = role;
 }

 @ManyToOne(targetEntity = Account.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 @JoinColumn(name = "accountId", nullable = true)
 Account account;

 public Account getAccount() {
 return account;
 }

 public void setAccount(Account account) {
 this.account = account;
 }

}

Warto zwrócić uwagę na adnotacje:

  1. @Entity – oznacza, że dana klasa jest klasą encyjną
  2. @Table – mówi jaka tabela w bazie odpowiada naszej encji (jeśli ustawimy, hibernate automatycznie wyeksportuje naszą encje do danej tabeli)
  3. @Inheritance – mówi hibernate-owi, że ewentualne zależności (poprzez dziedziczenie) powinny być zapisywane w osobnych tabelach (UWAGA! – domyślnie, hibernate łączy wszelkie zależności w jednej tabeli), mechanizm sam zadba o odpowiednie klucze obce.
  4. @Id – oznacza wybrane pole jako identyfikator
  5. @GeneratedValue – konfiguruje metodę generowania wartości dla pola, wykorzystywany w identyfikatorach (autoincrement)
  6. @SequenceGenerator – konfiguruje generator sekwencji dla wybranego pola
  7. @Basic – zwykłe pole
  8. @Transistent – mówi aplikacji, że dane pole nie jest odzwierciedlone w bazie danych
  9. @DateTimeFormat – ustala format daty, dla pola które datę będzie przechowywać
  10. @ManyToOne – tworzy relacje wiele-do-jednego
  11. @OneToMany – tworzy relacje jeden-do-wielu
  12. @JoinColumn – ustawia kolumnę łączącą dwie tabele

Ostatnie adnotacje posłużyły do skonfigurowania relacji Konto->Poziom dostępu, dzięki temu przy pobieraniu informacji o koncie, automatycznie dostaniemy listę poziomów dostępu jakie posiada użytkownik.

Drugą ważną rzeczą w powyższych klasach encji są adnotacje służące walidowaniu Dzięki nim nie musimy zaśmiecać kontrolerów dodatkowymi regułami sprawdzającymi, czy też konfigurować walidacji przez XML, reguły walidacji to kolejno:

  1. @NotNull – pole nie może być nullem
  2. @Size – wielkość pola musi mieścić się w granicach min do max znaków

Oczywiście, to nie jedyne walidatory jakie są dostępne, pełną listę podstawowych walidatorów znajdziecie w dokumentacji.

Dodawanie administratorów będzie zapisane w kontrolerze AdministratorController, na początek zaimplementujemy metodę która będzie wyświetlać formularz rejestracyjny.

AdministratorController (pełna zawartość pliku w repozytorium – zobacz koniec wpisu):


@Controller
public class AdministratorController {

 @Autowired
 AccountService accountService;

 @RequestMapping(value = "/administrator/add", method = RequestMethod.GET)
 public ModelAndView add() {
 ModelAndView mav = new ModelAndView("/administrator/add");
 mav.addObject("administrator", new Administrator());
 return mav;
 }

}

Co warto zauważyć?

  1. @Controler – każdy kontroler oznaczony musi być adnotacją @Controler, dzięki czemu spring podczas skanowania pakietu dodaje go do listy
  2. @Autowired - mówi Spring-owi aby poszukał obiektu o zadanym typie i automatycznie podpiął go do pola
  3. @RequestMapping – mówi springowi jakie żądanie ma być skierowane do danej metody, opcja RequestType wskazuje dodatkowo jaki typ żądania ma być tam skierowane,w tym przypadku zależy nam na żądaniu GET

Powyższa metoda zwraca obiekt ModelAndView (standardowy obiekt zwracany przez większość metod) który przechowuje informacje na temat pliku widok oraz obiekt klasy Administrator, obiekt ten zbindujemy w widoku dzięki czemu wartości pól w formularzu zostaną przepisane do odpowiadających im wartości pól w obiekcie.
Widok formularza prezentuje się następująco:


<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="tag" uri="http://www.springframework.org/tags" %>
<div>
 <form:form commandName="administrator">
 <ol>
 <li>
 <form:label path="username"><tag:message code="administrator.username" /></form:label>
 <form:input path="username" />
 <form:errors path="username" />
 </li>
 <li>
 <form:label path="password"><tag:message code="administrator.password" /></form:label>
 <form:password path="password" />
 <form:errors path="password" />
 </li>
 <li>
 <form:label path="repeatedPassword"><tag:message code="administrator.repeatedPassword" /></form:label>
 <form:password path="repeatedPassword" />
 <form:errors path="repeatedPassword" />
 </li>
 <li>
 <input type="submit" />
 </li>
 </ol>
 </form:form>
</div>

Gdzie:

  • taglib – pozwala stosować rozszerzenia w JSP; form-generowanie formularzy, obsługa błedów, tag-wyświetlanie wiadomości o których wspomniałem wcześniej
  • commandName – to nazwa nadana naszemu obiektowi podczas przekazywania go z kontrolera do widoku,
  • input path – to pole w naszym obiekcie
  • errors – lista błędów dla danego pola (pojawia się po walidacji)

Powyższy formularz prezentuje się następująco:

Formularz dodawania administratora

Formularz dodawania administratora

Po wciśnięciu wyślij, dane z formularza już pod postacią obiektu klasy Administrator przekazywane są do kolejnej metody która sprawdza poprawność danych, i jeśli wszystko jest jak trzeba zapisuje je. Metoda ta wygląda następująco (pełna zawartość pliku w repozytorium – zobacz koniec posta):


@RequestMapping(value = "/administrator/add", method = RequestMethod.POST)
 public ModelAndView add(@Valid Administrator admin, BindingResult result) {
 ModelAndView mav = new ModelAndView("administrator/add");
 if (!admin.getPassword().equals(admin.getRepeatedPassword())) {
 result.addError(new FieldError("administrator", "repeatedPassword",
 "notEqual"));
 }
 if (result.hasErrors()) {
 mav.addObject("administrator", admin);
 return mav;
 }
 List<AccountRole> ar = new ArrayList<AccountRole>();
 ar.add(new AccountRole("ROLE_ADMIN"));
 try {
 accountService.registerAccount(admin, ar);
 } catch (UserExistsException e) {
 result.reject("user.exists");
 mav.addObject("administrator", admin);
 return mav;
 }
 mav.setViewName("redirect:/administrator.html");
 return mav;
 }

Powyższa metoda przyjmuje dwa argumenty, pierwszym jest nasz obiekt Administrator który zawiera dane z formularza, oraz obiekt BindingResult który przechowuje informacje na temat ewentualnych błędów które wystąpiły podczas sprawdzania poprawności (zgodnie z adnotacjami w klasach encyjnych). Aby Spring wiedział, że dany obiekt wymaga sprawdzenia poprawności danych należy oznaczyć go adnotacją @Valid, dzięki temu, spring automatycznie sprawdzi obiekt, a błędy zapisze w obiekcie BindingResult.

Ponieważ nie istnieje adnotacja walidacyjna (przynajmniej w podstawowym zestawie) która sprawdza czy dwa pola są identyczne musiałem zaprogramować dodatkowe sprawdzanie już w kontrolerze. Gdy akcja wykryje, że hasło oraz jego powtórzona wartość nie są identyczne, doda do obiektu BindingResult błąd dla pola repeatedPassword przez co formularz nie zostanie zapisany w bazie, a zamiast tego zostanie ponownie wyświetlony z zaznaczonym błędem, jak przykład poniżej:

Formularz z błędnymi polami

Formularz z błędnymi polami

Jeśli natomiast wszystkie nasze pola zostaną wypełnione poprawnie nastąpi próba zapisania formularza accountService.registerAccount, a po poprawnym zapisaniu zostaniemy przekierowani (dyrektywa „redirect:/administrator”) do strony /administrator.html. Akcja rejestracji nowego administratora składa się z 2 plików (nie wliczając interfejsów które te pliki implementują.

Pierwszy plik to AccountServiceImpl który jest w tym wypadku głównym plikiem (pełna zawartość pliku w repozytorium – zobacz koniec posta):


@Transactional
@Repository
public class AccountServiceImpl implements AccountService {
 @Autowired
 AccountDao accountDao;

 @Autowired
 PasswordEncoder passwordEncoder;

 @Autowired
 SaltSource saltSource;

 @PersistenceContext
 EntityManager entityManager;

 @Override
 public void registerAccount(Account account,List<AccountRole> ar) throws UserExistsException {
 try{
 accountDao.findUsername(account.getUsername());
 throw new UserExistsException();
 }catch(UserNotFoundException une){
 entityManager.persist(account);
 account.setPassword(passwordEncoder.encodePassword(account.getPassword(), saltSource));
 for(AccountRole arole : ar){
 account.addAccountRole(arole);
 }
 entityManager.flush();
 }

 }

}

Nasza klasa oznaczona została dwoma adnotacjami, @Transactional, która mówi że, wszystkie metody w niej zaimplementowane objęte są transakcją, oraz @Repository które pozwala nam na pobranie managera encji poprzez adnotację @PersistenceContext.

Aby nasza metoda działała poprawnie musimy dostarczyć jej obiekt accountDao który posłuży do sprawdzenia czy dany użytkownik już istnieje, manager encji który zapisze nasz obiekt w bacie, a także obiekty passwordEncoder oraz saltSource służące szyfrowaniu hasła.

Po wywołaniu metody obiekt accountDao znajduje użytkownika o podanej nazwie użytkownika i jeśli go nie znajdzie wyrzuca wyjątek UserNotFoundException i gdy ten wyjątek wystąpi możemy zapisywać użytkownika do bazy. Nasz administrator zapisywany jest metodą persist z obiektu entityManager. Dzięki tej metodzie nasza encja zostanie tymczasowo związana z rekordem w bazie danych co oznacza, że wszelkie modyfikacje administratora będą automatyczne odzwierciedlane w bazie danych (więcej o cyklu życia encji w dokumentacji). Gdy nasz użytkownik zostanie zapisany musimy zaktualizować mu hasło, dzieje się tak, gdyż hasło szyfrowane algorytmem sha256 z dodatkową solą w postaci identyfikatora użytkownika, który nadawany jest dopiero po zapisaniu go do bazy danych.

Po aktualizacji hasła przypisujemy naszemu użytkownikowi odpowiednie poziomy dostępu (może mieć ich więcej jak jeden) poprzez dodanie obiektów AccountRole do obiektu Administrator (dane zostają zapisane dzięki wcześniejszemu skonfigurowaniu powiązań @ManyToOne i @OneToMany).

Ciekawie wygląda również plik AccountDaoImpl który wyszukuje użytkowników po zadanym loginie (pełna zawartość pliku w repozytorium – zobacz koniec posta):


 public class AccountDaoImpl implements AccountDao {

 @Autowired
 HibernateTemplate template;

 @Autowired
 SessionFactory session;

 public Account findUsername(String username) throws  UserNotFoundException {
 DetachedCriteria dc = DetachedCriteria.forClass(Account.class);
 dc.add(Property.forName("username").eq(username));
 List users = template.findByCriteria(dc, 0, 1);

 if (users.size() > 0) {
 return (Account) users.get(0);
 }

 throw new UserNotFoundException();
 }

 }

W ciele metody findUsername zastosowane zostało wyszukiwanie po kryteriach, CriteriaApi daje ogromne możliwości w dynamicznym budowaniu zapytań do bazy, w naszym przypadku wskazaliśmy, że dane zapytanie dotyczyć będzie klasy Account (a tym samym tabeli odzwierciedlającej tą klasę), oraz dodaliśmy właściwość pola username ustalając że pole to powinno być równe wartości podanej w argumencie.

Wyświetlamy użytkowników

Jeśli nasi administratorzy zostali zapisani do bazy, warto by ich wyświetlić w liście, w tym celu stworzymy metodę obsługującą żądanie /administrator.html. Metoda ta znajduje się w pliku AdministratorController i wygląda następująco:


@RequestMapping(value = "/administrator")
 public ModelAndView index() {
 ModelAndView mav = new ModelAndView("/administrator/index");
 List<String> roles = new ArrayList<String>();
 roles.add("ROLE_ADMIN");
 List<Account> acc = accountService.listAccounts(roles);
 mav.addObject("accounts", acc);
 return mav;
 }

Metoda listująca pobiera z bazy wszystkich użytkowników o zadanym poziomie dostępu (AccountRole) po czym przekazujemy listę do widoku. Metoda wyszukująca użytkowników zaimplementowana jest w dwóch plikach, pierwszy AccountServiceImpl poniżej:


@Override
 @Transactional(readOnly=true)
 public List<Account> listAccounts(List<String> roles) {
 return accountDao.listAccounts(roles);
 }

Ma jedynie za zadanie wywołać metodę wyszukującą z obiektu AccountDaoImpl, warto wyjaśnić adnotację @Transactional, ponieważ wszystkie metody w klasie AccountServiceImpl objęte są transakcją warto przy metodach które nie zapisują danych zaznaczyć, że transakcja ma być traktowana jako tylko do odczytu, dzięki temu zyskujemy na wydajności.

Metoda wywołana przez powyższą metodę ma postać:

@Override
public List listAccounts(List roles) {
Criteria criteria = session.openSession().createCriteria(Account.class);
criteria.addOrder(Order.asc(„username”));
criteria.createCriteria(„accountRole”).add(Restrictions.in(„role”,roles));
return criteria.list();
}

Również tutaj zastosowanie znalazły kryteria, choć w troszkę inny sposób. W tym przypadku wyszukujemy danych dla klasy Account sortując je (criteria.addOrder) według nazwy użytkownika, przy czym wszystkie zwracane rekordy powinny posiadać powiązany rekord z tabeli reprezentowanej przez obiekt accountRole który pole role ma zadaną wartość (tu ROLE_ADMIN). Ponieważ do wyszukania poziomów dostępu musimy złączyć dwie tabele robimy to poprzez stworzenie nowych cryteriów „na obiekcie” już aktywnych kryteriów.

UPDATE 1

W komentarzach zauważyliście, że w aplikacji mieszam JPA z hibernatem, aby to poprawić stworzyłem nową metodę z wykorzystaniem JPA QL:


@Override
 public Collection<Account> listAccounts(Collection<AccountRole> roles){
 List<String> c = new ArrayList<String>(roles.size());
 for(AccountRole in : roles){
 c.add(in.getRole());
 }
 List<Account> accounts = entityManager.createQuery("SELECT a FROM Account a JOIN a.accountRole r WHERE r.role IN(?1)",Account.class).setParameter(1,c).getResultList();
 return accounts;
 }

Powyższa metoda przyjmuje jako argument kolekcję ról do jakich muszą należeć konta które pobieramy. Kolekcję obiektów musimy przekrztałcić na kolekcję prymitywów (w naszym wypadku ciągów znaków – STRING).
Następnie przy pomocy managera encji (entityManager) tworzymy zapytanie (createQuery) które przyjmuje tylko jeden parametr przekazywany poprzez setParameter.

Gdy znajdziemy wszystkich użytkowników przekazujemy ich listę do widoku i generujemy:


<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

<c:choose>
 <c:when test="${not empty accounts}">
 <c:forEach items="${accounts}" var="account" varStatus="status">
 ${status.index} ${account.username}
 </c:forEach>
 </c:when>
 <c:otherwise>
 <tag:message code="list.no-entry" />
 </c:otherwise>
</c:choose>

Co dalej

W kolejnej części tutoriala postaramy się zabezpieczyć nasz panel administracyjny poprzez zastosowanie SpringSecurity, ponieważ w tej chwili panel administracyjny wygląda biednie, wykorzystamy sitemesh, jsp oraz html by poprawić jego wygląd. A jeśli zostanie trochę miejsca i czasu zajmiemy się…. (może niespodzianka)

PS. Zauważyłem, że ta część tutoriala zajęła mi dużo czasu, postanowiłem rozbić go na mniejsze ale częściej występujące wpisy.

Jak pobrać projekt

Projekt został umieszczony na serwerach Kenai.com. Adres bezpośredni do projektu: http://kenai.com/projects/summer-bookstore.
Dodatkowo zostało uruchomione repozytorium GIT dla wszystkich chętnych i dostępny jest pod adresem: git://kenai.com/summer-bookstore~books0re-source


  1. Gdzie TOMCAT_HOME jest katalogiem głównym tomcata

Dnia 02.05.2010

Fire(wall)walking – spacer po zaporze ogniowej

F

irewalking w oryginalnym znaczeniu odnosi się do spaceru po ogniu / żarze. Od strony informatycznej stosuje się to pojęcie do dokładnej analizy sieci i zapory ogniowej od strony intruza. Analiza taka pozwala na ocenę stanu jej odporności i ukazania słabości. Można stwierdzić, że każdy audyt bezpieczeństwa sieciowego dotyczy przeprowadzania testów penetracyjnych. Wówczas idea opiera się na symulacji działań potencjalnego intruza. Testy penetracyjne lub tzw. pentesty przeprowadza się przy założeniu, że nie są znane: struktura oraz usługi badanej sieci.

Interesującą techniką umożliwiającą wykonanie takiej analizy sieci jest właśnie firewalking, czyli technika pierwotnie rozwinięta przez Mike’a Schiffman’a oraz Davida Goldsmith’a umożliwiająca skanowanie sieci chronionej zaporą ogniową (ang. firewall) oraz badanie konfiguracji samej zapory ogniowej, a dokładniej jej list kontroli dostępu (ang. ACL – Access Control List). Technika ta jest zbliżona do metody traceroute umożliwiającej badanie trasy pakietów w sieci. Pozwala sprawdzić, jakie rodzaje pakietów są przepuszczane przez firewall chroniący daną sieć – jakie porty są otwarte na zaporze (ang. open), a które są przekazywane do chronionej sieci (ang. pass throught). Wykorzystując firewalking można również odkryć topologię chronionej sieci (podsieci, routery i inne urządzenia).

Technika traceroute polega na wysyłaniu pakietów o rosnących wartościach TTL (ang. Time-To-Live) – z reguły zaczyna się od TTL=1 i inkrementuje o 1, a otrzymany ciąg odpowiedzi ICMP pozwala określić trasę do maszyny docelowej (czasami może istnieć wiele tras i odpowiedzi nie zawsze będą jednoznaczne), gdyż wartość pola TTL jest zmniejszana na każdym routerze pośredniczącym w transmisji. W momencie gdy osiągnie wartość 0, router gubi pakiet i zwraca komunikat ICMP Time Exceeded (wraz z swoim źródłowym adresem IP) informujący o tym, że host docelowy nie został jeszcze osiągnięty. Wartość TTL jest zwiększana dopóki nie zostanie zwrócony odpowiedni komunikat ICMP Destination Unreachable – jeśli host działa poprawnie jest to Port Unreachable , jeśli nie ma do niego sieciowego dostępu to generowany jest błąd Host Unreachable przez ostatni węzeł sieciowy. Możemy sprawdzić to na przykładzie:

agresor:~# traceroute 12.34.56.78
traceroute to 12.34.56.78 (12.34.56.78), 30 hops max, 40 byte packets
 1  agresor.pl (4.3.2.1)  0.330 ms  0.298 ms  0.285 ms
 2  router1.pl (66.666.666.1)  14.837 ms  15.755 ms  16.942 ms
 3  router2.pl (66.666.666.2)  17.552 ms  18.713 ms  20.156 ms
 4  router3.pl (66.666.666.3)  25.295 ms  26.736 ms  28.419 ms
 5  router4.pl (66.666.666.4)  29.615 ms  31.299 ms  32.260 ms
 6  router5.pl (66.666.666.5)  36.894 ms  37.583 ms  38.227 ms
 7  router6.pl (66.666.666.6)  39.929 ms  28.307 ms  29.118 ms
 8  target1.pl (12.34.56.78)   34.382 ms  33.379 ms  36.175 ms

Jak widać, aby traceroute dotarł do celu musiał zwiększać pole TTL, aż osiągnęło wartość 8. Zgodnie z założeniami, jeśli pakiet TTL miał wartość 7 to odpowiedź z routera nr 6 powinna zostać zwrócona w postaci komunikatu ICMP 11:

agresor:~# hping3 -V -1 -t 7 -c 1 12.34.56.78
using eth0, addr: 4.3.2.1, MTU: 1500
HPING 12.34.56.78 (eth0 12.34.56.78): icmp mode set, 28 headers + 0 data bytes
TTL 0 during transit from ip=66.666.666.6 name=66.666.666.6.isp.pl

--- 12.34.56.78 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

Co potwierdza analiza pakietów:

ICMP echo req (28 bytes) from agresor.pl to 12.34.56.78 (src HWaddr 000347ac3f20) on eth0
ICMP time excd (56 bytes) from 66.666.666.6 to agresor.pl (src HWaddr 0018d1398393) on eth0

Zwiększając TTL do 8 oraz używając pakietu UDP zamiast ICMP, powinniśmy otrzymać odpowiedni komunikat ICMP Destination Unreachable:

agresor:~# hping3 -V -2 -t 8 -c 1 12.34.56.78
using eth0, addr: 4.3.2.1, MTU: 1500
HPING 12.34.56.78 (eth2 12.34.56.78): udp mode set, 28 headers + 0 data bytes
ICMP Port Unreachable from ip=12.34.56.78 name=12-34-56-78.isp.pl

--- 12.34.56.78 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

Technika firewalking, podobnie jak traceroute, wysyła pakiety z odpowiednim polem TTL. Jest w pewnym sensie rozwinięciem traceroute – generowane pakiety mogą być różnych typów i z różnymi parametrami i numerami portów. W technice tej wymagane są trzy hosty – pierwszy, wykonujący firewalking, drugi pełniący rolę bramy / firewall’a oraz trzeci znajdujący się za bramą / firewall’em. Najpierw wyznaczana jest minimalna wartość TTL tak, aby pakiet mógł dotrzeć do bramy łączącej skanowaną sieć ze światem. Następnie badanie firewalla polega na wysyłaniu różnych rodzajów pakietów z polem TTL zwiększonym o 1 tak, aby pakiet mógł przeskoczyć firewall i zobaczyć jaki rodzaj hostu za nim stoi – kolejny router czy serwer. Przy badaniu pozostałych hostów w sieci również stosuje się wartość TTL zwiększoną o 1, przy badaniu zaś podsieci – wartości odpowiednio większe. Mike Schiffman i David Goldsmith w tym celu stworzyli aktywne narzędzie bezpieczeństwa sieciowego – firewalk, pozwalające na określenie jakie protokoły są przekazywane przez zaporę sieciową. Firewalk wysyła pakiety TCP lub UDP z zwiększonym TTL o 1 niż liczba routerów / bram do sprawdzanej zapory sieciowej. Jeśli firewall zezwala na tego rodzaju ruch – jest on przekazywany do celu znajdującego się wewnątrz chronionej sieci. Powodzenie tej metody zależy głównie od możliwości wychodzenia komunikatów ICMP Time Exceeded przez zdalną zaporę ogniową. Niestety firewalk nie jest już rozwijany dlatego bardzo prosty przykład zostanie zaprezentowany za pomocą takich narzędzi jak traceroute oraz hping. Pierwszym krokiem jest określenie minimalnej odległości do wybranego celu:

agresor:~# traceroute target2.pl
traceroute to target2.pl (12.12.21.21), 30 hops max, 40 byte packets
 1  agresor.pl (6.6.9.9)  0.619 ms  0.692 ms  0.702 ms
 2  router1.pl (212.25.5.69)  11.720 ms  12.877 ms  14.071 ms
 3  router2.pl (80.150.150.180)  15.522 ms  16.222 ms  17.441 ms
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *

Brak odpowiedzi na wysyłane pakiety UDP sygnalizowany jest znakiem gwiazdki “*” i prawdopodobnie wynika z filtrowania pakietów. Możemy przełączyć traceroute na pakiety ICMP ECHO:

agresor:~# traceroute -I target2.pl
traceroute to target2.pl (12.12.21.21), 30 hops max, 40 byte packets
 1  agresor.pl (6.6.9.9)  0.593 ms  0.654 ms  0.650 ms
 2  router1.pl (212.25.5.69)  9.397 ms  10.603 ms  13.069 ms
 3  router2.pl (80.150.150.180)  13.129 ms  13.763 ms  15.474 ms
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *

Jeśli efekt pozostaje ten sam to ostatnią próbą są pakiety TCP SYN:

agresor:~# traceroute -T target2.pl
traceroute to target2.pl (12.12.21.21), 30 hops max, 40 byte packets
 1  agresor.pl (6.6.9.9)  0.722 ms  0.681 ms  0.686 ms
 2  router1.pl (212.25.5.69)  29.681 ms  30.620 ms  31.052 ms
 3  router2.pl (80.150.150.180)  14.029 ms  15.226 ms  17.147 ms
 4  * * *
 5  * * *
 6  target2.pl (12.12.21.21)  59.753 ms  60.326 ms  61.914 ms
 7  target2.pl (12.12.21.21)  68.972 ms  58.191 ms  58.273 ms

Problemem, w tym przypadku wynika z firewalla umieszczonego prawdopodobnie na piątym i czwartym węźle, który filtruje pakiety typu UDP i ICMP uniemożliwiając tym samym dokładne zbadanie trasy pakietów. W wielu przypadkach jednak zapory pozwalają na przejście pakietów inicjujących połączenie TCP SYN do konkretnych portów, za którymi kryją się nasłuchujące usługi serwerów chronionych przez firewall. Na przykładzie powyżej widać, że dzięki tego rodzaju metodzie traceroute “automatycznie” wykrył, że za portem 80 (standardowy port w trybie -T, który można zmienić dzięki opcji -p [nr portu]) szóstego hosta (według numeracji traceroute) “chowa” się kolejny host. Jest to również dla nas podpowiedź, by w poszukiwaniu reszty otwartych portów używać skanowania typu TCP SYN:

agresor:~# nmap -PN -sS -p 1-80 target2.pl

Starting Nmap 4.62 ( http://nmap.org ) at 2010-05-03 17:44 CEST
Interesting ports on target2.pl (12.12.21.21):
Not shown: 78 filtered ports
PORT   STATE  SERVICE
21/tcp open   ftp
80/tcp open   http

Nmap done: 1 IP address (1 host up) scanned in 2.931 seconds

W tym zakresie portów została wykryta również usługa FTP. Ostatnią czynnością jest sprawdzenie “topologicznego” rozmieszczenia tych usług – zaczynając od portu FTP oraz minimalnego TTL równego 5 odpowiadającego ostatniemu filtrowi sieciowemu. Omijamy w ten sposób filtr pakietów na 4 węźle i sprawdzamy czy usługa FTP nie znajduje się już na 5‘tce:

agresor:~# hping3 -V -S -t 5 -c 1 -p 21 12.12.21.21
using eth0, addr: 6.6.9.9, MTU: 1500
HPING 12.12.21.21 (eth0 12.12.21.21): S set, 40 headers + 0 data bytes

--- 12.12.21.21 hping statistic ---
1 packets transmitted, 0 packets received, 100% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

Brak odpowiedzi na pakiet SYN sugeruje, że drugi Firewall nie udostępnia usługi FTP. Daje nam to tymczasowy obraz sieci:

[Router1]-[Router2]-[Firewall/Router]-[Firewall/Router]
                                              |
                                            21/80 TCP
                                              |
                                      [Router ? Serwer]
                                              |
                                      [Router ? Serwer]

Sprawdzamy czy usługa FTP nie znajduje się na 6‘tce:

agresor:~# hping3 -V -S -t 6 -c 1 -p 21 12.12.21.21
using eth0, addr: 6.6.9.9, MTU: 1500
HPING 12.12.21.21 (eth0 12.12.21.21): S set, 40 headers + 0 data bytes
len=46 ip=12.12.21.21 ttl=59 DF id=0 tos=0 iplen=44
sport=21 flags=SA seq=0 win=5840 rtt=39.9 ms
seq=379077794 ack=114171087 sum=5b5a urp=0

--- 12.12.21.21 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 39.9/39.9/39.9 ms

W odpowiedzi otrzymaliśmy pakiet SYN/ACK, co oznacza, że usługa FTP znajduje się na szóstym węźle liczonym według listingu traceroute. W dodatku TTL=59, który pokonał 5 węzłów sieciowych sugeruje, że usługa znajduje się na serwerze Linuksowym (TTL=64 – 5 = 59). W ten sam sposób możemy sprawdzić czy serwer FTP nie jest zarazem serwerem WWW:

agresor:~# hping3 -V -S -t 6 -c 1 -p 80 12.12.21.21
using eth0, addr: 6.6.9.9, MTU: 1500
HPING 12.12.21.21 (eth0 12.12.21.21): S set, 40 headers + 0 data bytes
TTL 0 during transit from ip=12.12.21.21 name=target2.pl

--- 12.12.21.21 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.0/0.0/0.0 ms

Otrzymaliśmy komunikat ICMP Time Exceeded, co oznacza, że węzeł 6 przekazuje pakiety kierowane na port 80 dalej do węzła 7, co potwierdza zwiększenie TTL o 1:

agresor:~# hping3 -V -S -t 7 -c 1 -p 12.12.21.21
using eth0, addr: 6.6.9.9, MTU: 1500
HPING 12.12.21.21 (eth0 12.12.21.21): S set, 40 headers + 0 data bytes
len=46 ip=12.12.21.21 ttl=58 DF id=0 tos=0 iplen=44
sport=80 flags=SA seq=0 win=5840 rtt=44.1 ms
seq=27375734 ack=1918260500 sum=7956 urp=0

--- 12.12.21.21 hping statistic ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 44.1/44.1/44.1 ms

Daje nam to następujący obraz sieci:

[Router1]-[Router2]-[Firewall/Router]-[Firewall/Router]
                                              |
                                            21/80 TCP
                                              |
                                   [Router 80 / Serwer 21]
                                              |
                                         [Serwer 80]

W celu ochrony przed skanowaniem tą metodą można filtrować wychodzące pakiety ICMP 11. Większość zapór sieciowych powinna zawierać reguły całkowicie blokujące ruch komunikatów ICMP używanych przy poleceniach ping i traceroute do Internetu (w przypadku małych sieci ze względu na możliwości skanowania hostów za pomocą protokołu ICMP warto rozważyć blokadę wszystkich rodzajów wychodzących komunikatów ICMP). Wyjątkiem mogą być objęte tylko zaufane systemy, z których możemy przeprowadzić szybką diagnostykę. Efekt ten możemy uzyskać na przykład poprzez odpowiednie wpisy iptables:

iptables -A INPUT -p icmp --icmp-type 8 -s [zaufane IP] -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type 0 ! -d [zaufane IP] -j DROP
iptables -A OUTPUT -p icmp --icmp-type 11 ! -d [zaufane IP] -j DROP

Należy również pomyśleć odpowiednich regułach dla adresaców IP znajdujących się wewnątrz chronionej sieci tak, aby nie zablokować im możliwości używania narzędzia traceroute. Blokada wychodzących komunikatów ICMP 11 spowodowała również blokadę wykrywania przez traceroute w trybie TCP SYN przekazywania ruchu na porcie 80′tym:

agresor:~# traceroute -T target2.pl
traceroute to target2.pl (12.12.21.21), 30 hops max, 40 byte packets
 1  agresor.pl (6.6.9.9)  0.684 ms  0.657 ms  0.712 ms
 2  router1.pl (212.25.5.69) (213.25.2.66)  12.479 ms  14.224 ms  16.832 ms
 3  router2.pl (80.150.150.180)  20.494 ms  20.681 ms  20.893 ms
 4  * * *
 5  * * *
 6  target2.pl (12.12.21.21)  66.721 ms  57.522 ms  57.994 ms

Dodatkowym maskowaniem dla blokady wychodzących komunikatów ICMP 11 jest filtrowanie wszystkich pakietów z niską wartością TTL (np. < 5) i zwracanie odpowiedniego komunikatu ICMP 3:

iptables -A INPUT -i eth0 -p all -m ttl --ttl-eq 0 -j DROP
iptables -A INPUT -i eth0 -p all -m ttl --ttl-lt 5 ! -s [zaufane IP] -j REJECT --reject-with icmp-port-unreachable
iptables -A FORWARD -p all -i eth0 -o eth1 -m ttl --ttl-eq 0 -j DROP
iptables -A FORWARD -p all -i eth0 -o eth1 -m ttl --ttl-lt 5 ! -s [zaufane IP] -j REJECT --reject-with icmp-port-unreachable

W przypadku wpisu dotyczącego przekazywania pakietów (łańcuch FORWARD) eth0 jest interfejsem zewnętrznym (publicznym), a eth1 jest interfejsem wewnętrznym (lokalnym). Dodatkowo blokujemy pakiet z wartością TTL 0. Tego rodzaju pakiet może istnieć jedynie wtedy, gdy router przekazujący pakiet do naszej sieci działa wadliwie lub pakiet pochodzi z komputera w tej samej podsieci. Oprócz podjęcia kroków utrudniających łatwe wykonanie tej techniki sam firewall powinien być wyposażony w system IDS/IPS (ang. Intrusion Detection System / Intrusion Prevention System) umożliwiający wykrywanie i blokowanie jednej z głównych faz tego ataku, czyli skanowania portów za pomocą różnych technik i protokołów.

Więcej informacji: K. Folga, Firewalking, czyli spacer po zaporze ogniowej, Networld 1 czerwca, 2005, hping, Parametry jądra i protokołów sieciowych

Dnia 30.04.2010

Microsoft znowu nabroił

J

estem od jakiegoś czasu wielkim zwolennikiem cyfrowego podpisu w poczcie elektronicznej. Kiedy zaobserwowałem przerażający trend związany z wprowadzaniem dziurawych koncepcji ochrony marki w poczcie elektronicznej (np. SPF lub Microsoft Sender ID), który bezmyślnie popierają największe polskie i zagraniczne portale i firmy internetowe, zacząłem szukać alternatywy. Stwierdziłem, że jedynym sensownym wyjściem jest nie zabranianie innym wykorzystywania mojego adresu jako adresu nadawcy, lecz przekonanie moich rozmówców, że tylko wiadomości cyfrowo podpisane pochodzą ode mnie…

Artykuł ten został opublikowany w numerze 02/2006 (16) magazynu hakin9.

Artykuł w formacie PDF

Dnia 28.04.2010

Mały bootloader LILO

P

odczas startu komputera wszystkie urządzenia są testowane przez BIOS w celu nawiązania z nimi połączenia i wykrycia usterek w ich działaniu. Fazę tę określamy mianem POST (Power-On-Self-Test). Następnie w pamięci CMOS przy niezainicjonowanych przerwaniach odczytywane są dane na podstawie, których odbywa się inicjalizacja urządzeń I/O (Input / Output) obsługiwanych przez BIOS. Później zaczyna działać procedura BIOS-u zwana bootstrap loaderem, sprawdzając kolejno wszystkie urządzenia i napędy w poszukiwaniu sektora startowego, z którego da się uruchomić system operacyjny. Proces wyszukiwania urządzenia zdolnego do uruchomienia OS-u uzależniony jest od ustawień BIOS-u.

Standardowo jest to pierwszy sektor dyskietki, dysku twardego lub płyty CD. Gdy urządzenie zdolne do uruchomienia systemu zostanie zlokalizowane bootstrap odnajduje pierwszy sektor na dysku (MBR – Master Boot Record), wykonując jednocześnie zawarty w nim kod programu, którego zadaniami są identyfikacja aktywnej partycji, załadowanie z jej pierwszego sektoru, tzw. rekordu ładującego, umieszczonego tam kodu oraz przekazanie mu sterowania. W systemie Slackware Linux najczęściej wykorzystywanym programem ładującym (bootloaderem) jest LILO (Li-nuks Lo-ader).

Jedną z metod uzyskania dostępu do konta root omijając proces autoryzacji jest podanie podczas procedury botowania dodatkowych parametrów np. linux single, initrd=/dev/fd0, init=/bin/bash. Po wydaniu tego ostatniego możemy uzyskać bezpośredni dostęp do linii poleceń w trybie administratora, następnie zamontować system plików w trybie read-write (mount -o remount,rw /) oraz dokonać edycji plików /etc/shadow i /etc/passwd w celu usunięcia hasła oraz otrzymania bezproblemowego dostępu do uprawnień administratora systemu. Zabezpieczeniem się przed takimi opcjami jest ustawienie hasła na wykonywanie poleceń ładowania z dodatkowymi parametrami przez naszego loadera.

     Przy końcu instalacji system Slackware pyta się, czy ma zainstalować bootloadera i w jaki sposób? Instalacja bootloadera może odbyć się poprzez dwa sposoby: 1) własne ustawienie opcji botowania; 2) pozwolenie Linuksowi na automatyczne przekazanie parametrów do bootloadera i poproszenie użytkownika o ich zweryfikowanie. Każda z tych metod jest dobra i zależy od naszej znajomości opcji botowania systemu. Jeśli czujemy się na siłach, możemy sami skonfigurować loadera, lub pozwolić, aby ta czynność została wykonana przez system i przy weryfikacji wprowadzić własne poprawki. LILO wczytuję opcje ładowania z wcześniej załadowanego i skonfigurowanego przez użytkownika pliku konfiguracyjnego z tego powodu, że w MBR posiada tylko 512 bajtów długości – pierwsze 446 bajtów zajmuje program bootstrap (IPL) dalszą część MBR-a to tablica partycji zawierająca 4 struktury (każda po 16 bajtów), opisujące poszczególne partycje podstawowe. MBR kończą 2 bajty o wartości 0×55AA zapisanej szesnastkowo. W sumie mamy zatem 466 + (4×16) + 2 = 512. Jeśli używamy LILO w celu ustawienia hasła musimy edytować jego plik konfiguracyjny (/etc/lilo.conf) i dodać do niego w sekcji odwołującej się do załadowania aktualnego jądra systemu takie zmienne jak “password” i “restricted“. Oto przykładowy plik lilo.conf po dokonaniu zmian:

# LILO configuration file
# generated by 'liloconfig'
append="vt.default_utf8=1"
boot = /dev/sda
lba32
compact
  bitmap = /boot/slack.bmp
  bmp-colors = 255,0,255,0,255,0
  bmp-table = 60,6,1,16
  bmp-timer = 65,27,0,255
prompt
timeout = 20
change-rules
  reset
vga = 791
# Linux bootable partition config begins
image = /boot/vmlinuz
  root = /dev/sda2
  label = Slackware
  read-only
  password = singleroot
  restricted
# Linux bootable partition config ends

Po wprowadzeniu zmian wczytujemy nowe ustawienia poleceniem: lilo -v. Funkcja “restricted” pod zmienną “password” spowoduje, że podanie hasła wymagane będzie tylko wtedy, gdy użytkownik zamierza podać dodatkowe parametry ładowania systemu. Jest ona wymagana, gdyż w przypadku restartowania serwera zdalnie – wymagane by było podawanie każdorazowo hasła umożliwiającego dalsze ładowanie się systemu. Jeśli posiadamy więcej niż jedno jądro, wyżej wymienione zmienne umieszczamy pod każdą sekcją odwołującą się do danego jądra. Następnie zabezpieczamy plik lilo.conf przed poznaniem hasła przez innych użytkowników komendą: chmod 600 /etc/lilo.conf.

Innym sposobem ochrony systemu przed trybem pojedynczego użytkownika jest uniemożliwienie wszystkim użytkownikom wprowadzenia jakichkolwiek poleceń z klawiatury podczas uruchamiania LILO, poprzez ustawienie czasu oczekiwania na zero. Takie ustawienie można wymusić wprowadzając podane tu polecenie na początku pliku /etc/lilo.conf (jest to wymagane zgodnie z zabezpieczeniami C2, opisanymi w odpowiedniej specyfikacji Orange Book):

timeout = 0

Wyłączenie automatycznego uruchamiania jest możliwe poprzez dodanie wiersza: prompt w pliku /etc/lilo.conf (przed fragmentami dotyczącymi ustawień dla każdego z obrazów). Z tego powodu, jeżeli włamywacz w pewien sposób odkryje, jak zdalnie zmienić główny sektor rozruchowy dysku, zainstaluje nowe jądro lub w inny sposób spowoduje zniszczenia, nie będzie mógł wczytać nowej konfiguracji systemu. Oczywiście, po każdej awarii powinny zostać podjęte czynności sprawdzające, w celu wykluczenia prawdopodobieństwa, że została ona spowodowana przez potencjalnego włamywacza.

Wszystkie wpisy w pliku /etc/lilo.conf, które będą mogły zostać wybrane podczas startu systemu, to znaczy wpisy określające systemy, które można wczytać, powinny reprezentować ostrożnie skonfigurowane jądra, jak chociażby jądra systemu Linux lub innego podobnego systemu. Mówiąc prościej, żadne z nich nie powinno udostępniać trybu pojedynczego użytkownika lub systemu plików bez potwierdzenia przez żądającego posiadania odpowiednich praw dostępu. Żaden z systemów, który można uruchomić, nie powinien być systemem niezabezpieczonym (szczególnie podatnym na lokalne ataki, które pozwolą na rozszerzenie praw).Bouns:     Wybierając miejsce, w którym będzie zainstalowane LILO musimy mieć na uwadze czy posiadamy jeden system i jest nim Linux czy oprócz niego posiadamy jeszcze inne systemy np. Windows, DOS. Jeżeli posiadamy tylko jeden system na naszym komputerze, to instalacja LILO powinna odbyć się w MBR: Master Boot Record. Jednak jeśli posiadamy inne systemy i nasza partycja z Linuksem jest oznaczona jako botowalana (w tym przypadku powinna to być pierwsza partycja na dysku) to powinniśmy wybrać opcję Root superblok na naszej partycji Linuksowej. Może się także zdarzyć że po instalacji Linuksa nasze LILO, zamiast się uruchomić wyświetla tylko dwie pierwsze litery “LI”. Oznacza to, że system (dokładnie katalog /boot z obrazem jądra) został zainstalowany powyżej 1024 cylindra dysku. Aby rozwiązać ten problem należy podczas instalacji partycje – Linux Native zainstalować poniżej 1024 cylindra, lub stworzyć niewielką, dodatkową partycje na początku dysku, i przydzielić jej katalog /boot. Poza tym LILO posiada bardzo ciekawą funkcję, która daje możliwość skopiowania go na dyskietkę, dzięki temu będziemy mogli uruchomić system nawet wtedy, gdy przypadkowo uszkodzimy dysk.

Więcej informacji: man lilo.conf, Lilo HowTo, LILO

Przeprowadzka

Minął ponad miesiąc od poprzedniego wpisu, który sprawiał wrażenie optymistycznego i konstruktywnego, a tymczasem cisza jak makiem zasiał. Nie znaczy to jednak, że był to wpis na wiatr i czcze słowa. Wręcz przeciwnie - myśl o reinkarnacji ewoluowała i w efekcie ogłaszam dzisiaj przeprowadzkę bloga. (szczegóły w dalszej części wpisu)

Dnia 24.04.2010

Zdalne zarządzanie – NetBus Pro

A

rtykuł przedstawi w wyczerpującym zakresie trojana NetBus. W prosty i zwięzły sposób wyjaśni zasadę działania oraz poszczególne funkcje aplikacji. NetBus jest jednym ze starszych trojanów, jakie ukazały się w sieci – powstał w 1998 roku. Został napisany przez Szweda, Carla Fredrika Neiktera. Jest to jeden z nielicznych dobrych programów typu backdoor.

Artykuł ten został opublikowany w numerze 05/2008 (37) magazynu hakin9.

Artykuł w formacie PDF

Dnia 23.04.2010

Cyberprzestępstwo w społeczeństwie informacyjnym

P

owstrzymywanie aktywności przestępczej w Internecie głównie zależy od dwóch czynników: bardziej bezpiecznej infrastruktury Internetu, przeimplementowanej od postaw z uwzględnieniem lepszych mechanizmów bezpieczeństwa oraz skoordynowanych czynności oferujących lepszą edukację początkowych użytkowników Internetu. Można przewidywać, że drugiej generacji Internet będzie szybszy, większy, ale przede wszystkim bezpieczniejszy i trudniejszy do zaatakowania. Niestety jeszcze bardzo dużo pracy zostało do wykonania na tym polu.

     Cyberprzestępcy wykorzystują w pełni zalety anonimowości, tajemnic oraz złożoności połączeń oferowanych przez Internet dzięki temu mając możliwość napaści na fundamenty naszego nowoczesnego społeczeństwa informacyjnego. Cyberprzestępstwo może obejmować botnety, wirusy, cyberterroryzm, cyberstręczycielstwo, cyberpornografię, ataki Denial of Service i inne, hacktywizm, kradzieże tożsamości, szkodliwe oprogramowanie czy spam. Rządy wprowadziły odpowiednie przepisy prawne, by dotrzymać kroku w walce z cyberprzestępcami, którzy kosztują globalną gospodarkę miliardy rocznie. Policja próbuje wykorzystywać takie same narzędzia jak oni w celu lepszego ich tropienia oraz doprowadzania przed wymiar sprawiedliwości, lecz nadal to za mało.

     Powiązane ze światem komputerowym przestępstwa datują na początki rozwoju samych komputerów. Coraz większa dostępność globalnej łączności między komputerami za pomocą Internetu – wniosła pojęcie cyberprzestępstwa do społecznej świadomości naszego społeczeństwa informacyjnego, którego początki zaczynają się dopiero w 21 wieku. W 1995 roku, gdy World Wide Web przeżywało swoje początki rozwoju, futurystyczny Gen Stephens pisał na temat teraźniejszości i przyszłości cyberprzestępstw. Wspomniał on wówczas: “Biliony dolarów w stratach zostały już odkryte. Miliardy zostały przepuszczone nieodwracalnie. Tryliony zostaną ukradzione niezauważalnie, przez pojawiającego się w 21 wieku doskonałego przestępcę – przestępcę cyberprzestrzeni.” Opierając się na jego przewidywaniach w artykule pt. “Cybercrime in the year 2025″ z 2008 roku w czasopiśmie Futurist, Stephens zauważył, że on i inni przewidują dopiero prawdziwe nadejście cyberprzestępczości: “Poprawnie prognozowałem gwałtowny wzrost użycia telefonów komórkowych, a za tym idących oszustw telefonicznych; wzrost cyberataków oraz oszustw finansowych przeciwko rządom, oraz gospodarce; masowe kradzieże oraz defraudacje środków z kart kredytowych; kradzieże ludzkich tożsamości przez chciwych i skorumpowanych pracowników urzędowych; więcej cyberpornografii; cyberstręczycielstwa; cybernękania; cyberzemsty i użycia metod biometrii oraz kryptografii do ochrony danych w cyberprzestrzeni.” Warto przypomnieć, że dystyngowany termin przestępczości komputerowej określa zbiorowe lub różne przestępstwa popełnione za pomocą usług dostępnych w Internecie (WWW, e-mail, itd.), są to m.in.: kradzieże danych osobowych lub finansowych; rozprzestrzenianie szkodliwego oprogramowania, w tym też wirusów; używanie cudzych komputerów do wysyłania wiadomości spam (też botnety); przeprowadzanie ataków DoS na różne sieci, strony (tu też botnety); źle postrzegany hacktywizym sponsorowany przez organizacje osiągające zyski z wyrządzonych szkód; cyberstręczycielstwo, w którym “seksualni drapieżcy” za pośrednictwem Internetu wyszukują na czatach, serwisach społecznościowych czy innych stronach swoje ofiary; cyberzastraszenie, w którym jednostki są nękane przez innych, powodując poważne zastraszenie umysłowe; cyberpornografia, w której wykorzystuje się Internet do rozprzestrzeniania treści pornograficznych z udziałem dzieci oraz dorosłych; hazard internetowy oraz piractwo oprogramowania; cyberterroryzm, w którym wykorzystuje się Internet do szerzenia propagandowych treści, rekrutacji terrorystów, planowania ataków czy ich przeprowadzania na obiekty w Sieci i rzeczywistości.

     Ustawowe wprowadzenie w życie prawa, które zobowiązuje się do walki poprzez identyfikowanie, aresztowanie oraz skazanie technologicznych dzikusów, nastąpiło w momencie, gdy socjolodzy próbowali dotrzeć do sedna złożoności cyberprzestępstw. Federalny Urząd Śledczy U.S.A. (FBI) ma rozłożone cyber-oddziały przy każdym z jego 56′ściu biur na terenie Stanów Zjednoczonych – wspierających 70’siąt narodowych grup specjalnych, popieranych w dodatku przez ogólnokrajowy wywiad o nazwie Internet Crime Complaint Centre (ang. Ośrodek Internetowej Kryminalistyki). Pole cyberprzestępstw zrodziło dział cyberkryminalistyki definiowany jako “nauka o przyczynowości przestępstw, które następują w cyberprzestrzeni oraz ich wpływ na przestrzeń rzeczywistości.” Zakres cyberprzestępstw pozostaje naprawdę olbrzymi, a najgorszym faktem jest jego ciągły rozrost wraz z popularyzacją technologii. W 2007 roku gospodarka U.S.A. straciła 240 milionów dolarów na walkę z cyberprzestępcami. Jest to kwota o 40 milionów większa niż w 2006 roku (biorąc pod uwagę kurs dolara oraz raporty, które zostały oficjalnie zamieszczone na podstawie spraw odbytych oficjalnie w sądach). Według jednej z internetowych firm zajmujących się bezpieczeństwem przemysł wirtualnych przestępstw, posiada wartość około 200 miliardów dolarów, dorównując takim wykroczeniom jak sprzedaż nielegalnych leków czy pranie brudnych pieniędzy. W Europie ponad ćwierć użytkowników należących do Unii Europejskiej przyznała się do faktu, bycia ofiarom cyberprzestępstwa w różnej postaci. Ponieważ, coraz więcej i więcej ludzi używa Internetu, by robić zakupy, komunikować się z bankiem i płacić rachunki – krąg tego zjawiska znajduje ciągle nowych odbiorców. Oczywiście głównie dzięki zdrowemu rozsądkowi istnieją kroki zapobiegawcze przed kradzieżami e-kart kredytowych i innymi przekrętami oraz groźbami, ale cyberprzestępcy nie ustają w tym obszarze w dużej mierze dzięki brakowi edukacji przeciętnego konsumenta.

“Niezależnie od tego, czy ktoś był ofiarą kradzieży tożsamości, karty kredytowej lub cyberstręczycielstwa – nawet po restytucji efekty z odniesionych urazów mogą być porównywalne do takich przestępstw jak rabunek z pobiciem, czy gwałt.”

Niektóre przejawy cyberprzestępstw – jakie jak zły hacktywizm – są rzekomo umotywowane przez szlachetne zamiary, z których nadużyć tak naprawdę czerpią zyski rządy oraz duże korporacje. Często takie ataki zaczynają się od przesłania czytelnych wiadomości na oficjalnych witrynach rządowych. Nie są one bezpośrednio motywowane zyskiem materialnym, ale masowym zwróceniem uwagi opinii publicznej na drażniący (według atakujących) problem. Aczkolwiek inne formy takie jak: cyberstręczycielstwo, cybernękanie czy cyberterroryzm nastawione są już na bardziej brutalne zachowanie. Pomimo że wpływ cyberprzestępstw na gospodarkę jest bezsporny, to swoją uwagę należy również przenieść na społeczne implikacje, jakie niesie za sobą to zjawisko. Psycholodzy i psychiatrzy są w stanie pomagać radzić sobie ofiarą z kradzieżami tożsamości, stręczycielstwem seksualnym lub bankructwem finansowym, podczas gdy socjolodzy tak naprawdę jeszcze nie potrafią przyjąć oficjalnego stanowiska wobec szerszego wpływu cyberprzestępstw na społeczeństwo. Ataki w cyberprzestrzeni od swoich współczesnych fundamentów są wymierzone w technicznie zaawansowane społeczeństwa, ze względu na fakt, iż oferują one bardzo szybką możliwość wycieku danych z komputera przez Internet. Podstawowym poziomem, jaki przyjmują cyberprzestępcy, są często indywidualne jednostki z podstawową wiedzą technologiczną, które dopiero odnajdują się w świecie, w którym Internet coraz bardziej odgrywa znaczącą rolę. W ich życiu społecznym, jak i prywatnym. Na tym poziomie cyberprzestęstwo ogranicza się do oszukania innych – przez bardziej zaawansowanych użytkowników. Potrafią oni wykorzystać trochę bardziej wyrafinowane techniki w celu wyciągnięcia np. informacji o numerach kont czy polis ubezpieczeniowych.

     Podczas gdy w wielu sytuacjach ofiara odzyskuje swoje stracone pieniądze lub tożsamość, to i tak zdarzenie to odciska na niej głęboki uraz np. do Internetu czy innych oznak współczesnego życia, a tym samym cyberprzestępstwa pozbawiają jego lub ją wielu wygód, jakie ofiaruje dzisiaj gospodarka informacyjna. Specjaliści zauważyli, że uderzenia te następują na wielu poziomach. Pierwszym jest gospodarka, która obejmuje kradzieże milionów może nawet miliardów dolarów, co roku. W dodatku na poziomie tym, jednostki czy instytucje są narażane na dodatkowe koszty związane z zaopatrzeniem się w oprogramowanie gwarantujące im minimalny poziom bezpieczeństwa. Drugi występuje na szerszym kulturalnym poziomie, w którym cyberprzestępstwo skutecznie pomaga zniechęcić do Internetu oraz ogólnie nowych technologii. To w ofiarach wzbudza pewną nostalgię, strach przed nieznanym oraz chęć powrotu do milszej i wygodniejszej (już znanej) przeszłości, w której takie zjawisko nie było jeszcze znane. Naturalnie taki widok może przysłonić wizję, w której przestępstwa kroczyły z ludzkością od samego jej początku, niemniej jednak powoduje to u jednostek odsunięcie na boczny tor ekonomii informacyjnej. Paradoksalnie zjawisko to może sprawić, że osoby, które były kiedyś ofiarami jednego z rodzajów ataków automatycznie staną się bardziej podatne na inne rodzaje, ze względu na ich brak świadomości o nowych formach, które ciągle ewoluują. Raz sparzona osoba, będzie zwracać większą uwagę na jeden punkt, krytyczny, który już w nowej formie ataku nie jest wcale istotny. Trzecim i może najbardziej niepokojącym poziomem ze wszystkich przedstawionych powyżej jest efekt, jaki stwarza cyberprzestępstwo na jednostki w życiu codziennym. Czasami są to na tyle poważne urazy, że powodują nieodwracalne komplikacje na drodze, gdzie należy sprostać żądaniom życia.

Felieton ten pochodzi z magazynu: Hakin9 Nr 12 (54) Grudzień 2009.

Dnia 22.04.2010

C#.NET – Podsłuchiwanie klawiatury

S

komplikowane i często aktualizowane hasło, które oprócz liter zawiera również cyfry i znaki specjalne, to bardzo dobry sposób obrony przed nieautoryzowanym dostępem. Pod warunkiem, że nie jesteśmy podsłuchiwani w trakcie jego wprowadzania…

Artykuł ten został opublikowany w numerze 01/2008 (33) magazynu hakin9.

Artykuł w formacie PDF

Dnia 20.04.2010

Dzielenie dużych logów na małe

P

rzeglądanie dużych logów systemowych posiadających zajętość czasami dochodzącą do kilku gigabajtów może być bardzo kłopotliwe dla wielu edytorów tekstowych. Najlepszym rozwiązaniem w tej sytuacji wydaje się pocięcie ich na mniejsze pliki, które łatwiej i bardziej płynnie wyświetlają swoją zawartość, a przede wszystkim dają się szybciej przeszukiwać.

Do tego celu możemy użyć prostego narzędzia o nazwie split. Jego działanie polega na określeniu pliku do pocięcia, rozmiarów mniejszych kawałków oraz ich prefiksu. Na przykład do pocięcia pliku maillog.log o rozmiarze 27 MB na kawałki liczące po 1 MB wystarczy wydać polecenie:

split -b1m maillog.log maly_maillog_

A w bieżącym katalogu zostaną utworzone następujące pliki:

27M     ./maillog.log
1.0M    ./maly_mailog_aa
1.0M    ./maly_mailog_ab
1.0M    ./maly_mailog_ac
1.0M    ./maly_mailog_ad
1.0M    ./maly_mailog_ae
1.0M    ./maly_mailog_af
1.0M    ./maly_mailog_ag
1.0M    ./maly_mailog_ah
1.0M    ./maly_mailog_ai
1.0M    ./maly_mailog_aj
1.0M    ./maly_mailog_ak
1.0M    ./maly_mailog_al
1.0M    ./maly_mailog_am
1.0M    ./maly_mailog_an
1.0M    ./maly_mailog_ao
1.0M    ./maly_mailog_ap
1.0M    ./maly_mailog_aq
1.0M    ./maly_mailog_ar
1.0M    ./maly_mailog_as
1.0M    ./maly_mailog_at
1.0M    ./maly_mailog_au
1.0M    ./maly_mailog_av
1.0M    ./maly_mailog_aw
1.0M    ./maly_mailog_ax
1.0M    ./maly_mailog_ay
1.0M    ./maly_mailog_az
440K    ./maly_mailog_ba
53M     .

Rozmiary mniejszych plików możemy zmieniać według własnego upodobania używając wartości b (bajtów), k (Kilobajtów) lub m (Megabajtów). Ponadto możemy określać długość i format sufiksu dodawanego automatycznie przez program do pociętych plików.
Więcej informacji: Strona manualna dla narzędzia split: man split

Dnia 19.04.2010

Uwierzytelnianie i autoryzacja w ASP.NET 2.0

J

ak wiadomo, urzędom nie są potrzebni obywatele, szpitale najlepiej funkcjonują bez pacjentów, a profesorom studenci tak naprawdę tylko przeszkadzają. Zgodnie z tą zasadą witryny internetowe najbezpieczniejsze są wówczas, gdy pracują off-line. Niestety smutna rzeczywistość zmusza administratorów do pogodzenia się z obecnością użytkowników.


Artykuł ten został opublikowany w numerze 6/2007 (26) magazynu hakin9.

Artykuł w formacie PDF

Dnia 15.04.2010

BS

Wydarzenia w rodzaju katastrofy samolotu rządowego pod Smoleńskiem są znakomitym bodźcem do rozwoju sportu i rekreacji. Przynajmniej w moim wypadku. Dzieje się tak dlatego, że nie da się wtedy na dłuższą metę obcować z mediami elektronicznymi, które taką historię potrafią przeżuć, przetrawić, wypluć a potem znowu przeżuć. Do zajechania materiału, do upadłego, do momentu, gdy zaczyna się komentować komentarze zdobyte w ramach zbierania materiału dotyczącego jeszcze innych komentarzy. Państwo wybaczą, ale ja nie mogę. To gwałci te resztki wrażliwości, które mam w sobie.

W ramach zatem odtrutki – oraz oczywiście komentarza – pozwolę sobie wkleić materiał stacji ONN, który dość dobrze ilustruje problem. Osoby będące w żałobie ostrzegam, że jest to śmieszne, więc pewnie powinny sobie darować.

Dnia 13.04.2010

Spring Framework 3.0 Tutorial – cz 1 – przygotowanie projektu, witaj świecie

Zanim przystąpimy do tworzenia projektu warto odpowiednio przygotować sobie zaplecze techniczne. Z racji, że w eclipse pisze znaczna część firm (przynajmniej polskich), a ja jeszcze z niego nie korzystałem w tego typu projektach postanowiłem, że to będzie dobry moment by się z nim zmierzyć.
Eclipse wyposażony zostanie dodatkowo we wtyczkę m2Eclipse która pomoże mi w zarządzaniu maven-em. Aplikacja uruchomiona zostanie na kontenerze aplikacji Tomcat, a dane przechowam w bazie PostreSQL. Z racji, że źródła umieszczane będą w zewnętrznym repozytorium opartym o GIT potrzebny jest też ten właśnie program, ja preferuję korzystać z gita poprzez konsolę, oczywiście jeśli ktoś woli można doinstalować odpowiednią wtyczkę bądź nakładkę graficzną.

Co przyda się przy tworzeniu:

Podstawowe założenia

Aplikacja składać się będzie z dwóch modułów, panelu administracyjnego dostępnego tylko i wyłącznie dla użytkowników z poziomem dostępu ADMIN oraz części otwartej do której dostęp będą mieli wszyscy internauci (za wyjątkiem obszarów które będą wymagały zalogowania się z poziomem dostępu CLIENT). Podział taki można wykonać na dwa sposoby, pierwszym jest stworzenie jednego projektu w którym dokonamy logicznego podziału widoków jak i kontrolerów na panel administracyjny oraz strefę otwartą, spring security dodatkowo zabezpieczy wejście. Wyniki składane będą przez sitemesh dzięki któremu można stworzyć oddzielny layout dla panelu administracyjnego oraz dla części otwartej. Jedynym plusem tego rozwiązania jest łatwość operowania plikami w projekcie(o ile nie jest duży), wszystko mamy w jednym miejscu dzięki czemu nie trzeba przechodzić między projektami i szukać plików jeśli tylko chcemy coś zmienić. Niestety przeciw temu rozwiązaniu jest cała reszta, kod staje się mniej czytelny, potrzebne są dodatkowe obejścia które rozdzielać będą żądania do panelu administracyjnego jak i strony klienckiej, nie możliwe jest również umieszczenie osobno części administracyjnej na np. naszym serwerze wewnętrznym. Pomimo tego, że pliki poukładane mamy w jednym projekcie co z początku może wydawać się plusem w większych projektach staje się zmorą, gdyż większa ilość plików powoduje utrudnienia w odszukaniu tego który chcemy zmodyfikować (wiem, przeżyłem to na własnej skórze).

Drugim rozwiązaniem jest stworzenie osobnych projektów dla panelu administracyjnego oraz części klienckiej. Dzięki takiemu rozwiązaniu zachowujemy pewien ład i porządek w strukturze folderów projektów oraz plikach (mniej plików mniej problemu). Dzięki rozdzieleniu plików konfiguracyjnych zyskujemy większą elastyczność oraz możliwość łatwiejszego dostosowania ustawień. Część wspólna obu projektów (klasy związane z obiektami bazy danych) trzymane są w projekcie który dołączany jest jako biblioteka. Mój wybór padł właśnie na tą metodę.

Podsumowując, utworzone zostaną 3 projekty: bookstore, bookstore-admin oraz bookstore-lib.

Zaczynamy

Projekt zaczniemy od stworzenia prostej strony a’la Witaj Świecie!. Aby zacząć całą zabawę otwieramy Eclipse i tworzymy nowy projekt typu „Dynamic Web Project” (File -> New -> Project… -> Web -> Dynamic Web Project). Następnie wpisujemy nazwę projektu i klikamy finish.
Gdy nasz projekt zostanie utworzony musimy dodać do niego obsługę mavena. Jeśli mamy zainstalowaną wtyczkę m2Eclipse wystarczy kliknąć prawym klawiszem myszy na nasz projekt i wybrać odpowiednio Maven -> Enable Dependency Managment. Plugin doda do naszego projektu plik pom.xml, który zawiera wszelkie informacje potrzebne dla maven-a. W strukturze projektu możemy zauważyć folder WebContent który zawierać będzie pliki konfiguracyjne, tłumaczące, pliki jsp oraz wszystko co potrzebne do wyświetlania wyników. Ponieważ nazwa folderu nie przypadła mi do gustu zamieniłem ją na war (co będziecie mogli zobaczyć po pobraniu projektu).

Struktura projektu z uruchomioną opcją Dependency Managment

Dodawanie zależności

Pierwszą rzeczą jaką robię w nowo utworzonym projekcie jest dodanie podstawowych zależności. Z mojej strony są to takie biblioteki jak sitemesh 3 (UWAGA! – wydanie alpha, mam nadzieję, że działa), spring-web, spring-context, czy też spring-webmvc; czyli wszystko co potrzebne na dobry początek.
Na koniec dodaję biblioteki JUnit oraz Mockito które posłużą do testowania aplikacji. Ponieważ biblioteki te nie będą nam potrzebne w działającej aplikacji, warto zaznaczyć w ich zakresie (ang. scope) opcje „test” dzięki czemu będą dołączane tylko podczas testów.

Konfiguracja

Podstawowa konfiguracja obejmuje dwa pliki, najważniejszy web.xml oraz podstawowa konfiguracja spring-a i głównych servletów w pliku web-servlet.xml
Plik web.xml jest jak najbardziej zwyczajny, podana jest lokalizacja pliku web-servlet.xml, skonfigurowane zostały listenery, a także servlety wraz z mapowaniem.

web.xml:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

id="b0ok" version="2.5">

<display-name>bookstore</display-name>

<!--

wskazujemy lokalizacje plikow konfiguracyjnych

-->

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>

/WEB-INF/web-servlet.xml

</param-value>

</context-param>

<listener>

<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

<!--

tworzymy servlet ktory obslugiwac bedzie nasze zapytania

-->

<servlet>

<servlet-name>web</servlet-name>

<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>

<!--

ustalamy ze nasz servlet obslugiwac bedzie tylko zapytania konczace

sie rozszerzeniem *.html

-->

<servlet-mapping>

<servlet-name>web</servlet-name>

<url-pattern>*.html</url-pattern>

</servlet-mapping>

<!--

ustalamy, jakie pliki beda ladowane gdy aplikacja dostanie zapyanie

"/" (np. http://example.com/)

-->

<welcome-file-list>

<welcome-file>redirect.jsp</welcome-file>

</welcome-file-list>

</web-app>

Dodatkowo wskazaliśmy plik który jest ładowany, gdy serwer otrzyma żądanie /(czyli strona startowa), w tym przypadku jest to załadowanie pliku redirect.jsp który przekieruje nas na stronę główną:

redirect.jsp:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>

<jsp:forward page="/index.html" />

Update 1:
Jak trafnie zauważył
Chlebik (zob. komentarz), zamiast redirect.jsp możemy śmiało napisać „index.html” wtedy spring wykona akcję przeznaczoną dla żądania „/”, przy czym, należy dodać plik index.html do głównego katalogu (war/webContent) aplikacji, może być nawet pusty, ważne by spring wiedział, że jest. Za podpowiedź dziękuję.

Plik web-servlet.xml na początek wskażemy gdzie aplikacja ma szukać kontrolerów, oraz zaznaczymy, że będzie ona działała w oparciu o adnotacje.
web-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:component-scan base-package="com.darekzon.bookstore.controller" />
<context:annotation-config />
<context:spring-configured />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>

W sekcji <context:component-scan> wskazujemy, który pakiet ma być skanowany w poszukiwaniu kontrolerów (klas z adnotacją @Controller), jeśli chcemy możemy wskazać więcej jak jeden pakiet przy czym trzeba pamiętać, że nazwy klas muszę się różnić, więc jeśli mamy IndexController w naszym pakiecie to w pakiecie com.darekzon.bookstore.controller musimy umieścić Index2Controller.

Ach, no i ostatni blok wskazuje gdzie spring ma szukać plików jsp za pomocą których generować będzie wyniki.

Pierwszy kontroler

Aplikacja skonfigurowana, pierwszy kontroler będzie wyświetlał legendarny napis „Witaj świecie!”. Sam kontroler jest wyjątkowo prosty, posiada tylko jedną metodę, która zwraca obiekt typu „ModelAndView” przechowujący nazwę widoku do wyrenderowania. Kontroler zapisany jest w pliku IndexController.java (konwencja nazewnicza nie jest obowiązkowa) a jego zawartość przedstawia się jak poniżej:

package com.darekzon.bookstore.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

@RequestMapping(value = "/index")
public ModelAndView index(){
ModelAndView mav = new ModelAndView("index/index");

return mav;
}

}

Warto tutaj zwrócić uwagę na 3 rzeczy:

  1. Każdy kontroler powinien mieć adnotację @Controller, dzięki temu spring podczas skanowania pakietów (zob. konfigurację web-servlet.xml ↑)
  2. Spring szuka metody którą ma wykonać na podstawie adnotacji @RequestMapping, w naszym przypadku czeka aż wywołamy żądanie „/index„,  warto dodać, że nie można dodać dwóch metod z tą samą wartością tej adnotacji (podczas uruchamiania wyskoczy wyjątek)
  3. W tym przypadku zwracamy obiekt ModelAndView który zawiera nazwę pliku widoków który posłuży do renderowania wyników, plik widoku powinien znajdować się w folderze /views/index/index.jsp, czyli według ustawień w pliku web-servlet.xml oraz wartości zwracanej przez metodę.

Kontroler gotowy, pora na widok który będzie renderowany, ponieważ będzie to wyświetlenie tekstu „Witaj świecie!” plik ten nie jest skomplikowany (kolejne na pewno wniosą coś nowego w tej kwestii), a jego zawartość przedstawia się następująco:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<title>Index</title>
</head>
<body>
Witaj świecie!
</body>
</html>

Tu tłumaczyć raczej nic nie trzeba, no może poza faktem pisania kodu całej strony w wyniku, ale o tym za chwilę.

Sitemesh i konfiguracja szablonów

Sitemesh to ciekawy projekt dzięki któremu znacznie ułatwimy sobie zabawę z wyglądem strony, jego głównym zadaniem jest sklejanie widoków wygenerowanych przez „aplikację” z ogólnym szablonem, oraz doklejanie części wspólnych między widokami (np. mamy oddzielny layout dla strony głównej, kontaktu oraz reszty serwisu, przy czym menu jest takie samo).

„]Sitemesh - sposób działania

Sposób działania Sitemesh-a[1

W projekcie użyję najnowszej (3.0alpha-1) wersji sitemesh-a, ponieważ nie jest to jeszcze stabilna wersja (nawet nie beta), zalecam do poważnych projektów używać wersję 2.4 dostępną pod starą stroną projektu.

Konfiguracja sitemesh-a może odbywać się na dwa sposoby: klasa Java rozszerzająca klasę ConfigurableSiteMeshFilter lub plik XML, ponieważ z niewiadomych przyczyn konfiguracja przez XML mi nie działa skupię się na konfigurowaniu z wykorzystaniem JAVY.

W pliku web.xml musimy dodać filtry które będą go uruchamiać dla każdego żądania (przynajmniej w moim przypadku), wskazując przy tym naszą klasę konfigurującą, kod wygląda następująco:

<filter>
<filter-name>sitemesh</filter-name>
<filter-class>com.darekzon.bookstore.filter.Sitemesh</filter-class>
</filter>
<filter-mapping>
<filter-name>sitemesh</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Zaś klasa Sitemesh konfigurująca ma postać:

public class Sitemeshextends ConfigurableSiteMeshFilter {
@Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
builder.addDecoratorPath("/*", "/views/layout/default.jsp");
}
}

Działanie proste, przechwytujemy wyniki żądań wysłanych do aplikacji, i „kompilujemy” je z dekoratorem z pliku „/views/layout/default.jsp” (UWAGA! powinno podawać się pliki z rozszerzeniami innymi od tych zdefiniowanych w filtrach w pliku web.xml – w moim wypadku .html).

W tej chwili dekorator wygląda następująco:

<!doctype html>
<html lang="pl" dir="ltr">
<head>
<title><sitemesh:write property='title' /> - BookStore</title>
<link rel="stylesheet" href="/resource/style/default.css" />
<sitemesh:write property='head' />
</head>
<body>
<sitemesh:write property='body' />
</body>
</html>

Podczas renderowania sitemesh otwiera dekorator oraz plik wynikowy kontrolera oraz je scala (nie chodzi o język programowania), w miejscu tagu <sitemesh:write property=’title’ /> wstawia wartość tagu <title> wyrenderowanego wyniku, w miejsce tagu <sitemesh:write property=’head’ /> wartość tagu head (za wyjątkiem title), a tam gdzie pyta o <sitemesh:write property=’body’ />, wszystko co znajduje się w body. Proste, a co ważne wygodne.

CDN…

W następnej części zajmiemy się panelem administracyjnym oraz jego zabezpieczeniem, stworzymy również cały layout tego panelu wykorzystując bardziej zaawansowane techniki dostarczane przez JSP i Sitemesh.Tymczasem zapraszam do pozostawiania komentarzy, wszelkie postaram się wziąć pod uwagę.

Do zobaczenia wkrótce.

Jak pobrać projekt

Projekt został umieszczony na serwerach Kenai.com. Adres bezpośredni do projektu: http://kenai.com/projects/summer-bookstore.
Dodatkowo zostało uruchomione repozytorium GIT dla wszystkich chętnych i dostępny jest pod adresem: git://kenai.com/summer-bookstore~books0re-source


1. Diagram pobrany ze strony http://www.sitemesh.org/overview.html

Dnia 12.04.2010

Start systemu Slackware Linux – skrypty i daemony

N

a początku warto powiedzieć, że proces rozruchu systemu operacyjnego Linux na różnych platformach sprzętowych jest taki sam. Różnice wynikające z architektury danego sprzętu nie mają znaczenia (od momentu ładowania systemu – nieznaczne różnice można zauważyć podczas startu samego komputera).

Zaczynając od włączenia zasilania Basic Input Output System (BIOS) wykonuje Power On Self Test (POST), następnie odczytywany jest Master Boot Record (MBR) zawierający program rozruchowy np. Lilo lub inny (np. GRUB). Program rozruchowy zawiera menu proponujące użytkownikowi wybór oraz ustanowienie parametrów startu systemu, czyli po prostu wybór jądra – ponieważ można powiedzieć, że jądro systemu to Linux. Jest ono rdzeniem całej tej otoczki, którą nazywamy oprogramowaniem systemowym. Po wyborze jądra (jego wersji) – następuje jego załadowanie do pamięci – sprawdzane są zainstalowane urządzenia sprzętowe (rezultaty wyświetlane są na ekranie monitora), montowany jest główny system plików wraz z drzewem systemowym:

./ - główny system plików
|
+-/bin - programy uznane za niezbędne.
+-/boot - obraz jądra i statyczne pliki boot loadera.
+-/sbin - binarne pliki systemu (tylko dla administratora).
+-/lib - biblioteki programowe i moduły jądra.
+-/etc - pliki konfiguracyjne hosta, sieci, X11, poczty itp.
+-/home - tutaj żyją użytkownicy (włączając administratora).
+-/lost+found - odzyskane pliki (przez e2fsck).
+-/mnt - miejsce na montowanie innych systemów plików.
   +|- cdrom
    |- flash
    |- floppy
    |- ...
+-/srv - katalog dla oprogramowania serwerowego.
+-/sys - od jądra 2.6 - interfejs zmiany jego parametrów.
+-/tmp - tutaj są przechowywane i kasowane tymaczasowe pliki.
+-/opt - oprogramowanie dodatkowe nie wchodzące w skład systemu.
+-/proc - wirtualny system plików (informacje na temat procesów, jądra, urządzeń).
+-/root - tutaj pracuje administrator.
+-/usr - więcej oprogramowania, bibliotek i dokumentacji.
   +|- X11R6 - oprogramowanie X Window.
    |- bin - więcej oprogramowania uznanego za niezbędne.
    |- dict - słowniki systemowe.
    |- doc - faqi, jak-to-zrobić, dokumentacje programów.
    |- etc - pliki konfiguracyjne programów.
    |- games - gry, gry, gry!
    |- include - pliki nagłówkowe wykorzystywane do programowania w C.
    |- info - informacje GNU.
    |- lib - więcej bibliotek systemowych.
    |- libexec
    |- local - oprogramowanie pozasystemowe nie załączone na CD-ROMie.
    |   +|- bin
    |    |- doc
    |    |- etc
    |    |- games
    |    |- info
    |    |- lib
    |    |- man
    |    |- sbin
    |    |- src - źródła programów.
    |    |- ...
    |- man - strony manualne.
    |   +|- man1..9n
    |- sbin - więcej systemowych plików binarnych administratora.
    |- share -
    |- src - źródła samego Linuksa - czyli jądro.
    |   +|- linux -> linux-2.6.31337
    |    |- linux-2.6.31337
    |- tmp -> ../var/tmp
+-/var - logi systemowe, poczta i inne ważne pliki.
   +|- cache - zcacheowane dane aplikacji.
    |- lock - pliki blokujące współdzielone zasoby.
	|- log - logi systemowe.
	|- mail - poczta systemowa.
	|- run - aktualnie działające programy i ich identyfikatory procesów.
	|- spool - dane oczekujące / w trakcie przetwarzania.
	|- yp - dane przewidziane dla serwisów NIS.
+-...

Następnie zostaje uruchomiony pierwszy proces (ma on identyfikator procesu PID o wartości 1), który nazywa się /sbin/init (lub gdy go nie ma szukane są /etc/init ewentualnie /bin/bash). Bezpośrednio po uruchomieniu ładuje on plik /etc/inittab (plik konfiguracyjny demona init), po czym wykonuje akcje, które w tym pliku zostały opisane (np. odpala procesy getty). Linux może pracować w kilku trybach pracy oznaczonych numerami od 0 do 6. W dokumentacji są określone jako runlevels (poziomy pracy systemu). Dzięki nim możemy pogrupować programy działające rezydentnie w systemie (aby je uruchamiać / zatrzymywać całymi grupami). To dzięki poziomom pracy możemy również zamknąć system. Znaczenie poszczególnych poziomów jest następujące:

  • 0* (halt) – tryb zamknięcia systemu,
  • 1 (single user mode) – tryb jednoużytkowy, działają tylko serwisy niezbędne do pracy systemu,
  • 2 – nieużywany – lecz tak samo skonfigurowany jak poziom 3,
  • 3 (multiuser mode) – tryb wieloużytkowy, działają wszystkie serwisy sieciowe, które są zainstalowane,
  • 4 (session managers) – uruchomione zostanie środowisko graficzne X11,
  • 5 – nieużywany – lecz tak samo skonfigurowany jak poziom 3,
  • 6* (reboot) – restart systemu.

Warto wspomnieć, że Slackware używa stylu botowania systemu pochodzącego z BSD. Inne dystrybcje zazwyczaj korzystają z systemu System V stworzonego przez Miquel’a van Smoorenburg’a. Styl botowania BSD jest systemem, gdzie wszystkie startowe / kończące skrypty znajdują się w jednym katalogu /etc/rc.d. Dla każdego poziomu pracy jest odnośnik do odpowiedniego uruchamiającego dany poziom (/etc/rc.d/rc.1, /etc/rc.d/rc.2 itd.) podczas, gdy System V posiada dla każdego poziomu oddzielny katalog, w którym znajdują się ponumerowane skrypty. W przypadku stylu BSD, każdy z tych skryptów jest i posiada w sobie odnośniki do odpowiednich demonów oraz programów, a także innych, kolejnych skryptów, które posiadają podobną zawartość. Poziomy, które zostały wyróżnione gwiazdkami są poziomami specjalnymi, ponieważ odpowiedzialne są za restart i prawidłowe zamknięcie systemu. Jeśli chcemy przełączać się pomiędzy danymi trybami pracy systemu to służy do tego komenda init:

init 1

Spowoduje ona uruchomienie trybu pojedynczego użytkownika, zaś:

init 3

Spowoduje powrót do standardowego trybu pracy. Wynika to z tego, że plik /etc/inittab zawiera informacje o tym, jak system ma reagować w odpowiedzi na określone zdarzenia (np. zmiana trybu pracy, wciśnięcie kombinacji klawiszy ALT+CTRL+DEL). Dalsza analiza tego pliku pozwoli nam poznać, które skrypty za co są odpowiedzialne oraz jak zbudowana jest prawidłowa sekwencja danego trybu systemu. Plik ten składa się z ciągu linii o następującej budowie:

id:runlevels:action:process

Gdzie:

  • Pole “ID” – jest unikalnym łańcuchem 1 do 4 znaków (identyfikatorem), opisującym całą linię.
  • Pole “RUNLEVELS” – określa tryby pracy, w których opisywana akcja ma działać.
  • Pole “ACTION” – określa warunki niezbędne do wykonania komendy opisanej przez process.
  • Pole “PROCESS” – jest najczęściej ścieżką dostępu, która uruchamia dany program lub skrypt przez init.

Pliku /etc/inittab z reguły się nie modyfikuje, chociaż można go wykorzystać do zmian niektórych ustawień, np. standardowy poziom startu systemu czy ilość konsol tekstowych. Kiedy system wprowadzany jest w dany poziom pracy, init przegląda wszystkie linie dotyczące danego poziomu. Tak samo postępuje podczas uruchomienia standardowego trybu pracy systemu, tylko z tym wyjątkiem, że szukana jest opcja “initdefault” w polu “ACTION”. Pole “ACTION” może przyjmować następujące wartości:

  • 1) initdefault – poziom do jakiego zostanie doprowadzony system po zakończeniu procedur startowych (standardowo 3). Jeśli taki wpis nie zostanie odnaleziony init podczas startu systemu zada pytania o poziom rozruchu systemu. Dlatego linia: id:3:initdefault: określa docelowy tryb pracy systemu (osiągany podczas normalnego startu systemu). Jeśli chcemy wykorzystać więcej trybów, należy zmienić numer trybu w tej linii. Należy pamiętać, aby nie wstawić tam numerów 0 lub 6.
  • 2) once – proces zostanie wykonany tyko raz.
  • 3) boot – proces zostanie wykonany w trakcie startu systemu.
  • 4) sysinit – proces zostanie uruchomiony podczas startu systemu. Zostanie on uruchomiony przed wszystkimi pozostałymi (o niższym priorytecie np. boot) wpisami uruchamiającymi inne procesy. Przykładem tutaj może być linia: si:S:sysinit:/etc/rc.d/rc.S, która uruchomi skrypt rc.S na początku samego startu systemu – odpowiedzialny jest on za m.in. za aktywację partycji wymiany, ustawienie czasu, sprawdzenie integralności systemu plików.
  • 5) wait – proces zostanie uruchomiony jednorazowo, gdy wskazany poziom pracy systemu zostanie osiągnięty. Init będzie podczas jego pracy oczekiwał na jego całkowite zakończenie. Po jego zakończeniu proces nie zostanie ponownie uruchomiony. Przykładem może tu być linia: rc:2345:wait:/etc/rc.d/rc.M – uruchamiająca skrypt wprawiający system w rozruch trybu wielu użytkowników. Dopiero po jego zakończeniu będą odpalane kolejne linie w pliku /etc/inittab.
  • 6) respawn – proces zostanie uruchomiony jednorazowo, gdy wskazany poziom pracy systemu zostanie osiągnięty. Init będzie podczas jego pracy oczekiwał na jego całkowite zakończenie. Po jego zakończeniu proces zostanie ponownie uruchomiony. Czynność ta będzie powtarzana za każdym zakończeniem danego procesu. Przykładem może tu być linia: c1:1235:respawn:/sbin/agetty 38400 tty1 linux – uruchamia ona program agetty otwierający port lokalnej konsoli terminala (tty) wyświetlając znak zachęty logowania. Po wylogowaniu proces ten zostanie ponownie uruchomiony.
  • 7) ctrlaltdel – proces zostanie uruchomiony wtedy, gdy init otrzyma sygnał SIGINT. Sygnał ten oznacza, że ktoś przy konsoli systemowej nacisnął “trzech króli” (Ctrl+Alt+Del często używanych w systemie Windows). Wykonując tę kombinację uruchamia on odpowiedni skrypt przypisany dla tej właśnie kombinacji. Przykładem może tu być linia: ca:ctrlaltdel:/sbin/shutdown -t5 -r now – uruchamiająca komendę, która poddaje system przeładowaniu.

Innymi dość rzadko spotykanymi (chyba, że posiadamy system UPS) opcjami są:

  • bootwait – init nie oczekuje na zakończenie danego procesu,
  • powerwait – proces zostanie rozpoczęty, gdy init otrzyma sygnał: SIGPWR – mówiący o zaistniałych problemach z zasilaniem,
  • power – ta sama sytuacja tylko, że init nie oczekuje na zakończenie procesu,
  • powerokwait – proces zostanie rozpoczęty, gdy init otrzyma sygnał SIGPWR, a plik konfiguracyjny /etc/powerstatus będzie zawierał wpis: OK.

I na tym kończy się zadanie init. Na starcie systemu uruchamia on odpowiednie skrypty, niektóre jednorazowo, a inne wiele razy. Dalej w akcję wchodzą skrypty uruchamiające odpowiednie demony oraz programy diagnozujące system – włączenie pamięci wirtualnej, zamontowanie systemu plików, wyczyszczenie katalogów z logami, inicjalizacja urządzeń Plug & Play, załadowanie modułów jądra, konfiguracja urządzeń PCMCIA, ustawienia portów szeregowych, uruchomienie skryptu stylu System V (jeśli zostanie znaleziony). Poniżej przedstawiono małą mapę ładowania systemu na podstawie systemu Slackware, która pozwoli nam na płynne przejście od init do skryptów po poszczególne daemony:

*-jądro systemu (kernel)
|
init-+-rc.S-+
     |      |-rc.modules
     |      |-rc.serial
     |      |-rc.sysvinit
     |
     +-rc.M-+
     |      |-rc.pcmcia
     |      |-rc.inet1
     |      |-rc.hotplug
     |      |-rc.inet2
     |      |- ...
     |
     +-rc.K
     +-rc.0
     +-rc.6

Oczywiście rozbijając ten schemat drzewa na bardziej drobne składniki możemy otrzymać szczegółową mapę systemu. Lecz to nie jest naszym celem. Przypatrując się zaprezentowanemu schematowi widzimy po zagałęzieniach, że kończą się one na podskryptach posiadających postać rc.*. Podskrypty te uruchamiają lub zatrzymują programy rezydentne, działające w systemie – w Linuksie określa się je mianem daemonów. Jak już wspomniałem skrypty uruchamiające poszczególne daemony znajdują się w katalogu /etc/rc.d/. Nazwa każdego skryptu odpowiada nazwie uruchamianego serwisu, np. komenda /etc/rc.d/rc.httpd start – uruchomi demona http, zaś /etc/rc.d/rc.httpd stop – spowoduje jego zatrzymanie. Możemy się temu przyjrzeć dokładniej rozwijając jedno rozgałęzienie do końca jego “owocu”:

*-jądro
|
init-+-rc.M-+
            |-rc.inet2
            |     +
            |     |-rc.sshd
            |          |- /usr/sbin/sshd
            |-rc.httpd
                 |- /usr/sbin/apachectl

Wynikiem tak wielu rozgałęzień jest zawsze poszczególna usługa lub ich grupa. W tym przypadku został uruchomiony daemon Secure Shell (SSH). Inne daemony np. httpd są uruchamiane na wcześniejszych gałęziach. Dlaczego takich przykładowych rozgałęzień nie posiadają rc.K, rc.0 i rc.6? Oczywiście, że je posiadają, lecz powyższe mapy ilustrują start systemu, a te trzy skrypty odpowiedzialne są za kończenie pracy wszystkich demonów (rc.K jest skryptem poziomu pojedynczego użytkownika, który pozostawia tylko daemony niezbędne do pracy systemu). Gdybyśmy opisywali zamykanie systemu rozgałęzienia te z pewnością by się tam znalazły. Wnikając w poszczególną budowę tych skryptów możemy zauważyć, że są one głównie zbudowane z warunków sprawdzających istnienie dalszych gałęzi oraz w przypadku pozytywnego wyniku uruchamianiu dalszych podskryptów i demonów. Dla przykładu oto warunek pochodzący ze skryptu rc.M sprawdzający istnienie podskryptu rc.inet2:

# Start networking daemons:
if [ -x /etc/rc.d/rc.inet2 ]; then
  . /etc/rc.d/rc.inet2
else
  # Start the system logger.  Normally this is started by
  # rc.inet2 because /usr might be mounted via NFS.
  if [ -x /etc/rc.d/rc.syslog ]; then
    . /etc/rc.d/rc.syslog start
  fi
fi

Jeśli istnieje plik /etc/rc.d/rc.inet2 – odpowiedzialny za uruchomienie wielu daemonów (tak więc rc.inet2 możemy nazwać daemonem daemonów sieciowych – choć brzmi to dziwnie) to zostanie on uruchomiony. W przeciwnym wypadku zostanie uruchomiony tylko daemon raportowania komunikatów systemowych syslogd. Wpis dotyczący syslogd także znajduje się w rc.inet2, który w normalnych warunkach uruchamia go, lecz gdyby z jakiś powodów rc.inet2 nie było na swoim miejscu wpis ten stanowi swego rodzaju zabezpieczenie przed awaryjnym włączeniem raportowania zdarzeń w systemie. Przechodząc jedno piętro niżej wycinamy warunek z rc.inet2 uruchamiający daemona rc.sshd:

# Start the OpenSSH SSH daemon:
if [ -x /etc/rc.d/rc.sshd ]; then
  echo "Starting OpenSSH SSH daemon:  /usr/sbin/sshd"
  /etc/rc.d/rc.sshd start
fi

Przypadek analogicznie podobny do poprzedniego, z tą różnicą, że został dodany komunikat wyświetlany podczas startu systemu informujący nas o pomyślnym załadowaniu usługi. Czas więc przejść do samego pojedynczego daemona rc.* oraz zapoznaniem się z jego budową:

demon_start() {
  /usr/sbin/demon
}

demon_stop() {
  killall demon
}

demon_restart() {
  demon_stop
  sleep 1
  demon_start
}

case "$1" in
'start')
  demon_start
  ;;
'stop')
  demon_stop
  ;;
'restart')
  demon_restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

Słowo daemon może być zastąpione dowolnym programem, którego dany system zarządzania daemonami się tyczy. System ten składa się z trzech sekcji: start, stop i restart – są to trzy typowe operacje wykonywane na danych usługach w systemie (dodatkowymi mogą być: status czy reload). Możemy je uruchamiać, zatrzymywać i restartować w celu odczytania nowych konfiguracji. W sekcji start zazwyczaj jest ścieżka dostępu do danego daemona, po danej ścieżce mogą występować parametry z jakimi ma zostać uruchomiony dany daemon w celu optymalizacji jego pracy. Sekcja stop posiada instrukcje “zabijające” wszelkie procesy związane z tą usługą w celu jej całkowitego zatrzymania. Natomiast sekcja restart zwyczajowo wykorzystuje wcześniejsze sekcje powodując zatrzymanie i uruchomienie danego daemona. Dlatego jeśli byśmy chcieli zatrzymać np. daemona syslogd wystarczy, że wydamy komendę:

/etc/rc.d/rc.syslog stop

Tak samo postępujemy w przypadku jego uruchomienia czy restartu. Należy jednak pamiętać, że nie wszystkimi daemonami możemy tak zarządzać. Należy wiedzieć, który daemon jest ostatnim w gałęzi składowym systemem zarządzającym daną usługą. Przecież po wydaniu polecenia /etc/rc.d/rc.M stop otrzymamy komunikaty błędu, ponieważ rc.M jest daemonem wielu uruchomień składników systemowych, które dzielą się na kolejne podskrypty i programy. Najczęściej daemonami, którymi możemy zarządzać na trzy wyżej wymienione sposoby są usługi i serwery linuksowe np. httpd, sshd, ftpd, pop3d, imapd, telnetd (końcówka “d” jest skrótem od daemon). Ich nazwa w odzwierciedleniu daemona jest taka sama, lecz poprzedzona frazą “rc.” np. rc.http czy rc.sshd. By w pełni zrozumieć cały mechanizm startu Linuksa Slackware i przybliżyć sobie pojęcia daemonów najlepiej krok po kroku samemu przeanalizować poszczególne skrypty startowe.

Bonus:Jak już wiemy init jest programem, który ładuje system i konfiguruje terminale, ale także świetnie się nadaje do stworzenia własnego daemona. Wystarczy, że do pliku /etc/inittab dodamy dowolny wiersz, który określi, który daemon ma być przez program init obserwowany:

xx:13:respawn:/usr/local/sbin/demon

Jak widzimy wiersz ten w pliku inittab składa się z dowolnego (ale unikatowego) identyfikacyjnego ciągu znaków, za którym występują poziomy uruchomieniowe programów, a następnie znane już nam słowo kluczowe respawn, na samym końcu zaś – pełna ścieżka do programu, który ma być naszym daemonem. W powyższym przykładzie, dopóki “daemon” nie posiada konfiguracji powodującej pracy na pierwszym planie systemu, program init będzie tworzył jego kolejne kopie po każdym jego zakończeniu pracy. Po wprowadzeniu tych zmian do pliku inittab konieczne jest zrestartowanie programu init np. przez sygnał HUP. W tym celu wydajemy polecenie:

kill -HUP 1

Warto dodać, że jeśli nasz program będzie bardzo szybko kończył swoją pracę tym samym powodując zbyt szybkie tworzenie swoich egzemplarzy, wówczas program init na chwilę wstrzyma jego działanie, aby zapobiec całkowitemu skonsumowaniu zasobów systemowych.

Od Slackware w wersji 7.0 został zaimplementowany skrypt pozwalający na kompatybilność Slackware ze stylem uruchamiania stosowanym w System V. Od wersji 12.0 odpowiada za tą funkcję pakiet o nazwie sysvinit (zawierający programy zgodne z System V) oraz sysvinit-functions (zwierający odpowiednią strukturę katalogów oraz dowiązań symbolicznych do stylu BSD). Jak wspomniałem wcześniej, styl ten polega na przydzieleniu, każdemu poziomowi rozruchu własnego katalogu oraz umieszczeniu w nim poszczególnych daemonów, które mają być w danym poziomie uruchamiane. Styl ten daje dość przejrzyste zarządzanie poszczególnymi usługami. Jeśli nie potrafimy się poruszać się po drzewie daemonów stylu BSD, możemy na własne potrzeby stworzyć odpowiednie katalogi (od wersji 12.0 zrobi to za nas w/w pakiet) i w nich poumieszczać dane skrypty. W tym celu należy zapoznać się z budową pliku /etc/rc.d/rc.sysvinit oraz rozmieszczeniem stosowanym np. w systemie opartym na dystrybucji RedHat / Debian.

Więcej informacji: man init, pliki konfiguracji /etc/inittab i /etc/rc.d/

Dnia 09.04.2010

Bezpieczne aplikacje Web w oparciu o ASP.NET2.0

A

SP.NET 20.0 jest technologią, dzięki której możliwe jest tworzenie dynamicznych stron internetowych. Wykorzystuje ona większość możliwości, jakie dostępne są wraz z platformą .NET Framework w związku z wykorzystaniem środowiska uruchomieniowego CLR.

Artykuł ten został opublikowany w numerze 7/2007 (27) magazynu hakin9.

Artykuł w formacie PDF

Spring Framework 3.0 Tutorial – wstęp

Największym minusem podczas nauki Spring Framework był brak kompleksowych przykładów pokazujących jak zbudować pełną aplikację wykorzystując nie tylko Spring-a, ale również integrując z nim inne rozwiązania.

Ten tutorial ma za zadanie uzupełnić tą lukę, choć jego zadanie jest troszkę większe. Pisząc tutorial mam zamiar nie tylko pokazać jak wygląda taka aplikacja, ale również skonsolidować swoją wiedzę oraz nauczyć się czegoś więcej od was (choćby poprzez komentarze). Myślę, że będzie to dobre miejsce na wszelkie dyskusje na temat technologii użytych w projekcie oraz sposobu ich użycia. Z chęcią przyjmę również wszelką KONSTRUKTYWNĄ krytykę.

Projekt jaki tutaj zrealizuje to księgarnia internetowa (helion może zacząć się bać ;) ) która na początku oferować będzie standardowe funkcjonalności (kategorie, książki, wyszukiwarkę, mechanizm zamawiania). Szerzej opiszę wszystko w następnych częściach tutorialu.

W projekcie mam zamiar wykorzystać:

  • Spring Framework 3.0
  • Hibernate + Hibernate Search (implementacja wyszukiwarki Lucene)
  • Jasypt
  • Sitemesh
  • inne o których jeszcze nie wiem
  • Lucene (indeksowanie/wyszukiwanie zawartości)
  • inne

Wkrótce podam również adres do repozytorium projektu który umieszczony będzie na serwerach kenai.com (wkrótce w strukturach java.net)

Dnia 08.04.2010

Polonizacja systemu Slackware – UTF-8

Z

e względu na fakt, iż UTF-8 stał się już standardem oprócz polonizacji Slackware w standardzie ISO od pewnego czasu istnieje również możliwość wykonania tej czynności w UTF-8. W celu przygotowania konsoli systemu do tego trybu wyświetlania wystarczy wykonać następujące zmiany:

W pliku konfiguracyjnym (/etc/lilo.conf) bootloader’a LILO dodać wiersz:

append="vt.default_utf8=1"

Oraz przeładować konfigurację poleceniem: lilo -v. Drugą czynnością jest dopisanie w pliku /etc/profile.d/lang.sh następujących pozycji:

# There is also support for UTF-8 locales, but be aware that
# some programs are not yet able to handle UTF-8 and will fail to
# run properly.  In those cases, you can set LANG=C before
# starting them.  Still, I'd avoid UTF unless you actually need it.
export LANG=pl_PL.utf8
export LC_ALL=pl_PL.utf8

Plik odpowiedzialny za ładowanie czcionek ekranowych (/etc/rc.d/rc.font) powinien posiadać postać:

#!/bin/sh
#
# This selects your default screen font from among the ones in
# /usr/share/kbd/consolefonts.
#
setfont -v lat2-16.psfu.gz

Wraz z czcionką obsługującą unicode należy zadbać o prawidłowe mapowanie klawiatury, za które odpowiada plik /etc/rc.d/rc.keymap:

#!/bin/sh
# Load the keyboard map.  More maps are in /usr/share/kbd/keymaps.
if [ -x /usr/bin/loadkeys ]; then
 /usr/bin/kbd_mode -u
 /usr/bin/loadkeys -u pl2.map
fi

Polonizując nasz system musimy również zadbać o poprawne wyświetlanie polskich stron manualnych, które nadal są utrzymywane w starszym kodowaniu ISO. W pliku /usr/lib/man.conf podmieniamy wiersz wywołujący NROFF na następujący:

NROFF		/usr/bin/nroff -mlatin2 -c -mandoc

Oraz na końcu pliku /etc/profile przekazujemy odpowiednią zmienną dla programu less:

if echo "$LANG" | grep -q -i utf8 ; then
  export LESSCHARSET="utf-8"
fi

Kolejnym krokiem jest zapewnienie odpowiedniej ilości stron manualnych. W tym celu możemy skorzystać z uprzejmości systemu Debian oraz jego repozytorium pakietów:

mkdir mans
cd mans
wget http://ftp.de.debian.org/debian/pool/main/m/manpages-pl/manpages-pl_20060617.orig.tar.gz
wget http://ftp.de.debian.org/debian/pool/main/m/manpages-pl/manpages-pl_20060617-2.diff.gz
tar -zxvf manpages-pl_20060617.orig.tar.gz
gunzip manpages-pl_20060617-2.diff.gz
mv manpages-pl_20060617-2.diff manpages-pl-20060617.orig/
rm manpages-pl_20060617.orig.tar.gz
cd manpages-pl-20060617.orig/
patch -p1  manpages-pl_20060617-2.diff
rm manpages-pl_20060617-2.diff
cd ..
rm -r /usr/man/pl/
mv manpages-pl-20060617.orig /usr/man/pl
cd ..
rmdir mans

Ostatnią czynnością jest restart całego systemu.
UTF-8 w Midnight Commander: ESC+9 | Opcje | Wyświetlanie znaków | UTF-8 [x] Pełne 8-bitowe wejście.Więcej informacji: Slackware and UTF-8, Kodowanie UTF-8 w Gentoo

Dnia 03.04.2010

ClamAV, czyli jak to robią małże…

M

ałże internetowe nastawione na kradzież danych bądź transformację komputera ofiary w maszynkę do robienia pieniędzy, to już dzisiaj standard. Wieloletnia wojna z nimi pokazała, że najlepszą strategią jest bezpośrednia eliminacja zagrożeń na poziomie serwerów pocztowych. Tu z pomocą przychodzi oprogramowanie Open Source, które oferuje gamę rozwiązań do walki ze spamem i przynajmniej jeden program do bezpośredniej walki ze złośliwym oprogramowaniem, który zostanie opisany w tym artykule. Problem zalewu niechcianej poczty dotyczy nas wszystkich, zarówno administratorów systemów, jak i zwykłych użytkowników Internetu, który w ostatnich latach stał się łakomym kąskiem dla szeroko pojętej branży marketingowej oraz wszelkiej maści przestępców, zainteresowanych głównie kilkoma numerami z naszych kart kredytowych. Ataki typu phishing czy robaki.

Artykuł ten został opublikowany w numerze 1/2007 (20) magazynu hakin9.

Artykuł w formacie PDF

Dnia 01.04.2010

Partycje, a bezpieczeństwo systemu Linux

W

trakcie instalacji systemu Linux zostajemy poproszeni o dokonanie podziału dysku twardego na partycje. Niektóre dystrybucje Linuksa oferują nawet automatyczne ich przydzielanie. Ilość tych partycji może wpłynąć na poziom bezpieczeństwa systemu. Dlatego rezygnując z automatyzacji tego procesu jesteśmy w stanie własnoręcznie przystosować dysk do bezpieczeństwa instalowanego systemu.

     Jak wiemy partycje to obszary na dysku twardym zarezerwowane dla określonego systemu plików. Linux posiada tą właściwość, że już przy podziale dysku na partycje (w zależności od ich ilości) zostaje ustalony pewien poziom bezpieczeństwa. Dzieląc nasz dysk twardy na jak najwięcej przydatnych partycji zyskujemy możliwość zastosowania bardziej rygorystycznej kontroli nad poszczególnymi systemami plików oraz nad sposobami ich montowania w systemie, ułatwiamy tworzenie kopii zapasowych i administracje nad całym systemem, a co najważniejsze pliki systemowe oddzielone są od plików użytkowników, skutkiem czego jest zmniejszenie szans na wykorzystanie przez intruza programów typu SUID i kontroli nad krytycznymi zasobami naszego systemu.

Wyobraźmy sobie Linuksa zainstalowanego na jednej partycji: katalogi użytkowników i katalog główny znajduje się na tej samej partycji, administrowanie systemem jest praktycznie niewykonalne, wykonywanie aktualizacji systemu czy tworzenie jego kopii zapasowych jest bardzo kłopotliwe i czasochłonne, system jest na tyle niestabilny, że nawet niewielkie uszkodzenie pliku może doprowadzić do pojawienia się kłopotów z całym systemem. Każdy użytkownik może przeprowadzić atak DoS poprzez zapełnienie wolnego miejsca. Także widzimy, że ta operacja nie posiada w ogóle sensu. Wraz z oddzielaniem poszczególnych obszarów systemu zyskujemy jego większą stabilność, zwiększony poziom bezpieczeństwa, kontrole nad sposobem montowania poszczególnych partycji w naszym systemie.

Dla przykładu podzielmy dysk twardy na sześć partycji – podziału na partycje możemy dokonać programem fdisk (pochodzącym z Linuksa nie Windowsa) lub cfdisk. Ważnym elementem podziału dysku na partycje jest, aby dwie lub trzy pierwsze partycje posiadały status podstawowych (ang. primary), a reszta logicznych utworzonych na partycji rozszerzonej (ang. extended – w architekturach opartych na procesorach Intela można utworzyć, co najwyżej cztery partycje podstawowe lub trzy partycje podstawowe, jedną partycję rozszerzoną i kilka partycji logicznych).

  • Pierwszą partycją będzie partycja wymiany, czyli Linux Swap (kod identyfikatora partycji: 82 – zmieniamy go klawiszem T w fdisk),
  • Drugą partycją będzie partycja podstawowa: / – root (kod identyfikatora partycji: 83),
  • Trzecią partycją będzie partycja dla użytkowników systemu: /home,
  • Czwartą partycją będzie partycja na pliki tymczasowe: /tmp,
  • Piątą partycją będzie partycja na pocztę i logi systemowe: /var,
  • Szóstą partycją będzie partycja na programy, dokumentację itp.: /usr.

Podział ten jest tylko podziałem przykładowym (choć przyjmowanym za podstawowy), ponieważ partycji może być znacznie więcej – ich ilość zależy głównie od usług jakimi chcemy dysponować. Na przykład siódmą partycją może być partycja na cache serwera proxy (/cache), na zasoby serwera ftp (/ftp) lub stronę web (/httpd) – możemy także zwiększyć naszą liczbę partycji poprzez dodaje jako drugiej partycji /boot – gdzie są przechowywane pliki uruchamiające system – między innymi jądro Linuksa, lub dobrym pomysłem jest także stworzenie osobnych partycji dla oprogramowania pozasystemowego. Według standardu hierarchii plików poprzez utworzenie osobnych partycji /opt oraz /usr/local podczas reinstalacji systemu nie tracimy przechowywanych na nich dodatkowych programów.

Natomiast jeśli chodzi o pojemność poszczególnych partycji to jest ona kwestią osobistego wyboru użytkownika i tylko w niektórych przypadkach zależna od różnych czynników np. wielkość partycji /home zależy od posiadania przewidywalnej ilości użytkowników oraz pojemności konta każdego z nich. Niektóre z tych czynników są wzajemnie powiązane. Jeżeli na przykład przewidujemy udostępnienie naszego systemu wielu użytkownikom i chcemy udostępnić im usługi pocztowe to rozmiar partycji /var powinien być odpowiednio proporcjonalny do partycji /home. Także jeśli chcemy posiadać właściwy stopień bezpieczeństwa oraz ułatwić sobie późniejszą administrację systemem – oddzielamy od siebie partycje: /, /home, /tmp, /var, /usr. Absolutnym minimum jest wydzielenie osobnej partycji dla katalogu głównego (/). Dodatkowo dzięki podziałowi dysku twardego możemy określić opcje montowania poszczególnych systemów pliku w naszym systemie z osobna, co dodatkowo przyznaje nam większe pole manewru w podniesieniu poziomu bezpieczeństwa. Odpowiedzialny za tę operacje jest plik /etc/fstab, z którego odczytywane są wszystkie dostępne systemy plików i montowane według podanych w nim reguł. Każdy wiersz w tym pliku odpowiada jednemu systemowi plików. Taki wiersz składa się z sześciu pól:

  • (s_block_dev) to pole jest specyfikacją systemu plików. Podaje się tu albo nazwę urządzenia blokowego, albo system plików, który ma być montowany.
  • (mount_point) to pole jest plikiem lokalizującym system plików, czyli punkt montowania.
  • (fstype) to pole jest typem systemu plików, czyli tutaj podajemy rodzaj montowanego systemu plików.
  • (mntops) to pole jest opcją montowania. Tu określamy zakres dostępu, jaki do danego systemu plików będą mieli użytkownicy i system. Zawartość tego pola ma więc znaczenie dla bezpieczeństwa systemu.
  • (freq) pole to określa parametr tworzenia kopii zapasowych danego systemu plików.
  • (passno) pole to określa liczbę określającą kolejność sprawdzania integralności systemu.

Oto przykładowy wpis pliku /etc/fstab:

/dev/sda1     swap     swap     defaults     0    0
/dev/sda2     /        ext3     defaults     1    1
/dev/sda3     /boot    ext3     defaults     1    1
/dev/sda5     /home    ext3     defaults     1    1
/dev/sda6     /tmp     ext3     defaults     1    1
/dev/sda7     /var     ext3     defaults     1    1
/dev/sda8     /usr     ext3     defaults     1    1

Jak możemy zauważyć niektóre z tych partycji są niepotrzebnie montowane z przyznaniem zbyt dużych przywilejów, wyznaczonych opcją defaults (read-write, suid). Przywileje te możemy ograniczyć takimi opcjami jak: rw – możliwy odczyt i zapis; ro – znacznik ro powoduje zamontowanie plików w trybie tylko do odczytu, powstrzymując wszystkie modyfikacje informacji dotyczących plików, włączając w to na przykład czas dostępu do pliku. Opcja ta jest bardzo przydatna w przypadku systemów używanych jako katalog plików dla potrzeb demona httpd – pozwala na zachowanie niezmienionych danych; nosuid – znacznik ten zapobiega uwzględnianiu bitów set-UID oraz set-GID w przypadku dowolnego pliku wykonywalnego. Ponadto pomoże uniknąć wykorzystaniu określonych “sztuczek”, używanych w celu złamania zabezpieczeń w przypadku przerwania “pierścienia zabezpieczeń”; nodev – znacznik ten zapobiega rozpoznawaniu przez jądro dowolnych plików urządzeń, znajdujących się w systemie plików. Jeżeli nie istnieje żaden powód użycia plików urządzeń w danym systemie plików, użycie tej opcji zapobiegnie złamaniu zabezpieczeń poprzez utworzenie urządzeń hda1 lub sda1 z prawami zapisu dla wszystkich użytkowników. Jest to szczególnie przydatne w przypadku korzystania z czytników CD-ROM oraz NFS; noexec – ten znacznik zapobiega wykonywaniu plików wykonywalnych w danym systemie plików. Jest on szczególnie przydatny w przypadku tych systemów plików, w których nie powinny być umieszczone żadne pliki wykonywalne, na przykład obsługujących repozytoria serwera Apache (httpd) dla plików innych niż skrypty CGI; Prawa te powinniśmy ograniczyć co najmniej w odniesieniu do partycji /home. zawierającej katalogi domowe poszczególnych użytkowników. W przedstawionym przypadku ograniczone zostały partycje /home, /tmp i /var, co daje nam większy stopień bezpieczeństwa:

/dev/sda1     swap     swap     defaults     0    0
/dev/sda2     /        ext3     defaults     1    1
/dev/sda3     /boot    ext3     defaults     1    1
/dev/sda5     /home    ext3     defaults,rw,nosuid,nodev,noexec     1    1
/dev/sda6     /tmp     ext3     defaults,rw,nosuid,nodev,noexec     1    1
/dev/sda7     /var     ext3     defaults,rw,nosuid,noexec     1    1
/dev/sda8     /usr     ext3     defaults,rw,nodev     1    1

Dodanie tych flag spowoduje, że na wszystkich tych partycjach pliki z bitem SUID jak i urządzenia blokowe, i znakowe będą “ignorowane”. Na ogół zastosowanie setuid i setgid powinno ograniczać się jedynie do tych partycji, w których prawa zapisu ma wyłącznie root. Osobiście zalecam jawną blokadę użytkowania setuid i setgid w katalogu /home za pomocą opcji nosuid w pliku /etc/fstab. Zauważmy, że zaznaczona jest także opcja No Special Device File Support (opcja nodev) – zapobiega ona utworzeniu urządzenia blokowego w systemie plików /home, /tmp, co byłoby czynnością wysoce podejrzaną, gdyby miał to zrobić zwykły użytkownik. Dodatkowo z partycji /tmp i /var nie będzie możliwości uruchamiania programów binarnych pochodzących z poza systemu (jeśli plnaujemy np. posiadanie Qmail’a lub inny program którego pliki binarne będą znajdowały się na partycji /var – to powinniśmy usunąć flagę noexec z opcji montowania tej partycji). Jeśli chcemy być bardziej rygorystyczni możemy flagę noexec dodać do partycji /home, tak więc użytkownicy znajdujący się w katalogu /home będą mogli tylko i wyłącznie korzystać z programów oferowanych przez nasz system. W przypadku ostatniej solucji dobrym rozwiązaniem dla nas by było stworzenie własnej partycji (np. /admin) gdzie jako jedyni byśmy posiadali konto, w ten sposób jesteśmy w stanie ominąć własne restrykcje. Oczywiście konto to musi być bardzo dobrze strzeżone z uwagi na to, iż z niego można przeprowadzić atak z użyciem programów pochodzących z poza systemu.

Więcej informacji: man fdisk, man mount, man fstab, quota, control mounting a file system

Dnia 26.03.2010

Hak na Windows

I

mię domowego zwierzaka i bieżący rok to najczęściej wykorzystywany schemat haseł. Jednak, gdy hasło jest tak silne, że nie można go wykryć typowymi metodami, istnieje groźba, że zostanie ono podsłuchane. Nie chodzi o przysłuchiwanie się osobom mamroczącym podczas pisania, lecz o podsłuchiwanie klawiatury przez programy uruchomione w Windows.

Artykuł ten został opublikowany w numerze 4/2007 (24) magazynu hakin9.

Artykuł w formacie PDF

Dnia 25.03.2010

W obronie wolności

K

rucjata hackera na rzecz wolnego oprogramowania — fascynująca opowieść o Richardzie Stallmanie Dlaczego rządzący Microsoftem budzą się w nocy na myśl o dokonaniach długowłosego hackera Richarda Stallmana? Dlaczego kilku najsłynniejszych programistów świata nazywa go “świętym Ignucym”? W jaki sposób ten uparty, nad wiek rozwinięty chłopak wyrósł na Dawida zagrażającego Goliatowi przemysłu programistycznego? Dla Stallmana istnienie wolnego oprogramowania, wolnego swobodą wprowadzania zmian, ale nie zwolnionego od konieczności zapłaty — to sprawa priorytetowa.

Swoje życie poświęcił uwalnianiu świata od oprogramowania o zastrzeżonym prawie własności i modyfikacji. W roku 1983 wydał swój Manifest GNU, rozpoczynając realizację zuchwałego projektu stworzenie wolnego systemu operacyjnego mogącego zastąpić Uniksa. Zręcznie stawił czoła przyjętemu systemowi intelektualnej własności, wstawiając do stworzonej przez siebie „Powszechnej Licencji Publicznej (General Public Licence — GPL) notę “copyleft”. Był to ruch, który naczelny dyrektor techniczny Microsoftu Craig Mundie nazwał miną podłożoną pod niezależny sektor oprogramowania komercyjnego. “W obronie wolności” jest śledzeniem losów ekscentrycznego geniusza. Przeprowadzając wiele wyczerpujących wywiadów z “Robin Hoodem nowych technologii”, jego rodziną, kolegami hackerami i osobistościami przemysłu nowych technologii, autor Sam Williams kreśli portret bojownika o wolność, któremu udało się zmienić świat.

“Niewątpliwie jedna z najbardziej kreatywnych postaci hackerskej kultury”
– Eric Raymond

“(Richard) był pierwszą napotkaną przeze mnie osobą, pasującą do stereotypu długowłosego, brodatego hackera. Niewielu takich mamy w Helsinkach”.
– Linus Torvalds, twórca Linuksa

“Opowieść o fascynującym człowieku, który tylko siłą swej woli zmienił spojrzenie świata na technologię”.
– Bob Young, współzałożyciel Red Hat, Inc.

Obszerna recenzja, której autorem jest Daniel Koć, opublikowana w serwisie jakilinux.org:

Charakterystyczna broda, długie włosy, spokojny i pewny głos, przenikliwe oczy… To Richard Stallman, znany też od swoich inicjałów jako RMS – jeden ze współczesnych wizjonerów, który odcisnął swoje piętno na kształcie informatyki. Jego dzieło już dziś wpływa na naszą rzeczywistość, ale nie mam wątpliwości, że ten wpływ będzie dostatecznie widoczny dopiero za jakiś czas, tym bardziej, że nie powiedział jeszcze swojego ostatniego słowa.

Aby objaśnić na czym polega ten wpływ, trzeba się cofnąć o ponad 30 lat i prześledzić drogę rozwoju kultury informatycznej aż do chwili obecnej. Gotowi do długiej podróży?…

AI Lab, czyli ostatni hacker:

Czy dziwicie się, że programy komputerowe się kupuje? Zapewne nie: dziś oprogramowanie w większości jest traktowane jak towar, taki jak każdy inny, dostępny w kolorowych pudełkach ze sklepu. Ale nie zawsze tak było.

Początkowo oprogramowanie było po prostu dodatkiem do sprzętu. Ludzie, którzy wówczas pracowali z komputerami, byli dosyć nieliczni i bardzo specyficzni. Trzeba bowiem wiedzieć, że w tych czasach określenie “komputer osobisty” byłoby równie abstrakcyjne, co dziś na przykład “osobista rakieta kosmiczna”. Jednym z miejsc, gdzie był dostęp do komputerów, było laboratorium sztucznej inteligencji (AI Lab) w słynnej amerykańskiej uczelni technicznej, MIT. W tych akademickich warunkach powstało środowisko, które dzieliło się kodem i pomysłami tak, jak każdą inną ciekawą lub użyteczną ideą. Współpraca była tam jedną z podstawowych zasad działania. Była to społeczność hackerska.

Zwróćcie uwagę, że słowo “hackowanie” miało wtedy zupełnie inny odcień znaczeniowy niż obecnie. To bardzo ważne, aby zrozumieć istotę sprawy. Nie było mowy o szkodzeniu innym ludziom – chodziło jedynie o twórczą, nieskrępowaną zabawę lub pracę nad oprogramowaniem (praca i zabawa mogły też wzajemnie się przenikać). Pojęcie to zresztą ewoluowało przez kilka dziesięcioleci i już wówczas było czymś innym niż pierwotne “nieszkodliwy żart, wygłup” w studenckim slangu MIT z lat 50., choć dziedziczyło po nim element swobody w działaniu.

Na początku lat 70. do AI Lab trafił młody Richard Stallman – człowiek mało towarzyski, ale zdradzający wybitne zdolności analityczne, zwłaszcza w matematyce. Możliwość twórczej pracy z komputerami w gronie pokrewnych mu dusz oraz tamtejsze niezwykle egalitarne i nieformalne podejście do życia spowodowało, że laboratorium stało się dla niego prawdziwą ostoją oraz źródłem życiowego spełnienia.

Z czasem atmosfera w MIT zaczęła się ogromnie zmieniać. Pod koniec dekady wpływy hackerów zaczęły się kurczyć na rzecz administratorów, którzy forsowali zabezpieczanie kont użytkowników, a zarazem swoją nadrzędną pozycję. Mimo spektakularnych akcji sprzeciwu wobec systemu haseł i kontroli, do roku 1980 już w całej uczelni, nie wyłączając AI Lab, zapanowały nowe porządki, a nowe pokolenie nie podtrzymywało hackerskich tradycji. Etos zaufania, współpracy i twórczego fermentu został więc silnie podważony.

Nie koniec na tym, także poza uczelnią w świecie informatyki następowały zasadnicze zmiany. Do tej pory pieniądze spływały z projektów związanych z obronnością, ale po wojnie wietnamskiej (trwającej do 1975 roku) to źródło wyschło i trzeba było szukać innego sposobu na dalszy rozwój. Rodzący się wówczas rynek oprogramowania skutecznie zasysał więc hackerów, a jednocześnie zaczął wymyślać różne sposoby na ochronę kodu przed wykorzystywaniem przez innych.

Stallman, dla którego etyka hackerska zespoliła się z prywatnym życiem tak, że stała się praktycznie częścią jego natury, te zmiany oznaczały prywatną klęskę. Dla niego naturalne było przeświadczenie, że współdziałanie w programowaniu jest znacznie bardziej efektywne niż izolacja i stawianie zapór ludzkiej kreatywności i wolności osobistej. Łatwo jest z dzisiejszej perspektywy uważać tę ideą za utopię. Sęk jednak w tym, że wówczas nie była to żadna utopia, tylko wciąż jeszcze istniejąca rzeczywistość!

Ale były to już jej ostatnie tchnienia. Rozkład społeczności hackerskiej i spychanie na margines historii zasad nią rządzących postępowały bezlitośnie. Richard Stallman najboleśniej odczuł to 16 marca 1982 r., gdy jedna z firm wynajmująca hackerów z MIT, Symbolics, odmówiła mu nawet grzecznościowego wglądu w kod swojego oprogramowania (Lisp Machine). Symbolics zrobiła to po to, aby utrudnić życie konkurencyjnej firmie LMI, ponieważ LMI obficie posiłkowała się kodem z AI Lab, gdzie nad swoim kodem lispowym nadal pracował Stallman. Odcięcie go od kodu pisanego w Symbolics uderzało więc faktycznie w LMI, ale bezpośredni cios został wymierzony w Stallmana i resztki kultury hackerskiej.

Zatrzęsło to w posadach światem “ostatniego hackera” i wywołało jego silną reakcję. Od tej pory Stallman przez wiele miesięcy pracował jak nakręcony, próbując samodzielnie dotrzymać kroku zmianom wprowadzanym przez zespół programistów Symbolics, i to nie byle jakich, bo także wywodzących się z AI Lab. Do dyspozycji miał tylko dokumentację, w której opisywali oni wyniki swojej pracy. Niezwykłe zdolności Stallmana połączone z ogromną determinacją doprowadziły do niezwykłego skutku: cokolwiek w latach 1982-1983 stworzyli programiści Symbolics, było natychmiast niezależnie odtwarzane przez Stallmana w MIT jedynie na podstawie tych opisów.

Ten heroiczny sprzeciw wobec próby zniszczenia tego, co RMS uznał za swój dom – czyli społeczności i ducha swobodnej współpracy w AI Lab – ugruntował jego sławę i przeszedł do informatycznej legendy. Ale maszyna lispowa sama okazała się w końcu boczną ścieżką rozwoju informatyki, więc dalsze wysiłki w tym kierunku utraciły sens. Prawdziwym wyzwaniem stał się rozwój tak zwanych mikrokomputerów, a wraz z nim zalew “własnościowego” oprogramowania, któremu już żaden pojedynczy geniusz nie dałby rady.

Pewna epoka nieodwracalnie odchodziła w przeszłość.

GNU, czyli alternatywa:

W obliczu tak niekorzystnego obrotu spraw Richard Stallman był bliski rezygnacji i rozważał nawet porzucenie swojego ukochanego zajęcia. Znalazł w sobie jednak dość siły i uporu, aby powołać do życia projekt GNU. 27 września 1983 r. ukazało się w sieci jego ogłoszenie o planach pracy nad GNU wraz z zaproszeniem do przyłączenia się do projektu.

Cel tego przedsięwzięcia był równie szaleńczy co samotna walka z firmą zatrudniającą zespół hackerów. Stallman postanowił mianowicie stworzyć pełen system operacyjny opierający się na hackerskiej etyce, a więc dostępny dla wszystkich. Zgodnie z hackerskim podejściem zamiast budować od zera, zaczął szukać gotowych klocków, które pasowały do jego wizji. Postanowił między innymi, ze GNU będzie niezależnym odtworzeniem powszechnie znanego systemu operacyjnego UNIX.

Do Stallmana dołączali ludzie tak samo jak on rozczarowani coraz częstszym zamykaniem się dostępności kodu. Opiekuńczym “parasolem” dla GNU została założona w 1985 roku Fundacja Wolnego Oprogramowania (Free Software Foundation, FSF). Jej nazwa sprawiała i do dziś sprawia kłopoty, ponieważ w języku angielskim “free” oznacza zarówno wolność jak i “darmowość”, jednak Stallman ostatecznie uznał, że nie ma słowa, które lepiej oddawałoby ideę, jaką stara się wprowadzić w życie, i tak już zostało.

Jednym z pierwszych programów GNU był edytor tekstu EMACS. Stallman stworzył go jeszcze w poprzedniej dekadzie, więc była to bezpośrednia kontynuacja jego hackerskiego życiorysu. EMACS sam w sobie jest świetnym przykładem na to, jak atmosfera swobodnej współpracy stymuluje rozwój. Richard Stallman zapoczątkował go dodając do edytora o nazwie TECO (napisanego wcześniej przez innego hackera) możliwość wykonywania makropoleceń, czyli całych, nawet bardzo złożonych ciągów instrukcji. Okazało się, że to był strzał w dziesiątkę i ludzie masowo tworzyli własne makra dla EMACS-a, przyczyniając się do jego sukcesu. Przerobienie po latach EMACS-a tak, aby działał także pod Uniksami, było sygnałem, że GNU nie jest tylko pustym hasłem garstki frustratów i naprawdę ma do zaoferowania coś wartościowego.

Stopniowo projekt nabierał ciała. Po GNU EMACS (1985 r.) pojawiały się kolejne ważne cegiełki nowego systemu operacyjnego, ale edytor ten zapisał się w historii informatyki w jeszcze jeden istotny sposób. Była to licencja GNU EMACS, która oddawała ducha hackerskiej etyki także w postaci zapisu prawnego. Najistotniejsze jej postanowienie głosiło, że wprawdzie każdy może dowolnie modyfikować program, ale w zamian swoje poprawki musi udostępniać na tych samych zasadach. Gwarantowało to, że raz udostępniony kod nie mógł zostać przez nikogo zamknięty, odcinając tym samym społeczność od swoich ulepszeń. Gdy GNU wzbogaciło się o kolejne narzędzie programistyczne, Stallman objął całość nową wersją licencji, którą nazwał “Ogólna Licencja Publiczna GNU” (GNU General Public License, w skrócie GPL).

To dzieło rozpoczęło odtąd swój własny żywot i zatoczyło szerokie kręgi w świecie twórców oprogramowania. GNU GPL zostało wykorzystane nie tylko w projektach GNU, ale także w tysiącach innych programach, których autorzy niekoniecznie nawet poczuwają się do jakiejkolwiek bliskości z RMS-em. To jeden z kamieni milowych położonych pod rozwój wolnego oprogramowania oraz pod powrót już niemal pogrzebanego hackerskiego kodeksu postępowania.

Open Source, czyli schizma:

System operacyjny GNU rozwijał się kolejny rok, ale wciąż nie było działającego jądra systemu, czyli jego “mózgu” (czy też, używając innej analogii, “silnika”). Elementy GNU nadal nie stanowiły samowystarczalnej całości i póki co musiały być uruchamiane na znienawidzonych przez Stallmana własnościowych systemach uniksowych. Opracowywane w ramach GNU jądro HURD z powodu komplikacji technicznych rodziło się w ślimaczym tempie i wystawiało cierpliwość zwolenników wolnego oprogramowania na ciężką próbę. Dziurę tę zapełnił wkrótce zupełnie niespodziewany projekt – zapoczątkowane przez fińskiego studenta informatyki Linusa Torvaldsa jądro Linux.

Linux powstał w ramach działalności hobbystycznej i – jak w swojej pierwszej publicznej wiadomości z 26 sierpnia 1991 r. pisał jego autor – wcale nie miał być tak “poważny” jak GNU. Wkrótce za to, zainspirowany jednym z wykładów Stallmana, Torvalds doszedł do wniosku, że licencja GNU GPL świetnie nadaje się do wykorzystania w jego projekcie… Społeczność Linuksa szybko zaczęła rosnąć w siłę, a jądro Linux zlepione z wieloma istotnymi narzędziami GNU stały się podstawą pełnego wolnego systemu operacyjnego, czyli dystrybucji Linuksa, co jest powszechnie skracane do nazwy “Linux”. Nic jednak dziwnego, że Stallmanowi nie spodobała się ta nazewnicza maniera, która pomijała wieloletnie prace u podstaw nad takim systemem w ramach GNU. W 1995 ukuł więc własną nazwę, na którą nalega do dziś: “GNU/Linux”. Jak okazało się później, kontrowersja z nazwą była preludium znacznie poważniejszych zmian w środowisku.

W roku 1996 odbyła się przełomowa dla ruchu wolnego oprogramowania impreza pod nazwą Conference on Freely Redistributable Software, na której pojawili między innymi się obaj panowie: Richard Stallman i Linus Torvalds. Na tym zlocie młody, zawadiacki lider zdobył serca publiczności swoim swobodnym zachowaniem. Już wcześniej upór Stallmana i odporność na wszelkie kompromisy powodował liczne tarcia. Dość powiedzieć, że przed konferencją szeregi Fundacji Wolnego Oprogramowania opuścili wszyscy jej członkowie, poza jedną osobą! Idea wolności w wydaniu Stallmana jest tak mocno stopiona z jego wymagającą osobowością, że większości ludzi – nawet podzielających jego zdanie – trudno to w praktyce wytrzymać. Tymczasem Torvalds był jak najdalszy od rygoryzmu RMS-a, a zamiast moralnych przesłanek kierował się przede wszystkim względami technicznymi. Na konferencji posunął się nawet do publicznego oświadczenia, że podoba mu się program PowerPoint – aplikacja, która z wolnością oprogramowania jako żywo nie miała nic wspólnego.

Ta jawna, wręcz arogancka pochwała pragmatyzmu zwiastowała otwarte pęknięcie w środowisku wolnego oprogramowania. Faktycznie – w 1998 roku doszło do krystalizacji nowego ruchu, który przyjął nazwę Open Source (otwarte oprogramowanie) i w kolejnych latach zaczął zdobywać licznych zwolenników. Ruch otwartego oprogramowania nie ma jednego lidera, podczas gdy ruch wolnego oprogramowania to w ogromnym stopniu emanacja silnej osobowości Stallmana. Paradoksalnie, wobec wytrwałego bojownika o wolność stanęła nagle wolność, ale w zupełnie innej w postaci – luźnego ruchu społecznego, związanego z eksplozją Internetu. Można się zastanawiać, czy i bez jego udziału nie doszło by w końcu do przełomu, ale pozostaje faktem, że wpływ Stallmana odcisnął się także w tym nurcie kultury informatycznej.

FLOSS, czyli symbioza:

Open Source niedługo skończy 10 lat i przez ten czas w powszechnej świadomości właściwie zajęło ono miejsce idei wolnego oprogramowania, ale Stallman nie zawiesił swojej działalności na kołku, więc ta “schizma” trwa do dziś. Obok krzepkiego ruchu otwartego oprogramowania nadal rozwija się nurt stallmanowski, choć jest on dużo mniej znany. Łączy je szczególnego rodzaju symbioza, podobna do połączenia kodu GNU z jądrem Linux. Choć minęło już ponad 20 lat, projekt GNU nadal pracuje nad swoim jądrem HURD, jednak nie jest to już uznawane za zadanie priorytetowe. Mimo ideologicznego rozziewu między obydwoma liderami, Linux świetnie sobie radzi na tym nieplanowanym “zastępstwie”, a z kolei licencje stworzone w ramach FSF są jednoznacznie akceptowane przez zwolenników Open Source. Amalgamat tych dwóch odrębnych, ale przenikających się nurtów jest zwykle określany przez obserwatorów jako FLOSS (Free/Libre and Open Source Software).

Oprogramowanie na wolnych licencjach rozwija się w wielu, często niezależnych od siebie miejscach, w różnych organizacjach i firmach, a także rękami programistów niezrzeszonych, a takie aplikacje jak przeglądarka Firefox, pakiet biurowy OpenOffice.org, program do grafiki wektorowej Inkscape, czy program do składu Scribus robią samodzielne “kariery”, i nie wykorzystały jeszcze swojego pełnego potencjału. W dodatku nawet Linux nie jest już jedynym jądrem na wolnej licencji. Istnieją wolne systemy zbudowane na jądrach BSD, rozwijają się też systemy wyrosłe z zupełnie innych podstaw niż UNIX, takie jak Haiku, Syllable, ReactOS – i wiele innych.

Sytuacja od strony czysto praktycznej wygląda więc całkiem nieźle, a obecne problemy techniczne stopniowo zostają rozwiązywane – jeśli nie dziś, to z upływem czasu przestaną być ważne. Zakrawa na paradoks, że triumf nurtu otwartego oprogramowania obraca się powoli przeciw niemu. Popularność tego terminu sprawia, że chcą się pod nią podczepić różni sprytni przedsiębiorcy, którzy powołują się na ideę bliżej nieokreślonej “otwartości” nie zapewniając przy tym podstawowych zasad wolnej współpracy. Stallman ze swoją sztywną postawą moralną stanowi więc nadal kotwicę, która przypomina o zasadniczych regułach gry i nie pozwala na zwichnięcie idei wolności oprogramowania.

Środowisko wolnego oprogramowania bliskie lub związane z FSF znów zaznacza swoje istnienie, między innymi nawiązując kontakty z “wolnościowcami” w innych organizacjach społecznych, nie zajmujących się oprogramowaniem, a jednocześnie zyskało wsparcie jednej z największych firm informatycznych, Sun Microsystems. Fundacja stara się też atakować inne przeszkody stojące na drodze wolnemu oprogramowaniu: problemy z niejawnymi, własnościowymi standardami i formatami plików, systemy kontroli użytkownika (tzw. DRM) oraz przestarzałe, a czasem wręcz nieprzyjazne duchowi wolnego oprogramowania prawodawstwo.

Dziś trudno jeszcze powiedzieć, czy wobec tego czeka nas renesans oryginalnej idei Richarda Stallmana, czy też środowisko Open Source poradzi sobie z zagrożeniami i pozostanie dominującą siłą, czy może na przykład dojdzie do jakiejś – trudnej dziś do wyobrażenia, choć już zaproponowanej – fuzji tych dwóch nurtów? Informatyka wciąż pozostaje burzliwie rozwijająca się dziedziną życia i jeszcze wiele może się zmienić.

Na koniec krótko o książce:

Richard Stallman to postać niezwykła i pełna kontrastów: samotnik, którego idea zmienia cały przemysł informatyczny. Trudny we współpracy indywidualista, ale zarazem mówca i działacz polityczny, który aktywnie promuje współdziałanie. Relikt odległej przeszłości, który wyznaczył kierunki rozwoju w przyszłości. Technik, którego najważniejszym dziełem jest ruch społeczny skupiony wokół wartości filozoficznych i moralnych w informatyce. Wizjoner ze skłonnością do czepiania się zupełnie nieistotnych dla innych szczegółów. Sam Williams próbuje przybliżyć czytelnikowi tę postać w jednym pakiecie z jej działalnością, i moim zdaniem to była słuszna strategia. Konia z rzędem temu, kto potrafiłby wskazać, gdzie kończą się osobiste cechy Stallmana, a gdzie zaczynają się obiektywne skutki jego pracy. Dodatkowo kucyka temu, kto oddzieli jego osobiste wady od zalet jako działacza społecznego…

Biografia może być prawdziwym dziełem literackim, ale może też pełnić rolę przypisu do życiorysu niezwykłego człowieka. “W obronie wolności” jest takim właśnie kwitkiem, który jest tylko dodatkiem do osoby, warto się jednak w ten “kwitek” wczytać. Książka w kategorii “literatura” nie wypada szczególnie dobrze – styl jest mało dopracowany, choć być może to wina tłumaczenia (także dlatego, że odpowiednie słownictwo w języku polskim dopiero z roku na rok dojrzewa). Jednak pracowite zebranie wielu faktów w jedną opowieść na temat osoby o tak istotnym wpływie na rzeczywistość aż prosi się o uznanie i nie zamierzam tego autorowi odbierać.

Oczywiście znajomość komputerów, a zwłaszcza środowiska wolnego i otwartego oprogramowania, znacznie ułatwi odbiór tej biografii, ale wydaje mi się, że opis fenomenu Stallmana może wiele wyjaśnić także ludziom interesującym się ogólnymi kierunkami rozwoju naszej cywilizacji. Ostatecznie w świecie, gdzie nawet humaniści piszą swoje eseje na komputerze, ludzie zawierają znajomości w sieci, a oprogramowanie czai się nawet w telefonie i niewinnym odtwarzaczu muzyki, tradycyjny rozdział techniki od kwestii społecznych i etycznych staje się coraz mniej uzasadniony – o ile w ogóle jeszcze ma jakiś sens.

Tytuł: W obronie wolności
Tytuł oryginału: Free as in Freedom
Autor: Sam Williams
Przekład: Krzysztof Masłowski
Seria: Open Source
Wydawnictwo: Helion
Data wydania: 2003, listopad
Wydanie: I
ISBN: 83-7361-247-5

Opis fizyczny: stron: 296, format: B5, oprawa: miękka

Książka do ściągnięcia w formacie HTML | PDF

Dnia 24.03.2010

Delikatność Internet Explorera

J

edno z pytań, które z biegu zostaną przez czytelników Hakin9u zaliczone do grupy retorycznych, jest pytanie o to która z przeglądarek jest przeglądarką najdelikatniejszą. I choć powiedzenie „wszystko co piękne jest delikatne” do niedawna nie miało zupełnie żadnego odniesienia w stosunku do najpopularniejszej przeglądarki na świecie, to przynajmniej na…

Artykuł ten został opublikowany w numerze 1/2007 (21) magazynu hakin9.

Artykuł w formacie PDF

Dnia 23.03.2010

Ukrywanie wersji Apache 2.x jako Serwera WWW i Reverse Proxy

W

iele standardowo zainstalowanych serwerów WWW obsługiwanych za pomocą Apacza ujawnia zbyt wiele danych umożliwiających przeprowadzenie tzw. ataku banner grabbing należącego do grupy ataków typu fingerprinting. Jeśli chodzi o standardową konfigurację Apacza atak banner grabbing można przeprowadzić bez szczegółowego wgłębiania się w nagłówek HTTP. W przypadku zdezaktualizowanych serwerów może stanowić to pretekst do szybko podjętej decyzji o ataku wymierzonym w wykryte podatności starszej wersji.

Ze względu na fakt, iż wiele serwisów nie posiada dobrze skonfigurowanych stron błędów (korzystają z standardowych szablonów dostarczonych z oprogramowaniem) z reguły, aby uzyskać informację o wersji zainstalowanego serwera WWW wystarczy wywołać adres wybranej strony z przykładowym, błędnym odnośnikiem: http://www.abc.pl/obiektnieistnieje. W odpowiedzi serwera otrzymamy komunikat błędu wraz z danymi zawartymi w stopce strony:

Apache/2.2.9 (Debian) mod_ssl/2.2.9 OpenSSL/0.9.8g

W powyższym przykładzie możemy zauważyć, że informacje te nie tylko zdradzają wersję serwera WWW (Apache/2.2.9), ale również wersje dołączonych do niego modułów (mod_ssl/2.2.9) oraz innego oprogramowania systemowego (OpenSSL/0.9.8g) jak i samą wersję dystrybucji Linuksa (Debian). Przy założeniu, że ten sam serwer skonfigurował już poprawną obsługę stron błędów jego wersja niestety nadal zawarta jest w nagłówku HTTP:

agresor@nfsec:[~]: nc abc.pl 80
HEAD / HTTP/1.0

HTTP/1.1 200 OK
Date: Sun, 21 Mar 2010 10:17:03 GMT
Server: Apache/2.2.9 (Debian) proxy_html/3.0.0 mod_ssl/2.2.9 OpenSSL/0.9.8g
Last-Modified: Mon, 24 Nov 2008 07:56:58 GMT
ETag: "2c016-3c6-45c6abd3ca680"
Accept-Ranges: bytes
Content-Length: 966
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=UTF-8
Content-Language: pl

Ta sama sytuacja odnosi się do przypadku, w którym Apache działa jako reverse proxy. Wówczas udostępniane są nie tylko dane samego serwera pośredniczącego, ale również docelowego:

HTTP/1.1 200 OK
Date: Sun, 21 Mar 2010 10:40:32 GMT
Server: Zope 2.9.5;Zope/(Zope 2.9.5-final, python 2.4.3, linux2) ZServer/1.1 Plone/2.5.1
Content-Type: text/html; charset=utf-8
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 1041
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Language: pl

W powyższym nagłówku zawarte są dane serwera znajdującego się za Apaczem (Zope 2.9.5), oprogramowanie systemowe (python 2.4.3) jak i wersja aplikacji internetowej (Plone/2.5.1). Aby zapobiec zgłaszaniu się Apacza w tak otwarty sposób m.in. również dla standardowych stron z kodem 404 wystarczy odpowiednio ustawić opcję ServerTokens oraz ServerSignature w pliku konfiguracyjnym na wartości:

ServerTokens Prod
ServerSignature Off

Wówczas odpowiedź serwera WWW na błędne żądanie będzie ujęta tylko w postaci:

agresor@nfsec:[~]: nc abc.pl 80
DELETE / HTTP/1.0

HTTP/1.1 405 Method Not Allowed
Date: Sun, 21 Mar 2010 11:58:52 GMT
Server: Apache
Vary: accept-language,accept-charset,Accept-Encoding
Accept-Ranges: bytes
Connection: close
Content-Type: text/html; charset=iso-8859-2
Content-Language: pl
Expires: Sun, 21 Mar 2010 11:58:52 GMT

Niestety sytuacja ta pozostaje bez zmian w stosunku do trybu proxy. W tym celu należy do Apacza załadować moduł umożliwiający kontrolę i modyfikację nagłówków w żądaniach użytkownika i odpowiedziach serwera – mod_headers. Dzięki temu jesteśmy w stanie manipulować poszczególnymi wartościami w nagłówku HTTP, w tym również polem Server. Przykładowy wpis w pliku httpd.conf:

<IfModule mod_headers.c>
    Header set Server NF.sec
</IfModule>

spowoduje zwracanie nagłówków dla serwera ukrytego za Apaczem już w postaci:

HTTP/1.1 200 OK
Date: Sun, 21 Mar 2010 12:23:13 GMT
Server: NF.sec
Content-Type: text/html;charset=utf-8
Content-Language: pl
Set-Cookie: previous_page="http://abc.pl/folder_view"; Path=/
Set-Cookie: current_page="http://abc.pl/folder_view"; Path=/
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 3926
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive

Przedstawionego rozwiązania nie należy traktować jako mechanizmu bezpieczeństwa, gdyż bazuje ono jedynie na czystej metodzie bezpieczeństwa poprzez utajnienie (ang. security through obscurity). Jest to jedynie prosty sposób na uniknięcie ataku typu banner grabbing przeprowadzonego na nasz serwer WWW.

Więcej informacji: mod_headers, ServerTokens, ServerSignature, Apache jako Reverse Proxy

Dnia 22.03.2010

Format GIF okiem hakera

P

liki graficzne są dziś szeroko rozpowszechnionym nośnikiem informacji, spotyka się je praktycznie na każdym komputerze. Dobry programista powinien wiedzieć, jak wyglądają nagłówki poszczególnych formatów plików graficznych, a także – jak przechowywany jest sam obraz.

Artykuł ten został opublikowany w numerze 07-08/2008 (37) magazynu hakin9.

Artykuł w formacie PDF

Dnia 21.03.2010

Ataki społecznościowe

J

esteśmy społeczeństwem informacyjnym (ang. Information Society) – czyli społeczeństwem, w którym głównym towarem przetargowym staje się informacja, traktowana jako szczególne dobro niematerialne, będąca częścią każdego produktu czy usługi i wykorzystywana w każdej sferze naszego dzisiejszego życia. W tym kontekście informacja staje się dla społeczeństwa informacyjnego równoważna lub cenniejsza nawet od dóbr materialnych.

Termin społeczeństwa informacyjnego został wprowadzony w 1963 roku przez Japończyka T. Umesao (wersja oryginalna “jōhōka shakai”) w artykule o teorii ewolucji społeczeństwa opartego na technologiach informatycznych. Przez lata definicja ta przechodziła i przechodzi bardzo wiele ewolucji. W zależności od punktu spojrzenia i pełnionych funkcji społeczeństwo informacyjne posiada wiele twarzy. Luc Soete jeden z ekspertów Unii Europejskiej definiuje społeczeństwo informacyjne w następującym kontekście:

“Społeczeństwo informacyjne to społeczeństwo, które właśnie się kształtuje, gdzie technologie gromadzenia i transmisji informacji, i danych są powszechnie dostępne po niskich kosztach. Powszechnemu użyciu informacji i danych towarzyszą organizacyjne, komercyjne, społeczne i prawne zmiany, które głęboko zmieniają życie, pracę i społeczeństwo jako takie.”

Spoglądając, na członków społeczeństwa informacyjnego jako potencjalnych użytkowników technologii informatycznej można uznać, że społeczeństwo informacyjne to “społeczeństwo charakteryzujące się przygotowaniem i zdolnością do użytkowania systemów informatycznych, skomputeryzowane i wykorzystujące usługi telekomunikacji do przesyłania i zdalnego przetwarzania informacji”. Tak jak w przypadku, systemów informacyjnych możemy spotkać się z definicjami społeczeństwa informacyjnego oraz społeczeństwa informatycznego. Należy pamiętać, że mając na myśli społeczeństwo informatyczne określa się grupę społeczną, która posiada dostęp nie tylko do informacji, ale także do technologii informatycznych. Bez względu, która definicja zostanie użyta do scharakteryzowania społeczeństwa informacyjnego, trzeba mieć na uwadze, że to informacja jako proces stwarza możliwości technologiczne i staje się dominującą siłą napędzającą społeczeństwo. Mimo globalnego rozwoju informatycznego i massmediów, cywilizacja informacji zajmuje pierwsze miejsce w nadawaniu tonu w sposobie życia społeczeństwa. Społeczeństwo, będąc pod wpływem takiego rozwoju, uzupełnia o nią swój model kultury i stylu życia. Aktualnym trendem w rozwoju światowej gospodarki jest skala, na jaką występuje powszechny dostęp do informacji, co stanowi bardziej zaawansowany proces w kształtowaniu się społeczeństwa informacyjnego. Oczywiście, w każdym społeczeństwie, nawet informacyjnym istnieje wiele problemów, które należy pokonać. Mimo, iż informatyzacja i globalny dostęp do informacji przynosi społeczeństwu możliwość życia na wyższym poziomie, to nie wszystkie jednostki posiadają dostęp do tych technologii, a tym samym cechuje je brak społecznej świadomości, wiedzy i doświadczenia w wykorzystywaniu dostępnych dla nich rozwiązań. Konsekwencją tego, może być rozwarstwienie się na dwie kategorię społeczne: osoby korzystające na bieżąco z dóbr Technologii Informacyjnej (IT) oraz osoby będące cywilizacyjnie i ekonomicznie upośledzone. Z problemów możemy także zwrócić uwagę na kwestię bezpieczeństwa społecznego. Znacznie ułatwiony dostęp do informacji, która wcześniej była traktowana bardziej osobiście, może zagrażać także prywatności oraz statusowi społecznemu osób. Pojawienie się nowej technologii zawsze rodzi możliwość pojawienia się nowej kategorii nadużyć z nią związanych.
      Dlatego powiązanie społeczeństwa z wykorzystaniem danej technologii ściśle wiąże się z wieloma aspektami dobrego, złego i nieprzewidzianego jej użycia. Za doskonały przykład można wziąć serwisy społecznościowe (Web 2.0), w których budowie i działaniu czynnie uczestniczy społeczeństwo informacyjne. W kwestii bezpieczeństwa można na początku nawiązać do różnic, technologicznych całego Internetu. Jak wiadomo, na serwisach społecznościowych przeprowadza się ocenę jakości dostarczonej informacji pod różnymi względami: przydatności, wiarygodności, nowości itd. Jednak sama technologia, której użyto do dostarczenia tej informacji jest pomijana. Dlatego, osoba oferująca skromne zaplecze technologiczne, ale odznaczająca się dużym potencjałem informacyjnym z pewnością zostanie poszkodowana, gdy jej zasoby zostaną uznane za godne wyróżnienia na przykładowym serwisie społecznościowym. Dlaczego? Wyobraźmy sobie, że bardziej popularny serwis społecznościowy odwiedza dana ilość osób. Każda z nich ma szerokopasmowe łącze oferujące szybką penetrację Internetu w celu dotarcia do interesującej informacji. Po publikacji odnośnika na serwisie społecznościowym do strony, która utrzymywana jest na średniej przepustowości łączu istnieje wielkie prawdopodobieństwo, że owa „nieproszona” popularność spowoduje przeprowadzenie nieświadomego ataku DoS (ang. Denial of Service) przez użytkowników danego serwisu na stronę, która została polecona jako godna do odwiedzenia. Używając trochę wyobraźni i dopuszczając myśl, że ten sam link zostanie opublikowany jednocześnie na dwóch różnych serwisach przez tego samego użytkownika – spowoduje przeprowadzenie nieświadomego ataku DDoS (ang. Distributed Denial of Service). W dodatku same serwisy społecznościowe stają się ofiarami tego rodzaju ataków ze względu na rosnącą swoją popularność, nie będąc w stanie obsłużyć wszystkich odwiedzających, którzy szerzą informację wśród kolejnych osób o pojawieniu się w Sieci nowego, ciekawego serwisu. Drugim pojawiającym się problemem jest problem skali w wykryciu ewentualnej luki w bezpieczeństwie i opublikowaniu jej na tego rodzaju serwisie. Skutki są naprawdę drastyczne. To, co miało przynieść autorowi wpisu większą, bądź mniejszą sławę – stanowi karygodne posunięcie. W dodatku straty są tym większe, jeśli wpis zawierał dodatkowo szczegóły techniczne luki. Przykładem może tutaj być publikacja na tego rodzaju serwisie ukierunkowanym na różne technologiczne wpisy z blogów ludzi związanych z branżą IT, linku o informacji, że w danym oprogramowaniu istnieje luka X, i można ją wykorzystać poprzez ABC. Na wpisie blogu dodany jest do tego link do strony producenta oprogramowania, na której zawarte są informacje o klientach wykorzystujących dane oprogramowanie. Oczywiście producent nie został jeszcze, o tym fakcie powiadomiony, a niczego winni klienci nawet nie są świadomi, że ktoś przekazał całej masie użytkowników instrukcje, o możliwości przeprowadzenia ataku na ich zasoby. Kolejnym niebezpieczeństwem jest samo bezpieczeństwo użytkowników, posiadających konta na danych serwisach oraz Czytelników, którzy mogą zostać poddani manipulacji medialnej. Pierwszy wariant jest związany z wymogiem ochrony danych personalnych, znajdujących się w tego rodzaju serwisach, które są publicznie wystawiane jako baza danych. Każda taka baza, powinna zawierać ochronę danych zebranych użytkowników przez serwis w postaci wewnętrznej struktury, do której dostęp powinien być przyznany tylko i wyłącznie właścicielom danych osobowych, administratorom i Inspektorowi Ochrony Danych Osobowych (wyłączyć można mechanizmy logowania oraz kopii zapasowych jako procesy niezbędne do funkcjonowania serwisu), po uprzedniej autoryzacji, czyli podaniu nazwy użytkownika i hasła. Jednak wiele rodzai tego typu serwisów nadal umożliwia obchodzenie tych mechanizmów bezpieczeństwa, poprzez stawianie nacisku na dzielenie się tymi danymi wśród użytkowników, bez możliwości określenia szczegółowych list dostępu, dla osób postronnych. Mówiąc, o manipulacji Czytelników należy mieć na myśli, fakt oddziaływania poprzez nich na różne opinie publiczne. Często osoby nie posiadające własnego zdania – poddawane są sugestii na różnego rodzaju tematy w ten sposób są autorami fałszowania rzeczywistych osiągnięć i wyników, które by zostały osiągnięte w normalnym tego rodzaju procesie. Przykładem są różnego rodzaju sugestie na temat, wypełniania sond czy ankiet, których manipulacja przynosi odpowiednie korzyści. Skoro wszyscy, to czemu ja też nie? Powyższe przykłady są początkiem góry lodowej w społecznych anomaliach występujących w tego rodzaju działalności Internetowej. Oczywiście istnieje wiele plusów przemawiających za stosowaniem tego, rodzaju promocji informacji, ale każdy kij ma dwa końce (oprócz procy). Dlatego przed przystąpieniem do jakiejkolwiek działalności w nowym trendzie technologicznym, należy zdawać sobie sprawę, że każde nowe zjawisko niezależnie od środowiska w jakim występuje, zaburza w pewnych warunkach dotychczasowe działanie starego systemu dopóki nie zostanie opracowany pomost pomiędzy, tym co nowe, a tym co stare – zapewniający bezpieczeństwo przejścia.

Felieton ten pochodzi z magazynu: Hakin9 Nr 7-8 (39) Lipiec / Sierpień 2008.

Dnia 20.03.2010

Mały powrót

A tak, czas na odrodzenie. Mały powrót występuje tu w opozycji do wszelkiej maści tytułów w rodzaju wielki comeback. Zresztą uzasadnione jest to chyba faktem, że z owym powrotem nie wiąże się nic szczególnego poza puszczeniem w niepamięć martwych miesięcy bez ani jednej notki Żeby jednak nie marnować wpisu na suche obwieszczenie, dodam “na osłodę” nieco [...]

Zimowy AgileTuning - ON-LINE!

Start konferencji już za kilka godzin. Mimo, że wszystkie wejściówki zostały wysprzedane to dzięki uprzejmości firmy Transmisje Online nadal istnieje szansa na wzięcie udzialu w konferencji.  O godznie 14:00 rozpoczynamy transmisję na żywo pod adresem: www.transmisjeonline.pl/agiletuning