1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-29 02:49:01 +00:00

Add connect-mode recv() and send() support.

This commit is contained in:
david
2013-09-12 08:12:25 +00:00
parent bc96871709
commit 08e38545a3
5 changed files with 204 additions and 27 deletions

View File

@@ -83,15 +83,19 @@ DATAFILES = certs/ca-bundle.crt
endif
ifneq ($(HAVE_LUA),)
LUA_SRCS = ncat_lua_exec.c ncat_lua.c ncat_lua_filters.c
LUA_OBJS = ncat_lua_exec.o ncat_lua.o ncat_lua_filters.o
LUA_SRCS = ncat_lua.c ncat_lua_exec.c ncat_lua_filters.c ncat_lua_connect.c
LUA_OBJS = ncat_lua.o ncat_lua_exec.o ncat_lua_filters.o ncat_lua_connect.o
LUA_LIBS = @LIBLUA_LIBS@ -lm
LUA_CFLAGS += -DHAVE_LUA=1 -I../liblua
# This is the result of lua_setup() pulling in recv/send routines, which
# in turn pull a few other files.
MORE_TEST_OBJS = http.o http_digest.o base64.o ncat_ssl.o ncat_connect.o
else
LUA_SRCS =
LUA_OBJS =
LUA_LIBS =
LUA_CFLAGS =
MORE_TEST_OBJS =
endif
SRCS += $(LUA_SRCS)
@@ -135,16 +139,16 @@ config.h:
$(SHELL) ./config.status; \
fi
test/addrset: test/addrset.o ncat_core.o sys_wrap.o util.o ncat_posix.o $(LUA_OBJS)
test/addrset: test/addrset.o ncat_core.o sys_wrap.o util.o ncat_posix.o $(MORE_TEST_OBJS) $(LUA_OBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS) $(LIBS)
test/test-uri: test/test-uri.o base64.o http.o ncat_core.o sys_wrap.o util.o ncat_posix.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 $(MORE_TEST_OBJS) $(LUA_OBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS) $(LIBS)
test/test-cmdline-split: test/test-cmdline-split.o ncat_posix.o ncat_core.o sys_wrap.o util.o $(LUA_OBJS)
test/test-cmdline-split: test/test-cmdline-split.o ncat_posix.o ncat_core.o sys_wrap.o util.o $(MORE_TEST_OBJS) $(LUA_OBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS) $(LIBS)
test/test-wildcard: test/test-wildcard.o ncat_core.o ncat_ssl.o sys_wrap.o util.o ncat_posix.o $(LUA_OBJS)
test/test-wildcard: test/test-wildcard.o ncat_core.o ncat_ssl.o sys_wrap.o util.o ncat_posix.o $(MORE_TEST_OBJS) $(LUA_OBJS)
$(CC) -o $@ $(CFLAGS) $(LDFLAGS) $^ $(NSOCKLIB) $(NBASELIB) $(OPENSSL_LIBS) $(PCAP_LIBS) $(LUA_LIBS) $(LIBS)
.PHONY: uninstall all clean distclean

View File

