fixed crash in rtsp module

This commit is contained in:
van Hauser 2020-02-17 10:39:17 +01:00
parent 0b093e67c4
commit 5b6fc88428
14 changed files with 107 additions and 86 deletions

View file

@ -3,6 +3,7 @@ Changelog for hydra
Release 9.1-dev Release 9.1-dev
* new module: smb2 which also supports smb3 (uses libsmbclient-dev) (thanks to Karim Kanso for the module!) * new module: smb2 which also supports smb3 (uses libsmbclient-dev) (thanks to Karim Kanso for the module!)
* rtsp: fixed crash in MD5 auth
* svn: updated to support past and new API * svn: updated to support past and new API
* http module now supports F=/S= string matching conditions (thanks to poucz@github) * http module now supports F=/S= string matching conditions (thanks to poucz@github)
* changed mysql module not to use mysql db as a default. if the user has not access to this db auth fails ... * changed mysql module not to use mysql db as a default. if the user has not access to this db auth fails ...

View file

@ -170,7 +170,7 @@ int32_t start_http_proxy_urlenum(int32_t s, char *ip, int32_t port, unsigned cha
} else { } else {
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
if (hydra_strcasestr(buf, "Proxy-Authenticate: Digest") != NULL) { if (hydra_strcasestr(buf, "Proxy-Authenticate: Digest") != NULL) {
char *pbuffer; char *pbuffer, *result;
http_proxy_auth_mechanism = AUTH_DIGESTMD5; http_proxy_auth_mechanism = AUTH_DIGESTMD5;
pbuffer = hydra_strcasestr(buf, "Proxy-Authenticate: Digest "); pbuffer = hydra_strcasestr(buf, "Proxy-Authenticate: Digest ");
@ -178,8 +178,8 @@ int32_t start_http_proxy_urlenum(int32_t s, char *ip, int32_t port, unsigned cha
buffer[sizeof(buffer) - 1] = '\0'; buffer[sizeof(buffer) - 1] = '\0';
pbuffer = buffer2; pbuffer = buffer2;
sasl_digest_md5(pbuffer, login, pass, buffer, miscptr, "proxy", host, 0, header); result = sasl_digest_md5(pbuffer, login, pass, buffer, miscptr, "proxy", host, 0, header);
if (pbuffer == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)

View file

@ -179,7 +179,7 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option
} else { } else {
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
if (hydra_strcasestr(http_proxy_buf, "Proxy-Authenticate: Digest") != NULL) { if (hydra_strcasestr(http_proxy_buf, "Proxy-Authenticate: Digest") != NULL) {
char *pbuffer; char *pbuffer, *result;
http_proxy_auth_mechanism = AUTH_DIGESTMD5; http_proxy_auth_mechanism = AUTH_DIGESTMD5;
pbuffer = hydra_strcasestr(http_proxy_buf, "Proxy-Authenticate: Digest "); pbuffer = hydra_strcasestr(http_proxy_buf, "Proxy-Authenticate: Digest ");
@ -188,8 +188,8 @@ int32_t start_http_proxy(int32_t s, char *ip, int32_t port, unsigned char option
pbuffer = NULL; pbuffer = NULL;
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "proxy", host, 0, header); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "proxy", host, 0, header);
if (fooptr == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)

View file

@ -76,15 +76,15 @@ int32_t start_http(int32_t s, char *ip, int32_t port, unsigned char options, cha
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
case AUTH_DIGESTMD5: { case AUTH_DIGESTMD5: {
char *pbuffer; char *pbuffer, *result;
pbuffer = hydra_strcasestr(http_buf, "WWW-Authenticate: Digest "); pbuffer = hydra_strcasestr(http_buf, "WWW-Authenticate: Digest ");
strncpy(buffer, pbuffer + strlen("WWW-Authenticate: Digest "), buffer_size - 1); strncpy(buffer, pbuffer + strlen("WWW-Authenticate: Digest "), buffer_size - 1);
buffer[buffer_size - 1] = '\0'; buffer[buffer_size - 1] = '\0';
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, type, webtarget, webport, header);
if (fooptr == NULL) { if (result == NULL) {
free(buffer); free(buffer);
free(header); free(header);
return 3; return 3;

View file

@ -41,7 +41,7 @@ char *imap_read_server_capacity(int32_t sock) {
} }
int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = ""; char *empty = "", *result = NULL;
char *login, *pass, buffer[500], buffer2[500], *fooptr; char *login, *pass, buffer[500], buffer2[500], *fooptr;
if (strlen(login = hydra_get_next_login()) == 0) if (strlen(login = hydra_get_next_login()) == 0)
@ -104,7 +104,8 @@ int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
sasl_plain(buffer2, login, pass); result = sasl_plain(buffer2, login, pass);
if (result == NULL) return 3;
sprintf(buffer, "%.250s\r\n", buffer2); sprintf(buffer, "%.250s\r\n", buffer2);
break; break;
@ -161,15 +162,18 @@ int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, cha
switch (imap_auth_mechanism) { switch (imap_auth_mechanism) {
case AUTH_CRAMMD5: { case AUTH_CRAMMD5: {
sasl_cram_md5(buffer2, pass, buffer); result = sasl_cram_md5(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
case AUTH_CRAMSHA1: { case AUTH_CRAMSHA1: {
sasl_cram_sha1(buffer2, pass, buffer); result = sasl_cram_sha1(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
case AUTH_CRAMSHA256: { case AUTH_CRAMSHA256: {
sasl_cram_sha256(buffer2, pass, buffer); result = sasl_cram_sha256(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
} }
@ -202,8 +206,8 @@ int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, cha
hydra_report(stderr, "DEBUG S: %s\n", buffer); hydra_report(stderr, "DEBUG S: %s\n", buffer);
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "imap", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "imap", NULL, 0, NULL);
if (fooptr == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)
hydra_report(stderr, "DEBUG C: %s\n", buffer2); hydra_report(stderr, "DEBUG C: %s\n", buffer2);
@ -262,8 +266,8 @@ int32_t start_imap(int32_t s, char *ip, int32_t port, unsigned char options, cha
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
fooptr = buffer2; fooptr = buffer2;
sasl_scram_sha1(fooptr, pass, clientfirstmessagebare, serverfirstmessage); result = sasl_scram_sha1(fooptr, pass, clientfirstmessagebare, serverfirstmessage);
if (fooptr == NULL) { if (result == NULL) {
hydra_report(stderr, "[ERROR] Can't compute client response\n"); hydra_report(stderr, "[ERROR] Can't compute client response\n");
return 1; return 1;
} }

View file

@ -8,7 +8,7 @@ int32_t counter;
int32_t tls_required = 0; int32_t tls_required = 0;
int32_t start_ldap(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *hostname, char version, int32_t auth_method) { int32_t start_ldap(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp, char *hostname, char version, int32_t auth_method) {
char *empty = ""; char *empty = "", *result = NULL;
char *login = "", *pass, *fooptr = ""; char *login = "", *pass, *fooptr = "";
unsigned char buffer[512]; unsigned char buffer[512];
int32_t length = 0; int32_t length = 0;
@ -123,8 +123,8 @@ int32_t start_ldap(int32_t s, char *ip, int32_t port, unsigned char options, cha
ptr = strstr((char *)buf, "<"); ptr = strstr((char *)buf, "<");
fooptr = buf2; fooptr = buf2;
sasl_cram_md5(fooptr, pass, ptr); result = sasl_cram_md5(fooptr, pass, ptr);
if (fooptr == NULL) if (result == NULL)
return 1; return 1;
counter++; counter++;
if (strstr(miscptr, "^USER^") != NULL) { if (strstr(miscptr, "^USER^") != NULL) {
@ -180,8 +180,8 @@ int32_t start_ldap(int32_t s, char *ip, int32_t port, unsigned char options, cha
} }
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, ptr, miscptr, "ldap", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, ptr, miscptr, "ldap", NULL, 0, NULL);
if (fooptr == NULL) { if (result == NULL) {
free(buf); free(buf);
return 3; return 3;
} }

View file

@ -48,7 +48,7 @@ char *nntp_read_server_capacity(int32_t sock) {
} }
int32_t start_nntp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { int32_t start_nntp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = "\"\""; char *empty = "\"\"", *result = NULL;
char *login, *pass, buffer[500], buffer2[500], *fooptr; char *login, *pass, buffer[500], buffer2[500], *fooptr;
int32_t i = 1; int32_t i = 1;
@ -112,7 +112,8 @@ int32_t start_nntp(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
sasl_plain(buffer, login, pass); result = sasl_plain(buffer, login, pass);
if (result == NULL) return 3;
char tmp_buffer[sizeof(buffer)]; char tmp_buffer[sizeof(buffer)];
sprintf(tmp_buffer, "%.250s\r\n", buffer); sprintf(tmp_buffer, "%.250s\r\n", buffer);
@ -147,7 +148,8 @@ int32_t start_nntp(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
sasl_cram_md5(buffer2, pass, buffer); result = sasl_cram_md5(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
hydra_tobase64((unsigned char *)buffer, strlen(buffer), sizeof(buffer)); hydra_tobase64((unsigned char *)buffer, strlen(buffer), sizeof(buffer));
@ -178,8 +180,8 @@ int32_t start_nntp(int32_t s, char *ip, int32_t port, unsigned char options, cha
if (debug) if (debug)
hydra_report(stderr, "DEBUG S: %s\n", buffer); hydra_report(stderr, "DEBUG S: %s\n", buffer);
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "nntp", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "nntp", NULL, 0, NULL);
if (fooptr == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)

View file

@ -118,7 +118,7 @@ char *pop3_read_server_capacity(int32_t sock) {
} }
int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = "\"\""; char *empty = "\"\"", *result = NULL;
char *login, *pass, buffer[500], buffer2[500], *fooptr; char *login, *pass, buffer[500], buffer2[500], *fooptr;
if (strlen(login = hydra_get_next_login()) == 0) if (strlen(login = hydra_get_next_login()) == 0)
@ -202,7 +202,8 @@ int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
sasl_plain(buffer, login, pass); result = sasl_plain(buffer, login, pass);
if (result == NULL) return 3;
char tmp_buffer[sizeof(buffer)]; char tmp_buffer[sizeof(buffer)];
sprintf(tmp_buffer, "%.250s\r\n", buffer); sprintf(tmp_buffer, "%.250s\r\n", buffer);
@ -263,15 +264,18 @@ int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, cha
switch (p->pop3_auth_mechanism) { switch (p->pop3_auth_mechanism) {
case AUTH_CRAMMD5: { case AUTH_CRAMMD5: {
sasl_cram_md5(buffer2, pass, buffer); result = sasl_cram_md5(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
case AUTH_CRAMSHA1: { case AUTH_CRAMSHA1: {
sasl_cram_sha1(buffer2, pass, buffer); result = sasl_cram_sha1(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
case AUTH_CRAMSHA256: { case AUTH_CRAMSHA256: {
sasl_cram_sha256(buffer2, pass, buffer); result = sasl_cram_sha256(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
} break; } break;
} }
@ -304,8 +308,8 @@ int32_t start_pop3(int32_t s, char *ip, int32_t port, unsigned char options, cha
hydra_report(stderr, "[DEBUG] S: %s\n", buffer); hydra_report(stderr, "[DEBUG] S: %s\n", buffer);
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "pop", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "pop", NULL, 0, NULL);
if (fooptr == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)

View file

@ -116,22 +116,21 @@ int32_t start_rtsp(int32_t s, char *ip, int32_t port, unsigned char options, cha
} }
} else { } else {
if (use_Digest_Auth(lresp) == 1) { if (use_Digest_Auth(lresp) == 1) {
char *dbuf = NULL; char aux[500] = "", dbuf[500] = "", *result = NULL;
char aux[500] = "";
char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest "); char *pbuffer = hydra_strcasestr(lresp, "WWW-Authenticate: Digest ");
strncpy(aux, pbuffer + strlen("WWW-Authenticate: Digest "), sizeof(aux)); strncpy(aux, pbuffer + strlen("WWW-Authenticate: Digest "), sizeof(aux));
aux[sizeof(aux) - 1] = '\0'; aux[sizeof(aux) - 1] = '\0';
free(lresp); free(lresp);
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
sasl_digest_md5(dbuf, login, pass, aux, miscptr, "rtsp", hydra_address2string(ip), port, ""); result = sasl_digest_md5(dbuf, login, pass, aux, miscptr, "rtsp", hydra_address2string(ip), port, "");
#else #else
hydra_report(stderr, "[ERROR] Digest auth required but compiled " hydra_report(stderr, "[ERROR] Digest auth required but compiled "
"without OpenSSL/MD5 support\n"); "without OpenSSL/MD5 support\n");
return 3; return 3;
#endif #endif
if (dbuf == NULL) { if (result == NULL) {
hydra_report(stderr, "[ERROR] digest generation failed\n"); hydra_report(stderr, "[ERROR] digest generation failed\n");
return 3; return 3;
} }

View file

@ -48,7 +48,7 @@ int32_t get_sip_code(char *buf) {
} }
int32_t start_sip(int32_t s, char *ip, char *lip, int32_t port, int32_t lport, unsigned char options, char *miscptr, FILE *fp) { int32_t start_sip(int32_t s, char *ip, char *lip, int32_t port, int32_t lport, unsigned char options, char *miscptr, FILE *fp) {
char *login, *pass, *host, buffer[SIP_MAX_BUF]; char *login, *pass, *host, buffer[SIP_MAX_BUF], *result = NULL;
int32_t i; int32_t i;
char buf[SIP_MAX_BUF]; char buf[SIP_MAX_BUF];
@ -138,7 +138,8 @@ int32_t start_sip(int32_t s, char *ip, char *lip, int32_t port, int32_t lport, u
hydra_report(stderr, "[INFO] S: %s\n", buf); hydra_report(stderr, "[INFO] S: %s\n", buf);
char buffer2[512]; char buffer2[512];
sasl_digest_md5(buffer2, login, pass, strstr(buf, "WWW-Authenticate: Digest") + strlen("WWW-Authenticate: Digest") + 1, host, "sip", NULL, 0, NULL); result = sasl_digest_md5(buffer2, login, pass, strstr(buf, "WWW-Authenticate: Digest") + strlen("WWW-Authenticate: Digest") + 1, host, "sip", NULL, 0, NULL);
if (result == NULL) return 3;
memset(buffer, 0, SIP_MAX_BUF); memset(buffer, 0, SIP_MAX_BUF);
snprintf(buffer, SIP_MAX_BUF, snprintf(buffer, SIP_MAX_BUF,

View file

@ -37,7 +37,7 @@ char *smtp_read_server_capacity(int32_t sock) {
} }
int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = ""; char *empty = "", *result = NULL;
char *login, *pass, buffer[500], buffer2[500], *fooptr, *buf; char *login, *pass, buffer[500], buffer2[500], *fooptr, *buf;
if (strlen(login = hydra_get_next_login()) == 0) if (strlen(login = hydra_get_next_login()) == 0)
@ -67,7 +67,8 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
sasl_plain(buffer, login, pass); result = sasl_plain(buffer, login, pass);
if (result == NULL) return 3;
char tmp_buffer[sizeof(buffer)]; char tmp_buffer[sizeof(buffer)];
sprintf(tmp_buffer, "%.250s\r\n", buffer); sprintf(tmp_buffer, "%.250s\r\n", buffer);
@ -102,7 +103,8 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha
free(buf); free(buf);
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
sasl_cram_md5(buffer2, pass, buffer); result = sasl_cram_md5(buffer2, pass, buffer);
if (result == NULL) return 3;
sprintf(buffer, "%s %.250s", preplogin, buffer2); sprintf(buffer, "%s %.250s", preplogin, buffer2);
hydra_tobase64((unsigned char *)buffer, strlen(buffer), sizeof(buffer)); hydra_tobase64((unsigned char *)buffer, strlen(buffer), sizeof(buffer));
@ -135,8 +137,8 @@ int32_t start_smtp(int32_t s, char *ip, int32_t port, unsigned char options, cha
hydra_report(stderr, "DEBUG S: %s\n", buffer); hydra_report(stderr, "DEBUG S: %s\n", buffer);
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "smtp", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, buffer, miscptr, "smtp", NULL, 0, NULL);
if (fooptr == NULL) if (result == NULL)
return 3; return 3;
if (debug) if (debug)

View file

@ -13,7 +13,7 @@ char *JABBER_CLIENT_INIT_END_STR = "' xmlns='jabber:client' xmlns:stream='http:/
"version='1.0'>"; "version='1.0'>";
int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) { int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, char *miscptr, FILE *fp) {
char *empty = "\"\""; char *empty = "\"\"", *result = NULL;
char *login, *pass, buffer[500], buffer2[500]; char *login, *pass, buffer[500], buffer2[500];
char *AUTH_STR = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='"; char *AUTH_STR = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='";
char *AUTH_STR_END = "'/>"; char *AUTH_STR_END = "'/>";
@ -125,7 +125,8 @@ int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, cha
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
case AUTH_PLAIN: { case AUTH_PLAIN: {
memset(buffer2, 0, sizeof(buffer)); memset(buffer2, 0, sizeof(buffer));
sasl_plain(buffer2, login, pass); result = sasl_plain(buffer2, login, pass);
if (result == NULL) return 3;
sprintf(buffer, "%s%.250s%s", RESPONSE_STR, buffer2, RESPONSE_END_STR); sprintf(buffer, "%s%.250s%s", RESPONSE_STR, buffer2, RESPONSE_END_STR);
if (debug) if (debug)
hydra_report(stderr, "DEBUG C: %s\n", buffer); hydra_report(stderr, "DEBUG C: %s\n", buffer);
@ -136,7 +137,8 @@ int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, cha
char *preplogin; char *preplogin;
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
sasl_cram_md5(buffer2, pass, buffer); result = sasl_cram_md5(buffer2, pass, buffer);
if (result == NULL) return 3;
rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) { if (rc) {
@ -156,8 +158,8 @@ int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, cha
case AUTH_DIGESTMD5: { case AUTH_DIGESTMD5: {
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
fooptr = buffer2; fooptr = buffer2;
sasl_digest_md5(fooptr, login, pass, buffer, domain, "xmpp", NULL, 0, NULL); result = sasl_digest_md5(fooptr, login, pass, buffer, domain, "xmpp", NULL, 0, NULL);
if (fooptr == NULL) { if (result == NULL) {
free(buf); free(buf);
return 3; return 3;
} }
@ -217,8 +219,8 @@ int32_t start_xmpp(int32_t s, char *ip, int32_t port, unsigned char options, cha
memset(buffer2, 0, sizeof(buffer2)); memset(buffer2, 0, sizeof(buffer2));
fooptr = buffer2; fooptr = buffer2;
sasl_scram_sha1(fooptr, pass, clientfirstmessagebare, serverfirstmessage); result = sasl_scram_sha1(fooptr, pass, clientfirstmessagebare, serverfirstmessage);
if (fooptr == NULL) { if (result == NULL) {
hydra_report(stderr, "[ERROR] Can't compute client response\n"); hydra_report(stderr, "[ERROR] Can't compute client response\n");
free(buf); free(buf);
return 1; return 1;

60
sasl.c
View file

@ -68,20 +68,20 @@ sasl_plain computes the plain authentication from strings login and password
and stored the value in variable result and stored the value in variable result
the first parameter result must be able to hold at least 255 bytes! the first parameter result must be able to hold at least 255 bytes!
*/ */
void sasl_plain(char *result, char *login, char *pass) { char *sasl_plain(char *result, char *login, char *pass) {
char *preplogin; char *preplogin;
char *preppasswd; char *preppasswd;
int32_t rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin); int32_t rc = sasl_saslprep(login, SASL_ALLOW_UNASSIGNED, &preplogin);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
free(preplogin); free(preplogin);
result = NULL; result = NULL;
return; return result;
} }
if (2 * strlen(preplogin) + 3 + strlen(preppasswd) < 180) { if (2 * strlen(preplogin) + 3 + strlen(preppasswd) < 180) {
strcpy(result, preplogin); strcpy(result, preplogin);
@ -91,6 +91,7 @@ void sasl_plain(char *result, char *login, char *pass) {
} }
free(preplogin); free(preplogin);
free(preppasswd); free(preppasswd);
return result;
} }
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
@ -102,7 +103,7 @@ and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_md5(char *result, char *pass, char *challenge) { char *sasl_cram_md5(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
char opad[64]; char opad[64];
unsigned char md5_raw[MD5_DIGEST_LENGTH]; unsigned char md5_raw[MD5_DIGEST_LENGTH];
@ -112,12 +113,12 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return result;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
@ -148,6 +149,7 @@ void sasl_cram_md5(char *result, char *pass, char *challenge) {
result += 2; result += 2;
} }
free(preppasswd); free(preppasswd);
return result;
} }
/* /*
@ -156,7 +158,7 @@ and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_sha1(char *result, char *pass, char *challenge) { char *sasl_cram_sha1(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
char opad[64]; char opad[64];
unsigned char sha1_raw[SHA_DIGEST_LENGTH]; unsigned char sha1_raw[SHA_DIGEST_LENGTH];
@ -166,12 +168,12 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return result;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
@ -202,6 +204,7 @@ void sasl_cram_sha1(char *result, char *pass, char *challenge) {
result += 2; result += 2;
} }
free(preppasswd); free(preppasswd);
return result;
} }
/* /*
@ -210,7 +213,7 @@ and the challenge sent by the server, and stored the value in variable
result result
the parameter result must be able to hold at least 100 bytes! the parameter result must be able to hold at least 100 bytes!
*/ */
void sasl_cram_sha256(char *result, char *pass, char *challenge) { char *sasl_cram_sha256(char *result, char *pass, char *challenge) {
char ipad[64]; char ipad[64];
char opad[64]; char opad[64];
unsigned char sha256_raw[SHA256_DIGEST_LENGTH]; unsigned char sha256_raw[SHA256_DIGEST_LENGTH];
@ -220,14 +223,14 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
if (challenge == NULL) { if (challenge == NULL) {
result = NULL; result = NULL;
return; return result;
} }
memset(ipad, 0, sizeof(ipad)); memset(ipad, 0, sizeof(ipad));
memset(opad, 0, sizeof(opad)); memset(opad, 0, sizeof(opad));
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
if (strlen(preppasswd) >= 64) { if (strlen(preppasswd) >= 64) {
SHA256_Init(&sha256c); SHA256_Init(&sha256c);
@ -256,13 +259,14 @@ void sasl_cram_sha256(char *result, char *pass, char *challenge) {
result += 2; result += 2;
} }
free(preppasswd); free(preppasswd);
return result;
} }
/* /*
RFC 2831: Using Digest Authentication as a SASL Mechanism RFC 2831: Using Digest Authentication as a SASL Mechanism
the parameter result must be able to hold at least 500 bytes!! the parameter result must be able to hold at least 500 bytes!!
*/ */
void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int32_t webport, char *header) { char *sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int32_t webport, char *header) {
char *pbuffer = NULL; char *pbuffer = NULL;
int32_t array_size = 10; int32_t array_size = 10;
unsigned char response[MD5_DIGEST_LENGTH]; unsigned char response[MD5_DIGEST_LENGTH];
@ -277,13 +281,13 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
memset(realm, 0, sizeof(realm)); memset(realm, 0, sizeof(realm));
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
rc = sasl_saslprep(pass, 0, &preppasswd); rc = sasl_saslprep(pass, 0, &preppasswd);
if (rc) { if (rc) {
free(preplogin); free(preplogin);
result = NULL; result = NULL;
return; return result;
} }
// DEBUG S: // DEBUG S:
// nonce="HB3HGAk+hxKpijy/ichq7Wob3Zo17LPM9rr4kMX7xRM=",realm="tida",qop="auth",maxbuf=4096,charset=utf-8,algorithm=md5-sess // nonce="HB3HGAk+hxKpijy/ichq7Wob3Zo17LPM9rr4kMX7xRM=",realm="tida",qop="auth",maxbuf=4096,charset=utf-8,algorithm=md5-sess
@ -344,7 +348,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(array[j]); free(array[j]);
hydra_report(stderr, "Error: DIGEST-MD5 nonce from server could not be extracted\n"); hydra_report(stderr, "Error: DIGEST-MD5 nonce from server could not be extracted\n");
result = NULL; result = NULL;
return; return result;
} }
} else { } else {
strncpy(nonce, strstr(array[i], "nonce=") + strlen("nonce="), sizeof(nonce) - 1); strncpy(nonce, strstr(array[i], "nonce=") + strlen("nonce="), sizeof(nonce) - 1);
@ -367,7 +371,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(array[i]); free(array[i]);
hydra_report(stderr, "Error: DIGEST-MD5 realm from server could not be extracted\n"); hydra_report(stderr, "Error: DIGEST-MD5 realm from server could not be extracted\n");
result = NULL; result = NULL;
return; return result;
} }
} else { } else {
strncpy(realm, strstr(array[i], "realm=") + strlen("realm="), sizeof(realm) - 1); strncpy(realm, strstr(array[i], "realm=") + strlen("realm="), sizeof(realm) - 1);
@ -390,7 +394,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
hydra_report(stderr, "Error: DIGEST-MD5 quality of protection only " hydra_report(stderr, "Error: DIGEST-MD5 quality of protection only "
"authentication is not supported by server\n"); "authentication is not supported by server\n");
result = NULL; result = NULL;
return; return result;
} }
} }
if (strstr(array[i], "algorithm=") != NULL) { if (strstr(array[i], "algorithm=") != NULL) {
@ -410,7 +414,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
hydra_report(stderr, "Error: DIGEST-MD5 algorithm from server could " hydra_report(stderr, "Error: DIGEST-MD5 algorithm from server could "
"not be extracted\n"); "not be extracted\n");
result = NULL; result = NULL;
return; return result;
} }
} else { } else {
strncpy(algo, strstr(array[i], "algorithm=") + strlen("algorithm="), sizeof(algo) - 1); strncpy(algo, strstr(array[i], "algorithm=") + strlen("algorithm="), sizeof(algo) - 1);
@ -424,7 +428,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
free(array[j]); free(array[j]);
hydra_report(stderr, "Error: DIGEST-MD5 algorithm not based on md5, based on %s\n", algo); hydra_report(stderr, "Error: DIGEST-MD5 algorithm not based on md5, based on %s\n", algo);
result = NULL; result = NULL;
return; return result;
} }
} }
free(array[i]); free(array[i]);
@ -575,6 +579,7 @@ void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *
} }
free(preplogin); free(preplogin);
free(preppasswd); free(preppasswd);
return result;
} }
/* /*
@ -584,7 +589,7 @@ I want to thx Simon Josefsson for his public server test,
and my girlfriend that let me work on that 2 whole nights ;) and my girlfriend that let me work on that 2 whole nights ;)
clientfirstmessagebare must be at least 500 bytes in size! clientfirstmessagebare must be at least 500 bytes in size!
*/ */
void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) { char *sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage) {
int32_t saltlen = 0; int32_t saltlen = 0;
int32_t iter = 4096; int32_t iter = 4096;
char *salt, *nonce, *ic; char *salt, *nonce, *ic;
@ -603,7 +608,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
if (rc) { if (rc) {
result = NULL; result = NULL;
return; return result;
} }
/*client-final-message */ /*client-final-message */
@ -614,7 +619,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
hydra_report(stderr, "Error: Can't understand server message\n"); hydra_report(stderr, "Error: Can't understand server message\n");
free(preppasswd); free(preppasswd);
result = NULL; result = NULL;
return; return result;
} }
strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1); strncpy(buffer, serverfirstmessage, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0'; buffer[sizeof(buffer) - 1] = '\0';
@ -627,7 +632,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
hydra_report(stderr, "Error: Can't understand server response\n"); hydra_report(stderr, "Error: Can't understand server response\n");
free(preppasswd); free(preppasswd);
result = NULL; result = NULL;
return; return result;
} }
if ((nonce != NULL) && (strlen(nonce) > 2)) if ((nonce != NULL) && (strlen(nonce) > 2))
snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce); snprintf(clientfinalmessagewithoutproof, sizeof(clientfinalmessagewithoutproof), "c=biws,%s", nonce);
@ -635,7 +640,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
hydra_report(stderr, "Error: Could not identify server nonce value\n"); hydra_report(stderr, "Error: Could not identify server nonce value\n");
free(preppasswd); free(preppasswd);
result = NULL; result = NULL;
return; return result;
} }
if ((salt != NULL) && (strlen(salt) > 2) && (strlen(salt) <= sizeof(buffer))) if ((salt != NULL) && (strlen(salt) > 2) && (strlen(salt) <= sizeof(buffer)))
// s=ghgIAfLl1+yUy/Xl1WD5Tw== remove the header s= // s=ghgIAfLl1+yUy/Xl1WD5Tw== remove the header s=
@ -644,7 +649,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
hydra_report(stderr, "Error: Could not identify server salt value\n"); hydra_report(stderr, "Error: Could not identify server salt value\n");
free(preppasswd); free(preppasswd);
result = NULL; result = NULL;
return; return result;
} }
/* SaltedPassword := Hi(Normalize(password), salt, i) */ /* SaltedPassword := Hi(Normalize(password), salt, i) */
@ -653,7 +658,7 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
hydra_report(stderr, "Error: Failed to generate PBKDF2\n"); hydra_report(stderr, "Error: Failed to generate PBKDF2\n");
free(preppasswd); free(preppasswd);
result = NULL; result = NULL;
return; return result;
} }
/* ClientKey := HMAC(SaltedPassword, "Client Key") */ /* ClientKey := HMAC(SaltedPassword, "Client Key") */
@ -674,5 +679,6 @@ void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, cha
if (debug) if (debug)
hydra_report(stderr, "DEBUG C: %s\n", result); hydra_report(stderr, "DEBUG C: %s\n", result);
free(preppasswd); free(preppasswd);
return result;
} }
#endif #endif

12
sasl.h
View file

@ -32,7 +32,7 @@ typedef enum { SASL_ALLOW_UNASSIGNED = 1 } sasl_saslprep_flags;
int32_t print_hex(unsigned char *buf, int32_t len); int32_t print_hex(unsigned char *buf, int32_t len);
void sasl_plain(char *result, char *login, char *pass); char* sasl_plain(char *result, char *login, char *pass);
int32_t sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out); int32_t sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out);
#ifdef LIBOPENSSL #ifdef LIBOPENSSL
@ -40,9 +40,9 @@ int32_t sasl_saslprep(const char *in, sasl_saslprep_flags flags, char **out);
#include <openssl/md5.h> #include <openssl/md5.h>
#include <openssl/sha.h> #include <openssl/sha.h>
void sasl_cram_md5(char *result, char *pass, char *challenge); char* sasl_cram_md5(char *result, char *pass, char *challenge);
void sasl_cram_sha1(char *result, char *pass, char *challenge); char* sasl_cram_sha1(char *result, char *pass, char *challenge);
void sasl_cram_sha256(char *result, char *pass, char *challenge); char* sasl_cram_sha256(char *result, char *pass, char *challenge);
void sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int32_t webport, char *header); char* sasl_digest_md5(char *result, char *login, char *pass, char *buffer, char *miscptr, char *type, char *webtarget, int32_t webport, char *header);
void sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage); char* sasl_scram_sha1(char *result, char *pass, char *clientfirstmessagebare, char *serverfirstmessage);
#endif #endif