Nmap Development mailing list archives
Re: ncat - UNIX-domain sockets support
From: Tomas Hozza <thozza () redhat com>
Date: Mon, 26 Nov 2012 10:44:53 -0500 (EST)
----- Original Message -----
I used tempnam() function which uses TMPDIR and TMP, so "/tmp" is not hardcoded. It was done so also in the last bunch of patches.http://www.dwheeler.com/secure-programs/Secure-Programs-HOWTO/avoid-race.html#TEMPORARY-FILESThere is example of how to use tempnam function to be more safe, but unfortunately this can not be used in this case. The problem is that after the temporary name is generated, we are not opening/creating any file/socket. It is done later when calling bind() on the source socket FD together with the temporary name (so the socket binds to the path/name).This is the way I was thinking before too. But netcat-openbsd calls mkstemp, at least if I understand correctly. Apparently it is no problem for the file to exist as a regular file before binding to it?
If the file already exists it is a real problem. The bind() call will fail with errno 98 "Address already in use". Therefore when creating source socket "file" (when bind() is called) file with the given/generated path MUST NOT exist. Another thing I found out after discussion with my colleagues is, that Ncat's configure script should let user specify the directory for creating temporary source DGRAM Unix sockets generated by Ncat. Therefore I added new argument into Ncat configure script called TMP_UNIX_SOCK_DIR. If it is specified, then configure will define macro in config.h header. Depending on whether it is specified, tempnam() is compiled with or without specific directory set: #ifdef TMP_UNIX_SOCK_DIR if ((tmp_name = tempnam(TMP_UNIX_SOCK_DIR, "ncat.")) == NULL) #else if ((tmp_name = tempnam(NULL, "ncat.")) == NULL) #endif Even if TMP_UNIX_SOCK_DIR is specified, tempnam() prefers TMPDIR environment variable if it is set. My motivation for this is, that regarding to FSH 2.3 standard (http://www.pathname.com/fhs/pub/fhs-2.3.html#VARRUNRUNTIMEVARIABLEDATA) System programs that maintain transient UNIX-domain sockets must place them in "/var/run". Therefore we would like to have a way to specify the directory in compilation time.
If so, then that is what we should do. I want to avoid a race condition like the following: 1. tempnam generates a nonexistent name in /tmp.
This is a MUST for Ncat to connect successfully.
2. Attacker guesses the name and puts something there. 3. Ncat binds to the file name.
If the file already exist, Ncat will exit.
4. Ncat calls unlink on the attacker-controlled file name.
I modified the code, so Ncat does not call unlink on socket, that it did not create.
Offhand I can't think of what harm an attacker can do with such an unlink, but since the implications are unknown, it's better to be safe. Please correct me if I misunderstand something. I'd also like to be sure to unlink the socket even if there is an error. Would you check if it's possible to replace exit(1); with nsock_loop_quit(nsp); return; in the ncat_connect callbacks?
Thank you for this idea. I used it in every handler function, so now the created socket is deleted if any ERROR occurs. Regarding to this I discovered one Bug in Nsock library, that caused bad statistic output when client tried to send some data to server, but the server was not running any more. I this case it caused output like the following (where you can see "18446744073709551615 bytes sent"): $ ./ncat -Uu -vvvvvvvvvvvvvvvvvvv -s source_socket9 /tmp/socket Ncat: Version 6.20BETA1 ( http://nmap.org/ncat ) Ncat: [source_socket9] used as source DGRAM Unix domain socket. NSOCK (0.0010s) UNIX domain socket (DGRAM) connection requested to /tmp/socket (IOD #1) EID 8 NSOCK (0.0010s) Callback: CONNECT SUCCESS for EID 8 [/tmp/socket] Ncat: Connected to /tmp/socket. NSOCK (0.0010s) Read request from IOD #1 [/tmp/socket] (timeout: -1ms) EID 18 NSOCK (0.0010s) Read request for 0 bytes from IOD #2 (peer unspecified) EID 26 NSOCK (7.3750s) Callback READ SUCCESS for EID 26 (peer unspecified) (1 bytes) NSOCK (7.3750s) Write request for 1 bytes to IOD #1 EID 35 [/tmp/socket] NSOCK (7.3750s) Callback: WRITE ERROR [Connection refused (111)] for EID 35 [/tmp/socket] Ncat: Connection refused. NSOCK (7.3750s) Read request for 0 bytes from IOD #2 (peer unspecified) EID 42 Ncat: 18446744073709551615 bytes sent, 0 bytes received in 7.38 seconds. Ncat: Deleting source DGRAM Unix domain socket. [source_socket9] NSOCK (7.3750s) Callback: READ KILL for EID 18 [/tmp/socket] NSOCK (7.3750s) Callback: READ KILL for EID 42 (peer unspecified) Regards, Tomas Hozza
Attachment:
0001-Bring-back-generation-of-src-DGRAM-socket-name-v2.patch
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Oct 04)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Oct 15)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 08)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 08)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 12)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 12)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 13)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 20)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 21)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 21)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 26)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 27)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 28)
- Re: ncat - UNIX-domain sockets support David Fifield (Nov 28)
- Re: ncat - UNIX-domain sockets support Tomas Hozza (Nov 12)