Trang 1 trên tổng số 2 12 Cuối cùngCuối cùng
Từ 1 tới 10 trên tổng số 13 kết quả

Đề tài: Hướng dẫn viết một chương trình Sniffer

  1. #1
    Ngày gia nhập
    01 2007
    Nơi ở
    Somewhere I belong
    Bài viết
    168

    Mặc định Hướng dẫn viết một chương trình Sniffer

    Bài này mình hướng dẫn các bạn viết một sniffer (nghe lén) packet đơn giản trên Windows. Để lập trình được thì cần các bạn hiểu rõ cách lập trình socket trong ngôn ngữ C.
    Với cách lập trình socket thông thường chúng ta sử dụng SOCK_STREAM, SOCK_DGRAM tức lập trình ở mức Application của mạng mà thôi, để lập trình ở mức IP (tức tầng Network trong 4 tầng của Internet: Tầng vật lý --> Tầng Ip--> Tầng TCP --> Tầng ứng dụng) sử dụng SOCK_RAW là một dạng socket "thô"
    Điều đầu tiên bao giờ chúng ta cũng phải khởi tạo thư viện Winsocket
    Hàm khởi tạo thư viện như sau:
    Code:
    void InitWinSock()
     {
     	WSADATA wsaData;
     	if (WSAStartup(MAKEWORD(1,1),&wsaData)!=0) return;
     }
    Chi tiết hàm WSAStartup có thể xem trợ giúp của MSDN ...

    Cách tạo một Raw Socket như sau:
    Code:
    int	CreateRawSocket()
     {
     	int	sock;
     	if ((sock=WSASocket(AF_INET,SOCK_RAW,0,NULL,NULL,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) return 0;
     	return sock;
     }
    Hàm trên trả về một sock mới nếu như không gặp lỗi

    Như chúng ta đã biết mô hình mạng Internet được phân chia thành 4 tầng (Tầng vật lý <--> Tầng Ip<--> Tầng TCP <--> Tầng ứng dụng) tương ứng với 7 tầng của mô hình OSI (Tầng vật lý <--> Tầng liên kết <--> Tầng mạng <--> Tầng vận chuyển <--> Tầng phiên <---> Tầng trình diễn <--> Tầng ứng dụng). Mình khỏi phải nhắc lại mô hình OSI như thế nào vì có rất nhiều bài viết trong diễn đàn đã nói đến OSI
    Giới thiệu cấu trúc của gói IP, TCP, ICMP
    a. Gói IP (ở tầng IP)
    Định nghĩa một struct mô tả gói IP
    Code:
    struct ip_hdr{
     	unsigned	char	ver_ihl;	//<-- Version (4 bits) + Internet Header Length (4 bits)
     	unsigned	char	tos;	//<-- Type Of Service
     	unsigned short	tol_len	//<-- Total Length (Ip Header + TCP Header + Data)
     	unsigned	short	id	//<-- Identification
     	unsigned	short	offset	//<-- Frame Offset trong đó 8 bits cho flags
     	unsigned	char	ttl	//<-- Time to Live
     	unsigned char	protocol	//<-- Protocol
     	unsigned short	checksum//<-- Header Checksum
     	unsigned int	saddr	//<-- Source Address
     	unsigned	int	daddr	//<-- Destination Address
     };
    b. Gói TCP
    Định nghĩa một struct mô tả gói TCP
    Code:
    struct tcp_hdr{
     	unsigned	short	sport	//<-- Source Port
     	unsigned short	dport	//<-- Destiantion Port
     	unsigned int	seq_num	//<-- Sequence Number
     	unsigned	int	ack_num	//<-- Acknowledgment Number
     	unsigned char	dataoffset//<--Data Offset
     	unsigned char	flags	//Flags: SYN, ACK, FIN, RST, PUSH, URG (2 bits) + 6 bits Reserve
     	unsigned short	window	//Windows
     	unsigned short	checksum //Checksum
     	unsigned short	urgpointer //Urgent Pointer
     }
    c. Gói ICMP
    Định nghĩa một struct mô tả gói ICMP
    Code:
    struct icmp_hdr{
     	unsigned char	type	//Type
     	unsigned char	code	//Code
     	unsigned short	checksum
     	unsigned short	id	//Identification
     	unsigned short	sequence
     	unsigned short	timestamp
     }
    Ở trên là toàn bộ định nghĩa về các gói IP, ICMP, TCP. Trong bài này mình chỉ hướng dẫn bắt các gói TCP và ICMP mà thôi, còn các gói khác thì có thể làm tương tự
    Code:
    #include <winsock2.h>
     #include <stdio.h>
     #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
     #pragma comment (lib,"ws2_32.lib")
     void	InitWinSock();
     int		CreateRawSocket();
     int		Sniffer(int	sock);
     int		packetcapture(char *packet);
     int		tcp_display(struct ip_hdr	*ip,struct tcp_hdr *tcp);
     int		icmp_display(struct ip_hdr *ip,struct icmp_hdr *icmp);
     struct ip_hdr
     {
     	unsigned char	ver_ihl;//VER va IHL (Internet Header Length)
     	unsigned char	tos;	//Type of Server
     	unsigned short	tol_len;//Total Length=IpHeader + TCP Header + Data
     	unsigned short	id;		//Identification
     	unsigned short	offset;	//Frame offset
     	unsigned char	ttl;	//Time To Live
     	unsigned char	protocol;
     	unsigned short	checksum;
     	unsigned int	saddr;	//Source Address
     	unsigned int	daddr;	//Destination Address
     };
     
     struct tcp_hdr
     {
     	unsigned short	sport;	//Source Port
     	unsigned short	dport;	//Detinations Port	
     	unsigned int	seqnum;	//Sequence;
     	unsigned int	acknum;	//Acknowlege
     	unsigned char	dataoffset;	//Data Offset
     	unsigned char	flags;	//SYN, URG, FIN, ACK, RST, PUSH + Preserve
     	unsigned short  windows;
     	unsigned short	checksum;
     	unsigned short	urgpointer;
     };
     struct icmp_hdr
     {
     	unsigned char	type;
     	unsigned char	code;
     	unsigned short	checksum;
     	unsigned short	id;
     	unsigned short	sequence;
     	unsigned short	timestamp;
     };
     int	socksniffer;
     int	main()
     {
     	InitWinSock();
     	socksniffer=CreateRawSocket();
     	printf("Seamoun (http://nhomvicki.net)\n");
     	printf("Sniffer TCP, ICMP v1.0\n\n");
     	printf("          Packet Capture ...\n");
     	Sniffer(socksniffer);
     	return 0;
     }
     //Ham khoi tao thu vien WinSock
     void InitWinSock()
     {
     	WSADATA wsaData;
     	if (WSAStartup(MAKEWORD(1,1),&wsaData)!=0) return;
     }
     //Ham tao RawSocket
     int	CreateRawSocket()
     {
     	int	sock;
     	if ((sock=WSASocket(AF_INET,SOCK_RAW,0,NULL,NULL,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET) return 0;
     	return sock;
     }
     //Ham thuc hien Sniffer
     int	Sniffer(int sock)
     {
     	DWORD dwBufferLen[10], dwBufferInLen = 1, dwBytesReturned = 0;
     
     	char *HostName=new char [32];
     	unsigned long	nSize=32;
     	struct	hostent	*hp;
     	sockaddr_in	from,dest;
     	int	sread,fromlen=sizeof(from);
     	
     	char *packet=new char [2048];
     	if (GetComputerName(HostName,&nSize)==0) return -1;
     	if ((hp=gethostbyname(HostName))==0) return -1;
     	delete(HostName);
     	
     	int	i=0;
     	while ((hp->h_addr_list[i+1])!=NULL)
     	{
     		i++;
     	}
     	memcpy(&from.sin_addr.s_addr,hp->h_addr_list[i],hp->h_length);
     	if ((hp=gethostbyname(inet_ntoa(from.sin_addr)))==NULL) return -1;
     
     	memset(&dest,0,sizeof(dest));
     	memcpy(&dest.sin_addr.s_addr,hp->h_addr_list[0],hp->h_length);
     	dest.sin_family=AF_INET;
     	dest.sin_port=htons(8000);
     	if (bind(sock,(struct sockaddr *)&dest,sizeof(dest))==SOCKET_ERROR) return -1;
     	
     	//WSAIoctl : dieu khien vao ra socket
     	if(WSAIoctl(sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL) == SOCKET_ERROR)		return(-1);
     	
     	//Don nhan va su ly goi du lieu
     	while (1)
     	{
     		sread=recvfrom(sock,packet,8191,0,(struct sockaddr *)&from.sin_addr,&fromlen);
     		if ((sread==SOCKET_ERROR)||sread<0) continue ;
     		packetcapture(packet);
     	}
     	delete(packet);
     
     	return 0;
     }
     //Ham thuc hien phan tich goi du lieu
     int	packetcapture(char *packet)
     {
     	struct ip_hdr	*ip;
     	struct tcp_hdr	*tcp;
     	struct icmp_hdr	*icmp;
     	ip=(struct ip_hdr *)packet;
     	tcp=(struct tcp_hdr *)(packet+sizeof(struct ip_hdr));
     	icmp=(struct icmp_hdr *)(packet+sizeof(struct ip_hdr));
     	switch(ip->protocol)
     	{
     	case 6:
     		tcp_display(ip,tcp);
     		break;
     	case 1:
     		icmp_display(ip,icmp);
     		break;
     	default:
     		break;
     	}
     	return 0;
     }
     //Ham hien thi goi TCP
     int	tcp_display(ip_hdr *ip,tcp_hdr *tcp)
     {
     	printf("TCP: [%d] %s:%d", ntohs(ip->tol_len), inet_ntoa(*(struct in_addr *)&ip->saddr), ntohs(tcp->sport));
     	printf(" > %s:%d|ttl = %d|win = %d|checksum = %d|flag = %d\n\n", inet_ntoa(*(struct in_addr *)&ip->daddr), 
     	ntohs(tcp->dport), ip->ttl, ntohs(tcp->windows), tcp->checksum, tcp->flags);
     	return 0;
     }
     //Ham hien thi goi ICMP
     int icmp_display(struct ip_hdr *ip, struct icmp_hdr *icmp)
     {  	
     
     	printf("ICMP: [%d] %s", ntohs(ip->tol_len), inet_ntoa(*(struct in_addr *)&ip->saddr));
     	printf(" > %s type = %d|code = %d|ttl = %d|seq = %x\n", inet_ntoa(*(struct in_addr *)&ip->daddr), icmp->type, icmp->code, ip->ttl, ntohs(icmp->sequence));
     	return 0;
     }
    Kết quả khi chạy chương trình
    + Thực hiện gửi gói ICMP bằng cách dùng lệnh PING
    Code:
    C:\>ping 10.0.0.2
     Reply from 10.0.0.2: bytes=32 time<10ms TTL=64
     Reply from 10.0.0.2: bytes=32 time=15ms TTL=64
     Reply from 10.0.0.2: bytes=32 time=15ms TTL=64
     Reply from 10.0.0.2: bytes=32 time=15ms TTL=64
     
     Ping statistics for 10.0.0.2:
         Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
     Approximate round trip times in milli-seconds:
         Minimum = 0ms, Maximum =  15ms, Average =  11ms
     
     Chương trình Sniffer:
     Seamoun (http://nhomvicki.net)
     Sniffer TCP, ICMP v1.0
     
               Packet Capture ...
     ICMP: [60] 10.0.0.1 > 10.0.0.2 type = 8|code = 0|ttl = 128|seq = 3d00
     ICMP: [60] 10.0.0.2 > 10.0.0.1 type = 0|code = 0|ttl = 64|seq = 3d00
     ICMP: [60] 10.0.0.1 > 10.0.0.2 type = 8|code = 0|ttl = 128|seq = 3e00
     ICMP: [60] 10.0.0.2 > 10.0.0.1 type = 0|code = 0|ttl = 64|seq = 3e00
     ICMP: [60] 10.0.0.1 > 10.0.0.2 type = 8|code = 0|ttl = 128|seq = 3f00
     ICMP: [60] 10.0.0.2 > 10.0.0.1 type = 0|code = 0|ttl = 64|seq = 3f00
     ICMP: [60] 10.0.0.1 > 10.0.0.2 type = 8|code = 0|ttl = 128|seq = 4000
     ICMP: [60] 10.0.0.2 > 10.0.0.1 type = 0|code = 0|ttl = 64|seq = 4000
    +Thực hiện gửi gói TCP bằng netcat (Ai chưa có netcat vào đây down )
    Code:
    C:\>nx -vv -n 10.0.0.1
     
     Chương trình Sniffer:
     Seamoun (http://nhomvicki.net)
     Sniffer TCP, ICMP v1.0
     
               Packet Capture ...
     TCP: [64] 10.0.0.1:80 > 10.0.0.2:1033|ttl = 128|win = 64240|checksum = 55340|flag = 18
     TCP: [60] 10.0.0.2:1033 > 10.0.0.1:80|ttl = 64|win = 5840|checksum = 5942|flag = 2
     TCP: [52] 10.0.0.2:1033 > 10.0.0.1:80|ttl = 64|win = 5840|checksum = 23589|flag = 16
    Bài này mình sưu tầm bên HVA
    Đã được chỉnh sửa lần cuối bởi iamvtn : 13-07-2007 lúc 11:15 PM.
    In code we trust

  2. #2
    Ngày gia nhập
    01 2008
    Bài viết
    3

    cho hỏi nếu muốn Sniff được thông tin dưới dạng Text thì làm thế nào? ví dụ một máy trên mạng truyền thông tin qua mail là "ngày mai nghỉ học" thì dùng C# để lập trình và sniff được thông tin là "ngày mai nghỉ học",...

  3. #3
    Ngày gia nhập
    07 2006
    Nơi ở
    Hà nội
    Bài viết
    204

    Muốn bắt được gói tin ở máy khác gửi đi thì gói tin đó phải đi qua máy mình đã
    Life:\> dir

  4. #4
    Ngày gia nhập
    01 2008
    Bài viết
    3

    cho hỏi tiếp, Thế làm thế nào để bắt gói tin đó lại máy mình? đó Có thể cho tài liệu hoặc đoạn code tham khảo không?

  5. #5
    Ngày gia nhập
    01 2008
    Bài viết
    11

    vấn đề này lại liên quan đến network. Hoặc mạng dùng hub như ngày xưa thì các gói tin được truyền đến tất cả các máy trong cùng mạng. Nếu là switch thì phải cấu hình cho switch nó forward gói tin về máy mình thì mình mới nhận được. Một cách khác là alias, giả dạng MAC address của máy đích để switch nó tưởng máy mình là địa chỉ đích thì nó gửi gói tin về cho máy mình, rồi sau đó mình lại lặng lẽ forward gói tin đó đi tiếp. Cách khác nữa là dùng 1 agent để ở trạm cuối để khi nó nhận được gói tin nó nó forward ngược về cho mình.

  6. #6
    Ngày gia nhập
    07 2006
    Nơi ở
    Hà nội
    Bài viết
    204

    Mặc định Hướng dẫn viết một chương trình Sniffer

    Những cái vấn đề về mạng thế này lằng nhằng lắm, nói thì như vậy nhưng mà cụ thể ra thì cũng ít người biết, bạn phải tìm 1 cao thủ mà hỏi tận nơi mới được, hoặc là sang bên hvaonline.net ấy, chứ bên này chắc chả ai biết được tường tận !
    Life:\> dir

  7. #7
    Ngày gia nhập
    01 2008
    Bài viết
    3

    "vấn đề này lại liên quan đến network. Hoặc mạng dùng hub như ngày xưa thì các gói tin được truyền đến tất cả các máy trong cùng mạng. Nếu là switch thì phải cấu hình cho switch nó forward gói tin về máy mình thì mình mới nhận được. Một cách khác là alias, giả dạng MAC address của máy đích để switch nó tưởng máy mình là địa chỉ đích thì nó gửi gói tin về cho máy mình, rồi sau đó mình lại lặng lẽ forward gói tin đó đi tiếp. Cách khác nữa là dùng 1 agent để ở trạm cuối để khi nó nhận được gói tin nó nó forward ngược về cho mình."
    -------------------------
    Tôi cũng đã từng nghe nói như trên nhưng chưa biết làm như thế nào, Bác nào có biết thì chỉ dùm với. có thể cho tài liệu hoặc cho đoạn code thì rất cảm ơn. Đề tài luận văn mà chưa biết phải làm thế nào.

  8. #8
    Ngày gia nhập
    01 2008
    Bài viết
    11

    Mình ko rành lập trình C trên windows. Có thể tham khảo ở đây thử xem:
    http://www.planet-source-code.com/vb...=4952&lngWId=3
    Về vấn để capture packet thì để làm được, tất nhiên packet phải đi qua card mạng của máy muốn capture. Để làm đề tài này bạn nên bắt đầu ở mức đơn giản: cho 2 máy tính nối mạng qua 1 cái hub 10Mbps rồi viết chương trình để listen các packet đi ngang qua, sau đó giải mã để lấy được thông tin mình cần. Thông tin có thể là text, image, audio ... tùy theo transmission protocol. cho nên việc hiểu protocol để giải mã ngược lại thành thông tin có thể "thấy" được là một điều quan trọng và cần thiết.
    Các vấn đề còn lại thì chỉ cần hỏi một vài hacker bình thường chuyên về network là sẽ được chỉ rõ ràng, ko có gì khó cả.

  9. #9
    Ngày gia nhập
    11 2007
    Bài viết
    153

    Hơ theo mình nghĩ thì là thế này, nếu bạn muốn viết 1 chương trình sniffer thì bạn nên tìm hiểu hub và switch trước đi đã nhé.Còn cách thức thì đại khái thế này: với hub thì tương đối đơn giản, khi thông tin đi từ hub tới máy đích thì nó sẽ mã hóa thông tin và máy đích cũng sẽ mã hóa thông tin sao cho 2 mã hóa này trùng nhau, chỉ những mã hóa thông tin trùng nhau máy đích mới nhận và khi gửi thông tin đi thì ví dụ có 3 máy kết nối với nhau qua hub thì hub sẽ send gói packet đó cho tất cả các máy và máy nào có cùng mã với hub tức máy đích mới nhận gói tin đó còn các máy khác sẽ từ chối không nhận gói tin đó.Chúng ta sẽ có 1 hàm trong socket để sửa lại việc máy của ta sẽ tiếp nhận tất cả các gói tin không mang số id của nó.
    Còn với switch thì nó sẽ send trực tiếp gói packet đó đến máy đích chứ không send cho tất cả các máy như hub,vì nó ta sẽ phải tấn công gây tràn bộ nhớ đệm của nó, và khi đó thì nó sẽ điên lên và không kiểm soát được, lúc này nó sẽ gửi packet tới tất cả các máy, và như vậy nó đã làm việc như 1 hub.Việc còn lại chỉ là làm y chang với hub mà thôi.

    Have fun!!
    ttecak ?

  10. #10
    Ngày gia nhập
    12 2008
    Bài viết
    198

    cái này là nguyên tắc hoạt động của bọn chăn web đen đây

Các đề tài tương tự

  1. muốn viết code cho 1 button nằm trong girdview thì viết ở đâu
    Gửi bởi thuan trong diễn đàn Nhập môn lập trình C#, ASP.NET
    Trả lời: 2
    Bài viết cuối: 14-09-2011, 01:08 PM
  2. Viết Giao Diện Phần Mềm bằng Flash, Core viết = C
    Gửi bởi trần trân trong diễn đàn Thắc mắc lập trình C/C++ trên Linux
    Trả lời: 5
    Bài viết cuối: 31-05-2011, 06:45 AM
  3. Algorithm Viết code thời khóa biểu viết trên Window Form C# như thế nào?
    Gửi bởi hocphp_1998 trong diễn đàn Thắc mắc lập trình C#
    Trả lời: 10
    Bài viết cuối: 12-04-2011, 11:10 PM
  4. [visual basic]Viết lệnh trong sự kiện timer là viết ở đâu?
    Gửi bởi thuan trong diễn đàn Thắc mắc chung
    Trả lời: 2
    Bài viết cuối: 21-09-2010, 12:53 AM
  5. đang tìm sách lập trình mạng hoặc sniffer
    Gửi bởi minbu trong diễn đàn Tài liệu, ebooks và công cụ
    Trả lời: 1
    Bài viết cuối: 01-04-2008, 11:46 PM

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn