-
Notifications
You must be signed in to change notification settings - Fork 30
/
netcat.texi
1062 lines (947 loc) · 56.7 KB
/
netcat.texi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
\input texinfo.tex @c -*- texinfo -*-
@c %**start of header (This is for running Texinfo on a region.)
@setfilename netcat.info
@settitle Netcat Hacker's Guide
@setchapternewpage odd
@smallbook
@c %**end of header (This is for running Texinfo on a region.)
@c ******************************************* Values and macros *********
@dircategory Netcat
@direntry
* Netcat: (netcat). TCP/IP swiss army knife.
@end direntry
@copying
@quotation
Netcat 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 @strong{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.
@end quotation
@end copying
@titlepage
@title Netcat's Hacker's Guide
@author by *Hobbit*
@comment The following two commands start the copyright page.
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@node Top, , , (DIR)
@top
@menu
* Introduction::
* Features::
* Light side::
* Dark side::
* Notes::
@end menu
@node Introduction
@chapter Introduction to Netcat
Netcat is a simple Unix utility which reads and writes data across
network connections, using @acronym{TCP} or @acronym{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. Netcat, or @command{nc} as the
actual program is named, should have been supplied long ago as another
one of those cryptic but standard Unix tools.
In the simplest usage, @command{nc @var{host} @var{port}} creates a
@acronym{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 @acronym{UDP} too, so Netcat is possibly the
``udp telnet-like'' application you always wanted for testing your
@acronym{UDP}-mode servers. @acronym{UDP}, as the ``U'' implies, gives
less reliable data transmission than @acronym{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 @acronym{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 @emph{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 @emph{output} and will never modify any
of the real data in transit unless you @emph{really} want it to. And of
course telnet is incapable of listening for inbound connections, or
using @acronym{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:
@itemize @bullet
@item
Outbound or inbound connections, @acronym{TCP} or @acronym{UDP}, to or
from any ports
@item
Full @acronym{DNS} forward/reverse checking, with appropriate warnings
@item
Ability to use any local source port
@item
Ability to use any locally-configured network source address
@item
Built-in port-scanning capabilities, with randomizer
@item
Can read command line arguments from standard input
@item
Slow-send mode, one line every N seconds
@item
Hex dump of transmitted and received data
@item
Optional ability to let another program service established connections
@item
Optional telnet-options responder
@end itemize
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 release is not made by the original author; the overall differences
from 1.10 are relatively minor and have mostly to do with readability of
source code and some modernization. It is not an attempt to steal
*Hobbit*'s merits as Netcat's author, but rather to keep an
extraordinarily useful tool in pace with the changes in the Internet,
and to make an extraordinarily instructive piece of code even more so.
Netcat is entirely *Hobbit*'s own creation, although he says plenty of
other code was used as examples. Here are his words:
@insertcopying
Comments, questions, flames, and patches to bonzini@@gnu.org.
@node Features
@chapter 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
@command{ps} displays.
The host argument can be a name or IP address. If @option{-n} is
specified, Netcat will only accept numeric IP addresses and do no
@acronym{DNS} lookups for anything. If @option{-n} is not given and
@option{-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 @acronym{DNS}. This often takes a
little longer for connection setup, but is useful to know about. There
are circumstances under which this can @emph{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.
A port argument is required for outbound connections, and can be numeric
or a name as listed in /etc/services. If @option{-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 @option{-v} switch controls the verbosity level of messages sent to
standard error. You will probably want to run Netcat most of the time
with @option{-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
@option{-w} argument, which limits the time spent trying to make a
connection. I usually alias @command{nc} to @command{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 @option{-w}
argument which overrides the earlier one. Specifying @option{-v} more
than once makes diagnostic output @emph{more} verbose. If @option{-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 @emph{not} considered
to be errors, unless you only asked for a single @acronym{TCP} port and
it was refused.
Note that @option{-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 @var{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 @emph{don't} close by themselves until told to.
@acronym{UDP} connections are opened instead of @acronym{TCP} when
@option{-u} is specified. These aren't really ``connections'' per se
since @acronym{UDP} is a connectionless protocol, although Netcat does
internally use the ``connected @acronym{UDP} socket'' mechanism that
most kernels support. Although Netcat claims that an outgoing
@acronym{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 @acronym{UDP} server on the other
end, and often you just can't tell. Most @acronym{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 @acronym{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 @option{-o
@var{log-file}}. The dump lines begin with @code{<} or @code{>} 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.@footnote{Note: this does not work correctly on all
platforms.} Use @option{-p @var{port}} to grab a specific local port,
and @option{-s @var{addr}} or @option{-s @var{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 @option{-p} will bind to
whatever unused port the system gives you, just like any other normal
client connection, unless you use @option{-r}@footnote{see below}.
Listen mode will cause Netcat to wait for an inbound connection, and
then the same data transfer happens. Thus, you can do @command{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
@acronym{UDP} mode, while @acronym{TCP} mode can have the system assign
one and tell you what it is if @option{-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 @emph{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.
The @option{-e} argument specifies a program to exec after making or
receiving a successful connection. In the listening mode, this works
similarly to @command{inetd} but only for a single instance. Use with
@strong{great care}. This hack also works in @acronym{UDP} mode. Note
that you can only supply @option{-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 @command{inetd} like always.
The @option{-t} argument enables Netcat to respond to Telnet option
negotiation (always in the negative, i.e. @code{DONT} or @code{WONT}).
This allows it to connect to a @command{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 option 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 @option{-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 @option{-i} interval
rather long, what you type will go out at a fairly normal rate.
@option{-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. @emph{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 @emph{all} of them,
sending the same batch of data from standard input@footnote{up to 8K
worth} to each one that is successfully connected to. Specifying
multiple ports also suppresses diagnostic messages about refused
connections, unless @option{-v} is specified twice for ``more
verbosity''. This way you normally get notified only about genuinely
open connections. Example: @command{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 @acronym{FTP} server, telnet
server, and mailer along the way. The @option{-z} switch prevents
sending any data to a @acronym{TCP} connection and very limited probe
data to a @acronym{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, @option{-i} will insert a delay between
each port probe. There are some pitfalls with regard to @acronym{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 @option{-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 @command{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 @option{-r} and
selected port ranges to cover. If you use @option{-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 @option{-p} overrides any
local-port randomization.
Netcat tries its best to behave just like @command{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.
@node Light side
@chapter 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 @acronym{URL}
and pipes @code{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 @command{nc host 25}, talk
to someone's mailer, and just @kbd{^C} out than having to type @kbd{^]c}
or @kbd{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 @command{>& file} in @command{csh} or @command{> file 2>&1} in the
Bourne shell.
A scanning example: @command{echo QUIT | nc -v -w 5 target 20-250
500-600 5990-7000} will inform you about a target's various well-known
@acronym{TCP} servers, including r-services, X, @acronym{IRC}, and maybe
a few you didn't expect. Sending in @kbd{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.@footnote{Beware of the ``chargen'' port, though...}
@acronym{SATAN} uses exactly this technique to collect host information,
and indeed some of the ideas herein were taken from the @acronym{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
@acronym{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 @command{rsh} is often used for: on one
side,
@example
nc -l -p 1234 | tar xvzpf -
@end example
@noindent
and then on the other side
@example
tar cpf - /some/dir | gzip -9c | nc -w 3 othermachine 1234
@end example
@noindent
will transfer the contents of a directory from one machine to another,
without having to worry about @file{.rhosts} files, user accounts, or
@command{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 @command{dump} or @command{tar} on one
machine to @command{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 @acronym{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 @acronym{URL}, but you can dig the raw data out of the on-disk
cache.
You can use Netcat as an @command{inetd} substitute to test experimental
network servers that would otherwise run under @command{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 @command{inetd} or not, it is possible for Netcat avoid
the ``address already in use'' error by binding to a specific address.
This lets you@footnote{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
@file{inetd}. Running with @option{-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 @command{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 @command{inetd}, Netcat will function perfectly well
@emph{under} @command{inetd} as a @acronym{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 @command{inetd} and tcp_wrappers, perhaps thusly:
@example
www stream tcp nowait nobody /etc/tcpd /bin/nc -w3 realwww 80
@end example
@noindent
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
@example
yes AAAAAAAAAAAAAAAAAAAAAA | nc -v -v -l -p 2222 > /dev/null
@end example
@noindent
on one side and then hitting it with
@example
yes BBBBBBBBBBBBBBBBBBBBBB | nc othermachine 2222 > /dev/null
@end example
@noindent
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 @acronym{UDP} mode
produces @emph{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
@file{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 @option{%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 @command{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 @emph{not} use @option{-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
@kbd{^@@root^@@joe^@@pwd^@@} (where ^@@ is a null, and
@kbd{root}/@kbd{joe} could be any other local/remote username pair) into
a @command{rsh} or @command{rlogin} server, @emph{from} your port 1023
for example, duplicates what the server expects to receive. Thus, you
can test for insecure @file{.rhosts} files around your network without
having to create new user accounts on your client machine. The program
@file{data/rservice.c} can aid this process by constructing the
@command{rcmd} protocol bytes. Doing this also prevents @command{rshd}
from trying to create that separate standard-error socket and still
gives you an input path, as opposed to the usual action of @command{rsh
-n}. Using Netcat for things like this can be really useful sometimes,
because rsh and rlogin generally want a host @emph{name} as an argument
and won't accept IP addresses. If your client-end @acronym{DNS} is
hosed, as may be true when you're trying to extract backup sets on to a
dumb client, @command{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 @acronym{UDP} connection to port 514 and type in
@code{<0>message}, which should correspond to @code{kern.emerg} and
cause syslogd to scream into every file it has open@footnote{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 @file{syslog.conf}. For
example, @command{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. @acronym{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 @acronym{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
@example
while true ; do
nc -v -l -s @var{your-addr} -p 6000 localhost 2
done
@end example
@noindent
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 @code{: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
@acronym{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 @acronym{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 @acronym{CGI}
script, and since it's running under your user id 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
@acronym{CGI} script. The possibilities for using Netcat and scripts to
handle Web stuff are almost endless. Again, see the examples under
scripts/.
@node Dark side
@chapter 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 @emph{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 @command{ps} ignorant of
your doings. The more random the scanning, the less likelihood of
detection by humans, scan-detectors, or dynamic filtering, and with
@option{-i} you'll wait longer but avoid loading down the target's
network. Some examples for crafting various standard @acronym{UDP}
probes are given in @file{data/*.d}.
Some configurations of packet filters attempt to solve the
@acronym{FTP}-data problem by just allowing such connections from the
outside. These come @emph{from} port 20, @emph{to} high @acronym{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 @acronym{TCP} @acronym{NFS} servers, X
servers, Prospero, ciscos that listen on 200x and 400x... Similar
bypassing may be possible for @acronym{UDP} (and maybe @acronym{TCP}
too) if a connection comes from port 53; a filter may assume it's a
nameserver response.
Using @option{-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 @option{-s} and @option{-e} to run various
hacked daemons without having to touch @file{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 @acronym{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 @acronym{RPC} services on some platforms
(@command{yppasswdd}?). Kerberos tickets, X cookies, and @acronym{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. @acronym{SOCKS} servers run on 1080. Do @command{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
@acronym{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 @acronym{PPP} links.
There are some hacked web servers and versions of @command{inetd}
floating around that specifically bind as well, based on a configuration
file---these generally @emph{are} bound to alias addresses to offer
several different address-based services from one machine.
Using @option{-e} to start a remote backdoor shell is another obvious
sort of thing, easier than constructing a file for @command{inetd} to
listen on @code{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
@emph{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 @acronym{UDP} has several interesting
features, although be aware that once ``connected'', the @acronym{UDP}
stub sockets tend to show up in @command{netstat} just like
@acronym{TCP} connections and may not be quite as subtle as you wanted.
Packets may also be lost, so use @acronym{TCP} if you need reliable
connections. But since @acronym{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 @acronym{UDP}-plus-exec
connection creates the connected socket and starts the program
immediately. On a listening @acronym{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 @emph{all} of the following to take over such a session:
@itemize @bullet
@item
forge @acronym{UDP} with your source address (trivial to do; see below)
@item
guess the port numbers of @emph{both} ends, or sniff the wire for them
@item
arrange to block @acronym{ICMP} or @acronym{UDP} return traffic between
it and your real source, so the session doesn't die with a network write
error.
@end itemize
The companion program @file{data/rservice.c} is helpful in scripting up
any sort of r-service username or password guessing attack. The
arguments to @command{rservice} are simply the strings that get
null-terminated and passed over an @command{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 @command{rexec} if
it is available since it is less likely to log failed attempts. Thus,
doing @command{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 @command{rservice joe joe pwd} and such.
Netcat can prevent inadvertently sending extra information over a telnet
connection. Use @command{nc -t} in place of telnet, and daemons that
try to ask for things like @env{USER} and @env{TERM} environment
variables will get no useful answers, as they otherwise would from a
more recent telnet program. Some @command{telnetd}s 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 @emph{your} real username to be logged over
there if you use a Borman-based telnet instead of @command{nc -t}.
Got an unused network interface configured in your kernel
(e.g. @acronym{SLIP}), or support for alias addresses? Ifconfig one to
be any address you like, and bind to it with @option{-s} to enable all
sorts of shenanigans with bogus source addresses. The interface
probably has to be UP before this works; some @acronym{SLIP} versions
need a far-end address before this is true. Hammering on @acronym{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
@acronym{UDP} echo and chargen servers check if an incoming packet was
sent from @emph{another} ``internal'' @acronym{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.
@ignore
Your @acronym{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 @option{-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 @acronym{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 @command{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!
@end ignore
SYN bombing (sometimes called ``hosing'') can disable many @acronym{TCP}
servers@footnote{At least if SYN cookies are not enabled.}, 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
@code{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 @emph{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.
@node Notes
@chapter Notes
A discussion of various caveats, subtleties, and the design of the
innards.
@ignore
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 @code{fgets()} for
the command line argument, which behind the scenes does a large
@code{read()} from standard input, perhaps 4096 bytes or so, and feeds
that out to the @code{fgets()} library routine. By the time Netcat 1.00
started directly @code{read()}ing stdin for more data, 4096 bytes of it
were gone. It now uses raw @code{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.
@end ignore
When Netcat receives an inbound @acronym{UDP} connection, it creates a
``connected socket'' back to the source of the connection so that it can
also send out data using normal @code{write()}. Using this mechanism
instead of recvfrom/sendto has several advantages---the read/write
select loop is simplified, and @acronym{ICMP} errors can in effect be
received by non-root users. However, it has the subtle side effect that
if further @acronym{UDP} packets arrive from the caller but from
different source ports, the listener will not receive them.
@acronym{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 @acronym{UDP} connected sockets and/or my
understanding of it is entirely complete here, so experiment...
You should be aware of some subtleties concerning @acronym{UDP}
scanning. If @option{-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 @option{-w} timeout, or Netcat will try to make a
``sideline'' @acronym{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 @option{-w} timeout and @option{-i} timeout set,
@emph{both} take effect and you wait twice as long. The @acronym{TCP}
connection is to a normally refused port to minimize traffic, but if you
notice a @acronym{UDP} fast-scan taking somewhat longer than it should,
it could be that the target is actually listening on the @acronym{TCP}
port. Either way, any @acronym{ICMP} port-unreachable messages from the
target should have arrived in the meantime. The second single-byte
@acronym{UDP} probe is then sent. Under @acronym{BSD} kernels, the
@acronym{ICMP} error is delivered to the ``connected socket'' and the
second write returns an error, which tells Netcat that there is
@emph{not} a @acronym{UDP} service there. While Linux seems to be a
fortunate exception, under many SYSV derived kernels the @acronym{ICMP}
is not delivered, and Netcat starts reporting that @emph{all} the ports
are ``open''---clearly wrong.@footnote{Some systems may not even
@emph{have} the ``udp connected socket'' concept, and Netcat in its
current form will not work for @acronym{UDP} at all.} If @option{-z} is
specified and only one @acronym{UDP} port is probed, Netcat's exit
status reflects whether the connection was ``open'' or ``refused'' as
with @acronym{TCP}.
It may also be that @acronym{UDP} packets are being blocked by filters
with no @acronym{ICMP} error returns, in which case everything will time
out and return ``open''. This all sounds backwards, but that's how
@acronym{UDP} works. If you're not sure, try @command{echo w00gumz | nc
-u -w 2 target 7} to see if you can reach its @acronym{UDP} echo port at
all. You should have no trouble using a @acronym{BSD}-flavor system to
scan for @acronym{UDP} around your own network, although flooding a
target with the high activity that @option{-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 @acronym{ICMP}
errors, as does @acronym{SATAN}'s @command{udp_scan} backend, but then
again there's no guarantee that the @acronym{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 @acronym{ICMP}
received. Netcat uses a much sleazier method which is nonetheless quite
effective. Cisco routers are known to have a ``dead time'' in between
@acronym{ICMP} responses about unreachable @acronym{UDP} ports, so a
fast scan of a cisco will show almost everything ``open''. If you are
looking for a specific @acronym{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 @acronym{UDP} port given. Note that you
must use a timeout in this case (as would any other @acronym{UDP} client
application) since the two-write probe only happens if @option{-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 @command{telnetd} happy worked some places but failed against
newer @acronym{BSD}-flavor ones, possibly due to timing problems, but
there are a couple of much better workarounds. First, use @option{-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 @emph{does} update the total byte
count, and show up in the hex dump. 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
@command{foo} script:
@example
#! /bin/sh
exec nc -otheroptions targethost 23
@end example
@noindent
and then do
@example
nc -l -p someport -e foo localhost &
telnet localhost someport
@end example
@noindent
and your telnet should connect transparently through the exec'ed Netcat
to the target, using whatever options you supplied in the @command{foo}
script. Don't use @option{-t} inside the script, or you'll wind up
sending @emph{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 @option{-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 @acronym{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, @emph{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 @acronym{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 @emph{real} network error from being
returned---@code{errno} at that point indicates ``interrupted system
call'' since the connect attempt was interrupted. Some old 4.3
@acronym{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 @emph{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
@emph{established} @acronym{TCP} connections when @acronym{ICMP}-bombed.
``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 @acronym{SATAN} tool kit, and Pluvius' @command{pscan}
utility. Healthy amounts of @acronym{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
@command{rsh} and Richard Stevens' @command{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
@command{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 @option{-e @var{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 @emph{will} get you there. While the coding
style is fairly ``tight'', I have attempted to present it cleanly
(keeping @emph{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 @code{XXX}. Source code was made