mirror of
https://github.com/nmap/nmap.git
synced 2026-08-27 03:48:14 +00:00
add NCAT_LOCAL_ADDR, NCAT_LOCAL_PORT, NCAT_REMOTE_ADDR, NCAR_REMOTE_PORT,
NCAT_REMOTE_ADDR environment variables set in all --*-exec child processes. (this is a merge of ncat-env-conninfo as of r31516)
This commit is contained in:
parent
f5a142b0d4
commit
8f84863a23
12 changed files with 276 additions and 4 deletions
|
|
@ -135,16 +135,16 @@ config.h:
|
|||
$(SHELL) ./config.status; \
|
||||
fi
|
||||
|
||||
test/addrset: test/addrset.o ncat_core.o sys_wrap.o util.o $(LUA_OBJS)
|
||||
test/addrset: test/addrset.o ncat_core.o sys_wrap.o util.o ncat_posix.o $(LUA_OBJS)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS)
|
||||
|
||||
test/test-uri: test/test-uri.o base64.o http.o ncat_core.o sys_wrap.o util.o $(LUA_OBJS)
|
||||
test/test-uri: test/test-uri.o base64.o http.o ncat_core.o sys_wrap.o util.o ncat_posix.o $(LUA_OBJS)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS)
|
||||
|
||||
test/test-cmdline-split: test/test-cmdline-split.o ncat_posix.o ncat_core.o sys_wrap.o util.o $(LUA_OBJS)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS)
|
||||
|
||||
test/test-wildcard: test/test-wildcard.o ncat_core.o ncat_ssl.o sys_wrap.o util.o $(LUA_OBJS)
|
||||
test/test-wildcard: test/test-wildcard.o ncat_core.o ncat_ssl.o sys_wrap.o util.o ncat_posix.o $(LUA_OBJS)
|
||||
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(LIBS) $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS)
|
||||
|
||||
.PHONY: uninstall all clean distclean
|
||||
|
|
|
|||
|
|
@ -462,6 +462,30 @@
|
|||
accept a maximum, definable, number of simultaneous connections
|
||||
controlled by the <option>-m</option> option. By default this is set
|
||||
to 100 (60 on Windows).</para>
|
||||
|
||||
<para>--exec adds the following variables to the child's environment:
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>NCAT_REMOTE_ADDR - the remote address - in connect mode,
|
||||
it's the one we're connecting to, in listen mode - it's the one
|
||||
that connected to us,</listitem>
|
||||
|
||||
<listitem>NCAT_REMOTE_PORT - the remote port number, where "remote"
|
||||
means the same as above,</listitem>
|
||||
|
||||
<listitem>NCAT_LOCAL_ADDR - our local address used for
|
||||
establishing/receiving the connection,</listitem>
|
||||
|
||||
<listitem>NCAT_LOCAL_PORT - our local port number,</listitem>
|
||||
|
||||
<listitem>NCAT_PROTO - the protocol name - TCP, UDP or SCTP,</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>Currently the address fields are numeric IP addresses. In IPv6
|
||||
mode, the address might be not expanded.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
|
@ -476,7 +500,9 @@
|
|||
<para>Same as <option>-e</option>, except it tries to execute
|
||||
the command via <filename>/bin/sh</filename>. This means you don't
|
||||
have to specify the full path for the command, and shell facilities
|
||||
like environment variables are available.</para>
|
||||
like environment variables are available. Ncat also sets a few
|
||||
special environment variables (see <option>-e</option> for details).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
|
|
|||
|
|
@ -511,3 +511,45 @@ static int ncat_hexdump(int logfd, const char *data, int len)
|
|||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void setup_environment(struct fdinfo *info)
|
||||
{
|
||||
union sockaddr_u su;
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
char port[16];
|
||||
socklen_t alen = sizeof(su);
|
||||
|
||||
if (getpeername(info->fd, &su.sockaddr, &alen) != 0) {
|
||||
bye("getpeername failed: %s", socket_strerror(socket_errno()));
|
||||
}
|
||||
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
|
||||
port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
|
||||
setenv_portable("NCAT_REMOTE_ADDR", ip);
|
||||
setenv_portable("NCAT_REMOTE_PORT", port);
|
||||
} else {
|
||||
bye("getnameinfo failed: %s", socket_strerror(socket_errno()));
|
||||
}
|
||||
|
||||
if (getsockname(info->fd, (struct sockaddr *)&su, &alen) < 0) {
|
||||
bye("getsockname failed: %s", socket_strerror(socket_errno()));
|
||||
}
|
||||
if (getnameinfo((struct sockaddr *)&su, alen, ip, sizeof(ip),
|
||||
port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
|
||||
setenv_portable("NCAT_LOCAL_ADDR", ip);
|
||||
setenv_portable("NCAT_LOCAL_PORT", port);
|
||||
} else {
|
||||
bye("getnameinfo failed: %s", socket_strerror(socket_errno()));
|
||||
}
|
||||
|
||||
switch(o.proto) {
|
||||
case IPPROTO_TCP:
|
||||
setenv_portable("NCAT_PROTO", "TCP");
|
||||
break;
|
||||
case IPPROTO_SCTP:
|
||||
setenv_portable("NCAT_PROTO", "SCTP");
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
setenv_portable("NCAT_PROTO", "UDP");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,3 +230,6 @@ extern int ncat_hostaccess(char *matchaddr, char *filename, char *remoteip);
|
|||
/* Make it so that line endings read from a console are always \n (not \r\n).
|
||||
Defined in ncat_posix.c and ncat_win.c. */
|
||||
extern void set_lf_mode(void);
|
||||
|
||||
extern int setenv_portable(const char *name, const char *value);
|
||||
extern void setup_environment(struct fdinfo *fdinfo);
|
||||
|
|
|
|||
|
|
@ -195,6 +195,28 @@ extern void set_pseudo_sigchld_handler(void (*handler)(void))
|
|||
ncat_assert(rc != 0);
|
||||
}
|
||||
|
||||
int setenv_portable(const char *name, const char *value)
|
||||
{
|
||||
BOOL ret = SetEnvironmentVariable(name, value);
|
||||
if (ret == 0) {
|
||||
DWORD last_error = GetLastError();
|
||||
switch (last_error) {
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
case ERROR_NOT_ENOUGH_MEMORY:
|
||||
errno = ENOMEM;
|
||||
break;
|
||||
default:
|
||||
if (o.debug)
|
||||
logdebug("SetEnvironmentVariable: GetLastError returned %d\n", last_error);
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret != 0;
|
||||
}
|
||||
|
||||
/* Run a command and redirect its input and output handles to a pair of
|
||||
anonymous pipes. The process handle and pipe handles are returned in the
|
||||
info struct. Returns the PID of the new process, or -1 on error. */
|
||||
|
|
@ -207,6 +229,8 @@ static int run_command_redirected(char *cmdexec, struct subprocess_info *info)
|
|||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
setup_environment(&info->fdn);
|
||||
|
||||
/* Make the pipe handles inheritable. */
|
||||
sa.nLength = sizeof(sa);
|
||||
sa.bInheritHandle = TRUE;
|
||||
|
|
|
|||
|
|
@ -192,6 +192,8 @@ void netexec(struct fdinfo *info, char *cmdexec)
|
|||
Dup2(child_stdin[0], STDIN_FILENO);
|
||||
Dup2(child_stdout[1], STDOUT_FILENO);
|
||||
|
||||
setup_environment(info);
|
||||
|
||||
switch (o.execmode) {
|
||||
char **cmdargs;
|
||||
|
||||
|
|
@ -389,3 +391,8 @@ int ssl_load_default_ca_certs(SSL_CTX *ctx)
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int setenv_portable(const char *name, const char *value)
|
||||
{
|
||||
return setenv(name, value, 1);
|
||||
}
|
||||
|
|
|
|||
10
ncat/scripts/log_ips.sh
Normal file
10
ncat/scripts/log_ips.sh
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
|
||||
LOGFILE="log_ips.log"
|
||||
|
||||
MSG="[`date`] Incoming connection from $NCAT_REMOTE_ADDR:$NCAT_REMOTE_PORT"
|
||||
|
||||
echo $MSG >&2
|
||||
echo $MSG >> $LOGFILE
|
||||
|
||||
echo "Yeah, hi."
|
||||
97
ncat/scripts/p0fme.py
Executable file
97
ncat/scripts/p0fme.py
Executable file
|
|
@ -0,0 +1,97 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from __future__ import print_function # logging, python2-only.
|
||||
|
||||
"""
|
||||
A script that reads data generated by p0f -f p0f.log, looking for all entries
|
||||
about an IP read from NCAT_REMOTE_ADDR environment variable. Then it prints out
|
||||
all the information it has found. To try it out, run "p0f -i any -o p0f.log"
|
||||
and ncat -l -k --sh-exec "python p0fme.py".
|
||||
|
||||
Script tested under Python versions 2.7 and 3.3.
|
||||
"""
|
||||
|
||||
P0F_LOG_FILE = "p0f.log"
|
||||
|
||||
import datetime # logging
|
||||
import sys # logging
|
||||
import os # environ
|
||||
import time # sleeping to wait for data
|
||||
import sys # to flush STDOUT
|
||||
|
||||
|
||||
def expand_ipv6(ip):
|
||||
"""
|
||||
Expands short IPv6 address like ::1 into an expanded form without trailing
|
||||
zeros. Copied from:
|
||||
|
||||
http://svn.python.org/projects/python/tags/r31b1/Lib/ipaddr.py
|
||||
|
||||
(Py3 standard library; added some modifications to match p0f's output data)
|
||||
"""
|
||||
|
||||
new_ip = []
|
||||
hextet = ip.split('::')
|
||||
sep = len(hextet[0].split(':')) + len(hextet[1].split(':'))
|
||||
new_ip = hextet[0].split(':')
|
||||
|
||||
for _ in range(8 - sep):
|
||||
new_ip.append('0')
|
||||
new_ip += hextet[1].split(':')
|
||||
|
||||
# Now need to make sure every hextet is 4 lower case characters.
|
||||
# If a hextet is < 4 characters, we've got missing leading 0's.
|
||||
ret_ip = []
|
||||
for hextet in new_ip:
|
||||
if hextet == '':
|
||||
hextet = '0'
|
||||
ret_ip.append(hextet.lower())
|
||||
return ':'.join(ret_ip)
|
||||
|
||||
|
||||
def split_by_equals(str_):
|
||||
ret = str_.split('=')
|
||||
return ret[0], ''.join(ret[1:])
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
ip = os.environ['NCAT_REMOTE_ADDR']
|
||||
if os.environ['NCAT_PROTO'] != 'TCP':
|
||||
sys.exit("ERROR: This script works for TCP servers only!")
|
||||
except KeyError:
|
||||
sys.exit("ERROR: This script has to be run from inside of Ncat.")
|
||||
print("[%s] Got a request from %s" % (
|
||||
datetime.datetime.now().isoformat(' '), ip), file=sys.stderr)
|
||||
|
||||
print("Hold on, I'm collecting data on you...")
|
||||
sys.stdout.flush()
|
||||
time.sleep(3.0)
|
||||
|
||||
if ':' in ip: # We need to expand IPv6 addresses in a specific way.
|
||||
ip = expand_ipv6(ip)
|
||||
result = {}
|
||||
|
||||
# Reading the log backward will give us more recent results.
|
||||
for line in reversed(open(P0F_LOG_FILE).readlines()):
|
||||
|
||||
without_date = line.split('] ')
|
||||
if without_date == ['\n']:
|
||||
continue
|
||||
without_date = ''.join(without_date[1:])
|
||||
|
||||
# Create a key-value dictionary out of the '|'-separated substrings.
|
||||
properties = dict(map(split_by_equals, without_date.split('|')))
|
||||
|
||||
if not properties['cli'].startswith(ip):
|
||||
continue # Not the IP we're looking for, check next one.
|
||||
|
||||
for key in properties:
|
||||
if not key in result or result[key] == '???':
|
||||
result[key] = properties[key]
|
||||
|
||||
if not result:
|
||||
print("Got nothing on you. Try again and I will, though.")
|
||||
|
||||
# Now that we've finished, print out the results.
|
||||
for key in sorted(result):
|
||||
print("%s: %s" % (key, result[key].rstrip()))
|
||||
4
ncat/scripts/whatismyip.lua
Normal file
4
ncat/scripts/whatismyip.lua
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
--A "what is my IP" service code. Since most web browsers put up with servers
|
||||
--not sending proper HTTP headers, you can simply query the service with it.
|
||||
|
||||
print(os.getenv("NCAT_REMOTE_ADDR"))
|
||||
|
|
@ -381,6 +381,16 @@ sub max_conns_test_tcp_ssl {
|
|||
max_conns_test_multi(["tcp", "tcp ssl"], @_);
|
||||
}
|
||||
|
||||
sub match_ncat_environment {
|
||||
$_ = shift;
|
||||
return /NCAT_REMOTE_ADDR=.+\n
|
||||
NCAT_REMOTE_PORT=.+\n
|
||||
NCAT_LOCAL_ADDR=.+\n
|
||||
NCAT_LOCAL_PORT=.+\n
|
||||
NCAT_PROTO=.+
|
||||
/x;
|
||||
}
|
||||
|
||||
# Ignore broken pipe signals that result when trying to read from a terminated
|
||||
# client.
|
||||
$SIG{PIPE} = "IGNORE";
|
||||
|
|
@ -1084,6 +1094,35 @@ server_client_test_all "--lua-exec",
|
|||
$resp eq "ABC\n" or die "Client received " . d($resp) . ", not " . d("ABC\n");
|
||||
};
|
||||
|
||||
# Test environment variables being set for --exec, --sh-exec and --lua-exec.
|
||||
|
||||
server_client_test_all "--exec, environment variables",
|
||||
["--exec", "/bin/sh test-environment.sh"], [], sub {
|
||||
syswrite($c_in, "abc\n");
|
||||
my $resp = timeout_read($c_out) or die "Read timeout";
|
||||
match_ncat_environment($resp) or die "Client received " . d($resp) . ".";
|
||||
};
|
||||
|
||||
server_client_test_all "--sh-exec, environment variables",
|
||||
["--sh-exec", "sh test-environment.sh"], [], sub {
|
||||
syswrite($c_in, "abc\n");
|
||||
my $resp = timeout_read($c_out) or die "Read timeout";
|
||||
match_ncat_environment($resp) or die "Client received " . d($resp) . ".";
|
||||
};
|
||||
|
||||
proxy_test "--exec through proxy, environment variables",
|
||||
[], [], ["--exec", "/bin/sh test-environment.sh"], sub {
|
||||
my $resp = timeout_read($s_out) or die "Read timeout";
|
||||
match_ncat_environment($resp) or die "Client received " . d($resp) . ".";
|
||||
};
|
||||
|
||||
server_client_test_all "--lua-exec, environment variables",
|
||||
["--lua-exec", "test-environment.lua"], [], sub {
|
||||
syswrite($c_in, "abc\n");
|
||||
my $resp = timeout_read($c_out) or die "Read timeout";
|
||||
match_ncat_environment($resp) or die "Client received " . d($resp) . ".";
|
||||
};
|
||||
|
||||
# Do a syswrite and then a delay to force separate reads in the subprocess.
|
||||
sub delaywrite {
|
||||
my ($handle, $data) = @_;
|
||||
|
|
|
|||
9
ncat/test/test-environment.lua
Normal file
9
ncat/test/test-environment.lua
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/lua
|
||||
|
||||
--Print the following NCAT_* variables and their values:
|
||||
envs = {'REMOTE_ADDR', 'REMOTE_PORT', 'LOCAL_ADDR', 'LOCAL_PORT', 'PROTO'}
|
||||
|
||||
for _,v in pairs(envs) do
|
||||
v = 'NCAT_' .. v
|
||||
print(("%s=%s"):format(v, os.getenv(v)))
|
||||
end
|
||||
11
ncat/test/test-environment.sh
Executable file
11
ncat/test/test-environment.sh
Executable file
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Print the contents of all environment variables set by Ncat.
|
||||
|
||||
echo "NCAT_REMOTE_ADDR=$NCAT_REMOTE_ADDR"
|
||||
echo "NCAT_REMOTE_PORT=$NCAT_REMOTE_PORT"
|
||||
|
||||
echo "NCAT_LOCAL_ADDR=$NCAT_LOCAL_ADDR"
|
||||
echo "NCAT_LOCAL_PORT=$NCAT_LOCAL_PORT"
|
||||
|
||||
echo "NCAT_PROTO=$NCAT_PROTO"
|
||||
Loading…
Add table
Add a link
Reference in a new issue