You're here: Snippet Directory » C/C++ (495)
Language:

IP Steganography 2-way communicator

Language: English
Programming Language: C
Published by: no_operation [not registered]
Last Update: 5/15/2006
Views: 167


Description

This snippet uses the TCP SYN ISN 32 bit field to send messages to other users. It has the IP ID field option (commented out at this time) as well. This was a research project I was working on, but got too busy to continue it, any improvements are welcome.

Code

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

No comments avaiable

Add a comment

Name *  

Email (won't be displayed) *    

Website  

Comment *  

Sicherheitscode Security Code *    

RSS