diff options
author | Nick Kralevich <nnk@google.com> | 2011-10-24 15:44:27 -0700 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2011-10-24 16:45:58 -0700 |
commit | e4e83f8147f92141cd02cc46cccca088c527ea2a (patch) | |
tree | c6447c33a54750c3c51d062d023e0c84ee788e9b | |
parent | 3b92542cff3f53ab608c25e1f65c538e42dece1b (diff) | |
download | netcat-e4e83f8147f92141cd02cc46cccca088c527ea2a.tar.gz |
Upgrade to openbsd's netcat.android-cts-4.2_r1android-4.2_r1android-4.2.2_r1.2android-4.2.2_r1.1android-4.2.2_r1android-4.2.1_r1.2android-4.2.1_r1.1android-4.2.1_r1android-4.1.2_r2.1android-4.1.2_r2android-4.1.2_r1android-4.1.1_r6.1android-4.1.1_r6android-4.1.1_r5android-4.1.1_r4android-4.1.1_r3android-4.1.1_r2android-4.1.1_r1.1android-4.1.1_r1jb-releasejb-mr1.1-releasejb-mr1-releasejb-mr0-release
Upgrade to openbsd's version of netcat, available for download
from http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/nc/
This version has been modified to remove BSD specific calls
and other functionality unnecessary for Android. The removed
portions of code are surrounded by #ifdef ANDROID / #endif.
This code corresponds to the following openbsd versions:
atomicio.c: v1.10
atomicio.h: v1.2
netcat.c: v1.103
The file socks.c and nc.1 are not included in this change.
Change-Id: I39df7fbe335af97e092dd4d4a96f957d6d1a5b5d
-rw-r--r-- | Android.mk | 4 | ||||
-rw-r--r-- | Changelog | 109 | ||||
-rw-r--r-- | Makefile.dist | 122 | ||||
-rw-r--r-- | NOTICE | 91 | ||||
-rw-r--r-- | README | 946 | ||||
-rw-r--r-- | atomicio.c | 69 | ||||
-rw-r--r-- | atomicio.h | 39 | ||||
-rw-r--r-- | data/Makefile | 10 | ||||
-rw-r--r-- | data/README | 9 | ||||
-rw-r--r-- | data/data.c | 274 | ||||
-rw-r--r-- | data/dns-any.d | 36 | ||||
-rw-r--r-- | data/nfs-0.d | 59 | ||||
-rw-r--r-- | data/pm.d | 8 | ||||
-rw-r--r-- | data/pmap-dump.d | 60 | ||||
-rw-r--r-- | data/pmap-mnt.d | 78 | ||||
-rw-r--r-- | data/rip.d | 52 | ||||
-rw-r--r-- | data/rservice.c | 68 | ||||
-rw-r--r-- | data/showmount.d | 63 | ||||
-rw-r--r-- | data/xor.c | 92 | ||||
-rw-r--r-- | generic.h | 377 | ||||
-rwxr-xr-x | nc | bin | 28216 -> 0 bytes | |||
-rw-r--r-- | netcat.blurb | 61 | ||||
-rw-r--r-- | netcat.c | 2679 | ||||
-rw-r--r-- | scripts/README | 5 | ||||
-rwxr-xr-x | scripts/alta | 33 | ||||
-rwxr-xr-x | scripts/bsh | 29 | ||||
-rwxr-xr-x | scripts/dist.sh | 23 | ||||
-rwxr-xr-x | scripts/irc | 79 | ||||
-rwxr-xr-x | scripts/iscan | 35 | ||||
-rwxr-xr-x | scripts/ncp | 46 | ||||
-rwxr-xr-x | scripts/probe | 50 | ||||
-rwxr-xr-x | scripts/web | 148 | ||||
-rwxr-xr-x | scripts/webproxy | 139 | ||||
-rwxr-xr-x | scripts/webrelay | 44 | ||||
-rwxr-xr-x | scripts/websearch | 77 | ||||
-rwxr-xr-x | stupidh | 464 |
36 files changed, 1236 insertions, 5242 deletions
@@ -2,7 +2,9 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:=\ - netcat.c + netcat.c \ + atomicio.c + LOCAL_CFLAGS:=-O2 -g #LOCAL_CFLAGS+=-DLINUX diff --git a/Changelog b/Changelog deleted file mode 100644 index 7bdd521..0000000 --- a/Changelog +++ /dev/null @@ -1,109 +0,0 @@ -Here is sort of an edit history for netcat, in forward cron order. - -950915 or so - basic gethostpoop and doconnect layout established -950920 or so - timeout handlers, improvements to gethostpoop, read-stdin-args, - primitive select loop, and later the stdin-to-many saved-count thing -950923 - select loop is firm, connect and i/o works nicely - added listen mode - crocked in UDP and debugged how its back-connect works -950927 - unsnarled main a fair amount - got "udptest" working right - added HELP!! yow. -951003 - added exec-a-prog thing - cleaned up routine-header comments - signal catcher - close stdin when we won't need it [-z, etc] -951004 - getportpoop - inbound options hexdump finally works [forgot to preload "size" int] -951005 or so - added random mode, which necessitated more main() logic cleanups -951008 - hammered out exit-status stuff, final main() argv loop cleanup - massive readme cleanup pre-1.00 release -951010 - almost-1.00 release up for FTP, but not announced yet - added a couple of wrapper scripts -951012 -- 1.00 - nc100 RELEASE, mailing-list spam, etc etc -951021 - doc tweak per cgull - webproxy/webrelay scripts came together. fuckin' yow. -951023 - added indication of *local* address in dolisten() connect handling - reset errno before dolisten msgs -- gethostpoop might have munged it -951028 -- 1.01 - fixed exit status if -z on a single port -- was -1, is now 0 or 1 - like it should be -951029 - put "sent/rcvd" typeout more places, still only if -v -v - Doc fix: It's *David* Borman, not Paul [aka Mr. Environment - Variables, this month...] -951106 -- 1.02 - added h_errno strings and updated holler, gethostpoop to find them - Still slightly confused if gethostpoop() returns prematurely... -951107 - sys/select.h for them what needs it - wrote_txt and more calls to print sent/rcvd -951110 - try rnd-options, but setsockopt tosses them. Punt... - dumped "x.y" microtiming idea; seconds are granular enough for now - tweaked help text -951113 -- 1.03 - added first-net-read skip to select loop if we have saved stdin, and - moved retry-count test ahead of this. Makes multimode work much more - sensibly... - fleshed out this here edit history -951204 -- 1.04 - fixed duplication lameness with printing h_errno stuff -951215 - improved data.c; added xfer count and %r -951217 - rservice.c, an answer to mudge's k-rad script -951227 - port data.c to msloss, it might be useful - some doc slogging; particularly the telnet-wrapper idea -960120 -- 1.05 - give totals even if we ^C out [that's what sigcatchers are *for*!] - cleaned up big LSRR explanation comment -960131 -- 1.06 - flushed rndoption stuff - report of closing stdin fucking up Solaris. Not tried yet. - extra arg to rservice.c - documentation updates, added netcat-art and many udder tings - added Bela Lubkin's #ifdefs for SIGURG [SCO rel 5] - added ignoring SIGPIPE [lesson learned from webs.c] -960201 - genned up some more data dumps: pmap-mnt.d, showmount.d, - various others; into real tree -960217 -- 1.07 - finally fixed stdin-read-args thing to retain and send leftover data - added version to help text - made ascii-art cuter - added "probe" script - added Nextstep systype - finally fixed data.c to run "forever" - created xor.c -960223 -- 1.08 - if doconnect skt is 0 grab another one, don't dup(). [stupid solaris..] - threw in latest web scripts - threw in irc - more doc tweaks - stuck 1.08 prerelease up for FTP -960227 - hexdump in -- it's actually gonna be quite useful! - doc adds for hexdump; orig idea from dgaudet@wired -960229 -- 1.09 - telnet-opts responder in; left as OPTIONAL chunk since it mucks - with the data stream. - -e disables -o hexdump; avoid zero-length file turds -960310 -- 1.09a goddamnit-I'm-gonna-release-REAL-soon - made -e work outbound, too - random final cleanups and doc updates ... pant pant ... -960320 -- 1.10 - RELEASE version tested everywhere I could get to, up for FTP diff --git a/Makefile.dist b/Makefile.dist deleted file mode 100644 index 99f2795..0000000 --- a/Makefile.dist +++ /dev/null @@ -1,122 +0,0 @@ -# makefile for netcat, based off same ol' "generic makefile". -# Usually do "make systype" -- if your systype isn't defined, try "generic" -# or something else that most closely matches, see where it goes wrong, fix -# it, and MAIL THE DIFFS back to Hobbit. - -### PREDEFINES - -# DEFAULTS, possibly overridden by <systype> recursive call: -# pick gcc if you'd rather , and/or do -g instead of -O if debugging -# debugging -# DFLAGS = -DTEST -DDEBUG -CFLAGS = -O -XFLAGS = # xtra cflags, set by systype targets -XLIBS = # xtra libs if necessary? -# -Bstatic for sunos, -static for gcc, etc. You want this, trust me. -STATIC = -CC = cc $(CFLAGS) -LD = $(CC) -s # linker; defaults to stripped executables -o = o # object extension - -ALL = nc - -### BOGON-CATCHERS - -bogus: - @echo "Usage: make <systype> [options]" - -### HARD TARGETS - -nc: netcat.c - $(LD) $(DFLAGS) $(XFLAGS) $(STATIC) -o nc netcat.c $(XLIBS) - -nc-dos: - @echo "DOS?! Maybe someday, but not now" - -### SYSTYPES -- in the same order as in generic.h, please - -# designed for msc and nmake, but easy to change for your compiler. -# Recursive make may fail if you're short on memory -- u-fix! -# Note special hard-target and "quotes" instead of 'quotes' ... -dos: - $(MAKE) -e $(ALL)-dos $(MFLAGS) CC="cl /nologo" XLIBS= \ - XFLAGS="/AS -D__MSDOS__ -DMSDOS" o=obj - -ultrix: - make -e $(ALL) $(MFLAGS) XFLAGS='-DULTRIX' - -# you may need XLIBS='-lresolv -l44bsd' if you have BIND 4.9.x -sunos: - make -e $(ALL) $(MFLAGS) XFLAGS='-DSUNOS' STATIC=-Bstatic \ - XLIBS='-lresolv' - -# Pick this one ahead of "solaris" if you actually have the nonshared -# libraries [lib*.a] on your machine. By default, the Sun twits don't ship -# or install them, forcing you to use shared libs for any network apps. -# Kludged for gcc, which many regard as the only thing available. -solaris-static: - make -e $(ALL) $(MFLAGS) XFLAGS='-DSYSV=4 -D__svr4__ -DSOLARIS' \ - CC=gcc STATIC=-static XLIBS='-lnsl -lsocket -lresolv' - -# the more usual shared-lib version... -solaris: - make -e $(ALL) $(MFLAGS) XFLAGS='-DSYSV=4 -D__svr4__ -DSOLARIS' \ - CC=gcc STATIC= XLIBS='-lnsl -lsocket -lresolv' - -aix: - make -e $(ALL) $(MFLAGS) XFLAGS='-DAIX' - -linux: - make -e $(ALL) $(MFLAGS) XFLAGS='-DLINUX' STATIC=-static - -# irix 5.2, dunno 'bout earlier versions. If STATIC='-non_shared' doesn't -# work for you, null it out and yell at SGI for their STUPID default -# of apparently not installing /usr/lib/nonshared/*. Sheesh. -irix: - make -e $(ALL) $(MFLAGS) XFLAGS='-DIRIX -DSYSV=4 -D__svr4__' \ - STATIC=-non_shared - -osf: - make -e $(ALL) $(MFLAGS) XFLAGS='-DOSF' STATIC=-non_shared - -# virtually the same as netbsd/bsd44lite/whatever -freebsd: - make -e $(ALL) $(MFLAGS) XFLAGS='-DFREEBSD' STATIC=-static - -bsdi: - make -e $(ALL) $(MFLAGS) XFLAGS='-DBSDI' STATIC=-Bstatic - -netbsd: - make -e $(ALL) $(MFLAGS) XFLAGS='-DNETBSD' STATIC=-static - -# finally got to an hpux box, which turns out to be *really* warped. -# STATIC here means "linker subprocess gets args '-a archive'" which causes -# /lib/libc.a to be searched ahead of '-a shared', or /lib/libc.sl. -hpux: - make -e $(ALL) $(MFLAGS) XFLAGS='-DHPUX' STATIC="-Wl,-a,archive" - -# unixware from bmc@telebase.com; apparently no static because of the -# same idiotic lack of link libraries -unixware: - make -e $(ALL) $(MFLAGS) XFLAGS='-DUNIXWARE -DSYSV=4 -D__svr4__' \ - STATIC= XLIBS='-L/usr/lib -lnsl -lsocket -lresolv' - -# from Declan Rieb at sandia, for a/ux 3.1.1 [also suggests using gcc]: -aux: - make -e $(ALL) $(MFLAGS) XFLAGS='-DAUX' STATIC=-static CC=gcc - -# Nexstep from mudge: NeXT cc is really old gcc -next: - make -e $(ALL) $(MFLAGS) XFLAGS='-DNEXT' STATIC=-Bstatic - -# start with this for a new architecture, and see what breaks. -generic: - make -e $(ALL) $(MFLAGS) XFLAGS='-DGENERIC' STATIC= - -# Still at large: dgux dynix ??? - -### RANDOM - -clean: - rm -f $(ALL) *.o *.obj - @@ -1,8 +1,83 @@ -Netcat is entirely my own creation, although plenty of other code was used as -examples. It is freely given away to the Internet community in the hope that -it will be useful, with no restrictions except giving credit where it is due. -No GPLs, Berkeley copyrights or any of that nonsense. The author assumes NO -responsibility for how anyone uses it. If netcat makes you rich somehow and -you're feeling generous, mail me a check. If you are affiliated in any way -with Microsoft Network, get a life. Always ski in control. Comments, -questions, and patches to hobbit@avian.org. +/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */ +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* $OpenBSD: atomicio.h,v 1.2 2007/09/07 14:50:44 tobias Exp $ */ + +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ +/* + * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ @@ -1,946 +0,0 @@ -Netcat 1.10 -=========== /\_/\ - / 0 0 \ -Netcat is a simple Unix utility which reads and writes data ====v==== -across network connections, using TCP or UDP protocol. \ W / -It is designed to be a reliable "back-end" tool that can | | _ -be used directly or easily driven by other programs and / ___ \ / -scripts. At the same time, it is a feature-rich network / / \ \ | -debugging and exploration tool, since it can create almost (((-----)))-' -any kind of connection you would need and has several / -interesting built-in capabilities. Netcat, or "nc" as the ( ___ -actual program is named, should have been supplied long ago \__.=|___E -as another one of those cryptic but standard Unix tools. / - -In the simplest usage, "nc host port" creates a TCP connection to the given -port on the given target host. Your standard input is then sent to the host, -and anything that comes back across the connection is sent to your standard -output. This continues indefinitely, until the network side of the connection -shuts down. Note that this behavior is different from most other applications -which shut everything down and exit after an end-of-file on the standard input. - -Netcat can also function as a server, by listening for inbound connections -on arbitrary ports and then doing the same reading and writing. With minor -limitations, netcat doesn't really care if it runs in "client" or "server" -mode -- it still shovels data back and forth until there isn't any more left. -In either mode, shutdown can be forced after a configurable time of inactivity -on the network side. - -And it can do this via UDP too, so netcat is possibly the "udp telnet-like" -application you always wanted for testing your UDP-mode servers. UDP, as the -"U" implies, gives less reliable data transmission than TCP connections and -some systems may have trouble sending large amounts of data that way, but it's -still a useful capability to have. - -You may be asking "why not just use telnet to connect to arbitrary ports?" -Valid question, and here are some reasons. Telnet has the "standard input -EOF" problem, so one must introduce calculated delays in driving scripts to -allow network output to finish. This is the main reason netcat stays running -until the *network* side closes. Telnet also will not transfer arbitrary -binary data, because certain characters are interpreted as telnet options and -are thus removed from the data stream. Telnet also emits some of its -diagnostic messages to standard output, where netcat keeps such things -religiously separated from its *output* and will never modify any of the real -data in transit unless you *really* want it to. And of course telnet is -incapable of listening for inbound connections, or using UDP instead. Netcat -doesn't have any of these limitations, is much smaller and faster than telnet, -and has many other advantages. - -Some of netcat's major features are: - - Outbound or inbound connections, TCP or UDP, to or from any ports - Full DNS forward/reverse checking, with appropriate warnings - Ability to use any local source port - Ability to use any locally-configured network source address - Built-in port-scanning capabilities, with randomizer - Built-in loose source-routing capability - Can read command line arguments from standard input - Slow-send mode, one line every N seconds - Hex dump of transmitted and received data - Optional ability to let another program service established connections - Optional telnet-options responder - -Efforts have been made to have netcat "do the right thing" in all its various -modes. If you believe that it is doing the wrong thing under whatever -circumstances, please notify me and tell me how you think it should behave. -If netcat is not able to do some task you think up, minor tweaks to the code -will probably fix that. It provides a basic and easily-modified template for -writing other network applications, and I certainly encourage people to make -custom mods and send in any improvements they make to it. This is the second -release; the overall differences from 1.00 are relatively minor and have mostly -to do with portability and bugfixes. Many people provided greatly appreciated -fixes and comments on the 1.00 release. Continued feedback from the Internet -community is always welcome! - -Netcat is entirely my own creation, although plenty of other code was used as -examples. It is freely given away to the Internet community in the hope that -it will be useful, with no restrictions except giving credit where it is due. -No GPLs, Berkeley copyrights or any of that nonsense. The author assumes NO -responsibility for how anyone uses it. If netcat makes you rich somehow and -you're feeling generous, mail me a check. If you are affiliated in any way -with Microsoft Network, get a life. Always ski in control. Comments, -questions, and patches to hobbit@avian.org. - -Building -======== - -Compiling is fairly straightforward. Examine the Makefile for a SYSTYPE that -matches yours, and do "make <systype>". The executable "nc" should appear. -If there is no relevant SYSTYPE section, try "generic". If you create new -sections for generic.h and Makefile to support another platform, please follow -the given format and mail back the diffs. - -There are a couple of other settable #defines in netcat.c, which you can -include as DFLAGS="-DTHIS -DTHAT" to your "make" invocation without having to -edit the Makefile. See the following discussions for what they are and do. - -If you want to link against the resolver library on SunOS [recommended] and -you have BIND 4.9.x, you may need to change XLIBS=-lresolv in the Makefile to -XLIBS="-lresolv -l44bsd". - -Linux sys/time.h does not really support presetting of FD_SETSIZE; a harmless -warning is issued. - -Some systems may warn about pointer types for signal(). No problem, though. - -Exploration of features -======================= - -Where to begin? Netcat is at the same time so simple and versatile, it's like -trying to describe everything you can do with your Swiss Army knife. This will -go over the basics; you should also read the usage examples and notes later on -which may give you even more ideas about what this sort of tool is good for. - -If no command arguments are given at all, netcat asks for them, reads a line -from standard input, and breaks it up into arguments internally. This can be -useful when driving netcat from certain types of scripts, with the side effect -of hiding your command line arguments from "ps" displays. - -The host argument can be a name or IP address. If -n is specified, netcat -will only accept numeric IP addresses and do no DNS lookups for anything. If --n is not given and -v is turned on, netcat will do a full forward and reverse -name and address lookup for the host, and warn you about the all-too-common -problem of mismatched names in the DNS. This often takes a little longer for -connection setup, but is useful to know about. There are circumstances under -which this can *save* time, such as when you want to know the name for some IP -address and also connect there. Netcat will just tell you all about it, saving -the manual steps of looking up the hostname yourself. Normally mismatch- -checking is case-insensitive per the DNS spec, but you can define ANAL at -compile time to make it case-sensitive -- sometimes useful for uncovering minor -errors in your own DNS files while poking around your networks. - -A port argument is required for outbound connections, and can be numeric or a -name as listed in /etc/services. If -n is specified, only numeric arguments -are valid. Special syntax and/or more than one port argument cause different -behavior -- see details below about port-scanning. - -The -v switch controls the verbosity level of messages sent to standard error. -You will probably want to run netcat most of the time with -v turned on, so you -can see info about the connections it is trying to make. You will probably -also want to give a smallish -w argument, which limits the time spent trying to -make a connection. I usually alias "nc" to "nc -v -w 3", which makes it -function just about the same for things I would otherwise use telnet to do. -The timeout is easily changed by a subsequent -w argument which overrides the -earlier one. Specifying -v more than once makes diagnostic output MORE -verbose. If -v is not specified at all, netcat silently does its work unless -some error happens, whereupon it describes the error and exits with a nonzero -status. Refused network connections are generally NOT considered to be errors, -unless you only asked for a single TCP port and it was refused. - -Note that -w also sets the network inactivity timeout. This does not have any -effect until standard input closes, but then if nothing further arrives from -the network in the next <timeout> seconds, netcat tries to read the net once -more for good measure, and then closes and exits. There are a lot of network -services now that accept a small amount of input and return a large amount of -output, such as Gopher and Web servers, which is the main reason netcat was -written to "block" on the network staying open rather than standard input. -Handling the timeout this way gives uniform behavior with network servers that -*don't* close by themselves until told to. - -UDP connections are opened instead of TCP when -u is specified. These aren't -really "connections" per se since UDP is a connectionless protocol, although -netcat does internally use the "connected UDP socket" mechanism that most -kernels support. Although netcat claims that an outgoing UDP connection is -"open" immediately, no data is sent until something is read from standard -input. Only thereafter is it possible to determine whether there really is a -UDP server on the other end, and often you just can't tell. Most UDP protocols -use timeouts and retries to do their thing and in many cases won't bother -answering at all, so you should specify a timeout and hope for the best. You -will get more out of UDP connections if standard input is fed from a source -of data that looks like various kinds of server requests. - -To obtain a hex dump file of the data sent either way, use "-o logfile". The -dump lines begin with "<" or ">" to respectively indicate "from the net" or -"to the net", and contain the total count per direction, and hex and ascii -representations of the traffic. Capturing a hex dump naturally slows netcat -down a bit, so don't use it where speed is critical. - -Netcat can bind to any local port, subject to privilege restrictions and ports -that are already in use. It is also possible to use a specific local network -source address if it is that of a network interface on your machine. [Note: -this does not work correctly on all platforms.] Use "-p portarg" to grab a -specific local port, and "-s ip-addr" or "-s name" to have that be your source -IP address. This is often referred to as "anchoring the socket". Root users -can grab any unused source port including the "reserved" ones less than 1024. -Absence of -p will bind to whatever unused port the system gives you, just like -any other normal client connection, unless you use -r [see below]. - -Listen mode will cause netcat to wait for an inbound connection, and then the -same data transfer happens. Thus, you can do "nc -l -p 1234 < filename" and -when someone else connects to your port 1234, the file is sent to them whether -they wanted it or not. Listen mode is generally used along with a local port -argument -- this is required for UDP mode, while TCP mode can have the system -assign one and tell you what it is if -v is turned on. If you specify a target -host and optional port in listen mode, netcat will accept an inbound connection -only from that host and if you specify one, only from that foreign source port. -In verbose mode you'll be informed about the inbound connection, including what -address and port it came from, and since listening on "any" applies to several -possibilities, which address it came *to* on your end. If the system supports -IP socket options, netcat will attempt to retrieve any such options from an -inbound connection and print them out in hex. - -If netcat is compiled with -DGAPING_SECURITY_HOLE, the -e argument specifies -a program to exec after making or receiving a successful connection. In the -listening mode, this works similarly to "inetd" but only for a single instance. -Use with GREAT CARE. This piece of the code is normally not enabled; if you -know what you're doing, have fun. This hack also works in UDP mode. Note that -you can only supply -e with the name of the program, but no arguments. If you -want to launch something with an argument list, write a two-line wrapper script -or just use inetd like always. - -If netcat is compiled with -DTELNET, the -t argument enables it to respond -to telnet option negotiation [always in the negative, i.e. DONT or WONT]. -This allows it to connect to a telnetd and get past the initial negotiation -far enough to get a login prompt from the server. Since this feature has -the potential to modify the data stream, it is not enabled by default. You -have to understand why you might need this and turn on the #define yourself. - -Data from the network connection is always delivered to standard output as -efficiently as possible, using large 8K reads and writes. Standard input is -normally sent to the net the same way, but the -i switch specifies an "interval -time" which slows this down considerably. Standard input is still read in -large batches, but netcat then tries to find where line breaks exist and sends -one line every interval time. Note that if standard input is a terminal, data -is already read line by line, so unless you make the -i interval rather long, -what you type will go out at a fairly normal rate. -i is really designed -for use when you want to "measure out" what is read from files or pipes. - -Port-scanning is a popular method for exploring what's out there. Netcat -accepts its commands with options first, then the target host, and everything -thereafter is interpreted as port names or numbers, or ranges of ports in M-N -syntax. CAVEAT: some port names in /etc/services contain hyphens -- netcat -currently will not correctly parse those, so specify ranges using numbers if -you can. If more than one port is thus specified, netcat connects to *all* of -them, sending the same batch of data from standard input [up to 8K worth] to -each one that is successfully connected to. Specifying multiple ports also -suppresses diagnostic messages about refused connections, unless -v is -specified twice for "more verbosity". This way you normally get notified only -about genuinely open connections. Example: "nc -v -w 2 -z target 20-30" will -try connecting to every port between 20 and 30 [inclusive] at the target, and -will likely inform you about an FTP server, telnet server, and mailer along the -way. The -z switch prevents sending any data to a TCP connection and very -limited probe data to a UDP connection, and is thus useful as a fast scanning -mode just to see what ports the target is listening on. To limit scanning -speed if desired, -i will insert a delay between each port probe. There are -some pitfalls with regard to UDP scanning, described later, but in general it -works well. - -For each range of ports specified, scanning is normally done downward within -that range. If the -r switch is used, scanning hops randomly around within -that range and reports open ports as it finds them. [If you want them listed -in order regardless, pipe standard error through "sort"...] In addition, if -random mode is in effect, the local source ports are also randomized. This -prevents netcat from exhibiting any kind of regular pattern in its scanning. -You can exert fairly fine control over your scan by judicious use of -r and -selected port ranges to cover. If you use -r for a single connection, the -source port will have a random value above 8192, rather than the next one the -kernel would have assigned you. Note that selecting a specific local port -with -p overrides any local-port randomization. - -Many people are interested in testing network connectivity using IP source -routing, even if it's only to make sure their own firewalls are blocking -source-routed packets. On systems that support it, the -g switch can be used -multiple times [up to 8] to construct a loose-source-routed path for your -connection, and the -G argument positions the "hop pointer" within the list. -If your network allows source-routed traffic in and out, you can test -connectivity to your own services via remote points in the internet. Note that -although newer BSD-flavor telnets also have source-routing capability, it isn't -clearly documented and the command syntax is somewhat clumsy. Netcat's -handling of "-g" is modeled after "traceroute". - -Netcat tries its best to behave just like "cat". It currently does nothing to -terminal input modes, and does no end-of-line conversion. Standard input from -a terminal is read line by line with normal editing characters in effect. You -can freely suspend out of an interactive connection and resume. ^C or whatever -your interrupt character is will make netcat close the network connection and -exit. A switch to place the terminal in raw mode has been considered, but so -far has not been necessary. You can send raw binary data by reading it out of -a file or piping from another program, so more meaningful effort would be spent -writing an appropriate front-end driver. - -Netcat is not an "arbitrary packet generator", but the ability to talk to raw -sockets and/or nit/bpf/dlpi may appear at some point. Such things are clearly -useful; I refer you to Darren Reed's excellent ip_filter package, which now -includes a tool to construct and send raw packets with any contents you want. - -Example uses -- the light side -============================== - -Again, this is a very partial list of possibilities, but it may get you to -think up more applications for netcat. Driving netcat with simple shell or -expect scripts is an easy and flexible way to do fairly complex tasks, -especially if you're not into coding network tools in C. My coding isn't -particularly strong either [although undoubtedly better after writing this -thing!], so I tend to construct bare-metal tools like this that I can trivially -plug into other applications. Netcat doubles as a teaching tool -- one can -learn a great deal about more complex network protocols by trying to simulate -them through raw connections! - -An example of netcat as a backend for something else is the shell-script -Web browser, which simply asks for the relevant parts of a URL and pipes -"GET /what/ever" into a netcat connection to the server. I used to do this -with telnet, and had to use calculated sleep times and other stupidity to -kludge around telnet's limitations. Netcat guarantees that I get the whole -page, and since it transfers all the data unmodified, I can even pull down -binary image files and display them elsewhere later. Some folks may find the -idea of a shell-script web browser silly and strange, but it starts up and -gets me my info a hell of a lot faster than a GUI browser and doesn't hide -any contents of links and forms and such. This is included, as scripts/web, -along with several other web-related examples. - -Netcat is an obvious replacement for telnet as a tool for talking to daemons. -For example, it is easier to type "nc host 25", talk to someone's mailer, and -just ^C out than having to type ^]c or QUIT as telnet would require you to do. -You can quickly catalog the services on your network by telling netcat to -connect to well-known services and collect greetings, or at least scan for open -ports. You'll probably want to collect netcat's diagnostic messages in your -output files, so be sure to include standard error in the output using -`>& file' in *csh or `> file 2>&1' in bourne shell. - -A scanning example: "echo QUIT | nc -v -w 5 target 20-250 500-600 5990-7000" -will inform you about a target's various well-known TCP servers, including -r-services, X, IRC, and maybe a few you didn't expect. Sending in QUIT and -using the timeout will almost guarantee that you see some kind of greeting or -error from each service, which usually indicates what it is and what version. -[Beware of the "chargen" port, though...] SATAN uses exactly this technique to -collect host information, and indeed some of the ideas herein were taken from -the SATAN backend tools. If you script this up to try every host in your -subnet space and just let it run, you will not only see all the services, -you'll find out about hosts that aren't correctly listed in your DNS. Then you -can compare new snapshots against old snapshots to see changes. For going -after particular services, a more intrusive example is in scripts/probe. - -Netcat can be used as a simple data transfer agent, and it doesn't really -matter which end is the listener and which end is the client -- input at one -side arrives at the other side as output. It is helpful to start the listener -at the receiving side with no timeout specified, and then give the sending side -a small timeout. That way the listener stays listening until you contact it, -and after data stops flowing the client will time out, shut down, and take the -listener with it. Unless the intervening network is fraught with problems, -this should be completely reliable, and you can always increase the timeout. A -typical example of something "rsh" is often used for: on one side, - - nc -l -p 1234 | uncompress -c | tar xvfp - - -and then on the other side - - tar cfp - /some/dir | compress -c | nc -w 3 othermachine 1234 - -will transfer the contents of a directory from one machine to another, without -having to worry about .rhosts files, user accounts, or inetd configurations -at either end. Again, it matters not which is the listener or receiver; the -"tarring" machine could just as easily be running the listener instead. One -could conceivably use a scheme like this for backups, by having cron-jobs fire -up listeners and backup handlers [which can be restricted to specific addresses -and ports between each other] and pipe "dump" or "tar" on one machine to "dd -of=/dev/tapedrive" on another as usual. Since netcat returns a nonzero exit -status for a denied listener connection, scripts to handle such tasks could -easily log and reject connect attempts from third parties, and then retry. - -Another simple data-transfer example: shipping things to a PC that doesn't have -any network applications yet except a TCP stack and a web browser. Point the -browser at an arbitrary port on a Unix server by telling it to download -something like http://unixbox:4444/foo, and have a listener on the Unix side -ready to ship out a file when the connect comes in. The browser may pervert -binary data when told to save the URL, but you can dig the raw data out of -the on-disk cache. - -If you build netcat with GAPING_SECURITY_HOLE defined, you can use it as an -"inetd" substitute to test experimental network servers that would otherwise -run under "inetd". A script or program will have its input and output hooked -to the network the same way, perhaps sans some fancier signal handling. Given -that most network services do not bind to a particular local address, whether -they are under "inetd" or not, it is possible for netcat avoid the "address -already in use" error by binding to a specific address. This lets you [as -root, for low ports] place netcat "in the way" of a standard service, since -inbound connections are generally sent to such specifically-bound listeners -first and fall back to the ones bound to "any". This allows for a one-off -experimental simulation of some service, without having to screw around with -inetd.conf. Running with -v turned on and collecting a connection log from -standard error is recommended. - -Netcat as well can make an outbound connection and then run a program or script -on the originating end, with input and output connected to the same network -port. This "inverse inetd" capability could enhance the backup-server concept -described above or help facilitate things such as a "network dialback" concept. -The possibilities are many and varied here; if such things are intended as -security mechanisms, it may be best to modify netcat specifically for the -purpose instead of wrapping such functions in scripts. - -Speaking of inetd, netcat will function perfectly well *under* inetd as a TCP -connection redirector for inbound services, like a "plug-gw" without the -authentication step. This is very useful for doing stuff like redirecting -traffic through your firewall out to other places like web servers and mail -hubs, while posing no risk to the firewall machine itself. Put netcat behind -inetd and tcp_wrappers, perhaps thusly: - - www stream tcp nowait nobody /etc/tcpd /bin/nc -w 3 realwww 80 - -and you have a simple and effective "application relay" with access control -and logging. Note use of the wait time as a "safety" in case realwww isn't -reachable or the calling user aborts the connection -- otherwise the relay may -hang there forever. - -You can use netcat to generate huge amounts of useless network data for -various performance testing. For example, doing - - yes AAAAAAAAAAAAAAAAAAAAAA | nc -v -v -l -p 2222 > /dev/null - -on one side and then hitting it with - - yes BBBBBBBBBBBBBBBBBBBBBB | nc othermachine 2222 > /dev/null - -from another host will saturate your wires with A's and B's. The "very -verbose" switch usage will tell you how many of each were sent and received -after you interrupt either side. Using UDP mode produces tremendously MORE -trash per unit time in the form of fragmented 8 Kbyte mobygrams -- enough to -stress-test kernels and network interfaces. Firing random binary data into -various network servers may help expose bugs in their input handling, which -nowadays is a popular thing to explore. A simple example data-generator is -given in data/data.c included in this package, along with a small collection -of canned input files to generate various packet contents. This program is -documented in its beginning comments, but of interest here is using "%r" to -generate random bytes at well-chosen points in a data stream. If you can -crash your daemon, you likely have a security problem. - -The hex dump feature may be useful for debugging odd network protocols, -especially if you don't have any network monitoring equipment handy or aren't -root where you'd need to run "tcpdump" or something. Bind a listening netcat -to a local port, and have it run a script which in turn runs another netcat -to the real service and captures the hex dump to a log file. This sets up a -transparent relay between your local port and wherever the real service is. -Be sure that the script-run netcat does *not* use -v, or the extra info it -sends to standard error may confuse the protocol. Note also that you cannot -have the "listen/exec" netcat do the data capture, since once the connection -arrives it is no longer netcat that is running. - -Binding to an arbitrary local port allows you to simulate things like r-service -clients, if you are root locally. For example, feeding "^@root^@joe^@pwd^@" -[where ^@ is a null, and root/joe could be any other local/remote username -pair] into a "rsh" or "rlogin" server, FROM your port 1023 for example, -duplicates what the server expects to receive. Thus, you can test for insecure -.rhosts files around your network without having to create new user accounts on -your client machine. The program data/rservice.c can aid this process by -constructing the "rcmd" protocol bytes. Doing this also prevents "rshd" from -trying to create that separate standard-error socket and still gives you an -input path, as opposed to the usual action of "rsh -n". Using netcat for -things like this can be really useful sometimes, because rsh and rlogin -generally want a host *name* as an argument and won't accept IP addresses. If -your client-end DNS is hosed, as may be true when you're trying to extract -backup sets on to a dumb client, "netcat -n" wins where normal rsh/rlogin is -useless. - -If you are unsure that a remote syslogger is working, test it with netcat. -Make a UDP connection to port 514 and type in "<0>message", which should -correspond to "kern.emerg" and cause syslogd to scream into every file it has -open [and possibly all over users' terminals]. You can tame this down by -using a different number and use netcat inside routine scripts to send syslog -messages to places that aren't configured in syslog.conf. For example, -"echo '<38>message' | nc -w 1 -u loggerhost 514" should send to auth.notice -on loggerhost. The exact number may vary; check against your syslog.h first. - -Netcat provides several ways for you to test your own packet filters. If you -bind to a port normally protected against outside access and make a connection -to somewhere outside your own network, the return traffic will be coming to -your chosen port from the "outside" and should be blocked. TCP may get through -if your filter passes all "ack syn", but it shouldn't be even doing that to low -ports on your network. Remember to test with UDP traffic as well! If your -filter passes at least outbound source-routed IP packets, bouncing a connection -back to yourself via some gateway outside your network will create "incoming" -traffic with your source address, which should get dropped by a correctly -configured anti-spoofing filter. This is a "non-test" if you're also dropping -source-routing, but it's good to be able to test for that too. Any packet -filter worth its salt will be blocking source-routed packets in both -directions, but you never know what interesting quirks you might turn up by -playing around with source ports and addresses and watching the wires with a -network monitor. - -You can use netcat to protect your own workstation's X server against outside -access. X is stupid enough to listen for connections on "any" and never tell -you when new connections arrive, which is one reason it is so vulnerable. Once -you have all your various X windows up and running you can use netcat to bind -just to your ethernet address and listen to port 6000. Any new connections -from outside the machine will hit netcat instead your X server, and you get a -log of who's trying. You can either tell netcat to drop the connection, or -perhaps run another copy of itself to relay to your actual X server on -"localhost". This may not work for dedicated X terminals, but it may be -possible to authorize your X terminal only for its boot server, and run a relay -netcat over on the server that will in turn talk to your X terminal. Since -netcat only handles one listening connection per run, make sure that whatever -way you rig it causes another one to run and listen on 6000 soon afterward, or -your real X server will be reachable once again. A very minimal script just -to protect yourself could be - - while true ; do - nc -v -l -s <your-addr> -p 6000 localhost 2 - done - -which causes netcat to accept and then close any inbound connection to your -workstation's normal ethernet address, and another copy is immediately run by -the script. Send standard error to a file for a log of connection attempts. -If your system can't do the "specific bind" thing all is not lost; run your -X server on display ":1" or port 6001, and netcat can still function as a probe -alarm by listening on 6000. - -Does your shell-account provider allow personal Web pages, but not CGI scripts? -You can have netcat listen on a particular port to execute a program or script -of your choosing, and then just point to the port with a URL in your homepage. -The listener could even exist on a completely different machine, avoiding the -potential ire of the homepage-host administrators. Since the script will get -the raw browser query as input it won't look like a typical CGI script, and -since it's running under your UID you need to write it carefully. You may want -to write a netcat-based script as a wrapper that reads a query and sets up -environment variables for a regular CGI script. The possibilities for using -netcat and scripts to handle Web stuff are almost endless. Again, see the -examples under scripts/. - -Example uses -- the dark side -============================= - -Equal time is deserved here, since a versatile tool like this can be useful -to any Shade of Hat. I could use my Victorinox to either fix your car or -disassemble it, right? You can clearly use something like netcat to attack -or defend -- I don't try to govern anyone's social outlook, I just build tools. -Regardless of your intentions, you should still be aware of these threats to -your own systems. - -The first obvious thing is scanning someone *else's* network for vulnerable -services. Files containing preconstructed data, be it exploratory or -exploitive, can be fed in as standard input, including command-line arguments -to netcat itself to keep "ps" ignorant of your doings. The more random the -scanning, the less likelihood of detection by humans, scan-detectors, or -dynamic filtering, and with -i you'll wait longer but avoid loading down the -target's network. Some examples for crafting various standard UDP probes are -given in data/*.d. - -Some configurations of packet filters attempt to solve the FTP-data problem by -just allowing such connections from the outside. These come FROM port 20, TO -high TCP ports inside -- if you locally bind to port 20, you may find yourself -able to bypass filtering in some cases. Maybe not to low ports "inside", but -perhaps to TCP NFS servers, X servers, Prospero, ciscos that listen on 200x -and 400x... Similar bypassing may be possible for UDP [and maybe TCP too] if a -connection comes from port 53; a filter may assume it's a nameserver response. - -Using -e in conjunction with binding to a specific address can enable "server -takeover" by getting in ahead of the real ones, whereupon you can snarf data -sent in and feed your own back out. At the very least you can log a hex dump -of someone else's session. If you are root, you can certainly use -s and -e to -run various hacked daemons without having to touch inetd.conf or the real -daemons themselves. You may not always have the root access to deal with low -ports, but what if you are on a machine that also happens to be an NFS server? -You might be able to collect some interesting things from port 2049, including -local file handles. There are several other servers that run on high ports -that are likely candidates for takeover, including many of the RPC services on -some platforms [yppasswdd, anyone?]. Kerberos tickets, X cookies, and IRC -traffic also come to mind. RADIUS-based terminal servers connect incoming -users to shell-account machines on a high port, usually 1642 or thereabouts. -SOCKS servers run on 1080. Do "netstat -a" and get creative. - -There are some daemons that are well-written enough to bind separately to all -the local interfaces, possibly with an eye toward heading off this sort of -problem. Named from recent BIND releases, and NTP, are two that come to mind. -Netstat will show these listening on address.53 instead of *.53. You won't -be able to get in front of these on any of the real interface addresses, which -of course is especially interesting in the case of named, but these servers -sometimes forget about things like "alias" interface addresses or interfaces -that appear later on such as dynamic PPP links. There are some hacked web -servers and versions of "inetd" floating around that specifically bind as well, -based on a configuration file -- these generally *are* bound to alias addresses -to offer several different address-based services from one machine. - -Using -e to start a remote backdoor shell is another obvious sort of thing, -easier than constructing a file for inetd to listen on "ingreslock" or -something, and you can access-control it against other people by specifying a -client host and port. Experience with this truly demonstrates how fragile the -barrier between being "logged in" or not really is, and is further expressed by -scripts/bsh. If you're already behind a firewall, it may be easier to make an -*outbound* connection and then run a shell; a small wrapper script can -periodically try connecting to a known place and port, you can later listen -there until the inbound connection arrives, and there's your shell. Running -a shell via UDP has several interesting features, although be aware that once -"connected", the UDP stub sockets tend to show up in "netstat" just like TCP -connections and may not be quite as subtle as you wanted. Packets may also be -lost, so use TCP if you need reliable connections. But since UDP is -connectionless, a hookup of this sort will stick around almost forever, even if -you ^C out of netcat or do a reboot on your side, and you only need to remember -the ports you used on both ends to reestablish. And outbound UDP-plus-exec -connection creates the connected socket and starts the program immediately. On -a listening UDP connection, the socket is created once a first packet is -received. In either case, though, such a "connection" has the interesting side -effect that only your client-side IP address and [chosen?] source port will -thereafter be able to talk to it. Instant access control! A non-local third -party would have to do ALL of the following to take over such a session: - - forge UDP with your source address [trivial to do; see below] - guess the port numbers of BOTH ends, or sniff the wire for them - arrange to block ICMP or UDP return traffic between it and your real - source, so the session doesn't die with a network write error. - -The companion program data/rservice.c is helpful in scripting up any sort of -r-service username or password guessing attack. The arguments to "rservice" -are simply the strings that get null-terminated and passed over an "rcmd"-style -connection, with the assumption that the client does not need a separate -standard-error port. Brute-force password banging is best done via "rexec" if -it is available since it is less likely to log failed attempts. Thus, doing -"rservice joe joespass pwd | nc target exec" should return joe's home dir if -the password is right, or "Permission denied." Plug in a dictionary and go to -town. If you're attacking rsh/rlogin, remember to be root and bind to a port -between 512 and 1023 on your end, and pipe in "rservice joe joe pwd" and such. - -Netcat can prevent inadvertently sending extra information over a telnet -connection. Use "nc -t" in place of telnet, and daemons that try to ask for -things like USER and TERM environment variables will get no useful answers, as -they otherwise would from a more recent telnet program. Some telnetds actually -try to collect this stuff and then plug the USER variable into "login" so that -the caller is then just asked for a password! This mechanism could cause a -login attempt as YOUR real username to be logged over there if you use a -Borman-based telnet instead of "nc -t". - -Got an unused network interface configured in your kernel [e.g. SLIP], or -support for alias addresses? Ifconfig one to be any address you like, and bind -to it with -s to enable all sorts of shenanigans with bogus source addresses. -The interface probably has to be UP before this works; some SLIP versions -need a far-end address before this is true. Hammering on UDP services is then -a no-brainer. What you can do to an unfiltered syslog daemon should be fairly -obvious; trimming the conf file can help protect against it. Many routers out -there still blindly believe what they receive via RIP and other routing -protocols. Although most UDP echo and chargen servers check if an incoming -packet was sent from *another* "internal" UDP server, there are many that still -do not, any two of which [or many, for that matter] could keep each other -entertained for hours at the expense of bandwidth. And you can always make -someone wonder why she's being probed by nsa.gov. - -Your TCP spoofing possibilities are mostly limited to destinations you can -source-route to while locally bound to your phony address. Many sites block -source-routed packets these days for precisely this reason. If your kernel -does oddball things when sending source-routed packets, try moving the pointer -around with -G. You may also have to fiddle with the routing on your own -machine before you start receiving packets back. Warning: some machines still -send out traffic using the source address of the outbound interface, regardless -of your binding, especially in the case of localhost. Check first. If you can -open a connection but then get no data back from it, the target host is -probably killing the IP options on its end [this is an option inside TCP -wrappers and several other packages], which happens after the 3-way handshake -is completed. If you send some data and observe the "send-q" side of "netstat" -for that connection increasing but never getting sent, that's another symptom. -Beware: if Sendmail 8.7.x detects a source-routed SMTP connection, it extracts -the hop list and sticks it in the Received: header! - -SYN bombing [sometimes called "hosing"] can disable many TCP servers, and if -you hit one often enough, you can keep it unreachable for days. As is true of -many other denial-of-service attacks, there is currently no defense against it -except maybe at the human level. Making kernel SOMAXCONN considerably larger -than the default and the half-open timeout smaller can help, and indeed some -people running large high-performance web servers have *had* to do that just to -handle normal traffic. Taking out mailers and web servers is sociopathic, but -on the other hand it is sometimes useful to be able to, say, disable a site's -identd daemon for a few minutes. If someone realizes what is going on, -backtracing will still be difficult since the packets have a phony source -address, but calls to enough ISP NOCs might eventually pinpoint the source. -It is also trivial for a clueful ISP to watch for or even block outgoing -packets with obviously fake source addresses, but as we know many of them are -not clueful or willing to get involved in such hassles. Besides, outbound -packets with an [otherwise unreachable] source address in one of their net -blocks would look fairly legitimate. - -Notes -===== - -A discussion of various caveats, subtleties, and the design of the innards. - -As of version 1.07 you can construct a single file containing command arguments -and then some data to transfer. Netcat is now smart enough to pick out the -first line and build the argument list, and send any remaining data across the -net to one or multiple ports. The first release of netcat had trouble with -this -- it called fgets() for the command line argument, which behind the -scenes does a large read() from standard input, perhaps 4096 bytes or so, and -feeds that out to the fgets() library routine. By the time netcat 1.00 started -directly read()ing stdin for more data, 4096 bytes of it were gone. It now -uses raw read() everywhere and does the right thing whether reading from files, -pipes, or ttys. If you use this for multiple-port connections, the single -block of data will now be a maximum of 8K minus the first line. Improvements -have been made to the logic in sending the saved chunk to each new port. Note -that any command-line arguments hidden using this mechanism could still be -extracted from a core dump. - -When netcat receives an inbound UDP connection, it creates a "connected socket" -back to the source of the connection so that it can also send out data using -normal write(). Using this mechanism instead of recvfrom/sendto has several -advantages -- the read/write select loop is simplified, and ICMP errors can in -effect be received by non-root users. However, it has the subtle side effect -that if further UDP packets arrive from the caller but from different source -ports, the listener will not receive them. UDP listen mode on a multihomed -machine may have similar quirks unless you specifically bind to one of its -addresses. It is not clear that kernel support for UDP connected sockets -and/or my understanding of it is entirely complete here, so experiment... - -You should be aware of some subtleties concerning UDP scanning. If -z is on, -netcat attempts to send a single null byte to the target port, twice, with a -small time in between. You can either use the -w timeout, or netcat will try -to make a "sideline" TCP connection to the target to introduce a small time -delay equal to the round-trip time between you and the target. Note that if -you have a -w timeout and -i timeout set, BOTH take effect and you wait twice -as long. The TCP connection is to a normally refused port to minimize traffic, -but if you notice a UDP fast-scan taking somewhat longer than it should, it -could be that the target is actually listening on the TCP port. Either way, -any ICMP port-unreachable messages from the target should have arrived in the -meantime. The second single-byte UDP probe is then sent. Under BSD kernels, -the ICMP error is delivered to the "connected socket" and the second write -returns an error, which tells netcat that there is NOT a UDP service there. -While Linux seems to be a fortunate exception, under many SYSV derived kernels -the ICMP is not delivered, and netcat starts reporting that *all* the ports are -"open" -- clearly wrong. [Some systems may not even *have* the "udp connected -socket" concept, and netcat in its current form will not work for UDP at all.] -If -z is specified and only one UDP port is probed, netcat's exit status -reflects whether the connection was "open" or "refused" as with TCP. - -It may also be that UDP packets are being blocked by filters with no ICMP error -returns, in which case everything will time out and return "open". This all -sounds backwards, but that's how UDP works. If you're not sure, try "echo -w00gumz | nc -u -w 2 target 7" to see if you can reach its UDP echo port at -all. You should have no trouble using a BSD-flavor system to scan for UDP -around your own network, although flooding a target with the high activity that --z generates will cause it to occasionally drop packets and indicate false -"opens". A more "correct" way to do this is collect and analyze the ICMP -errors, as does SATAN's "udp_scan" backend, but then again there's no guarantee -that the ICMP gets back to you either. Udp_scan also does the zero-byte -probes but is excruciatingly careful to calculate its own round-trip timing -average and dynamically set its own response timeouts along with decoding any -ICMP received. Netcat uses a much sleazier method which is nonetheless quite -effective. Cisco routers are known to have a "dead time" in between ICMP -responses about unreachable UDP ports, so a fast scan of a cisco will show -almost everything "open". If you are looking for a specific UDP service, you -can construct a file containing the right bytes to trigger a response from the -other end and send that as standard input. Netcat will read up to 8K of the -file and send the same data to every UDP port given. Note that you must use a -timeout in this case [as would any other UDP client application] since the -two-write probe only happens if -z is specified. - -Many telnet servers insist on a specific set of option negotiations before -presenting a login banner. On a raw connection you will see this as small -amount of binary gook. My attempts to create fixed input bytes to make a -telnetd happy worked some places but failed against newer BSD-flavor ones, -possibly due to timing problems, but there are a couple of much better -workarounds. First, compile with -DTELNET and use -t if you just want to get -past the option negotiation and talk to something on a telnet port. You will -still see the binary gook -- in fact you'll see a lot more of it as the options -are responded to behind the scenes. The telnet responder does NOT update the -total byte count, or show up in the hex dump -- it just responds negatively to -any options read from the incoming data stream. If you want to use a normal -full-blown telnet to get to something but also want some of netcat's features -involved like settable ports or timeouts, construct a tiny "foo" script: - - #! /bin/sh - exec nc -otheroptions targethost 23 - -and then do - - nc -l -p someport -e foo localhost & - telnet localhost someport - -and your telnet should connect transparently through the exec'ed netcat to -the target, using whatever options you supplied in the "foo" script. Don't -use -t inside the script, or you'll wind up sending *two* option responses. - -I've observed inconsistent behavior under some Linuxes [perhaps just older -ones?] when binding in listen mode. Sometimes netcat binds only to "localhost" -if invoked with no address or port arguments, and sometimes it is unable to -bind to a specific address for listening if something else is already listening -on "any". The former problem can be worked around by specifying "-s 0.0.0.0", -which will do the right thing despite netcat claiming that it's listening on -[127.0.0.1]. This is a known problem -- for example, there's a mention of it -in the makefile for SOCKS. On the flip side, binding to localhost and sending -packets to some other machine doesn't work as you'd expect -- they go out with -the source address of the sending interface instead. The Linux kernel contains -a specific check to ensure that packets from 127.0.0.1 are never sent to the -wire; other kernels may contain similar code. Linux, of course, *still* -doesn't support source-routing, but they claim that it and many other network -improvements are at least breathing hard. - -There are several possible errors associated with making TCP connections, but -to specifically see anything other than "refused", one must wait the full -kernel-defined timeout for a connection to fail. Netcat's mechanism of -wrapping an alarm timer around the connect prevents the *real* network error -from being returned -- "errno" at that point indicates "interrupted system -call" since the connect attempt was interrupted. Some old 4.3 BSD kernels -would actually return things like "host unreachable" immediately if that was -the case, but most newer kernels seem to wait the full timeout and *then* pass -back the real error. Go figure. In this case, I'd argue that the old way was -better, despite those same kernels generally being the ones that tear down -*established* TCP connections when ICMP-bombed. - -Incoming socket options are passed to applications by the kernel in the -kernel's own internal format. The socket-options structure for source-routing -contains the "first-hop" IP address first, followed by the rest of the real -options list. The kernel uses this as is when sending reply packets -- the -structure is therefore designed to be more useful to the kernel than to humans, -but the hex dump of it that netcat produces is still useful to have. - -Kernels treat source-routing options somewhat oddly, but it sort of makes sense -once one understands what's going on internally. The options list of addresses -must contain hop1, hop2, ..., destination. When a source-routed packet is sent -by the kernel [at least BSD], the actual destination address becomes irrelevant -because it is replaced with "hop1", "hop1" is removed from the options list, -and all the other addresses in the list are shifted up to fill the hole. Thus -the outbound packet is sent from your chosen source address to the first -*gateway*, and the options list now contains hop2, ..., destination. During -all this address shuffling, the kernel does NOT change the pointer value, which -is why it is useful to be able to set the pointer yourself -- you can construct -some really bizarre return paths, and send your traffic fairly directly to the -target but around some larger loop on the way back. Some Sun kernels seem to -never flip the source-route around if it contains less than three hops, never -reset the pointer anyway, and tries to send the packet [with options containing -a "completed" source route!!] directly back to the source. This is way broken, -of course. [Maybe ipforwarding has to be on? I haven't had an opportunity to -beat on it thoroughly yet.] - -"Credits" section: The original idea for netcat fell out of a long-standing -desire and fruitless search for a tool resembling it and having the same -features. After reading some other network code and realizing just how many -cool things about sockets could be controlled by the calling user, I started -on the basics and the rest fell together pretty quickly. Some port-scanning -ideas were taken from Venema/Farmer's SATAN tool kit, and Pluvius' "pscan" -utility. Healthy amounts of BSD kernel source were perused in an attempt to -dope out socket options and source-route handling; additional help was obtained -from Dave Borman's telnet sources. The select loop is loosely based on fairly -well-known code from "rsh" and Richard Stevens' "sock" program [which itself is -sort of a "netcat" with more obscure features], with some more paranoid -sanity-checking thrown in to guard against the distinct likelihood that there -are subtleties about such things I still don't understand. I found the -argument-hiding method cleanly implemented in Barrett's "deslogin"; reading the -line as input allows greater versatility and is much less prone to cause -bizarre problems than the more common trick of overwriting the argv array. -After the first release, several people contributed portability fixes; they are -credited in generic.h and the Makefile. Lauren Burka inspired the ascii art -for this revised document. Dean Gaudet at Wired supplied a precursor to -the hex-dump code, and mudge@l0pht.com originally experimented with and -supplied code for the telnet-options responder. Outbound "-e <prog>" resulted -from a need to quietly bypass a firewall installation. Other suggestions and -patches have rolled in for which I am always grateful, but there are only 26 -hours per day and a discussion of feature creep near the end of this document. - -Netcat was written with the Russian railroad in mind -- conservatively built -and solid, but it *will* get you there. While the coding style is fairly -"tight", I have attempted to present it cleanly [keeping *my* lines under 80 -characters, dammit] and put in plenty of comments as to why certain things -are done. Items I know to be questionable are clearly marked with "XXX". -Source code was made to be modified, but determining where to start is -difficult with some of the tangles of spaghetti code that are out there. -Here are some of the major points I feel are worth mentioning about netcat's -internal design, whether or not you agree with my approach. - -Except for generic.h, which changes to adapt more platforms, netcat is a single -source file. This has the distinct advantage of only having to include headers -once and not having to re-declare all my functions in a billion different -places. I have attempted to contain all the gross who's-got-what-.h-file -things in one small dumping ground. Functions are placed "dependencies-first", -such that when the compiler runs into the calls later, it already knows the -type and arguments and won't complain. No function prototyping -- not even the -__P(()) crock -- is used, since it is more portable and a file of this size is -easy enough to check manually. Each function has a standard-format comment -ahead of it, which is easily found using the regexp " :$". I freely use gotos. -Loops and if-clauses are made as small and non-nested as possible, and the ends -of same *marked* for clarity [I wish everyone would do this!!]. - -Large structures and buffers are all malloc()ed up on the fly, slightly larger -than the size asked for and zeroed out. This reduces the chances of damage -from those "end of the buffer" fencepost errors or runaway pointers escaping -off the end. These things are permanent per run, so nothing needs to be freed -until the program exits. - -File descriptor zero is always expected to be standard input, even if it is -closed. If a new network descriptor winds up being zero, a different one is -asked for which will be nonzero, and fd zero is simply left kicking around -for the rest of the run. Why? Because everything else assumes that stdin is -always zero and "netfd" is always positive. This may seem silly, but it was a -lot easier to code. The new fd is obtained directly as a new socket, because -trying to simply dup() a new fd broke subsequent socket-style use of the new fd -under Solaris' stupid streams handling in the socket library. - -The catch-all message and error handlers are implemented with an ample list of -phoney arguments to get around various problems with varargs. Varargs seems -like deliberate obfuscation in the first place, and using it would also -require use of vfprintf() which not all platforms support. The trailing -sleep in bail() is to allow output to flush, which is sometimes needed if -netcat is already on the other end of a network connection. - -The reader may notice that the section that does DNS lookups seems much -gnarlier and more confusing than other parts. This is NOT MY FAULT. The -sockaddr and hostent abstractions are an abortion that forces the coder to -deal with it. Then again, a lot of BSD kernel code looks like similar -struct-pointer hell. I try to straighten it out somewhat by defining my own -HINF structure, containing names, ascii-format IP addresses, and binary IP -addresses. I fill this structure exactly once per host argument, and squirrel -everything safely away and handy for whatever wants to reference it later. - -Where many other network apps use the FIONBIO ioctl to set non-blocking I/O -on network sockets, netcat uses straightforward blocking I/O everywhere. -This makes everything very lock-step, relying on the network and filesystem -layers to feed in data when needed. Data read in is completely written out -before any more is fetched. This may not be quite the right thing to do under -some OSes that don't do timed select() right, but this remains to be seen. - -The hexdump routine is written to be as fast as possible, which is why it does -so much work itself instead of just sprintf()ing everything together. Each -dump line is built into a single buffer and atomically written out using the -lowest level I/O calls. Further improvements could undoubtedly be made by -using writev() and eliminating all sprintf()s, but it seems to fly right along -as is. If both exec-a-prog mode and a hexdump file is asked for, the hexdump -flag is deliberately turned off to avoid creating random zero-length files. -Files are opened in "truncate" mode; if you want "append" mode instead, change -the open flags in main(). - -main() may look a bit hairy, but that's only because it has to go down the -argv list and handle multiple ports, random mode, and exit status. Efforts -have been made to place a minimum of code inside the getopt() loop. Any real -work is sent off to functions in what is hopefully a straightforward way. - -Obligatory vendor-bash: If "nc" had become a standard utility years ago, -the commercial vendors would have likely packaged it setuid root and with --DGAPING_SECURITY_HOLE turned on but not documented. It is hoped that netcat -will aid people in finding and fixing the no-brainer holes of this sort that -keep appearing, by allowing easier experimentation with the "bare metal" of -the network layer. - -It could be argued that netcat already has too many features. I have tried -to avoid "feature creep" by limiting netcat's base functionality only to those -things which are truly relevant to making network connections and the everyday -associated DNS lossage we're used to. Option switches already have slightly -overloaded functionality. Random port mode is sort of pushing it. The -hex-dump feature went in later because it *is* genuinely useful. The -telnet-responder code *almost* verges on the gratuitous, especially since it -mucks with the data stream, and is left as an optional piece. Many people have -asked for example "how 'bout adding encryption?" and my response is that such -things should be separate entities that could pipe their data *through* netcat -instead of having their own networking code. I am therefore not completely -enthusiastic about adding any more features to this thing, although you are -still free to send along any mods you think are useful. - -Nonetheless, at this point I think of netcat as my tcp/ip swiss army knife, -and the numerous companion programs and scripts to go with it as duct tape. -Duct tape of course has a light side and a dark side and binds the universe -together, and if I wrap enough of it around what I'm trying to accomplish, -it *will* work. Alternatively, if netcat is a large hammer, there are many -network protocols that are increasingly looking like nails by now... - -_H* 960320 v1.10 RELEASE -- happy spring! diff --git a/atomicio.c b/atomicio.c new file mode 100644 index 0000000..feb6f19 --- /dev/null +++ b/atomicio.c @@ -0,0 +1,69 @@ +/* $OpenBSD: atomicio.c,v 1.10 2011/01/08 00:47:19 jeremy Exp $ */ +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 2005 Anil Madhavapeddy. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#include <sys/param.h> + +#include <errno.h> +#include <poll.h> +#include <unistd.h> + +#include "atomicio.h" + +/* + * ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t +atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n) +{ + char *s = _s; + size_t pos = 0; + ssize_t res; + struct pollfd pfd; + + pfd.fd = fd; + pfd.events = f == read ? POLLIN : POLLOUT; + while (n > pos) { + res = (f) (fd, s + pos, n - pos); + switch (res) { + case -1: + if (errno == EINTR) + continue; + if ((errno == EAGAIN) || (errno == ENOBUFS)) { + (void)poll(&pfd, 1, -1); + continue; + } + return 0; + case 0: + errno = EPIPE; + return pos; + default: + pos += (size_t)res; + } + } + return (pos); +} diff --git a/atomicio.h b/atomicio.h new file mode 100644 index 0000000..7bf5b25 --- /dev/null +++ b/atomicio.h @@ -0,0 +1,39 @@ +/* $OpenBSD: atomicio.h,v 1.2 2007/09/07 14:50:44 tobias Exp $ */ + +/* + * Copyright (c) 2006 Damien Miller. All rights reserved. + * Copyright (c) 1995,1999 Theo de Raadt. All rights reserved. + * 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _ATOMICIO_H +#define _ATOMICIO_H + +/* + * Ensure all of data on socket comes through. f==read || f==vwrite + */ +size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t); + +#define vwrite (ssize_t (*)(int, void *, size_t))write + +#endif /* _ATOMICIO_H */ diff --git a/data/Makefile b/data/Makefile deleted file mode 100644 index 65cf185..0000000 --- a/data/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -all: data rservice xor - -data: data.c - cc -s -O -o data data.c -rservice: rservice.c - cc -s -O -o rservice rservice.c -xor: xor.c - cc -s -O -o xor xor.c -clean: - rm -f *.o data rservice xor diff --git a/data/README b/data/README deleted file mode 100644 index 7e4b9fb..0000000 --- a/data/README +++ /dev/null @@ -1,9 +0,0 @@ -For now, read the header comments inside each of these for documentation. -The programs are simple enough that they don't really need a Makefile any more -complex than the one given; ymmv. Data and xor may also be useful on DOS, -which is why there are hooks for it in the code. - -data.c a primitive atob / btoa byte generator -*.d example input to "data -g" -rservice.c a utility for scripting up rsh/rexec attacks -xor.c generic xor handler diff --git a/data/data.c b/data/data.c deleted file mode 100644 index 56c167f..0000000 --- a/data/data.c +++ /dev/null @@ -1,274 +0,0 @@ -/* primitive arbitrary-data frontend for netcat. 0.9 960226 - only handles one value per ascii line, but at least parses 0xNN too - an input line containing "%r" during "-g" generates a random byte - - todo: - make work on msloss jus' for kicks [workin' on it...] - - syntax: data -X [limit] - where X is one of - d: dump raw bytes to ascii format - g: generate raw bytes from ascii input - c: generate ??? of value -- NOTYET - r: generate all random bytes - and limit is how many bytes to generate or dump [unspecified = infinite] - - *Hobbit*, started 951004 or so and randomly screwed around with since */ - -#include <stdio.h> - -#ifdef MSDOS /* for MSC only at the moment... */ -#include <fcntl.h> -#else /* MSDOS */ -#include <sys/file.h> -#define HAVE_RANDOM /* XXX: might have to change */ -#endif /* MSDOS */ - -static char buf_in [128]; -static char buf_raw [8192]; -static char surveysez[] = "survey sez... XXX\n"; - -/* fgetss : - wrapper for fgets, that yanks trailing newlines. Doing the work ourselves - instead of calling strchr/strlen/whatever */ -char * fgetss (buf, len, from) - char * buf; - size_t len; - FILE * from; -{ - register int x; - register char * p, * q; - p = fgets (buf, len, from); /* returns ptr to buf */ - if (! p) - return (NULL); - q = p; - for (x = 0; x < len; x++) { - *p = (*p & 0x7f); /* rip parity, just in case */ - switch (*p) { - case '\n': - case '\r': - case '\0': - *p = '\0'; - return (q); - } /* switch */ - p++; - } /* for */ -} /* fgetss */ - -/* randint: - swiped from rndb.c. Generates an INT, you have to mask down to char. */ -int randint() -{ - register int q; - register int x; - -#ifndef HAVE_RANDOM - q = rand(); -#else - q = random(); -#endif - x = ((q >> 8) & 0xff); /* perturb low byte using some higher bits */ - x = q ^ x; - return (x); -} - -main (argc, argv) - int argc; - char ** argv; -{ - register unsigned char * p; - register char * q; - register int x; - int bc = 0; - int limit = 0; /* num to gen, or 0 = infinite */ - register int xlimit; /* running limit */ - FILE * txt; /* line-by-line ascii file */ - int raw; /* raw bytes fd */ - int dumping = 0; /* cmd flags ... */ - int genning = 0; - int randing = 0; - - memset (buf_in, 0, sizeof (buf_in)); - memset (buf_raw, 0, sizeof (buf_raw)); - - xlimit = 1; /* doubles as "exit flag" */ - bc = 1; /* preload, assuming "dump" */ - x = getpid() + 687319; -/* if your library doesnt have srandom/random, use srand/rand. [from rnd.c] */ -#ifndef HAVE_RANDOM - srand (time(0) + x); -#else - srandom (time(0) + x); -#endif - -#ifdef O_BINARY -/* DOS stupidity */ -/* Aha: *here's* where that setmode() lib call conflict in ?BSD came from */ - x = setmode (0, O_BINARY); /* make stdin raw */ - if (x < 0) { - fprintf (stderr, "stdin binary setmode oops: %d\n", x); - exit (1); - } - x = setmode (1, O_BINARY); /* make stdout raw */ - if (x < 0) { - fprintf (stderr, "stdout binary setmode oops: %d\n", x); - exit (1); - } -#endif /* O_BINARY */ - - if (argv[1]) { - p = argv[1]; /* shit-simple single arg parser... */ - if (*p == '-') /* dash is optional, we'll deal */ - p++; - if (*p == 'd') - dumping++; - if (*p == 'g') - genning++; - if (*p == 'r') - randing++; - } /* if argv 1 */ - -/* optional second argument: limit # of bytes shoveled either way */ - if (argv[2]) { - x = atoi (argv[2]); - if (x) - limit = x; - else - goto wrong; - xlimit = limit; - } - -/* Since this prog would likely best be written in assmbler, I'm gonna - write it *like* assembler. So there. */ - - if (randing) - goto do_rand; - -nextbuf: /* loop sleaze */ - - if (dumping) { /* switch off to wherever */ - if (genning) - goto wrong; - goto do_dump; - } - if (genning) - goto do_gen; -wrong: - fprintf (stderr, surveysez); /* if both or neither */ - exit (1); - -do_gen: -/* here if genning -- original functionality */ - q = buf_raw; - bc = 0; -/* suck up lines until eof or buf_raw is full */ - while (1) { - p = fgetss (buf_in, 120, stdin); - if (! p) - break; /* EOF */ -/* super-primitive version first: one thingie per line */ - if (*p == '#') /* comment */ - continue; - if (*p == '\0') /* blank line */ - continue; - if (*p == '%') { /* escape char? */ - p++; - if (*p == 'r') { /* random byte */ - x = randint(); - goto stuff; - } /* %r */ - } /* if "%" escape */ - if (*p == '0') - if (*(p+1) == 'x') /* 0x?? */ - goto hex; - x = atoi (p); /* reg'lar decimal number */ - goto stuff; - -hex: -/* A 65 a 97 */ -/* xxx: use a conversion table for this or something. Since we ripped the - parity bit, we only need a preset array of 128 with downconversion factors - loaded in *once*. maybe look at scanf... */ - p++; p++; /* point at hex-chars */ - x = 0; - if ((*p > 96) && (*p < 123)) /* a-z */ - *p = (*p - 32); /* this is massively clumsy */ - if ((*p > 64) && (*p < 71)) /* A-F */ - x = (*p - 55); - if ((*p > 47) && (*p < 58)) /* digits */ - x = (*p - 48); - p++; - if (*p) /* another digit? */ - x = (x << 4); /* shift to hi half */ - if ((*p > 96) && (*p < 123)) /* a-z */ - *p = (*p - 32); - if ((*p > 64) && (*p < 71)) /* A-F */ - x = (x | (*p - 55)); /* lo half */ - if ((*p > 47) && (*p < 58)) /* digits */ - x = (x | (*p - 48)); - -/* fall thru */ -stuff: /* cvt to byte and add to buffer */ - *q = (x & 0xff); - q++; - bc++; - if (limit) { - xlimit--; - if (xlimit == 0) /* max num reached */ - break; - } /* limit */ - if (bc >= sizeof (buf_raw)) /* buffer full */ - break; - } /* while 1 */ - -/* now in theory we have our buffer formed; shovel it out */ - x = write (1, buf_raw, bc); - if (x <= 0) { - fprintf (stderr, "write oops: %d\n", x); - exit (1); - } - if (xlimit && p) - goto nextbuf; /* go get some more */ - exit (0); - -do_dump: -/* here if dumping raw stuff into an ascii file */ -/* gad, this is *so* much simpler! can we say "don't rewrite printf"? */ - x = read (0, buf_raw, 8192); - if (x <= 0) - exit (0); - q = buf_raw; - for ( ; x > 0; x--) { - p = q; - printf ("%-3.3d # 0x%-2.2x # ", *p, *p); - if ((*p > 31) && (*p < 127)) - printf ("%c %d\n", *p, bc); - else - printf (". %d\n", bc); - q++; - bc++; - if (limit) { - xlimit--; - if (xlimit == 0) { - fflush (stdout); - exit (0); - } - } /* limit */ - } /* for */ - goto nextbuf; - -do_rand: -/* here if generating all-random bytes. Stays in this loop */ - p = buf_raw; - while (1) { - *p = (randint() & 0xff); - write (1, p, 1); /* makes very slow! */ - if (limit) { - xlimit--; - if (xlimit == 0) - break; - } - } /* while */ - exit (0); - -} /* main */ diff --git a/data/dns-any.d b/data/dns-any.d deleted file mode 100644 index 77b014c..0000000 --- a/data/dns-any.d +++ /dev/null @@ -1,36 +0,0 @@ -# dns "any for ." query, to udp 53 -# if tcp: precede with 2 bytes of len: -# 0 -# 17 -# you should get at least *one* record back out - -# HEADER: -0 # query id = 2 -2 - -1 # flags/opcodes = query, dorecurse -0 - -0 # qdcount, i.e. nqueries: 1 -1 - -0 # ancount: answers, 0 -0 - -0 # nscount: 0 -0 - -0 # addl records: 0 -0 - -# end of fixed header - -0 # name-len: 0 for ".", lenbyte plus name-bytes otherwise - -0 # type: any, 255 -0xff - -0 # class: IN -1 - -# i think that's it.. diff --git a/data/nfs-0.d b/data/nfs-0.d deleted file mode 100644 index 0360938..0000000 --- a/data/nfs-0.d +++ /dev/null @@ -1,59 +0,0 @@ -# UDP NFS null-proc call; finds active NFS listeners on port 2049. -# If you get *something* back, there's an NFS server there. - -000 # XID: 4 trash bytes -001 -002 -003 - -000 # CALL: 0 -000 -000 -000 - -000 # RPC version: 2 -000 -000 -002 - -000 # nfs: 100003 -001 -0x86 -0xa3 - -000 # version: 1 -000 -000 -001 - -000 # procedure number: 0 -000 -000 -000 - -000 # port: junk -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # extra auth trash? probably not needed -000 -000 -000 - -# that's it! diff --git a/data/pm.d b/data/pm.d deleted file mode 100644 index fe32769..0000000 --- a/data/pm.d +++ /dev/null @@ -1,8 +0,0 @@ -# obligatory duplicate of dr delete's Livingston portmaster crash, aka -# telnet break. Fire into its telnet listener. An *old* bug by now, but -# consider the small window one might obtain from a slightly out-of-rev PM -# used as a firewall, that starts routing IP traffic BEFORE its filter sets -# are fully loaded... - -255 # 0xff # . 1 -243 # 0xf3 # . 2 diff --git a/data/pmap-dump.d b/data/pmap-dump.d deleted file mode 100644 index bc6b632..0000000 --- a/data/pmap-dump.d +++ /dev/null @@ -1,60 +0,0 @@ -# portmap dump request: like "rpcinfo -p" but via UDP instead -# send to UDP 111 and hope it's not a logging portmapper! -# split into longwords, since rpc apparently only deals with them - -001 # 0x01 # . # XID: 4 trash bytes -002 # 0x02 # . -003 # 0x03 # . -004 # 0x04 # . - -000 # 0x00 # . # MSG: int 0=call, 1=reply -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # pmap call body: rpc version=2 -000 # 0x00 # . -000 # 0x00 # . -002 # 0x02 # . - -000 # 0x00 # . # pmap call body: prog=PMAP, 100000 -001 # 0x01 # . -134 # 0x86 # . -160 # 0xa0 # . - -000 # 0x00 # . # pmap call body: progversion=2 -000 # 0x00 # . -000 # 0x00 # . -002 # 0x02 # . - -000 # 0x00 # . # pmap call body: proc=DUMP, 4 -000 # 0x00 # . -000 # 0x00 # . -004 # 0x04 # . - -# with AUTH_NONE, there are 4 zero integers [16 bytes] here - -000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0 -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -# The reply you get back contains your XID, int 1 if "accepted", and -# a whole mess of gobbledygook containing program numbers, versions, -# and ports that rpcinfo knows how to decode. For the moment, you get -# to wade through it yourself... diff --git a/data/pmap-mnt.d b/data/pmap-mnt.d deleted file mode 100644 index 00588ba..0000000 --- a/data/pmap-mnt.d +++ /dev/null @@ -1,78 +0,0 @@ -# portmap request for mountd [or whatever; see where prog=MOUNT] -# send to UDP 111 and hope it's not a logging portmapper! -# split into longwords, since rpc apparently only deals with them - -001 # 0x01 # . # XID: 4 trash bytes -002 # 0x02 # . -003 # 0x03 # . -004 # 0x04 # . - -000 # 0x00 # . # MSG: int 0=call, 1=reply -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # pmap call body: rpc version=2 -000 # 0x00 # . -000 # 0x00 # . -002 # 0x02 # . - -000 # 0x00 # . # pmap call body: prog=PMAP, 100000 -001 # 0x01 # . -134 # 0x86 # . -160 # 0xa0 # . - -000 # 0x00 # . # pmap call body: progversion=2 -000 # 0x00 # . -000 # 0x00 # . -002 # 0x02 # . - -000 # 0x00 # . # pmap call body: proc=GETPORT, 3 -000 # 0x00 # . -000 # 0x00 # . -003 # 0x03 # . - -# with AUTH_NONE, there are 4 zero integers [16 bytes] here - -000 # 0x00 # . # auth junk: cb_cred: auth_unix = 1; NONE = 0 -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # auth junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -000 # 0x00 # . # prog=MOUNT, 100005 -001 # 0x01 # . -134 # 0x86 # . -165 # 0xa5 # . - -000 # 0x00 # . # progversion=1 -000 # 0x00 # . -000 # 0x00 # . -001 # 0x01 # . - -000 # 0x00 # . # protocol=udp, 17 -000 # 0x00 # . -000 # 0x00 # . -017 # 0x11 # . - -000 # 0x00 # . # proc num = junk -000 # 0x00 # . -000 # 0x00 # . -000 # 0x00 # . - -# The reply you get back contains your XID, int 1 if "accepted", and -# mountd's port number at the end or 0 if not registered. diff --git a/data/rip.d b/data/rip.d deleted file mode 100644 index da505e2..0000000 --- a/data/rip.d +++ /dev/null @@ -1,52 +0,0 @@ -# struct netinfo { -# struct sockaddr rip_dst; /* destination net/host */ -# int rip_metric; /* cost of route */ -# }; -# struct rip { -# u_char rip_cmd; /* request/response */ -# u_char rip_vers; /* protocol version # */ -# u_char rip_res1[2]; /* pad to 32-bit boundary */ -# union { -# struct netinfo ru_nets[1]; /* variable length... */ -# char ru_tracefile[1]; /* ditto ... */ -# } ripun; -#define rip_nets ripun.ru_nets -#define rip_tracefile ripun.ru_tracefile -#define RIPCMD_REQUEST 1 /* want info */ -#define RIPCMD_RESPONSE 2 /* responding to request */ -#define RIPCMD_TRACEON 3 /* turn tracing on */ -#define RIPCMD_TRACEOFF 4 /* turn it off */ -#define HOPCNT_INFINITY 16 /* per Xerox NS */ -#define MAXPACKETSIZE 512 /* max broadcast size */ - -### RIP packet redux -### UDP send FROM clued-rtr/520 to target/520 -2 # RIPCMD_RESPONSE -1 # version -0 # padding -0 - -# sockaddr-plus-metric structs begin, as many as necessary... -0 # len -2 # AF_INET -0 # port -0 -# addr bytes: -X -Y -Z -Q -0 # filler, out to 16 bytes [sizeof (sockaddr)] ... -0 -0 -0 -0 -0 -0 -0 -0 # metric: net-order integer -0 -0 -1 - -## that's it diff --git a/data/rservice.c b/data/rservice.c deleted file mode 100644 index 1085d9c..0000000 --- a/data/rservice.c +++ /dev/null @@ -1,68 +0,0 @@ -/* generate ^@string1^@string2^@cmd^@ input to netcat, for scripting up - rsh/rexec attacks. Needs to be a prog because shells strip out nulls. - - args: - locuser remuser [cmd] - remuser passwd [cmd] - - cmd defaults to "pwd". - - ... whatever. _H*/ - -#include <stdio.h> - -/* change if you like; "id" is a good one for figuring out if you won too */ -static char cmd[] = "pwd"; - -static char buf [256]; - -main(argc, argv) - int argc; - char * argv[]; -{ - register int x; - register int y; - char * p; - char * q; - - p = buf; - memset (buf, 0, 256); - - p++; /* first null */ - y = 1; - - if (! argv[1]) - goto wrong; - x = strlen (argv[1]); - memcpy (p, argv[1], x); /* first arg plus another null */ - x++; - p += x; - y += x; - - if (! argv[2]) - goto wrong; - x = strlen (argv[2]); - memcpy (p, argv[2], x); /* second arg plus null */ - x++; - p += x; - y += x; - - q = cmd; - if (argv[3]) - q = argv[3]; - x = strlen (q); /* not checked -- bfd */ - memcpy (p, q, x); /* the command, plus final null */ - x++; - p += x; - y += x; - - memcpy (p, "\n", 1); /* and a newline, so it goes */ - y++; - - write (1, buf, y); /* zot! */ - exit (0); - -wrong: - fprintf (stderr, "wrong! needs 2 or more args.\n"); - exit (1); -} diff --git a/data/showmount.d b/data/showmount.d deleted file mode 100644 index 499794b..0000000 --- a/data/showmount.d +++ /dev/null @@ -1,63 +0,0 @@ -# UDP mountd call. Use as input to find mount daemons and avoid portmap. -# Useful proc numbers are 2, 5, and 6. -# UDP-scan around between 600-800 to find most mount daemons. -# Using this with "2", plugged into "nc -u -v -w 2 victim X-Y" will -# directly scan *and* dump the current exports when mountd is hit. -# combine stdout *and* stderr thru "strings" or something to clean it up - -000 # XID: 4 trash bytes -001 -002 -003 - -000 # CALL: 0 -000 -000 -000 - -000 # RPC version: 2 -000 -000 -002 - -000 # mount: 100005 -001 -0x86 -0xa5 - -000 # mount version: 1 -000 -000 -001 - -000 # procedure number -- put what you need here: -000 # 2 = dump [showmount -e] -000 # 5 = exportlist [showmount -a] -xxx # "sed s/xxx/$1/ | data -g | nc ..." or some such... - -000 # port: junk -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # auth trash -000 -000 -000 - -000 # extra auth trash? probably not needed -000 -000 -000 - -# that's it! diff --git a/data/xor.c b/data/xor.c deleted file mode 100644 index 9feead0..0000000 --- a/data/xor.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Generic xor handler. - - With no args, xors stdin against 0xFF to stdout. A single argument is a - file to read xor-bytes out of. Any zero in the xor-bytes array is treated - as the end; if you need to xor against a string that *includes* zeros, - you're on your own. - - The indirect file can be generated easily with data.c. - - Written because there are so many lame schemes for "masking" plaintext - passwords and the like floating around, and it's handy to just run an - obscure binary-format configuration file through this and look for strings. - - *Hobbit*, 960208 */ - -#include <stdio.h> -#include <fcntl.h> - -char buf[8192]; -char bytes[256]; -char * py; - -/* do the xor, in place. Uses global ptr "py" to maintain "bytes" state */ -xorb (buf, len) - char * buf; - int len; -{ - register int x; - register char * pb; - - pb = buf; - x = len; - while (x > 0) { - *pb = (*pb ^ *py); - pb++; - py++; - if (! *py) - py = bytes; - x--; - } -} /* xorb */ - -/* blah */ -main (argc, argv) - int argc; - char ** argv; -{ - register int x = 0; - register int y; - -/* manually preload; xor-with-0xFF is all too common */ - memset (bytes, 0, sizeof (bytes)); - bytes[0] = 0xff; - -/* if file named in any arg, reload from that */ -#ifdef O_BINARY /* DOS shit... */ - x = setmode (0, O_BINARY); /* make stdin raw */ - if (x < 0) { - fprintf (stderr, "stdin binary setmode oops: %d\n", x); - exit (1); - } - x = setmode (1, O_BINARY); /* make stdout raw */ - if (x < 0) { - fprintf (stderr, "stdout binary setmode oops: %d\n", x); - exit (1); - } -#endif /* O_BINARY */ - - if (argv[1]) -#ifdef O_BINARY - x = open (argv[1], O_RDONLY | O_BINARY); -#else - x = open (argv[1], O_RDONLY); -#endif - if (x > 0) { - read (x, bytes, 250); /* nothin' fancy here */ - close (x); - } - py = bytes; - x = 1; - while (x > 0) { - x = read (0, buf, sizeof (buf)); - if (x <= 0) - break; - xorb (buf, x); - y = write (1, buf, x); - if (y <= 0) - exit (1); - } - exit (0); -} - diff --git a/generic.h b/generic.h deleted file mode 100644 index b3dd5f5..0000000 --- a/generic.h +++ /dev/null @@ -1,377 +0,0 @@ -/* generic.h -- anything you don't #undef at the end remains in effect. - The ONLY things that go in here are generic indicator flags; it's up - to your programs to declare and call things based on those flags. - - You should only need to make changes via a minimal system-specific section - at the end of this file. To build a new section, rip through this and - check everything it mentions on your platform, and #undef that which needs - it. If you generate a system-specific section you didn't find in here, - please mail me a copy so I can update the "master". - - I realize I'm probably inventing another pseudo-standard here, but - goddamnit, everybody ELSE has already, and I can't include all of their - hairball schemes too. HAVE_xx conforms to the gnu/autoconf usage and - seems to be the most common format. In fact, I dug a lot of these out - of autoconf and tried to common them all together using "stupidh" to - collect data from platforms. - - In disgust... _H* 940910, 941115, 950511. Pseudo-version: 1.3 - - Updated 951104 with many patches from netcat feedback, and properly - closed a lot of slop in open-ended comments: version 1.4 - 960217 + nextstep: version 1.5 -*/ - -#ifndef GENERIC_H /* only run through this once */ -#define GENERIC_H - -/* =============================== */ -/* System calls, lib routines, etc */ -/* =============================== */ - -/* How does your system declare malloc, void or char? Usually void, but go - ask the SunOS people why they had to be different... */ -#define VOID_MALLOC - -/* notably from fwtk/firewall.h: posix locking? */ -#define HAVE_FLOCK /* otherwise it's lockf() */ - -/* if you don't have setsid(), you might have setpgrp(). */ -#define HAVE_SETSID - -/* random() is generally considered better than rand() */ -#define HAVE_RANDOM - -/* the srand48/lrand48/etc family is s'posedly even better */ -#define HAVE_RAND48 -/* bmc@telebase and others have suggested these macros if a box *does* have - rand48. Will consider for later if we're doing something that really - requires stronger random numbers, but netcat and such certainly doesn't. -#define srandom(seed) srand48((long) seed) -#define random() lrand48() */ - -/* if your machine doesn't have lstat(), it should have stat() [dos...] */ -#define HAVE_LSTAT - -/* different kinds of term ioctls. How to recognize them, very roughly: - sysv/POSIX_ME_HARDER: termio[s].h, struct termio[s], tty.c_*[] - bsd/old stuff: sgtty.h, ioctl(TIOCSETP), sgttyb.sg_*, tchars.t_* */ -#define HAVE_TERMIOS - -/* dbm vs ndbm */ -#define HAVE_NDBM - -/* extended utmp/wtmp stuff. MOST machines still do NOT have this SV-ism */ -#define UTMPX - -/* some systems have nice() which takes *relative* values... [resource.h] */ -#define HAVE_SETPRIORITY - -/* a sysvism, I think, but ... */ -#define HAVE_SYSINFO - -/* ============= */ -/* Include files */ -/* ============= */ - -/* Presence of these can be determined via a script that sniffs them - out if you aren't sure. See "stupidh"... */ - -/* stdlib comes with most modern compilers, but ya never know */ -#define HAVE_STDLIB_H - -/* not on a DOS box! */ -#define HAVE_UNISTD_H - -/* stdarg is a weird one */ -#define HAVE_STDARG_H - -/* dir.h or maybe ndir.h otherwise. */ -#define HAVE_DIRENT_H - -/* string or strings */ -#define HAVE_STRINGS_H - -/* if you don't have lastlog.h, what you want might be in login.h */ -#define HAVE_LASTLOG_H - -/* predefines for _PATH_various */ -#define HAVE_PATHS_H - -/* some SV-flavors break select stuff out separately */ -#define HAVE_SELECT_H - -/* assorted others */ -#define HAVE_PARAM_H /* in sys/ */ -#define HAVE_SYSMACROS_H /* in sys/ */ -#define HAVE_TTYENT_H /* securetty et al */ - -/* ==================== */ - -/* Still maybe have to do something about the following, if it's even - worth it. I just grepped a lot of these out of various code, without - looking them up yet: - -#define HAVE_EINPROGRESS -#define HAVE_F_SETOWN -HAVE_FILIO_H ... fionbio, fiosetown, etc... will need for hairier - select loops. -#define HAVE_SETENV ... now *there's* a hairy one; **environ is portable -#define BIG_ENDIAN/little_endian ... *please* try to avoid this stupidity - and LSBFIRST/MSBFIRST -#define HAVE_GETUSERSHELL ... you could always pull it out of getpwent() -#define HAVE_SETE[UG]ID ... lib or syscall, it varies on diff platforms -#define HAVE_STRCHR ... should actually be handled by string/strings -#define HAVE_PSTAT -#define HAVE_ST_BLKSIZE ... a stat() thing? -#define HAVE_IP_TOS -#define HAVE_STRFTIME ... screw this, we'll just INCLUDE one for lame - old boxes that don't have it [sunos 3.x, early 4.x?] -#define HAVE_VFPRINTF -#define HAVE_SHADOW_PASSWD ... in its multitudinous schemes?? ... how - about sumpin' like #define SHADOW_PASSWD_TYPE ... could get grody. - ... looks like sysv /etc/shadow, getspent() family is common. -#define SIG* ... what a swamp, punt for now; should all be in signal.h -#define HAVE_STRCSPN ... see larry wall's comment in the fwtk regex code -#define ULTRIX_AUTH ... bwahaha. -#define HAVE_YP or NIS or whatever you wanna call it this week -randomness about VARARGS?? ---- later stuff to be considered --- -#define UINT4 ... u-int on alpha/osf, i.e. __alpha/__osf__, ulong elsewhere? - dont name it that, though, it'll conflict with extant .h files like md5 -randomness about machine/endian.h, machine/inline.h -- bsdi, net/2 -randomness about _PATH_WTMP vs WTMP_FILE and where they even live!! -#define HAVE_SYS_ERRLIST ... whether it's in stdio.h or not [bsd 4.4] ---- still more stuff -#define HAVE_SETENV -#define _PATH_UTMP vs UTMP_FILE, a la deslogind?! -#define HAVE_DAEMON -#define HAVE_INETADDR [vixie bind?] -lseek: SEEK_SET vs L_SET and associated lossage [epi-notes, old 386Mach] -bsdi: ioctl_compat.h ? ---- takin' some ifdefs from CNS krb: -F_GETOWN/F_SETOWN -CRAY: long = 8 bytes, etc [class with alpha?] -CGETENT -SIGINFO -SIGTSTP SIGTTOU SIGWINCH -SPX? -SYSV_TERMIO -- covered elsewhere, I hope -TIOCEXT TIOCFLUSH TIOC[GS]WINSIZ -NEWINIT: something about init cleaning up dead login processes [telnet?] -PARENT_DOES_UTMP, too [telnet] -VDISCARD -VEOL/VEOL2/VLNEXT VREPRINT -- termios stuff?, and related... -STREAMSPTY/STREAMSPTYEM -AF_INET/AF_UNSPEC, PF_* -ECHOCTL/ECHOKE -F_ULOCK [?!] -setpgrp/getpgrp() ONEARG business.. -HAVE_ALLOCA -HAVE_GETUTENT -HAVE_SYS_SELECT_H [irix!] -HAVE_DIRENT [old 386mach has *direct.h*!] -HAVE_SIGSET -HAVE_VFORK_H and HAVE_VFORK -HAVE_VHANGUP -HAVE_VSPRINTF -HAVE_IPTOS_* -HAVE_STRCASECMP, STRNCASECMP -HAVE_SYS_FCNTL_H -HAVE_SYS_TIME_H -HAVE_UTIMES -NOTTYENT [?] -HAVE_FCHMOD -HAVE_GETUSERSHELL -HAVE_SIGCONTEXT [stack hair, very machine-specific] -YYLINENO? -POSIX_SIGNALS -POSIX_TERMIOS -SETPROCTITLE -- breaks some places, like fbsd sendmail -SIG* -- actual signal names? some are missing -SIOCGIFCONF -SO_BROADCAST -SHMEM [krb tickets] -VARARGS, or HAVE_VARARGS -CBAUD -... and B300, B9600, etc etc -HAVE_BZERO vs memset/memcpy -HAVE_SETVBUF -HAVE_STRDUP -HAVE_GETENV -HAVE_STRSAVE -HAVE_STBLKSIZE [stat?] -HAVE_STREAM_H -- in sys/, ref sendmail 8.7 for IP_SRCROUTE -FCHMOD -INITGROUPS -- most machines seem to *have* -SETREUID -SNPRINTF -SETPGRP semantics bsd vs. sys5 style - -There's also the issue about WHERE various .h files live, sys/ or otherwise. -There's a BIG swamp lurking where network code of any sort lives. -*/ - -/* ======================== */ -/* System-specific sections */ -/* ======================== */ - -/* By turning OFF various bits of the above, you can customize for - a given platform. Yes, we're ignoring the stock compiler predefines - and using our own plugged in via the Makefile. */ - -/* DOS boxes, with MSC; you may need to adapt to a different compiler. */ -/* looks like later ones *do* have dirent.h, for example */ -#ifdef MSDOS -#undef HAVE_FLOCK -#undef HAVE_RANDOM -#undef HAVE_LSTAT -#undef HAVE_TERMIOS -#undef UTMPX -#undef HAVE_SYSINFO -#undef HAVE_UNISTD_H -#undef HAVE_DIRENT_H /* unless you have the k00l little wrapper from L5!! */ -#undef HAVE_STRINGS_H -#undef HAVE_LASTLOG_H -#undef HAVE_PATHS_H -#undef HAVE_PARAM_H -#undef HAVE_SYSMACROS_H -#undef HAVE_SELECT_H -#undef HAVE_TTYENT_H -#endif /* MSDOS */ - -/* buglix 4.x; dunno about 3.x on down. should be bsd4.2 */ -#ifdef ULTRIX -#undef UTMPX -#undef HAVE_PATHS_H -#undef HAVE_SYSMACROS_H -#undef HAVE_SELECT_H -#endif /* buglix */ - -/* some of this might still be broken on older sunoses */ -#ifdef SUNOS -#undef VOID_MALLOC -#undef UTMPX -#undef HAVE_PATHS_H -#undef HAVE_SELECT_H -#endif /* sunos */ - -/* "contact your vendor for a fix" */ -#ifdef SOLARIS -/* has UTMPX */ -#undef HAVE_RANDOM -#undef HAVE_SETPRIORITY -#undef HAVE_STRINGS_H /* this is genuinely the case, go figure */ -#undef HAVE_PATHS_H -#undef HAVE_SELECT_H -#undef HAVE_TTYENT_H -#endif /* SOLARIS */ - -/* whatever aix variant MIT had at the time; 3.2.x?? */ -#ifdef AIX -#undef UTMPX -#undef HAVE_LASTLOG_H -#define HAVE_LOGIN_H /* "special", in the educational sense */ -#endif /* aix */ - -/* linux, which is trying as desperately as the gnu folks can to be - POSIXLY_CORRECT. I think I'm gonna hurl... */ -#ifdef LINUX -#undef UTMPX -#undef HAVE_SYSINFO -#undef HAVE_SELECT_H -#undef HAVE_TTYENT_H -#endif /* linux */ - -/* irix 5.x; may not be correct for earlier ones */ -#ifdef IRIX -/* wow, does irix really have everything?! */ -#endif /* irix */ - -/* osf on alphas */ -#ifdef OSF -#undef UTMPX -#undef HAVE_SELECT_H -#endif /* osf */ - -/* they's some FUCKED UP paths in this one! */ -#ifdef FREEBSD -#undef UTMPX -#undef HAVE_SYSINFO -#undef HAVE_LASTLOG_H -#undef HAVE_SYSMACROS_H -#undef HAVE_SELECT_H /* actually a lie, but only for kernel */ -#endif /* freebsd */ - -/* Originally from the sidewinder site, of all places, but subsequently - checked further under a more normal bsdi 2.0 */ -#ifdef BSDI -#undef UTMPX -#undef HAVE_LASTLOG_H -#undef HAVE_SYSMACROS_H -/* and their malloc.h was in sys/ ?! */ -#undef HAVE_SELECT_H -#endif /* bsdi */ - -/* netbsd/44lite, jives with amiga-netbsd from cactus */ -#ifdef NETBSD -#undef UTMPX -#undef HAVE_SYSINFO -#undef HAVE_LASTLOG_H -#undef HAVE_SELECT_H -#endif /* netbsd */ - -/* Hpux 9.0x, from BBN and various patches sent in */ -#ifdef HPUX -#undef HAVE_RANDOM /* but *does* have ?rand48 -- need to consider.. */ -#undef HAVE_UTMPX -#undef HAVE_LASTLOG_H /* has utmp/wtmp/btmp nonsense, and pututline() */ -#undef HAVE_PATHS_H -#undef HAVE_SELECT_H -#undef HAVE_TTYENT_H -#endif /* hockeypux */ - -/* Unixware [a loose definition of "unix", to be sure], 1.1.2 [at least] - from Brian Clapper. He wasn't sure about 2.0... */ -#ifdef UNIXWARE -/* has UTMPX */ -#undef HAVE_SETPRIORITY -/* NOTE: UnixWare does provide the BSD stuff, in "/usr/ucbinclude" (headers) - and "/usr/ucblib" (libraries). However, I've run into problems linking - stuff out of that version of the C library, when objects are also coming - out of the "regular" C library. My advice: Avoid the BSD compatibility - stuff wherever possible. Brian Clapper <bmc@telebase.com> */ -#undef HAVE_STRINGS_H -#undef HAVE_PATHS_H -#undef HAVE_TTYENT_H -#endif /* UNIXWARE */ - -/* A/UX 3.1.x from darieb@sandia.gov */ -#ifdef AUX -#undef HAVE_RANDOM -#undef HAVE_SELECT_H /* xxx: untested */ -#endif /* a/ux */ - -/* NeXTSTEP 3.2 motorola mudge@l0pht.com xxx should also work with - white hardware and Sparc/HPPA. Should work with 3.3 too as it's - 4.3 / 4.4 bsd wrapped around mach */ -#ifdef NEXT -#undef UTMPX -#undef HAVE_SELECT_X -#endif /* NeXTSTEP 3.2 motorola */ - -/* Make some "generic" assumptions if all else fails */ -#ifdef GENERIC -#undef HAVE_FLOCK -#if defined(SYSV) && (SYSV < 4) /* TW leftover: old SV doesnt have symlinks */ -#undef HAVE_LSTAT -#endif /* old SYSV */ -#undef HAVE_TERMIOS -#undef UTMPX -#undef HAVE_PATHS_H -#undef HAVE_SELECT_H -#endif /* generic */ - -/* ================ */ -#endif /* GENERIC_H */ - Binary files differdiff --git a/netcat.blurb b/netcat.blurb deleted file mode 100644 index 2c540ad..0000000 --- a/netcat.blurb +++ /dev/null @@ -1,61 +0,0 @@ -Netcat 1.10 is an updated release of Netcat, a simple Unix utility which reads -and writes data across network connections using TCP or UDP protocol. It is -designed to be a reliable "back-end" tool that can be used directly or easily -driven by other programs and scripts. At the same time it is a feature-rich -network debugging and exploration tool, since it can create almost any kind of -connection you would need and has several interesting built-in capabilities. - -Some of netcat's major features are: - - Outbound or inbound connections, TCP or UDP, to or from any ports - Full DNS forward/reverse checking, with appropriate warnings - Ability to use any local source port - Ability to use any locally-configured network source address - Built-in port-scanning capabilities, with randomizer - Built-in loose source-routing capability - Can read command line arguments from standard input - Slow-send mode, one line every N seconds - Hex dump of transmitted and received data - Optional ability to let another program service established connections - Optional telnet-options responder - -A very short list of potential uses: - - Script backends - Scanning ports and inventorying services, automated probes - Backup handlers - File transfers - Server testing, simulation, debugging, and hijacking - Firewall testing - Proxy gatewaying - Network performance testing - Address spoofing tests - Protecting X servers - 1001 other uses you'll likely come up with - -Changes between the 1.00 release and this release: - - Better portability -- updated generic.h and Makefile [thanx folks!] - Indication of local-end interface address on inbound connections - That's *Dave* Borman's telnet, not Paul Borman... - Better indication of DNS errors - Total byte counts printed if -v -v is used - A bunch of front-end driver companion programs and scripts - Better handling of stdin arguments-plus-data - Hex-dump feature - Telnet responder - Program exec works inbound or outbound now - -Netcat and the associated package is a product of Avian Research, and is freely -available in full source form with no restrictions save an obligation to give -credit where due. Get it via anonymous FTP at avian.org:/src/hacks/nc110.tgz -which is a gzipped tar file and not to be confused with its version 1.00 -precursor, nc100.tgz. Other distribution formats can be accomodated upon -request. Netcat is also mirrored at the following [faster] sites: - - zippy.telcom.arizona.edu:/pub/mirrors/avian.org/hacks/nc110.tgz - ftp.sterling.com:/mirrors/avian.org/src/hacks/nc110.tgz - coast.cs.purdue.edu:/pub/tools/unix/netcat/nc110.tgz - ftp.rge.com:/pub/security/coast/mirrors/avian.org/netcat/nc110.tgz - -_H* 960320 @@ -1,1679 +1,1084 @@ -/* Netcat 1.10 RELEASE 960320 - - A damn useful little "backend" utility begun 950915 or thereabouts, - as *Hobbit*'s first real stab at some sockets programming. Something that - should have and indeed may have existed ten years ago, but never became a - standard Unix utility. IMHO, "nc" could take its place right next to cat, - cp, rm, mv, dd, ls, and all those other cryptic and Unix-like things. - - Read the README for the whole story, doc, applications, etc. - - Layout: - conditional includes: - includes: - handy defines: - globals: - malloced globals: - cmd-flag globals: - support routines: - readwrite select loop: - main: - - bluesky: - parse ranges of IP address as well as ports, perhaps - RAW mode! - backend progs to grab a pty and look like a real telnetd?! - backend progs to do various encryption modes??!?! -*/ - -#include "generic.h" /* same as with L5, skey, etc */ - -/* conditional includes -- a very messy section which you may have to dink - for your own architecture [and please send diffs...]: */ -#if 0 -#undef _POSIX_SOURCE /* might need this for something? */ -#endif -#if !defined(ANDROID) -#define HAVE_BIND /* ASSUMPTION -- seems to work everywhere! */ -#endif -#define HAVE_HELP /* undefine if you dont want the help text */ -#if 0 -#define ANAL /* if you want case-sensitive DNS matching */ +/* $OpenBSD: netcat.c,v 1.103 2011/10/04 08:34:34 fgsch Exp $ */ +/* + * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> + * + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * Re-written nc(1) for OpenBSD. Original implementation by + * *Hobbit* <hobbit@avian.org>. + */ + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/un.h> + +#include <netinet/in.h> +#include <netinet/in_systm.h> +#include <netinet/tcp.h> +#include <netinet/ip.h> +#include <arpa/telnet.h> + +#include <err.h> +#include <errno.h> +#include <netdb.h> +#include <poll.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include "atomicio.h" + +#ifndef SUN_LEN +#define SUN_LEN(su) \ + (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) #endif -#ifdef HAVE_STDLIB_H -#include <stdlib.h> +#define PORT_MAX 65535 +#define PORT_MAX_LEN 6 +#define UNIX_DG_TMP_SOCKET_SIZE 19 + +/* Command Line Options */ +int dflag; /* detached, no stdin */ +unsigned int iflag; /* Interval Flag */ +#ifdef ANDROID +int jflag = 0; +#else +int jflag; /* use jumbo frames if we can */ +#endif /* !ANDROID */ +int kflag; /* More than one connect */ +int lflag; /* Bind to local port */ +int nflag; /* Don't do name look up */ +char *Pflag; /* Proxy username */ +char *pflag; /* Localport flag */ +int rflag; /* Random ports flag */ +char *sflag; /* Source Address */ +int tflag; /* Telnet Emulation */ +int uflag; /* UDP - Default to TCP */ +int vflag; /* Verbosity */ +#ifndef ANDROID +int xflag; /* Socks proxy */ +#endif /* !ANDROID */ +int zflag; /* Port Scan Flag */ +int Dflag; /* sodebug */ +int Iflag; /* TCP receive buffer size */ +int Oflag; /* TCP send buffer size */ +#ifndef ANDROID +int Sflag; /* TCP MD5 signature option */ +int Tflag = -1; /* IP Type of Service */ +u_int rtableid; +#endif /* !ANDROID */ + +int timeout = -1; +int family = AF_UNSPEC; +char *portlist[PORT_MAX+1]; +char *unix_dg_tmp_socket; + +void atelnet(int, unsigned char *, unsigned int); +void build_ports(char *); +void help(void); +int local_listen(char *, char *, struct addrinfo); +void readwrite(int); +int remote_connect(const char *, const char *, struct addrinfo); +int timeout_connect(int, const struct sockaddr *, socklen_t); +#ifndef ANDROID +int socks_connect(const char *, const char *, struct addrinfo, + const char *, const char *, struct addrinfo, int, const char *); +#endif /* !ANDROID */ +int udptest(int); +int unix_bind(char *); +int unix_connect(char *); +int unix_listen(char *); +void set_common_sockopts(int); +int map_tos(char *, int *); +void usage(int); + +int +main(int argc, char *argv[]) +{ + int ch, s, ret, socksv; + char *host, *uport; + struct addrinfo hints; + struct servent *sv; + socklen_t len; + struct sockaddr_storage cliaddr; + char *proxy; + const char *errstr, *proxyhost = "", *proxyport = NULL; + struct addrinfo proxyhints; + char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; + + ret = 1; + s = 0; + socksv = 5; + host = NULL; + uport = NULL; + sv = NULL; + + while ((ch = getopt(argc, argv, + "46DdhI:i:jklnO:P:p:rSs:tT:UuV:vw:X:x:z")) != -1) { + switch (ch) { + case '4': + family = AF_INET; + break; + case '6': + family = AF_INET6; + break; + case 'U': + family = AF_UNIX; + break; + case 'X': + if (strcasecmp(optarg, "connect") == 0) + socksv = -1; /* HTTP proxy CONNECT */ + else if (strcmp(optarg, "4") == 0) + socksv = 4; /* SOCKS v.4 */ + else if (strcmp(optarg, "5") == 0) + socksv = 5; /* SOCKS v.5 */ + else + errx(1, "unsupported proxy protocol"); + break; + case 'd': + dflag = 1; + break; + case 'h': + help(); + break; + case 'i': +#ifdef ANDROID + iflag = atoi(optarg); +#else + iflag = strtonum(optarg, 0, UINT_MAX, &errstr); + if (errstr) + errx(1, "interval %s: %s", errstr, optarg); +#endif /* ANDROID */ + break; +#ifndef ANDROID + case 'j': + jflag = 1; + break; +#endif /* !ANDROID */ + case 'k': + kflag = 1; + break; + case 'l': + lflag = 1; + break; + case 'n': + nflag = 1; + break; + case 'P': + Pflag = optarg; + break; + case 'p': + pflag = optarg; + break; + case 'r': + rflag = 1; + break; + case 's': + sflag = optarg; + break; + case 't': + tflag = 1; + break; + case 'u': + uflag = 1; + break; +#ifndef ANDROID + case 'V': + rtableid = (unsigned int)strtonum(optarg, 0, + RT_TABLEID_MAX, &errstr); + if (errstr) + errx(1, "rtable %s: %s", errstr, optarg); + break; +#endif /* !ANDROID */ + case 'v': + vflag = 1; + break; + case 'w': +#ifdef ANDROID + timeout = atoi(optarg); +#else + timeout = strtonum(optarg, 0, INT_MAX / 1000, &errstr); + if (errstr) + errx(1, "timeout %s: %s", errstr, optarg); +#endif + timeout *= 1000; + break; +#ifndef ANDROID + case 'x': + xflag = 1; + if ((proxy = strdup(optarg)) == NULL) + err(1, NULL); + break; +#endif /* !ANDROID */ + case 'z': + zflag = 1; + break; + case 'D': + Dflag = 1; + break; + case 'I': +#ifdef ANDROID + Iflag = atoi(optarg); #else -#include <malloc.h> + Iflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP receive window %s: %s", + errstr, optarg); #endif -#ifdef HAVE_SELECT_H /* random SV variants need this */ -#include <sys/select.h> + break; + case 'O': +#ifdef ANDROID + Oflag = atoi(optarg); +#else + Oflag = strtonum(optarg, 1, 65536 << 14, &errstr); + if (errstr != NULL) + errx(1, "TCP send window %s: %s", + errstr, optarg); #endif + break; +#ifndef ANDROID + case 'S': + Sflag = 1; + break; + case 'T': + errstr = NULL; + errno = 0; + if (map_tos(optarg, &Tflag)) + break; + if (strlen(optarg) > 1 && optarg[0] == '0' && + optarg[1] == 'x') + Tflag = (int)strtol(optarg, NULL, 16); + else + Tflag = (int)strtonum(optarg, 0, 255, + &errstr); + if (Tflag < 0 || Tflag > 255 || errstr || errno) + errx(1, "illegal tos value %s", optarg); + break; +#endif /* !ANDROID */ + default: + usage(1); + } + } + argc -= optind; + argv += optind; + + /* Cruft to make sure options are clean, and used properly. */ + if (argv[0] && !argv[1] && family == AF_UNIX) { + host = argv[0]; + uport = NULL; + } else if (argv[0] && !argv[1]) { + if (!lflag) + usage(1); + uport = argv[0]; + host = NULL; + } else if (argv[0] && argv[1]) { + host = argv[0]; + uport = argv[1]; + } else + usage(1); + + if (lflag && sflag) + errx(1, "cannot use -s and -l"); + if (lflag && pflag) + errx(1, "cannot use -p and -l"); + if (lflag && zflag) + errx(1, "cannot use -z and -l"); + if (!lflag && kflag) + errx(1, "must use -l with -k"); + + /* Get name of temporary socket for unix datagram client */ + if ((family == AF_UNIX) && uflag && !lflag) { + if (sflag) { + unix_dg_tmp_socket = sflag; + } else { + strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", + UNIX_DG_TMP_SOCKET_SIZE); + if (mktemp(unix_dg_tmp_socket_buf) == NULL) + err(1, "mktemp"); + unix_dg_tmp_socket = unix_dg_tmp_socket_buf; + } + } + + /* Initialize addrinfo structure. */ + if (family != AF_UNIX) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + if (nflag) + hints.ai_flags |= AI_NUMERICHOST; + } -/* have to do this *before* including types.h. xxx: Linux still has it wrong */ -#ifdef FD_SETSIZE /* should be in types.h, butcha never know. */ -#undef FD_SETSIZE /* if we ever need more than 16 active */ -#endif /* fd's, something is horribly wrong! */ -#define FD_SETSIZE 16 /* <-- this'll give us a long anyways, wtf */ -#include <sys/types.h> /* *now* do it. Sigh, this is broken */ +#ifndef ANDROID + if (xflag) { + if (uflag) + errx(1, "no proxy support for UDP mode"); -#ifdef HAVE_RANDOM /* aficionados of ?rand48() should realize */ -#define SRAND srandom /* that this doesn't need *strong* random */ -#define RAND random /* numbers just to mix up port numbers!! */ -#else -#define SRAND srand -#define RAND rand -#endif /* HAVE_RANDOM */ + if (lflag) + errx(1, "no proxy support for listen"); -/* includes: */ -#include <sys/time.h> /* timeval, time_t */ -#include <setjmp.h> /* jmp_buf et al */ -#include <sys/socket.h> /* basics, SO_ and AF_ defs, sockaddr, ... */ + if (family == AF_UNIX) + errx(1, "no proxy support for unix sockets"); -#include <netinet/in.h> /* sockaddr_in, htons, in_addr */ + /* XXX IPv6 transport to proxy would probably work */ + if (family == AF_INET6) + errx(1, "no proxy support for IPv6"); -#if 0 -#include <netinet/in_systm.h> /* misc crud that netinet/ip.h references */ -#endif -#include <netinet/ip.h> /* IPOPT_LSRR, header stuff */ -#include <netdb.h> /* hostent, gethostby*, getservby* */ -#include <arpa/inet.h> /* inet_ntoa */ -#include <stdio.h> -#include <string.h> /* strcpy, strchr, yadda yadda */ -#include <errno.h> -#include <signal.h> -#include <fcntl.h> /* O_WRONLY et al */ - -/* handy stuff: */ -#define SA struct sockaddr /* socket overgeneralization braindeath */ -#define SAI struct sockaddr_in /* ... whoever came up with this model */ -#define IA struct in_addr /* ... should be taken out and shot, */ - /* ... not that TLI is any better. sigh.. */ -#define SLEAZE_PORT 31337 /* for UDP-scan RTT trick, change if ya want */ -#define USHORT unsigned short /* use these for options an' stuff */ -#define BIGSIZ 8192 /* big buffers */ - -#ifndef INADDR_NONE -#define INADDR_NONE 0xffffffff -#endif -#ifdef MAXHOSTNAMELEN -#undef MAXHOSTNAMELEN /* might be too small on aix, so fix it */ -#endif -#define MAXHOSTNAMELEN 256 - -struct host_poop { - char name[MAXHOSTNAMELEN]; /* dns name */ - char addrs[8][24]; /* ascii-format IP addresses */ - struct in_addr iaddrs[8]; /* real addresses: in_addr.s_addr: ulong */ -}; -#define HINF struct host_poop - -struct port_poop { - char name [64]; /* name in /etc/services */ - char anum [8]; /* ascii-format number */ - USHORT num; /* real host-order number */ -}; -#define PINF struct port_poop - -/* globals: */ -jmp_buf jbuf; /* timer crud */ -int jval = 0; /* timer crud */ -int netfd = -1; -int ofd = 0; /* hexdump output fd */ -static char unknown[] = "(UNKNOWN)"; -static char p_tcp[] = "tcp"; /* for getservby* */ -static char p_udp[] = "udp"; -#ifdef HAVE_BIND -extern int h_errno; -/* stolen almost wholesale from bsd herror.c */ -static char * h_errs[] = { - "Error 0", /* but we *don't* use this */ - "Unknown host", /* 1 HOST_NOT_FOUND */ - "Host name lookup failure", /* 2 TRY_AGAIN */ - "Unknown server error", /* 3 NO_RECOVERY */ - "No address associated with name", /* 4 NO_ADDRESS */ -}; -#else -int h_errno; /* just so we *do* have it available */ -#endif /* HAVE_BIND */ -int gatesidx = 0; /* LSRR hop count */ -int gatesptr = 4; /* initial LSRR pointer, settable */ -USHORT Single = 1; /* zero if scanning */ -unsigned int insaved = 0; /* stdin-buffer size for multi-mode */ -unsigned int wrote_out = 0; /* total stdout bytes */ -unsigned int wrote_net = 0; /* total net bytes */ -static char wrote_txt[] = " sent %d, rcvd %d"; -static char hexnibs[20] = "0123456789abcdef "; - -/* will malloc up the following globals: */ -struct timeval * timer1 = NULL; -struct timeval * timer2 = NULL; -SAI * lclend = NULL; /* sockaddr_in structs */ -SAI * remend = NULL; -HINF ** gates = NULL; /* LSRR hop hostpoop */ -char * optbuf = NULL; /* LSRR or sockopts */ -char * bigbuf_in; /* data buffers */ -char * bigbuf_net; -fd_set * ding1; /* for select loop */ -fd_set * ding2; -PINF * portpoop = NULL; /* for getportpoop / getservby* */ -unsigned char * stage = NULL; /* hexdump line buffer */ - -/* global cmd flags: */ -USHORT o_alla = 0; -unsigned int o_interval = 0; -USHORT o_listen = 0; -USHORT o_nflag = 0; -USHORT o_wfile = 0; -USHORT o_random = 0; -USHORT o_udpmode = 0; -USHORT o_verbose = 0; -unsigned int o_wait = 0; -USHORT o_zero = 0; -/* o_tn in optional section */ - -/* Debug macro: squirt whatever message and sleep a bit so we can see it go - by. need to call like Debug ((stuff)) [with no ; ] so macro args match! - Beware: writes to stdOUT... */ -#ifdef DEBUG -#define Debug(x) printf x; printf ("\n"); fflush (stdout); sleep (1); -#else -#define Debug(x) /* nil... */ -#endif + if (sflag) + errx(1, "no proxy support for local source address"); + proxyhost = strsep(&proxy, ":"); + proxyport = proxy; -/* support routines -- the bulk of this thing. Placed in such an order that - we don't have to forward-declare anything: */ + memset(&proxyhints, 0, sizeof(struct addrinfo)); + proxyhints.ai_family = family; + proxyhints.ai_socktype = SOCK_STREAM; + proxyhints.ai_protocol = IPPROTO_TCP; + if (nflag) + proxyhints.ai_flags |= AI_NUMERICHOST; + } +#endif /* !ANDROID */ + + if (lflag) { + int connfd; + ret = 0; + + if (family == AF_UNIX) { + if (uflag) + s = unix_bind(host); + else + s = unix_listen(host); + } + + /* Allow only one connection at a time, but stay alive. */ + for (;;) { + if (family != AF_UNIX) + s = local_listen(host, uport, hints); + if (s < 0) + err(1, NULL); + /* + * For UDP, we will use recvfrom() initially + * to wait for a caller, then use the regular + * functions to talk to the caller. + */ + if (uflag) { + int rv, plen; + char buf[16384]; + struct sockaddr_storage z; + + len = sizeof(z); + plen = jflag ? 16384 : 2048; + rv = recvfrom(s, buf, plen, MSG_PEEK, + (struct sockaddr *)&z, &len); + if (rv < 0) + err(1, "recvfrom"); + + rv = connect(s, (struct sockaddr *)&z, len); + if (rv < 0) + err(1, "connect"); + + readwrite(s); + } else { + len = sizeof(cliaddr); + connfd = accept(s, (struct sockaddr *)&cliaddr, + &len); + readwrite(connfd); + close(connfd); + } + + if (family != AF_UNIX) + close(s); + else if (uflag) { + if (connect(s, NULL, 0) < 0) + err(1, "connect"); + } + + if (!kflag) + break; + } + } else if (family == AF_UNIX) { + ret = 0; + + if ((s = unix_connect(host)) > 0 && !zflag) { + readwrite(s); + close(s); + } else + ret = 1; + + if (uflag) + unlink(unix_dg_tmp_socket); + exit(ret); -/* holler : - fake varargs -- need to do this way because we wind up calling through - more levels of indirection than vanilla varargs can handle, and not all - machines have vfprintf/vsyslog/whatever! 6 params oughta be enough. */ -void holler (str, p1, p2, p3, p4, p5, p6) - char * str; - char * p1, * p2, * p3, * p4, * p5, * p6; -{ - if (o_verbose) { - fprintf (stderr, str, p1, p2, p3, p4, p5, p6); -#ifdef HAVE_BIND - if (h_errno) { /* if host-lookup variety of error ... */ - if (h_errno > 4) /* oh no you don't, either */ - fprintf (stderr, "preposterous h_errno: %d", h_errno); - else - fprintf (stderr, "%s", h_errs[h_errno]); /* handle it here */ - h_errno = 0; /* and reset for next call */ - } -#endif - if (errno) { /* this gives funny-looking messages, but */ - perror (" "); /* it's more portable than sys_errlist[]... */ - } else /* xxx: do something better? */ - fprintf (stderr, "\n"); - fflush (stderr); - } -} /* holler */ - -/* bail : - error-exit handler, callable from anywhere */ -void bail (str, p1, p2, p3, p4, p5, p6) - char * str; - char * p1, * p2, * p3, * p4, * p5, * p6; -{ - o_verbose = 1; - holler (str, p1, p2, p3, p4, p5, p6); - close (netfd); - sleep (1); - exit (1); -} /* bail */ - -/* catch : - no-brainer interrupt handler */ -void catch () + } else { + int i = 0; + + /* Construct the portlist[] array. */ + build_ports(uport); + + /* Cycle through portlist, connecting to each port. */ + for (i = 0; portlist[i] != NULL; i++) { + if (s) + close(s); + +#ifndef ANDROID + if (xflag) + s = socks_connect(host, portlist[i], hints, + proxyhost, proxyport, proxyhints, socksv, + Pflag); + else +#endif /* !ANDROID */ + s = remote_connect(host, portlist[i], hints); + + if (s < 0) + continue; + + ret = 0; + if (vflag || zflag) { + /* For UDP, make sure we are connected. */ + if (uflag) { + if (udptest(s) == -1) { + ret = 1; + continue; + } + } + + /* Don't look up port if -n. */ + if (nflag) + sv = NULL; + else { + sv = getservbyport( + ntohs(atoi(portlist[i])), + uflag ? "udp" : "tcp"); + } + + fprintf(stderr, + "Connection to %s %s port [%s/%s] " + "succeeded!\n", host, portlist[i], + uflag ? "udp" : "tcp", + sv ? sv->s_name : "*"); + } + if (!zflag) + readwrite(s); + } + } + + if (s) + close(s); + + exit(ret); +} + +/* + * unix_bind() + * Returns a unix socket bound to the given path + */ +int +unix_bind(char *path) { - errno = 0; - if (o_verbose > 1) /* normally we don't care */ - bail (wrote_txt, wrote_net, wrote_out); - bail (" punt!"); + struct sockaddr_un sun; + int s; + + /* Create unix domain socket. */ + if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, + 0)) < 0) + return (-1); + + memset(&sun, 0, sizeof(struct sockaddr_un)); + sun.sun_family = AF_UNIX; + + if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= + sizeof(sun.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + + if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { + close(s); + return (-1); + } + return (s); } -/* timeout and other signal handling cruft */ -void tmtravel () +/* + * unix_connect() + * Returns a socket connected to a local unix socket. Returns -1 on failure. + */ +int +unix_connect(char *path) { - signal (SIGALRM, SIG_IGN); - alarm (0); - if (jval == 0) - bail ("spurious timer interrupt!"); - longjmp (jbuf, jval); + struct sockaddr_un sun; + int s; + + if (uflag) { + if ((s = unix_bind(unix_dg_tmp_socket)) < 0) + return (-1); + } else { + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return (-1); + } + (void)fcntl(s, F_SETFD, 1); + + memset(&sun, 0, sizeof(struct sockaddr_un)); + sun.sun_family = AF_UNIX; + + if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= + sizeof(sun.sun_path)) { + close(s); + errno = ENAMETOOLONG; + return (-1); + } + if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { + close(s); + return (-1); + } + return (s); + } -/* arm : - set the timer. Zero secs arg means unarm */ -void arm (num, secs) - unsigned int num; - unsigned int secs; +/* + * unix_listen() + * Create a unix domain socket, and listen on it. + */ +int +unix_listen(char *path) { - if (secs == 0) { /* reset */ - signal (SIGALRM, SIG_IGN); - alarm (0); - jval = 0; - } else { /* set */ - signal (SIGALRM, tmtravel); - alarm (secs); - jval = num; - } /* if secs */ -} /* arm */ - -/* Hmalloc : - malloc up what I want, rounded up to *4, and pre-zeroed. Either succeeds - or bails out on its own, so that callers don't have to worry about it. */ -char * Hmalloc (size) - unsigned int size; + int s; + if ((s = unix_bind(path)) < 0) + return (-1); + + if (listen(s, 5) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* + * remote_connect() + * Returns a socket connected to a remote host. Properly binds to a local + * port or source address if needed. Returns -1 on failure. + */ +int +remote_connect(const char *host, const char *port, struct addrinfo hints) { - unsigned int s = (size + 4) & 0xfffffffc; /* 4GB?! */ - char * p = malloc (s); - if (p != NULL) - memset (p, 0, s); - else - bail ("Hmalloc %d failed", s); - return (p); -} /* Hmalloc */ - -/* findline : - find the next newline in a buffer; return inclusive size of that "line", - or the entire buffer size, so the caller knows how much to then write(). - Not distinguishing \n vs \r\n for the nonce; it just works as is... */ -unsigned int findline (buf, siz) - char * buf; - unsigned int siz; + struct addrinfo *res, *res0; + int s, error, on = 1; + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifndef ANDROID + if (rtableid) { + if (setsockopt(s, SOL_SOCKET, SO_RTABLE, &rtableid, + sizeof(rtableid)) == -1) + err(1, "setsockopt SO_RTABLE"); + } +#endif /* !ANDROID */ + + /* Bind to a local port or source address if specified. */ + if (sflag || pflag) { + struct addrinfo ahints, *ares; + +#ifndef ANDROID + /* try SO_BINDANY, but don't insist */ + setsockopt(s, SOL_SOCKET, SO_BINDANY, &on, sizeof(on)); +#endif /* !ANDROID */ + memset(&ahints, 0, sizeof(struct addrinfo)); + ahints.ai_family = res0->ai_family; + ahints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + ahints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + ahints.ai_flags = AI_PASSIVE; + if ((error = getaddrinfo(sflag, pflag, &ahints, &ares))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + if (bind(s, (struct sockaddr *)ares->ai_addr, + ares->ai_addrlen) < 0) + errx(1, "bind failed: %s", strerror(errno)); + freeaddrinfo(ares); + } + + set_common_sockopts(s); + + if (timeout_connect(s, res0->ai_addr, res0->ai_addrlen) == 0) + break; + else if (vflag) + warn("connect to %s port %s (%s) failed", host, port, + uflag ? "udp" : "tcp"); + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + freeaddrinfo(res); + + return (s); +} + +int +timeout_connect(int s, const struct sockaddr *name, socklen_t namelen) { - register char * p; - register int x; - if (! buf) /* various sanity checks... */ - return (0); - if (siz > BIGSIZ) - return (0); - x = siz; - for (p = buf; x > 0; x--) { - if (*p == '\n') { - x = (int) (p - buf); - x++; /* 'sokay if it points just past the end! */ -Debug (("findline returning %d", x)) - return (x); - } - p++; - } /* for */ -Debug (("findline returning whole thing: %d", siz)) - return (siz); -} /* findline */ - -/* comparehosts : - cross-check the host_poop we have so far against new gethostby*() info, - and holler about mismatches. Perhaps gratuitous, but it can't hurt to - point out when someone's DNS is fukt. Returns 1 if mismatch, in case - someone else wants to do something about it. */ -int comparehosts (poop, hp) - HINF * poop; - struct hostent * hp; + struct pollfd pfd; + socklen_t optlen; + int flags, optval; + int ret; + + if (timeout != -1) { + flags = fcntl(s, F_GETFL, 0); + if (fcntl(s, F_SETFL, flags | O_NONBLOCK) == -1) + err(1, "set non-blocking mode"); + } + + if ((ret = connect(s, name, namelen)) != 0 && errno == EINPROGRESS) { + pfd.fd = s; + pfd.events = POLLOUT; + if ((ret = poll(&pfd, 1, timeout)) == 1) { + optlen = sizeof(optval); + if ((ret = getsockopt(s, SOL_SOCKET, SO_ERROR, + &optval, &optlen)) == 0) { + errno = optval; + ret = optval == 0 ? 0 : -1; + } + } else if (ret == 0) { + errno = ETIMEDOUT; + ret = -1; + } else + err(1, "poll failed"); + } + + if (timeout != -1 && fcntl(s, F_SETFL, flags) == -1) + err(1, "restoring flags"); + + return (ret); +} + +/* + * local_listen() + * Returns a socket listening on a local port, binds to specified source + * address. Returns -1 on failure. + */ +int +local_listen(char *host, char *port, struct addrinfo hints) { - errno = 0; - h_errno = 0; -/* The DNS spec is officially case-insensitive, but for those times when you - *really* wanna see any and all discrepancies, by all means define this. */ -#ifdef ANAL - if (strcmp (poop->name, hp->h_name) != 0) { /* case-sensitive */ + struct addrinfo *res, *res0; + int s, ret, x = 1; + int error; + + /* Allow nodename to be null. */ + hints.ai_flags |= AI_PASSIVE; + + /* + * In the case of binding to a wildcard address + * default to binding to an ipv4 address. + */ + if (host == NULL && hints.ai_family == AF_UNSPEC) + hints.ai_family = AF_INET; + + if ((error = getaddrinfo(host, port, &hints, &res))) + errx(1, "getaddrinfo: %s", gai_strerror(error)); + + res0 = res; + do { + if ((s = socket(res0->ai_family, res0->ai_socktype, + res0->ai_protocol)) < 0) + continue; + +#ifndef ANDROID + if (rtableid) { + if (setsockopt(s, IPPROTO_IP, SO_RTABLE, &rtableid, + sizeof(rtableid)) == -1) + err(1, "setsockopt SO_RTABLE"); + } +#endif /* !ANDROID */ + +#ifdef ANDROID + ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); #else - if (strcasecmp (poop->name, hp->h_name) != 0) { /* normal */ + ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x)); #endif - holler ("DNS fwd/rev mismatch: %s != %s", poop->name, hp->h_name); - return (1); - } - return (0); -/* ... do we need to do anything over and above that?? */ -} /* comparehosts */ - -/* gethostpoop : - resolve a host 8 ways from sunday; return a new host_poop struct with its - info. The argument can be a name or [ascii] IP address; it will try its - damndest to deal with it. "numeric" governs whether we do any DNS at all, - and we also check o_verbose for what's appropriate work to do. */ -HINF * gethostpoop (name, numeric) - char * name; - USHORT numeric; -{ - struct hostent * hostent; - struct in_addr iaddr; - register HINF * poop = NULL; - register int x; - -/* I really want to strangle the twit who dreamed up all these sockaddr and - hostent abstractions, and then forced them all to be incompatible with - each other so you *HAVE* to do all this ridiculous casting back and forth. - If that wasn't bad enough, all the doc insists on referring to local ports - and addresses as "names", which makes NO sense down at the bare metal. - - What an absolutely horrid paradigm, and to think of all the people who - have been wasting significant amounts of time fighting with this stupid - deliberate obfuscation over the last 10 years... then again, I like - languages wherein a pointer is a pointer, what you put there is your own - business, the compiler stays out of your face, and sheep are nervous. - Maybe that's why my C code reads like assembler half the time... */ - -/* If we want to see all the DNS stuff, do the following hair -- - if inet_addr, do reverse and forward with any warnings; otherwise try - to do forward and reverse with any warnings. In other words, as long - as we're here, do a complete DNS check on these clowns. Yes, it slows - things down a bit for a first run, but once it's cached, who cares? */ - - errno = 0; - h_errno = 0; - if (name) - poop = (HINF *) Hmalloc (sizeof (HINF)); - if (! poop) - bail ("gethostpoop fuxored"); - strcpy (poop->name, unknown); /* preload it */ -/* see wzv:workarounds.c for dg/ux return-a-struct inet_addr lossage */ - iaddr.s_addr = inet_addr (name); - - if (iaddr.s_addr == INADDR_NONE) { /* here's the great split: names... */ - if (numeric) - bail ("Can't parse %s as an IP address", name); - hostent = gethostbyname (name); - if (! hostent) -/* failure to look up a name is fatal, since we can't do anything with it */ - bail ("%s: forward host lookup failed: ", name); - strncpy (poop->name, hostent->h_name, MAXHOSTNAMELEN - 2); - for (x = 0; hostent->h_addr_list[x] && (x < 8); x++) { - memcpy (&poop->iaddrs[x], hostent->h_addr_list[x], sizeof (IA)); - strncpy (poop->addrs[x], inet_ntoa (poop->iaddrs[x]), - sizeof (poop->addrs[0])); - } /* for x -> addrs, part A */ - if (! o_verbose) /* if we didn't want to see the */ - return (poop); /* inverse stuff, we're done. */ -/* do inverse lookups in separate loop based on our collected forward addrs, - since gethostby* tends to crap into the same buffer over and over */ - for (x = 0; poop->iaddrs[x].s_addr && (x < 8); x++) { - hostent = gethostbyaddr ((char *)&poop->iaddrs[x], - sizeof (IA), AF_INET); - if ((! hostent) || (! hostent-> h_name)) - holler ("Warning: inverse host lookup failed for %s: ", - poop->addrs[x]); - else - (void) comparehosts (poop, hostent); - } /* for x -> addrs, part B */ - - } else { /* not INADDR_NONE: numeric addresses... */ - memcpy (poop->iaddrs, &iaddr, sizeof (IA)); - strncpy (poop->addrs[0], inet_ntoa (iaddr), sizeof (poop->addrs)); - if (numeric) /* if numeric-only, we're done */ - return (poop); - if (! o_verbose) /* likewise if we don't want */ - return (poop); /* the full DNS hair */ - hostent = gethostbyaddr ((char *) &iaddr, sizeof (IA), AF_INET); -/* numeric or not, failure to look up a PTR is *not* considered fatal */ - if (! hostent) - holler ("%s: inverse host lookup failed: ", name); - else { - strncpy (poop->name, hostent->h_name, MAXHOSTNAMELEN - 2); - hostent = gethostbyname (poop->name); - if ((! hostent) || (! hostent->h_addr_list[0])) - holler ("Warning: forward host lookup failed for %s: ", - poop->name); - else - (void) comparehosts (poop, hostent); - } /* if hostent */ - } /* INADDR_NONE Great Split */ - -/* whatever-all went down previously, we should now have a host_poop struct - with at least one IP address in it. */ - h_errno = 0; - return (poop); -} /* gethostpoop */ - -/* getportpoop : - Same general idea as gethostpoop -- look up a port in /etc/services, fill - in global port_poop, but return the actual port *number*. Pass ONE of: - pstring to resolve stuff like "23" or "exec"; - pnum to reverse-resolve something that's already a number. - If o_nflag is on, fill in what we can but skip the getservby??? stuff. - Might as well have consistent behavior here, and it *is* faster. */ -USHORT getportpoop (pstring, pnum) - char * pstring; - unsigned int pnum; -{ - struct servent * servent; - register int x; - register int y; - char * whichp = p_tcp; - if (o_udpmode) - whichp = p_udp; - portpoop->name[0] = '?'; /* fast preload */ - portpoop->name[1] = '\0'; - -/* case 1: reverse-lookup of a number; placed first since this case is much - more frequent if we're scanning */ - if (pnum) { - if (pstring) /* one or the other, pleeze */ - return (0); - x = pnum; - if (o_nflag) /* go faster, skip getservbyblah */ - goto gp_finish; - y = htons (x); /* gotta do this -- see Fig.1 below */ - servent = getservbyport (y, whichp); - if (servent) { - y = ntohs (servent->s_port); - if (x != y) /* "never happen" */ - holler ("Warning: port-bynum mismatch, %d != %d", x, y); - strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)); - } /* if servent */ - goto gp_finish; - } /* if pnum */ - -/* case 2: resolve a string, but we still give preference to numbers instead - of trying to resolve conflicts. None of the entries in *my* extensive - /etc/services begins with a digit, so this should "always work" unless - you're at 3com and have some company-internal services defined... */ - if (pstring) { - if (pnum) /* one or the other, pleeze */ - return (0); - x = atoi (pstring); - if (x) - return (getportpoop (NULL, x)); /* recurse for numeric-string-arg */ - if (o_nflag) /* can't use names! */ - return (0); - servent = getservbyname (pstring, whichp); - if (servent) { - strncpy (portpoop->name, servent->s_name, sizeof (portpoop->name)); - x = ntohs (servent->s_port); - goto gp_finish; - } /* if servent */ - } /* if pstring */ - - return (0); /* catches any problems so far */ - -/* Obligatory netdb.h-inspired rant: servent.s_port is supposed to be an int. - Despite this, we still have to treat it as a short when copying it around. - Not only that, but we have to convert it *back* into net order for - getservbyport to work. Manpages generally aren't clear on all this, but - there are plenty of examples in which it is just quietly done. More BSD - lossage... since everything getserv* ever deals with is local to our own - host, why bother with all this network-order/host-order crap at all?! - That should be saved for when we want to actually plug the port[s] into - some real network calls -- and guess what, we have to *re*-convert at that - point as well. Fuckheads. */ - -gp_finish: -/* Fall here whether or not we have a valid servent at this point, with - x containing our [host-order and therefore useful, dammit] port number */ - sprintf (portpoop->anum, "%d", x); /* always load any numeric specs! */ - portpoop->num = (x & 0xffff); /* ushort, remember... */ - return (portpoop->num); -} /* getportpoop */ - -/* nextport : - Come up with the next port to try, be it random or whatever. "block" is - a ptr to randports array, whose bytes [so far] carry these meanings: - 0 ignore - 1 to be tested - 2 tested [which is set as we find them here] - returns a USHORT random port, or 0 if all the t-b-t ones are used up. */ -USHORT nextport (block) - char * block; -{ - register unsigned int x; - register unsigned int y; - - y = 70000; /* high safety count for rnd-tries */ - while (y > 0) { - x = (RAND() & 0xffff); - if (block[x] == 1) { /* try to find a not-done one... */ - block[x] = 2; - break; - } - x = 0; /* bummer. */ - y--; - } /* while y */ - if (x) - return (x); - - y = 65535; /* no random one, try linear downsearch */ - while (y > 0) { /* if they're all used, we *must* be sure! */ - if (block[y] == 1) { - block[y] = 2; - break; - } - y--; - } /* while y */ - if (y) - return (y); /* at least one left */ - - return (0); /* no more left! */ -} /* nextport */ - -/* loadports : - set "to be tested" indications in BLOCK, from LO to HI. Almost too small - to be a separate routine, but makes main() a little cleaner... */ -void loadports (block, lo, hi) - char * block; - USHORT lo; - USHORT hi; + if (ret == -1) + err(1, NULL); + + set_common_sockopts(s); + + if (bind(s, (struct sockaddr *)res0->ai_addr, + res0->ai_addrlen) == 0) + break; + + close(s); + s = -1; + } while ((res0 = res0->ai_next) != NULL); + + if (!uflag && s != -1) { + if (listen(s, 1) < 0) + err(1, "listen"); + } + + freeaddrinfo(res); + + return (s); +} + +/* + * readwrite() + * Loop that polls on the network file descriptor and stdin. + */ +void +readwrite(int nfd) { - USHORT x; - - if (! block) - bail ("loadports: no block?!"); - if ((! lo) || (! hi)) - bail ("loadports: bogus values %d, %d", lo, hi); - x = hi; - while (lo <= x) { - block[x] = 1; - x--; - } -} /* loadports */ - -#ifdef GAPING_SECURITY_HOLE -char * pr00gie = NULL; /* global ptr to -e arg */ - -/* doexec : - fiddle all the file descriptors around, and hand off to another prog. Sort - of like a one-off "poor man's inetd". This is the only section of code - that would be security-critical, which is why it's ifdefed out by default. - Use at your own hairy risk; if you leave shells lying around behind open - listening ports you deserve to lose!! */ -doexec (fd) - int fd; + struct pollfd pfd[2]; + unsigned char buf[16384]; + int n, wfd = fileno(stdin); + int lfd = fileno(stdout); + int plen; + + plen = jflag ? 16384 : 2048; + + /* Setup Network FD */ + pfd[0].fd = nfd; + pfd[0].events = POLLIN; + + /* Set up STDIN FD. */ + pfd[1].fd = wfd; + pfd[1].events = POLLIN; + + while (pfd[0].fd != -1) { + if (iflag) + sleep(iflag); + + if ((n = poll(pfd, 2 - dflag, timeout)) < 0) { + close(nfd); + err(1, "Polling Error"); + } + + if (n == 0) + return; + + if (pfd[0].revents & POLLIN) { + if ((n = read(nfd, buf, plen)) < 0) + return; + else if (n == 0) { + shutdown(nfd, SHUT_RD); + pfd[0].fd = -1; + pfd[0].events = 0; + } else { + if (tflag) + atelnet(nfd, buf, n); + if (atomicio(vwrite, lfd, buf, n) != n) + return; + } + } + + if (!dflag && pfd[1].revents & POLLIN) { + if ((n = read(wfd, buf, plen)) < 0) + return; + else if (n == 0) { + shutdown(nfd, SHUT_WR); + pfd[1].fd = -1; + pfd[1].events = 0; + } else { + if (atomicio(vwrite, nfd, buf, n) != n) + return; + } + } + } +} + +/* Deal with RFC 854 WILL/WONT DO/DONT negotiation. */ +void +atelnet(int nfd, unsigned char *buf, unsigned int size) { - register char * p; - - dup2 (fd, 0); /* the precise order of fiddlage */ - close (fd); /* is apparently crucial; this is */ - dup2 (0, 1); /* swiped directly out of "inetd". */ - dup2 (0, 2); - p = strrchr (pr00gie, '/'); /* shorter argv[0] */ - if (p) - p++; - else - p = pr00gie; -Debug (("gonna exec %s as %s...", pr00gie, p)) - execl (pr00gie, p, NULL); - bail ("exec %s failed", pr00gie); /* this gets sent out. Hmm... */ -} /* doexec */ -#endif /* GAPING_SECURITY_HOLE */ - -/* doconnect : - do all the socket stuff, and return an fd for one of - an open outbound TCP connection - a UDP stub-socket thingie - with appropriate socket options set up if we wanted source-routing, or - an unconnected TCP or UDP socket to listen on. - Examines various global o_blah flags to figure out what-all to do. */ -int doconnect (rad, rp, lad, lp) - IA * rad; - USHORT rp; - IA * lad; - USHORT lp; + unsigned char *p, *end; + unsigned char obuf[4]; + + if (size < 3) + return; + end = buf + size - 2; + + for (p = buf; p < end; p++) { + if (*p != IAC) + continue; + + obuf[0] = IAC; + p++; + if ((*p == WILL) || (*p == WONT)) + obuf[1] = DONT; + else if ((*p == DO) || (*p == DONT)) + obuf[1] = WONT; + else + continue; + + p++; + obuf[2] = *p; + if (atomicio(vwrite, nfd, obuf, 3) != 3) + warn("Write Error!"); + } +} + +/* + * build_ports() + * Build an array or ports in portlist[], listing each port + * that we should try to connect to. + */ +void +build_ports(char *p) { - register int nnetfd; - register int rr; - int x, y; - errno = 0; - -/* grab a socket; set opts */ -newskt: - if (o_udpmode) - nnetfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); - else - nnetfd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (nnetfd < 0) - bail ("Can't get socket"); - if (nnetfd == 0) /* if stdin was closed this might *be* 0, */ - goto newskt; /* so grab another. See text for why... */ - x = 1; - rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)); - if (rr == -1) - holler ("nnetfd reuseaddr failed"); /* ??? */ -#ifdef SO_REUSEPORT /* doesnt exist everywhere... */ - rr = setsockopt (nnetfd, SOL_SOCKET, SO_REUSEPORT, &x, sizeof (x)); - if (rr == -1) - holler ("nnetfd reuseport failed"); /* ??? */ + const char *errstr; + char *n; + int hi, lo, cp; + int x = 0; + + if ((n = strchr(p, '-')) != NULL) { + if (lflag) + errx(1, "Cannot use -l with multiple ports!"); + + *n = '\0'; + n++; + + /* Make sure the ports are in order: lowest->highest. */ +#ifdef ANDROID + hi = atoi(n); +#else + hi = strtonum(n, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, n); #endif -#if 0 -/* If you want to screw with RCVBUF/SNDBUF, do it here. Liudvikas Bukys at - Rochester sent this example, which would involve YET MORE options and is - just archived here in case you want to mess with it. o_xxxbuf are global - integers set in main() getopt loop, and check for rr == 0 afterward. */ - rr = setsockopt(nnetfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); - rr = setsockopt(nnetfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); +#ifdef ANDROID + lo = atoi(p); +#else + lo = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); #endif - - /* fill in all the right sockaddr crud */ - lclend->sin_family = AF_INET; - -/* fill in all the right sockaddr crud */ - lclend->sin_family = AF_INET; - remend->sin_family = AF_INET; - -/* if lad/lp, do appropriate binding */ - if (lad) - memcpy (&lclend->sin_addr.s_addr, lad, sizeof (IA)); - if (lp) - lclend->sin_port = htons (lp); - rr = 0; - if (lad || lp) { - x = (int) lp; -/* try a few times for the local bind, a la ftp-data-port... */ - for (y = 4; y > 0; y--) { - rr = bind (nnetfd, (SA *)lclend, sizeof (SA)); - if (rr == 0) - break; - if (errno != EADDRINUSE) - break; - else { - holler ("retrying local %s:%d", inet_ntoa (lclend->sin_addr), lp); - sleep (2); - errno = 0; /* clear from sleep */ - } /* if EADDRINUSE */ - } /* for y counter */ - } /* if lad or lp */ - if (rr) - bail ("Can't grab %s:%d with bind", - inet_ntoa(lclend->sin_addr), lp); - - if (o_listen) - return (nnetfd); /* thanks, that's all for today */ - - memcpy (&remend->sin_addr.s_addr, rad, sizeof (IA)); - remend->sin_port = htons (rp); - -/* rough format of LSRR option and explanation of weirdness. -Option comes after IP-hdr dest addr in packet, padded to *4, and ihl > 5. -IHL is multiples of 4, i.e. real len = ip_hl << 2. - type 131 1 ; 0x83: copied, option class 0, number 3 - len 1 ; of *whole* option! - pointer 1 ; nxt-hop-addr; 1-relative, not 0-relative - addrlist... var ; 4 bytes per hop-addr - pad-to-32 var ; ones, i.e. "NOP" - -If we want to route A -> B via hops C and D, we must add C, D, *and* B to the -options list. Why? Because when we hand the kernel A -> B with list C, D, B -the "send shuffle" inside the kernel changes it into A -> C with list D, B and -the outbound packet gets sent to C. If B wasn't also in the hops list, the -final destination would have been lost at this point. - -When C gets the packet, it changes it to A -> D with list C', B where C' is -the interface address that C used to forward the packet. This "records" the -route hop from B's point of view, i.e. which address points "toward" B. This -is to make B better able to return the packets. The pointer gets bumped by 4, -so that D does the right thing instead of trying to forward back to C. - -When B finally gets the packet, it sees that the pointer is at the end of the -LSRR list and is thus "completed". B will then try to use the packet instead -of forwarding it, i.e. deliver it up to some application. - -Note that by moving the pointer yourself, you could send the traffic directly -to B but have it return via your preconstructed source-route. Playing with -this and watching "tcpdump -v" is the best way to understand what's going on. - -Only works for TCP in BSD-flavor kernels. UDP is a loss; udp_input calls -stripoptions() early on, and the code to save the srcrt is notdef'ed. -Linux is also still a loss at 1.3.x it looks like; the lsrr code is { }... -*/ - -/* if any -g arguments were given, set up source-routing. We hit this after - the gates are all looked up and ready to rock, any -G pointer is set, - and gatesidx is now the *number* of hops */ - if (gatesidx) { /* if we wanted any srcrt hops ... */ -/* don't even bother compiling if we can't do IP options here! */ -#ifdef IP_OPTIONS - if (! optbuf) { /* and don't already *have* a srcrt set */ - char * opp; /* then do all this setup hair */ - optbuf = Hmalloc (48); - opp = optbuf; - *opp++ = IPOPT_LSRR; /* option */ - *opp++ = (char) - (((gatesidx + 1) * sizeof (IA)) + 3) & 0xff; /* length */ - *opp++ = gatesptr; /* pointer */ -/* opp now points at first hop addr -- insert the intermediate gateways */ - for ( x = 0; x < gatesidx; x++) { - memcpy (opp, gates[x]->iaddrs, sizeof (IA)); - opp += sizeof (IA); - } -/* and tack the final destination on the end [needed!] */ - memcpy (opp, rad, sizeof (IA)); - opp += sizeof (IA); - *opp = IPOPT_NOP; /* alignment filler */ - } /* if empty optbuf */ -/* calculate length of whole option mess, which is (3 + [hops] + [final] + 1), - and apply it [have to do this every time through, of course] */ - x = ((gatesidx + 1) * sizeof (IA)) + 4; - rr = setsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, x); - if (rr == -1) - bail ("srcrt setsockopt fuxored"); -#else /* IP_OPTIONS */ - holler ("Warning: source routing unavailable on this machine, ignoring"); -#endif /* IP_OPTIONS*/ - } /* if gatesidx */ - -/* wrap connect inside a timer, and hit it */ - arm (1, o_wait); - if (setjmp (jbuf) == 0) { - rr = connect (nnetfd, (SA *)remend, sizeof (SA)); - } else { /* setjmp: connect failed... */ - rr = -1; - errno = ETIMEDOUT; /* fake it */ - } - arm (0, 0); - if (rr == 0) - return (nnetfd); - close (nnetfd); /* clean up junked socket FD!! */ - return (-1); -} /* doconnect */ - -/* dolisten : - just like doconnect, and in fact calls a hunk of doconnect, but listens for - incoming and returns an open connection *from* someplace. If we were - given host/port args, any connections from elsewhere are rejected. This - in conjunction with local-address binding should limit things nicely... */ -int dolisten (rad, rp, lad, lp) - IA * rad; - USHORT rp; - IA * lad; - USHORT lp; -{ - register int nnetfd; - register int rr; - HINF * whozis = NULL; - int x; - char * cp; - USHORT z; - errno = 0; - -/* Pass everything off to doconnect, who in o_listen mode just gets a socket */ - nnetfd = doconnect (rad, rp, lad, lp); - if (nnetfd <= 0) - return (-1); - if (o_udpmode) { /* apparently UDP can listen ON */ - if (! lp) /* "port 0", but that's not useful */ - bail ("UDP listen needs -p arg"); - } else { - rr = listen (nnetfd, 1); /* gotta listen() before we can get */ - if (rr < 0) /* our local random port. sheesh. */ - bail ("local listen fuxored"); - } - -/* Various things that follow temporarily trash bigbuf_net, which might contain - a copy of any recvfrom()ed packet, but we'll read() another copy later. */ - -/* I can't believe I have to do all this to get my own goddamn bound address - and port number. It should just get filled in during bind() or something. - All this is only useful if we didn't say -p for listening, since if we - said -p we *know* what port we're listening on. At any rate we won't bother - with it all unless we wanted to see it, although listening quietly on a - random unknown port is probably not very useful without "netstat". */ - if (o_verbose) { - x = sizeof (SA); /* how 'bout getsockNUM instead, pinheads?! */ - rr = getsockname (nnetfd, (SA *) lclend, &x); - if (rr < 0) - holler ("local getsockname failed"); - strcpy (bigbuf_net, "listening on ["); /* buffer reuse... */ - if (lclend->sin_addr.s_addr) - strcat (bigbuf_net, inet_ntoa (lclend->sin_addr)); - else - strcat (bigbuf_net, "any"); - strcat (bigbuf_net, "] %d ..."); - z = ntohs (lclend->sin_port); - holler (bigbuf_net, z); - } /* verbose -- whew!! */ - -/* UDP is a speeeeecial case -- we have to do I/O *and* get the calling - party's particulars all at once, listen() and accept() don't apply. - At least in the BSD universe, however, recvfrom/PEEK is enough to tell - us something came in, and we can set things up so straight read/write - actually does work after all. Yow. YMMV on strange platforms! */ - if (o_udpmode) { - x = sizeof (SA); /* retval for recvfrom */ - arm (2, o_wait); /* might as well timeout this, too */ - if (setjmp (jbuf) == 0) { /* do timeout for initial connect */ - rr = recvfrom /* and here we block... */ - (nnetfd, bigbuf_net, BIGSIZ, MSG_PEEK, (SA *) remend, &x); -Debug (("dolisten/recvfrom ding, rr = %d, netbuf %s ", rr, bigbuf_net)) - } else - goto dol_tmo; /* timeout */ - arm (0, 0); -/* I'm not completely clear on how this works -- BSD seems to make UDP - just magically work in a connect()ed context, but we'll undoubtedly run - into systems this deal doesn't work on. For now, we apparently have to - issue a connect() on our just-tickled socket so we can write() back. - Again, why the fuck doesn't it just get filled in and taken care of?! - This hack is anything but optimal. Basically, if you want your listener - to also be able to send data back, you need this connect() line, which - also has the side effect that now anything from a different source or even a - different port on the other end won't show up and will cause ICMP errors. - I guess that's what they meant by "connect". - Let's try to remember what the "U" is *really* for, eh? */ - rr = connect (nnetfd, (SA *)remend, sizeof (SA)); - goto whoisit; - } /* o_udpmode */ - -/* fall here for TCP */ - x = sizeof (SA); /* retval for accept */ - arm (2, o_wait); /* wrap this in a timer, too; 0 = forever */ - if (setjmp (jbuf) == 0) { - rr = accept (nnetfd, (SA *)remend, &x); - } else - goto dol_tmo; /* timeout */ - arm (0, 0); - close (nnetfd); /* dump the old socket */ - nnetfd = rr; /* here's our new one */ - -whoisit: - if (rr < 0) - goto dol_err; /* bail out if any errors so far */ - -/* If we can, look for any IP options. Useful for testing the receiving end of - such things, and is a good exercise in dealing with it. We do this before - the connect message, to ensure that the connect msg is uniformly the LAST - thing to emerge after all the intervening crud. Doesn't work for UDP on - any machines I've tested, but feel free to surprise me. */ -#ifdef IP_OPTIONS - if (! o_verbose) /* if we wont see it, we dont care */ - goto dol_noop; - optbuf = Hmalloc (40); - x = 40; - rr = getsockopt (nnetfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); - if (rr < 0) - holler ("getsockopt failed"); -Debug (("ipoptions ret len %d", x)) - if (x) { /* we've got options, lessee em... */ - unsigned char * q = (unsigned char *) optbuf; - char * p = bigbuf_net; /* local variables, yuk! */ - char * pp = &bigbuf_net[128]; /* get random space farther out... */ - memset (bigbuf_net, 0, 256); /* clear it all first */ - while (x > 0) { - sprintf (pp, "%2.2x ", *q); /* clumsy, but works: turn into hex */ - strcat (p, pp); /* and build the final string */ - q++; p++; - x--; - } - holler ("IP options: %s", bigbuf_net); - } /* if x, i.e. any options */ -dol_noop: -#endif /* IP_OPTIONS */ - -/* find out what address the connection was *to* on our end, in case we're - doing a listen-on-any on a multihomed machine. This allows one to - offer different services via different alias addresses, such as the - "virtual web site" hack. */ - memset (bigbuf_net, 0, 64); - cp = &bigbuf_net[32]; - x = sizeof (SA); - rr = getsockname (nnetfd, (SA *) lclend, &x); - if (rr < 0) - holler ("post-rcv getsockname failed"); - strcpy (cp, inet_ntoa (lclend->sin_addr)); - -/* now check out who it is. We don't care about mismatched DNS names here, - but any ADDR and PORT we specified had better fucking well match the caller. - Converting from addr to inet_ntoa and back again is a bit of a kludge, but - gethostpoop wants a string and there's much gnarlier code out there already, - so I don't feel bad. - The *real* question is why BFD sockets wasn't designed to allow listens for - connections *from* specific hosts/ports, instead of requiring the caller to - accept the connection and then reject undesireable ones by closing. In - other words, we need a TCP MSG_PEEK. */ - z = ntohs (remend->sin_port); - strcpy (bigbuf_net, inet_ntoa (remend->sin_addr)); - whozis = gethostpoop (bigbuf_net, o_nflag); - errno = 0; - x = 0; /* use as a flag... */ - if (rad) /* xxx: fix to go down the *list* if we have one? */ - if (memcmp (rad, whozis->iaddrs, sizeof (SA))) - x = 1; - if (rp) - if (z != rp) - x = 1; - if (x) /* guilty! */ - bail ("invalid connection to [%s] from %s [%s] %d", - cp, whozis->name, whozis->addrs[0], z); - holler ("connect to [%s] from %s [%s] %d", /* oh, you're okay.. */ - cp, whozis->name, whozis->addrs[0], z); - return (nnetfd); /* open! */ - -dol_tmo: - errno = ETIMEDOUT; /* fake it */ -dol_err: - close (nnetfd); - return (-1); -} /* dolisten */ - -/* udptest : - fire a couple of packets at a UDP target port, just to see if it's really - there. On BSD kernels, ICMP host/port-unreachable errors get delivered to - our socket as ECONNREFUSED write errors. On SV kernels, we lose; we'll have - to collect and analyze raw ICMP ourselves a la satan's probe_udp_ports - backend. Guess where one could swipe the appropriate code from... - - Use the time delay between writes if given, otherwise use the "tcp ping" - trick for getting the RTT. [I got that idea from pluvius, and warped it.] - Return either the original fd, or clean up and return -1. */ -int udptest (fd, where) - int fd; - IA * where; -{ - register int rr; - - rr = write (fd, bigbuf_in, 1); - if (rr != 1) - holler ("udptest first write failed?! errno %d", errno); - if (o_wait) - sleep (o_wait); - else { -/* use the tcp-ping trick: try connecting to a normally refused port, which - causes us to block for the time that SYN gets there and RST gets back. - Not completely reliable, but it *does* mostly work. */ - o_udpmode = 0; /* so doconnect does TCP this time */ -/* Set a temporary connect timeout, so packet filtration doesnt cause - us to hang forever, and hit it */ - o_wait = 5; /* enough that we'll notice?? */ - rr = doconnect (where, SLEAZE_PORT, 0, 0); - if (rr > 0) - close (rr); /* in case it *did* open */ - o_wait = 0; /* reset it */ - o_udpmode++; /* we *are* still doing UDP, right? */ - } /* if o_wait */ - errno = 0; /* clear from sleep */ - rr = write (fd, bigbuf_in, 1); - if (rr == 1) /* if write error, no UDP listener */ - return (fd); - close (fd); /* use it or lose it! */ - return (-1); -} /* udptest */ - -/* oprint : - Hexdump bytes shoveled either way to a running logfile, in the format: -D offset - - - - --- 16 bytes --- - - - - # .... ascii ..... - where "which" sets the direction indicator, D: - 0 -- sent to network, or ">" - 1 -- rcvd and printed to stdout, or "<" - and "buf" and "n" are data-block and length. If the current block generates - a partial line, so be it; we *want* that lockstep indication of who sent - what when. Adapted from dgaudet's original example -- but must be ripping - *fast*, since we don't want to be too disk-bound... */ -void oprint (which, buf, n) - int which; - char * buf; - int n; -{ - int bc; /* in buffer count */ - int obc; /* current "global" offset */ - int soc; /* stage write count */ - register unsigned char * p; /* main buf ptr; m.b. unsigned here */ - register unsigned char * op; /* out hexdump ptr */ - register unsigned char * a; /* out asc-dump ptr */ - register int x; - register unsigned int y; - - if (! ofd) - bail ("oprint called with no open fd?!"); - if (n == 0) - return; - - op = stage; - if (which) { - *op = '<'; - obc = wrote_out; /* use the globals! */ - } else { - *op = '>'; - obc = wrote_net; - } - op++; /* preload "direction" */ - *op = ' '; - p = (unsigned char *) buf; - bc = n; - stage[59] = '#'; /* preload separator */ - stage[60] = ' '; - - while (bc) { /* for chunk-o-data ... */ - x = 16; - soc = 78; /* len of whole formatted line */ - if (bc < x) { - soc = soc - 16 + bc; /* fiddle for however much is left */ - x = (bc * 3) + 11; /* 2 digits + space per, after D & offset */ - op = &stage[x]; - x = 16 - bc; - while (x) { - *op++ = ' '; /* preload filler spaces */ - *op++ = ' '; - *op++ = ' '; - x--; - } - x = bc; /* re-fix current linecount */ - } /* if bc < x */ - - bc -= x; /* fix wrt current line size */ - sprintf (&stage[2], "%8.8x ", obc); /* xxx: still slow? */ - obc += x; /* fix current offset */ - op = &stage[11]; /* where hex starts */ - a = &stage[61]; /* where ascii starts */ - - while (x) { /* for line of dump, however long ... */ - y = (int)(*p >> 4); /* hi half */ - *op = hexnibs[y]; - op++; - y = (int)(*p & 0x0f); /* lo half */ - *op = hexnibs[y]; - op++; - *op = ' '; - op++; - if ((*p > 31) && (*p < 127)) - *a = *p; /* printing */ - else - *a = '.'; /* nonprinting, loose def */ - a++; - p++; - x--; - } /* while x */ - *a = '\n'; /* finish the line */ - x = write (ofd, stage, soc); - if (x < 0) - bail ("ofd write err"); - } /* while bc */ -} /* oprint */ - -#ifdef TELNET -USHORT o_tn = 0; /* global -t option */ - -/* atelnet : - Answer anything that looks like telnet negotiation with don't/won't. - This doesn't modify any data buffers, update the global output count, - or show up in a hexdump -- it just shits into the outgoing stream. - Idea and codebase from Mudge@l0pht.com. */ -void atelnet (buf, size) - unsigned char * buf; /* has to be unsigned here! */ - unsigned int size; + + if (lo > hi) { + cp = hi; + hi = lo; + lo = cp; + } + + /* Load ports sequentially. */ + for (cp = lo; cp <= hi; cp++) { + portlist[x] = calloc(1, PORT_MAX_LEN); + if (portlist[x] == NULL) + err(1, NULL); + snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); + x++; + } + + /* Randomly swap ports. */ + if (rflag) { + int y; + char *c; + + for (x = 0; x <= (hi - lo); x++) { + y = (arc4random() & 0xFFFF) % (hi - lo); + c = portlist[x]; + portlist[x] = portlist[y]; + portlist[y] = c; + } + } + } else { +#ifdef ANDROID + hi = atoi(p); +#else + hi = strtonum(p, 1, PORT_MAX, &errstr); + if (errstr) + errx(1, "port number %s: %s", errstr, p); +#endif + portlist[0] = strdup(p); + if (portlist[0] == NULL) + err(1, NULL); + } +} + +/* + * udptest() + * Do a few writes to see if the UDP port is there. + * XXX - Better way of doing this? Doesn't work for IPv6. + * Also fails after around 100 ports checked. + */ +int +udptest(int s) { - static unsigned char obuf [4]; /* tiny thing to build responses into */ - register int x; - register unsigned char y; - register unsigned char * p; - - y = 0; - p = buf; - x = size; - while (x > 0) { - if (*p != 255) /* IAC? */ - goto notiac; - obuf[0] = 255; - p++; x--; - if ((*p == 251) || (*p == 252)) /* WILL or WONT */ - y = 254; /* -> DONT */ - if ((*p == 253) || (*p == 254)) /* DO or DONT */ - y = 252; /* -> WONT */ - if (y) { - obuf[1] = y; - p++; x--; - obuf[2] = *p; /* copy actual option byte */ - (void) write (netfd, obuf, 3); -/* if one wanted to bump wrote_net or do a hexdump line, here's the place */ - y = 0; - } /* if y */ -notiac: - p++; x--; - } /* while x */ -} /* atelnet */ -#endif /* TELNET */ - -/* readwrite : - handle stdin/stdout/network I/O. Bwahaha!! -- the select loop from hell. - In this instance, return what might become our exit status. */ -int readwrite (fd) - int fd; + int i, ret; + + for (i = 0; i <= 3; i++) { + if (write(s, "X", 1) == 1) + ret = 1; + else + ret = -1; + } + return (ret); +} + +void +set_common_sockopts(int s) { - register int rr; - register char * zp; /* stdin buf ptr */ - register char * np; /* net-in buf ptr */ - unsigned int rzleft; - unsigned int rnleft; - USHORT netretry; /* net-read retry counter */ - USHORT wretry; /* net-write sanity counter */ - USHORT wfirst; /* one-shot flag to skip first net read */ - -/* if you don't have all this FD_* macro hair in sys/types.h, you'll have to - either find it or do your own bit-bashing: *ding1 |= (1 << fd), etc... */ - if (fd > FD_SETSIZE) { - holler ("Preposterous fd value %d", fd); - return (1); - } - FD_SET (fd, ding1); /* global: the net is open */ - netretry = 2; - wfirst = 0; - rzleft = rnleft = 0; - if (insaved) { - rzleft = insaved; /* preload multi-mode fakeouts */ - zp = bigbuf_in; - wfirst = 1; - if (Single) /* if not scanning, this is a one-off first */ - insaved = 0; /* buffer left over from argv construction, */ - else { - FD_CLR (0, ding1); /* OR we've already got our repeat chunk, */ - close (0); /* so we won't need any more stdin */ - } /* Single */ - } /* insaved */ - if (o_interval) - sleep (o_interval); /* pause *before* sending stuff, too */ - errno = 0; /* clear from sleep, close, whatever */ - -/* and now the big ol' select shoveling loop ... */ - while (FD_ISSET (fd, ding1)) { /* i.e. till the *net* closes! */ - wretry = 8200; /* more than we'll ever hafta write */ - if (wfirst) { /* any saved stdin buffer? */ - wfirst = 0; /* clear flag for the duration */ - goto shovel; /* and go handle it first */ - } - *ding2 = *ding1; /* FD_COPY ain't portable... */ -/* some systems, notably linux, crap into their select timers on return, so - we create a expendable copy and give *that* to select. *Fuck* me ... */ - if (timer1) - memcpy (timer2, timer1, sizeof (struct timeval)); - rr = select (16, ding2, 0, 0, timer2); /* here it is, kiddies */ - if (rr < 0) { - if (errno != EINTR) { /* might have gotten ^Zed, etc ?*/ - holler ("select fuxored"); - close (fd); - return (1); + int x = 1; + +#ifndef ANDROID + if (Sflag) { + if (setsockopt(s, IPPROTO_TCP, TCP_MD5SIG, + &x, sizeof(x)) == -1) + err(1, NULL); } - } /* select fuckup */ -/* if we have a timeout AND stdin is closed AND we haven't heard anything - from the net during that time, assume it's dead and close it too. */ - if (rr == 0) { - if (! FD_ISSET (0, ding1)) - netretry--; /* we actually try a coupla times. */ - if (! netretry) { - if (o_verbose > 1) /* normally we don't care */ - holler ("net timeout"); - close (fd); - return (0); /* not an error! */ +#endif + if (Dflag) { + if (setsockopt(s, SOL_SOCKET, SO_DEBUG, + &x, sizeof(x)) == -1) + err(1, NULL); } - } /* select timeout */ -/* xxx: should we check the exception fds too? The read fds seem to give - us the right info, and none of the examples I found bothered. */ - -/* Ding!! Something arrived, go check all the incoming hoppers, net first */ - if (FD_ISSET (fd, ding2)) { /* net: ding! */ - rr = read (fd, bigbuf_net, BIGSIZ); - if (rr <= 0) { - FD_CLR (fd, ding1); /* net closed, we'll finish up... */ - rzleft = 0; /* can't write anymore: broken pipe */ - } else { - rnleft = rr; - np = bigbuf_net; -#ifdef TELNET - if (o_tn) - atelnet (np, rr); /* fake out telnet stuff */ -#endif /* TELNET */ - } /* if rr */ -Debug (("got %d from the net, errno %d", rr, errno)) - } /* net:ding */ - -/* if we're in "slowly" mode there's probably still stuff in the stdin - buffer, so don't read unless we really need MORE INPUT! MORE INPUT! */ - if (rzleft) - goto shovel; - -/* okay, suck more stdin */ - if (FD_ISSET (0, ding2)) { /* stdin: ding! */ - rr = read (0, bigbuf_in, BIGSIZ); -/* Considered making reads here smaller for UDP mode, but 8192-byte - mobygrams are kinda fun and exercise the reassembler. */ - if (rr <= 0) { /* at end, or fukt, or ... */ - FD_CLR (0, ding1); /* disable and close stdin */ - close (0); - } else { - rzleft = rr; - zp = bigbuf_in; -/* special case for multi-mode -- we'll want to send this one buffer to every - open TCP port or every UDP attempt, so save its size and clean up stdin */ - if (! Single) { /* we might be scanning... */ - insaved = rr; /* save len */ - FD_CLR (0, ding1); /* disable further junk from stdin */ - close (0); /* really, I mean it */ - } /* Single */ - } /* if rr/read */ - } /* stdin:ding */ - -shovel: -/* now that we've dingdonged all our thingdings, send off the results. - Geez, why does this look an awful lot like the big loop in "rsh"? ... - not sure if the order of this matters, but write net -> stdout first. */ - -/* sanity check. Works because they're both unsigned... */ - if ((rzleft > 8200) || (rnleft > 8200)) { - holler ("Bogus buffers: %d, %d", rzleft, rnleft); - rzleft = rnleft = 0; - } -/* net write retries sometimes happen on UDP connections */ - if (! wretry) { /* is something hung? */ - holler ("too many output retries"); - return (1); - } - if (rnleft) { - rr = write (1, np, rnleft); - if (rr > 0) { - if (o_wfile) - oprint (1, np, rr); /* log the stdout */ - np += rr; /* fix up ptrs and whatnot */ - rnleft -= rr; /* will get sanity-checked above */ - wrote_out += rr; /* global count */ +#ifndef ANDROID + if (jflag) { + if (setsockopt(s, SOL_SOCKET, SO_JUMBO, + &x, sizeof(x)) == -1) + err(1, NULL); } -Debug (("wrote %d to stdout, errno %d", rr, errno)) - } /* rnleft */ - if (rzleft) { - if (o_interval) /* in "slowly" mode ?? */ - rr = findline (zp, rzleft); - else - rr = rzleft; - rr = write (fd, zp, rr); /* one line, or the whole buffer */ - if (rr > 0) { - if (o_wfile) - oprint (0, zp, rr); /* log what got sent */ - zp += rr; - rzleft -= rr; - wrote_net += rr; /* global count */ + if (Tflag != -1) { + if (setsockopt(s, IPPROTO_IP, IP_TOS, + &Tflag, sizeof(Tflag)) == -1) + err(1, "set IP ToS"); } -Debug (("wrote %d to net, errno %d", rr, errno)) - } /* rzleft */ - if (o_interval) { /* cycle between slow lines, or ... */ - sleep (o_interval); - errno = 0; /* clear from sleep */ - continue; /* ...with hairy select loop... */ - } - if ((rzleft) || (rnleft)) { /* shovel that shit till they ain't */ - wretry--; /* none left, and get another load */ - goto shovel; - } - } /* while ding1:netfd is open */ - -/* XXX: maybe want a more graceful shutdown() here, or screw around with - linger times?? I suspect that I don't need to since I'm always doing - blocking reads and writes and my own manual "last ditch" efforts to read - the net again after a timeout. I haven't seen any screwups yet, but it's - not like my test network is particularly busy... */ - close (fd); - return (0); -} /* readwrite */ - -/* main : - now we pull it all together... */ -int main (argc, argv) - int argc; - char ** argv; -{ -#ifndef HAVE_GETOPT - extern char * optarg; - extern int optind, optopt; -#endif - register int x; - register char *cp; - HINF * gp; - HINF * whereto = NULL; - HINF * wherefrom = NULL; - IA * ouraddr = NULL; - IA * themaddr = NULL; - USHORT o_lport = 0; - USHORT ourport = 0; - USHORT loport = 0; /* for scanning stuff */ - USHORT hiport = 0; - USHORT curport = 0; - char * randports = NULL; - -#ifdef HAVE_BIND -/* can *you* say "cc -yaddayadda netcat.c -lresolv -l44bsd" on SunLOSs? */ - res_init(); -#endif -/* I was in this barbershop quartet in Skokie IL ... */ -/* round up the usual suspects, i.e. malloc up all the stuff we need */ - lclend = (SAI *) Hmalloc (sizeof (SA)); - remend = (SAI *) Hmalloc (sizeof (SA)); - bigbuf_in = Hmalloc (BIGSIZ); - bigbuf_net = Hmalloc (BIGSIZ); - ding1 = (fd_set *) Hmalloc (sizeof (fd_set)); - ding2 = (fd_set *) Hmalloc (sizeof (fd_set)); - portpoop = (PINF *) Hmalloc (sizeof (PINF)); - - errno = 0; - gatesptr = 4; - h_errno = 0; - -/* catch a signal or two for cleanup */ - signal (SIGINT, catch); - signal (SIGQUIT, catch); - signal (SIGTERM, catch); -/* and suppress others... */ -#ifdef SIGURG - signal (SIGURG, SIG_IGN); -#endif -#ifdef SIGPIPE - signal (SIGPIPE, SIG_IGN); /* important! */ #endif + if (Iflag) { + if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &Iflag, sizeof(Iflag)) == -1) + err(1, "set TCP receive buffer size"); + } + if (Oflag) { + if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &Oflag, sizeof(Oflag)) == -1) + err(1, "set TCP send buffer size"); + } +} -/* if no args given at all, get 'em from stdin, construct an argv, and hand - anything left over to readwrite(). */ - if (argc == 1) { - cp = argv[0]; - argv = (char **) Hmalloc (128 * sizeof (char *)); /* XXX: 128? */ - argv[0] = cp; /* leave old prog name intact */ - cp = Hmalloc (BIGSIZ); - argv[1] = cp; /* head of new arg block */ - fprintf (stderr, "Cmd line: "); - fflush (stderr); /* I dont care if it's unbuffered or not! */ - insaved = read (0, cp, BIGSIZ); /* we're gonna fake fgets() here */ - if (insaved <= 0) - bail ("wrong"); - x = findline (cp, insaved); - if (x) - insaved -= x; /* remaining chunk size to be sent */ - if (insaved) /* which might be zero... */ - memcpy (bigbuf_in, &cp[x], insaved); - cp = strchr (argv[1], '\n'); - if (cp) - *cp = '\0'; - cp = strchr (argv[1], '\r'); /* look for ^M too */ - if (cp) - *cp = '\0'; - -/* find and stash pointers to remaining new "args" */ - cp = argv[1]; - cp++; /* skip past first char */ - x = 2; /* we know argv 0 and 1 already */ - for (; *cp != '\0'; cp++) { - if (*cp == ' ') { - *cp = '\0'; /* smash all spaces */ - continue; - } else { - if (*(cp-1) == '\0') { - argv[x] = cp; - x++; +#ifndef ANDROID +int +map_tos(char *s, int *val) +{ + /* DiffServ Codepoints and other TOS mappings */ + const struct toskeywords { + const char *keyword; + int val; + } *t, toskeywords[] = { + { "af11", IPTOS_DSCP_AF11 }, + { "af12", IPTOS_DSCP_AF12 }, + { "af13", IPTOS_DSCP_AF13 }, + { "af21", IPTOS_DSCP_AF21 }, + { "af22", IPTOS_DSCP_AF22 }, + { "af23", IPTOS_DSCP_AF23 }, + { "af31", IPTOS_DSCP_AF31 }, + { "af32", IPTOS_DSCP_AF32 }, + { "af33", IPTOS_DSCP_AF33 }, + { "af41", IPTOS_DSCP_AF41 }, + { "af42", IPTOS_DSCP_AF42 }, + { "af43", IPTOS_DSCP_AF43 }, + { "critical", IPTOS_PREC_CRITIC_ECP }, + { "cs0", IPTOS_DSCP_CS0 }, + { "cs1", IPTOS_DSCP_CS1 }, + { "cs2", IPTOS_DSCP_CS2 }, + { "cs3", IPTOS_DSCP_CS3 }, + { "cs4", IPTOS_DSCP_CS4 }, + { "cs5", IPTOS_DSCP_CS5 }, + { "cs6", IPTOS_DSCP_CS6 }, + { "cs7", IPTOS_DSCP_CS7 }, + { "ef", IPTOS_DSCP_EF }, + { "inetcontrol", IPTOS_PREC_INTERNETCONTROL }, + { "lowdelay", IPTOS_LOWDELAY }, + { "netcontrol", IPTOS_PREC_NETCONTROL }, + { "reliability", IPTOS_RELIABILITY }, + { "throughput", IPTOS_THROUGHPUT }, + { NULL, -1 }, + }; + + for (t = toskeywords; t->keyword != NULL; t++) { + if (strcmp(s, t->keyword) == 0) { + *val = t->val; + return (1); + } } - } /* if space */ - } /* for cp */ - argc = x; - } /* if no args given */ - -/* If your shitbox doesn't have getopt, step into the nineties already. */ -/* optarg, optind = next-argv-component [i.e. flag arg]; optopt = last-char */ - while ((x = getopt (argc, argv, "ae:g:G:hi:lno:p:rs:tuvw:z")) != EOF) { -/* Debug (("in go: x now %c, optarg %x optind %d", x, optarg, optind)) */ - switch (x) { - case 'a': - bail ("all-A-records NIY"); - o_alla++; break; -#ifdef GAPING_SECURITY_HOLE - case 'e': /* prog to exec */ - pr00gie = optarg; - break; -#endif - case 'G': /* srcrt gateways pointer val */ - x = atoi (optarg); - if ((x) && (x == (x & 0x1c))) /* mask off bits of fukt values */ - gatesptr = x; - else - bail ("invalid hop pointer %d, must be multiple of 4 <= 28", x); - break; - case 'g': /* srcroute hop[s] */ - if (gatesidx > 8) - bail ("too many -g hops"); - if (gates == NULL) /* eat this, Billy-boy */ - gates = (HINF **) Hmalloc (sizeof (HINF *) * 10); - gp = gethostpoop (optarg, o_nflag); - if (gp) - gates[gatesidx] = gp; - gatesidx++; - break; - case 'h': - errno = 0; -#ifdef HAVE_HELP - helpme(); /* exits by itself */ -#else - bail ("no help available, dork -- RTFS"); + + return (0); +} #endif - case 'i': /* line-interval time */ - o_interval = atoi (optarg) & 0xffff; - if (! o_interval) - bail ("invalid interval time %s", optarg); - break; - case 'l': /* listen mode */ - o_listen++; break; - case 'n': /* numeric-only, no DNS lookups */ - o_nflag++; break; - case 'o': /* hexdump log */ - stage = (unsigned char *) optarg; - o_wfile++; break; - case 'p': /* local source port */ - o_lport = getportpoop (optarg, 0); - if (o_lport == 0) - bail ("invalid local port %s", optarg); - break; - case 'r': /* randomize various things */ - o_random++; break; - case 's': /* local source address */ -/* do a full lookup [since everything else goes through the same mill], - unless -n was previously specified. In fact, careful placement of -n can - be useful, so we'll still pass o_nflag here instead of forcing numeric. */ - wherefrom = gethostpoop (optarg, o_nflag); - ouraddr = &wherefrom->iaddrs[0]; - break; -#ifdef TELNET - case 't': /* do telnet fakeout */ - o_tn++; break; -#endif /* TELNET */ - case 'u': /* use UDP */ - o_udpmode++; break; - case 'v': /* verbose */ - o_verbose++; break; - case 'w': /* wait time */ - o_wait = atoi (optarg); - if (o_wait <= 0) - bail ("invalid wait-time %s", optarg); - timer1 = (struct timeval *) Hmalloc (sizeof (struct timeval)); - timer2 = (struct timeval *) Hmalloc (sizeof (struct timeval)); - timer1->tv_sec = o_wait; /* we need two. see readwrite()... */ - break; - case 'z': /* little or no data xfer */ - o_zero++; - break; - default: - errno = 0; - bail ("nc -h for help"); - } /* switch x */ - } /* while getopt */ - -/* other misc initialization */ -Debug (("fd_set size %d", sizeof (*ding1))) /* how big *is* it? */ - FD_SET (0, ding1); /* stdin *is* initially open */ - if (o_random) { - SRAND (time (0)); - randports = Hmalloc (65536); /* big flag array for ports */ - } -#ifdef GAPING_SECURITY_HOLE - if (pr00gie) { - close (0); /* won't need stdin */ - o_wfile = 0; /* -o with -e is meaningless! */ - ofd = 0; - } -#endif /* G_S_H */ - if (o_wfile) { - ofd = open (stage, O_WRONLY | O_CREAT | O_TRUNC, 0664); - if (ofd <= 0) /* must be > extant 0/1/2 */ - bail ("can't open %s", stage); - stage = (unsigned char *) Hmalloc (100); - } - -/* optind is now index of first non -x arg */ -Debug (("after go: x now %c, optarg %x optind %d", x, optarg, optind)) -/* Debug (("optind up to %d at host-arg %s", optind, argv[optind])) */ -/* gonna only use first addr of host-list, like our IQ was normal; if you wanna - get fancy with addresses, look up the list yourself and plug 'em in for now. - unless we finally implement -a, that is. */ - if (argv[optind]) - whereto = gethostpoop (argv[optind], o_nflag); - if (whereto && whereto->iaddrs) - themaddr = &whereto->iaddrs[0]; - if (themaddr) - optind++; /* skip past valid host lookup */ - errno = 0; - h_errno = 0; - -/* Handle listen mode here, and exit afterward. Only does one connect; - this is arguably the right thing to do. A "persistent listen-and-fork" - mode a la inetd has been thought about, but not implemented. A tiny - wrapper script can handle such things... */ - if (o_listen) { - curport = 0; /* rem port *can* be zero here... */ - if (argv[optind]) { /* any rem-port-arg? */ - curport = getportpoop (argv[optind], 0); - if (curport == 0) /* if given, demand correctness */ - bail ("invalid port %s", argv[optind]); - } /* if port-arg */ - netfd = dolisten (themaddr, curport, ouraddr, o_lport); -/* dolisten does its own connect reporting, so we don't holler anything here */ - if (netfd > 0) { -#ifdef GAPING_SECURITY_HOLE - if (pr00gie) /* -e given? */ - doexec (netfd); -#endif /* GAPING_SECURITY_HOLE */ - x = readwrite (netfd); /* it even works with UDP! */ - if (o_verbose > 1) /* normally we don't care */ - holler (wrote_txt, wrote_net, wrote_out); - exit (x); /* "pack out yer trash" */ - } else /* if no netfd */ - bail ("no connection"); - } /* o_listen */ - -/* fall thru to outbound connects. Now we're more picky about args... */ - if (! themaddr) - bail ("no destination"); - if (argv[optind] == NULL) - bail ("no port[s] to connect to"); - if (argv[optind + 1]) /* look ahead: any more port args given? */ - Single = 0; /* multi-mode, case A */ - ourport = o_lport; /* which can be 0 */ - -/* everything from here down is treated as as ports and/or ranges thereof, so - it's all enclosed in this big ol' argv-parsin' loop. Any randomization is - done within each given *range*, but in separate chunks per each succeeding - argument, so we can control the pattern somewhat. */ - while (argv[optind]) { - hiport = loport = 0; - cp = strchr (argv[optind], '-'); /* nn-mm range? */ - if (cp) { - *cp = '\0'; - cp++; - hiport = getportpoop (cp, 0); - if (hiport == 0) - bail ("invalid port %s", cp); - } /* if found a dash */ - loport = getportpoop (argv[optind], 0); - if (loport == 0) - bail ("invalid port %s", argv[optind]); - if (hiport > loport) { /* was it genuinely a range? */ - Single = 0; /* multi-mode, case B */ - curport = hiport; /* start high by default */ - if (o_random) { /* maybe populate the random array */ - loadports (randports, loport, hiport); - curport = nextport (randports); - } - } else /* not a range, including args like "25-25" */ - curport = loport; -Debug (("Single %d, curport %d", Single, curport)) - -/* Now start connecting to these things. curport is already preloaded. */ - while (loport <= curport) { - if ((! o_lport) && (o_random)) { /* -p overrides random local-port */ - ourport = (RAND() & 0xffff); /* random local-bind -- well above */ - if (ourport < 8192) /* resv and any likely listeners??? */ - ourport += 8192; /* if it *still* conflicts, use -s. */ - } - curport = getportpoop (NULL, curport); - netfd = doconnect (themaddr, curport, ouraddr, ourport); -Debug (("netfd %d from port %d to port %d", netfd, ourport, curport)) - if (netfd > 0) - if (o_zero && o_udpmode) /* if UDP scanning... */ - netfd = udptest (netfd, themaddr); - if (netfd > 0) { /* Yow, are we OPEN YET?! */ - x = 0; /* pre-exit status */ - holler ("%s [%s] %d (%s) open", - whereto->name, whereto->addrs[0], curport, portpoop->name); -#ifdef GAPING_SECURITY_HOLE - if (pr00gie) /* exec is valid for outbound, too */ - doexec (netfd); -#endif /* GAPING_SECURITY_HOLE */ - if (! o_zero) - x = readwrite (netfd); /* go shovel shit */ - } else { /* no netfd... */ - x = 1; /* preload exit status for later */ -/* if we're scanning at a "one -v" verbosity level, don't print refusals. - Give it another -v if you want to see everything. */ - if ((Single || (o_verbose > 1)) || (errno != ECONNREFUSED)) - holler ("%s [%s] %d (%s)", - whereto->name, whereto->addrs[0], curport, portpoop->name); - } /* if netfd */ - close (netfd); /* just in case we didn't already */ - if (o_interval) - sleep (o_interval); /* if -i, delay between ports too */ - if (o_random) - curport = nextport (randports); - else - curport--; /* just decrement... */ - } /* while curport within current range */ - optind++; - } /* while remaining port-args -- end of big argv-ports loop*/ - - errno = 0; - if (o_verbose > 1) /* normally we don't care */ - holler (wrote_txt, wrote_net, wrote_out); - if (Single) - exit (x); /* give us status on one connection */ - exit (0); /* otherwise, we're just done */ -} /* main */ - -#ifdef HAVE_HELP /* unless we wanna be *really* cryptic */ -/* helpme : - the obvious */ + void -helpme() +help(void) { - o_verbose = 1; - holler ("[v1.10]\n\ -connect to somewhere: nc [-options] hostname port[s] [ports] ... \n\ -listen for inbound: nc -l -p port [-options] [hostname] [port]\n\ -options:"); -/* sigh, this necessarily gets messy. And the trailing \ characters may be - interpreted oddly by some compilers, generating or not generating extra - newlines as they bloody please. u-fix... */ -#ifdef GAPING_SECURITY_HOLE /* needs to be separate holler() */ - holler ("\ - -e prog program to exec after connect [dangerous!!]"); -#endif - holler ("\ - -g gateway source-routing hop point[s], up to 8\n\ - -G num source-routing pointer: 4, 8, 12, ...\n\ - -h this cruft\n\ - -i secs delay interval for lines sent, ports scanned\n\ - -l listen mode, for inbound connects\n\ - -n numeric-only IP addresses, no DNS\n\ - -o file hex dump of traffic\n\ - -p port local port number\n\ - -r randomize local and remote ports\n\ - -s addr local source address"); -#ifdef TELNET - holler ("\ - -t answer TELNET negotiation"); -#endif - holler ("\ - -u UDP mode\n\ - -v verbose [use twice to be more verbose]\n\ - -w secs timeout for connects and final net reads\n\ - -z zero-I/O mode [used for scanning]"); - bail ("port numbers can be individual or ranges: lo-hi [inclusive]"); -} /* helpme */ -#endif /* HAVE_HELP */ - -/* None genuine without this seal! _H*/ + usage(0); + fprintf(stderr, "\tCommand Summary:\n\ + \t-4 Use IPv4\n\ + \t-6 Use IPv6\n\ + \t-D Enable the debug socket option\n\ + \t-d Detach from stdin\n\ + \t-h This help text\n\ + \t-I length TCP receive buffer length\n\ + \t-i secs\t Delay interval for lines sent, ports scanned\n\ + \t-k Keep inbound sockets open for multiple connects\n\ + \t-l Listen mode, for inbound connects\n\ + \t-n Suppress name/port resolutions\n\ + \t-O length TCP send buffer length\n\ + \t-P proxyuser\tUsername for proxy authentication\n\ + \t-p port\t Specify local port for remote connects\n\ + \t-r Randomize remote ports\n\ + \t-S Enable the TCP MD5 signature option\n\ + \t-s addr\t Local source address\n\ + \t-T toskeyword\tSet IP Type of Service\n\ + \t-t Answer TELNET negotiation\n\ + \t-U Use UNIX domain socket\n\ + \t-u UDP mode\n\ + \t-V rtable Specify alternate routing table\n\ + \t-v Verbose\n\ + \t-w secs\t Timeout for connects and final net reads\n\ + \t-X proto Proxy protocol: \"4\", \"5\" (SOCKS) or \"connect\"\n\ + \t-x addr[:port]\tSpecify proxy address and port\n\ + \t-z Zero-I/O mode [used for scanning]\n\ + Port numbers can be individual or ranges: lo-hi [inclusive]\n"); + exit(1); +} + +void +usage(int ret) +{ + fprintf(stderr, + "usage: nc [-46DdhklnrStUuvz] [-I length] [-i interval] [-O length]\n" + "\t [-P proxy_username] [-p source_port] [-s source] [-T ToS]\n" + "\t [-V rtable] [-w timeout] [-X proxy_protocol]\n" + "\t [-x proxy_address[:port]] [destination] [port]\n"); + if (ret) + exit(1); +} diff --git a/scripts/README b/scripts/README deleted file mode 100644 index 07aee0c..0000000 --- a/scripts/README +++ /dev/null @@ -1,5 +0,0 @@ -A collection of example scripts that use netcat as a backend, each -documented by its own internal comments. - -I'll be the first to admit that some of these are seriously *sick*, -but they do work and are quite useful to me on a daily basis. diff --git a/scripts/alta b/scripts/alta deleted file mode 100755 index 7a09176..0000000 --- a/scripts/alta +++ /dev/null @@ -1,33 +0,0 @@ -#! /bin/sh -## special handler for altavista, since they only hand out chunks of 10 at -## a time. Tries to isolate out results without the leading/trailing trash. -## multiword arguments are foo+bar, as usual. -## Second optional arg switches the "what" field, to e.g. "news" - -test "${1}" = "" && echo 'Needs an argument to search for!' && exit 1 -WHAT="web" -test "${2}" && WHAT="${2}" - -# convert multiple args -PLUSARG="`echo $* | sed 's/ /+/g'`" - -# Plug in arg. only doing simple-q for now; pg=aq for advanced-query -# embedded quotes define phrases; otherwise it goes wild on multi-words -QB="GET /cgi-bin/query?pg=q&what=${WHAT}&fmt=c&q=\"${PLUSARG}\"" - -# ping 'em once, to get the routing warm -nc -z -w 8 www.altavista.digital.com 24015 2> /dev/null -echo "=== Altavista ===" - -for xx in 0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 \ - 190 200 210 220 230 240 250 260 270 280 290 300 310 320 330 340 350 ; do - echo "${QB}&stq=${xx}" | nc -w 15 www.altavista.digital.com 80 | \ - egrep '^<a href="http://' -done - -exit 0 - -# old filter stuff - sed -e '/Documents .* matching .* query /,/query?.*stq=.* Document/p' \ - -e d - diff --git a/scripts/bsh b/scripts/bsh deleted file mode 100755 index 796e480..0000000 --- a/scripts/bsh +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/sh -## a little wrapper to "password" and re-launch a shell-listener. -## Arg is taken as the port to listen on. Define "NC" to point wherever. - -NC=nc - -case "$1" in - ?* ) - LPN="$1" - export LPN - sleep 1 - echo "-l -p $LPN -e $0" | $NC > /dev/null 2>&1 & - echo "launched on port $LPN" - exit 0 - ;; -esac - -# here we play inetd -echo "-l -p $LPN -e $0" | $NC > /dev/null 2>&1 & - -while read qq ; do -case "$qq" in -# here's yer password - gimme ) - cd / - exec csh -i - ;; -esac -done diff --git a/scripts/dist.sh b/scripts/dist.sh deleted file mode 100755 index 4d2534a..0000000 --- a/scripts/dist.sh +++ /dev/null @@ -1,23 +0,0 @@ -#! /bin/sh -## This is a quick example listen-exec server, which was used for a while to -## distribute netcat prereleases. It illustrates use of netcat both as a -## "fake inetd" and a syslogger, and how easy it then is to crock up a fairly -## functional server that restarts its own listener and does full connection -## logging. In a half-screen of shell script!! - -PORT=31337 - -sleep 1 -SRC=`tail -1 dist.log` -echo "<36>elite: ${SRC}" | ./nc -u -w 1 localhost 514 > /dev/null 2>&1 -echo ";;; Hi, ${SRC}..." -echo ";;; This is a PRERELEASE version of 'netcat', tar/gzip/uuencoded." -echo ";;; Unless you are capturing this somehow, it won't do you much good." -echo ";;; Ready?? Here it comes! Have phun ..." -sleep 8 -cat dist.file -sleep 1 -./nc -v -l -p ${PORT} -e dist.sh < /dev/null >> dist.log 2>&1 & -sleep 1 -echo "<36>elite: done" | ./nc -u -w 1 localhost 514 > /dev/null 2>&1 -exit 0 diff --git a/scripts/irc b/scripts/irc deleted file mode 100755 index 3557d7a..0000000 --- a/scripts/irc +++ /dev/null @@ -1,79 +0,0 @@ -#! /bin/sh -## Shit-simple script to supply the "privmsg <recipient>" of IRC typein, and -## keep the connection alive. Pipe this thru "nc -v -w 5 irc-server port". -## Note that this mechanism makes the script easy to debug without being live, -## since it just echoes everything bound for the server. -## if you want autologin-type stuff, construct some appropriate files and -## shovel them in using the "<" mechanism. - -# magic arg: if "tick", do keepalive process instead of main loop -if test "$1" = "tick" ; then -# ignore most signals; the parent will nuke the kid -# doesn't stop ^Z, of course. - trap '' 1 2 3 13 14 15 16 - while true ; do - sleep 60 - echo "PONG !" - done -fi - -# top level: fire ourselves off as the keepalive process, and keep track of it -sh $0 tick & -ircpp=$! -echo "[Keepalive: $ircpp]" >&2 -# catch our own batch of signals: hup int quit pipe alrm term urg -trap 'kill -9 $ircpp ; exit 0' 1 2 3 13 14 15 16 -sleep 2 - -sender='' -savecmd='' - -# the big honkin' loop... -while read xx yy ; do - case "${xx}" in -# blank line: do nothing - "") - continue - ;; -# new channel or recipient; if bare ">", we're back to raw literal mode. - ">") - if test "${yy}" ; then - sender="privmsg ${yy} :" - else - sender='' - fi - continue - ;; -# send crud from a file, one line per second. Can you say "skr1pt kidz"?? -# *Note: uses current "recipient" if set. - "<") - if test -f "${yy}" ; then - ( while read zz ; do - sleep 1 - echo "${sender}${zz}" - done ) < "$yy" - echo "[done]" >&2 - else - echo "[File $yy not found]" >&2 - fi - continue - ;; -# do and save a single command, for quick repeat - "/") - if test "${yy}" ; then - savecmd="${yy}" - fi - echo "${savecmd}" - ;; -# default case goes to recipient, just like always - *) - echo "${sender}${xx} ${yy}" - continue - ;; - esac -done - -# parting shot, if you want it -echo "quit :Bye all!" -kill -9 $ircpp -exit 0 diff --git a/scripts/iscan b/scripts/iscan deleted file mode 100755 index 6279bc8..0000000 --- a/scripts/iscan +++ /dev/null @@ -1,35 +0,0 @@ -#! /bin/sh -## duplicate DaveG's ident-scan thingie using netcat. Oooh, he'll be pissed. -## args: target port [port port port ...] -## hose stdout *and* stderr together. -## -## advantages: runs slower than ident-scan, giving remote inetd less cause -## for alarm, and only hits the few known daemon ports you specify. -## disadvantages: requires numeric-only port args, the output sleazitude, -## and won't work for r-services when coming from high source ports. - -case "${2}" in - "" ) echo needs HOST and at least one PORT ; exit 1 ;; -esac - -# ping 'em once and see if they *are* running identd -nc -z -w 9 "$1" 113 || { echo "oops, $1 isn't running identd" ; exit 0 ; } - -# generate a randomish base port -RP=`expr $$ % 999 + 31337` - -TRG="$1" -shift - -while test "$1" ; do - nc -v -w 8 -p ${RP} "$TRG" ${1} < /dev/null > /dev/null & - PROC=$! - sleep 3 - echo "${1},${RP}" | nc -w 4 -r "$TRG" 113 2>&1 - sleep 2 -# does this look like a lamer script or what... - kill -HUP $PROC - RP=`expr ${RP} + 1` - shift -done - diff --git a/scripts/ncp b/scripts/ncp deleted file mode 100755 index 1931b03..0000000 --- a/scripts/ncp +++ /dev/null @@ -1,46 +0,0 @@ -#! /bin/sh -## Like "rcp" but uses netcat on a high port. -## do "ncp targetfile" on the RECEIVING machine -## then do "ncp sourcefile receivinghost" on the SENDING machine -## if invoked as "nzp" instead, compresses transit data. - -## pick your own personal favorite port, which will be used on both ends. -## You should probably change this for your own uses. -MYPORT=23456 - -## if "nc" isn't systemwide or in your PATH, add the right place -# PATH=${HOME}:${PATH} ; export PATH - -test "$3" && echo "too many args" && exit 1 -test ! "$1" && echo "no args?" && exit 1 -me=`echo $0 | sed 's+.*/++'` -test "$me" = "nzp" && echo '[compressed mode]' - -# if second arg, it's a host to send an [extant] file to. -if test "$2" ; then - test ! -f "$1" && echo "can't find $1" && exit 1 - if test "$me" = "nzp" ; then - compress -c < "$1" | nc -v -w 2 $2 $MYPORT && exit 0 - else - nc -v -w 2 $2 $MYPORT < "$1" && exit 0 - fi - echo "transfer FAILED!" - exit 1 -fi - -# fall here for receiver. Ask before trashing existing files -if test -f "$1" ; then - echo -n "Overwrite $1? " - read aa - test ! "$aa" = "y" && echo "[punted!]" && exit 1 -fi -# 30 seconds oughta be pleeeeenty of time, but change if you want. -if test "$me" = "nzp" ; then - nc -v -w 30 -p $MYPORT -l < /dev/null | uncompress -c > "$1" && exit 0 -else - nc -v -w 30 -p $MYPORT -l < /dev/null > "$1" && exit 0 -fi -echo "transfer FAILED!" -# clean up, since even if the transfer failed, $1 is already trashed -rm -f "$1" -exit 1 diff --git a/scripts/probe b/scripts/probe deleted file mode 100755 index c47dc3f..0000000 --- a/scripts/probe +++ /dev/null @@ -1,50 +0,0 @@ -#! /bin/sh -## launch a whole buncha shit at yon victim in no particular order; capture -## stderr+stdout in one place. Run as root for rservice and low -p to work. -## Fairly thorough example of using netcat to collect a lot of host info. -## Will set off every intrusion alarm in existence on a paranoid machine! - -# where .d files are kept; "." if nothing else -DDIR=../data -# address of some well-connected router that groks LSRR -GATE=192.157.69.11 - -# might conceivably wanna change this for different run styles -UCMD='nc -v -w 8' - -test ! "$1" && echo Needs victim arg && exit 1 - -echo '' | $UCMD -w 9 -r "$1" 13 79 6667 2>&1 -echo '0' | $UCMD "$1" 79 2>&1 -# if LSRR was passed thru, should get refusal here: -$UCMD -z -r -g $GATE "$1" 6473 2>&1 -$UCMD -r -z "$1" 6000 4000-4004 111 53 2105 137-140 1-20 540-550 95 87 2>&1 -# -s `hostname` may be wrong for some multihomed machines -echo 'UDP echoecho!' | nc -u -p 7 -s `hostname` -w 3 "$1" 7 19 2>&1 -echo '113,10158' | $UCMD -p 10158 "$1" 113 2>&1 -rservice bin bin | $UCMD -p 1019 "$1" shell 2>&1 -echo QUIT | $UCMD -w 8 -r "$1" 25 158 159 119 110 109 1109 142-144 220 23 2>&1 -# newline after any telnet trash -echo '' -echo PASV | $UCMD -r "$1" 21 2>&1 -echo 'GET /' | $UCMD -w 10 "$1" 80 81 210 70 2>&1 -# sometimes contains useful directory info: -echo 'GET /robots.txt' | $UCMD -w 10 "$1" 80 2>&1 -# now the big red lights go on -rservice bin bin 9600/9600 | $UCMD -p 1020 "$1" login 2>&1 -rservice root root | $UCMD -r "$1" exec 2>&1 -echo 'BEGIN big udp -- everything may look "open" if packet-filtered' -data -g < ${DDIR}/nfs-0.d | $UCMD -i 1 -u "$1" 2049 | od -x 2>&1 -# no wait-time, uses RTT hack -nc -v -z -u -r "$1" 111 66-70 88 53 87 161-164 121-123 213 49 2>&1 -nc -v -z -u -r "$1" 137-140 694-712 747-770 175-180 2103 510-530 2>&1 -echo 'END big udp' -$UCMD -r -z "$1" 175-180 2000-2003 530-533 1524 1525 666 213 8000 6250 2>&1 -# Use our identd-sniffer! -iscan "$1" 21 25 79 80 111 53 6667 6000 2049 119 2>&1 -# this gets pretty intrusive, but what the fuck. Probe for portmap first -if nc -w 5 -z -u "$1" 111 ; then - showmount -e "$1" 2>&1 - rpcinfo -p "$1" 2>&1 -fi -exit 0 diff --git a/scripts/web b/scripts/web deleted file mode 100755 index 382b18e..0000000 --- a/scripts/web +++ /dev/null @@ -1,148 +0,0 @@ -#! /bin/sh -## The web sucks. It is a mighty dismal kludge built out of a thousand -## tiny dismal kludges all band-aided together, and now these bottom-line -## clueless pinheads who never heard of "TCP handshake" want to run -## *commerce* over the damn thing. Ye godz. Welcome to TV of the next -## century -- six million channels of worthless shit to choose from, and -## about as much security as today's cable industry! -## -## Having grown mightily tired of pain in the ass browsers, I decided -## to build the minimalist client. It doesn't handle POST, just GETs, but -## the majority of cgi forms handlers apparently ignore the method anyway. -## A distinct advantage is that it *doesn't* pass on any other information -## to the server, like Referer: or info about your local machine such as -## Netscum tries to! -## -## Since the first version, this has become the *almost*-minimalist client, -## but it saves a lot of typing now. And with netcat as its backend, it's -## totally the balls. Don't have netcat? Get it here in /src/hacks! -## _H* 950824, updated 951009 et seq. -## -## args: hostname [port]. You feed it the filename-parts of URLs. -## In the loop, HOST, PORT, and SAVE do the right things; a null line -## gets the previous spec again [useful for initial timeouts]; EOF to exit. -## Relative URLs behave like a "cd" to wherever the last slash appears, or -## just use the last component with the saved preceding "directory" part. -## "\" clears the "filename" part and asks for just the "directory", and -## ".." goes up one "directory" level while retaining the "filename" part. -## Play around; you'll get used to it. - -if test "$1" = "" ; then - echo Needs hostname arg. - exit 1 -fi -umask 022 - -# optional PATH fixup -# PATH=${HOME}:${PATH} ; export PATH - -test "${PAGER}" || PAGER=more -BACKEND="nc -v -w 15" -TMPAGE=/tmp/web$$ -host="$1" -port="80" -if test "$2" != "" ; then - port="$2" -fi - -spec="/" -specD="/" -specF='' -saving='' - -# be vaguely smart about temp file usage. Use your own homedir if you're -# paranoid about someone symlink-racing your shell script, jeez. -rm -f ${TMPAGE} -test -f ${TMPAGE} && echo "Can't use ${TMPAGE}" && exit 1 - -# get loopy. Yes, I know "echo -n" aint portable. Everything echoed would -# need "\c" tacked onto the end in an SV universe, which you can fix yourself. -while echo -n "${specD}${specF} " && read spec ; do - case $spec in - HOST) - echo -n 'New host: ' - read host - continue - ;; - PORT) - echo -n 'New port: ' - read port - continue - ;; - SAVE) - echo -n 'Save file: ' - read saving -# if we've already got a page, save it - test "${saving}" && test -f ${TMPAGE} && - echo "=== ${host}:${specD}${specF} ===" >> $saving && - cat ${TMPAGE} >> $saving && echo '' >> $saving - continue - ;; -# changing the logic a bit here. Keep a state-concept of "current dir" -# and "current file". Dir is /foo/bar/ ; file is "baz" or null. -# leading slash: create whole new state. - /*) - specF=`echo "${spec}" | sed 's|.*/||'` - specD=`echo "${spec}" | sed 's|\(.*/\).*|\1|'` - spec="${specD}${specF}" - ;; -# embedded slash: adding to the path. "file" part can be blank, too - */*) - specF=`echo "${spec}" | sed 's|.*/||'` - specD=`echo "${specD}${spec}" | sed 's|\(.*/\).*|\1|'` - ;; -# dotdot: jump "up" one level and just reprompt [confirms what it did...] - ..) - specD=`echo "${specD}" | sed 's|\(.*/\)..*/|\1|'` - continue - ;; -# blank line: do nothing, which will re-get the current one - '') - ;; -# hack-quoted blank line: "\" means just zero out "file" part - '\') - specF='' - ;; -# sigh - '?') - echo Help yourself. Read the script fer krissake. - continue - ;; -# anything else is taken as a "file" part - *) - specF=${spec} - ;; - esac - -# now put it together and stuff it down a connection. Some lame non-unix -# http servers assume they'll never get simple-query format, and wait till -# an extra newline arrives. If you're up against one of these, change -# below to (echo GET "$spec" ; echo '') | $BACKEND ... - spec="${specD}${specF}" - echo GET "${spec}" | $BACKEND $host $port > ${TMPAGE} - ${PAGER} ${TMPAGE} - -# save in a format that still shows the URLs we hit after a de-html run - if test "${saving}" ; then - echo "=== ${host}:${spec} ===" >> $saving - cat ${TMPAGE} >> $saving - echo '' >> $saving - fi -done -rm -f ${TMPAGE} -exit 0 - -####### -# Encoding notes, finally from RFC 1738: -# %XX -- hex-encode of special chars -# allowed alphas in a URL: $_-.+!*'(), -# relative names *not* described, but obviously used all over the place -# transport://user:pass@host:port/path/name?query-string -# wais: port 210, //host:port/database?search or /database/type/file? -# cgi-bin/script?arg1=foo&arg2=bar&... scripts have to parse xxx&yyy&zzz -# ISMAP imagemap stuff: /bin/foobar.map?xxx,yyy -- have to guess at coords! -# local access-ctl files: ncsa: .htaccess ; cern: .www_acl -####### -# SEARCH ENGINES: fortunately, all are GET forms or at least work that way... -# multi-word args for most cases: foo+bar -# See 'websearch' for concise results of this research... diff --git a/scripts/webproxy b/scripts/webproxy deleted file mode 100755 index 59e6a49..0000000 --- a/scripts/webproxy +++ /dev/null @@ -1,139 +0,0 @@ -#! /bin/sh -## Web proxy, following the grand tradition of Web things being handled by -## gross scripts. Uses netcat to listen on a high port [default 8000], -## picks apart requests and sends them on to the right place. Point this -## at the browser client machine you'll be coming from [to limit access to -## only it], and point the browser's concept of an HTTP proxy to the -## machine running this. Takes a single argument of the client that will -## be using it, and rejects connections from elsewhere. LOGS the queries -## to a configurable logfile, which can be an interesting read later on! -## If the argument is "reset", the listener and logfile are cleaned up. -## -## This works surprisingly fast and well, for a shell script, although may -## randomly fail when hammered by a browser that tries to open several -## connections at once. Drop the "maximum connections" in your browser if -## this is a problem. -## -## A more degenerate case of this, or preferably a small C program that -## does the same thing under inetd, could handle a small site's worth of -## proxy queries. Given the way browsers are evolving, proxies like this -## can play an important role in protecting your own privacy. -## -## If you grabbed this in ASCII mode, search down for "eew" and make sure -## the embedded-CR check is intact, or requests might hang. -## -## Doesn't handle POST forms. Who cares, if you're just watching HTTV? -## Dumbness here has a highly desirable side effect: it only sends the first -## GET line, since that's all you really ever need to send, and suppresses -## the other somewhat revealing trash that most browsers insist on sending. - -# set these as you wish: proxy port... -PORT=8000 -# logfile spec: a real file or /dev/null if you don't care -LFILE=${0}.log -# optional: where to dump connect info, so you can see if anything went wrong -# CFILE=${0}.conn -# optional extra args to the listener "nc", for instance "-s inside-net-addr" -# XNC='' - -# functionality switch has to be done fast, so the next listener can start -# prelaunch check: if no current client and no args, bail. -case "${1}${CLIENT}" in - "") - echo needs client hostname - exit 1 - ;; -esac - -case "${1}" in - "") -# Make like inetd, and run the next relayer process NOW. All the redirection -# is necessary so this shell has NO remaining channel open to the net. -# This will hang around for 10 minutes, and exit if no new connections arrive. -# Using -n for speed, avoiding any DNS/port lookups. - nc -w 600 -n -l -p $PORT -e "$0" $XNC "$CLIENT" < /dev/null > /dev/null \ - 2> $CFILE & - ;; -esac - -# no client yet and had an arg, this checking can be much slower now -umask 077 - -if test "$1" ; then -# if magic arg, just clean up and then hit our own port to cause server exit - if test "$1" = "reset" ; then - rm -f $LFILE - test -f "$CFILE" && rm -f $CFILE - nc -w 1 -n 127.0.0.1 $PORT < /dev/null > /dev/null 2>&1 - exit 0 - fi -# find our ass with both hands - test ! -f "$0" && echo "Oops, cannot find my own corporeal being" && exit 1 -# correct launch: set up client access control, passed along thru environment. - CLIENT="$1" - export CLIENT - test "$CFILE" || CFILE=/dev/null - export CFILE - touch "$CFILE" -# tell us what happened during the last run, if possible - if test -f "$CFILE" ; then - echo "Last connection results:" - cat $CFILE - fi - -# ping client machine and get its bare IP address - CLIENT=`nc -z -v -w 8 "$1" 22000 2>&1 | sed 's/.*\[\(..*\)\].*/\1/'` - test ! "$CLIENT" && echo "Can't find address of $1" && exit 1 - -# if this was an initial launch, be informative about it - echo "=== Launch: $CLIENT" >> $LFILE - echo "Proxy running -- will accept connections on $PORT from $CLIENT" - echo " Logging queries to $LFILE" - test -f "$CFILE" && echo " and connection fuckups to $CFILE" - -# and run the first listener, showing us output just for the first hit - nc -v -w 600 -n -l -p $PORT -e "$0" $XNC "$CLIENT" & - exit 0 -fi - -# Fall here to handle a page. -# GET type://host.name:80/file/path HTTP/1.0 -# Additional: trash -# More: trash -# <newline> - -read x1 x2 x3 x4 -echo "=== query: $x1 $x2 $x3 $x4" >> $LFILE -test "$x4" && echo "extra junk after request: $x4" && exit 0 -# nuke questionable characters and split up the request -hurl=`echo "$x2" | sed -e "s+.*//++" -e 's+[\`'\''|$;<>{}\\!*()"]++g'` -# echo massaged hurl: $hurl >> $LFILE -hh=`echo "$hurl" | sed -e "s+/.*++" -e "s+:.*++"` -hp=`echo "$hurl" | sed -e "s+.*:++" -e "s+/.*++"` -test "$hp" = "$hh" && hp=80 -hf=`echo "$hurl" | sed -e "s+[^/]*++"` -# echo total split: $hh : $hp : $hf >> $LFILE -# suck in and log the entire request, because we're curious -# Fails on multipart stuff like forms; oh well... -if test "$x3" ; then - while read xx ; do - echo "${xx}" >> $LFILE - test "${xx}" || break -# eew, buried returns, gross but necessary for DOS stupidity: - test "${xx}" = " -" && break - done -fi -# check for non-GET *after* we log the query... -test "$x1" != "GET" && echo "sorry, this proxy only does GETs" && exit 0 -# no, you can *not* phone home, you miserable piece of shit -test "`echo $hh | fgrep -i netscap`" && \ - echo "access to Netscam's servers <b>DENIED.</b>" && exit 0 -# Do it. 30 sec net-wait time oughta be *plenty*... -# Some braindead servers have forgotten how to handle the simple-query syntax. -# If necessary, replace below with (echo "$x1 $hf" ; echo '') | nc... -echo "$x1 $hf" | nc -w 30 "$hh" "$hp" 2> /dev/null || \ - echo "oops, can't get to $hh : $hp". -echo "sent \"$x1 $hf\" to $hh : $hp" >> $LFILE -exit 0 - diff --git a/scripts/webrelay b/scripts/webrelay deleted file mode 100755 index 829a8b0..0000000 --- a/scripts/webrelay +++ /dev/null @@ -1,44 +0,0 @@ -#! /bin/sh -## web relay -- a degenerate version of webproxy, usable with browsers that -## don't understand proxies. This just forwards connections to a given server. -## No query logging, no access control [although you can add it to XNC for -## your own run], and full-URL links will undoubtedly confuse the browser -## if it can't reach the server directly. This was actually written before -## the full proxy was, and it shows. -## The arguments in this case are the destination server and optional port. -## Please flame pinheads who use self-referential absolute links. - -# set these as you wish: proxy port... -PORT=8000 -# any extra args to the listening "nc", for instance "-s inside-net-addr" -XNC='' - -# functionality switch, which has to be done fast to start the next listener -case "${1}${RDEST}" in - "") - echo needs hostname - exit 1 - ;; -esac - -case "${1}" in - "") -# no args: fire off new relayer process NOW. Will hang around for 10 minutes - nc -w 600 -l -n -p $PORT -e "$0" $XNC < /dev/null > /dev/null 2>&1 & -# and handle this request, which will simply fail if vars not set yet. - exec nc -w 15 $RDEST $RPORT - ;; -esac - -# Fall here for setup; this can now be slower. -RDEST="$1" -RPORT="$2" -test "$RPORT" || RPORT=80 -export RDEST RPORT - -# Launch the first relayer same as above, but let its error msgs show up -# will hang around for a minute, and exit if no new connections arrive. -nc -v -w 600 -l -p $PORT -e "$0" $XNC < /dev/null > /dev/null & -echo \ - "Relay to ${RDEST}:${RPORT} running -- point your browser here on port $PORT" -exit 0 diff --git a/scripts/websearch b/scripts/websearch deleted file mode 100755 index 60c3a33..0000000 --- a/scripts/websearch +++ /dev/null @@ -1,77 +0,0 @@ -#! /bin/sh -## Hit the major search engines. Hose the [large] output to a file! -## autoconverts multiple arguments into the right format for given servers -- -## usually worda+wordb, with certain lame exceptions like dejanews. -## Extracting and post-sorting the URLs is highly recommended... -## -## Altavista currently handled by a separate script; may merge at some point. -## -## _H* original 950824, updated 951218 and 960209 - -test "${1}" = "" && echo 'Needs argument[s] to search for!' && exit 1 -PLUSARG="`echo $* | sed 's/ /+/g'`" -PIPEARG="`echo ${PLUSARG} | sed 's/+/|/g'`" -IFILE=/tmp/.webq.$$ - -# Don't have "nc"? Get "netcat" from avian.org and add it to your toolkit. -doquery () { - echo GET "$1" | nc -v -i 1 -w 30 "$2" "$3" -} - -# changed since original: now supplying port numbers and separator lines... - -echo "=== Yahoo ===" -doquery "/bin/search?p=${PLUSARG}&n=300&w=w&s=a" search.yahoo.com 80 - -echo '' ; echo "=== Webcrawler ===" -doquery "/cgi-bin/WebQuery?searchText=${PLUSARG}&maxHits=300" webcrawler.com 80 - -# the infoseek lamers want "registration" before they do a real search, but... -echo '' ; echo "=== Infoseek ===" -echo " is broken." -# doquery "WW/IS/Titles?qt=${PLUSARG}" www2.infoseek.com 80 -# ... which doesn't work cuz their lame server wants the extra newlines, WITH -# CRLF pairs ferkrissake. Fuck 'em for now, they're hopelessly broken. If -# you want to play, the basic idea and query formats follow. -# echo "GET /WW/IS/Titles?qt=${PLUSARG}" > $IFILE -# echo "" >> $IFILE -# nc -v -w 30 guide-p.infoseek.com 80 < $IFILE - -# this is kinda flakey; might have to do twice?? -echo '' ; echo "=== Opentext ===" -doquery "/omw/simplesearch?SearchFor=${PLUSARG}&mode=phrase" \ - search.opentext.com 80 - -# looks like inktomi will only take hits=100, or defaults back to 30 -# we try to suppress all the stupid rating dots here, too -echo '' ; echo "=== Inktomi ===" -doquery "/query/?query=${PLUSARG}&hits=100" ink3.cs.berkeley.edu 1234 | \ - sed '/^<IMG ALT.*inktomi.*\.gif">$/d' - -#djnews lame shit limits hits to 120 and has nonstandard format -echo '' ; echo "=== Dejanews ===" -doquery "/cgi-bin/nph-dnquery?query=${PIPEARG}+maxhits=110+format=terse+defaultOp=AND" \ - smithers.dejanews.com 80 - -# OLD lycos: used to work until they fucking BROKE it... -# doquery "/cgi-bin/pursuit?query=${PLUSARG}&maxhits=300&terse=1" \ -# query5.lycos.cs.cmu.edu 80 -# NEW lycos: wants the User-agent field present in query or it returns nothing -# 960206: webmaster@lycos duly bitched at -# 960208: reply received; here's how we will now handle it: -echo \ -"GET /cgi-bin/pursuit?query=${PLUSARG}&maxhits=300&terse=terse&matchmode=and&minscore=.5 HTTP/1.x" \ - > $IFILE -echo "User-agent: *FUCK OFF*" >> $IFILE -echo "Why: go ask todd@pointcom.com (Todd Whitney)" >> $IFILE -echo '' >> $IFILE -echo '' ; echo "=== Lycos ===" -nc -v -i 1 -w 30 twelve.srv.lycos.com 80 < $IFILE - -rm -f $IFILE -exit 0 - -# CURRENTLY BROKEN [?] -# infoseek - -# some args need to be redone to ensure whatever "and" mode applies diff --git a/stupidh b/stupidh deleted file mode 100755 index 9214102..0000000 --- a/stupidh +++ /dev/null @@ -1,464 +0,0 @@ -#! /bin/sh -## -## Find stupid system include dependencies and account for them. Squirts -## a sample .h file to stdout containing [too many of] the right things. -## If you hose the output into "stupid.h", you will get MORE information. -## This takes a while to run, because it checks so many things. -## -## IF YOU HAVE a system/arch/compiler/whatever that is NOT one of: -## msdos-msc6.x ultrix-vax ultrix-mips sunos4.1.x-sparc solaris2.x-sparc -## aix-rs6k linux1.[01].x-x86 freebsd-x86 netbsd-x86 hpux -## [... hopefully this list will grow very large] -## or even if you aren't sure, you would be doing me and the net in general -## a wonderful service by running this and MAILING me the "full" output, e.g. -## -## chmod +x stupidh -## ./stupidh > stupid.h -## mail hobbit@avian.org < stupid.h -## -## WARNING: You may have to change "cc" to "gcc" below if you don't have -## "cc" [e.g. solaris, thank you very fucking much, Sun]. -## Please note any errors this generates, too... -## -## *Hobbit*, 941122 and previous. VERSION: 1.3 951107 -## -## edits: Use a consistent naming scheme, for easier identification and cleanup. -## accomodate gcc's BOGUS assumptions based on input filename. -## added a few more include-names and try-predefines; some swiped from autoconf. -## added a couple of things commonly done as #defines so we can SEE 'em - -## Here is where to change "cc" to "gcc" if needed: -CC=cc - -if test -z "${INCLUDE}" ; then - INCLUDE=/usr/include -fi - -echo '/* STUPIDH run:' -uname -a -echo '*/' -echo '' - -echo "/* Includes, from ${INCLUDE} */" -for xx in \ -assert ctype cdefs errno file fcntl ioctl malloc stdio stdlib stdarg iostdio \ -stddef dirent direct dir ndir utmp wtmp utmpx wtmpx lastlog login paths \ -getopt string strings signal setjmp io param stat types time timeb utime \ -dos msdos unistd socket netdb varargs sysinfo systeminfo resource ulimit \ -stream stropts pstat sysmacros termio termios sgtty tty ttyent lstat select \ -sockio wait vfork bsdtypes mkdev utsname sysexits \ -; do - - XX='' - if test -f ${INCLUDE}/${xx}.h ; then - echo "#include <${xx}.h>" - XX=`echo $xx | tr '[a-z]' '[A-Z]'` - fi - if test -f ${INCLUDE}/sys/${xx}.h ; then - echo "#include <sys/${xx}.h>" - XX=`echo $xx | tr '[a-z]' '[A-Z]'` - fi - -# everyone seems to have their own conventions; this may not be complete. -# thats why this is so STUPID. -# HAS_xx and USE_xx might indicate functions and available library calls, -# not includes. Deal... - - if test "${XX}" ; then - echo "#define USE_${XX}_H" - echo "#define HAS_${XX}_H" - echo "#define HAS_${XX}" - echo "#define HAS${XX}" - echo "#define HAVE_${XX}_H" - echo "#define HAVE_${XX}" - echo "#define HAVE${XX}H" - echo "#define ${XX}H" - echo '' - fi -# Stupid hack: "dir" and "dirent" might mutually exclusive, a la GNU -# includes. This is to prevent it from biting us. - if test "${xx}" = "dirent" ; then - echo "#ifdef _SYS_DIRENT_H" - echo "#undef _SYS_DIRENT_H" - echo "#endif" - fi - -### To make a DOS batchfile instead, do this [on a unix box!], xfer results, -### and have "xxx.bat" that types out all the cruft for %INCLUDE%\%1. -### WARNING: I might not have gotten the superquoting exactly right here... -# echo "if exist %INCLUDE%\\${xx}.h call xxx ${xx}" -# echo "if exist %INCLUDE%\\sys\\${xx}.h call xxx sys/${xx}" -### You also need to save and manually run the CPP input file, below. -### I've done this for msc6 and would appreciate results for other compilers. - -done -sync -sleep 1 - -### Note: if all the previous output went to "stupid.h", it will be -### reincluded in the second part of this. - -sed -e '/^#/d' -e '/^[ ]*$/d' > st00pid.in << 'EOF' - -### More recently, some of this was swiped from the "gcc" doc. Autoconf is -### worth a harder look for more ideas; havent gotten around to it yet. -# architectures -alpha -dec -ibm -i370 -i960 -i860 -ibm032 -a29k -indigo -iris -mips -mipsel -sparc -sparclite -ncr -sh -harris -apple -vax -x86 -ix86 -i286 -i386 -i486 -i586 -pentium -intel -smp -mpu -mpu8080 -mpu8086 -amiga -hp -hppa -hp400 -hp9000 -snake -decmips -mc68000 -mc68010 -mc68020 -mc68030 -m68000 -m68010 -m68020 -m68030 -m68k -m88k -u3b15 -u3b -u3b2 -u3b5 -u3b15 -u3b20d -we32k -ppc -powerpc -arm -aviion -ns32000 -iapx286 -# minor exception to lc-vs-uc thing? -iAPX286 -rs6000 -rs6k -risc -sun -sun3 -sun4 -sun4c -sun4m -sequent -apollo -solbourne -pyr -pyramid -interdata -intertec -pdp11 -u370 -next -mac -macintosh - -# for completeness; ya never know ... yes, found it!! -- solaris inet/common.h -big_endian -little_endian -lsbfirst -msbfirst - -# vendors/OSes -unix -munix -m_unix -gcos -os -gssc -tss -isc -# *This* pair of imbeciles does *caseified defines*. Pinheads. One of -# these might trigger before the "tr" step. -NetBSD -netbsd -freebsd -FreeBSD -# cant do 386bsd, I dont think, but ... -_386bsd -bsd386 -bsdunix -bsd_2 -bsd_20 -bsd -bsdi -bsd4 -bsd42 -bsd43 -bsd44 -bsd4_2 -bsd4_3 -bsd4_4 -linux -minix -ultrix -ult3 -ult4 -bull -convex -convex_source -res -rt -esix -dg -dgux -encore -osf -osf1 -osf2 -# oops: -# osf/1 -mach -mach386 -mach_386 -nextstep -tahoe -reno -sunos -sunos3 -sunos4 -sunos5 -solaris -sun_src_compat -svr3 -svr4 -svr3_style -svr4_style -sysv -hpux -hp_ux -irix -sgi -sony -news -newsos -news_os -luna -lynxos -riscos -microport -ewsux -ews_ux -mport -dynix -genix -unicos -unixware -msdos -dos -os2 -novell -univel -plan9 -att -att_unix -sco -odt -aix -aux -a_ux -rsx -vms - -# compiler cruft?? -ansi -ansi_source -ansic -stdc -lint -sccs -libc_sccs -ms -msc -microsoft -gcc -gnu -gnuc -gnucc -gnu_source -sabre -saber -cygnus -source -all_source -gprof -prof -posix -posix_source -posix_sources -posix_c_source -xopen_source -args -p -proto -no_proto -prototype -prototypes -reentrant -kernel -str -trace -asm -libcpp -athena -athena_compat -# some preprocessors cant deal with this -# c++ -cxx -cplusplus -borland -turbo -turboc -lattice -highc - -# various defines that pop out of other .h files that we need to know about -index -strchr -rindex -strrchr -bcopy -memcpy -bzero -memset -path_login -path_lastlog -path_utmp -path_utmpx - -EOF - -# FL must be named something.c, so STUPID gcc recognized it as a non-object!! -( FL=st00pid.c - if test -f stupid.h ; then - cp stupid.h $FL - sync - echo '/* Re-including stupid.h */' - sleep 1 - else - echo '/* Skipping stupid.h */' - fi - while read xx ; do - XX=`echo $xx | tr '[a-z]' '[A-Z]'` - echo "#ifdef ${xx}" >> $FL - echo "\"${xx}\" = ${xx}" >> $FL - echo "#endif" >> $FL - echo "#ifdef _${xx}" >> $FL - echo "\"_${xx}\" = _${xx}" >> $FL - echo "#endif" >> $FL - echo "#ifdef _${xx}_" >> $FL - echo "\"_${xx}_\" = _${xx}_" >> $FL - echo "#endif" >> $FL - echo "#ifdef __${xx}" >> $FL - echo "\"__${xx}\" = __${xx}" >> $FL - echo "#endif" >> $FL - echo "#ifdef __${xx}__" >> $FL - echo "\"__${xx}__\" = __${xx}__" >> $FL - echo "#endif" >> $FL - echo "#ifdef ${XX}" >> $FL - echo "\"${XX}\" = ${XX}" >> $FL - echo "#endif" >> $FL - echo "#ifdef _${XX}" >> $FL - echo "\"_${XX}\" = _${XX}" >> $FL - echo "#endif" >> $FL - echo "#ifdef _${XX}_" >> $FL - echo "\"_${XX}_\" = _${XX}_" >> $FL - echo "#endif" >> $FL - echo "#ifdef __${XX}" >> $FL - echo "\"__${XX}\" = __${XX}" >> $FL - echo "#endif" >> $FL - echo "#ifdef __${XX}__" >> $FL - echo "\"__${XX}__\" = __${XX}__" >> $FL - echo "#endif" >> $FL - done -# and pick up a few specials - echo "#ifdef major" >> $FL - echo "\"major\" = major (x)" >> $FL - echo "\"minor\" = minor (x)" >> $FL - echo "#endif" >> $FL - echo "#ifdef FD_SETSIZE" >> $FL - echo "\"FD_SETSIZE\" = FD_SETSIZE" >> $FL - echo "#endif" >> $FL -) < st00pid.in -sync - -echo '/* Compiler predefines:' -${CC} -E st00pid.c | sed -e '/^#/d' -e '/^[ ]*$/d' -echo '*/' -sync - -cat > st00pid.c << 'EOF' -#include <stdio.h> -main() { -union { - char *bletch; - int *i; -} yow; -static char orig[16]; - strcpy (orig, "ABCDEFGHIJK"); - yow.bletch = orig; - printf ("endian thing: %s = 0x%lx, addrbyte = %x -- ", - yow.bletch, *yow.i, *yow.i & 0xFF); - printf (((*yow.i & 0xff) == 0x41) ? "LITTLE\n" : "BIG\n"); - printf ("short %d; int %d; long %d\n", - sizeof (short), sizeof (int), sizeof (long)); -} -EOF - -${CC} -o st00pid.x st00pid.c -echo '/* Architecture:' -./st00pid.x -echo '*/' - -### dont nuke if generating DOS batchfiles -rm -f st00pid.* -sync -exit 0 - -### stuff remaining to deal with: -# maybe take out the slew of HAS_* and HAS* excess predefines, and only use -# our "standardized" scheme [like we were going to generate a real includible -# file outa this??] -# various POSIX_ME_HARDERisms: -# vfork -# lockf/flock/fcntl/euuugh -# signal stuff -# termio/termios/sgtty hair -# strdup and related -# ifdef HAVE_STD_LIB and such nonsense -# auto-sniff cc-vs-gcc somehow? maybe a straight OR with exit statii.. - |