1 /*
2 * Black Hat 1.0 by 0x90 (0x90@invisiblenet.net)
3 * 2-way IP Steganography proof of concept.
4 *
5 * This software should be used at your own risk.
6 *
7 * compile: cc -o black_hat black_hat.c -lpcap
8 *
9 *
10 *
11 * Portions of this code based on ping.c (c) 1987 Regents of the
12 * University of California. (See function in_cksm() for details)
13 *
14 * Small portions from various packet utilities by unknown authors
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <signal.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <netdb.h>
23 #include <netinet/in.h>
24 #include <sys/socket.h>
25 #include <arpa/inet.h>
26 #include <netinet/ip.h>
27 #include <netinet/tcp.h>
28 #include <pcap.h>
29 #include <fcntl.h>
30 #include <termios.h>
31 #include <netinet/if_ether.h>
32 #define VERSION "1.0"
33 static int count = 1;
34 char *packet_buf;
35 char rbuffer[5];
36 FILE *output;
37 char filename[80]="bored.txt";
38 char *dev;
39 char errbuf[PCAP_ERRBUF_SIZE];
40 pcap_t *pd;
41 struct bpf_program fp;
42 long public_port;
43 long private_port;
44 unsigned int source_host=0,dest_host=0;
45 //int server_port;
46 unsigned short source_port=3001,dest_port=3000;
47 int ipid=0,seq=1,ack=0,server=0,file=0;
48 char *portnum;
49 char filter[] = "tcp src port 3001";
50 bpf_u_int32 maskp;
51 bpf_u_int32 netp;
52 struct termios term, original;
53 char desthost[80];char srchost[80];
54 /* Prototypes */
55 void packetconstruct(unsigned int, unsigned int, unsigned short, unsigned
56 short);
57 unsigned short in_cksum(unsigned short *, int);
58 unsigned int host_convert(char *);
59 void usage(char *);
60 void packet_handler(u_char *useless, const struct pcap_pkthdr* pkthdr, const u_char* packet)
61 {
62 const struct ether_header *eptr;
63 const struct ip *iptr;
64 const struct tcphdr* tcp;
65 useless = NULL;
66 count++;
67
68 eptr = (struct ether_header *)packet;
69 iptr = (struct ip *)(packet + sizeof(struct ether_header)); /* 0xe bytes, ethernet header */
70 tcp = (struct tcphdr *)(packet + sizeof(struct ether_header) + sizeof(struct ip));
71
72 /*
73 later use, let me get stuff working first ;)
74 // if(ntohs(tcp->dest) == 3001 && tcp->rst==1 )
75 {
76 rbuffer[0] = tcp->seq >> 24; rbuffer[1] = tcp->seq >> 16; rbuffer[2]=tcp->seq >> 8; rbuffer[3] = tcp->seq;
77 rbuffer[0] = (rbuffer[0]-1);
78 printf("%s", rbuffer);
79
80
81
82 }*/
83
84 if(ntohs(tcp->source) == 3001 && tcp->syn ==1)
85 {
86 rbuffer[0] = tcp->seq>>24;rbuffer[1] = tcp->seq >> 16; rbuffer[2]=tcp->seq >> 8; rbuffer[3] = tcp->seq;
87 printf("%s",rbuffer);
88
89
90 }
91 }
92 main()
93 {
94
95
96
97 dev = pcap_lookupdev(errbuf);
98 //dev = "eth1";
99 pcap_lookupnet(dev, &netp, &maskp, errbuf);
100
101 if ((pd = pcap_open_live(dev, BUFSIZ, 0, 0, errbuf)) == NULL) {
102 fprintf(stderr, "OpenLive: %s\n", errbuf);
103 exit(1);}
104 if((pcap_compile(pd, &fp, filter, 0, netp)) == -1)
105 {
106 perror("pcap_compile");
107 exit(EXIT_FAILURE);
108 }
109 if((pcap_setfilter(pd, &fp)) == -1)
110 {
111 perror("pcap_setfilter");
112 exit(EXIT_FAILURE);
113 }
114
115 pcap_setnonblock(pd,1,errbuf);
116
117
118
119
120
121
122 /* Title */
123 printf("Black Hat %s (c)2002 0x90\n",VERSION);
124 printf("Not for commercial use without permission.\n");
125
126
127
128
129 loop:
130 printf("Client Setup (TX):");
131
132 printf("Your host:");
133 scanf("%s", &srchost);
134 printf("Destination Host:");
135 scanf("%s", &desthost);
136
137
138
139
140 dest_host=host_convert(desthost);
141 source_host=host_convert(srchost);
142
143
144 printf("\nClient Info:\n");
145 printf("Destination Host: %s\n",desthost);
146 printf("Source Host : %s\n",srchost);
147 printf("Originating Port: %u\n",source_port); printf("Destination Port: %u\n",dest_port);
148 printf("Encoding Type : IP Sequence Number\n");
149
150
151 printf("Talk:\n");
152 fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
153 /* Can they run this? */
154 if(geteuid() !=0)
155 {
156 printf("\nYou need to be root to run this.\n\n");
157 exit(0);
158 }
159 /* Do the dirty work */while(1){
160
161 packetconstruct(source_host, dest_host, source_port, dest_port);
162
163 }
164
165 exit(0);
166 }
167
168
169
170 void packetconstruct(unsigned int source_addr, unsigned int dest_addr, unsigned
171 short source_port, unsigned short dest_port)
172 {
173
174
175
176
177
178
179
180 struct send_tcp
181 {
182 struct iphdr ip;
183 struct tcphdr tcp;
184 } send_tcp;
185
186 struct recv_tcp
187 {
188 struct iphdr ip;
189 struct tcphdr tcp;
190 char buffer[10000];
191 } recv_pkt;
192
193 /* From synhose.c by knight */
194 struct pseudo_header
195 {
196 unsigned int source_address;
197 unsigned int dest_address;
198 unsigned char placeholder;
199 unsigned char protocol;
200 unsigned short tcp_length;
201 struct tcphdr tcp;
202 } pseudo_header;
203
204
205 /*decode*/
206 /* char rbuffer[5]; rbuffer[4] = 0; while(1) { rbuffer[0] =
207 ch >> 24; rbuffer[1] = ch >> 16; rbuffer[2] =
208 ch >> 8; rbuffer[3] = ch; fprintf(output,
209 "%s", rbuffer); if(strlen(rbuffer) < 4) { break;} }
210 */
211
212
213
214 int seconds;
215
216
217
218 long ch;
219 int count;
220 int send_socket;
221 int recv_socket;
222 struct sockaddr_in sin;
223 FILE *input;
224 FILE *output;
225 int t; int eofflag =0;
226 char sbuffer[4];
227
228 rbuffer[4]=0;
229
230 /* Initialize RNG for future use */
231 srand((getpid())*(dest_port));
232
233 /**********************/
234 /* Client code */
235 /**********************/
236
237
238 while(!eofflag) {if(tcgetattr(fileno(stdin), &term) < 0)
239 {
240 perror("error getting terminal information");
241 exit(1);
242 }
243
244 original = term; /* save Terminal Attributes */
245
246 /* switch off echo and canonical mode */
247 term.c_lflag &= ~ICANON;
248 // term.c_lflag &= ~ECHO;
249
250 /* set terminal attributes */
251 if(tcsetattr(fileno(stdin), TCSANOW, &term) < 0)
252 {
253 perror("error setting terminal information");
254 exit(1);
255 }
256
257 t=fread(sbuffer,1,4,stdin); for( ; t < 4; t++)
258 {sbuffer[t] = 0; eofflag = 1;} ch = (long)
259 sbuffer[0] << 24 | (long) sbuffer[1] << 16 | (long)
260 sbuffer[2] << 8 | (long) sbuffer[3];
261 /*
262 if(tcsetattr(fileno(stdin), TCSANOW, &original) <
263 0)
264 {
265 perror("error setting terminal information");
266 exit(1);
267 }
268 */
269 {
270 }
271 usleep(500000);
272 /* Make the IP header with our forged information */
273 send_tcp.ip.ihl = 5;
274 send_tcp.ip.version = 4;
275 send_tcp.ip.tos = 0;
276 send_tcp.ip.tot_len = htons(40);
277 /* if we are NOT doing IP ID header encoding, randomize the value */
278 /* of the IP identification field */
279 //if (ipid == 0)
280 send_tcp.ip.id =(int)(255.0*rand()/(RAND_MAX+1.0));
281 //else /* otherwise we "encode" it with our cheesy algorithm */
282 // send_tcp.ip.id =ch;
283
284 send_tcp.ip.frag_off = 0;
285 send_tcp.ip.ttl = 64;
286 send_tcp.ip.protocol = IPPROTO_TCP;
287 send_tcp.ip.check = 0;
288 send_tcp.ip.saddr = source_addr;
289 send_tcp.ip.daddr = dest_addr;
290
291 /* begin forged TCP header */
292 //if(source_port == 0) /* if the didn't supply a source port, we make one */
293 // send_tcp.tcp.source = 1+(int)(10000.0*rand()/(RAND_MAX+1.0));
294 //else /* otherwise use the one given */
295 send_tcp.tcp.source = htons(source_port);
296
297 //if(seq==0) /* if we are not encoding the value into the seq number */
298 // send_tcp.tcp.seq = 1+(int)(10000.0*rand()/(RAND_MAX+1.0));
299 //else /* otherwise we'll hide the data using our cheesy algorithm one more time. */
300 send_tcp.tcp.seq = ch;
301
302 /* forge destination port */
303 send_tcp.tcp.dest = htons(dest_port);
304
305 /* the rest of the flags */
306 /* NOTE: Other covert channels can use the following flags to encode data a BIT */
307 /* at a time. A good example would be the use of the PSH flag setting to either */
308 /* on or off and having the remote side decode the bytes accordingly... LJ */
309 send_tcp.tcp.ack_seq = 0;
310 send_tcp.tcp.res1 = 0;
311 send_tcp.tcp.doff = 5;
312 send_tcp.tcp.fin = 0;
313 send_tcp.tcp.syn = 1;
314 send_tcp.tcp.rst = 0;
315 send_tcp.tcp.psh = 0;
316 send_tcp.tcp.ack = 0;
317 send_tcp.tcp.urg = 0;
318 send_tcp.tcp.window = htons(512);
319 send_tcp.tcp.check = 0;
320 send_tcp.tcp.urg_ptr = 0;
321
322 /* Drop our forged data into the socket struct */
323 sin.sin_family = AF_INET;
324 sin.sin_port = send_tcp.tcp.source;
325 sin.sin_addr.s_addr = send_tcp.ip.daddr;
326
327 /* Now open the raw socket for sending */
328 send_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
329 if(send_socket < 0)
330 {
331 perror("send socket cannot be open. Are you root?");
332 exit(1);
333 }
334
335 /* Make IP header checksum */
336 send_tcp.ip.check = in_cksum((unsigned short *)&send_tcp.ip, 20);
337 /* Final preparation of the full header */
338
339 /* From synhose.c by knight */
340 pseudo_header.source_address = send_tcp.ip.saddr;
341 pseudo_header.dest_address = send_tcp.ip.daddr;
342 pseudo_header.placeholder = 0;
343 pseudo_header.protocol = IPPROTO_TCP;
344 pseudo_header.tcp_length = htons(20);
345
346 bcopy((char *)&send_tcp.tcp, (char *)&pseudo_header.tcp, 20);
347 /* Final checksum on the entire package */
348 send_tcp.tcp.check = in_cksum((unsigned short *)&pseudo_header, 32);
349 /* Away we go.... */
350 sendto(send_socket, &send_tcp, 40, 0, (struct sockaddr *)&sin, sizeof(sin));
351 //printf("Sending Data: %c",ch);
352
353 close(send_socket);
354 pcap_dispatch(pd,1, packet_handler, NULL);
355
356 } /* end while(fread()) loop */
357 //fclose(input);
358 /* end if(server == 0) loop */
359
360 /* end else(serverloop) function */
361
362 } /* end packetconstruct() function */
363
364
365 /* clipped from ping.c (this function is the whore of checksum routines */
366 /* as everyone seems to use it..I feel so dirty...) */
367
368 /* Copyright (c)1987 Regents of the University of California.
369 * All rights reserved.
370 *
371 * Redistribution and use in source and binary forms are permitted
372 * provided that the above copyright notice and this paragraph are
373 * dupliated in all such forms and that any documentation, advertising
374 * materials, and other materials related to such distribution and use
375 * acknowledge that the software was developed by the University of
376 * California, Berkeley. The name of the University may not be used
377 * to endorse or promote products derived from this software without
378 * specific prior written permission. THIS SOFTWARE IS PROVIDED ``AS
379 * IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
380 * WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHATIBILITY AND
381 * FITNESS FOR A PARTICULAR PURPOSE
382 */
383
384
385 unsigned short in_cksum(unsigned short *ptr, int nbytes)
386 {
387 register long sum; /* assumes long == 32 bits */
388 u_short oddbyte;
389 register u_short answer; /* assumes u_short == 16 bits */
390
391 /*
392 * Our algorithm is simple, using a 32-bit accumulator (sum),
393 * we add sequential 16-bit words to it, and at the end, fold back
394 * all the carry bits from the top 16 bits into the lower 16 bits.
395 */
396
397 sum = 0;
398 while (nbytes > 1) {
399 sum += *ptr++;
400 nbytes -= 2;
401 }
402
403 /* mop up an odd byte, if necessary */
404 if (nbytes == 1) {
405 oddbyte = 0; /* make sure top half is zero */
406 *((u_char *) &oddbyte) = *(u_char *)ptr; /* one byte only */
407 sum += oddbyte;
408 }
409
410 /*
411 * Add back carry outs from top 16 bits to low 16 bits.
412 */
413
414 sum = (sum >> 16) + (sum & 0xffff); /* add high-16 to low-16 */
415 sum += (sum >> 16); /* add carry */
416 answer = ~sum; /* ones-complement, then truncate to 16 bits */
417 return(answer);
418 } /* end in_cksm()
419
420
421
422 /* Generic resolver from unknown source */
423 unsigned int host_convert(char *hostname)
424 {
425 static struct in_addr i;
426 struct hostent *h;
427 i.s_addr = inet_addr(hostname);
428 if(i.s_addr == -1)
429 {
430 h = gethostbyname(hostname);
431 if(h == NULL)
432 {
433 fprintf(stderr, "cannot resolve %s\n", hostname);
434 exit(0);
435 }
436 bcopy(h->h_addr, (char *)&i.s_addr, h->h_length);
437 }
438 return i.s_addr;
439 } /* end resolver */
440
441
442
443 /* The End */
444
445
446
447