[LinuxFocus-icon]
Ev  |  Eri�imd�zeni  |  ��indekiler  |  Arama

Duyumlar | Belgelikler | Ba�lant�lar | LF Nedir
Bu makalenin farkl� dillerde bulundu�u adresler: English  Castellano  Deutsch  Francais  Nederlands  Portugues  Russian  Turkce  

convert to palmConvert to GutenPalm
or to PalmDoc

[image of the authors]
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:

 

Uygulama geli�tirirken g�venlik a��klar�ndan ka��nmak - B�l�m 6: CGI betikleri

[article illustration]

�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 :



 

Web sunucusu, URI ve tan�mlama sorunlar�

 

(�ok k�sa) Web sunucusu nas�l �al���r ve bir URI nas�l kurulura giri�

�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][...] [&param_n=val_n]]
Veri listesi 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
Asl�nda bu g�z�kt���nden daha basit. Bu URL'yi inceleyelim:

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 :



Ekteki guestbook.cgi beti�inde, kullan�c� taraf�ndan sa�lanan metin bir HTML dosyas� i�erisinde, '<' ve ' >' i�erisinde &lt; ve &gt; karakter d�n��t�rmesi olmadan bulunur. Merakl� birisi �u talimatlardan birisini g�nderebilir:

Birincisiyle,
guestbook.cgi?email=pappy&texte=%3c%21--%23printenv%20--%3e
sistem hakk�nda birka� sat�r bilgi al�rs�n�z :
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.

 

Perl betikleri

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.

 

Bo� byte

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;


 

Borular� kullanmak

��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%2Fpasswd
Yap�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|
 

Sat�r besleme

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� :



Mutat ifadeyle korunduklar�ndan itibaren �al��mazlar. Ancak, gelin bunu atlatman�n bir yolunu bulal�m.  

Ters kesme ve noktal� virg�l

�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/passwd
A�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/passwd
Kabuk bunu iki farkl� y�nergeye ay�r�r :
  1. Muhtemelen ba�ar�s�z olacak olan /usr/bin/finger kmaster\ .. fakat umursam�yoruz ;-)
  2. �ifreyi g�r�nt�leyen cat /etc/passwd file.
��z�m basit : ters kesme '\' de ka�abilir.

 

Korumas�z bir " kullanmak

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%22
Kabuk 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 yazmak

 

Uyar� ve kusur tercihleri

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 :

�zelle�tirilmemi� bir yolla dosyalar�n�z� a�may�n.

Bir 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�.

 

Ka�ma ve filtreleme girdisi

�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 :

�ki setten birinde bulunmayan bir karakter i�eren her talep an�nda geri �evrilmelidir.

 

PHP betikleri

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.

 

Sonu�

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.


 

Baz� URI kodlu karakterleri

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 >
Tab 1 : ISO 8859-1 ve karakter kar��l�klar�

 

Linkler


 

guestbook.cgi program�

#!/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);
}


 

Bu yaz� i�in g�r�� bildiriminde bulunabilirsiniz

Her yaz� kendi g�r�� bildirim sayfas�na sahiptir. Bu sayfaya yorumlar�n�z� yazabilir ve di�er okuyucular�n yorumlar�na bakabilirsiniz.
 talkback page 

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:
fr --> -- : Frédéric Raynal, Christophe Blaess, Christophe Grenier <pappy(at)users.sourceforge.net, ccb(at)club-internet.fr, grenier(at)nef.esiea.fr>
fr --> en: Georges Tarbouriech <georges.t(at)linuxfocus.org>
en --> en: Lorne Bailey <sherm_pbody(at)yahoo.com>
en --> tr: �nan� �z�ubuk�u <mio(at)ceomio.com>

2001-12-19, generated by lfparser version 2.22