@@ -151,6 +151,11 @@
#define SHUT_WR SD_SEND
#endif
#ifdef HAVE_LUA
#include "ncat_lua_filters.h"
#include "ncat_lua_connect.h"
#endif
struct conn_state {
nsock_iod sock_nsi;
nsock_iod stdin_nsi;
@@ -169,7 +174,6 @@ static void connect_handler(nsock_pool nsp, nsock_event evt, void *data);
static void post_connect(nsock_pool nsp, nsock_iod iod);
static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data);
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data);
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data);
static void idle_timer_handler(nsock_pool nsp, nsock_event evt, void *data);
static void refresh_idle_timer(nsock_pool nsp);
@@ -549,6 +553,10 @@ int ncat_connect(void)
cs.sock_nsi = nsi_new(mypool, NULL);
if (cs.sock_nsi == NULL)
bye("Failed to create nsock_iod.");
#ifdef HAVE_LUA
if (o.script)
lua_nsock_save(mypool, cs.sock_nsi);
#endif
if (nsi_set_hostname(cs.sock_nsi, o.target) == -1)
bye("Failed to set hostname on iod.");
@@ -706,6 +714,10 @@ int ncat_connect(void)
/* Create IOD for nsp->stdin */
if ((cs.stdin_nsi = nsi_new2(mypool, 0, NULL)) == NULL)
bye("Failed to create stdin nsiod.");
#ifdef HAVE_LUA
if (o.script)
lua_nsock_save(mypool, cs.sock_nsi);
#endif
post_connect(mypool, cs.sock_nsi);
}
@@ -792,8 +804,14 @@ static void post_connect(nsock_pool nsp, nsock_iod iod)
/* Start the initial reads. */
if (!o.sendonly)
nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL);
if (!o.sendonly) {
#ifdef HAVE_LUA
if (o.script)
lua_nsock_read(0);
else
#endif
nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL);
}
if (!o.recvonly)
nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0);
@@ -845,7 +863,13 @@ static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data)
buf = tmp;
}
nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, buf, nbytes);
#ifdef HAVE_LUA
if (o.script)
lua_nsock_write(nsp, cs.sock_nsi, buf, nbytes);
else
#endif
nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, buf, nbytes);
ncat_log_send(buf, nbytes);
if (tmp)
@@ -854,12 +878,11 @@ static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data)
refresh_idle_timer(nsp);
}
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
/* Handle nsock errors. */
int check_nsock_error(nsock_pool nsp, nsock_event evt)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);
char *buf;
int nbytes;
ncat_assert(type == NSE_TYPE_READ);
@@ -868,7 +891,7 @@ static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
/* In --recv-only mode or non-TCP mode, exit after EOF on the socket. */
if (o.proto != IPPROTO_TCP || (o.proto == IPPROTO_TCP && o.recvonly))
nsock_loop_quit(nsp);
return;
return 1;
} else if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
@@ -876,29 +899,46 @@ static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else if (status == NSE_STATUS_CANCELLED || status == NSE_STATUS_KILL) {
return;
return 1;
} else {
ncat_assert(status == NSE_STATUS_SUCCESS);
}
return 0;
}
buf = nse_readbuf(evt, &nbytes);
/* Handle some post-read activities. */
void ncat_nsock_postread(nsock_pool nsp, nsock_event evt, const char *buf, int nbytes)
{
if (o.linedelay)
ncat_delay_timer(o.linedelay);
if (o.telnet)
dotelnet(nsi_getsd(nse_iod(evt)), (unsigned char *) buf, nbytes);
if (nbytes > 0) {
if (o.telnet)
dotelnet(nsi_getsd(nse_iod(evt)), (unsigned char *) buf, nbytes);
/* Write socket data to stdout */
Write(STDOUT_FILENO, buf, nbytes);
ncat_log_recv(buf, nbytes);
nsock_readbytes(nsp, cs.sock_nsi, read_socket_handler, -1, NULL, 0);
/* Write socket data to stdout */
Write(STDOUT_FILENO, buf, nbytes);
ncat_log_recv(buf, nbytes);
}
refresh_idle_timer(nsp);
}
static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
{
char *buf;
int nbytes;
if (check_nsock_error(nsp, evt))
return;
buf = nse_readbuf(evt, &nbytes);
ncat_nsock_postread(nsp, evt, buf, nbytes);
nsock_readbytes(nsp, cs.sock_nsi, read_socket_handler, -1, NULL, 0);
}
void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
enum nse_type type = nse_type(evt);

View File

@@ -123,5 +123,13 @@
#include "nsock.h"
#ifdef HAVE_LUA
#include "ncat_lua.h"
#include "ncat_lua_connect.h"
#endif
/* handle nsock-powered connections */
extern int ncat_connect(void);
int check_nsock_error(nsock_pool nsp, nsock_event evt);
void ncat_nsock_postread(nsock_pool nsp, nsock_event evt, const char *buf, int nbytes);
void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data);

View File

