हम विंडोज के लिए एक साधारण स्निफर लिखते हैं

इस लेख में, हम विंडोज के लिए एक सरल स्निफर बनाने पर गौर करेंगे।
कौन परवाह करता है, बिल्ली में आपका स्वागत है।

परिचय


उद्देश्य: एक प्रोग्राम लिखना है जो नेटवर्क ट्रैफ़िक (ईथरनेट, वाईफाई) पर कब्जा कर लेगा, जो आईपी पर प्रसारित होगा।
उपकरण: विज़ुअल स्टूडियो 2005 या उच्चतर।
यहाँ वर्णित दृष्टिकोण लेखक के लिए व्यक्तिगत रूप से संबंधित नहीं है और इसे कई वाणिज्यिक और साथ ही स्पष्ट रूप से मुफ्त कार्यक्रमों (हैलो, जीपीएल) में सफलतापूर्वक उपयोग किया जाता है।
यह कार्य मुख्य रूप से नेटवर्क प्रोग्रामिंग में शुरुआती लोगों के लिए है, जो सामान्य रूप से सॉकेट्स के क्षेत्र में कम से कम बुनियादी ज्ञान रखते हैं, और विशेष रूप से विंडोज़ सॉकेट्स। यहां मैं अक्सर अच्छी तरह से ज्ञात चीजें लिखूंगा, क्योंकि विषय क्षेत्र विशिष्ट है, अगर आप कुछ याद करते हैं, तो आपके सिर में गड़बड़ होगी।

मुझे आशा है कि आप रुचि लेंगे।

सिद्धांत (पढ़ने के लिए आवश्यक नहीं, लेकिन वांछनीय)


वर्तमान में, अधिकांश आधुनिक सूचना नेटवर्क टीसीपी / आईपी प्रोटोकॉल स्टैक की नींव पर आधारित हैं। प्रोटोकॉल स्टैक टीसीपी / आईपी (इंजी। ट्रांसमिशन कंट्रोल प्रोटोकॉल / इंटरनेट प्रोटोकॉल) - नेटवर्क में उपयोग किए जाने वाले विभिन्न स्तरों के नेटवर्क प्रोटोकॉल का सामूहिक नाम। इस आलेख में, हम मुख्य रूप से आईपी प्रोटोकॉल में रुचि लेंगे - एक पैकेट नेटवर्क प्रोटोकॉल जो तथाकथित पैकेटों द्वारा साझा किए गए डेटा की गैर-गारंटीकृत डिलीवरी के लिए उपयोग किया जाता है (एक अधिक सही शब्द एक डेटाग्राम है) एक नेटवर्क नोड से दूसरे में।
हमारे लिए विशेष रूप से रुचि रखने वाले आईपी पैकेट हैं जो सूचना प्रसारित करने के लिए डिज़ाइन किए गए हैं। यह OSI नेटवर्क डेटा मॉडल का एक उच्च स्तर है, जब आप केवल तार्किक प्रतिनिधित्व का उपयोग करके अपने आप को डिवाइस और डेटा ट्रांसमिशन माध्यम से अलग कर सकते हैं।
यह पूरी तरह से तर्कसंगत है कि नेटवर्क ट्रैफ़िक को अवरोधन, नियंत्रण, रिकॉर्ड और विश्लेषण करने के लिए जल्द या बाद में उपकरण दिखाई देने चाहिए। इस तरह के औजारों को आम तौर पर ट्रैफिक एनालाइजर, पैकेट एनालाइजर या स्निफर (अंग्रेजी से सूंघने - सूंघने के लिए) कहा जाता है। यह एक नेटवर्क ट्रैफ़िक एनालाइज़र, प्रोग्राम, या हार्डवेयर-सॉफ़्टवेयर डिवाइस है जिसे इंटरसेप्ट करने के लिए डिज़ाइन किया गया है और बाद में इसका विश्लेषण करते हैं, या केवल अन्य नोड्स के लिए नियत नेटवर्क ट्रैफ़िक का विश्लेषण करते हैं। [1]

