Icmp protokoli. Icmp protokoli va sender(spoofer)




Download 31.1 Kb.
Sana26.04.2023
Hajmi31.1 Kb.
#54002
Bog'liq
13Word
qodir, siroj, Davlatimiz ramzlari, 1. Cho\'l haqida umumiy ma\'lumot Cho\'llarning shakllanishi va tar

ICMP protokoli.
ICMP protokoli va sender(spoofer)

Xammaga salom.
Ushbu maqola Nosirjon do'stimizning muammosini o'rganish davomida yozildi.
Bu maqola bundan 1 oycha oldin (balki undan xam ko'pdir) yozilgandi, chiqarishga joy topilmayotgandi ;)
Xullas, tog'risini aytsam yuqoridagi muammoni boshida umuman tushunmadim, sababi man usha payti icmp nima ekanligini taxminan bilardim :). manimcha forum a'zolarining ko'pchiligi mani holatimga tushgan bo'lsa kerak. ozgina o'rgandim, keyin o'zimgayam judayam qizib bo'lishni boshladi ushbu muammo.
keling terminlar nimaligini va nima uchun kerakligiga aniqlik kiritamiz.
ICMP — (ingl. Internet Control Message Protocol — tarmoqni boshqaruvchi xabarlar protokoli)
bu protokol asosan malumot uzatishdagi hatoliklar, istisnolar (masalan suralgan resurs topilmagani, host yoki marshrutizator javob bermayotgani) haqidagi xabarlarni uzatishda ishlatiladi. Ulardan tashqari icmp asosida ayrim hizmatlar xam mavjud. Endi bu wikidan olingan nazariya edi, amalyotga keladigan bo'lsak har kuni ishlatadigan (asosan adminlar) ping, traceroute va mtr larni kurishimiz mumkin. bilmaydiganlar ping — icmp protokoli yordamida «host» bn aloqani bor yuqligi va aloqaning «sifatini» tekshiruvchi utirilita. traceroute — «host» gacha bo'lgan routelarni va ular orasidagi ushlanish (zaderjka)ni tekshiruvchi utilitadir.
TTL — (ingl. Time to live) yani paketning yashash vaqti, bu IT sohasida judayam keng qo'llaniladi, bizni holatda tarmoq orqali uzatilgan habarlarni yashash vaqti, bu joyda vaqt deb aynan minut secund yoki microsecund qabul qilinmagan, balki oldindan berilgan hisoblagich (counter) asosida qilinadi, paket har belgilangan joyga borguncha nechta «host» (route)ga uchrasa har birida kamida TTL=TTL-1 buladi. masalan icmp paket A clientdan X hostga junatildi, ular orasida 20 ta router bor, agar TTL 15 quyilsa u belgilangan (X) joyga yetib bormaydi, balki maksimum 15 routerda tuxtab router A clientga junatilgan paketingni yashash vaqti tugadi (TE — time exceeded) degan habarni jo'natadi.
RTT — (round trip time) bu paket (xabar) junatilgandan qabul qilguncha oraliqdagi vaqt.
Spoofing — bu tarmoq atakalaridan bir turi bo'lib, havfsizlikni aldash uchun jo'natuvchi (src) manzilini o'zgartirib paket jo'natish (bog'lanish) tushuniladi. Albatta biz spoofingni ataka maqsadida emas, balki muammoni hal qilish maqsadida ishlatamiz.
Xullas terminlar bo'yicha manimcha yetarli. endi asosiy muammoga qaytsak.
masala quyidagicha:

Bizda ikkita host bor, A va B. oddiyroq tilda A — client, B — server. Ammo bu oddiy local tarmoqdan farqli ravishda client bilan server orasida bir nechta routerlar bulishi kerak. oddiy qilib aytganda client bitta providerga ulangan server esa boshqa providerda bulishi zarur. yani xech bo'lmaganda 1 ta router bulishi shart! Bizni holatda faqat 1 ta router bo'ldi :).

Client Serverga qarab TTL=10 bo'lgan birinchi ICMP paketni jo'natadi. Server uni qabul qilib olib kelgan vaqtini T1 deb belgilab quyadi. Client Serverga qarab TTL=1 bo'lgan ikkinchi ICMP paketni jo'natadi. Ammo spoofing qo'llagan holda jo'natish zarur. Bizda hisob kitob Serverda qilinayotganligi sababli, ICMP paket birinchi (va yagona) routerga yetib borganda TTL=0 bo'ladi va TE xabarni Serverga uzatish kerak. Shuning uchun biz ikkinchi paketda jo'natuvchi manzili tariqasida Serverni manzilini ko'rsatvorishimiz zarur.
Va nihoyot ikkinchi paketni javobi (TE) serverga yetib borganda, server qabul qilgan vaqtini T2 belgilab qo'yadida, RTT = T2-T1 qilib olinadi.

Manimcha masala etarlicha tushunarli qilib qo'yildi. Endi esa yechim :). Xa aytgande, masalani shartlaridan biri C/C++ da hal qilinishi zarur.

Eksperimentlar uchun 2 ta Debian OT bn mashina ajratildi. Development uchun xamma lib va utilitalar tayor deb hisoblaymiz, umuman olganda gcc/g++ o'rnatilsa bo'ldi :)
Manimcha clientdan boshlaymiz :)

