
Setiap programmer pada dasarnya adalah seorang hacker. Setelah semua, awalnya peretasan disebut pencarian solusi yang terampil dan tidak jelas. Memahami pemrograman membantu Anda menemukan kerentanan, dan keterampilan deteksi kerentanan membantu Anda membuat program, sehingga banyak peretas melakukan keduanya sekaligus. Ada gerakan non-standar yang menarik baik dalam teknik untuk menulis program yang elegan dan teknik untuk menemukan titik lemah.
Di mana untuk memulai? Untuk menimpa memori menggunakan buffer overflows, mengakses server jarak jauh dan menyadap koneksi, Anda harus memprogram dalam C dan assembler, menggunakan kode shell dan register prosesor, berkenalan dengan interaksi jaringan dan enkripsi, dan banyak lagi.
Tidak peduli seberapa besar kita ingin percaya pada mukjizat, perangkat lunak dan jaringan komputer yang menjadi sandaran kehidupan sehari-hari kita memiliki kerentanan.
Dunia tanpa peretas adalah dunia tanpa rasa ingin tahu dan solusi inovatif. (John Erickson)
Penanggulangan
Ada katak seperti itu - listolaz yang mengerikan (Phyllobates terribilis). Kelenjar kulitnya mengandung racun terkuat. Cukup sentuh untuk mendapatkan keracunan fatal. Obat yang sangat kuat dijelaskan oleh fakta bahwa katak ini memakan jenis ular tertentu yang telah mengembangkan kekebalan terhadap racun. Lambat laun, racun katak menjadi semakin kuat. Sebagai hasil dari evolusi bersama seperti itu, pendaki daun yang mengerikan tidak memiliki musuh alami yang tersisa. Hal serupa terjadi pada peretas. Teknik yang mereka ciptakan sudah lama dikenal, sehingga kemunculan tindakan penanggulangan cukup alami. Sebagai tanggapan, peretas mencari cara untuk menghindari dan menghancurkan mekanisme pertahanan, yang mengarah pada penciptaan teknik pertahanan baru.
Siklus mencari tindakan dan penanggulangan ini sangat berguna. Virus dan worm menjadi penyebab berbagai masalah dan membawa kerugian besar bagi bisnis, tetapi pada saat yang sama mereka memaksa pengembang untuk mengambil tindakan balasan untuk menyelesaikan masalah yang muncul. Worms mereplikasi diri menggunakan kerentanan perangkat lunak berkualitas rendah. Kesalahan sering tidak diperhatikan selama bertahun-tahun, dan cacing yang relatif tidak berbahaya seperti CodeRed atau Sasser memaksa pengembang untuk memperbaikinya. Proses ini dapat dibandingkan dengan cacar air, yang lebih baik untuk sakit pada masa kanak-kanak, dan tidak pada usia dewasa, ketika hal itu dapat menyebabkan konsekuensi bencana. Jika cacing internet tidak menarik perhatian universal pada lubang keamanan, lubang ini akan tetap terbuka untuk serangan dengan tujuan yang jauh lebih berbahaya daripada reproduksi diri sederhana. Dengan cara ini, worm dan virus berkontribusi terhadap keamanan jangka panjang. Tetapi ada metode yang lebih aktif: teknik yang mencoba untuk membatalkan hasil serangan atau membuatnya sama sekali tidak mungkin. Konsep "penanggulangan" agak kabur, kata-kata ini dapat berarti sarana teknis keamanan, seperangkat aturan, program atau hanya administrator sistem yang penuh perhatian. Penanggulangan secara kondisional dibagi menjadi dua kelompok: mencoba mendeteksi serangan dan berusaha melindungi kerentanan.
Alat Deteksi Serangan 0x610
Langkah-langkah penanggulangan dari kelompok pertama menjadi upaya untuk memperhatikan intrusi dalam waktu dan entah bagaimana bereaksi terhadapnya. Proses pengenalan dapat diimplementasikan dengan cara apa pun - dari administrator membaca log sistem ke program yang menganalisis lalu lintas jaringan. Kadang-kadang reaksi terhadap invasi turun untuk memutuskan koneksi secara otomatis atau menutup proses, dan kadang-kadang administrator harus hati-hati mempelajari seluruh isi konsol.
Metode yang dikenal untuk mengeksploitasi kerentanan tidak berbahaya bagi administrator sistem seperti yang belum dia ketahui. Semakin cepat intrusi dapat dideteksi, semakin cepat pekerjaan akan dimulai dengan itu dan semakin besar kemungkinan akan dilokalisasi. Intrusi yang telah diabaikan selama berbulan-bulan adalah penyebab serius yang perlu diperhatikan.
Untuk mengenali intrusi, Anda perlu mengantisipasi apa yang akan dilakukan penyerang. Ini memberikan informasi tentang apa yang sebenarnya perlu dipantau. Detektor mencari pola serangan yang dikenal dalam log, paket jaringan, dan bahkan dalam memori program. Ketika intrusi terdeteksi, Anda dapat menghilangkan peretas akses ke mesin, memulihkan sistem file yang rusak menggunakan cadangan, dan mengidentifikasi dan memperbaiki lubang keamanan. Dengan kemampuan cadangan dan pemulihan yang tersedia saat ini, tindakan pencegahan yang mengurangi deteksi serangan cukup efektif.
Untuk seorang penyerang, deteksi berarti melawan semua yang dilakukannya. Tentu saja, tidak selalu mungkin untuk segera melihat serangan, oleh karena itu ada sejumlah skenario "ambil dan jalankan" di mana fakta deteksi tidak penting, tetapi bahkan dalam kasus ini lebih baik untuk tidak meninggalkan jejak. Kerahasiaan adalah salah satu kualitas peretas yang paling berharga. Mendapatkan akses ke shell perintah dengan hak administrator dengan mengeksploitasi kerentanan memungkinkan untuk melakukan apa saja pada sistem, dan jika Anda berhasil menghindari deteksi, tidak ada yang akan tahu tentang keberadaan Anda. Kombinasi permisif dengan tembus pandang inilah yang membuat peretas berbahaya. Mereka dapat dengan mudah mencegat kata sandi dan data di jaringan, menambahkan bookmark ke program untuk akses tidak sah berikutnya, dan menyerang node jaringan lainnya. Untuk tetap berada dalam bayang-bayang, peretas harus memahami metode pengakuan apa yang digunakan dalam kasus tertentu. Jika Anda tahu persis apa yang mereka cari, Anda dapat menghindari pola eksploitasi kerentanan tertentu atau menyamarkan tindakan Anda sebagai valid. Faktor pendorong untuk siklus evolusi gabungan alat deteksi dan teknik yang memungkinkan untuk tidak diperhatikan adalah ide-ide yang belum terpikir oleh pihak lain.
0x620 Daemon sistem
Namun, penanggulangan terhadap peretas dan penyelesaiannya sebaiknya didiskusikan menggunakan contoh praktis. Sekarang kami akan mempertimbangkan serangan pada program server yang menerima koneksi masuk. Pada sistem operasi mirip UNIX, daemon sistem cocok untuk kriteria ini. Daemon adalah program yang berjalan di latar belakang dan dengan cara tertentu dipisahkan dari terminal kontrol. Istilah ini diciptakan pada tahun 1960 oleh peretas dari Massachusetts Institute of Technology. Prototipe adalah makhluk mitos yang menyortir molekul dari eksperimen mental oleh fisikawan James Maxwell. Setan Maxwell memiliki kemampuan supernatural untuk dengan mudah melakukan tugas-tugas kompleks, melanggar hukum kedua termodinamika. Demikian pula, daemon sistem Linux tanpa lelah melakukan tugas-tugas seperti memberikan akses ke SSH dan memelihara log sistem. Nama-nama iblis biasanya diakhiri dengan d, yang menekankan sifatnya: misalnya, sshd atau syslogd.
Pengeditan kecil akan mengubah tinyweb.c dari bagian 0x427 menjadi kemiripan yang realistis dengan daemon sistem. Versi baru kode berisi fungsi daemon (), yang memunculkan proses latar belakang baru. Ini digunakan oleh banyak proses daemon sistem Linux. Ini adalah halaman yang didedikasikan untuknya dari direktori:
Referensi DAEMON (3) Linux Programmer DAEMON (3)
NAME
daemon - jalankan di latar belakang
Sintaksis
#include <unistd.h> int daemon(int nochdir, int noclose);
DESKRIPSI
Fungsi daemon () memutus program dari terminal kontrol dan mulai
dia di latar belakang sebagai daemon sistem.
Dengan argumen bukan nol, nochdir, fungsi daemon () mengubah direktori kerja saat ini.
di root ("/").
Dengan nullose, fungsi daemon () mengarahkan ulang utas
input standar, output standar, dan kesalahan di / dev / null.
NILAI KEMBALI
(Fungsi ini menghasilkan salinan proses, dan jika fork () berhasil
induk mengeksekusi _exit (0) sehingga kesalahan lebih lanjut hanya terlihat
proses anak.) Jika berhasil, mengembalikan nol. Pada kesalahan, fungsinya
daemon () mengembalikan -1 dan memberikan nomor kesalahan ke errno variabel global
dari perpustakaan fungsi fork (2) dan setsid (2).
Daemon sistem tidak memiliki terminal kontrol, sehingga kode untuk daemon tinywebd baru akan ditampilkan ke buku catatan. Setan biasanya dikendalikan oleh sinyal. Versi baru dari tinyweb harus dapat menerima sinyal penyelesaian untuk keluar dengan benar.
Ikhtisar Sinyal 0x621
Sinyal menyediakan komunikasi antar-proses di UNIX. Setelah sinyal diterima oleh suatu proses, sistem operasi menghentikan eksekusi untuk memanggil penangan sinyal. Setiap sinyal memiliki nomor sendiri dan penangannya sendiri. Misalnya, ketika Anda menekan kombinasi tombol Ctrl + C, sinyal interupsi dikirim, pawang yang menghentikan program yang terbuka pada terminal kontrol, bahkan jika itu telah memasuki loop tak terbatas.
Anda dapat membuat penangan sinyal Anda sendiri dan mendaftarkannya menggunakan fungsi sinyal (). Mari kita lihat kode di mana beberapa penangan terdaftar untuk beberapa sinyal, dan di bagian utama ada loop tak terbatas.
signal_example.c #include <stdio.h> #include <stdlib.h> #include <signal.h> /* signal.h * #define SIGHUP 1 * #define SIGINT 2 (Ctrl+C) * #define SIGQUIT 3 (Ctrl+\) * #define SIGILL 4 * #define SIGTRAP 5 * #define SIGABRT 6 * #define SIGBUS 7 * #define SIGFPE 8 * #define SIGKILL 9 * #define SIGUSR1 10 1 * #define SIGSEGV 11 * #define SIGUSR2 12 2 * #define SIGPIPE 13 , * #define SIGALRM 14 , alarm() * #define SIGTERM 15 ( kill) * #define SIGCHLD 17 * #define SIGCONT 18 , * #define SIGSTOP 19 ( ) * #define SIGTSTP 20 [] (Ctrl+Z) * #define SIGTTIN 21 * #define SIGTTOU 22 */ /* */ void signal_handler(int signal) { printf(, signal); if (signal == SIGTSTP) printf(); else if (signal == SIGQUIT) printf(); else if (signal == SIGUSR1) printf(); else if (signal == SIGUSR2) printf(); printf(); } void sigint_handler(int x) { printf(); exit(0); } int main() { /* Registering signal handlers */ signal(SIGQUIT, signal_handler); // signal_handler() signal(SIGTSTP, signal_handler); // signal(SIGUSR1, signal_handler); signal(SIGUSR2, signal_handler); signal(SIGINT, sigint_handler); // sigint_handler() SIGINT while(1) {} // }
Ketika program yang dikompilasi dijalankan, penangan sinyal terdaftar, dan kemudian program memasuki loop tanpa akhir. Namun, meskipun demikian, sinyal yang masuk akan mengganggu pelaksanaannya dan beralih ke penangan yang terdaftar. Berikut ini adalah contoh penerapan sinyal yang dapat diaktifkan dari terminal kontrol. Setelah fungsi signal_handler () selesai, kontrol kembali ke loop yang terputus, sedangkan fungsi sigint_handler () mengakhiri program.
reader@hacking:~/booksrc $ gcc -o signal_example signal_example.c reader@hacking:~/booksrc $ ./signal_example 20 SIGTSTP (Ctrl-Z) 3 SIGQUIT (Ctrl-\) Ctrl-C (SIGINT) Exiting. reader@hacking:~/booksrc $
Perintah kill memungkinkan Anda untuk mengirim seluruh rangkaian sinyal ke suatu proses. Secara default, ini mengirimkan sinyal penyelesaian (SIGTERM). Menambahkan opsi -l padanya menampilkan daftar semua sinyal yang mungkin. Mari kita lihat bagaimana program signal_example berjalan di terminal lain mengirimkan sinyal SIGUSR1 dan SIGUSR2.
reader@hacking:~/booksrc $ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX reader@hacking:~/booksrc $ ps a | grep signal_example 24491 pts/3 R+ 0:17 ./signal_example 24512 pts/1 S+ 0:00 grep signal_example reader@hacking:~/booksrc $ kill -10 24491 reader@hacking:~/booksrc $ kill -12 24491 reader@hacking:~/booksrc $ kill -9 24491 reader@hacking:~/booksrc $
Pada akhirnya, perintah kill -9 mengirimkan sinyal SIGKILL. Penangan sinyal tidak dapat diubah, sehingga perintah kill -9 selalu digunakan untuk mematikan proses. Program signal_example yang diluncurkan pada terminal lain menunjukkan bahwa sinyal dicegat dan prosesnya dihancurkan.
reader@hacking:~/booksrc $ ./signal_example 10 SIGUSR1 12 SIGUSR2 Killed reader@hacking:~/booksrc $
Sinyal itu sendiri sangat sederhana, tetapi interaksi antara proses dapat dengan cepat berubah menjadi jaringan dependensi yang kompleks. Untungnya, di daemon tinyweb kami, sinyal hanya digunakan untuk shutdown yang benar, dan semuanya diimplementasikan dengan sangat sederhana.
0x622 Tinyweb Daemon
Versi baru dari tinywebd adalah daemon sistem yang diluncurkan di latar belakang tanpa terminal kontrol. Data output ditulis ke buku catatan dengan cap waktu, dan program itu sendiri menunggu sinyal SIGTERM untuk menyelesaikan pekerjaan dengan benar.
Perubahan yang dilakukan pada dokumen asli tidak terlalu signifikan, tetapi mereka memungkinkan studi yang lebih realistis tentang proses eksploitasi kerentanan. Fragmen kode baru dicetak tebal.
tinywebd.c #include <sys/stat.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #include <signal.h> #include "hacking.h" #include "hacking-network.h" #define PORT 80 // , #define WEBROOT "./webroot" // - #define LOGFILE "/var/log/tinywebd.log" // int logfd, sockfd; // void handle_connection(int, struct sockaddr_in *, int); int get_file_size(int); // // void timestamp(int); // // void handle_shutdown(int signal) { timestamp(logfd); write(logfd, " .\n", 16); close(logfd); close(sockfd); exit(0); } int main(void) { int new_sockfd, yes=1; struct sockaddr_in host_addr, client_addr; // socklen_t sin_size; logfd = open(LOGFILE, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR); if(logfd == -1) fatal(" "); if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) fatal(" "); if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) fatal(" SO_REUSEADDR"); printf(" tiny web.\n"); if(daemon(1, 0) == -1) // fatal(" "); signal(SIGTERM, handle_shutdown); // handle_shutdown signal(SIGINT, handle_shutdown); // handle_shutdown timestamp(logfd); write(logfd, ".\n", 15); host_addr.sin_family = AF_INET; // host_addr.sin_port = htons(PORT); // , host_addr.sin_addr.s_addr = INADDR_ANY; // IP memset(&(host_addr.sin_zero), '\0', 8); // if (bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)) == -1) fatal(" "); if (listen(sockfd, 20) == -1) fatal(" "); while(1) { // accept sin_size = sizeof(struct sockaddr_in); new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size); if(new_sockfd == -1) fatal(" "); handle_connection(new_sockfd, &client_addr, logfd); } return 0; } void handle_connection(int sockfd, struct sockaddr_in *client_addr_ptr, int logfd) { unsigned char *ptr, request[500], resource[500], log_buffer[500]; int fd, length; length = recv_line(sockfd, request); sprintf(log_buffer, " %s:%d \"%s\"\t", inet_ntoa(client_addr_ptr->sin_addr), ntohs(client_addr_ptr->sin_port), request); ptr = strstr(request, " HTTP/"); // if(ptr == NULL) { // HTTP strcat(log_buffer, " HTTP!\n"); } else { *ptr = 0; // URL ptr = NULL; // ptr NULL ( // ) if(strncmp(request, "GET ", 4) == 0) // GET ptr = request+4; // ptr - URL if(strncmp(request, "HEAD ", 5) == 0) // HEAD ptr = request+5; // ptr - URL if(ptr == NULL) { // strcat(log_buffer, " !\n"); } else { // ptr, if (ptr[strlen(ptr) - 1] == '/') // , // '/', strcat(ptr, "index.html"); // 'index.html' strcpy(resource, WEBROOT); // resource // strcat(resource, ptr); // fd = open(resource, O_RDONLY, 0); // if(fd == -1) { // strcat(log_buffer, " 404 Not Found\n"); send_string(sockfd, "HTTP/1.0 404 NOT FOUND\r\n"); send_string(sockfd, "Server: Tiny webserver\r\n\r\n"); send_string(sockfd, "<html><head><title>404 Not Found</title> </head>"); send_string(sockfd, "<body><h1>URL not found</h1></body></html> \r\n"); } else { // strcat(log_buffer, " 200 OK\n"); send_string(sockfd, "HTTP/1.0 200 OK\r\n"); send_string(sockfd, "Server: Tiny webserver\r\n\r\n"); if(ptr == request + 4) { // GET if( (length = get_file_size(fd)) == -1) fatal(" "); if( (ptr = (unsigned char *) malloc(length)) == NULL) fatal(" "); read(fd, ptr, length); // send(sockfd, ptr, length, 0); // free(ptr); // } close(fd); // } // if / } // if } // if HTTP timestamp(logfd); length = strlen(log_buffer); write(logfd, log_buffer, length); // shutdown(sockfd, SHUT_RDWR); // } int get_file_size(int fd) { struct stat stat_struct; if(fstat(fd, &stat_struct) == -1) return -1; return (int) stat_struct.st_size; } void timestamp(fd) { time_t now; struct tm *time_struct; int length; char time_buffer[40]; time(&now); // time_struct = localtime((const time_t *)&now); // tm length = strftime(time_buffer, 40, "%m/%d/%Y %H:%M:%S> ", time_struct); write(fd, time_buffer, length); // }
Program ini menciptakan proses duplikat yang berjalan di latar belakang, menulis ke file log bersama dengan cap waktu, dan berakhir dengan benar setelah menerima sinyal yang sesuai. Deskriptor file log dan soket yang menerima koneksi dinyatakan sebagai variabel global sehingga fungsi handle_shutdown () dapat menyelesaikan pekerjaannya dengan benar. Ini didefinisikan sebagai penangan panggilan balik untuk sinyal penyelesaian dan interupsi, yang memastikan bahwa program diakhiri oleh perintah kill.
Ini adalah hasil kompilasi, eksekusi, dan penyelesaian program. Perhatikan cap waktu di log dan pesan penyelesaian yang muncul setelah program menerima sinyal yang sesuai dan disebut fungsi handle_shutdown ().
reader@hacking:~/booksrc $ gcc -o tinywebd tinywebd.c reader@hacking:~/booksrc $ sudo chown root ./tinywebd reader@hacking:~/booksrc $ sudo chmod u+s ./tinywebd reader@hacking:~/booksrc $ ./tinywebd tiny web. reader@hacking:~/booksrc $ ./webserver_id 127.0.0.1 The web server for 127.0.0.1 is Tiny webserver reader@hacking:~/booksrc $ ps ax | grep tinywebd 25058 ? Ss 0:00 ./tinywebd 25075 pts/3 R+ 0:00 grep tinywebd reader@hacking:~/booksrc $ kill 25058 reader@hacking:~/booksrc $ ps ax | grep tinywebd 25121 pts/3 R+ 0:00 grep tinywebd reader@hacking:~/booksrc $ cat /var/log/tinywebd.log cat: /var/log/tinywebd.log: Permission denied reader@hacking:~/booksrc $ sudo cat /var/log/tinywebd.log 07/22/2007 17:55:45> . 07/22/2007 17:57:00> 127.0.0.1:38127 "HEAD / HTTP/1.0" 200 OK 07/22/2007 17:57:21> . reader@hacking:~/booksrc $
Program tinywebd baru memproses konten HTTP, seperti tinyweb yang asli, tetapi berperilaku seperti daemon sistem karena tidak memiliki terminal kontrol dan hasilnya adalah file log. Kedua program rentan terhadap buffer overflow yang sama - tetapi ini hanyalah awal dari kerentanan ini. Sekarang kami telah memilih tinywebd sebagai target serangan, saya akan menunjukkan kepada Anda bagaimana menghindari deteksi setelah Anda memasuki mesin lain.
Β»Informasi lebih lanjut tentang buku ini dapat ditemukan di
situs web penerbitΒ»
IsiΒ»
KutipanDiskon 20% untuk kupon Habrozhitel -
Peretasan