@@ -139,11 +139,17 @@ static void lua_create_supersocket()
lua_newtable(filters_L);
lua_pushstring(filters_L, "recv");
lua_pushcfunction(filters_L, lua_do_nothing);
if (o.listen)
lua_pushcfunction(filters_L, lua_do_nothing); /* TODO */
else
lua_pushcfunction(filters_L, lua_nsock_recv_raw);
lua_settable(filters_L, -3);
lua_pushstring(filters_L, "send");
lua_pushcfunction(filters_L, lua_do_nothing);
if (o.listen)
lua_pushcfunction(filters_L, lua_do_nothing);
else
lua_pushcfunction(filters_L, lua_nsock_write_raw);
lua_settable(filters_L, -3);
lua_set_registry("socket");
@@ -229,3 +235,109 @@ void lua_run_filter(char *cmdexec)
lua_report(filters_L, cmdexec, 1);
lua_set_registry("socket");
}
/* Try to find the connection in the global table named "connections" with fd
as the key. If it's not there, create it, find its topmost "super", set its
"fd" to the given struct ncat_lua_state and save it in connection_supers.
Leave the socket on the stack. If *fdn is NULL, we assume that fd=0 and
we're in connect mode. Also, if *created is not NULL, it is set to 1 if
the socket put on the stack was just created. */
struct ncat_lua_state* get_connection(struct fdinfo *fdn, int *created)
{
struct ncat_lua_state *ret;
int connections_key;
if (fdn == NULL)
connections_key = 0;
else
connections_key = fdn->fd;
/* Try to access connections[fd]. Leave connections[] on the stack. */
lua_fetch_registry("connections");
lua_pushinteger(filters_L, connections_key);
lua_gettable(filters_L, -2);
if (lua_isnil(filters_L, -1)) {
lua_pop(filters_L, 1); /* nil means we hadn't added the connection yet, pop it. */
/* Basically: connections[fd] = new_socket(socket) */
lua_pushinteger(filters_L, connections_key);
lua_pushvalue(filters_L, make_socket_function_idx);
lua_pushvalue(filters_L, make_socket_function_idx);
lua_fetch_registry("socket");
if (lua_pcall(filters_L, 2, 1, error_handler_idx) != LUA_OK)
lua_report(filters_L, "Error creating the socket", 1);
lua_pushvalue(filters_L, -1); /* Make a copy of the connection we created. */
lua_insert(filters_L, -4); /* Move it below connection, 5 and original table. */
lua_settable(filters_L, -3);
lua_pop(filters_L, 1); /* Get rid of connections[]. */
/* Make another copy of the table - we'll work on the current one
looking for the topmost super. */
lua_pushvalue(filters_L, -1);
for(;;) {
lua_pushvalue(filters_L, -1); /* Copy the current table */
lua_pushstring(filters_L, "super");
lua_gettable(filters_L, -2);
lua_insert(filters_L, -2); /* Move the copy to the top, pop it */
lua_pop(filters_L, 1);
if (lua_isnil(filters_L, -1)) {
lua_pop(filters_L, 1); /* Pop the nil */
break; /* There's no super, we're at the top */
}
lua_insert(filters_L, -2); /* Get rid of the old table */
lua_pop(filters_L, 1);
}
ret = (struct ncat_lua_state *) Calloc(1, sizeof(*ret));
if (fdn != NULL)
ret->fdn = *fdn;
/* Set the "lua_state" to a pointer to ret. */
lua_pushlightuserdata(filters_L, ret);
lua_setfield(filters_L, -2, "lua_state");
lua_fetch_registry("connection_roots");
lua_pushinteger(filters_L, connections_key);
lua_pushvalue(filters_L, -3);
lua_remove(filters_L, -4);
lua_settable(filters_L, -3);
lua_pop(filters_L, 1);
if (created != NULL)
*created = 1;
} else {
lua_insert(filters_L, -2); /* Get rid of connections[]. */
lua_pop(filters_L, 1);
/* Get the struct ncat_lua_state from connection_roots[fd].lua_state. */
lua_fetch_registry("connection_roots");
lua_pushinteger(filters_L, connections_key);
lua_gettable(filters_L, -2);
lua_getfield(filters_L, -1, "lua_state");
ret = (struct ncat_lua_state *) lua_touserdata(filters_L, -1);
lua_pop(filters_L, 3); /* Pop the userdata, the table and connection_roots. */
if (created != NULL)
*created = 0;
}
return ret;
}
/* Read "lua_state" field from socket table available under stack index given
as the second argument. If after the call *ret is set to a non-negative
value, it must be returned. */
struct ncat_lua_state* lua_fetch_userdata(lua_State *L, int idx, int *ret)
{
struct ncat_lua_state *nls;
*ret = -1;
lua_getfield(L, idx, "lua_state");
nls = (struct ncat_lua_state *) lua_touserdata(L, -1);
if (nls == NULL) {
lua_pushnil(L);
lua_pushstring(L, "Socket already closed");
*ret = 2;
}
return nls;
}

View File

@@ -126,6 +126,19 @@
struct ncat_lua_state {
struct fdinfo fdn;
/* Only used in connect mode: */
int in_send;
/* Needed for receiving */
nsock_event evt;
/* 1 if the next read should be performed by nsock_readbytes, 0 if
nsock_read. */
int readbytes;
/* Needed for sending */
nsock_pool nsp;
nsock_iod nsiod;
};
void lua_fetch_registry(const char *key);