|
|
This document is available in: English Castellano Deutsch Francais Nederlands Indonesian Russian |
oleh Frédéric Raynal, Christophe Blaess, Christophe Grenier <pappy/at/users.sourceforge.net ccb/at/club-internet.fr grenier/at/nef.esiea.fr> Tentang Penulis: Christophe Blaess adalah seorang aeronautics engineer independen. Beliau seorang penggemar Linux dan banyak menghabiskan kerjanya pada system Linux ini. Beliau bertugas sebagai koordinator untuk publikasi alih bahasa dari halaman manual dari Linux Documentation Project. Christophe Grenier adalah mahasiswa tahun ke 5 pada ESIEA, dimana dia bekerja sebagai sysadmin juga. Dia sangat berhasrat pada keamanan komputer . Frédéric Raynal menggunakan Linux, sertifikasi tanpa (software atau yang lain) hak patent. Selain itu, Anda mesti melihat Dancer in the Dark : selain itu Björk yang hebat, film ini bisa membuat Anda tak bergerak (Saya tidak bisa berkata lebih tanpa memperlihatkan penutupannya, seluruh tragis dan kesenangan). Diterjemahkan Ke Indonesia Oleh: Razmal Djamal (homepage) Daftar Isi: |
Menghindari Terjadinya Lubang Keamanan Saat Mengembangkan Sebuah Aplikasi - Bagian 1Abstrak:
Artikel ini adalah bagian pertama dari tulisan berseri mengenai jenis utama dari lubang keamanan pada sebuah aplikasi. Kami akan menunjukkan cara untuk menghindari kemunculan lubang keamanan tersebut dengan merubah sedikit kebiasaan pembuatan program Anda. |
Tidak membutuhkan lebih dari 2 minggu sebelum aplikasi besar yang termasuk bagian dari sebagian besar distribusi Linux menghadirkan lubang keamanan yang mengizinkan, sebagai contoh, user lokal menjadi root. Mengesampingkan kualitas yang hebat dari kebanyakan software ini, memastikan keamanan dari sebuah program adalah sebuah kerja keras : yang seharusnya tidak mengizinkan para penjahat untuk mendapatkan keuntungan ilegal dari kekayaan system .Ketersediaan dari kode sumber aplikasi adalah sesuatu yang baik, lebih banyak penghargaan oleh para programmer, tetapi gangguan terkecil dari software adalah menjadi terlihat untuk semua orang. Lebih jauh lagi, pendeteksian dari gangguan-gangguan tersebut muncul secara acak dan orang-orang yang menemukan gangguan tersebut tidak selalu punya perhatian yang baik. .
Dari sisi sysadmin , kerja harian mereka terdiri dari membaca daftar-daftar
masalah keamanan dan sesegera mungkin melakukan update terhadap paket-paket
yang terlibat dengan masalah tersebut. Untuk seorang programmer ini bisa menjadi sebuah pelajaran yang baik
untuk mencoba beberapa masalah keamanan karena menghindari terjadinya lubang keamanan sejak awal
adalah metode paling disarankan untuk memperbaiki lobang keamanan tersebut. Kami akan mencoba untuk memaparkan beberapa
kebiasaan "klasik" yang berbahaya dan menyediakan solusi untuk menurunkan resikonya.
Kami tidak akan berbicara masalah-masalah keamanan jaringan karena masalah jaringan tersebut muncul dari kesalahan konfigurasi
(script-script cgi-bin yang berbahaya, ...) atau dari lubang system yang memperbolehkan DOS
(Denial Of Service) type serangan yang menghalangi mesin untuk
listen kepada client-nya sendiri. Masalah seperti ini mengacu ke sysadmin
atau ke para pengembang kernel. Tetapi para programmer aplikasi mesti melindungi
kode mereka segera setelah kode mengarah ke account external data. Beberapa versi dari
pine
, acroread
, netscape
,
access
,...telah mengizinkan elevated access atau kebocoran informasi
untuk beberapa kondisi tertentu.Dan sebenarnya secure programming adalah urusan semua orang.
Seri artikel ini menunjukkan metode-metode yang bisa digunakan untuk merusak system Unix. Kami hanya bisa memaparkan metode-metode tersebut atau berkata sedikit tentang metode tersebut, tapi kami menyediakan penjelasan lengkap untuk membuat orang-orang mengerti resiko-resikonya. Dikarenakan, ketika mencari kesalahan program atau mengembangkan program Anda sendiri, Anda akan bisa untuk menghindari atau memperbaiki kesalahan-kesalahan ini. Untuk setiap lubang kesalahan yang kita diskusikan, kami akan mengambil pendekatan yang sama. Kami mulai dengan detail bagaimana kesalahan terjadi. Selanjutnya, kami akan memperlihatkan cara untuk menghindarinya. Untuk semua contoh kami akan menggunakan lubang keamanan yang masih tersebar luas pada software sekarang ini.
Artikel pertama ini bercerita tentang kebutuhan dasar untuk memahami lubang keamanan,
yang menjadi titik dari privileges dan pada bit
Set-UID atau Set-GID. Selanjutnya, kami menganalisa
lubang berdasarkan pada fungsi system()
dikarenakan hal ini lebih mudah
untuk dipahami.
Kami juga akan sering menggunakan program C yang kecil untuk menggambarkan apa yang
sedang kita bicarakan. Bagaimanapun, pendekatan-pendekatan yang dipaparkan pada seri artikel ini
bisa di aplikasikan dengan bahasa pemrograman lain : perl, java, shell
scripts... Beberapa lubang keamanan bergantung pada bahasanya, tetapi ini
tidak benar untuk semua seperti yang akan kita lihat dengan fungsi
system()
.
Pada system Unix, para pengguna (user) tidaklah sama, begitu pula
dengan aplikasi. Akses pada node-node file system - dan menuruti
periferal mesin - bermuara pada kontrol identitas secara langsung. Beberapa
user diizinkan untuk melakukan operasi sensitif untuk mengurusi system
dalam kondisi yang bagus. Nomer-nomer yang disebut UID (User Identifier)
mengizinkan proses pengenalan (identification). Untuk membuat segala sesuatu menjadi lebih mudah, nama user
berkorespondensi dengan nomer UID ini, proses asosiasi ini terjadi pada
file /etc/passwd
Kode UID 0, dengan nama default-nya root, bisa mengakses
segalanya pada system. Dia bisa membuat, merubah, dan menghapus seluruh
system node, tapi dia juga bisa dengan baik mengurusi konfigurasi secara fisik
dari mesin, melakukan mounting pada partisi, mengaktifkan kartu interface jaringan
dan merubah konfigurasinya (IP address), atau menggunakan system call seperti mlock()
untuk beraksi pada memori fisik, atau
sched_setscheduler()
untuk mengganti mekanisme permintaan system.
Pada artikel yang akan datang kita akan mempelajari fitur dari Posix.1e yang memperbolehkan
pembatasan terhadap privileges dari sebuah aplikasi yang dijalankan sebagai root,
tapi sekarang, mari kita asumsikan the super-user bisa melakukan
segala hal pada mesin.
Serangan yang akan kita paparkan adalah yang dari dalam, dari user ber-otorisasi pada mesin, mencoba untuk meningkatkan hak pakai yang tidak dia punyai. Di sisi lain, serangan pada jaringan ada pula yang dari luar, datang dari orang-orang yang mencoba untuk terhubung ke mesin yang mana mereka tidak diijinkan untuk itu..
Untuk menggunakan hak pakai cadangan untuk pemakai yang lain tanpa tercatat sebagai pemakai tersebut, seseorang mesti mempunyai minimal kesempatan untuk berbicara ke aplikasi yang dijalankan dibawah UID korban. Ketika sebuah aplikasi - sebuah proses - berjalan pada Linux, maka dia mempunyai sebuah identitas yang jelas. Pertama, program mempunyai sebuah atribut yang disebut RUID (RealUID) berkoresponden ke user ID yang menjalankannya. Data ini di urusi oleh kernel dan bisanya tidak bisa diubah. Begitu atribut menyelesaikan informasi tersebut :field pada EUID (Effective UID)berkoresponden ke identitas yang kernel bawa ke account user ketika mengurusi hak akses (membuka file,system-calls cadangan).
Untuk mendapatkan privileges dari user lain yang berarti semua hal bisa dilakukan dibawah UID user tersebut, dan tidak pada UID yang seharusnya. Tentunya, seorang cracker mencoba untuk mendapatkan ID dari root ,tapi banyak user yang lain juga menarik , dikarenakan mereka bisa memberikan akses ke informasi dari system (news, mail, lp...) atau karena mereka mengijinkan membaca data pribadi (mail, file pribadi, dll) atau mereka dapat digunakan untuk menyembunyikan aktifitas ilegal seperti serangan dari situs yang lain.
Untuk menjalankan aplikasi dengan privileges dari Effective UID
yang berbeda dari UID sebenarnya (user yang menjalankannya) file eksekusi
harus mempunyai bit tertentu yang di aktifkan, yang disebut Set-UID. Bit ini ditemukan
pada atribut file (seperti User execute,read, write bits, anggota group atau yang lain)
dan mempunyai nilai oktal 4000. Bit Set-UID diwakili dengan kode s
ketika
menampilkan hak-hak pakai dengan perintah ls
:
Perintah ">> ls -l /bin/su -rwsr-xr-x 1 root root 14124 Aug 18 1999 /bin/su >>
find / -type f -perm +4000
" menampilkan daftar
dari aplikasi-aplikasi system yang bit Set-UID mereka di set ke 1, atau diaktifkan.
Ketika kernel menjalankan applikasi dengan bit Set-UID on,
kernel menggunakan identitas EUID si empunya program EUID untuk proses itu. Dengan kata lain
,RUID tidak berubah dan berkorespondensi dengan user yang
menjalankan program. Sebagai gambaran, setiap user mempunyai akses ke
perintah /bin/su
, tetapi perintah ini berjalan
dibawah identitas pemilik program dalam hal ini (root) dengan
seluruh privileges pada system. Penting untuk dikatakan, bahwa seseorang mesti sangat
berhati-hati ketika menulis program dengan atribut seperti ini.
Setiap proses juga mempunyai Effective group ID, EGID, dan tanda pengenal asli
disebut RGID (Real GID). Bit Set-GID (2000 dalam octal) dalam hak akses
dari file eksekusi , bertanya ke kernel untuk menggunakan identitas group
dari pemilik file sebagai EGID dan bukan GID dari user yang menjalankan program.
Kombinasi yang serius terkadang muncul dengan Set-GID yang di set ke 1 tapi tanpa
bit eksekusi group. Kenyataannya, kejadian ini tidak ada hubungannya dengan
privileges yang berhubungan dengan aplikasi, tetapi mengindikasikan bahwa file bisa di block
dengan fungsi fcntl(fd, F_SETLK, lock)
.
Biasanya sebuah aplikasi tidak menggunakan bit Set-GID, tapi itu tidak terjadi setiap kali.
Beberapa game, sebagai gambaran, menggunakan proses itu utnuk menyimpan score terbesar
ke direktori system .
Ada banyak jenis dan type serangan terhadap system. Hari ini kita mempelajari mekanisme untuk menjalankan perintah external dari dan bersama aplikasi. Ini biasanya sebuah shell yang berjalan dibawah identity dari empunya aplikasi. Type kedua dari serangan mengarah ke buffer overflow memberikan penyerang kemampuan untuk menjalankan kode atau instruksi pribadi. Terakhir, Type serangan utama yang ketiga berdasar kepada race condition - selisih waktu antara dua instruksi dimana komponen system berubah (biasanya berupa file) yang mana aplikasi masih percaya bahwa itu berasal dari sumber yang sama.
Dua type serangan pertama biasanya mencoba mengeksekusi shell menggunakan
privileges dari empunya aplikasi, sementara type yang ketiga ditargetkan
pada mendapatkan hak akses menulis ke file system yang terproteksi.
Akses membaca terkadang mengarah ke kelemahan dari keamanan system
(file-file pribadi, email, file password /etc/shadow
,
and file konfigurasi pseudo kernel pada /proc
).
Target-target pada serangan keamanan sebagian besar kepada program yang mempunyai
bit Set-UID (atau Set-GID) on. Bagaimanapun, ini juga mempengaruhi setiap
aplikasi yang berjalan dibawah ID yang berbeda ID dibanding user-nya.
Daemon-daemon system mewakili bagian yang besar dari program-program ini. Daemon
adalah aplikasi yang bisanya di jalankan saat boot, berjalan di latar belakang
tanpa ada terminal kontrol, dan melakukan kerja dengan privilege untuk
setiap user. Sebagai contoh, daemon lpd
mengijinkan
semua user untuk mengirimkan dokumen ke printer, sendmail
menerima dan meneruskan surat elektronik, atau apmd
bertanya ke
Bios mengenai status baterai dari sebuah laptop. Beberapa daemon
bertugas terhadap komunikasi dengan user dari luar melalui jaringan
(Ftp, Http, Telnet... services). Server bernama inetd
mengurusi koneksi-koneksi
dari banyak jenis service ini.
Lalu kita bisa memutuskan bahwa program bisa diserang begitu program berkomunikasi - biarpun secara perlahan - kepada user yang berbeda dengan user yang menjalankannya. Saat mengembangkan aplikasi type ini Anda mesti berhati-hati untuk memikirkan resiko-resiko yang dipaparkan oleh function yang akan kita pelajari disini.
Ketika sebuah aplikasi berjalan dengan EUID yang berbeda dibanding RUID-nya, adalah bertujuan untuk menyediakan pemakai privileges yang dia butuhkan tetapi tidak mempunyai privileges tersebut (Hak akses file, system calls cadangan...). Walau begitu privileges tersebut dibutuhkan hanya untuk waktu yang sangat singkat, sebagai contoh ketika membuka sebuah file, dengan kata lain aplikasi dapat berjalan dengan privileges privileges-nya. Menjadi mungkin untuk sementara mengubah EUID aplikasi dengan menggunakan system-call :
int seteuid (uid_t uid);Sebuah proses selalu dapat mengubah nilai EUID-nya memberikan salah satu nilai dari RUID. Pada kasus tersebut, UID terdahulu tersimpan pada field yang disebut SUID (Saved UID) yang berbeda dari SID (Session ID) yang berguna untuk pengurusan terminal kontrol . Selalu menjadi mungkin untuk mendapatkan SUID kembali dan menggunakannya sebagai EUID. Tentu saja, program yang mempunyai EUID (root) dapat berubah seketika termasuk EUID dan RUID-nya (begitulah cara
/bin/su
bekerja).
Untuk mengurangi resiko dari serangan-serangan, disarankan untuk mengubah EUID dan juga mengubah RUID dari user. Ketika ada bagian dari kode membutuhkan privileges yang berhubungan dengan para pemilik file, sangat memungkinkan untuk menempatkan kode dari Saved UID ke EUID. Berikut sebagai contoh :
uid_t e_uid_initial; uid_t r_uid; int main (int argc, char * argv []) { /* Saves the different UIDs */ e_uid_initial = geteuid (); r_uid = getuid (); /* limits access rights to the ones of the * user launching the program */ seteuid (r_uid); ... privileged_function (); ... } void privileged_function (void) { /* Gets initial privileges back */ seteuid (e_uid_initial); ... /* Portion needing privileges */ ... /* Back to the rights of the runner */ seteuid (r_uid); }
Metode ini sangat lebih aman dibandingkan dengan semua ketidakberuntungan pada metode-metode umum terdiri dari penggunaan inisialisasi EUID dan pengurangan sementara privileges sesaat sebelum melakukan operasi "beresiko". Bagaimanapun pengurangan privilege ini tidaklah berguna menghadapi serangan buffer-overflow. Seperti yang akan kita lihat pada artikel selanjutnya, serangan serangan ini bertujuan untuk meminta pada aplikasi untuk mengeksekusi instruksi pribadi dan bisa saja mengandung system-calls yang dibutuhkan untuk membuat level privilege menjadi lebih tinggi. Dan pada akhirnya, pendekatan ini akan melindungi program dari perintah-perintah external dan dari kebanyakan race conditions.
Terkadang sebuah aplikasi butuh untuk memanggil perintah atau service external system.
Sebuah contoh yang telah dikenal dengan baik seperti perintah mail
untuk mengurusi
surat elektronik (menjalankan laporan, alarm, statistik, etc) tanpa
membutuhkan dialog yang rumit dengan mail system. Solusi yang termudah
adalah dengan menggunakan fungsi library :
int system (const char * command)
Fungsi ini lebih berbahaya : dia akan memanggil shell untuk
menjalankan perintah yang diberikan sebagai argumen. Perilaku shell bergantung pada
pilihan dari userr. Sebuah contoh sederhana datang dari lingkungan
PATH
variabel lingkungan. Mari kita lihat aplikasi yang
memanggil fungsi mail
. Sebagai gambaran, program berikut ini mengirimkan kode sumbernya
kepada pemakai yang menjalankannya :
Katakanlah program ini ber Set-UID root :/* system1.c */ #include <stdio.h> #include <stdlib.h> int main (void) { if (system ("mail $USER < system1.c") != 0) perror ("system"); return (0); }
Untuk menjalankan program ini,system menjalankan shell (dengan>> cc system1.c -o system1 >> su Password: [root] chown root.root system1 [root] chmod +s system1 [root] exit >> ls -l system1 -rwsrwsr-x 1 root root 11831 Oct 16 17:25 system1 >>
/bin/sh
) dan dengan opsi -c
, memberikan
instruksi untuk invoke. Lalu shell tersebut menelusuri hirarki direktori
berdasarkan pada lingkungan variabel PATH
untuk menemukan perintah yang disebut mail
. Untuk menguasai program,
pemakai hanya harus merubah isi dari variabel ini sebelum menjalankan
aplikasi. Sebagai contoh :
perhatikan perintah>> export PATH=. >> ./system1
mail
hanya pada direktori aktif-nya.
Seseorang hanya butuh untuk membuat file eksekusi (sebagai contoh
, sebuah script yang menjalankan shell baru) dan memberinya nama
mail
maka program akan di jalankan dengan EUID dari pemilik aplikasi utama !
Disini, script kami menjalankan /bin/sh
. Akan tetapi, karena ini dijalankan dengan
merubah arah standard input (seperti inisialisasi perintah mail
),
kita harus mendapatkannya kembali pada terminal. Lalu kita membuat script berikut :
Dan inilah hasilnya :#! /bin/sh # "mail" script running a shell # getting its standard input back. /bin/sh < /dev/tty
>> export PATH="." >> ./system1 bash# /usr/bin/whoami root bash#
Tentu saja, solusi pertama mengarah ke pemberian path penuh
kepada program, sebagai contoh /bin/mail
. Lalu sebuah program baru
muncul : aplikasi bersandar pada instalasi system. Jika program /bin/mail
biasanya tersedia pada
seluruh system, dimana GhostScript, sebagai contoh? (dia ada di /usr/bin
, /usr/share/bin
,
/usr/local/bin
?). Disisi lain, jenis lain dari serangan
menjadi mungkin dengan beberapa shell yang sudah lawas : penggunaan dari
lingkungan variable IFS
. Shell menggunakannya untuk melewatkan
kata-kata pada command line. Variabel ini mempunyai karakter pemisah .
Default karakter ini adalah spasi, tab dan return. Jika pengguna
menambahkan slash /
, perintah "/bin/mail
"
dipahami oleh shell sebagai "bin mail
". Sebuah file eksekusi yang disebut bin
pada direktorinya sendiri bisa dijalankan hanya dengan mengubah setting PATH
, seperti yang telah kita
lihat sebelumnya,dan mengizinkan untuk menjalankan program ini dengan EUID aplikasi.
Pada Linux, lingkungan variabel IFS
bukan lagi sebuah masalah
sejak bash dan pdksh kedua-duanya melengkapinya dengan karakter-karakter default
saat startup. Tetapi memikirkan tentang portability dari aplikasi
anda harus berhati-hati bahwa beberapa system mungkin lebih sedikit tidak aman
menanggapi variabel ini.
Beberapa Lingkungan variabel lain mungkin menyebabkan masalah-masalah yang tidak diharapkan.
Sebagai contoh, aplikasi mail
membolehkan user-user untuk
menjalankan perintah sembari membuat pesan menggunakan urutan escape
"~!
". Jika user menulis string
"~!command
" pada awal baris, maka perintah
akan berjalan. Program /usr/bin/suidperl
digunakan untuk
membuat script-script perl bekerja dengan bit Set-UID yang disebut
/bin/mail
untuk mengirimkan pesan ke root
ketika mendeteksi sebuah masalah.
Karena /bin/mail
ber Set-UID root, panggilan ke
/bin/mail
dilakukan dengan privileges root
dan mengandung nama dari file yang bermasalah.
Lalu user dapat membuat sebuah file yang namanya mengandung karakter carriage
return diikuti dengan urutan ~!command
dan carriage return yang lain.
Jika script perl itu memanggil suidperl
dan gagal pada masalah low-level yang berkaitan dengan file ini, sebuah pesan akan
terkirim melalui identitas root ,berisi urutan escape
dari aplikasi mail
, dan perintah pada nama file yang dijalankan dengan
privileges yang dipunyai root.
Masalah ini seharusnya tidak ada dikarenakan program mail
tidak mendukung untuk menerima urutan (escape sequences) ketika berjalan otomatis
(bukan dari terminal). Sayangnya, fitur yang tak tercatat dari
aplikasi ini (mungkin ketinggalan saat debugging), mengijinkan escape
sequences sesaat begitu lingkungan variabel interactive
di set.
Dan hasilnya? Sebuah lubang keamanan dengan mudahnya di exploitasi
(dan ter-exploitasi secara luas) didalam sebuah aplikasi yang seharusnya membuktikan
keamanan system . Dan kesalahan terbagi. Pertama,
/bin/mail
mempunyai opsi tak tercatat terutama menjadi berbahaya
saat mengijinkan eksekusi kode hanya memeriksa data yang terkirim,
yang seharusnya menjadi kecurigaan utama untuk sebuah
aplikasi mail. Kedua, biarpun jika pengembang /usr/bin/suidperl
tidak memperhatikan variabel interactive
,
mereka seharusnya tidak meninggalkan lingkungan eksekusi seperti saat memanggil
perintah external , terutama saat menulis program ber-Set-UID root ini.
Kenyataannya, Linux tidak memperdulikan bit Set-UID dan Set-GID
ketika menjalankan script-script (baca
/usr/src/linux/fs/binfmt_script.c
dan
/usr/src/linux/fs/exec.c
). Tetapi beberapa trik mneginjinkan Anda untuk mem- bypass
aturan ini, seperti Perl lakukan dengan script-nya sendiri menggunakan
/usr/bin/suidperl
untuk mengambil bit-bit tersebut ke account.
Tidak selamanya mudah untuk menemukan penggantian untuk fungsi
system()
. Variasi pertama adalah menggunakan
system-calls seperti execl()
atau execle()
.
Bagaimanapun, itu akan sedikit berbeda dikarenakan program external program tidak lagi
disebut sebagai sebuah sub rutin, selain perintah yang terlibat menggantikan
proses yang sedang terjadi. Anda mesti melakukan fork pada proses dan melewatkan
argumen pada baris perintah. Kemudian program :
menjadi :if (system ("/bin/lpr -Plisting stats.txt") != 0) { perror ("Printing"); return (-1); }
Biasanya, kode menjadi lebih berat! Dalam beberapa situasi, menjadi lumayan rumit, sebagi contoh, ketika Anda mesti mengubah arah (redirect) standar input aplikasi seperti pada :pid_t pid; int status; if ((pid = fork()) < 0) { perror("fork"); return (-1); } if (pid == 0) { /* child process */ execl ("/bin/lpr", "lpr", "-Plisting", "stats.txt", NULL); perror ("execl"); exit (-1); } /* father process */ waitpid (pid, & status, 0); if ((! WIFEXITED (status)) || (WEXITSTATUS (status) != 0)) { perror ("Printing"); return (-1); }
Begitulah, pengubahan arah ditentukan olehsystem ("mail root < stat.txt");
<
dikerjakan melalui
shell. Anda dapat melakukan hal yang sama, menggunakan urutan yang rumit
seperti pada fork()
, open()
,
dup2()
, execl()
, dll. Pada kasus tersebut, sebuah
solusi yang dapat diterima akan menggunakan fungsi system()
,
tetapi melakukan konfigurasi ke seluruh lingkungan (environment).
Pada Linux, variabel lingkungan disimpan pada form dari pointer ke tabel karakter :
char ** environ
. Tabel ini berakhir dengan NULL. String berada diluar dari form
"NAME=value
".
Kita mulai menghilangkan variabel Lingkungan menggunakan Gnu extension :
atau memaksakan pointerint clearenv (void);
untuk mengambil nilai NULL . Selanjutnya variabel-variabel lingkungan di inisialisasikan, menggunakan nilai terkontrol, dengan fungsi :extern char ** environ;
sebelum memanggil fungsiint setenv (const char * name, const char * value, int remove) int putenv(const char *string)
system()
. Sebagai
contoh :
Jika dibutuhkan, Anda bisa menyimpan isi dari ebberapa variabel yang berguna sebelum membuang lingkungan (clearenv (); setenv ("PATH", "/bin:/usr/bin:/usr/local/bin", 1); setenv ("IFS", " \t\n", 1); system ("mail root < /tmp/msg.txt");
HOME
,
LANG
, TERM
, TZ
,dll.). Isi
,form, ukuran dari variabel-variabel ini mesti diperiksa.
Sangatlah penting bahwa Anda membuang seluruh lingkungan sebelum mendefinisikan ulang variabel.
Lubang keamanan suidperl
tidak seharusnya muncul jika
environment telah dibuang dengan baik.
Analoginya, melindungi sebuah mesin dalam jaringan akan menolak seluruh koneksi. Selanjutnya, sysadmin mengaktifkan service yang dibutuhkan atau yang berguna . Dengan cara yang sama, ketika membuat aplikasi ber- Set-UID environment harus bersih baru kemudian diisi dengan variabel yang dibutuhkan.
Verifikasi format parameter dilakukan dengan membandingkan nilai yang diharapkan dengan format yang diizinkan. Jika proses perbandingan sukses maka parameter ter-validasi. Dengan kata lain, ditolak. Jika Anda menjalankan percobaan menggunakan daftar dari nilai-nilai ber-format invalid, resiko dari meninggalkan nilai yang salah akan meningkat dan ini bisa menjadi bencana bagi system.
Kita mesti memahami bahaya pada system()
adalah juga
bahaya untuk beberapa fungsi seperti popen()
, atau dengan system-calls seperti
execlp()
atau execvp()
diambil ke account
variabel PATH
.
Untuk meningkatkan kemampuan pakai dari program, mudah untuk memberikan user
kemampuan untuk mengkonfigurasikan sebagian besar kelakukan software menggunakan macro,
sebagai contoh. Untuk mengurusi variabel atau pola generic seperti yang dilakukan oleh shell
, terdapat fungsi yang hebat disebut wordexp()
.
Anda mesti berhati-hati dengan hal ini, karena mengirimkan string seperti
$(command)
mengizinkan eksekusi dari perintah external yang disebutkan.
Memberikan string "$(/bin/sh)
" membuat sebuah shell ber-Set-UID. Untuk menghindari
hal ini, wordexp()
mempunyai atribut yang disebut
WRDE_NOCMD
yang me-non-aktifkan interpretasi dari urutan $( )
.
Ketika melibatkan perintah external Anda mesti berhati-hati untuk tidak
memanggil utility yang menyediakan mekanismen escape ke shell
(seperti sequence vi :!command
).
Sangat susah untuk mendata semua utiliti tersebut, beberapa aplikasi mencurigakan
(text editors, file managers...) yang lain sulit untuk dideteksi
(seperti yang telah kita lihat /bin/mail
) atau mempunyai mode debugging berbahaya.
Artikel ini meng-ilustrasikan bermacam-macam aspek :
Artikel selanjutnya akan berbicara mengenai memory, organisasinya, dan pemanggilan fungsinya sebelum meraih buffer overflows. Kita juga akan melihat bagaimana membangun sebuah shellcode.
Halaman Web Dirawat oleh Team Editor LinuxFocus
© Frédéric Raynal, Christophe Blaess, Christophe Grenier "some rights reserved" see linuxfocus.org/license/ http://www.LinuxFocus.org |
Informasi Terjemahan:
|
2004-11-07, generated by lfparser version 2.51