diff --git a/hydra-rdp.c b/hydra-rdp.c index cfa2e12..69feee5 100644 --- a/hydra-rdp.c +++ b/hydra-rdp.c @@ -1,37 +1,10 @@ /* - david: this module is heavily based on rdesktop v 1.7.0 - - rdesktop: A Remote Desktop Protocol client. - Protocol services - RDP layer - Copyright (C) Matthew Chapman 1999-2008 - Copyright 2003-2011 Peter Astrand for Cendio AB - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -note: - -this module was tested on w2k, xp, w2k3, w2k8 - -in terminal services configuration, in rdp-tcp properties -in Logon Settings tab, if 'Always prompt for password' is checked, -the password can't be passed interactively so there is no way -to test the credential (unless manually). - -it's advised to lower the number of parallel tasks as RDP server -can't handle multiple connections at the same time. -It's particularly true on windows XP - + This module is using freerdp2 lib + + Tested on: + - Windows 7 pro SP1 + - Windows 10 pro build 1809 + - Windows Server 2016 build 1607 */ #include "hydra-mod.h" @@ -44,18 +17,20 @@ void dummy_rdp() { #else #include -freerdp * instance; +freerdp * instance = 0; BOOL rdp_connect(char *server, int32_t port, char *domain, char *login, char *password) { + int32_t err = 0; + instance->settings->Username = login; instance->settings->Password = password; - int32_t ret = 0; instance->settings->IgnoreCertificate = TRUE; instance->settings->AuthenticationOnly = TRUE; instance->settings->ServerHostname = server; instance->settings->ServerPort = port; instance->settings->Domain = domain; - ret = freerdp_connect(instance); - return ret==1? True : False; + freerdp_connect(instance); + err = freerdp_get_last_error(instance->context); + return err; } /* Client program */ @@ -64,8 +39,8 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, char *login, *pass; char server[64]; char domain[256]; - - BOOL login_result = False; + int32_t login_result = 0; + memset(domain, 0, sizeof(domain)); if (strlen(login = hydra_get_next_login()) == 0) @@ -81,25 +56,33 @@ int32_t start_rdp(char *ip, int32_t port, unsigned char options, char *miscptr, } login_result = rdp_connect(server, port, domain, login, pass); - - int x = 0; - x = freerdp_get_last_error(instance->context); - int err = freerdp_get_last_error(instance->context); - if ( err != 0 && err != 0x00020014) { //0x00020014 == logon failed - return 3; + switch(login_result){ + case 0: + // login success + hydra_report_found_host(port, ip, "rdp", fp); + hydra_completed_pair_found(); + break; + case 0x00020009: + case 0x00020014: + case 0x00020015: + // login failure + hydra_completed_pair(); + break; + case 0x00020006: + case 0x00020008: + case 0x0002000c: + case 0x0002000d: + // cannot establish rdp connection, either the port is not opened or it's not rdp + return 3; + default: + if (verbose) { + hydra_report(stderr, "[ERROR] freerdp: %s (0x%.8x)\n", freerdp_get_last_error_string(login_result), login_result); + } + return login_result; } - - if (login_result == True) { - hydra_report_found_host(port, ip, "rdp", fp); - hydra_completed_pair_found(); - } else { - hydra_completed_pair(); - } - if (memcmp(hydra_get_next_pair(), &HYDRA_EXIT, sizeof(HYDRA_EXIT)) == 0) return 2; return 1; - } void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FILE * fp, int32_t port, char *hostname) { @@ -120,14 +103,15 @@ void service_rdp(char *ip, int32_t sp, unsigned char options, char *miscptr, FIL break; case 2: /* clean exit */ freerdp_disconnect(instance); + freerdp_free(instance); hydra_child_exit(0); return; case 3: /* connection error case */ - hydra_report(stderr, "[ERROR] freerdp: %s\n", freerdp_get_last_error_string(freerdp_get_last_error(instance->context))); + hydra_report(stderr, "[ERROR] freerdp: %s\n", "The connection failed to establish."); + freerdp_free(instance); hydra_child_exit(1); return; default: - hydra_report(stderr, "[ERROR] Caught unknown return code, exiting!\n"); hydra_child_exit(2); } run = next_run; @@ -151,11 +135,14 @@ int32_t service_rdp_init(char *ip, int32_t sp, unsigned char options, char *misc // Init freerdp instance instance = freerdp_new(); - freerdp_context_new(instance); + if (instance == NULL || freerdp_context_new(instance) == FALSE) { + hydra_report(stderr, "[ERROR] freerdp init failed\n"); + return -1; + } return 0; } void usage_rdp(const char* service) { printf("Module rdp is optionally taking the windows domain name.\n" "For example:\nhydra rdp://192.168.0.1/firstdomainname -l john -p doe\n\n"); } -#endif \ No newline at end of file +#endif