File misc-failures-and-features.patch of Package netcat-openbsd
From: Aron Xu <aron@debian.org>
Date: Mon, 13 Feb 2012 19:06:52 +0800
Subject: Misc failures and features
---
nc.1 | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
netcat.c | 37 +++++++++++++++++++++++++++++--------
2 files changed, 80 insertions(+), 8 deletions(-)
diff --git a/nc.1 b/nc.1
index 8285c10..a159c73 100644
--- a/nc.1
+++ b/nc.1
@@ -371,6 +371,54 @@ The connection may be terminated using an
as the
.Fl N
flag was given.
+.Pp
+There is no
+.Fl c
+or
+.Fl e
+option in this netcat, but you still can execute a command after connection
+being established by redirecting file descriptors. Be cautious here because
+opening a port and let anyone connected execute arbitrary command on your
+site is DANGEROUS. If you really need to do this, here is an example:
+.Pp
+On
+.Sq server
+side:
+.Pp
+.Dl $ rm -f /tmp/f; mkfifo /tmp/f
+.Dl $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
+.Pp
+On
+.Sq client
+side:
+.Pp
+.Dl $ nc host.example.com 1234
+.Dl $ (shell prompt from host.example.com)
+.Pp
+By doing this, you create a fifo at /tmp/f and make nc listen at port 1234
+of address 127.0.0.1 on
+.Sq server
+side, when a
+.Sq client
+establishes a connection successfully to that port, /bin/sh gets executed
+on
+.Sq server
+side and the shell prompt is given to
+.Sq client
+side.
+.Pp
+When connection is terminated,
+.Nm
+quits as well. Use
+.Fl k
+if you want it keep listening, but if the command quits this option won't
+restart it or keep
+.Nm
+running. Also don't forget to remove the file descriptor once you don't need
+it anymore:
+.Pp
+.Dl $ rm -f /tmp/f
+.Pp
.Sh DATA TRANSFER
The example in the previous section can be expanded to build a
basic data transfer model.
@@ -523,6 +571,9 @@ Original implementation by
.br
Rewritten with IPv6 support by
.An Eric Jackson Aq Mt ericj@monkey.org .
+.br
+Modified for Debian port by Aron Xu
+.Aq aron@debian.org .
.Sh CAVEATS
UDP port scans using the
.Fl uz
diff --git a/netcat.c b/netcat.c
index 2f8890b..2a3714a 100644
--- a/netcat.c
+++ b/netcat.c
@@ -114,7 +114,7 @@
#include "atomicio.h"
#define PORT_MAX 65535
-#define UNIX_DG_TMP_SOCKET_SIZE 19
+#define UNIX_DG_TMP_SOCKET_SIZE 25
#define POLL_STDIN 0
#define POLL_NETOUT 1
@@ -618,10 +618,20 @@ main(int argc, char *argv[])
if (sflag) {
unix_dg_tmp_socket = sflag;
} else {
- strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
+ /* On Linux it's tempting to use abstract sockets here in
+ * order to limit bookkeeping and avoid cluttering /tmp.
+ * Unfortunately though this has security implications, as a
+ * second client could inject server responses if they
+ * manage to connect(2) to the temporary socket between the
+ * first client's bind(2) and connect(2) calls. OTOH for
+ * pathname sockets the injection is only possible on Linux
+ * when write access to the socket is granted. */
+ strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc-XXXXXX",
+ UNIX_DG_TMP_SOCKET_SIZE);
+ if (mkdtemp(unix_dg_tmp_socket_buf) == NULL)
+ err(1, "mkdtemp");
+ strlcat(unix_dg_tmp_socket_buf, "/recv.sock",
UNIX_DG_TMP_SOCKET_SIZE);
- if (mktemp(unix_dg_tmp_socket_buf) == NULL)
- err(1, "mktemp");
unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
}
}
@@ -851,8 +861,14 @@ main(int argc, char *argv[])
ret = 1;
}
- if (uflag)
+ if (uflag && !sflag) {
unlink(unix_dg_tmp_socket);
+ char *nam = strrchr(unix_dg_tmp_socket, '/');
+ if (nam != NULL) {
+ nam[0] = '\0';
+ rmdir(unix_dg_tmp_socket);
+ }
+ }
return ret;
} else {
int i = 0;
@@ -991,6 +1007,11 @@ unix_bind(char *path, int flags)
0)) == -1)
return -1;
+#ifdef __linux__
+ if (path[0] != '@')
+#endif
+ unlink(path);
+
if (bind(s, (struct sockaddr *)&s_un, addrlen) == -1) {
save_errno = errno;
close(s);
@@ -1108,7 +1129,7 @@ unix_connect(char *path)
if (uflag) {
if ((s = unix_bind(unix_dg_tmp_socket, SOCK_CLOEXEC)) == -1)
- return -1;
+ err(1, "%s", unix_dg_tmp_socket);
} else {
if ((s = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1)
return -1;
@@ -1381,12 +1402,12 @@ local_listen(const char *host, const char *port, struct addrinfo hints)
ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x));
if (ret == -1)
- err(1, NULL);
+ warn("Couldn't set SO_REUSEADDR");
#ifdef SO_REUSEPORT
ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &x, sizeof(x));
if (ret == -1)
- err(1, NULL);
+ warn("Couldn't set SO_REUSEPORT");
#endif
set_common_sockopts(s, res->ai_addr);