— 2-maqola — Xullas maqola yozish unchalik o'xshamadi, shuning uchun yozgan kodimni tog'ridan to'g'ri qo'ydim, albatta orasida commentlari bilan.

Dastur tuzilishi jarayonida ayrim qismlari internetdagi tayyor examplelardan olindi, shuning uchun ayrim joylari o'zimgayam ozgina mavhum :).

Ushbu kod client dasturi uchun, yani 2 ta paket serverga jo'natadi, 1 chisi serverga yetib borishi uchun TTL katta, ikkinchisi yo'ldagi 1 chi routerda icmp TE xabar chiqarishi uchun TTL=1 qilingan, va source addressga server addressi qo'yilsa shu 1 chi router TE paketni clientga qaytarmasdan, balki serverga jo'natadi (yani serverni client deb o'ylaydi).



Buni tekshirish uchun serverda tcpdump icmp ni ishga tushurib keyin clientda ./client qilib jo'natilsa shunda, serverga 2 ta paket boradi. 1 chisi client ipsi (agar client nat orqasida bo'lsa nat ip bn boradi) bilan icmp echo, ikkinchisi icmp te serverni o'zini ipsidan boradi.


/* created by geniuz */
#include
#include
#include
#include
#include
#include
typedef unsigned short int u16;
typedef unsigned int u32;
unsigned short in_cksum(unsigned short *ptr, int nbytes);
int send_icmp(unsigned long daddr, unsigned long saddr, u32 t_tl);
void help(const char *p);
unsigned long sent = 0;
//dastur 2 ta argument oladi, 1 chisi source address, 2 chisi destination address!
int main(int argc, char **argv)
{
if (argc < 3) {
help(argv[0]);
exit(0);
}
//destination addressni arg dan olamiz
unsigned long daddr;
daddr = inet_addr(argv[2]);
//source addressni arg dan olamiz
unsigned long saddr;
saddr = inet_addr(argv[1]);
//birinchi paketni serverga yetib borishi uchun TTL=255 bn jo'natamiz
send_icmp(daddr, saddr, 255);
//ikkinchi paketni serverga yetib bormasdan birinchi routerda qolib ketishi uchun ttl=1 qilib jo'natamiz
send_icmp(daddr, daddr, 1);
return (0);
}
//icmp paket jo'natuvchi function, params: daddr - destination address, saddr - source address, va t_tl - ttl
int send_icmp(unsigned long daddr, unsigned long saddr, u32 t_tl){
u32 payload_size(0);
//tcp da socket ochamiz
int sockfd = socket (AF_INET, SOCK_RAW, IPPROTO_TCP);
if (sockfd < 0) {
perror("socket");
//o'xshamasa xato ;)
return (0);
}
int on = 1;
//ochilgan socketga optionlarni beramiz
if (setsockopt (sockfd, IPPROTO_IP, IP_HDRINCL, (const char*)&on, sizeof (on)) == -1) {
perror("setsockopt");
return (0);
}
if (setsockopt (sockfd, SOL_SOCKET, SO_BROADCAST, (const char*)&on, sizeof (on)) == -1) {
perror("setsockopt");
return (0);
}
//paket hajmi
int packet_size = (sizeof (struct iphdr) + sizeof (struct icmphdr) + payload_size) * sizeof (char);
char *packet = (char *) malloc (packet_size);
if (!packet) {
perror("setsockopt");
close(sockfd);
return (0);
}
//paketni yaratishni boshlaymiz, ip paket
struct iphdr *ip = (struct iphdr *) packet;
//icmp paket
struct icmphdr *icmp = (struct icmphdr *) (packet + sizeof (struct iphdr));
memset (packet, 0, packet_size);
//ip paket qiymatlarini quyamiz
ip->version = 4;
ip->ihl = 5;
ip->tot_len = htons (packet_size);
ip->id = rand ();
ip->ttl = t_tl;
ip->protocol = IPPROTO_ICMP;
ip->saddr = saddr;
ip->daddr = daddr;
ip->check = in_cksum ((u16 *) ip, sizeof (struct iphdr));
//icmp paket qiymatlari
icmp->type = ICMP_ECHO;
icmp->un.echo.sequence = rand();
icmp->un.echo.id = rand();
icmp->checksum = in_cksum((u16 *)icmp, sizeof(struct icmphdr));
//serverni aniqlashtirib olamiz
sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = daddr;
memset(&servaddr.sin_zero, 0, sizeof (servaddr.sin_zero));
memset(packet + sizeof(struct iphdr) + sizeof(struct icmphdr), rand() % 255, payload_size);
//paket ketti :)
if (sendto(sockfd, packet, packet_size, 0, (const sockaddr*) &servaddr, sizeof (servaddr)) == -1) {
perror("send");
printf("(%d packets have been sent)\n", sent);
}
free(packet);
close(sockfd);
return (0);
}
//checksumm, paket summasini togriligini tekshiramiz
unsigned short in_cksum(unsigned short *ptr, int nbytes)
{
register long sum;
u_short oddbyte;
register u_short answer;
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
*((u_char *) & oddbyte) = *(u_char *) ptr;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
void help(const char *p)
{
printf(" foydalanish: %s \n", p);
}
Download 31.1 Kb.




Download 31.1 Kb.

Bosh sahifa
Aloqalar

    Bosh sahifa



Icmp protokoli. Icmp protokoli va sender(spoofer)

Download 31.1 Kb.