Trao đổi với tôi

http://www.buidao.com

2/6/10

[Virus] Inject packet với WinPcap

Khi sử dụng một số phần mềm monitor hay hacking như Wireshark, Cain, DSniff,... đều có sử dụng kèm thư viện Winpcap. Vậy Winpcap tại sao lại cần thiết trong các ứng dụng trên và có vai trò gì?
Wireshark có chức năng sniff packet và phân tích gói tin theo từng layer. Cain hoạt động ARP Spoofing phải gửi được các gói với MAC giả mạo và có thông tin trên các layer được thay đổi tùy ý. Để làm chuyện này các phần mềm trên phải có khả năng thu nhận hay gửi được gói dưới dạng thô (raw packet). Trên môi trường Windows để làm việc này thật sự không đơn giản.
Khi read packet, dữ liệu khi đến được application thì chỉ còn lại phần content (payload), do IP header, TCP header đã tự động bị tách ra bởi kernel TCP-IP stack. Khi write packet ứng dụng sẽ được kernel đóng gói thêm vào TCP Header, IP Header, và gửi tiếp xuống datalink do đó ta không thể tạo gói theo ý mình. Trên windows không có các hàm API đầy đủ để hỗ trợ tương tác ở mức thấp.
Winpcap ra đời đã tạo ra một thư việc cấp thấp đầy đủ và mạnh mẽ giúp các nhà lập trình giải quyết các vấn đề trên.
Các chức năng của WinPcap:
- Thu thập những gói dữ liệu thô.
- Lọc gói dữ liệu theo những qui tắc của người dùng trước khi chúng được truyền tới tầng ứng dụng
- Gửi gói dữ liệu thô
Bảng so sánh NPF với TCP-IP kernel:


Mô hình kiến trúc WinPCap:


NPF (Netgroup Packet Filter): Có chức năng tương tác trực tiếp với network interface driver. Thu nhận và truyền dữ liệu thô không qua OS kernel.
Packet.dll: cung cấp một API mức thấp. Chức năng:
- Cài đặt, khởi tạo và dừng trình điều khiển NPF
- Nhận và gửi gói từ trình điều khiển NPF
- Thiết lập các thông số cho card
- Thu được một danh sách các card mạng
- Lấy các thông tin về mạng: địa chỉ, netmask
Wpcap: cung cấp một tập các chức năng bắt gói mức cao, tương thích với libpcap (tương tự trên linux), hoạt động độc lập với phần cứng mạng và hệ điều hành.
(Hết phần 1)

Thư viện Winpcap: http://www.winpcap.org/install/bin/WpdPack_4_0_2.zip
Danh sách các hàm và tham số Winpcap: http://www.winpcap.org/docs/docs_40_...wpcapfunc.html
Một số vd:
1. Lấy danh sách thiết bị

Trích:

#include "pcap.h"
main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list from the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL /* auth is not needed */, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs_ex: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d= alldevs; d != NULL; d= d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if (i == 0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return;
}
/* We don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
}

(Winpcap)
2 hàm quan trọng sử dụng trong chương trình là: pcap_findalldevs_ex() và pcap_freealldevs() để giải phóng danh sách sau khi hoàn tất.
Kết quả:

Trích:

1. \Device\NPF_{4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
2. \Device\NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)

2. Capture packet:

Trích:

#include "pcap.h"
/* prototype of the packet handler */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
pcap_t *adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
/* Retrieve the device list on the local machine */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* Print the list */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
/* Jump to the selected adapter */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
/* Open the device */
if ( (adhandle= pcap_open(d->name, // name of the device
65536, // portion of the packet to capture
// 65536 guarantees that the whole packet will be captured on all the link layers
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
/* Free the device list */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/* start the capture */
pcap_loop(adhandle, 0, packet_handler, NULL);
return 0;
}
/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
/* convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}

(Winpcap)
3. Send packet

Trích:

#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
void main(int argc, char **argv)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
u_char packet[100];
int i;
/* Check the validity of the command line */
if (argc != 2)
{
printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]);
return;
}
/* Open the output device */
if ( (fp= pcap_open(argv[1], // name of the device
100, // portion of the packet to capture (only the first 100 bytes)
PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
1000, // read timeout
NULL, // authentication on the remote machine
errbuf // error buffer
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", argv[1]);
return;
}
/* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */
packet[0]=1;
packet[1]=1;
packet[2]=1;
packet[3]=1;
packet[4]=1;
packet[5]=1;
/* set mac source to 2:2:2:2:2:2 */
packet[6]=2;
packet[7]=2;
packet[8]=2;
packet[9]=2;
packet[10]=2;
packet[11]=2;
/* Fill the rest of the packet */
for(i=12;i<100;i++)
{
packet[i]=i%256;
}
/* Send down the packet */
if (pcap_sendpacket(fp, packet, 100 /* size */) != 0)
{
fprintf(stderr,"\nError sending the packet: \n", pcap_geterr(fp));
return;
}
return;
}

(Winpcap)
Hiện có nhiều công cụ packet generator được viết trên thư viện winpcap. Có thể tham khảo một số công cụ sau:
1. Network Packet Generator: generate packet theo định dạng dump file or npg format. Download
2. Engage Packet builder: công cụ generate packet với giao diện GUI dễ sử dụng, hỗ trợ script để tạo kịch bản gửi packet. Download
RefLink: http://nhatnghe.com/forum/showthread.php?t=25506