2018-11-14 14:18:05 +01:00
|
|
|
|
From: Guilhem Moulin <guilhem@debian.org>
|
|
|
|
|
Date: Mon, 22 Oct 2018 04:15:52 +0200
|
|
|
|
|
Subject: destination port list
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
nc.1 | 26 ++++++++++++++++---
|
|
|
|
|
netcat.c | 86 ++++++++++++++++++++++++++++++++-------------------------------
|
|
|
|
|
2 files changed, 68 insertions(+), 44 deletions(-)
|
|
|
|
|
|
|
|
|
|
--- a/nc.1
|
|
|
|
|
+++ b/nc.1
|
|
|
|
|
@@ -414,15 +414,35 @@ The
|
|
|
|
|
flag can be used to tell
|
|
|
|
|
.Nm
|
|
|
|
|
to report open ports,
|
|
|
|
|
-rather than initiate a connection.
|
|
|
|
|
+rather than initiate a connection. Usually it's useful to turn on verbose
|
|
|
|
|
+output to stderr by use this option in conjunction with
|
|
|
|
|
+.Fl v
|
|
|
|
|
+option.
|
|
|
|
|
+.Pp
|
|
|
|
|
For example:
|
|
|
|
|
.Bd -literal -offset indent
|
|
|
|
|
-$ nc -z host.example.com 20-30
|
|
|
|
|
+$ nc \-zv host.example.com 20-30
|
|
|
|
|
Connection to host.example.com 22 port [tcp/ssh] succeeded!
|
|
|
|
|
Connection to host.example.com 25 port [tcp/smtp] succeeded!
|
|
|
|
|
.Ed
|
|
|
|
|
.Pp
|
|
|
|
|
-The port range was specified to limit the search to ports 20 \- 30.
|
|
|
|
|
+The port range was specified to limit the search to ports 20 \- 30, and is
|
|
|
|
|
+scanned by increasing order (unless the
|
|
|
|
|
+.Fl r
|
|
|
|
|
+flag is set).
|
|
|
|
|
+.Pp
|
|
|
|
|
+You can also specify a list of ports to scan, for example:
|
|
|
|
|
+.Bd -literal -offset indent
|
|
|
|
|
+$ nc \-zv host.example.com http 20 22-23
|
|
|
|
|
+nc: connect to host.example.com 80 (tcp) failed: Connection refused
|
|
|
|
|
+nc: connect to host.example.com 20 (tcp) failed: Connection refused
|
|
|
|
|
+Connection to host.example.com port [tcp/ssh] succeeded!
|
|
|
|
|
+nc: connect to host.example.com 23 (tcp) failed: Connection refused
|
|
|
|
|
+.Ed
|
|
|
|
|
+.Pp
|
|
|
|
|
+The ports are scanned by the order you given (unless the
|
|
|
|
|
+.Fl r
|
|
|
|
|
+flag is set).
|
|
|
|
|
.Pp
|
|
|
|
|
Alternatively, it might be useful to know which server software
|
|
|
|
|
is running, and which versions.
|
|
|
|
|
--- a/netcat.c
|
|
|
|
|
+++ b/netcat.c
|
2019-09-09 20:51:34 +02:00
|
|
|
|
@@ -191,7 +191,7 @@ int minttl = -1;
|
2018-11-14 14:18:05 +01:00
|
|
|
|
|
|
|
|
|
void atelnet(int, unsigned char *, unsigned int);
|
|
|
|
|
int strtoport(char *portstr, int udp);
|
|
|
|
|
-void build_ports(char *);
|
|
|
|
|
+void build_ports(char **);
|
|
|
|
|
void help(void) __attribute__((noreturn));
|
|
|
|
|
int local_listen(const char *, const char *, struct addrinfo);
|
|
|
|
|
# if defined(TLS)
|
2019-09-09 20:51:34 +02:00
|
|
|
|
@@ -242,7 +242,7 @@ int
|
2018-11-14 14:18:05 +01:00
|
|
|
|
main(int argc, char *argv[])
|
|
|
|
|
{
|
|
|
|
|
int ch, s = -1, ret, socksv;
|
|
|
|
|
- char *host, *uport;
|
|
|
|
|
+ char *host, **uport;
|
|
|
|
|
struct addrinfo hints;
|
|
|
|
|
struct servent *sv;
|
|
|
|
|
socklen_t len;
|
2019-09-09 20:51:34 +02:00
|
|
|
|
@@ -526,11 +526,11 @@ main(int argc, char *argv[])
|
2018-11-14 14:18:05 +01:00
|
|
|
|
} else if (argv[0] && !argv[1]) {
|
|
|
|
|
if (!lflag)
|
|
|
|
|
usage(1);
|
|
|
|
|
- uport = argv[0];
|
|
|
|
|
+ uport = &argv[0];
|
|
|
|
|
host = NULL;
|
|
|
|
|
} else if (argv[0] && argv[1]) {
|
|
|
|
|
host = argv[0];
|
|
|
|
|
- uport = argv[1];
|
|
|
|
|
+ uport = &argv[1];
|
|
|
|
|
} else
|
|
|
|
|
usage(1);
|
|
|
|
|
|
2019-09-09 20:51:34 +02:00
|
|
|
|
@@ -717,7 +717,7 @@ main(int argc, char *argv[])
|
2018-11-14 14:18:05 +01:00
|
|
|
|
else
|
|
|
|
|
s = unix_listen(host);
|
|
|
|
|
} else
|
|
|
|
|
- s = local_listen(host, uport, hints);
|
|
|
|
|
+ s = local_listen(host, *uport, hints);
|
|
|
|
|
if (s < 0)
|
|
|
|
|
err(1, NULL);
|
|
|
|
|
|
2019-09-09 20:51:34 +02:00
|
|
|
|
@@ -1785,57 +1785,61 @@ strtoport(char *portstr, int udp)
|
2018-11-14 14:18:05 +01:00
|
|
|
|
* that we should try to connect to.
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
-build_ports(char *p)
|
|
|
|
|
+build_ports(char **p)
|
|
|
|
|
{
|
|
|
|
|
struct servent *sv;
|
|
|
|
|
char *n;
|
|
|
|
|
int hi, lo, cp;
|
|
|
|
|
int x = 0;
|
|
|
|
|
+ int i;
|
|
|
|
|
|
|
|
|
|
char *proto = proto_name(uflag, dccpflag);
|
|
|
|
|
- sv = getservbyname(p, proto);
|
|
|
|
|
- if (sv) {
|
|
|
|
|
- if (asprintf(&portlist[0], "%d", ntohs(sv->s_port)) < 0)
|
|
|
|
|
- err(1, "asprintf");
|
2019-09-09 20:51:34 +02:00
|
|
|
|
- } else if (isdigit((unsigned char)*p) && (n = strchr(p, '-')) != NULL) {
|
2018-11-14 14:18:05 +01:00
|
|
|
|
- *n = '\0';
|
|
|
|
|
- n++;
|
|
|
|
|
-
|
|
|
|
|
- /* Make sure the ports are in order: lowest->highest. */
|
|
|
|
|
- hi = strtoport(n, uflag);
|
|
|
|
|
- lo = strtoport(p, uflag);
|
|
|
|
|
- if (lo > hi) {
|
|
|
|
|
- cp = hi;
|
|
|
|
|
- hi = lo;
|
|
|
|
|
- lo = cp;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- /*
|
|
|
|
|
- * Initialize portlist with a random permutation. Based on
|
|
|
|
|
- * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
|
|
|
|
|
- */
|
|
|
|
|
- if (rflag) {
|
|
|
|
|
- for (x = 0; x <= hi - lo; x++) {
|
|
|
|
|
- cp = arc4random_uniform(x + 1);
|
|
|
|
|
- portlist[x] = portlist[cp];
|
|
|
|
|
- if (asprintf(&portlist[cp], "%d", x + lo) < 0)
|
|
|
|
|
- err(1, "asprintf");
|
|
|
|
|
+ for (i = 0; p[i] != NULL; i++) {
|
|
|
|
|
+ sv = getservbyname(p[i], proto);
|
|
|
|
|
+ if (sv) {
|
|
|
|
|
+ if (asprintf(&portlist[x], "%d", ntohs(sv->s_port)) < 0)
|
|
|
|
|
+ err(1, "asprintf");
|
|
|
|
|
+ x++;
|
2019-09-09 20:51:34 +02:00
|
|
|
|
+ } else if (isdigit((unsigned char)*p[i]) && (n = strchr(p[i], '-')) != NULL) {
|
2018-11-14 14:18:05 +01:00
|
|
|
|
+ *n = '\0';
|
|
|
|
|
+ n++;
|
|
|
|
|
+
|
|
|
|
|
+ /* Make sure the ports are in order: lowest->highest. */
|
|
|
|
|
+ hi = strtoport(n, uflag);
|
|
|
|
|
+ lo = strtoport(p[i], uflag);
|
|
|
|
|
+ if (lo > hi) {
|
|
|
|
|
+ cp = hi;
|
|
|
|
|
+ hi = lo;
|
|
|
|
|
+ lo = cp;
|
|
|
|
|
}
|
|
|
|
|
- } else { /* Load ports sequentially. */
|
|
|
|
|
+
|
|
|
|
|
+ /* Load ports sequentially. */
|
|
|
|
|
for (cp = lo; cp <= hi; cp++) {
|
|
|
|
|
if (asprintf(&portlist[x], "%d", cp) < 0)
|
|
|
|
|
err(1, "asprintf");
|
|
|
|
|
x++;
|
|
|
|
|
}
|
|
|
|
|
+ } else {
|
|
|
|
|
+ hi = strtoport(p[i], uflag);
|
|
|
|
|
+ if (asprintf(&portlist[x], "%d", hi) < 0)
|
|
|
|
|
+ err(1, "asprintf");
|
|
|
|
|
+ x++;
|
|
|
|
|
}
|
|
|
|
|
- } else {
|
|
|
|
|
- char *tmp;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
- hi = strtoport(p, uflag);
|
|
|
|
|
- if (asprintf(&tmp, "%d", hi) != -1)
|
|
|
|
|
- portlist[0] = tmp;
|
|
|
|
|
- else
|
|
|
|
|
- err(1, NULL);
|
|
|
|
|
+ /*
|
|
|
|
|
+ * Initialize portlist with a random permutation using
|
|
|
|
|
+ * Fisher–Yates shuffle.
|
|
|
|
|
+ */
|
|
|
|
|
+ if (rflag) {
|
|
|
|
|
+ for (i = x-1; i > 0; i--) {
|
|
|
|
|
+ cp = arc4random_uniform(i+1);
|
|
|
|
|
+ if (cp != i) {
|
|
|
|
|
+ n = portlist[i];
|
|
|
|
|
+ portlist[i] = portlist[cp];
|
|
|
|
|
+ portlist[cp] = n;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|