Skip to content

Commit

Permalink
add StartTLS RDP support
Browse files Browse the repository at this point in the history
  • Loading branch information
tls-scan committed Dec 30, 2019
1 parent 2249310 commit 13ff0a1
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 20 deletions.
16 changes: 13 additions & 3 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,33 @@ tls-scan -- History of changes.
Bug numbers referenced in this log correspond to bug numbers at our issue tracker,
available at https://github.com/prbinu/tls-scan/issues

Version 1.3.0 (released 2019-12-28)
Version 1.4.0 (2019-12-30)
-----------------------------------
* Tag: https://github.com/prbinu/tls-scan/releases/tag/1.4.0

* Add StartTLS RDP protocol support

* Bug fix - starttls error stats counter

* Add version info to tls-scan

Version 1.3.0 (2019-12-28)
-----------------------------------
* Tag: https://github.com/prbinu/tls-scan/releases/tag/1.3.0

* Add StartTLS protocol support: IMAP, POP3, FTPS, SIEVE, NNTP, XMPP, LDAP, POSTGRES

* New test/ directory with scan output for reference

Version 1.2.0 (released 2019-12-07)
Version 1.2.0 (2019-12-07)
-----------------------------------
* Tag: https://github.com/prbinu/tls-scan/releases/tag/1.2.0

* Extend async/non-blocking support to TLS 1.3 version/cipher enum scans

* TLS 1.3 scan support for STARTTLS protocols

Version 1.0.1 (released 2019-12-01)
Version 1.0.1 (2019-12-01)
-----------------------------------
* Tag: https://github.com/prbinu/tls-scan/releases/tag/1.0.1

Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ $(info PREFIX (install) path: ${PREFIX})
src = $(wildcard *.c)
obj = $(src:.c=.o)

# tls-scan version
TS_VERSION = $(shell grep -m 1 Version ./CHANGELOG | awk '{print $$2}')
CC = gcc
CFLAGS= -I./include -I ${TS_DEPDIR}/include -I ${TS_DEPDIR}/include -Wall -Wundef -Wshadow -Wunreachable-code -Wswitch-default -Wcast-align -pedantic -g -std=c99 -Wl,-rpath,${TS_DEPDIR}/lib -D_GNU_SOURCE
CFLAGS = -I./include -I ${TS_DEPDIR}/include -I ${TS_DEPDIR}/include -Wall -Wundef -Wshadow -Wunreachable-code -Wswitch-default -Wcast-align -pedantic -g -std=c99 -Wl,-rpath,${TS_DEPDIR}/lib -D_GNU_SOURCE -DTS_VERSION=\"${TS_VERSION}\" -DTS_BUILD_DATE=\"$(shell date '+%Y-%m-%d')\" -DTS_OS=\"$(shell uname -s)\"

LDFLAGS = -L ${TS_DEPDIR}/lib -lssl -L ${TS_DEPDIR}/lib -lcrypto -L ${TS_DEPDIR}/lib -levent -L ${TS_DEPDIR}/lib -levent_openssl -L ${TS_DEPDIR}/lib -lgnutls -L ${TS_DEPDIR}/lib -lhogweed -L ${TS_DEPDIR}/lib -lnettle -ldl -lpthread $(libdep_$(shell uname -s))

Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ A program to scan TLS based servers and collect X.509 certificates, ciphers and
## Features

* **New: Support for TLSv1.3**
* **TLS and StartTLS protocol support: SMTP, IMAP, POP3, FTPS, SIEVE, NNTP, XMPP, LDAP, POSTGRES, MYSQL**
* **TLS and StartTLS protocol support: SMTP, IMAP, POP3, FTPS, SIEVE, NNTP, XMPP, LDAP, RDP, POSTGRES, MYSQL**
* Blazing fast - Can operate at scale with the ability to concurrently scan large number of servers (say scan IoT devices at scale)
* Detect SSLv2, SSLv3, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3 versions and ciphers
* Cipher and TLS version enumeration
* Extract X.509 certificate fields from the target server and print it in JSON format
* Certificate and host name verification checks
* Cipher and TLS version enumeration
* TLS compression checks
* Session reuse tests
* Certificate revocation checks with stapled OCSP response
* Blazing fast - Can operate at scale with the ability to concurrently scan large number of servers (say scan IoT devices at scale)
* Script friendly output - Can be combined with other tools to analyze the scan results