अभ्यास (ठोस बातचीत)


फिलहाल, ट्रैफिक को सुनने के लिए बहुत सारे सॉफ्टवेयर बनाए गए हैं। उनमें से सबसे प्रसिद्ध: विरेचक । स्वाभाविक रूप से, लक्ष्य अपनी प्रशंसा को प्राप्त करने के लायक नहीं है - हम नेटवर्क इंटरफ़ेस के लिए "सुनने" की सामान्य विधि द्वारा यातायात को बाधित करने के कार्य में रुचि रखते हैं। यह समझना महत्वपूर्ण है कि हम किसी और के ट्रैफ़िक को हैक और इंटरसेप्ट नहीं करने जा रहे हैं। आपको बस हमारे मेजबान से गुजरने वाले ट्रैफ़िक को देखना और उसका विश्लेषण करना होगा।

इसकी आवश्यकता क्यों हो सकती है:
  1. नेटवर्क कनेक्शन (आवक / जावक / कुल) के माध्यम से वर्तमान ट्रैफ़िक प्रवाह देखें।
  2. दूसरे होस्ट को बाद के विश्लेषण के लिए पुनर्निर्देशित ट्रैफ़िक
  3. सैद्धांतिक रूप से, आप इसका उपयोग वाईफाई नेटवर्क में हैक करने के लिए कर सकते हैं (क्या हम ऐसा नहीं करने जा रहे हैं?)।

Wireshark के विपरीत, जो कि libpcap / WinPcap लाइब्रेरी पर आधारित है, हमारे विश्लेषक इस ड्राइवर का उपयोग नहीं करेंगे। पहले से ही क्या है, हमारे पास बिल्कुल भी ड्राइवर नहीं होगा, और हम अपना एनडीआईएस (ओह, हॉरर!) नहीं लिखने जा रहे हैं। आप इस विषय में इसके बारे में पढ़ सकते हैं। वह केवल विनसॉक लाइब्रेरी का उपयोग करते हुए एक निष्क्रिय पर्यवेक्षक होगा। इस मामले में ड्राइवर का उपयोग करना बेमानी है।

ऐसा कैसे? बहुत सरल है।
नेटवर्क विश्लेषक में एक साधारण नेटवर्क एप्लिकेशन को चालू करने में महत्वपूर्ण कदम नेटवर्क इंटरफ़ेस को सुविधाजनक मोड में बदलना है, जो इसे नेटवर्क पर अन्य इंटरफेस को संबोधित पैकेट प्राप्त करने की अनुमति देगा। यह मोड नेटवर्क कार्ड को सभी फ़्रेमों को स्वीकार करने के लिए मजबूर करता है, भले ही वे नेटवर्क पर संबोधित किए गए हों। [2]

विंडोज 2000 (NT 5.0) से शुरू होकर, नेटवर्क सेगमेंट पर सुनने का प्रोग्राम बनाना बहुत सरल हो गया है, क्योंकि इसका नेटवर्क ड्राइवर आपको सभी पैकेटों के लिए सॉकेट प्राप्त करने की अनुमति देता है।

प्रोमिसस मोड चालू करें

long flag = 1; SOCKET socket; #define SIO_RCVALL 0x98000001 ioctlsocket(socket, SIO_RCVALL, &RS_Flag); 

हमारा कार्यक्रम आईपी पैकेट के साथ संचालित होता है, और विंडोज सॉकेट संस्करण 2.2 लाइब्रेरी और कच्चे सॉकेट का उपयोग करता है। IP पैकेट तक सीधी पहुँच प्राप्त करने के लिए, सॉकेट को इस प्रकार बनाया जाना चाहिए:

रॉ सॉकेट बनाएं

 s = socket(AF_INET, SOCK_RAW, IPPROTO_IP); 

