Mendeteksi traceroute
dan ping
- Saat ini tidak
hanya server komersial dengan bandwith yang besar, namun user dengan koneksi
dial up telah menjadi sasaran penyerangan cracker's. Sebagai contoh winnuke.c
program yang telah banyak digunakan untuk menyerang komputer dengan sistem
operasi windows.
Kebanyakan distribusi
Linux telah membuat telnet/ftp/dll server melakukan logging setiap koneksi,
dengan begini mudah bagi kita untuk meletakkan host yang melakukan penyerangan
ke /etc/host.deny. Namun masih ada dua hal yang hilang, dan akan penulis
jelaskan disini secara mendetail.
1. Medeteksi
traceroutes
Traceroute merupakan
tool yang sangat berguna, dan biasa digunakan untuk mendeteksi dimana
keberadaan suatu komputer dan di network mana dia terhubung.Karena suatu alasan
anda tidak *bisa* dengan mudah membuat seseorang melakukan traceroute ke
komputer anda, jadi hal terbaik yang dapat kita lakukan adalah mendeteksi siapa
yang melakukan traceroute, dan buat dia sedikit bingung.
1.1 Bagaimana
traceroute bekerja ?
Secara mudah
treaceroute akan mengirim packet IP/UDP ke host tujuan. Untuk mengetahui lewat
mana packet dikirimkan tarceroute menggunakan field TTL (time to live) pada
header IP. TTL ini menunjukan batas berapa router yang dapat dilewati oleh
sebuah paket. Setiap router akan mengurangi dengan satu TTL pada sebuah paket
yang datang padanya, dan bila menjadi 0 maka router akan mengirim ICMP
TIME_EXCEED ke pemilik paket (host yang melakukan traceroute).
Jadi traceroute
bekerja dengan mengirimkan paket ke host tujuan dengan TTL yang bertambah
dengan satu (dimulai dengan 1). Jika host mengirim balik ICMP TIME_EXCEED traceroute
akan memberitahukan ke user alamat dari pengirim ICMP tersebut dan jeda waktu
dari saat pengiriman IP/UDP paket sampai diterimanya paket ICMP TIME_EXCEED.
Setelah ini traceroute kan mengirimkan lagi ke host tujuan dengan TTL += 1 (TTL
sekarang lebih besar 1 dari sebelumnya).
Traceroute kan terus
melakukan hal seperti diatas sampai diterima ICMP PORT_UNREACHABLE dari host
tujuan atau maksimum hop telah tercapai (default 30).
Untuk mengetahui
bagaimana treaceroute telah sampai ke host tujuan dan tidak lagi mengirimkan
paket, traceroute menggunakan protokol UDP. Paket UDP ini ditujukan ke port
yang tidak digunakan pada host tujuan (hampir semua implementasi pada Unix
menggunakan 33434+ TTL pada IP). Dan biasanya port 33434 keatas tidak digunakan
(normal) mak host tujuan akan mengirimkan ICMP PORT_UNREACHABLE dan ini
memberitahukan traceroute ia telah mencapai host tujuan dan berhenti
mengirimkan paket.
Untuk lebih jelasnya
lihat contoh berikut ini :
diumpamakan anda
adalah "source" dan host tujuan "target"
source:/root # traceroute target
traceroute to target (134.2.110.94), 30
hops max, 40 byte packets
Sekarang source
mengirim packer ke target dengan port tujuan 33434 dengan TTL 1. Paket melewati
"suatu host" dan router akan mengurangi nilai TTL. Karena TTL
sekarang 0 (expired) router akan mengirimkan ICMP TIME_EXCEED ke source. Dari
informasi yang dikirim traceoute akan mencetak data tentang host pertama yang
dilewati paket.
1
some_host (142.45.23.1) 2.456 ms
Kemudian paket lain
dikirimkan dengan TTL 2 dan port tujuan 33434+1 = 33435.
2
another_host (142.45.10.1) 3.983
ms
Paket ketiga dengan
TTL 3 alamat port 33436. Dan akhirnya traceroute menerima ICMP PORT_UNREACHABLE
dari "target":
3
target (142.45.10.13) 4.032 ms
Perlu diketahui bahwa
traceroute secara default akan mengirimkan tiga buah paket dengan nilai TTL sama dan port
berurutan (mis: 33434, 33435, 33436).
traceroute to localhost (127.0.0.1), 30 hops max, 40 byte packets
1
localhost (127.0.0.1) 0.856
ms 0.722 ms 0.689 ms
1.2 Strategi dari
traceroute-detector
Mengetahui bagaimana traceroute bekerja sangatlah
mudah untuk mendeteksi bila ada paket traceroute yang dikirim ke host kita.
Cukup dengan listen() pada port 33435 keatas dan lakukan sesuatu bila menerima
paket UDP. Anda bahkan bisa menebak berapa hop jauhnya host yang melakukan
traceroute dengan mengurangi port tsb dengan 33434 dan membaginya dengan 3.
Dengan mendengarkan
paket pada port tujuan traceroute, traceroute akan mendapatakan ICMP
TIME_EXCEED dan ICMP PORT_UNREACHABLE, dan traceroute akan timeout menunggu
replay dari host target. karena itu traceroute tidak akan mengetahui bahwa ia
telah mencapai tujuannya dan akan terus mengirimkan paket sampai maksimum hop
tercapai.
dengan program
pendeteksi traceroute listen()ing pada port 33434 - 33434*30*3 hasil pada
traceroute akan seperti:
RubiC:/root # traceroute localhost
traceroute to localhost (127.0.0.1), 30 hops
max, 40 byte packets
1 *
* *
2 *
* *
.
.
.
30 * * *
1.3 Masalah yang
mungkin timbul
Seseorang mungkin akan memilih base port
tidak pada defaultnya atau menggunakan teknik lain. Namun bila cuman user biasa
yang melakukan traceroute kemungkinan besar kita dapat mendeteksinya :) Bila
perlu anda dapat melakukan edit pada kernel
/usr/src/linux/net/ipv4/udp.c
tambahkan:
printk(KERN_INFO
"UDP: packet sent to unreachable port by %s !\n",
in_ntoa(daddr));
sebelum:
icmp_send(skb,ICMP_DEST_UNREACH,
ICMP_PORT_UNREACH, 0, dev);
ini akan mencatat
semua koneksi ke port UDP yang tidak dibuka.
1.4 Contoh
Implementasi
lihat dibawah ->
2. Mendeteksi pings
Ping biasa digunakan untuk
meng"crash" suatu host dengan mengirimkan oversize data. Meski bug
ini telah diperbaiki namun ping masih sering digunakan untuk memperlambat
koneksi seseorang dengan koneksi ke internet melalui dial up modem. Anda tidak
bisa mencegah seseorang untuk melakukan ping terhadapa anda (kecuali ISP anda
memfilter paket ICMP_ECHO ke host anda). Seperti halnya traceroute anda dapat
mendeteksi host yang melakukan ping, dan memutuskan untuk tidak mengirimkan
replay (alan mengurangi jumlah data yang lewa modem denganfaktor 2).
2.1 Bagaimana ping
bekerja dan orang melakukan flood ke suatu host ?
Ping mengirim paket ICMP_ECHO dan beberapa
data ke host tujuan, tujuan host akan me-replay dengan paket ICMP_ECHOREPLAY
dengan data yang dikirimkan kepadanya. Secara default ping akan menunggu 1
detik sebelum mengirim ICMP_ECHO selanjutnya. Pada beberapa implementasi anda
dapat menset priode ini dengan 0 dan melakukan "floodping" dan bila
data yang dikirim cukup besar dengan koneksi yang cepat (T1 atau Ethernet) dan
terget cuma dengan modem ini akan memperlambat host target atau mungkin halt.
2.2 Bagaimana kita
mendeteksi ping ?
Anda dapat mengextract data pada paket
ICMP_ECHO dan mencatat alamat pengirim paket dan mumutuskan anda akan me-replay
atau tidak. Untuk non-floodpings anda dapat mengurangi jumlah paket yang lewat
modem anda dengan memilih untuk tidak me-replay (jika seseorang melakukan flood
ini tidak akan banyak membantu karena jumlah data yang datang mungkin akan
menyebabkan lambatnya koneksi, kecuali yang melakukan flood dengan koneksi yang
lambat).
2.3 Contoh
implementasi
Anda
dapat mengedit file /usr/src/linux/net/ipv4/icmp.c dan cari bagian tentang
"handle ICMP_ECHO" jika anda bisa C anda dapat dengan mudah melihat
ada define "CONFIG_IP_IGNORE_ECHO_REQUESTS". dengan define ini kita
dapat mengabaikan semua ICMP_ECHO yang datang dan tidak mereplay-nya. Atau
tambahkan:
printk(KERN_INFO
"ICMP: pinged by %s, packetsize = %d \n",in_ntoa(saddr),
icmp_param.data_len);
sebelum #endif untuk
me-log alamat pengirim.
Reference
· Sorry for the credit, I rip this file
from my old computer, and I can found who's the writer, but anyway this good
start for newbie.
----------------------------------------------------------------------------
/*
Program ini berhasil dikompilasi pada
Linux 2.0.34 (Slackware)
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<errno.h>
#include
<string.h>
#include
<sys/types.h>
#include
<netinet/in.h>
#include
<sys/socket.h>
#include
<sys/wait.h>
#include
<sys/time.h>
#include
<sys/signal.h>
#include
<sys/syslog.h>
#include
<netdb.h>
#define MAXBUFLEN 200
#define MYPORT 33435
#define NUMPORTS 30*3
int sockfd[NUMPORTS];
void shutitdown()
{
int w;
char buf[50];
for (w=0; w<NUMPORTS; w++)
close(sockfd);
sprintf (buf,"DetectTraceroute
terminated\n");
syslog(LOG_NOTICE , buf);
exit(0);
}
char *getname (struct
in_addr addr)
{
struct hostent *h;
int w;
char foo[4];
int tmpint[4];
char tmpbuf[20];
sprintf(tmpbuf, "%s",
inet_ntoa(addr));
if (
sscanf(tmpbuf,"%d.%d.%d.%d", &tmpint[0], &tmpint[1],
&tmpint[2], &tmpint[3]) != 4) {
printf ("Error while detecting
hostname !\n");
exit(1);
}
for(w=0; w<4; w++) foo[w]=tmpint[w];
if ( (h=gethostbyaddr(foo, 4, AF_INET))
== NULL) {
herror("gethostbyaddr");
exit(1);
}
return
h->h_name;
}
main(int argc, char
*argv[])
{
int hops;
struct sockaddr_in my_addr;
struct sockaddr_in remote_addr;
int addr_len, numbytes;
char buf[MAXBUFLEN];
int w;
fd_set readfds;
if( fork() !=0 ) return(0);
signal(SIGHUP, SIG_IGN);
signal(SIGTERM, shutitdown);
for(w=0; w<NUMPORTS; w++) {
if ( (sockfd[w] = socket( AF_INET,
SOCK_DGRAM, 0)) == -1) {
perror("socket");
exit(1);
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons (MYPORT+w);
my_addr.sin_addr.s_addr =
htonl(INADDR_ANY);
bzero(& (my_addr.sin_zero), 8);
if ( bind (sockfd[w], (struct
sockaddr *)&my_addr, sizeof (struct sockaddr) ) == -1) {
perror("bind");
exit(1);
}
}
FD_ZERO(&readfds);
for(w=0; w<NUMPORTS; w++)
FD_SET(sockfd[w], &readfds);
sprintf (buf,"Deteksi Traceroute
dijalankan\n");
syslog(LOG_NOTICE , buf);
while(1) {
select(sockfd[NUMPORTS-1]+1,
&readfds, NULL, NULL, NULL);
for (w=0; w < NUMPORTS; w++) {
if (FD_ISSET(sockfd[w],
&readfds))
hops = w;
}
addr_len = sizeof(struct sockaddr);
if
((numbytes=recvfrom(sockfd[hops], buf, MAXBUFLEN, 0, (struct sockaddr
*)&remote_addr, &addr_len)) == -1) {
perror("recvfrom");
exit(1);
}
/* we use buf for misc stuff O:-) */
sprintf (buf,"TRACEROUTE dari
IP %s. Hostname: %s HOPS: %d",
inet_ntoa(remote_addr.sin_addr), getname(remote_addr.sin_addr), hops / 3 +1);
syslog(LOG_NOTICE , buf);
FD_ZERO(&readfds);
for(w=0; w<NUMPORTS; w++)
FD_SET(sockfd[w],
&readfds);
}
}
0 komentar:
Posting Komentar