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

Adds zero-byte option(-z) for Ncat. Fixes #22 and #225

This commit is contained in:
abhishek
2016-07-19 10:07:58 +00:00
parent 0c1d68d6de
commit d1a10dfc63
4 changed files with 52 additions and 7 deletions

View File

@@ -1078,6 +1078,13 @@ int ncat_connect(void)
return rc == NSOCK_LOOP_ERROR ? 1 : 0;
}
static void send_udp_null(nsock_pool nsp)
{
char *NULL_PROBE = "\0";
int length = 1;
nsock_write(nsp, cs.sock_nsi, write_socket_handler, -1, NULL, NULL_PROBE, length);
}
static void connect_handler(nsock_pool nsp, nsock_event evt, void *data)
{
enum nse_status status = nse_status(evt);
@@ -1086,10 +1093,12 @@ static void connect_handler(nsock_pool nsp, nsock_event evt, void *data)
ncat_assert(type == NSE_TYPE_CONNECT || type == NSE_TYPE_CONNECT_SSL);
if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
if (!o.zerobyte||o.verbose)
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
if (!o.zerobyte||o.verbose)
loguser("%s.\n", socket_strerror(ETIMEDOUT));
exit(1);
} else {
ncat_assert(status == NSE_STATUS_SUCCESS);
@@ -1104,7 +1113,10 @@ static void connect_handler(nsock_pool nsp, nsock_event evt, void *data)
}
#endif
connect_report(cs.sock_nsi);
if (o.proto != IPPROTO_UDP && o.zerobyte) {
connect_report(cs.sock_nsi);
nsock_loop_quit(nsp);
}
/* Create IOD for nsp->stdin */
if ((cs.stdin_nsi = nsock_iod_new2(nsp, 0, NULL)) == NULL)
@@ -1134,12 +1146,15 @@ static void post_connect(nsock_pool nsp, nsock_iod iod)
/* Start the initial reads. */
if (!o.sendonly)
if (!o.sendonly && !o.zerobyte)
nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL);
if (!o.recvonly)
if (!o.recvonly && !o.zerobyte)
nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0);
if (o.zerobyte && o.proto==IPPROTO_UDP)
send_udp_null(nsp);
/* The --idle-timeout option says to exit after a certain period of
inactivity. We start a timer here and reset it on every read event; see
refresh_idle_timer. */
@@ -1158,6 +1173,7 @@ static void read_stdin_handler(nsock_pool nsp, nsock_event evt, void *data)
ncat_assert(type == NSE_TYPE_READ);
if (status == NSE_STATUS_EOF) {
shutdown(nsock_iod_get_sd(cs.sock_nsi), SHUT_WR);
/* In --send-only mode or non-TCP mode, exit after EOF on stdin. */
@@ -1212,7 +1228,8 @@ static void read_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
nsock_loop_quit(nsp);
return;
} else if (status == NSE_STATUS_ERROR) {
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
if (!o.zerobyte||o.verbose)
loguser("%s.\n", socket_strerror(nse_errorcode(evt)));
exit(1);
} else if (status == NSE_STATUS_TIMEOUT) {
loguser("%s.\n", socket_strerror(ETIMEDOUT));
@@ -1259,6 +1276,11 @@ static void write_socket_handler(nsock_pool nsp, nsock_event evt, void *data)
ncat_assert(status == NSE_STATUS_SUCCESS);
}
if (o.zerobyte){
ncat_assert(o.proto == IPPROTO_UDP);
nsock_read(nsp, cs.sock_nsi, read_socket_handler, -1, NULL);
return;
}
/* The write to the socket was successful. Allow reading more from stdin
now. */
nsock_readbytes(nsp, cs.stdin_nsi, read_stdin_handler, -1, NULL, 0);
@@ -1276,6 +1298,13 @@ static void idle_timer_handler(nsock_pool nsp, nsock_event evt, void *data)
ncat_assert(status == NSE_STATUS_SUCCESS);
if (o.zerobyte&&o.proto==IPPROTO_UDP){
if (o.verbose)
loguser("UDP packet sent successfully\n");
nsock_loop_quit(nsp);
return;
}
loguser("Idle timeout expired (%d ms).\n", o.idletimeout);
exit(1);

View File

@@ -200,6 +200,7 @@ void options_init(void)
o.execmode = EXEC_PLAIN;
o.proxy_auth = NULL;
o.proxytype = NULL;
o.zerobyte = 0;
#ifdef HAVE_OPENSSL
o.ssl = 0;

View File

@@ -205,6 +205,7 @@ struct options {
int sslverify;
char *ssltrustfile;
char *sslciphers;
int zerobyte;
};
extern struct options o;

View File

@@ -334,7 +334,7 @@ int main(int argc, char *argv[])
while (1) {
/* handle command line arguments */
int option_index;
int c = getopt_long(argc, argv, "46UCc:e:g:G:i:km:hp:d:lo:x:ts:uvw:n",
int c = getopt_long(argc, argv, "46UCc:e:g:G:i:km:hp:d:lo:x:ts:uvw:n:z",
long_options, &option_index);
/* That's the end of the options. */
@@ -458,6 +458,9 @@ int main(int argc, char *argv[])
case 't':
o.telnet = 1;
break;
case 'z':
o.zerobyte = 1;
break;
case 0:
if (strcmp(long_options[option_index].name, "version") == 0) {
print_banner();
@@ -606,6 +609,7 @@ int main(int argc, char *argv[])
" --sctp Use SCTP instead of default TCP\n"
" -v, --verbose Set verbosity level (can be used several times)\n"
" -w, --wait <time> Connect timeout\n"
" -z Zero-I/O mode, report connection status only\n"
" --append-output Append rather than clobber specified output files\n"
" --send-only Only send data, ignoring received; quit on EOF\n"
" --recv-only Only receive data, never send anything\n"
@@ -723,6 +727,16 @@ int main(int argc, char *argv[])
}
}
if (o.zerobyte) {
if (o.listen)
bye("Services designed for LISTENING can't be used with -z");
if (o.telnet)
bye("Invalid option combination: -z and -t.");
if (o.execmode||o.cmdexec)
bye("Command execution can't be done along with option -z.");
if (!o.idletimeout && o.proto == IPPROTO_UDP)
o.idletimeout = 2 * 1000;
}
/* Default port */
if (o.listen && o.proxytype && !o.portno && srcport == -1)
o.portno = DEFAULT_PROXY_PORT;