|
|
Bu makalenin farkl� dillerde bulundu�u adresler: English Castellano Deutsch Francais Nederlands Portugues Russian Turkce |
taraf�ndan Frédéric Raynal, Christophe Blaess, Christophe Grenier <pappy(at)users.sourceforge.net, ccb(at)club-internet.fr, grenier(at)nef.esiea.fr> Yazar hakk�nda: Christophe Blaess ba��ms�z bir havac�l�k m�hendisi. Bir Linux tutkunu ve i�inin �o�unu bu sistem �zerinde ger�ekle�tiriyor. Linux Documentation Project taraf�ndan yay�nlanan yard�m sayfalar�n�n �evrimini koordine ediyor. Christophe Grenier ESIEA'de 5. y�l ��rencisi. Orada sistem y�neticisi olarak ta �al���yor. Bilgisayar g�venli�i konusuna tutkusu var. Frédéric Raynal kirletilmedi�i, hormonlanmad��� i�in uzunca y�llard�r Linux kullan�yor, MSG yada k�pek kemik yeme�i... sadece tatl� ve h�nerli. T�rk�e'ye �eviri: �nan� �z�ubuk�u <mio(at)ceomio.com> ��erik:
|
�zet:
K�t� programlanm�� bir Perl beti�inden dosya almak, program �al��t�rmak... "Bunu Yapman�n Birden �ok Yolu Var!"
Serideki �nceki yaz�lar :
�stemci bir HTML dosyas� sordu�u zaman, sunucu istenen dosyay�
(yada bir hata mesaj�) g�nderir. Taray�c�, HTML kodunu i�lemek ve
ekranda g�stermek i�in yorumlar. �rnek olarak,
http://www.linuxdoc.org/HOWTO/ HOWTO-INDEX/howtos.html
yazarak URL (Uniform Request Locator), sunucu HTTP protokol�n� kullanarak
www.linuxdoc.org
sunucusuna ba�lan�r ve
/HOWTO/HOWTO-INDEX/howtos.html
sayfas�n� sorar
E�er sayfa varsa, sunucu istenen sayfay� g�nderir.
Bu dura�an modelle, e�er dosya sunucuda varsa,
istemciye "oldu�u gibi" g�nderilir, �b�r t�rl� bir hata
mesaj� g�nderilir (iyi bilinen 404 - Not Found hatas�).
Maalesef bu, e-i�, tatiller i�in e-rezervasyon yada m�mk�n olan her neyse kullan�c� ile interaktifli�i sa�lam�yor.
�ok ��k�r, de�i�ken olarak HTML sayfalar� yaratman�n yollar� var. CGI (Common Gateway Interface) betikleri bunlardan bir tanesi. Bu �rnekte, sayfalara eri�mek i�in kullan�lan URL biraz de�i�ik bir yolla yarat�lm��:
http://<server><pathToScript>[?[param_1=val_1][...] [¶m_n=val_n]]
QUERY_STRING
ortam de�i�keni i�erisinde
veri listesi QUERY_STRING
ortam de�i�keni i�erisinde
bir �al��t�r�labilir dosyad�r. ��erisinden ge�en verileri almak i�in
stdin
(standart girdi) yada bir QUERY_STRING
ortam
de�i�keni kullanmaktad�r. Kod �al��t�r�ld�ktan sonra sonu�,
stdout
'de (standard �ikti) g�z�k�r ve ard�ndan sanal y�re
sunucusuna y�nlenir. �o�unlukla her programlama dili CGI beti�i
(compiled C program, Perl,shell-scripts...) yazmakta kullan�labilir. �rnek olarak, www.linuxdoc.org
'dan ssh ile �rnek olarak, www.linuxdoc.org
'dan ssh ile
ilgili HOWTO arayal�m:
http://www.linuxdoc.org/cgi-bin/ldpsrch.cgi?
svr=http%3A%2F%2Fwww.linuxdoc.org&srch=ssh&db=1& scope=0&rpt=20
www.linuxdoc.org
;/cgi-bin/ldpsrch.cgi
olarak adland�r�l�r. ;?
uzun veri listesinin ba�lang�c�d�r.
:
srv=http%3A%2F%2Fwww.linuxdoc.org
iste�in geldi�i sunucudur;srch=ssh
iste�in kendisini i�erir;db=1
sadece HOWTO lar� i�erdi�ini anlat�r;scope=0
iste�in sadece ba�l��� de�il i�erikleri
kapsad���n� anlat�r;rpt=20
g�r�nt�lenen cevaplar� 20 ile s�n�rlar.
Genelde veri isimleri ve de�erleri anlamlar�n� anlamak i�in yeterlidir. Dahas�, g�r�nt�lenen sayfan�n i�eri�i olduk�a manal�d�r.
�imdi CGI betiklerinin iyi taraf�n�n kullan�c�n�n verilere ula�ma imkan� oldu�unu biliyorsunuz... Fakat karanl�k y�n� k�t� yaz�lm�� betiklerin g�venlik a���� yaratmas�d�r.
Muhtemelen tercih etti�iniz web taray�c�n�zda ilgin� karakterlere
rastlam��s�n�zd�r. Bu karakterler ISO 8859-1 karakter seti ile kodlanm��lard�r
(>man iso_8859_1
'e bir g�z at�n�z). table 1
bu kodlar�n baz�lar�n�n anlam�n� vermektedir. Baz� IIS4.0 ve IIS5.0 sunucular�n�n
unicode bug olarak adland�r�lan "/" and "\" uzat�lm�� unicode temsilcileri �zerine kurulu
�ok tehlikeli a��klar� oldu�unu belirtmeliyim.
SSI Server Side Include
" ile Apache Tan�mlamas�.Server Side Include
bir web sunucusu i�levinin bir par�as�d�r.
Web sayfalar�na emir g�ndermeye, ayn� zamanda bir dosyay� "oldu�u gibi" i�ermeye yada bir komutu
(kabuk yada CGI beti�i) �al��t�rmaya olanak sa�lar.
Apache tan�mlama dosyas� httpd.conf
i�erisinde
"AddHandler server-parsed .shtml
" bu d�zene�i harekete ge�irir.
Genelde, .html
ve .shtml
aras�ndaki farktan kurtulmak i�in,
.html
uzant�s� ilave edilebilir. Elbette bu sunucuyu yava�lat�r...
Bu, dizin seviyesinde �u y�nerge ile kontrol edilebilir :
Options Includes
her SSI'y� aktifle�tirir ;OptionsIncludesNoExec
, exec
cmd
ve exec cgi
'y� engeller.Ekteki guestbook.cgi
beti�inde, kullan�c� taraf�ndan
sa�lanan metin bir HTML dosyas� i�erisinde, '<' ve ' >' i�erisinde < ve >
karakter d�n��t�rmesi olmadan bulunur. Merakl� birisi �u talimatlardan birisini g�nderebilir:
<!--#printenv -->
(printenv
sonras� bo�lu�u unutma)<!--#exec cmd="cat /etc/passwd"-->
guestbook.cgi?email=pappy&texte=%3c%21--%23printenv%20--%3e
DOCUMENT_ROOT=/home/web/sites/www8080 HTTP_ACCEPT=image/gif, image/jpeg, image/pjpeg, image/png, */* HTTP_ACCEPT_CHARSET=iso-8859-1,*,utf-8 HTTP_ACCEPT_ENCODING=gzip HTTP_ACCEPT_LANGUAGE=en, fr HTTP_CONNECTION=Keep-Alive HTTP_HOST=www.esiea.fr:8080 HTTP_PRAGMA=no-cache HTTP_REFERER=http://www.esiea.fr:8080/~grenier/cgi/guestbook.cgi? email=&texte=%3C%21--%23include+file%3D%22guestbook.cgi%22--%3E HTTP_USER_AGENT=Mozilla/4.76 [fr] (X11; U; Linux 2.2.16 i686) PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin REMOTE_ADDR=194.57.201.103 REMOTE_HOST=nef.esiea.fr REMOTE_PORT=3672 SCRIPT_FILENAME=/mnt/c/nef/grenier/public_html/cgi/guestbook.html SERVER_ADDR=194.57.201.103 [email protected] SERVER_NAME=www.esiea.fr SERVER_PORT=8080 SERVER_SIGNATURE=<ADDRESS>Apache/1.3.14 Server www.esiea.fr Port 8080</ADDRESS> SERVER_SOFTWARE=Apache/1.3.14 (Unix) (Red-Hat/Linux) PHP/3.0.18 GATEWAY_INTERFACE=CGI/1.1 SERVER_PROTOCOL=HTTP/1.0 REQUEST_METHOD=GET QUERY_STRING= REQUEST_URI=/~grenier/cgi/guestbook.html SCRIPT_NAME=/~grenier/cgi/guestbook.html DATE_LOCAL=Tuesday, 27-Feb-2001 15:33:56 CET DATE_GMT=Tuesday, 27-Feb-2001 14:33:56 GMT LAST_MODIFIED=Tuesday, 27-Feb-2001 15:28:05 CET DOCUMENT_URI=/~grenier/cgi/guestbook.shtml DOCUMENT_PATH_INFO= USER_NAME=grenier DOCUMENT_NAME=guestbook.shtml
�al��t�rma
talimat�, genelde size bir kabuk e�de�eri sa�lar :
guestbook.cgi?email=ppy&texte=%3c%21--%23exec%20cmd="cat%20/etc/passwd"%20--%3e
�unu denemeyin "<!--#include
file="/etc/passwd"-->
", HTML dosyas�n� bulabilece�iniz dizin yolu g�relidir
ve "..
" i�eremez. Apache error_log
dosyas�, yasaklanm�� bir dosyaya eri�im
giri�imi oldu�u mesaj�n� i�erir. Kullan�c� HTML sayfas�nda [an error occurred while
processing this directive]
mesaj�n� g�rebilir.
SSI her zaman gerekli de�ildir. Bu sebeple sunucu �zerinde kapat�labilir. Ancak sorunun sebebi k�r�k guestbook uygulamas� ve SSI birle�imidir.
Bu b�l�mde, PERL ile yaz�lm�� CGI betikleri ile ilgili g�venlik a��klar�n� tan�taca��z. Olaylar� a��klamak i�in �rnek kodlar�n tamam�n� de�il, sadece sorunun sebebini anlamam�za yarayacak k�s�mlar�n� verece�iz.
Betiklerimizin hepsi asa��daki �ablona uygun olarak yarat�lm��t�r :
#!/usr/bin/perl -wT BEGIN { $ENV{PATH} = '/usr/bin:/bin' } delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer =:-) print "Content-type: text/html\n\n"; print "<HTML>\n<HEAD>"; print "<TITLE>Remote Command</TITLE></HEAD>\n"; &ReadParse(\%input); # now use $input e.g like this: # print "<p>$input{filename}</p>\n"; # #################################### # # Start of problem description # # #################################### # # ################################## # # End of problem description # # ################################## # form: print "<form action=\"$ENV{'SCRIPT_NAME'}\">\n"; print "<input type=texte name=filename>\n </form>\n"; print "</BODY>\n"; print "</HTML>\n"; exit(0); # first arg must be a reference to a hash. # The hash will be filled with data. sub ReadParse($) { my $in=shift; my ($i, $key, $val); my $in_first; my @in_second; # Read in text if ($ENV{'REQUEST_METHOD'} eq "GET") { $in_first = $ENV{'QUERY_STRING'}; } elsif ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN,$in_first,$ENV{'CONTENT_LENGTH'}); }else{ die "ERROR: unknown request method\n"; } @in_second = split(/&/,$in_first); foreach $i (0 .. $#in_second) { # Convert plus's to spaces $in_second[$i] =~ s/\+/ /g; # Split into key and value. ($key, $val) = split(/=/,$in_second[$i],2); # Convert %XX from hex numbers to alphanumeric $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; # Associate key and value # \0 is the multiple separator $$in{$key} .= "\0" if (defined($$in{$key})); $$in{$key} .= $val; } return length($#in_second); }
Perl'e ge�irilmi� tezler hak�nda daha fazlas� (-wT
) sonra.
$ENV
ve $PATH
�evre de�i�kenlerini
temizlemeye ba�l�yoruz ve HTML ba�l���n� (bu bir �e�it taray�c� ile sunucu aras�ndaki
html protokol�n bir par�as� gibidir. Taray�c�da g�r�nt�lenen web sayfas� i�erisinde
g�remezsiniz) g�nderiyoruz. ReadParse()
fonksiyonu beti�e ge�mi� tezleri okur.
Mod�llerle daha kolay ger�ekle�tirilebilir fakat bu yolla t�m kodu g�rebilirsiniz.
Ard�ndan, �rnekleri sunuyoruz. En son, HTML dosyas� ile bitiriyoruz.
Perl her karakteri ayn� yolla de�erlendirir, C fonksiyonundan farkl� olan nedir, �rne�inde oldu�u gibi. Perl i�in, bir dizi sonu bo� karakteri di�erleri gibi bir karakterdir. Yani ?
showhtml.cgi
beti�ini yaratmak i�in �u kodu ilave edelim :
# showhtml.cgi my $filename= $input{filename}.".html"; print "<BODY>File : $filename<BR>"; if (-e $filename) { open(FILE,"$filename") || goto form; print <FILE>; }
ReadParse()
fonksiyonu tek bir tez al�r :
g�r�nt�lenecek dosyan�n ismi. HTML dosyas�ndan fazlas�n� okuyarak olan baz�
"kaba konuklar�" �nlemek i�in, dosya sonuna ".html
" uzant�s�n� ekliyoruz.
Fakat, unutmay�n ki, bo� byte di�erleri gibi bir karakterdir...
B�ylece, e�er iste�imiz showhtml.cgi?filename=%2Fetc%2Fpasswd%00
ise,
�a�r�lan dosya my $filename = "/etc/passwd\0.html"
dir ve �a�k�n g�zlerimiz
HTML olmayan bir �eye dikilmi�tir.
Neler oluyor ? strace
komutu Perl bir dosyay� nas�l a��p g�steriyor:
/tmp >>cat >open.pl << EOF > #!/usr/bin/perl > open(FILE, "/etc/passwd\0.html"); > EOF /tmp >>chmod 0700 open.pl /tmp >>strace ./open.pl 2>&1 | grep open execve("./open.pl", ["./open.pl"], [/* 24 vars */]) = 0 ... open("./open.pl", O_RDONLY) = 3 read(3, "#!/usr/bin/perl\n\nopen(FILE, \"/et"..., 4096) = 51 open("/etc/passwd", O_RDONLY) = 3
strace
taraf�ndan temsil edilen sonda ki open()
, C ile yaz�lm��
sistem �a�r�s�yla uyu�ur. .html
uzant�s�n�n kayboldu�unu g�rebiliriz
ve bu, /etc/passwd dosyas�n� a�mam�z� sa�lar.
Bu problem, t�m bo� byte'lar� kald�ran tek bir mutat ifade ile ��z�lm��t�r:
s/\0//g;
��te korumas�z bir betik. /home/httpd/ dizin a�ac�ndan bir dosyay� g�stermekte:
#pipe1.cgi my $filename= "/home/httpd/".$input{filename}; print "<BODY>File : $filename<BR>"; open(FILE,"$filename") || goto form; print <FILE>;
G�lmeyin bu �rne�e ! B�yle �ok betik g�rd�m.
�lk i�letici (exploit) apa��k ortada:
pipe1.cgi?filename=..%2F..%2F..%2Fetc%2FpasswdYap�lmas� gereken tek �ey dizinde yukar� gitmek ve dosyaya eri�mek. Fakat daha ilgin� ba�ka bir olas�l�k daha var: tercih etti�iniz komutu �al��t�rmak. Perl'de,
open(FILE, "/bin/ls")
komutu "/bin/ls
" ikili taban dosyas�n� a�ar... fakat
open(FILE, "/bin/ls |")
belirtilen komutu �al��t�r�r.
Tek bir boru |
eklemek open()
'n�n davran���n� de�i�tirir. Bu ger�ekten yola ��karak gelen ba�ka bir sorunda dosyan�n varl���n�n test edilmemi� olmas�d�r.
Her komutu �al��t�rmam�z� sa�layan ama �zellikle her tezi veren :
pipe1.cgi?filename=..%2F..%2F..%2Fbin%2Fcat%20%2fetc%2fpasswd%20|
�ifre dosyas�n�n i�erisini g�sterir.
Dosyan�n varl���n� test etmek daha az �zg�rl�k tan�yor :
#pipe2.cgi my $filename= "/home/httpd/".$input{filename}; print "<BODY>File : $filename<BR>"; if (-e $filename) { open(FILE,"$filename") || goto form; print <FILE> } else { print "-e failed: no file\n"; }�nceki �rnek hi� i�lemiyor. "
-e
"
testi "../../../bin/cat
/etc/passwd |
" dosyas�n� bulamad���ndan �t�r� ba�aram�yor. �imdi /bin/ls
komutunu deneyelim. Sonu� �ncekinin ayn�s� olacak.
��te, �rnek olarak /etc
dizininin i�eri�ini g�r�nt�lemek
istersek, "-e
", "../../../bin/ls /etc |
dosyas�n�n
varl���n� sorgular, fakat her ikisi de var de�il. "hayalet" dosyas�n�n ismini en k�sa
zamanda sa�lamad�k�a, herhangi ilgin� bir�ey elde etmeyece�iz :(
Yine de hala bir "��k�� yolu" var, sonu� iyi olmasa bile.
/bin/ls
dosyas� var (sistemlerin �o�unda),
fakat e�er open()
bu dosya ismi taraf�ndan �a��r�l�rsa,
dosya �al��mayacak ancak ikili taban g�r�nt�lenecek. Bunun ard�ndan
ismin sonuna "-e
" taraf�ndan yap�lan incelemede kullan�lmadan bir boru
'|
' koyman�n yolunu bulmal�y�z. ��z�m� zaten biliyoruz: bo� byte. E�er
"../../../bin/ls\0|
" isim olarak g�nderirsek, mevcudiyet incelemesi sadece
"../../../bin/ls
" dizinini g�z �n�ne ald���nda ba�ar�l� olur, fakat open()
boruyu g�rebilir ve komutu �al��t�r�r. B�ylece, dizinin i�eri�ini veren URL :
pipe2.cgi?filename=../../../bin/ls%00|
finger.cgi beti�i, makinede ki finger
y�nergesini �al��t�r�r :
#finger.cgi print "<BODY>"; $login = $input{'login'}; $login =~ s/([;<>\*\|`&\$!#\(\)\[\]\{\}:'"])/\\$1/g; print "Login $login<BR>\n"; print "Finger<BR>\n"; $CMD= "/usr/bin/finger $login|"; open(FILE,"$CMD") || goto form; print <FILE>
Bu betik, (en az�ndan) kullan��l� bir tedbir al�r : baz� ilgin� karakterlerin,
ba�a '\
' kabu�u yerle�tirerek �n�ne ge�ilmesini engellemek i�in tedbirini al�r.
B�ylece, noktal� virg�l d�zenli anlat�mla "\;
" olarak de�i�ir. Ancak liste her
�nemli karakteri i�ermez. Di�erlerinin aras�nda, besleme sat�r� '\n
' kay�pt�r.
Tercihiniz olan kabuk komut sat�r�nda, \n
' karakteri g�nderen RETURN
yada ENTER
tu�lar�na basarak bit y�nergeyi ge�erli k�lars�n�z.
Perl'de, ayn�s�n� yapabilirsiniz. Zaten open()
y�nergesinin
'|
' borusuyla biten bir sat�r�n komut �al��t�rmam�za izin verdi�ini g�rm��t�k.
Bu davran��� canland�rmak i�in finger komutuna g�nderilen login ard�na bir sat�rba�� ve bir y�nerge ilave ettik :
finger.cgi?login=kmaster%0Acat%20/etc/passwd
Sat�rda �e�itli y�nergeler �al��t�rmak i�in di�er karakterler biraz daha ilgin� :
;
: ilk y�nergeyi bitiriyor ve di�erine ge�iyor;&&
: e�er ilk y�nerge ba�ar�rsa
(�rne�in; kabu�a 0 d��erse), s�radaki �al��t�r�l�r;||
: e�er ilk y�nerge ba�ar�s�z olursa
(�rne�in; kabukta bo� bir de�ere d��mezse), bir sonraki �al��t�r�l�r.�nceki finger.cgi
beti�i baz� ilgin� karakterlerle sorunlardan ka��yor. B�ylece,
<finger.cgi?login=kmaster;cat%20/etc/passwd
adresi, noktal� virg�l ka�t��� zaman �al��m�yor.
Yine de bir karakter korunmuyor : ters kesme '\
'.
�rnek olarak bizi "..
" dan mutat s/\.\.//g
ifadesi kurtaran dizin a�ac�ndan yukar�
a�a�� gitmemizi engelleyen bir betik alal�m. Fark etmez! Kabuklar �ok say�da '/
''yi tek seferde
y�netebilirler (ikna olmak i�in cat ///etc//////passwd
'yi deneyin).
�rnek olarak, yukar�da ki pipe2.cgi
beti�inde, $filename
de�i�keni
"/home/httpd/
" �rne�inden ba�lar. �nceki y�nergeyi kullanarak dizinler aras�nda yukar� a�a��
gidilmesini engellemede etkili oldu�u g�r�lebilir. Elbette, bu ifade "..
" dan itibaren korur,
ancak '.
' karakterini korursak ne olacak ? E�er dosya ismi .\./.\./etc/passwd
ise mutat
ifade uyu�maz. Belirtmeliyiz ki, system()
(yada ` ... `
) ile �ok iyi �al��makta,
fakat open()
yada "-e
" ba�ar�s�z olur.
finger.cgi
beti�ine geri d�nelim. Noktal� virg�l kullanarak
finger.cgi?login=kmaster;cat%20/etc/passwd
URI si noktal� virg�l mutat ifade taraf�ndan korundu�undan
beri umulan sonucu vermez. Kabuk �u y�nermeyi verir :
/usr/bin/finger kmaster\;cat /etc/passwdA�a��daki hatalar web sunucu kay�tlar�ndan bulundu :
finger: kmaster;cat: no such user. finger: /etc/passwd: no such user.Bu mesajlar bir kabukta yazarak elde edebilece�iniz sonu�larla e�tir. Sorun olgudan gelmektedir. Korunmal� '
;
' , "kmaster;cat
" dizisini yararl� olacak
�ekilde dikkate al�r. T�m y�nergeleri ay�rmak istiyoruz, birini betikten ve di�erini kullanmak istedi�imizden.
B�ylece korumam�z gereken
';
' : <A
HREF="finger.cgi?login=kmaster\;cat%20/etc/passwd">
finger.cgi?login=kmaster\;cat%20/etc/passwd</A>
. "\;
dizisi,
betik taraf�ndan "\\;
"'ya �evrilir ve sonra kabu�a g�nder. Sonuncunun okudu�u:
/usr/bin/finger kmaster\\;cat /etc/passwdKabuk bunu iki farkl� y�nergeye ay�r�r :
/usr/bin/finger kmaster\
.. fakat umursam�yoruz ;-)cat /etc/passwd
file.\
' de ka�abilir. Bazen parametreler kotalar kullan�larak korunur. �nceki finger.cgi
beti�ini,
korunakl� $login
beti�ine de�i�tirdik.
Yine de, e�er bu kotalar sakl� de�ilse, kullan��s�zd�r. Hatta talebinize ilave edilen bir tanesi ba�ar�s�z olacakt�r. Bu oluyor ��nk� ilk g�nderilen kota betikten a��k olan olan birisini kap�yor. Ard�ndan komutu yaz�yorsun, ve ikinci bir kota en son (kapanan) kotay� betikten a��yor.
finger2.cgi beti�i �unu ger�ekle�tiriyor :
#finger2.cgi print "<BODY>"; $login = $input{'login'}; $login =~ s/\0//g; $login =~ s/([<>\*\|`&\$!#\(\)\[\]\{\}:'\n])/\\$1/g; print "Login $login<BR>\n"; print "Finger<BR>\n"; #New (in)efficient super protection : $CMD= "/usr/bin/finger \"$login\"|"; open(FILE,"$CMD") || goto form; while(<FILE>) { print; }
Komut �al��t�ma URI'si �u �ekli al�yor :
finger2.cgi?login=kmaster%22%3Bcat%20%2Fetc%2Fpasswd%3B%22Kabuk komutu al�yor
/usr/bin/finger "$login";cat
/etc/passwd""
ve kotalar art�k sorun olmuyor. Bu, e�er ki parametreleri kotalarla korumak, �nceden bahsedildi�i gibi ters kesme ve noktal� virg�lden ka��rmak istiyorsan�z o derece �nemlidir.
Perl'de programlama yaparken, w
yada
"use warnings;
" (Perl 5.6.0 and later) se�eneklerini kullan�n. Bu sizi
incelenmemi� de�i�kenlere ve eski (modas� ge�mi�) terimlere/fonksiyonlara kar�� uyar�r.
T
se�ene�i (kusur modu) y�ksek g�venlik sa�lar.
Bu mod �e�itli testler ger�ekle�tirir. En �nemlisi, de�i�kenlerin
muhtemel kusurlar'� ile ilgilenir. De�i�kenler temiz yada kusurludur.
D��ar�dan gelen veri temizlenmedi�i s�rece program taraf�ndan kusurlu kabul edilir.
Kusurlu bir de�i�ken b�ylece program d��� kullan�lan de�erleri atayamaz (di�er kabuk komutlar�n� �a��rma).
Kusur modunda, komut sat�r� tezleri, �evre de�i�kenleri, baz� sistem �a�r� sonu�lar� (readdir()
,
readlink()
, readdir()
, ...) ve dosyalardan gelen veriler, ��pheli ve kusurlu olarak
de�erlendirilir.
De�i�kenleri temizlemek i�in, mutat terimlerin filtresinden ge�irmek gerekir. Belli ki .*
kullanmak yersizdir. Ama� sa�lanan tezlerden sizi endi�e duymaya zorlamakt�r. Her zaman m�mk�n oldu�unda �zel bir
mutat terim kullanmaya �al���n.
Yine de bu mod her�eyden korumaz : bir liste de�i�keni olarak system()
yada
exec()
'den ge�en tez kusurlar� incelenmez. E�er betiklerinizden biri bu fonksiyonlardan
birini kullan�yorsa �ok temkinli olmal�s�n�z. $arg
'�n kusurlu olup olmad��� bilinmeden,
exec "sh", '-c', $arg;
talimat� g�venli kabul edilir :(
Ayn� zamanda program�n�z�n ba��na "use strict;" ilave etmeniz tavsiye olnunur.
Bu sizi de�i�kenleri ilan etmenize zorlayacak; baz� insanlar bunu can s�k�c� bulacakt�r fakat
mod-perl
kullan�rsan�z bu mecburidir..
B�ylece, Perl CGI betikleriniz a�a��daki gibi ba�lamal�d�r :
#!/usr/bin/perl -wT use strict; use CGI;Yada Perl 5.6.0 ile:
#!/usr/bin/perl -T use warnings; use strict; use CGI;
open()
�a��rmak�o�u yaz�l�mc� basit�e open(FILE,"$filename") || ...
kullanarak dosya a�ar. Bu t�r kodlar�n risklerini
�nceden g�rm��t�k. Riski azaltmak i�in, a�ma modunu �zelle�tirelim :
open(FILE,"<$filename") || ...
sadece okumak i�in;open(FILE,">$filename") || ...
sadece yazmak i�inBir dosyaya eri�meden evvel, dosyan�n varl���n�n kontrol edilmesi tavsiye edilir. �nceki ba�l�kta an�at�lan baz� sorun tipleri �n�ne ge�ilmesinde yar�� havas� yaratmaz fakat tazli komutlar gibi baz� tuzaklardan ka��lmas�na yard�mc� olur.
if ( -e $filename ) { ... }
Perl 5.6'de ba�larken, open()
i�in yeni bir yaz�m var: open(FILEHANDLE,MODE,LIST)
.
'<' modu ile, dosya okumaya haz�rd�r; '>' modu ile, dosya k�salt�lm�� yada gerekliyse yarat�lm�� ve
yazma i�in a��lm��t�r. Di�er i�lemlerle konu�an modlar i�in ilgin�tir. E�er mod '|-' or '-|' ise, LIST tezi
bir komut olarak yorumlan�r ve s�raya g�re borudan �nce yada sonra bulunur.
Perl 5.6'dan ve 3 tezliopen()
'dan �nce, baz� insanlar sysopen()
komutunu kullan�rlard�.
�ki y�ntem var : yasaklanm�� karakterleri belirlersin yada mutat terimleri kullanan izin verilen karakterleri a��k�a belirlersin. �rnek programlar sizi muhtemel tehlikeli karakterleri unutman�n olduk�a kolay oldu�una inand�rmal�. Bu y�zden ikinci y�ntem tavsiye edilmektedir.
Hemen hemen yap�lmas� gereken ��yle bir �eydir : ilk olarak, izin verilen karakterlere sahip istekler kontrol edilir. Ard�ndan, izin verilenler aras�nda tehlikeli karakter olarak tan�mlananlar atlan�r.
#!/usr/bin/perl -wT # filtre.pl # $safe ve $danger de�i�kenleri s�ras�yla riskli olanlar� # ve olmayanlar� birbirinden ay�r�r. # Filtreyi de�i�tirmek i�in ekleme yada ��karma. # Sadece tan�mlardaki karakterleri i�eren $input ge�erlidir. use strict; my $input = shift; my $safe = '\w\d'; my $danger = '&`\'\\|"*?~<>^(){}\$\n\r\[\]'; #Note: # '/', bo�luk ve atlama, ama�taki tan�mlar�n par�as� de�il if ($input =~ m/^[$safe$danger]+$/g) { $input =~ s/([$danger]+)/\\$1/g; } else { die "Bad input chars in $input\n"; } print "input = [$input]\n";
Bu betik iki karakter seti tan�ml�yor :
$safe
riskli olarak tan�mlanmayanlar� i�erir (burada, sadece rakamlar ve harfler);$danger
izin verilen ancak muhtemel tehlikeli olan ka��n�lacak karakterleri i�erir.Tart��maya yol a�mak istemiyorum, ancak PERL yerine betikleri PHP 'de yazmak daha iyi.
Sistem y�netici olarak, kullan�c�lar�m�n betiklerini PERL'den �ok PHP de yazmalar�n� tercih ediyorum.
PHP'de g�vensiz programlama yapan birisi Perl de oldu�u gibi tehlikeli olacakt�r. �yleyse neden PHP'yi
tercih ediyoruz? E�er PHP ile baz� programlama sorunlar�n�z varsa g�venli modu aktifle�tirebilir
(safe_mode=on
) yada fonksiyonlar� pasifle�tirebilirsiniz disable_functions=...
).
Bu mod kullan�c�ya ait olmayan dosyalara eri�imi, a��k�a izin verilemedi�i taktirde �evre de�i�kenlerini de�i�tirmeyi,
komutlar� �al��t�rmay�, vs. engeller.
�n kabul olarak, Apache bayra�� bizi PHP kullan�laca�� y�n�nde bilgilendirir.
$ telnet localhost 80 Trying 127.0.0.1... Connected to localhost.localdomain. Escape character is '^]'. HEAD / HTTP/1.0 HTTP/1.1 200 OK Date: Tue, 03 Apr 2001 11:22:41 GMT Server: Apache/1.3.14 (Unix) (Red-Hat/Linux) mod_ssl/2.7.1 OpenSSL/0.9.5a PHP/4.0.4pl1 mod_perl/1.24 Connection: close Content-Type: text/html Connection closed by foreign host.A�a��daki bilgiyi gizlemek i�in
/etc/php.ini
i�erisine expose_PHP = Off
yaz�n:
Server: Apache/1.3.14 (Unix) (Red-Hat/Linux) mod_ssl/2.7.1 OpenSSL/0.9.5a mod_perl/1.24
/etc/php.ini
dosyas� (PHP4) ve
/etc/httpd/php3.ini
sistemi kat�la�t�rmak i�in bir�ok se�ene�e sahiptir.
�rnek olarak, "magic_quotes_gpc
" se�ene�i GET
, POST
metodlar� ve
kurabiyeler ile ile al�nan tezlere kotalar ilave eder; bu Perl �rneklerimizde bulunan bir �ok sorunun a��lmas�na
yard�mc� olur.
Muhtemelen bu yaz� serinin i�erisinde en anla��l�r olan�yd�. Herg�n sanal y�rede ortaya ��kan zay�fl�klar�
g�steriyor. S�k�a k�t� programlamaya ba�l� olarak �ok�a ba�kalar� da var (�rnek olarak, From:
k�sm�n� bir tez olarak alarak mesaj g�nderen bir betik, sald�r� i�in g�zel bir
site te�kil eder). �rnekler �ok�a. Betik web sitesi �zerinde olduk�a, en az�ndan bir ki�inin k�t� ama�la
kullanmaya �al��aca��na bahse girebilirsiniz.
Bu yaz� g�venlik yaz�l�mlar� serisini bitiriyor. Umar�m bir �ok uygulamada bulunan bir �ok temel g�venlik a����n� ke�fetmenizde yard�mc� olabildik ve "g�venlik" se�eneklerini uygulamalar�n�z� tasarlarken ve programlarken dikkate alacaks�n�z. Genelde s�n�rl� uygulama imkanlar� sebebi ile (i� kullan�m, ki�isel bilgisayar a�� kullan�m�, ge�ici modeller, vb.) g�venlik sorunlar� g�zard� edilmektedir. Yine de, �ok �zel bir kullan�m i�in tasarlanm�� bir mod�l ileride daha b�y�k bir uygulaman�n temelini olu�turabilir ve sonradan yap�lanacak de�i�iklikler �ok daha pahal�ya ��kabilir.
URI Encoding (ISO 8859-1) | Character |
%00 | \0 (end of string) |
%0a | \n (carriage return) |
%20 | space |
%21 | ! |
%22 | " |
%23 | # |
%26 | & (ampersand) |
%2f | / |
%3b | ; |
%3c | < |
%3e | > |
man perlsec
: g�venlikle ilgili Perl k�lavuz sayfas�;#!/usr/bin/perl -w # guestbook.cgi BEGIN { $ENV{PATH} = '/usr/bin:/bin' } delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # Make %ENV safer =:-) print "Content-type: text/html\n\n"; print "<HTML>\n<HEAD><TITLE>Buggy Guestbook</TITLE></HEAD>\n"; &ReadParse(\%input); my $email= $input{email}; my $texte= $input{texte}; $texte =~ s/\n/<BR>/g; print "<BODY><A HREF=\"guestbook.html\"> GuestBook </A><BR><form action=\"$ENV{'SCRIPT_NAME'}\">\n Email: <input type=texte name=email><BR>\n Texte:<BR>\n<textarea name=\"texte\" rows=15 cols=70> </textarea><BR><input type=submit value=\"Go!\"> </form>\n"; print "</BODY>\n"; print "</HTML>"; open (FILE,">>guestbook.html") || die ("Cannot write\n"); print FILE "Email: $email<BR>\n"; print FILE "Texte: $texte<BR>\n"; print FILE "<HR>\n"; close(FILE); exit(0); sub ReadParse { my $in =shift; my ($i, $key, $val); my $in_first; my @in_second; # Read in text if ($ENV{'REQUEST_METHOD'} eq "GET") { $in_first = $ENV{'QUERY_STRING'}; } elsif ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN,$in_first,$ENV{'CONTENT_LENGTH'}); }else{ die "ERROR: unknown request method\n"; } @in_second = split(/&/,$in_first); foreach $i (0 .. $#in_second) { # Convert plus's to spaces $in_second[$i] =~ s/\+/ /g; # Split into key and value. ($key, $val) = split(/=/,$in_second[$i],2); # Convert %XX from hex numbers to alphanumeric $key =~ s/%(..)/pack("c",hex($1))/ge; $val =~ s/%(..)/pack("c",hex($1))/ge; # Associate key and value $$in{$key} .= "\0" if (defined($$in{$key})); $$in{$key} .= $val; } return length($#in_second); }
|
G�rsely�re sayfalar�n�n bak�m�, LinuxFocus Edit�rleri taraf�ndan yap�lmaktad�r
© Frédéric Raynal, Christophe Blaess, Christophe Grenier, FDL LinuxFocus.org Buray� klikleyerek hatalar� rapor edebilir ya da yorumlar�n�z� LinuxFocus'a g�nderebilirsiniz |
�eviri bilgisi:
|
2001-12-19, generated by lfparser version 2.22