This tool is primarily for collecting data. The scan output can be easily combined with related tools to identify TLS misconfigurations.
This tool is primarily for collecting TLS cipher and X.509 certificate data. The scan output can be easily combined with related tools to identify TLS misconfigurations.

## Installation

Expand Down Expand Up @@ -211,12 +211,13 @@ jq-linux64 -r 'if (.tlsVersions[] | contains("SSL")) == true then [.host, .ip, .
|----------------|-------------|
-H --help | Print a usage message briefly summarizing these command-line options and the bug-reporting address, then exit.
-c --connect=\<arg\> | `target[:port]` to scan. target = {hostname, IPv4, [IPv6] }. IPv6 example: [::1]:443 (default port 443).
--starttls=\<protocol\> | Supported protocols: `smtp`, `imap`, `pop3`, `ftps`, `sieve`, `nntp`, `xmpp`, `ldap`, `postgres`, `mysql`, `tls` (default)
--starttls=\<protocol\> | Supported protocols: `smtp`, `imap`, `pop3`, `ftp`, `sieve`, `nntp`, `xmpp`, `ldap`, `rdp`, `postgres`, `mysql`, `tls` (default)
-c --cacert=\<file\> | Root CA file for certificate validation. By default the program attempts to load `ca-bundle.crt` file from current directory.
-C --ciphers=\<arg\> | Ciphers to use; try `openssl ciphers` to see all ciphers. Note that this option will be overwritten by `--ssl2`, `--ssl3`, `--tls1`, `--tls1_1`, `--tls1_2` options, if provided. Example: `"ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384"`
-e --cipher-enum | Enumerate supported ciphers. Currently use `--tls-old` ciphers. Try `--meta-info` to find predefined cipher suite options.
--show-unsupported-ciphers | Include unsupported ciphers in the cipher list to JSON output.
-V --version-enum | Enumerate supported TLS versions.
-v --version | Print tls-scan version and build information.
-r --session-reuse | Enable ssl session reuse.
-u --session-print | Print SSL session in PEM format to stderr. This is currently not included in the JSON output, but print seperately. This flag woould be useful if you wanted to pass SSL session to `--session-file` to test session reuse.
-T --session-file=\<file\> | File that contains SSL session in PEM format.
Expand Down
17 changes: 10 additions & 7 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1279,7 +1279,7 @@ const char *ts_supported_protocol(uint32_t port)
void print_usage()
{
printf("%s\n", "Usage: tls-scan [OPTION]...");
printf("Built with OpenSSL-%lx\n", OPENSSL_VERSION_NUMBER);
printf("Version: %s\n", TS_VERSION);
printf("\n%s\n","With no options, program accepts hostnames from standard input, scans TLS");
printf("%s\n","on port 443, and print results to standard output");
printf("\n%s\n", "Options:");
Expand All @@ -1288,8 +1288,8 @@ void print_usage()
// deprecated, use --connect instead
//printf(" %s\n", "-h --host=<hostname> Host to scan");
//printf(" %s\n", "-p --port=<port> TCP port (default 443)");
printf(" %s\n", " --starttls=<proto> Supported protocols: smtp, imap, pop3, ftps, sieve,");
printf(" %s\n", " nntp, xmpp, ldap, postgres, mysql, tls (default)");
printf(" %s\n", " --starttls=<proto> Supported protocols: smtp, imap, pop3, ftp, sieve,");
printf(" %s\n", " nntp, xmpp, ldap, rdp, postgres, mysql, tls (default)");
printf(" %s\n", " --cacert=<file> Root CA file/bundle for certificate validation");
printf(" %s\n", "-C --ciphers=<arg> Ciphers to use; try 'openssl ciphers' to see all.");
#if OPENSSL_VERSION_NUMBER > 0x10100000L
Expand Down Expand Up @@ -1319,7 +1319,7 @@ void print_usage()
printf(" %s\n", "-f --infile=<file> Input file with domains or IPs (default stdin)");
printf(" %s\n", "-o --outfile=<file> Output file (default stdout)");
printf(" %s\n", "-n --pretty Pretty print; add newline (\\n) between record fields");
//printf(" %s\n", "-v --verbose verbose");
printf(" %s\n", "-v --version Print version and build information");
printf(" %s\n", "-H --help help");
printf(" %s\n", "-N --nameserver=<ip> DNS resolver IPs, (eg. -N <ip1> -N <ip2> -N <ip3>..)");
printf(" %s\n", " --ssl2 SSLv2 ciphers");
Expand Down Expand Up @@ -1398,7 +1398,7 @@ int main(int argc, char **argv)
{"no-parallel-enum", no_argument, 0, 'X'},
{"concurrency", required_argument, 0, 'b'},
{"json", no_argument, 0, 'j'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'v'},
{"help", no_argument, 0, 'H'},
{"infile", required_argument, 0, 'f'},
{"timeout", required_argument, 0, 't'},
Expand Down Expand Up @@ -1445,7 +1445,7 @@ int main(int argc, char **argv)
int tsec = 0;
while ((opt = getopt_long(argc,
argv,
"P:h:p:c:C:eUruT:as:b:v:t:S:o:N:123456Q789VXnOjMH",
"P:h:p:c:C:eUruT:as:b:vt:S:o:N:123456Q789VXnOjMH",
long_options, &long_index)) != -1) {
valid = 1;
switch (opt) {
Expand Down Expand Up @@ -1579,7 +1579,10 @@ int main(int argc, char **argv)
strcpy(op.ciphers, old_ciphers);
break;
case 'v':
op.verbose++;
printf("tls-scan %s %s %s\n", TS_VERSION, TS_OS, TS_BUILD_DATE);
printf("Built with OpenSSL-%lx GnuTLS-%x\n",
OPENSSL_VERSION_NUMBER, GNUTLS_VERSION_NUMBER);
exit(EXIT_SUCCESS);
break;
case 'M':
print_meta();
Expand Down
5 changes: 4 additions & 1 deletion man/tls-scan
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ For more information, please visit:
Destination TCP port.

-P --starttls=<protocol>
Supported protocols: smtp, imap, pop3, ftps, sieve, nntp, xmpp, ldap, postgres, mysql, tls (default)
Supported protocols: smtp, imap, pop3, ftp, sieve, nntp, xmpp, ldap, rdp, postgres, mysql, tls (default)

-c --cacert=<file>
Root CA file for certificate validation. By default the program attempts to load `ca-bundle.crt` file from current directory.
Expand All @@ -45,6 +45,9 @@ For more information, please visit:
-V --version-enum
Enumerate supported TLS versions.

-v --version
Print tls-scan version and build information.

-r --session-reuse
Enable ssl session reuse.

Expand Down
59 changes: 56 additions & 3 deletions proto-adapters.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ static void on_nntp_read(client_t *cli, unsigned char *read_buf, size_t nread);
// ldap
static void on_ldap_connect(client_t *cli);
static void on_ldap_read(client_t *cli, unsigned char *read_buf, size_t nread);
// rdp
static void on_rdp_connect(client_t *cli);
static void on_rdp_read(client_t *cli, unsigned char *read_buf, size_t nread);
// xmpp
static void on_xmpp_connect(client_t *cli);
static void on_xmpp_read(client_t *cli, unsigned char *read_buf, size_t nread);
Expand Down Expand Up @@ -88,11 +91,12 @@ static const adapter_table_t adapters[] = {
{ "smtp", on_create, on_init, NULL, on_smtp_read, NULL, on_reset, on_destroy },
{ "imap", on_create, on_init, NULL, on_imap_read, NULL, on_reset, on_destroy },
{ "pop3", on_create, on_init, NULL, on_pop3_read, NULL, on_reset, on_destroy },
{ "ftps", on_create, on_init, NULL, on_ftps_read, NULL, on_reset, on_destroy },
{ "ftp", on_create, on_init, NULL, on_ftps_read, NULL, on_reset, on_destroy },
{ "sieve", on_create, on_init, NULL, on_sieve_read, NULL, on_reset, on_destroy },
{ "nntp", on_create, on_init, NULL, on_nntp_read, NULL, on_reset, on_destroy },
{ "xmpp", on_create, on_init, on_xmpp_connect, on_xmpp_read, NULL, on_reset, on_destroy },
{ "ldap", NULL, NULL, on_ldap_connect, on_ldap_read, NULL, NULL, NULL },
{ "rdp", NULL, NULL, on_rdp_connect, on_rdp_read, NULL, NULL, NULL },
{ "postgres", NULL, NULL, on_postgres_connect, on_postgres_read, NULL, NULL, NULL },
{ "mysql", NULL, NULL, NULL, on_mysql_read, NULL, NULL, NULL }
};
Expand Down Expand Up @@ -227,6 +231,7 @@ void on_smtp_read(client_t * cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "220", 3) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n", cli->host, cli->ip,
"ERROR: NON 220 response");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand All @@ -251,7 +256,7 @@ void on_smtp_read(client_t * cli, unsigned char *rbuffer, size_t rbuf_len)

} while ((line = strtok_r(NULL, "\r\n", &saveptr)) != NULL);

if (found == false) {
if (!found) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
Expand Down Expand Up @@ -343,6 +348,7 @@ void on_mysql_read(client_t * cli, unsigned char *rbuffer, size_t rbuf_len)
} else {
fprintf(stderr, "host: %s; ip: %s; error: SSL NOT Supported\n",
cli->ip, cli->host);
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -392,7 +398,7 @@ void on_imap_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)

} while ((line = strtok_r(NULL, "\r\n", &saveptr)) != NULL);

