-
Notifications
You must be signed in to change notification settings - Fork 0
cntlm example
Alistair Michael edited this page Sep 6, 2023
·
1 revision
cntlm is an authentication proxy for Microsoft NTLM.
It is still reasonably widely-used, but has not been updated since 2013 https://sourceforge.net/projects/cntlm/.
The http_parse_basic
method in http.c
contains multiple errors we could detect through bounds checking and information flow through binary analysis.
/*
* Parse headers for BASIC auth credentials
*
* Return 1 = creds parsed OK, 0 = no creds, -1 = invalid creds
*/
int http_parse_basic(hlist_t headers, const char *header, struct auth_s *tcreds) {
char *tmp = NULL, *pos = NULL, *buf = NULL, *dom = NULL;
int i;
if (!hlist_subcmp(headers, header, "basic"))
return 0;
tmp = hlist_get(headers, header);
buf = new(strlen(tmp) + 1); // buf = "domain\\userid:password"
i = 5;
while (i < strlen(tmp) && tmp[++i] == ' ');
from_base64(buf, tmp+i);
pos = strchr(buf, ':');
if (pos == NULL) {
memset(buf, 0, strlen(buf)); /* clean password memory */ // optimised out
free(buf);
return -1;
} else {
*pos = 0; // strlen(buf) == strlen(user)
dom = strchr(buf, '\\');
if (dom == NULL) {
auth_strcpy(tcreds, user, buf);
} else {
*dom = 0; // strlen(buf) == strlen(domain)
auth_strcpy(tcreds, domain, buf);
auth_strcpy(tcreds, user, dom+1);
}
if (tcreds->hashntlm2) {
tmp = ntlm2_hash_password(tcreds->user, tcreds->domain, pos+1);
auth_memcpy(tcreds, passntlm2, tmp, 16);
free(tmp);
}
if (tcreds->hashnt) {
tmp = ntlm_hash_nt_password(pos+1);
auth_memcpy(tcreds, passnt, tmp, 21);
free(tmp);
}
if (tcreds->hashlm) {
tmp = ntlm_hash_lm_password(pos+1);
auth_memcpy(tcreds, passlm, tmp, 21);
free(tmp);
}
memset(buf, 0, strlen(buf)); // optimised out
free(buf);
}
return 1;
}