1 /* $OpenBSD: netcat.c,v 1.64 2003/10/19 22:50:35 deraadt Exp $ */ 2 /* 3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Re-written nc(1) for OpenBSD. Original implementation by 31 * *Hobbit* <hobbit@avian.org>. 32 */ 33 34 #include <sys/types.h> 35 #include <sys/socket.h> 36 #include <sys/time.h> 37 #include <sys/un.h> 38 39 #include <netinet/in.h> 40 #include <arpa/telnet.h> 41 42 #include <err.h> 43 #include <errno.h> 44 #include <netdb.h> 45 #include <poll.h> 46 #include <stdarg.h> 47 #include <stdio.h> 48 #include <stdlib.h> 49 #include <string.h> 50 #include <unistd.h> 51 #include <fcntl.h> 52 53 #ifndef SUN_LEN 54 #define SUN_LEN(su) \ 55 (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) 56 #endif 57 58 #define PORT_MAX 65535 59 #define PORT_MAX_LEN 6 60 61 /* Command Line Options */ 62 int iflag; /* Interval Flag */ 63 int kflag; /* More than one connect */ 64 int lflag; /* Bind to local port */ 65 int nflag; /* Dont do name lookup */ 66 char *pflag; /* Localport flag */ 67 int rflag; /* Random ports flag */ 68 char *sflag; /* Source Address */ 69 int tflag; /* Telnet Emulation */ 70 int uflag; /* UDP - Default to TCP */ 71 int vflag; /* Verbosity */ 72 int xflag; /* Socks proxy */ 73 int zflag; /* Port Scan Flag */ 74 75 int timeout = -1; 76 int family = AF_UNSPEC; 77 char *portlist[PORT_MAX+1]; 78 79 ssize_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); 80 void atelnet(int, unsigned char *, unsigned int); 81 void build_ports(char *); 82 void help(void); 83 int local_listen(char *, char *, struct addrinfo); 84 void readwrite(int); 85 int remote_connect(char *, char *, struct addrinfo); 86 int socks_connect(char *, char *, struct addrinfo, char *, char *, 87 struct addrinfo, int); 88 int udptest(int); 89 int unix_connect(char *); 90 int unix_listen(char *); 91 void usage(int); 92 93 int 94 main(int argc, char *argv[]) 95 { 96 int ch, s, ret, socksv; 97 char *host, *uport, *endp; 98 struct addrinfo hints; 99 struct servent *sv; 100 socklen_t len; 101 struct sockaddr *cliaddr; 102 char *proxy; 103 char *proxyhost = "", *proxyport = NULL; 104 struct addrinfo proxyhints; 105 106 ret = 1; 107 s = 0; 108 socksv = 5; 109 host = NULL; 110 uport = NULL; 111 endp = NULL; 112 sv = NULL; 113 114 while ((ch = getopt(argc, argv, "46UX:hi:klnp:rs:tuvw:x:z")) != -1) { 115 switch (ch) { 116 case '4': 117 family = AF_INET; 118 break; 119 case '6': 120 family = AF_INET6; 121 break; 122 case 'U': 123 family = AF_UNIX; 124 break; 125 case 'X': 126 socksv = (int)strtoul(optarg, &endp, 10); 127 if ((socksv != 4 && socksv != 5) || *endp != '\0') 128 errx(1, "only SOCKS version 4 and 5 supported"); 129 break; 130 case 'h': 131 help(); 132 break; 133 case 'i': 134 iflag = (int)strtoul(optarg, &endp, 10); 135 if (iflag < 0 || *endp != '\0') 136 errx(1, "interval cannot be negative"); 137 break; 138 case 'k': 139 kflag = 1; 140 break; 141 case 'l': 142 lflag = 1; 143 break; 144 case 'n': 145 nflag = 1; 146 break; 147 case 'p': 148 pflag = optarg; 149 break; 150 case 'r': 151 rflag = 1; 152 break; 153 case 's': 154 sflag = optarg; 155 break; 156 case 't': 157 tflag = 1; 158 break; 159 case 'u': 160 uflag = 1; 161 break; 162 case 'v': 163 vflag = 1; 164 break; 165 case 'w': 166 timeout = (int)strtoul(optarg, &endp, 10); 167 if (timeout < 0 || *endp != '\0') 168 errx(1, "timeout cannot be negative"); 169 if (timeout >= (INT_MAX / 1000)) 170 errx(1, "timeout too large"); 171 timeout *= 1000; 172 break; 173 case 'x': 174 xflag = 1; 175 if ((proxy = strdup(optarg)) == NULL) 176 err(1, NULL); 177 break; 178 case 'z': 179 zflag = 1; 180 break; 181 default: 182 usage(1); 183 } 184 } 185 argc -= optind; 186 argv += optind; 187 188 /* Cruft to make sure options are clean, and used properly. */ 189 if (argv[0] && !argv[1] && family == AF_UNIX) { 190 if (uflag) 191 errx(1, "cannot use -u and -U"); 192 host = argv[0]; 193 uport = NULL; 194 } else if (argv[0] && !argv[1]) { 195 if (!lflag) 196 usage(1); 197 uport = argv[0]; 198 host = NULL; 199 } else if (argv[0] && argv[1]) { 200 host = argv[0]; 201 uport = argv[1]; 202 } else 203 usage(1); 204 205 if (lflag && sflag) 206 errx(1, "cannot use -s and -l"); 207 if (lflag && pflag) 208 errx(1, "cannot use -p and -l"); 209 if (lflag && zflag) 210 errx(1, "cannot use -z and -l"); 211 if (!lflag && kflag) 212 errx(1, "must use -l with -k"); 213 214 /* Initialize addrinfo structure */ 215 if (family != AF_UNIX) { 216 memset(&hints, 0, sizeof(struct addrinfo)); 217 hints.ai_family = family; 218 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 219 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 220 if (nflag) 221 hints.ai_flags |= AI_NUMERICHOST; 222 } 223 224 if (xflag) { 225 if (uflag) 226 errx(1, "no proxy support for UDP mode"); 227 228 if (lflag) 229 errx(1, "no proxy support for listen"); 230 231 if (family == AF_UNIX) 232 errx(1, "no proxy support for unix sockets"); 233 234 /* XXX IPv6 transport to proxy would probably work */ 235 if (family == AF_INET6) 236 errx(1, "no proxy support for IPv6"); 237 238 if (sflag) 239 errx(1, "no proxy support for local source address"); 240 241 proxyhost = strsep(&proxy, ":"); 242 proxyport = proxy; 243 244 memset(&proxyhints, 0, sizeof(struct addrinfo)); 245 proxyhints.ai_family = family; 246 proxyhints.ai_socktype = SOCK_STREAM; 247 proxyhints.ai_protocol = IPPROTO_TCP; 248 if (nflag) 249 proxyhints.ai_flags |= AI_NUMERICHOST; 250 } 251 252 if (lflag) { 253 int connfd; 254 ret = 0; 255 256 if (family == AF_UNIX) 257 s = unix_listen(host); 258 259 /* Allow only one connection at a time, but stay alive */ 260 for (;;) { 261 if (family != AF_UNIX) 262 s = local_listen(host, uport, hints); 263 if (s < 0) 264 err(1, NULL); 265 /* 266 * For UDP, we will use recvfrom() initially 267 * to wait for a caller, then use the regular 268 * functions to talk to the caller. 269 */ 270 if (uflag) { 271 int rv; 272 char buf[1024]; 273 struct sockaddr_storage z; 274 275 len = sizeof(z); 276 rv = recvfrom(s, buf, sizeof(buf), MSG_PEEK, 277 (struct sockaddr *)&z, &len); 278 if (rv < 0) 279 err(1, "recvfrom"); 280 281 rv = connect(s, (struct sockaddr *)&z, len); 282 if (rv < 0) 283 err(1, "connect"); 284 285 connfd = s; 286 } else { 287 connfd = accept(s, (struct sockaddr *)&cliaddr, 288 &len); 289 } 290 291 readwrite(connfd); 292 close(connfd); 293 if (family != AF_UNIX) 294 close(s); 295 296 if (!kflag) 297 break; 298 } 299 } else if (family == AF_UNIX) { 300 ret = 0; 301 302 if ((s = unix_connect(host)) > 0 && !zflag) { 303 readwrite(s); 304 close(s); 305 } else 306 ret = 1; 307 308 exit(ret); 309 310 } else { 311 int i = 0; 312 313 /* construct the portlist[] array */ 314 build_ports(uport); 315 316 /* Cycle through portlist, connecting to each port */ 317 for (i = 0; portlist[i] != NULL; i++) { 318 if (s) 319 close(s); 320 321 if (xflag) 322 s = socks_connect(host, portlist[i], hints, 323 proxyhost, proxyport, proxyhints, socksv); 324 else 325 s = remote_connect(host, portlist[i], hints); 326 327 if (s < 0) 328 continue; 329 330 ret = 0; 331 if (vflag || zflag) { 332 /* For UDP, make sure we are connected */ 333 if (uflag) { 334 if (udptest(s) == -1) { 335 ret = 1; 336 continue; 337 } 338 } 339 340 /* Don't lookup port if -n */ 341 if (nflag) 342 sv = NULL; 343 else { 344 sv = getservbyport( 345 ntohs(atoi(portlist[i])), 346 uflag ? "udp" : "tcp"); 347 } 348 349 printf("Connection to %s %s port [%s/%s] succeeded!\n", 350 host, portlist[i], uflag ? "udp" : "tcp", 351 sv ? sv->s_name : "*"); 352 } 353 if (!zflag) 354 readwrite(s); 355 } 356 } 357 358 if (s) 359 close(s); 360 361 exit(ret); 362 } 363 364 /* 365 * unix_connect() 366 * Return's a socket connected to a local unix socket. Return's -1 on failure. 367 */ 368 int 369 unix_connect(char *path) 370 { 371 struct sockaddr_un sun; 372 int s; 373 374 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 375 return (-1); 376 (void)fcntl(s, F_SETFD, 1); 377 378 memset(&sun, 0, sizeof(struct sockaddr_un)); 379 sun.sun_family = AF_UNIX; 380 381 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 382 sizeof(sun.sun_path)) { 383 close(s); 384 errno = ENAMETOOLONG; 385 return (-1); 386 } 387 if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 388 close(s); 389 return (-1); 390 } 391 return (s); 392 393 } 394 395 /* 396 * unix_listen() 397 * create a unix domain socket, and listen on it. 398 */ 399 int 400 unix_listen(char *path) 401 { 402 struct sockaddr_un sun; 403 int s; 404 405 /* create unix domain socket */ 406 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 407 return (-1); 408 409 memset(&sun, 0, sizeof(struct sockaddr_un)); 410 sun.sun_family = AF_UNIX; 411 412 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 413 sizeof(sun.sun_path)) { 414 close(s); 415 errno = ENAMETOOLONG; 416 return (-1); 417 } 418 419 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 420 close(s); 421 return (-1); 422 } 423 424 if (listen(s, 5) < 0) { 425 close(s); 426 return (-1); 427 } 428 return (s); 429 } 430 431 /* 432 * remote_connect() 433 * Return's a socket connected to a remote host. Properly bind's to a local 434 * port or source address if needed. Return's -1 on failure. 435 */ 436 int 437 remote_connect(char *host, char *port, struct addrinfo hints) 438 { 439 struct addrinfo *res, *res0; 440 int s, error; 441 442 if ((error = getaddrinfo(host, port, &hints, &res))) 443 errx(1, "getaddrinfo: %s", gai_strerror(error)); 444 445 res0 = res; 446 do { 447 if ((s = socket(res0->ai_family, res0->ai_socktype, 448 res0->ai_protocol)) < 0) 449 continue; 450 451 /* Bind to a local port or source address if specified */ 452 if (sflag || pflag) { 453 struct addrinfo ahints, *ares; 454 455 if (!(sflag && pflag)) { 456 if (!sflag) 457 sflag = NULL; 458 else 459 pflag = NULL; 460 } 461 462 memset(&ahints, 0, sizeof(struct addrinfo)); 463 ahints.ai_family = res0->ai_family; 464 ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 465 ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 466 ahints.ai_flags = AI_PASSIVE; 467 if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) 468 errx(1, "getaddrinfo: %s", gai_strerror(error)); 469 470 if (bind(s, (struct sockaddr *)ares->ai_addr, 471 ares->ai_addrlen) < 0) 472 errx(1, "bind failed: %s", strerror(errno)); 473 freeaddrinfo(ares); 474 } 475 476 if (connect(s, res0->ai_addr, res0->ai_addrlen) == 0) 477 break; 478 479 close(s); 480 s = -1; 481 } while ((res0 = res0->ai_next) != NULL); 482 483 freeaddrinfo(res); 484 485 return (s); 486 } 487 488 /* 489 * local_listen() 490 * Return's a socket listening on a local port, binds to specified source 491 * address. Return's -1 on failure. 492 */ 493 int 494 local_listen(char *host, char *port, struct addrinfo hints) 495 { 496 struct addrinfo *res, *res0; 497 int s, ret, x = 1; 498 int error; 499 500 /* Allow nodename to be null */ 501 hints.ai_flags |= AI_PASSIVE; 502 503 /* 504 * In the case of binding to a wildcard address 505 * default to binding to an ipv4 address. 506 */ 507 if (host == NULL && hints.ai_family == AF_UNSPEC) 508 hints.ai_family = AF_INET; 509 510 if ((error = getaddrinfo(host, port, &hints, &res))) 511 errx(1, "getaddrinfo: %s", gai_strerror(error)); 512 513 res0 = res; 514 do { 515 if ((s = socket(res0->ai_family, res0->ai_socktype, 516 res0->ai_protocol)) == 0) 517 continue; 518 519 ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); 520 if (ret == -1) 521 err(1, NULL); 522 523 if (bind(s, (struct sockaddr *)res0->ai_addr, 524 res0->ai_addrlen) == 0) 525 break; 526 527 close(s); 528 s = -1; 529 } while ((res0 = res0->ai_next) != NULL); 530 531 if (!uflag && s != -1) { 532 if (listen(s, 1) < 0) 533 err(1, "listen"); 534 } 535 536 freeaddrinfo(res); 537 538 return (s); 539 } 540 541 /* 542 * readwrite() 543 * Loop that polls on the network file descriptor and stdin. 544 */ 545 void 546 readwrite(int nfd) 547 { 548 struct pollfd pfd[2]; 549 char buf[BUFSIZ]; 550 int wfd = fileno(stdin), n, ret; 551 int lfd = fileno(stdout); 552 553 /* Setup Network FD */ 554 pfd[0].fd = nfd; 555 pfd[0].events = POLLIN; 556 557 /* Setup STDIN FD */ 558 pfd[1].fd = wfd; 559 pfd[1].events = POLLIN; 560 561 while (pfd[0].fd != -1) { 562 if (iflag) 563 sleep(iflag); 564 565 if ((n = poll(pfd, 2, timeout)) < 0) { 566 close(nfd); 567 err(1, "Polling Error"); 568 } 569 570 if (n == 0) 571 return; 572 573 if (pfd[0].revents & POLLIN) { 574 if ((n = read(nfd, buf, sizeof(buf))) < 0) 575 return; 576 else if (n == 0) { 577 shutdown(nfd, SHUT_RD); 578 pfd[0].fd = -1; 579 pfd[0].events = 0; 580 } else { 581 if (tflag) 582 atelnet(nfd, buf, n); 583 if ((ret = atomicio( 584 (ssize_t (*)(int, void *, size_t))write, 585 lfd, buf, n)) != n) 586 return; 587 } 588 } 589 590 if (pfd[1].revents & POLLIN) { 591 if ((n = read(wfd, buf, sizeof(buf))) < 0) 592 return; 593 else if (n == 0) { 594 shutdown(nfd, SHUT_WR); 595 pfd[1].fd = -1; 596 pfd[1].events = 0; 597 } else { 598 if((ret = atomicio( 599 (ssize_t (*)(int, void *, size_t))write, 600 nfd, buf, n)) != n) 601 return; 602 } 603 } 604 } 605 } 606 607 /* Deal with RFC854 WILL/WONT DO/DONT negotiation */ 608 void 609 atelnet(int nfd, unsigned char *buf, unsigned int size) 610 { 611 int ret; 612 unsigned char *p, *end; 613 unsigned char obuf[4]; 614 615 end = buf + size; 616 obuf[0] = '\0'; 617 618 for (p = buf; p < end; p++) { 619 if (*p != IAC) 620 break; 621 622 obuf[0] = IAC; 623 p++; 624 if ((*p == WILL) || (*p == WONT)) 625 obuf[1] = DONT; 626 if ((*p == DO) || (*p == DONT)) 627 obuf[1] = WONT; 628 if (obuf) { 629 p++; 630 obuf[2] = *p; 631 obuf[3] = '\0'; 632 if ((ret = atomicio( 633 (ssize_t (*)(int, void *, size_t))write, 634 nfd, obuf, 3)) != 3) 635 warnx("Write Error!"); 636 obuf[0] = '\0'; 637 } 638 } 639 } 640 641 /* 642 * build_ports() 643 * Build an array or ports in portlist[], listing each port 644 * that we should try to connect too. 645 */ 646 void 647 build_ports(char *p) 648 { 649 char *n, *endp; 650 int hi, lo, cp; 651 int x = 0; 652 653 if ((n = strchr(p, '-')) != NULL) { 654 if (lflag) 655 errx(1, "Cannot use -l with multiple ports!"); 656 657 *n = '\0'; 658 n++; 659 660 /* Make sure the ports are in order: lowest->highest */ 661 hi = (int)strtoul(n, &endp, 10); 662 if (hi <= 0 || hi > PORT_MAX || *endp != '\0') 663 errx(1, "port range not valid"); 664 lo = (int)strtoul(p, &endp, 10); 665 if (lo <= 0 || lo > PORT_MAX || *endp != '\0') 666 errx(1, "port range not valid"); 667 668 if (lo > hi) { 669 cp = hi; 670 hi = lo; 671 lo = cp; 672 } 673 674 /* Load ports sequentially */ 675 for (cp = lo; cp <= hi; cp++) { 676 portlist[x] = calloc(1, PORT_MAX_LEN); 677 if (portlist[x] == NULL) 678 err(1, NULL); 679 snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); 680 x++; 681 } 682 683 /* Randomly swap ports */ 684 if (rflag) { 685 int y; 686 char *c; 687 688 for (x = 0; x <= (hi - lo); x++) { 689 y = (arc4random() & 0xFFFF) % (hi - lo); 690 c = portlist[x]; 691 portlist[x] = portlist[y]; 692 portlist[y] = c; 693 } 694 } 695 } else { 696 hi = (int)strtoul(p, &endp, 10); 697 if (hi <= 0 || hi > PORT_MAX || *endp != '\0') 698 errx(1, "port range not valid"); 699 portlist[0] = calloc(1, PORT_MAX_LEN); 700 if (portlist[0] == NULL) 701 err(1, NULL); 702 portlist[0] = p; 703 } 704 } 705 706 /* 707 * udptest() 708 * Do a few writes to see if the UDP port is there. 709 * XXX - Better way of doing this? Doesn't work for IPv6 710 * Also fails after around 100 ports checked. 711 */ 712 int 713 udptest(int s) 714 { 715 int i, rv, ret; 716 717 for (i = 0; i <= 3; i++) { 718 if ((rv = write(s, "X", 1)) == 1) 719 ret = 1; 720 else 721 ret = -1; 722 } 723 return (ret); 724 } 725 726 void 727 help(void) 728 { 729 usage(0); 730 fprintf(stderr, "\tCommand Summary:\n\ 731 \t-4 Use IPv4\n\ 732 \t-6 Use IPv6\n\ 733 \t-U Use UNIX domain socket\n\ 734 \t-X vers\t SOCKS version (4 or 5)\n\ 735 \t-h This help text\n\ 736 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 737 \t-k Keep inbound sockets open for multiple connects\n\ 738 \t-l Listen mode, for inbound connects\n\ 739 \t-n Suppress name/port resolutions\n\ 740 \t-p port\t Specify local port for remote connects\n\ 741 \t-r Randomize remote ports\n\ 742 \t-s addr\t Local source address\n\ 743 \t-t Answer TELNET negotiation\n\ 744 \t-u UDP mode\n\ 745 \t-v Verbose\n\ 746 \t-w secs\t Timeout for connects and final net reads\n\ 747 \t-x addr[:port]\tSpecify socks proxy address and port\n\ 748 \t-z Zero-I/O mode [used for scanning]\n\ 749 Port numbers can be individual or ranges: lo-hi [inclusive]\n"); 750 exit(1); 751 } 752 753 void 754 usage(int ret) 755 { 756 fprintf(stderr, "usage: nc [-46Uhklnrtuvz] [-i interval] [-p source port]\n"); 757 fprintf(stderr, "\t [-s ip address] [-w timeout] [-X vers] [-x proxy address [:port]]\n"); 758 fprintf(stderr, "\t [hostname] [port[s...]]\n"); 759 if (ret) 760 exit(1); 761 } 762