if (found == false) {
if (!found) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
Expand Down Expand Up @@ -501,6 +507,7 @@ void on_ftps_read(client_t * cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "220", 3) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n", cli->host, cli->ip,
"ERROR: NON 220 response");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -532,6 +539,7 @@ void on_ftps_read(client_t * cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "234", 3) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -588,6 +596,7 @@ void on_sieve_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "OK ", 3) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -628,6 +637,7 @@ void on_nntp_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "200 ", 4) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n", cli->host, cli->ip,
"ERROR: NON 200 response");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand All @@ -641,6 +651,7 @@ void on_nntp_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "382 ", 3) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -706,6 +717,7 @@ void on_xmpp_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
if (strncmp((char*)rbuf, "<proceed", 8) != 0) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

Expand Down Expand Up @@ -748,6 +760,47 @@ void on_ldap_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
}
}

void on_rdp_connect(client_t *cli)
{
uint8_t rdp_str[] = {
0x03, 0x00, 0x00, 0x13, 0x0E, 0xE0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x08, 0x00, 0x03, 0x00, 0x00, 0x00
};

ts_scan_tcp_write(cli, rdp_str, sizeof(rdp_str));
}

void on_rdp_read(client_t *cli, unsigned char *rbuffer, size_t rbuf_len)
{
//printf("%.*s+ resp_index: %d\n", (int)rbuf_len, rbuffer);
if (rbuf_len < 2) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

if ((rbuffer[0] != 0x03) || (rbuffer[1] != 0x00)) {
fprintf(stderr, "host: %s; ip: %s; error: %s\n",
cli->host, cli->ip, "STARTTLS 2 not supported");
ts_get_stats_obj()->starttls_no_support_count++;
goto error;
}

if (cli->scan_engine == SE_GNUTLS) {
ts_scan_do_tls1_3_handshake(cli);
} else {
ts_scan_do_tls_handshake(cli);
}

return;

error:
ts_scan_error(cli);
return;
}

void on_postgres_connect(client_t *cli)
{
uint8_t postgres_str[] = { 0x00, 0x00, 0x00, 0x08, 0x04, 0xD2, 0x16, 0x2F };
Expand Down

0 comments on commit 13ff0a1

Please sign in to comment.