Nmap Development mailing list archives

Implementation sketch for Ncat caretaker processes


From: David Fifield <david () bamsoftware com>
Date: Fri, 6 Nov 2009 15:47:22 -0700

On Fri, Nov 06, 2009 at 10:39:58PM +0530, venkat sanaka wrote:
Yes, this has been on my TODO for a long time. We already do this on
Windows, where you can't just redirect the standard input and output of
a child process to a socket. Instead, we create a couple of pipes to
pass to the subprocess, and start a thread to relay data between the
socket and the pipes. Besides allowing --exec with SSL, this would also
allow logging of data sent and received by the child process.

I had already gone through some part of command execution code
while fixing this bug: http://seclists.org/nmap-dev/2009/q4/44

So David,I would like to work on this if you can give me more insight
on this issue.

Look at the netrun function in ncat_posix.c. It forks to create a new
process, then calls netexec. netexec reassigns some file descriptors,
then runs execl to run a new process with the changed descriptors. When
the new process reads and writes stdin and stdout, it is really reading
and writing the socket.

What I was thinking of is that netexec can first create a pair of pipes
(http://www.gnu.org/software/libc/manual/html_node/Creating-a-Pipe.html),
fork a new process, call dup2 to rearrange the descriptors in the child
process, then exec the requested command. The parent process would be a
simple loop:

        while (true) {
                select([socket and read_pipe]);
                if (socket is ready) {
                        read(socket); // May use SSL.
                        log socket read;
                        write(write_pipe)
                } else if (read_pipe is ready) {
                        read(read_pipe);
                        log pipe read;
                        write(socket); // May use SSL.
                }
        }

You would break the loop on any read or write error. Look at
subprocess_thread_func in ncat_exec_win.c. The Windows version already
uses a caretaker thread so it would only need SSL support and logging to
be added.

The above technique costs two processes per connection. You could do it
with less overhead if you create the pipes and fork a subprocess when a
connection is received, then add the read end of the pipe connected to
stdout of the child process to the select set. When select indicates
that a decriptor is ready, there would be four cases:

        1. The listening socket.
        2. A connected client socket.
        3. The server's own stdin.
        4. The stdout of a child process.

In case 2, you would read from the socket and write to the pipe of its
corresponding process. In case 4, you would read from the pipe and write
to its corresponding socket.

David Fifield
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: