Jak zabezpieczyć konta shellowe na FreeBSD w czterech krokach
Jak zabezpieczyc konta shellowe na FreeBSD w czterech krokach?
=========================================================
Ponizszy artykul ma z zalozenia w czterech punktach pomoc zabezpieczyc nasze
ulubione BSDiki przed zbyt ciekawskimi uzytkownikami ostatnio popularnych kont
shellowych. Jesli dajemy uzytkownikom mozliwosc logowania sie do systemu
i pracowania przy uzyciu jego powloki, odkrywamy przed nimi wszystkie karty;
jakiego OSu uzywamy, numeru wersji, jakie uslugi sa uruchomione, itp. Uzytkownik
moze wowczas bezkarnie przegladac sobie konfiguracje serwera, ew. szukajac jego
slabych stron. Takie podejscie jest oczywiscie odrobine paranoiczne - w
wiekszosci przypadkow z pewnoscia czlowiek, ktory uzyskal uprawniony dostep do
shella naszego systemu bedzie go uzywal do malo wykwintnych celow jak odbieranie
poczty, ircowanie, wysylanie smsow czy po prostu skladowanie w swoim katalogu
domowym roznych smieci, ktore oczywiscie bedzie uwazal za najcenniejsze dla
niego lub jego firmy dane :). Moze sie jednak od czasu do czasu trafic ktos,
niestety, bardziej obeznany i wowczas mozemy miec problem. Aby temu zapobiec
wystarczy jednak przedsiewziac kilka bardzo prostych zasad.
Artykul nie porusza oczywistosci takich jak zapezpieczanie niektorych aplikacji
suidowych czy quota - autor staral sie zwrocic uwage na, jak przypuszcza, troche
niedoceniane lub lekcewazone elementy systemu mogace znacznie poprawic jego
bezpieczenstwo.
1 HOSTY
W przypadku naruszenia bezpieczenstwa systemu wazna jest mozliwosc ustalenia
zrodla ataku. W tym celu nalezy ograniczyc liczbe hostow z jakich poszczegolni
uzytkownicy beda mogli sie logowac. Oczywiscie wciaz istniec bedzie ryzyko, ze
nasz zdolniacha zacznie spoofowac jakis adres, lecz jak praktyka pokazuje jest
to najrzadsza forma ataku - wiec ryzyko jest znikome.
Aby juz przestac beltac od rzeczy a zabrac sie do roboty edytujemy
/etc/hosts.allow.
$vi /etc/hosts.allow
--------------------
#
# hosts.allow access control file for "tcp wrapped" applications.
# $FreeBSD: src/etc/hosts.allow,v 1.8.2.7 2002/04/17 19:44:22 dougb Exp $
#
# NOTE: The hosts.deny file is deprecated.
# Place both 'allow' and 'deny' rules in the hosts.allow file.
# See hosts_options(5) for the format of this file.
# hosts_access(5) no longer fully applies.
ALL : ALL : allow
#ten wpis pozwala na dostep wszystkich
sshd : ALL: deny
#ten wpis odmawia WSZYSTKIM dostepu do shella przed demona sshd
#i teraz dla kazdego hosta uzytkownika dodajemy oddzielne wpisy
sshd : host.jednego.usera.com : allow
sshd : host.drugiego.usera.com : allow
#... i tak dalej
#oczywiscie jesli user deklaruje ze bedzie sie laczyl przez PPP (tepsa)
#to wowczas mozemy napisac dla niego cos takiego:
sshd : .ppp.tpnet.pl
---------------------
I tym sposobem pierwszy plik za nami. Wyedytowany i zapisany. Zapominamy o nim
i idziemy dalej.
$vi /etc/login.access
---------------------
# $FreeBSD: src/etc/login.access,v 1.3 1999/08/27 23:23:42 peter Exp $
#
# Login access control table.
-:glupikazio:ALL EXCEPT host.kazia.com
-:reksio:ALL EXCEPT reksio.tez.ma.swoj.host.iraq.mil
#Tym sposobem dajemy uzytkownikom dostep tylko z okreslonych hostow.
#- oznacza brak dostepu (+ oznacz przyznanie dostepu - jak sie jeszcze
#ktos nie domyslil :>), po dwukropku ALL oczywiscie oznacza wszystkie hosty,
#EXCEPT pozwala okreslic wyjatki od reguly. Czyli w wolnym tlumaczeniu bedzie
#to oznaczalo:
#brak dostepu(-): user (glupikazio): dla wszystkich oprocz host.kazia.com
-----------------------
I w ten sposob formulujemy zasady udzielania dostepu userom. Oczywiscie mozna
dla jednego usera dac wiecej hostow niz jeden.
2 HISTORIA
Nastepna kwestia do rozwiazania jest to co user bedzie mogl robic po
zalogowaniu, a raczej to czego mu nie pozwolimy robic.
Po pierwsze niektorzy, bardziej cwani userzy dopisuje sobie do skryptow
startowych ln -fs /dev/null .history i wtedy nie ma mozliwosci sledzic w ich
historiach co robili. Jest to pierwszy sygnal ze uzytkownik cos kombinuje i nie
chce abysmy wiedzieli co.
Ponizszy opis ma zastosowanie jedynie w przypadku powlok tcsh i csh. Obie sa w
systemie FreeBSD wiec nie ma problemu. Nalezy tylko userom ustawic jedna z nich
jako standardowa.
Ustawiamy flage SAPPND na plik historii (man chflags), co uniemozliwi jego
modyfikacje. W /etc/csh.cshrc blokujemy zmienne $SAVEHIST (odpowiadajaca za
zapis) oraz $HISTORY (odp. za pamietanie bierzacej historii podczas pracy
powloki) jako TYLKO-DO-ODCZYTU. W ten sposob uzytkownik po zalogowaniu nie
bedzie mogl overridowac tychze zmiennych.
$vi /etc/csh.cshrc
------------------
# $FreeBSD: src/etc/csh.cshrc,v 1.3 1999/08/27 23:23:40 peter Exp $
#
# System-wide .cshrc file for csh(1).
# Dopisujemy ponizsze linijki
set -r savehist = 0
# To teraz jest nam niepotrzebne wiec 0
set -r history = 100000
# do 100 000 komend do zapamietania chyba wystarczy na kazda sesje.
-----------------------
Bierzaca historia zawsze moze zostac wyswietlona przez wbudowana komende powloki
csh (wlasciwie tcsh), history. Jako argument nalezy podac liczbe > 0.
Wyswietlona zostanie taka wlasnie ilosc ostatnio wywolanych polecen. Aby w
koncu do .history trafila lista wstukiwanych przez naszego ulubienca komend
nalezy do /etc/csh.logout dopisac "history 100000 >>.history".
$vi /etc/csh.logout
-------------------
# $FreeBSD: src/etc/csh.logout,v 1.3 1999/08/27 23:23:41 peter Exp $
#
# System-wide .logout file for csh(1).
history -h 100000 >>.history
-------------------
W ten prosty sposob kazde zdalne logowanie do systemu zakonczone bedzie zapisem
historii do wlasciwego pliku. Flaga SAPPND zabezpieczy plik, tak ze uzytkownik
nie bedzie mogl dokonac zadnej jego modyfikacji. To tyle jesli chodzi o
historie. Zabezpieczylismy ja na tyle ze wiekszosc przecietnych juserow ku
swojemu zmartwieniu nie bedzie mogla zatrzec sladow swojej niechlubnej
dzialalnosci.
3 PARTYCJE
Standardowo montowane partycje mozna znalezc w /etc/fstab:
%cat /etc/fstab
---------------
# See the fstab(5) manual page for important information on automatic mounts
# of network filesystems before modifying this file.
#
# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1a / ufs rw 1 1
/dev/ad0s1f /tmp ufs rw,noexec 2 2
/dev/ad4s1a /home ufs rw,noexec 2 2
/dev/ad0s1g /usr ufs rw 2 2
/dev/ad0s1e /var ufs rw,noexec 2 2
/dev/acd0c /cdrom cd9660 ro,noauto 0 0
/dev/acd1c /cdrom1 cd9660 ro,noauto 0 0
/dev/fd0a /mnt ufs rw,noauto 0 0
proc /proc procfs rw 0 0
----------------
Nie bede sie zajmowal tlumaczeniem co oznaczaja poszczegolne wpisy - w tym celu
polecam lekture man 5 fstab - zwrocmy jednak uwage na kolumne Options. rw -
oznacza read/write czyli urzadzenie montowane standardowo z mozliwoscia odczytu
i zapisu. Po przecinku mozna tam umiescic dodatkowe opcje i na tym wlasnie sie
skupimy. Dopisanie "noexec" uniemozliwi po nastepnym zamontowaniu urzadzenia
uruchomienie jakichkolwiek plikow wykonywalnych umieszczonych na tej partycji.
Dobrym zwyczajem jest przeznaczanie oddzielnej partycji na katalog /tmp
i montowanie go wlasnie z ta opcja. Katalog /tmp ma standardowo prawa 777, czyli
daje mozliwosc zapisu kazdemu uzytkownikowi. To z kolei umozliwic moze
przeprowadznie nawet wiekszej kompilacji wlasnie w tym katalogu, a potem
uruchomienie dowolnego programu. Ta cecha systemow UNIXowych byla czesto w
przeszlosci wykorzystywana do uruchamiania exploitow. W wiekszosci przypadkow
nie ma uzasadnionej potrzeby pozostawiania prawa do uruchamiania programow z
/tmp wiec mozemy zaraz po zainstalowaniu systemu dopisac odpowiednia opcje do
fstab. Mozna to samo rowniez zrobic dla /home. Tym sposobem eliminujemy
uzytkownikom mozliwosc uruchamiania instalowanych przez siebie aplikacji.
W skrocie: user nie moze uruchomic tego co moze zapisac i na odwrot :) Jesli
akurat ktos potrzebuje jakiegos programu moze przeciez poprosic administratora o
jego doinstalowanie :)
4 HASLA
Haslo do konta unixowego mozna chyba uznac za 'ostatnia linie obrony', dlatego
jest to szczegolnie wazne aby bylo dobre. Jezeli intruz dotarl juz do hasla to
ma juz praktycznie dostep do systemu (a przynajmniej do jednego z kont). Co
kryje sie pod pojeciem d o b r e g o hasla? Taki ciag znakow ktory jest trudny
do odgadniecia, najlepiej zupelnie losowy. Praktyka dowodzi jednak ze wiekszosc
uzytkownikow uzywa stosunkowo prostych hasel, przeciez latwiej je zapamietac
i latwiej jest je wstukac. Unixowy system autoryzacji wykorzystuje obecnie w
wiekszosci przypadkow algorytmy DES lub MD5, ktore sa praktycznie niemozliwe do
zlamania metoda inna niz brute-force. Specjalisci dowiedli wprawdzie, ze DES
jest podatny na metode analizy roznicowej, jednak ze wzgledu na koniecznosc
spelnienia odpowiednich warunkow metoda ta jest daleko poza zasiegiem wiekszosci
smiertelnikow. Mozna wiec przyjac ze oba algorytmy zapewniaja wystarczajacy
poziom bezpieczenstwa, oczywiscie pod warunkiem ze zaszyfrowane nimi hasla
spelniaja pewne kryteria - przede wszystkim co do dlugosci i zroznicowania. I tu
sprawa sie rypie, gdyz jak to zwykle bywa, to element ludzki ma tu najwiekszy
wplyw - jesli haslo bedzie proste, zlamanie go metoda brute-force moze zajac
jedynie kilkanascie minut! Dlatego stosuje sie m.in. rozne mechanizmy
wymuszajace na juserze koniecznosc regularnej zmiany hasla. Nic jednak nie
gwarantuje, ze w koncu wybrane zostanie haslo ktore mozna uznac za dobre.
Dodatkowym ryzykiem jest mozliwosc wysniffowania hasla w przypadku
nieszyfrowanej transmisji - raz przechwycona sekwencja logowania umozliwi
wlamywaczowi wielokrotne logowanie do systemu przy uzyciu podsluchanego hasla.
I tu z pomoca przychodzi nam OPIE - One-time Password In Everything. Pakiet ten
jest standardowo instalowany razem z FreeBSD 4-7R (o innych nie wiem). Umozliwia
autoryzacje na podstawie jednorazowych hasel i tak go wlasnie skonfigurujemy
zeby z najmniejsza mozliwa niewygoda dla juserow zapewnial wieksze
bezpieczenstwo.
Dla dociekliwych - opie(4), dla niecierpliwych: zabieramy sie do pracy :)Aby
utworzyc dla uzytkownika 'luser1' haslo w OPIE piszemy jako root:
#opiepasswd -c luser1
Adding luser1:
Ony use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Enter new secret pass phrase:
Again new secret pass phrase:
ID luser1 OTP key is 499 z03313
YEAR NEAR HINT STAB HUNK JEAN
#
W ten sposob dodalismy uzytkownika do OPIE. Mowa byla o wygodzie userow wiec
chyba najlepszym rozwiazaniem bedzie dopisanie paru linijek do skryptow
startowych powloki, tak aby przy kazdym logowaniu uzytkownik informowany byl o
nastepnym hasle. Jednak nie mozna podac gotowego hasla (owszem da sie to zrobic
skryptami, tylko po co wtedy OPIE?:> ), zamiast tego informowac bedziemy
uzytkownika jaki jest nastepny numer hasla. Oczywiscie wymaga to sporzadzenia
listy hasel z odpowiadajacymi im numerami, ktora zaraz po zalozeniu konta w
b e z p i e c z n y sposob (Poczta Polska? ;>) dostarczymy do uzytkownika. OPIE
odlicza numery od 499 do 0. Sprawa jest wiec dosc prosta. Uzytkownik z haslem
OPIE loguje sie do systemu, wyswietla mu sie numer nastepnego hasla a on
sprawdza je sobie na swojej liscie. Dobrze bylo jeszcze zautomatyzowac proces
tworzenia hasel podczas zakladania kont. W tym celu przyjmiemy, ze kazdy
uzytkownik bedzie mial wlasne haslo (secret pass phrase) sluzace do
wygenerowania hasel OPIE. Najlepiej zeby bylo zupelnie losowe. W tym celu
posluzymy sie urzadzeniem /dev/urandom, ktore wyrzuci nam troche losowych
smieci, ktore to z kolei zapiszemy na chwile sobie do pliku.
Zaczniemy od napisania malego skryptu.
#vi opie.sh
--------------------
# opie.sh - Generator hasel OPIE
#
cat /etc/opiekeys | grep -v $1 > /etc/opiekeys
head -c 16 /dev/urandom |cat -v > /tmp/tmp.opie0
printf "\n" >> /tmp/tmp.opie0
cat /tmp/tmp.opie0 > /tmp/tmp.opie1
cat /tmp/tmp.opie1 >>/tmp/tmp.opie0
(opiepasswd -n 9999 -c $1 /root/$1.9999) 2> /dev/null
rm /tmp/tmp.opie0
(opiekey -n 9999 `opieinfo $1` < /tmp/tmp.opie1 > /root/$1.passwd) 2> /dev/null
printf "9999: " >> /root/$1.passwd
cat /root/$1.9999 >> /root/$1.passwd
chflags noschg $2/.opiepass
mv /tmp/tmp.opie1 $2/.opiepass
chflags schg $2/.opiepass
rm /root/$1.9999
---Zapisujemy-------
Powyzszy skrypt przygotuje nam losowy pass phrase, utworzy haslo OPIE dla
dodawanego uzytkownika, wygeneruje liste jego 9999 hasel oraz przeniesie plik z
/tmp do katalogu domowego uzytkownika do pliku .opiepass. Plik ten zawiera haslo
sluzace do generowania hasel OPIE, wiec mozna dodatkowo zabezpieczyc go przed
modyfikacjami flaga SCHG. Plik /root/$naszuser.passwd trzeba teraz wyslac w
jakis bezpieczny sposob do uzytkownika. Dla bezpieczenstwa mozna wyslac tylko
czesc i potem regularnie dosylac np. po 100 hasel. I tutaj uwaga: oczywiscie
mozna dopisac do powyzszego skryptu cos takiego:
printf "0\t0\t*\t*\t6\troot\t/usr/bin/opieinfo $1>/root/opie.info" \
>>/etc/crontab i wowczas raz w miesiacu w pliku opie.info bedzie aktualny stan
wszystkich uzytkownikow i mozna samemu fgrepnac komu ile hasel zostalo, potem
tylko odpalic opie.sh i juz mamy gotowa liste nowych hasel do wyslania.
Zaznaczam: MOZNA to zrobic. Ale jesli komus sie nie chce, wystarczy do motd
dopisac info, ze kazdy user ma obowiazek we wlasnym zakresie pilnowac hasel,
i gdy zblizaja sie do zera powiadomic admina :). Osobiscie optuje za drugim
rozwiazaniem :P
Po kazdym dodaniu nowego konta, wystarczy odpalic opie.sh i juz w /root mamy
plik z haslami jusera, a on sam w katalogu domowym - plik z losowym pass
phrase. Nastepnie idziemy na kawe, papierosa i rogalika z adwokatem :)
*UWAGA: Skrypt opie.sh wymaga dwoch argumentow: nazwy usera i jego katalogu
domowego. ("sh opie.sh juzer jegohomekatalog")
(C)Copyright, 2003, Nimn0d
=========================================================
Ponizszy artykul ma z zalozenia w czterech punktach pomoc zabezpieczyc nasze
ulubione BSDiki przed zbyt ciekawskimi uzytkownikami ostatnio popularnych kont
shellowych. Jesli dajemy uzytkownikom mozliwosc logowania sie do systemu
i pracowania przy uzyciu jego powloki, odkrywamy przed nimi wszystkie karty;
jakiego OSu uzywamy, numeru wersji, jakie uslugi sa uruchomione, itp. Uzytkownik
moze wowczas bezkarnie przegladac sobie konfiguracje serwera, ew. szukajac jego
slabych stron. Takie podejscie jest oczywiscie odrobine paranoiczne - w
wiekszosci przypadkow z pewnoscia czlowiek, ktory uzyskal uprawniony dostep do
shella naszego systemu bedzie go uzywal do malo wykwintnych celow jak odbieranie
poczty, ircowanie, wysylanie smsow czy po prostu skladowanie w swoim katalogu
domowym roznych smieci, ktore oczywiscie bedzie uwazal za najcenniejsze dla
niego lub jego firmy dane :). Moze sie jednak od czasu do czasu trafic ktos,
niestety, bardziej obeznany i wowczas mozemy miec problem. Aby temu zapobiec
wystarczy jednak przedsiewziac kilka bardzo prostych zasad.
Artykul nie porusza oczywistosci takich jak zapezpieczanie niektorych aplikacji
suidowych czy quota - autor staral sie zwrocic uwage na, jak przypuszcza, troche
niedoceniane lub lekcewazone elementy systemu mogace znacznie poprawic jego
bezpieczenstwo.
1 HOSTY
W przypadku naruszenia bezpieczenstwa systemu wazna jest mozliwosc ustalenia
zrodla ataku. W tym celu nalezy ograniczyc liczbe hostow z jakich poszczegolni
uzytkownicy beda mogli sie logowac. Oczywiscie wciaz istniec bedzie ryzyko, ze
nasz zdolniacha zacznie spoofowac jakis adres, lecz jak praktyka pokazuje jest
to najrzadsza forma ataku - wiec ryzyko jest znikome.
Aby juz przestac beltac od rzeczy a zabrac sie do roboty edytujemy
/etc/hosts.allow.
$vi /etc/hosts.allow
--------------------
#
# hosts.allow access control file for "tcp wrapped" applications.
# $FreeBSD: src/etc/hosts.allow,v 1.8.2.7 2002/04/17 19:44:22 dougb Exp $
#
# NOTE: The hosts.deny file is deprecated.
# Place both 'allow' and 'deny' rules in the hosts.allow file.
# See hosts_options(5) for the format of this file.
# hosts_access(5) no longer fully applies.
ALL : ALL : allow
#ten wpis pozwala na dostep wszystkich
sshd : ALL: deny
#ten wpis odmawia WSZYSTKIM dostepu do shella przed demona sshd
#i teraz dla kazdego hosta uzytkownika dodajemy oddzielne wpisy
sshd : host.jednego.usera.com : allow
sshd : host.drugiego.usera.com : allow
#... i tak dalej
#oczywiscie jesli user deklaruje ze bedzie sie laczyl przez PPP (tepsa)
#to wowczas mozemy napisac dla niego cos takiego:
sshd : .ppp.tpnet.pl
---------------------
I tym sposobem pierwszy plik za nami. Wyedytowany i zapisany. Zapominamy o nim
i idziemy dalej.
$vi /etc/login.access
---------------------
# $FreeBSD: src/etc/login.access,v 1.3 1999/08/27 23:23:42 peter Exp $
#
# Login access control table.
-:glupikazio:ALL EXCEPT host.kazia.com
-:reksio:ALL EXCEPT reksio.tez.ma.swoj.host.iraq.mil
#Tym sposobem dajemy uzytkownikom dostep tylko z okreslonych hostow.
#- oznacza brak dostepu (+ oznacz przyznanie dostepu - jak sie jeszcze
#ktos nie domyslil :>), po dwukropku ALL oczywiscie oznacza wszystkie hosty,
#EXCEPT pozwala okreslic wyjatki od reguly. Czyli w wolnym tlumaczeniu bedzie
#to oznaczalo:
#brak dostepu(-): user (glupikazio): dla wszystkich oprocz host.kazia.com
-----------------------
I w ten sposob formulujemy zasady udzielania dostepu userom. Oczywiscie mozna
dla jednego usera dac wiecej hostow niz jeden.
2 HISTORIA
Nastepna kwestia do rozwiazania jest to co user bedzie mogl robic po
zalogowaniu, a raczej to czego mu nie pozwolimy robic.
Po pierwsze niektorzy, bardziej cwani userzy dopisuje sobie do skryptow
startowych ln -fs /dev/null .history i wtedy nie ma mozliwosci sledzic w ich
historiach co robili. Jest to pierwszy sygnal ze uzytkownik cos kombinuje i nie
chce abysmy wiedzieli co.
Ponizszy opis ma zastosowanie jedynie w przypadku powlok tcsh i csh. Obie sa w
systemie FreeBSD wiec nie ma problemu. Nalezy tylko userom ustawic jedna z nich
jako standardowa.
Ustawiamy flage SAPPND na plik historii (man chflags), co uniemozliwi jego
modyfikacje. W /etc/csh.cshrc blokujemy zmienne $SAVEHIST (odpowiadajaca za
zapis) oraz $HISTORY (odp. za pamietanie bierzacej historii podczas pracy
powloki) jako TYLKO-DO-ODCZYTU. W ten sposob uzytkownik po zalogowaniu nie
bedzie mogl overridowac tychze zmiennych.
$vi /etc/csh.cshrc
------------------
# $FreeBSD: src/etc/csh.cshrc,v 1.3 1999/08/27 23:23:40 peter Exp $
#
# System-wide .cshrc file for csh(1).
# Dopisujemy ponizsze linijki
set -r savehist = 0
# To teraz jest nam niepotrzebne wiec 0
set -r history = 100000
# do 100 000 komend do zapamietania chyba wystarczy na kazda sesje.
-----------------------
Bierzaca historia zawsze moze zostac wyswietlona przez wbudowana komende powloki
csh (wlasciwie tcsh), history. Jako argument nalezy podac liczbe > 0.
Wyswietlona zostanie taka wlasnie ilosc ostatnio wywolanych polecen. Aby w
koncu do .history trafila lista wstukiwanych przez naszego ulubienca komend
nalezy do /etc/csh.logout dopisac "history 100000 >>.history".
$vi /etc/csh.logout
-------------------
# $FreeBSD: src/etc/csh.logout,v 1.3 1999/08/27 23:23:41 peter Exp $
#
# System-wide .logout file for csh(1).
history -h 100000 >>.history
-------------------
W ten prosty sposob kazde zdalne logowanie do systemu zakonczone bedzie zapisem
historii do wlasciwego pliku. Flaga SAPPND zabezpieczy plik, tak ze uzytkownik
nie bedzie mogl dokonac zadnej jego modyfikacji. To tyle jesli chodzi o
historie. Zabezpieczylismy ja na tyle ze wiekszosc przecietnych juserow ku
swojemu zmartwieniu nie bedzie mogla zatrzec sladow swojej niechlubnej
dzialalnosci.
3 PARTYCJE
Standardowo montowane partycje mozna znalezc w /etc/fstab:
%cat /etc/fstab
---------------
# See the fstab(5) manual page for important information on automatic mounts
# of network filesystems before modifying this file.
#
# Device Mountpoint FStype Options Dump Pass#
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1a / ufs rw 1 1
/dev/ad0s1f /tmp ufs rw,noexec 2 2
/dev/ad4s1a /home ufs rw,noexec 2 2
/dev/ad0s1g /usr ufs rw 2 2
/dev/ad0s1e /var ufs rw,noexec 2 2
/dev/acd0c /cdrom cd9660 ro,noauto 0 0
/dev/acd1c /cdrom1 cd9660 ro,noauto 0 0
/dev/fd0a /mnt ufs rw,noauto 0 0
proc /proc procfs rw 0 0
----------------
Nie bede sie zajmowal tlumaczeniem co oznaczaja poszczegolne wpisy - w tym celu
polecam lekture man 5 fstab - zwrocmy jednak uwage na kolumne Options. rw -
oznacza read/write czyli urzadzenie montowane standardowo z mozliwoscia odczytu
i zapisu. Po przecinku mozna tam umiescic dodatkowe opcje i na tym wlasnie sie
skupimy. Dopisanie "noexec" uniemozliwi po nastepnym zamontowaniu urzadzenia
uruchomienie jakichkolwiek plikow wykonywalnych umieszczonych na tej partycji.
Dobrym zwyczajem jest przeznaczanie oddzielnej partycji na katalog /tmp
i montowanie go wlasnie z ta opcja. Katalog /tmp ma standardowo prawa 777, czyli
daje mozliwosc zapisu kazdemu uzytkownikowi. To z kolei umozliwic moze
przeprowadznie nawet wiekszej kompilacji wlasnie w tym katalogu, a potem
uruchomienie dowolnego programu. Ta cecha systemow UNIXowych byla czesto w
przeszlosci wykorzystywana do uruchamiania exploitow. W wiekszosci przypadkow
nie ma uzasadnionej potrzeby pozostawiania prawa do uruchamiania programow z
/tmp wiec mozemy zaraz po zainstalowaniu systemu dopisac odpowiednia opcje do
fstab. Mozna to samo rowniez zrobic dla /home. Tym sposobem eliminujemy
uzytkownikom mozliwosc uruchamiania instalowanych przez siebie aplikacji.
W skrocie: user nie moze uruchomic tego co moze zapisac i na odwrot :) Jesli
akurat ktos potrzebuje jakiegos programu moze przeciez poprosic administratora o
jego doinstalowanie :)
4 HASLA
Haslo do konta unixowego mozna chyba uznac za 'ostatnia linie obrony', dlatego
jest to szczegolnie wazne aby bylo dobre. Jezeli intruz dotarl juz do hasla to
ma juz praktycznie dostep do systemu (a przynajmniej do jednego z kont). Co
kryje sie pod pojeciem d o b r e g o hasla? Taki ciag znakow ktory jest trudny
do odgadniecia, najlepiej zupelnie losowy. Praktyka dowodzi jednak ze wiekszosc
uzytkownikow uzywa stosunkowo prostych hasel, przeciez latwiej je zapamietac
i latwiej jest je wstukac. Unixowy system autoryzacji wykorzystuje obecnie w
wiekszosci przypadkow algorytmy DES lub MD5, ktore sa praktycznie niemozliwe do
zlamania metoda inna niz brute-force. Specjalisci dowiedli wprawdzie, ze DES
jest podatny na metode analizy roznicowej, jednak ze wzgledu na koniecznosc
spelnienia odpowiednich warunkow metoda ta jest daleko poza zasiegiem wiekszosci
smiertelnikow. Mozna wiec przyjac ze oba algorytmy zapewniaja wystarczajacy
poziom bezpieczenstwa, oczywiscie pod warunkiem ze zaszyfrowane nimi hasla
spelniaja pewne kryteria - przede wszystkim co do dlugosci i zroznicowania. I tu
sprawa sie rypie, gdyz jak to zwykle bywa, to element ludzki ma tu najwiekszy
wplyw - jesli haslo bedzie proste, zlamanie go metoda brute-force moze zajac
jedynie kilkanascie minut! Dlatego stosuje sie m.in. rozne mechanizmy
wymuszajace na juserze koniecznosc regularnej zmiany hasla. Nic jednak nie
gwarantuje, ze w koncu wybrane zostanie haslo ktore mozna uznac za dobre.
Dodatkowym ryzykiem jest mozliwosc wysniffowania hasla w przypadku
nieszyfrowanej transmisji - raz przechwycona sekwencja logowania umozliwi
wlamywaczowi wielokrotne logowanie do systemu przy uzyciu podsluchanego hasla.
I tu z pomoca przychodzi nam OPIE - One-time Password In Everything. Pakiet ten
jest standardowo instalowany razem z FreeBSD 4-7R (o innych nie wiem). Umozliwia
autoryzacje na podstawie jednorazowych hasel i tak go wlasnie skonfigurujemy
zeby z najmniejsza mozliwa niewygoda dla juserow zapewnial wieksze
bezpieczenstwo.
Dla dociekliwych - opie(4), dla niecierpliwych: zabieramy sie do pracy :)Aby
utworzyc dla uzytkownika 'luser1' haslo w OPIE piszemy jako root:
#opiepasswd -c luser1
Adding luser1:
Ony use this method from the console; NEVER from remote. If you are using
telnet, xterm, or a dial-in, type ^C now or exit with no password.
Then run opiepasswd without the -c parameter.
Enter new secret pass phrase:
Again new secret pass phrase:
ID luser1 OTP key is 499 z03313
YEAR NEAR HINT STAB HUNK JEAN
#
W ten sposob dodalismy uzytkownika do OPIE. Mowa byla o wygodzie userow wiec
chyba najlepszym rozwiazaniem bedzie dopisanie paru linijek do skryptow
startowych powloki, tak aby przy kazdym logowaniu uzytkownik informowany byl o
nastepnym hasle. Jednak nie mozna podac gotowego hasla (owszem da sie to zrobic
skryptami, tylko po co wtedy OPIE?:> ), zamiast tego informowac bedziemy
uzytkownika jaki jest nastepny numer hasla. Oczywiscie wymaga to sporzadzenia
listy hasel z odpowiadajacymi im numerami, ktora zaraz po zalozeniu konta w
b e z p i e c z n y sposob (Poczta Polska? ;>) dostarczymy do uzytkownika. OPIE
odlicza numery od 499 do 0. Sprawa jest wiec dosc prosta. Uzytkownik z haslem
OPIE loguje sie do systemu, wyswietla mu sie numer nastepnego hasla a on
sprawdza je sobie na swojej liscie. Dobrze bylo jeszcze zautomatyzowac proces
tworzenia hasel podczas zakladania kont. W tym celu przyjmiemy, ze kazdy
uzytkownik bedzie mial wlasne haslo (secret pass phrase) sluzace do
wygenerowania hasel OPIE. Najlepiej zeby bylo zupelnie losowe. W tym celu
posluzymy sie urzadzeniem /dev/urandom, ktore wyrzuci nam troche losowych
smieci, ktore to z kolei zapiszemy na chwile sobie do pliku.
Zaczniemy od napisania malego skryptu.
#vi opie.sh
--------------------
# opie.sh - Generator hasel OPIE
#
cat /etc/opiekeys | grep -v $1 > /etc/opiekeys
head -c 16 /dev/urandom |cat -v > /tmp/tmp.opie0
printf "\n" >> /tmp/tmp.opie0
cat /tmp/tmp.opie0 > /tmp/tmp.opie1
cat /tmp/tmp.opie1 >>/tmp/tmp.opie0
(opiepasswd -n 9999 -c $1 /root/$1.9999) 2> /dev/null
rm /tmp/tmp.opie0
(opiekey -n 9999 `opieinfo $1` < /tmp/tmp.opie1 > /root/$1.passwd) 2> /dev/null
printf "9999: " >> /root/$1.passwd
cat /root/$1.9999 >> /root/$1.passwd
chflags noschg $2/.opiepass
mv /tmp/tmp.opie1 $2/.opiepass
chflags schg $2/.opiepass
rm /root/$1.9999
---Zapisujemy-------
Powyzszy skrypt przygotuje nam losowy pass phrase, utworzy haslo OPIE dla
dodawanego uzytkownika, wygeneruje liste jego 9999 hasel oraz przeniesie plik z
/tmp do katalogu domowego uzytkownika do pliku .opiepass. Plik ten zawiera haslo
sluzace do generowania hasel OPIE, wiec mozna dodatkowo zabezpieczyc go przed
modyfikacjami flaga SCHG. Plik /root/$naszuser.passwd trzeba teraz wyslac w
jakis bezpieczny sposob do uzytkownika. Dla bezpieczenstwa mozna wyslac tylko
czesc i potem regularnie dosylac np. po 100 hasel. I tutaj uwaga: oczywiscie
mozna dopisac do powyzszego skryptu cos takiego:
printf "0\t0\t*\t*\t6\troot\t/usr/bin/opieinfo $1>/root/opie.info" \
>>/etc/crontab i wowczas raz w miesiacu w pliku opie.info bedzie aktualny stan
wszystkich uzytkownikow i mozna samemu fgrepnac komu ile hasel zostalo, potem
tylko odpalic opie.sh i juz mamy gotowa liste nowych hasel do wyslania.
Zaznaczam: MOZNA to zrobic. Ale jesli komus sie nie chce, wystarczy do motd
dopisac info, ze kazdy user ma obowiazek we wlasnym zakresie pilnowac hasel,
i gdy zblizaja sie do zera powiadomic admina :). Osobiscie optuje za drugim
rozwiazaniem :P
Po kazdym dodaniu nowego konta, wystarczy odpalic opie.sh i juz w /root mamy
plik z haslami jusera, a on sam w katalogu domowym - plik z losowym pass
phrase. Nastepnie idziemy na kawe, papierosa i rogalika z adwokatem :)
*UWAGA: Skrypt opie.sh wymaga dwoch argumentow: nazwy usera i jego katalogu
domowego. ("sh opie.sh juzer jegohomekatalog")
(C)Copyright, 2003, Nimn0d
Autor:
Nimn0d
Porozmawiaj o tym artykule na forum:
quex, pon., 25/02/2008 - 01:37