यहां, निरंतर SOCK_STREAM (TCP प्रोटोकॉल) या SOCK_DGRAM (UDP प्रोटोकॉल) के बजाय, हम SOCK_RAW मान का उपयोग करते हैं। आम तौर पर, कच्ची कुर्सियां ​​के साथ काम करना न केवल यातायात पर कब्जा करने के मामले में दिलचस्प है। वास्तव में, हम पैकेज के गठन पर पूरा नियंत्रण प्राप्त करते हैं। बल्कि, हम इसे मैन्युअल रूप से बनाते हैं, जो कि, उदाहरण के लिए, एक विशिष्ट ICMP पैकेट भेजने की अनुमति देता है ...

आगे बढ़ो। यह ज्ञात है कि एक आईपी पैकेट में हेडर, सेवा की जानकारी और वास्तव में, डेटा होता है। मैं आपको सलाह देता हूं कि ज्ञान को ताज़ा करने के लिए यहां देखें । आइए एक संरचना के रूप में आईपी हेडर का वर्णन करें (आरएसडीएन पर उत्कृष्ट लेख के लिए धन्यवाद ] [3] ):

आईपी ​​पैकेट संरचना विवरण

 typedef struct _IPHeader { unsigned char ver_len; //     unsigned char tos; //   unsigned short length; //    unsigned short id; // Id unsigned short flgs_offset; //    unsigned char ttl; //   unsigned char protocol; //  unsigned short xsum; //   unsigned long src; // IP-  unsigned long dest; // IP-  unsigned short *params; //  ( 320 ) unsigned char *data; //  ( 65535 ) }IPHeader; 

सुनने के एल्गोरिथ्म का मुख्य कार्य इस तरह दिखेगा:

एकल पैकेट कैप्चर फ़ंक्शन

 IPHeader* RS_Sniff() { IPHeader *hdr; int count = 0; count = recv(RS_SSocket, (char*)&RS_Buffer[0], sizeof(RS_Buffer), 0); if (count >= sizeof(IPHeader)) { hdr = (LPIPHeader)malloc(MAX_PACKET_SIZE); memcpy(hdr, RS_Buffer, MAX_PACKET_SIZE); RS_UpdateNetStat(count, hdr); return hdr; } else return 0; } 

यहां सब कुछ सरल है: हमें मानक recv सॉकेट फ़ंक्शन का उपयोग करके डेटा का एक हिस्सा मिलता है, और फिर इसे IPHeader प्रकार की संरचना में कॉपी किया जाता है।
और अंत में, हम अंतहीन पैकेट कैप्चर लूप शुरू करते हैं:

हमारे नेटवर्क इंटरफ़ेस पर आने वाले सभी पैकेटों को पकड़ना

 while (true) { IPHeader* hdr = RS_Sniff(); //  IP- if (hdr) { //     } } 

थोड़ा ऑफटॉपिक

यहां और नीचे, कुछ महत्वपूर्ण कार्यों और चर के लिए, लेखक ने उपसर्ग RS_ (रॉ सॉकेट्स से) बनाया। परियोजना 3-4 साल पहले की गई थी, और कच्चे सॉकेट्स के साथ काम करने के लिए एक पूर्ण पुस्तकालय लिखना एक पागल विचार था। जैसा कि अक्सर होता है, किसी भी महत्वपूर्ण (लेखक के लिए) परिणाम प्राप्त करने के बाद, उत्साह दूर हो गया, और मामला शैक्षिक उदाहरण से आगे नहीं बढ़ा।

सिद्धांत रूप में, आप आगे जा सकते हैं और उपरोक्त सभी प्रोटोकॉल के शीर्षकों का वर्णन कर सकते हैं। ऐसा करने के लिए, IPHeader संरचना में प्रोटोकॉल फ़ील्ड का विश्लेषण करें। कोड उदाहरण देखें (हां, एक स्विच होना चाहिए, लानत है!), जहां हेडर रंगीन है, जिसके आधार पर आईपी में पैकेट के किस प्रोटोकॉल पर निर्भर है:

 /* *    */ void ColorPacket(const IPHeader *h, const u_long haddr, const u_long whost = 0) { if (h->xsum) SetConsoleTextColor(0x17); //     else SetConsoleTextColor(0x07); //   if (haddr == h->src) { SetConsoleTextColor(BACKGROUND_BLUE | /*BACKGROUND_INTENSITY |*/ FOREGROUND_RED | FOREGROUND_INTENSITY); // ""    } else if (haddr == h->dest) { SetConsoleTextColor(BACKGROUND_BLUE | /*BACKGROUND_INTENSITY |*/ FOREGROUND_GREEN | FOREGROUND_INTENSITY); // ""    } if (h->protocol == PROT_ICMP || h->protocol == PROT_IGMP) { SetConsoleTextColor(0x70); // ICMP- } else if(h->protocol == PROT_IP || h->protocol == 115) { SetConsoleTextColor(0x4F); // IP-in-IP-, L2TP } else if(h->protocol == 53 || h->protocol == 56) { SetConsoleTextColor(0x4C); // TLS, IP with Encryption } if(whost == h->dest || whost == h->src) { SetConsoleTextColor(0x0A); } } 


हालाँकि, यह इस लेख के दायरे से काफी परे है। हमारे प्रशिक्षण उदाहरण के लिए, यह उन मेजबानों के आईपी पते को देखने के लिए पर्याप्त होगा जहां से ट्रैफ़िक चल रहा है और इसकी संख्या प्रति यूनिट की गणना करने के लिए (समाप्त कार्यक्रम लेख के अंत में संग्रह में है)।

आईपी ​​हेडर डेटा प्रदर्शित करने के लिए, स्ट्रिंग के डेटाग्राम के हेडर (लेकिन डेटा नहीं) को परिवर्तित करने के कार्य को लागू करना आवश्यक है। कार्यान्वयन के एक उदाहरण के रूप में, हम इस विकल्प की पेशकश कर सकते हैं:

IP हैडर को स्ट्रिंग में बदलें

 inline char* iph2str(IPHeader *iph) { const int BUF_SIZE = 1024; char *r = (char*)malloc(BUF_SIZE); memset((void*)r, 0, BUF_SIZE); sprintf(r, "ver=%d hlen=%d tos=%d len=%d id=%d flags=0x%X offset=%d ttl=%dms prot=%d crc=0x%X src=%s dest=%s", BYTE_H(iph->ver_len), BYTE_L(iph->ver_len)*4, iph->tos, ntohs(iph->length), ntohs(iph->id), IP_FLAGS(ntohs(iph->flgs_offset)), IP_OFFSET(ntohs(iph->flgs_offset)), iph->ttl, iph->protocol, ntohs(iph->xsum), nethost2str(iph->src), nethost2str(iph->dest) ); return r; } 

ऊपर दी गई बुनियादी जानकारी के आधार पर, हमें एक ऐसा छोटा कार्यक्रम (भयानक नाम ss, अंग्रेजी से संक्षिप्त। सरल स्निफर) मिलता है, जो आईपी ट्रैफ़िक के स्थानीय सुनने को लागू करता है। इसका इंटरफ़ेस नीचे चित्र में दिखाया गया है।



मैं स्रोत और बाइनरी कोड प्रदान करता हूं, जैसे कि यह कई साल पहले था। अब मैं उसे देखकर डर गया, और फिर भी, वह काफी पठनीय है (बेशक, आप इतने आत्मविश्वासी नहीं हो सकते)। यहां तक ​​कि विजुअल स्टूडियो एक्सप्रेस 2005 भी संकलन के लिए पर्याप्त होगा।

परिणामस्वरूप हमें क्या मिला:

आपका ध्यान के लिए धन्यवाद, मैं खब्रोवस्क नागरिकों और खब्रोव्स्क नागरिकों और सभी को मेरी क्रिसमस की बधाई देता हूं!

डाउनलोड प्रोजेक्ट ओपनिंग पासवर्ड: habr

अपडाउन : वेथू की सलाह पर, गिथब पर पोस्ट किया गया।

Source: https://habr.com/ru/post/In164901/


All Articles