--- hydra-4.6-src/hydra-smbnt.c 2004-05-10 14:27:07.000000000 -0500 +++ hydra-jmk/hydra-smbnt.c 2005-03-29 15:57:53.000000000 -0600 @@ -8,13 +8,26 @@ #else #include #include -#include /* SMB NTLM Password/HASH Checking Hydra Module - Copyright (C) m0j0.j0j0 - m0j0.j0j0 / m0j0@foofus.net - 09/30/2003 + Version: $Id: hydra-smbnt.c 67 2005-03-08 20:14:40Z jmk $ + + ------------------------------------------------------------------------ + Copyright (C) 2005 Joseph N. Mondloch + JoMo-Kun / jmk@foofus.net + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2, + as published by the Free Software Foundation + + 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. + + http://www.gnu.org/licenses/gpl.txt + ------------------------------------------------------------------------ Based on code from: SMB Auditing Tool [Copyright (C) Patrik Karlsson 2001] @@ -27,7 +40,7 @@ LanMan passwords. The "-m 'METHOD'" option is required for this module. The - following are valid methods: L, LH, D, DH, B and BH + following are valid methods: L, LH, D, DH, B, BH and M (in quotes). L == Check local account. @@ -39,6 +52,7 @@ locally on the host being tested, that host then queries its domain controller. H == Use a NTLM hash rather than a password. + M == Use the Machine's NetBIOS name as the password. Be careful of mass domain account lockout with this. For example, assume you are checking several accounts against @@ -49,20 +63,28 @@ lockouts. Of course, it'd look like the workstations, not you, were doing it. ;) - **FYI, this code does not appear to currently work against - Windows XP hosts which are NOT a member of a domain. Will - look into this... + **FYI, this code is unable to test accounts on default XP + hosts which are not part of a domain and do not have normal + file sharing enabled. Default XP does not allow shares and + returns STATUS_LOGON_FAILED for both valid and invalid + credentials. XP with simple sharing enabled returns SUCCESS + for both valid and invalid credentials. If anyone knows a + way to test in these configurations... - See http://www.foofus.net/m0j0/passhash.html for further + See http://www.foofus.net/jmk/passhash.html for further examples. Greets: Foofus, Phenfen & Fizzgig */ +#define WIN2000_NATIVEMODE 1 +#define WIN_NETBIOSMODE 2 + extern char *HYDRA_EXIT; char challenge[8]; unsigned char workgroup[16]; -int hashFlag, accntFlag; +unsigned char machine_name[16]; +int hashFlag, accntFlag, protoFlag; static unsigned char Get7Bits(unsigned char *input, int startBit) @@ -122,13 +144,13 @@ unsigned char p21[21]; unsigned char ntlm_response[24]; int i = 0, j = 0; - int mdlen = strlen((char *) pass) * 2 * 8; + int mdlen; unsigned char *p; char HexChar; int HexValue; /* Use NTLM Hash instead of password */ - if (hashFlag) { + if (hashFlag == 1) { /* 1000:D42E35E1A1E4C22BD32E2170E4857C20:5E20780DD45857A68402938C7629D3B2::: */ p = pass; while ((*p != '\0') && (i < 2)) { @@ -170,12 +192,22 @@ hash[i] = (unsigned char) HexValue; } } else { + /* Password == Machine Name */ + if (hashFlag == 2) { + for (i = 0; i < 16; i++) { + if (machine_name[i] > 0x39) + machine_name[i] = machine_name[i] | 0x20; /* convert upper case to lower */ + pass = machine_name; + } + } + /* Initialize the Unicode version of the secret (== password). */ /* This implicitly supports 8-bit ISO8859/1 characters. */ bzero(unicodePassword, sizeof(unicodePassword)); for (i = 0; i < strlen((char *) pass); i++) unicodePassword[i * 2] = (unsigned char) pass[i]; + mdlen = strlen((char *) pass) * 2; /* length in bytes */ MD4_Init(&md4Context); MD4_Update(&md4Context, unicodePassword, mdlen); MD4_Final(hash, &md4Context); /* Tell MD4 we're done */ @@ -205,6 +237,10 @@ char *buf; unsigned char rbuf[400]; + /* if we are running in native mode (aka port 445) don't do netbios */ + if (protoFlag == WIN2000_NATIVEMODE) + return 0; + /* convert computer name to netbios name */ memset(nb_name, 0, 32); memset(nb_local, 0, 32); @@ -219,7 +255,7 @@ memcpy(buf + 39, nb_local, 32); memcpy(buf + 71, (char *) rqbuf + 5, 1); - hydra_send(s, buf, 72, 0); + hydra_send(s, buf, 76, 0); free(buf); memset(rbuf, 0, 400); @@ -269,10 +305,18 @@ }; unsigned char rbuf[400]; - int i = 0; + unsigned char sess_key[2]; + unsigned char userid[2] = {0xCD, 0xEF}; + int i = 0, j = 0; memset((char *) rbuf, 0, 400); + /* set session key */ + sess_key[1] = getpid() / 100; + sess_key[0] = getpid() - (100 * sess_key[1]); + memcpy(buf + 30, sess_key, 2); + memcpy(buf + 32, userid, 2); + hydra_send(s, (char *) buf, 168, 0); hydra_recv(s, (char *) rbuf, sizeof(rbuf)); @@ -281,12 +325,18 @@ /* find the primary domain/workgroup name */ memset(workgroup, 0, 16); + memset(machine_name, 0, 16); while ((rbuf[81 + i * 2] != 0) && (i < 16)) { workgroup[i] = rbuf[81 + i * 2]; i++; } + while ((rbuf[81 + (i + j + 1) * 2] != 0) && (j < 16)) { + machine_name[j] = rbuf[81 + (i + j + 1) * 2]; + j++; + } + return 2; } @@ -300,7 +350,7 @@ valid NTLM hash. Returns: TRUE on success else FALSE. */ -int +short SMBSessionSetup(int s, char *user, char *pass, char *miscptr) { unsigned char b[137] = { @@ -328,6 +378,7 @@ unsigned char *NTLMhash; unsigned char LMhash[24]; unsigned char rbuf[400]; + unsigned char sess_key[2]; int userlen; NTLMhash = (unsigned char *) malloc(24); @@ -349,6 +400,11 @@ memcpy(buf + 65, LMhash, 24); memcpy(buf + 89, NTLMhash, 24); + /* set session key */ + sess_key[1] = getpid() / 100; + sess_key[0] = getpid() - (100 * sess_key[1]); + memcpy(buf + 30, sess_key, 2); + userlen = strlen(user); memcpy(buf + 113, user, userlen); @@ -366,7 +422,9 @@ hydra_send(s, (char *) buf, 126 + userlen + strlen((char *) workgroup), 0); hydra_recv(s, (char *) rbuf, sizeof(rbuf)); - return rbuf[9]; + /* 41 - Action (Guest/Non-Guest Account) */ + /* 9 - NT Status (Error code) */ + return ((rbuf[41] << 8) | rbuf[9]); } int @@ -374,28 +432,44 @@ { char *empty = ""; char *login, *pass; - int SMBerr; + int SMBerr, SMBaction; + short SMBSessionRet; + char ipaddr_str[INET_ADDRSTRLEN]; if (strlen(login = hydra_get_next_login()) == 0) login = empty; if (strlen(pass = hydra_get_next_password()) == 0) pass = empty; - SMBerr = SMBSessionSetup(s, login, pass, miscptr); + inet_ntop(AF_INET, &ip, ipaddr_str, sizeof(ipaddr_str)); + SMBSessionRet = SMBSessionSetup(s, login, pass, miscptr); + SMBerr = (short) SMBSessionRet & 0x00FF; + SMBaction = ((short) SMBSessionRet & 0xFF00) >> 8; if (0x00 == SMBerr) { /* success */ - hydra_report_found_host(port, ip, "smb", fp); + if (0x01 == SMBaction) { /* invalid account - anonymous connection */ + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: Invalid Account (Anonymous Mapping Created)\n", port, ipaddr_str, login); + hydra_completed_pair(); + } else { /* valid account */ + hydra_report_found_host(port, ip, "smbnt", fp); hydra_completed_pair_found(); + } } else if (0x24 == SMBerr) { /* change password on next login [success] */ - hydra_report_found_host(port, ip, "smb (must change password)", fp); + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_CHANGE_PASSWORD\n", port, ipaddr_str, login); hydra_completed_pair_found(); + } else if (0x6D == SMBerr) { /* STATUS_LOGON_FAILURE */ + hydra_completed_pair(); } else if (0x72 == SMBerr) { /* account disabled */ - hydra_report_found_host(port, ip, "smb (account disabled)", fp); + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_DISABLED\n", port, ipaddr_str, login); hydra_completed_pair(); } else if (0x34 == SMBerr) { /* account locked out */ - fprintf(stderr, "[%d][smb] Account: %s is locked out\n", port, login); + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: ACCOUNT_LOCKED\n", port, ipaddr_str, login); + hydra_completed_pair(); + } else if (0x8D == SMBerr) { /* ummm... broken client-domain membership */ + fprintf(stderr, "[%d][smb] Host: %s Account: %s Error: NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE\n", port, ipaddr_str, login); hydra_completed_pair(); } else { /* failed */ + fprintf(stderr, "[%d][smb] Host: %s Account: %s Unknown Error: %2.2X\n", port, ipaddr_str, login, SMBerr); hydra_completed_pair(); } @@ -409,7 +483,6 @@ service_smbnt(unsigned long int ip, int sp, unsigned char options, char *miscptr, FILE * fp, int port) { int run = 1, next_run, sock = -1; - int myport = PORT_SMB, mysslport = PORT_SMB_SSL; if ((strcmp(miscptr, "L") == 0)) { accntFlag = 0; @@ -429,6 +502,9 @@ } else if ((strcmp(miscptr, "BH") == 0)) { accntFlag = 2; hashFlag = 1; + } else if ((strcmp(miscptr, "M") == 0)) { + accntFlag = 0; + hashFlag = 2; } else { printf("SMBNT Module requires -m METHOD\n"); hydra_child_exit(0); @@ -443,16 +519,26 @@ if (sock >= 0) sock = hydra_disconnect(sock); usleep(300000); - if ((options & OPTION_SSL) == 0) { - if (port != 0) - myport = port; - sock = hydra_connect_tcp(ip, myport); - port = myport; - } else { - if (port != 0) - mysslport = port; - sock = hydra_connect_ssl(ip, mysslport); - port = mysslport; + + if (port != 0) { + sock = hydra_connect_tcp(ip, port); + if (port == PORT_SMB) + protoFlag = WIN_NETBIOSMODE; + else + protoFlag = WIN2000_NATIVEMODE; + } + else { + sock = hydra_connect_tcp(ip, PORT_SMBNT); + if (sock > 0) { + port = PORT_SMBNT; + protoFlag = WIN2000_NATIVEMODE; + } + else { + fprintf(stderr, "Failed to establish WIN2000_NATIVE mode. Attempting WIN_NETBIOS mode.\n"); + port = PORT_SMB; + protoFlag = WIN_NETBIOSMODE; + sock = hydra_connect_tcp(ip, PORT_SMB); + } } if (sock < 0) { fprintf(stderr, "Error: Child with pid %d terminating, can not connect\n", (int) getpid()); --- hydra-4.6-src/hydra.h 2005-01-06 09:39:55.000000000 -0600 +++ hydra-jmk/hydra.h 2005-03-29 15:22:57.000000000 -0600 @@ -48,6 +48,8 @@ #define PORT_NNTP_SSL 563 #define PORT_SMB 139 #define PORT_SMB_SSL 139 +#define PORT_SMBNT 445 +#define PORT_SMBNT_SSL 445 #define PORT_IMAP 143 #define PORT_IMAP_SSL 993 #define PORT_LDAP 389 --- hydra-4.6-src/hydra.c 2005-02-01 08:51:21.000000000 -0600 +++ hydra-jmk/hydra.c 2005-03-29 15:34:13.000000000 -0600 @@ -670,7 +670,7 @@ {"rexec", PORT_REXEC, PORT_REXEC_SSL}, {"sapr3", PORT_SAPR3, PORT_SAPR3_SSL}, {"smb", PORT_SMB, PORT_SMB_SSL}, - {"smbnt", PORT_SMB, PORT_SMB_SSL}, + {"smbnt", PORT_SMBNT, PORT_SMBNT_SSL}, {"socks5", PORT_SOCKS5, PORT_SOCKS5_SSL}, {"ssh2", PORT_SSH, PORT_SSH_SSL}, {"telnet", PORT_TELNET, PORT_TELNET_SSL},