📄 capture.c
字号:
/* This file is part of AirSnort. AirSnort is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. AirSnort is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with AirSnort; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*//* 4/17/02 - Orinoco's now handle beacons properly thanks to monitor mode patch fix by johnp@chem...*/#include <stdio.h>#include <stdlib.h>#include <sys/time.h>#include <signal.h>#include <string.h>#include <time.h>#include <unistd.h>#include <ctype.h>#include <errno.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <linux/wireless.h>#include "capture.h"#include "crack.h"#include "bssidlist.h"#include <pcap.h>#ifndef SIOCIWFIRSTPRIV#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE#endif#define P80211_IFREQ (SIOCIWFIRSTPRIV + 1)#define ADDR1(x) ((x)+4)#define ADDR2(x) ((x)+10)#define ADDR3(x) ((x)+16)//PROTOTYPESvoid quick_message(char *title, char *message);void dump(unsigned char *pkt, int len);int do_ioctl(unsigned char *userMsg);void setPointers(CaptureRec *cr, const unsigned char *pkt);void changeChannel(int x);int resetMAC(void);extern int scan;extern int chan;extern int doCapture;extern int logfile;extern int readPcapFile;extern int oldscan;extern int cardType;extern int breadth40;extern int breadth128;extern char cmd[80];char dev[WLAN_DEVNAMELEN_MAX] = "wlan0";int count = 0;int lasttime = 0;//initialize pointers according to TO_DS,//FROM_DS flags. This saves time during packet decodingvoid setPointers(CaptureRec *cr, const unsigned char *pkt) { cr->iv = pkt + 24; switch (pkt[1] & 0x03) { case 0: //STA to STA, or management and control cr->bssid = ADDR3(pkt); cr->sta = ADDR2(pkt); break; case 2: //AP to STA data cr->bssid = ADDR2(pkt); cr->sta = ADDR1(pkt); break; case 3: //AP to AP cr->iv += 6; case 1: //STA to AP data cr->bssid = ADDR1(pkt); cr->sta = ADDR2(pkt); break; }}void dump(unsigned char *pkt, int len) { int i = 0; int j = 0; for (i = 0; i < len; i += 16) { for (j = 0; j < 16; j++) { if (i + j >= len) { fprintf(stdout, " "); } else { fprintf(stdout, "%2.2x ", pkt[i + j]); } } fprintf(stdout, " "); for (j = 0; j < 16; j++) { if (i + j >= len) break; if (isprint(pkt[i + j])) { fprintf(stdout, "%c", pkt[i + j]); } else { fprintf(stdout, "."); } } fprintf(stdout, "\n"); } fprintf(stdout, "\n----------------------------------------------------------------\n\n"); }//the thread function for the packet capture thread. It opens a packet //source and collects packets until instructed to stop. Packets are //parsed for interesting info and placed on the packet queue for consumption//by the cracking threadvoid *capture(void *arg) { CaptureArg *parms = (CaptureArg*) arg; int namelen, whichType, channelLoc, isData, crclen; PacketInfo pi; CaptureRec cap; BssidList *apNode = NULL; const unsigned char *pkt; unsigned char fc0 = 0, type = 0, subType = 0; struct pcap_pkthdr pktHdr; int allF = 0xFFFFFFFF; cap.pInfo = π while (doCapture) { pi.pack = NULL; pi.name = NULL; pi.wep = 0; apNode = NULL; isData = 0; pkt = pcap_next(parms->pcap, &pktHdr); if (pkt == NULL) { if (readPcapFile) break; //reached end of file continue; } if (parms->dump) { pcap_dump((unsigned char*)parms->dump, &pktHdr, pkt); } //test for prism2 appended dummy crc crclen = memcmp(pkt + pktHdr.len - 4, &allF, 4) ? 0 : 4; pktHdr.len -= crclen; pi.channel = -1; pkt += parms->offset; pi.raw = pkt; whichType = pkt[1] & 0x03; setPointers(&cap, pkt); fc0 = pkt[0]; type = fc0 & 0x0C; subType = (fc0 >> 4); switch (type) { case 0: //management if ((subType == 5) || (subType == 8)) { //beacon or probe response frame namelen = pkt[37]; channelLoc = 38 + namelen + 2; channelLoc += pkt[channelLoc - 1]; if (pkt[channelLoc] == 3) { pi.channel = pkt[channelLoc + 2]; } apNode = bssidFind(pkt + 16); //ADDR3 if (apNode) { if (apNode->name) { if (subType == 8) { //don't take name more than once from a beacon break; } free(apNode->name); } apNode->name = (char*) malloc(namelen + 1); strncpy(apNode->name, pkt + 38, namelen); (apNode->name)[namelen] = 0; break; } //might want to check elementid at pkt[36] == 0 as well pi.name = (char*) malloc(namelen + 1); strncpy(pi.name, pkt + 38, namelen); pi.name[namelen] = 0; pi.wep = pkt[34] & 0x10; } break; case 0x04: //control //break; continue; case 0x08: if (subType != 0) break; //not a data frame isData = 1; pktHdr.len -= whichType == 3 ? (parms->offset + 30) : (parms->offset + 24); //adjust len to size of frame body //this is a sloppy way to detect unencrypted packets, but since 0xAA is not //an IV byte of interest anyway, its probably not a big deal if (*((unsigned short *)cap.iv) != 0xAAAA || (pkt[1] & 0x40)) { pi.wep = 1; if (isResolved(cap.iv)) { pi.pack = (Packet*) malloc(sizeof(Packet)); pi.pack->len = pktHdr.len; //i.e. 802.11b "Frame Body" pi.pack->buf = (unsigned char*) malloc(pktHdr.len); memcpy(pi.pack->buf, cap.iv, pktHdr.len); pi.pack->next = NULL; } } } //switch addPacket(apNode, &cap, isData); } resetMAC(); if (parms->dump) { pcap_dump_close(parms->dump); } pcap_close(parms->pcap); free(parms); if (readPcapFile) { readPcapFile = 0; scan = oldscan; } doCapture = 0; pthread_exit(NULL);}void changeChannel(int x) { if (doCapture && scan) { chan = (chan % 11) + 1; setChannel(chan); }}/* * The setChannel function was lifted from the wlanctl source file:**src/wlanctl/wlanctl.c** user utility for the wlan card** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.* --------------------------------------------------------------------** linux-wlan* linux-wlan is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. linux-wlan is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with linux-wlan; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA** --------------------------------------------------------------------** Inquiries regarding the linux-wlan Open Source project can be* made directly to:** AbsoluteValue Systems Inc.* info@linux-wlan.com* http://www.linux-wlan.com** --------------------------------------------------------------------*//* * Set the NIC into promiscuous mode on the indicated channel * This code was distilled from wlanctl.c which is part of * the linux-wlan-ng package. This is the only wlanctl functionality * needed in airsnort, so I put it here rather than shelling out * to invoke wlanctl-ng every time I wanted to change channels. CSE. */#define MAKE_SYS_CALL/* * as opposed to making ioctl calls directly. We can make ioctls * directly if we can tie into the linux-wlan-ng header files */int setChannel( unsigned char channel ){ int result = 0; static int fd = -1; struct iwreq ireq; //for Orinoco int *ptr; if (fd == -1) { fd = socket(AF_INET, SOCK_STREAM, 0); } if (cardType == ORINOCO) { //assumes patched pcmcia-cs-3.1.31 and using orinoco_cs /* get a socket */// fd = socket(AF_INET, SOCK_STREAM, 0); if ( fd == -1 ) { return -1; } ptr = (int *) ireq.u.name; ptr[0] = 1; ptr[1] = chan; strcpy(ireq.ifr_ifrn.ifrn_name, dev); result = ioctl( fd, SIOCIWFIRSTPRIV + 0x8, &ireq);// close(fd); } else if (cardType == PRISM) {#ifndef MAKE_SYS_CALL p80211msg_lnxreq_wlansniff_t sniff; memset(&sniff, 0, sizeof(p80211msg_lnxreq_wlansniff_t)); sniff.msgcode = DIDmsg_lnxreq_wlansniff; sniff.msglen = sizeof(p80211msg_lnxreq_wlansniff_t); strcpy((char*) sniff.devname, dev); sniff.enable.did = DIDmsg_lnxreq_wlansniff_enable; sniff.enable.len = 4; sniff.enable.status = 0; sniff.enable.data = P80211ENUM_truth_true; sniff.channel.did = DIDmsg_lnxreq_wlansniff_channel; sniff.channel.len = 4; sniff.channel.status = 0; sniff.channel.data = channel; sniff.prismheader.did = DIDmsg_lnxreq_wlansniff_prismheader; sniff.prismheader.len = 4; sniff.prismheader.status = 0; sniff.prismheader.data = P80211ENUM_truth_true; sniff.keepwepflags.did = DIDmsg_lnxreq_wlansniff_keepwepflags; sniff.keepwepflags.len = 4; sniff.keepwepflags.status = 0; sniff.keepwepflags.data = P80211ENUM_truth_true; sniff.resultcode.did = DIDmsg_lnxreq_wlansniff_resultcode; sniff.resultcode.status = P80211ENUM_msgitem_status_no_value; sniff.resultcode.len = 4; result = do_ioctl((uint8_t*) &sniff);#else char cmd[128]; static char *parms = "keepwepflags=false prismheader=true"; sprintf(cmd, "wlanctl-ng %s lnxreq_wlansniff enable=true channel=%d %s > /dev/null", dev, channel, parms); result = system(cmd);#endif } return result;}int resetMAC(){ int result = 0; int fd; struct iwreq ireq; //for Orinoco int *ptr; if (cardType == ORINOCO) { //assumes patched pcmcia-cs-3.1.31 and using orinoco_cs /* get a socket */ fd = socket(AF_INET, SOCK_STREAM, 0); if ( fd == -1 ) { return -1; } ptr = (int *) ireq.u.name; ptr[0] = 0; ptr[1] = 0; strcpy(ireq.ifr_ifrn.ifrn_name, dev); result = ioctl( fd, SIOCIWFIRSTPRIV + 0x8, &ireq); close(fd); } else if (cardType == PRISM) {#ifndef MAKE_SYS_CALL p80211msg_lnxreq_wlansniff_t sniff; memset(&sniff, 0, sizeof(p80211msg_lnxreq_wlansniff_t)); sniff.msgcode = DIDmsg_lnxreq_wlansniff; sniff.msglen = sizeof(p80211msg_lnxreq_wlansniff_t); strcpy((char*) sniff.devname, dev); sniff.enable.did = DIDmsg_lnxreq_wlansniff_enable; sniff.enable.len = 4; sniff.enable.data = P80211ENUM_truth_false; sniff.channel.did = DIDmsg_lnxreq_wlansniff_channel; sniff.channel.status = P80211ENUM_msgitem_status_no_value; sniff.channel.len = 4; sniff.resultcode.did = DIDmsg_lnxreq_wlansniff_resultcode; sniff.resultcode.status = P80211ENUM_msgitem_status_no_value; sniff.resultcode.len = 4; result = do_ioctl((uint8_t*) &sniff);#else char cmd[80]; sprintf(cmd, "wlanctl-ng %s lnxreq_wlansniff enable=false > /dev/null", dev); result = system(cmd);#endif } return result;}int do_ioctl( unsigned char *userMsg ){ int result = -1; int fd; p80211ioctl_req_t req; p80211msg_t *msg = (p80211msg_t *) userMsg; strcpy(msg->devname, dev); /* set the magic */ req.magic = P80211_IOCTL_MAGIC; /* get a socket */ fd = socket(AF_INET, SOCK_STREAM, 0); if ( fd == -1 ) { return result; } req.len = msg->msglen; req.data = msg; strcpy( req.name, dev); req.result = 0; result = ioctl( fd, P80211_IFREQ, &req); close(fd); return result;}//load user settings from $HOME/.airsnortrcvoid loadOpts() { char *home = getenv("HOME"); char rcfile[128]; FILE *rc; char *index; int r; if (home) { sprintf(rcfile, "%s/.airsnortrc", home); rc = fopen(rcfile, "r"); if (rc) { while (fgets(rcfile, 128, rc)) { index = strchr(rcfile, '\n'); if (index) *index = 0; index = strchr(rcfile, ':'); if (index) { *index = 0; if (!strcmp(rcfile, "dev")) { strncpy(dev, index + 1, WLAN_DEVNAMELEN_MAX); dev[WLAN_DEVNAMELEN_MAX - 1] = 0; } else if (!strcmp(rcfile, "driver")) { r = atoi(index + 1); cardType = r < 0 || r > 2 ? 0 : r; } else if (!strcmp(rcfile, "breadth128")) { r = atoi(index + 1); breadth128 = r < 1 || r > 20 ? 1 : r; } else if (!strcmp(rcfile, "breadth40")) { r = atoi(index + 1); breadth40 = r < 1 || r > 20 ? 1 : r; } else if (!strcmp(rcfile, "channel")) { r = atoi(index + 1); chan = r < 1 || r > 11 ? 6 : r; } } } fclose(rc); } }}//save user settings to $HOME/.airsnortrcvoid saveOpts() { char *home = getenv("HOME"); char rcfile[128]; FILE *rc; if (home) { sprintf(rcfile, "%s/.airsnortrc", home); rc = fopen(rcfile, "w"); if (rc) { fprintf(rc, "dev:%s\n", dev); fprintf(rc, "driver:%d\n", cardType); fprintf(rc, "breadth128:%d\n", breadth128); fprintf(rc, "breadth40:%d\n", breadth40); fprintf(rc, "channel:%d\n", chan); fclose(rc); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -