From df83c1d8517eda5ac508990bfbe509611eb4e73e Mon Sep 17 00:00:00 2001 From: Gordon Tetlow Date: Tue, 12 Feb 2019 12:53:37 -0800 Subject: [PATCH] Add FTP STARTTLS support. Default port logic. When using STARTTLS, use a default port other than 443 that is dependent on the protocol being tested. This can be overridden using the normal host:port syntax. --- connect.c | 29 +++++++++++++++++++++++++++++ sslscan.c | 12 +++++++++--- sslscan_priv.h | 7 ++++++- 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/connect.c b/connect.c index 9a7b48e..d5e3275 100644 --- a/connect.c +++ b/connect.c @@ -48,6 +48,7 @@ extern bool proxydns; extern enum proxy_enum proxytype; extern struct sslhost proxy; +static void ftpconnect(int); static void mysqlconnect(int); static void smtpconnect(int); static int socksconnect(struct sslhost *); @@ -68,6 +69,9 @@ hostconnect(struct sslhost *h) } switch (tlstype) { + case TLS_FTP: + ftpconnect(fd); + break; case TLS_MYSQL: mysqlconnect(fd); break; @@ -82,6 +86,31 @@ hostconnect(struct sslhost *h) return(fd); } +static void +ftpconnect(int fd) +{ + char buf[BUFSIZ]; + int ret; + + memset(buf, 0, BUFSIZ); + ret = recv(fd, buf, BUFSIZ - 1, 0); + if (ret == -1) + err(EX_PROTOCOL, "FTP STARTTLS failure"); + else if (ret < 3 || strncmp(buf, "220", 3) != 0) + err(EX_PROTOCOL, "FTP STARTTLS failure"); + + ret = send(fd, "AUTH TLS\r\n", 10, 0); + if (ret == -1 || ret != 10) + err(EX_PROTOCOL, "FTP STARTTLS failure"); + + memset(buf, 0, BUFSIZ); + ret = recv(fd, buf, BUFSIZ - 1, 0); + if (ret == -1) + err(EX_PROTOCOL, "FTP STARTTLS failure"); + else if (ret < 3 || sscanf(buf, "234") != 0) + err(EX_PROTOCOL, "FTP server doesn't appear to support STARTTLS"); +} + static void mysqlconnect(int fd) { diff --git a/sslscan.c b/sslscan.c index c0f1b73..16df61d 100644 --- a/sslscan.c +++ b/sslscan.c @@ -262,7 +262,7 @@ usage(void) { fprintf(stderr, "Usage: sslscan [options] [host[:port] ...]\n\n"); fprintf(stderr, " -c, --cipher Output per-protocol OpenSSL-compatible cipher string.\n"); - fprintf(stderr, " -s, --starttls STARTTLS protocol supported: mysql smtp\n"); + fprintf(stderr, " -s, --starttls STARTTLS protocol supported: ftp mysql smtp\n"); fprintf(stderr, " -x, --proxy Use a proxy to connect to the server. Valid formats:\n"); fprintf(stderr, " socks5://localhost:1080/ -- Uses SOCKS5 proxy.\n"); fprintf(stderr, " socks5h://localhost:1080/ -- Uses SOCKS5 proxy with DNS tunnelling.\n"); @@ -299,7 +299,7 @@ main(int argc, char *argv[]) { int ch, i, status; int sslflag = SSLSCAN_NONE, nosslflag = SSLSCAN_NONE; - char *host, *port, *chp, *sarg = NULL, *xarg = NULL; + char *defport, *host, *port, *chp, *sarg = NULL, *xarg = NULL; struct addrinfo hints; struct option opts[] = { @@ -360,10 +360,16 @@ main(int argc, char *argv[]) if (sarg) { if (strncmp(sarg, "smtp", 4) == 0) { tlstype = TLS_SMTP; + defport = "smtp"; } else if (strncmp(sarg, "mysql", 5) == 0) { tlstype = TLS_MYSQL; + defport = "mysql"; + } else if (strncmp(sarg, "ftp", 3) == 0) { + tlstype = TLS_FTP; + defport = "ftp"; } else if (strncmp(sarg, "none", 4) == 0) { tlstype = TLS_NONE; + defport = "https"; } else { fprintf(stderr, "Unrecognized STARTTLS option: %s\n", sarg); usage(); @@ -434,7 +440,7 @@ main(int argc, char *argv[]) status = 0; for (i = 0; i < argc; i++) { /* XXX: There is probably a better way to detect a raw IPv6 address. */ - port = "https"; + port = defport; /* Check for a raw IPv6 address enclosed in brackets [::1]. */ if (argv[i][0] == '[') { /* That said, we don't actually want the brackets. */ diff --git a/sslscan_priv.h b/sslscan_priv.h index 5032c99..b8483b6 100644 --- a/sslscan_priv.h +++ b/sslscan_priv.h @@ -34,7 +34,12 @@ struct sslhost { }; enum proxy_enum { PROXY_NULL, PROXY_SOCKS5 }; -enum starttls_enum { TLS_NONE, TLS_MYSQL, TLS_SMTP }; +enum starttls_enum { + TLS_NONE, + TLS_FTP, + TLS_MYSQL, + TLS_SMTP + }; int hostconnect(struct sslhost *);