[squid-users] problem with ntlm_smb_lm_auth helper

Amos Jeffries squid3 at treenet.co.nz
Mon Sep 7 12:01:37 UTC 2015


On 7/09/2015 10:23 p.m., Emmanuel Garette wrote:
>
> ntlmssp: bad ascii: fffffffb
> ntlmssp: bad ascii: ffffff99
> ntlmssp: bad ascii: ffffffdc
> ntlmssp: bad ascii: fffffff3
> ntlmssp: bad ascii: 0000
> ntlmssp: bad ascii: ffffffdd
> ntlmssp: bad ascii: fffffffa
> ntlmssp: bad ascii: ffffff8f
> ntlmssp: bad ascii: ffffffa6
> ntlmssp: bad ascii: 0017
> ntlmssp: bad ascii: ffffffca
> ntlmssp: bad ascii: ffffff97
> ntlmssp: bad ascii: ffffffeb
> ntlmssp: bad ascii: ffffffd2
> ntlmssp: bad ascii: fffffffc
> ntlmssp: bad ascii: ffffffda
> ntlmssp: bad ascii: ffffffa9
> ntlmssp: bad ascii: ffffffdd
> ntlm_smb_lm_auth.cc(277): pid=5278 :Empty LM pass detection: user:
> 'ADMIN', ours:'(E�
>                                                                                     
> �p�����(jw�B�����.Q�7��h(�', his: '�2��Z�' (length: 24)
> ntlmssp: bad ascii: ffffffdd
> ntlmssp: bad ascii: 0018
> ntlmssp: bad ascii: ffffffb2
> ntlmssp: bad ascii: 001e
> ntlmssp: bad ascii: ffffff9b
> ntlmssp: bad ascii: fffffffd
> ntlmssp: bad ascii: 007f
> ntlmssp: bad ascii: 0010
> ntlmssp: bad ascii: ffffff89
> ntlmssp: bad ascii: ffffff8c
> ntlmssp: bad ascii: ffffff85
> ntlmssp: bad ascii: ffffffa0
> ntlmssp: bad ascii: ffffffac
> ntlmssp: bad ascii: ffffffb8
> ntlmssp: bad ascii: 0000
> ntlm_smb_lm_auth.cc(288): pid=5278 :Empty NT pass detection: user:
> 'ADMIN', ours:'�����a����A
>                                                                                              
> ��2��', his: '�g[�S�P�Z<�^�:���<�M' (length: 24)
> ntlm_smb_lm_auth.cc(299): pid=5278 :checking domain: 'DOMPEDAGO', user:
> 'ADMIN', pass='�2��Z�'
> 

Ah! fetch_string should not even have been used at all on these encoded
blobs. They are not strings. That appears to be the problem.

Please try the attached patch.
(It should apply on squid-3.3 with patch -p0 ).

Amos
-------------- next part --------------
=== modified file 'helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc'
--- helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc	2012-11-24 03:52:54 +0000
+++ helpers/ntlm_auth/smb_lm/ntlm_smb_lm_auth.cc	2015-09-07 11:46:55 +0000
@@ -239,80 +239,100 @@
     memcpy(domain, tmp.str, tmp.l);
     user = domain + tmp.l;
     *user = '\0';
     ++user;
 
     /*      debug("fetching user name\n"); */
     tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->user, auth->flags);
     if (tmp.str == NULL || tmp.l == 0) {
         debug("No username supplied. Returning no-auth\n");
         ntlm_errno = NTLM_ERR_LOGON;
         return NULL;
     }
     if (tmp.l > MAX_USERNAME_LEN) {
         debug("Username string exceeds %d bytes, rejecting\n", MAX_USERNAME_LEN);
         ntlm_errno = NTLM_ERR_LOGON;
         return NULL;
     }
     memcpy(user, tmp.str, tmp.l);
     *(user + tmp.l) = '\0';
 
-    /* Authenticating against the NT response doesn't seem to work... */
-    tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->lmresponse, auth->flags);
-    if (tmp.str == NULL || tmp.l == 0) {
-        fprintf(stderr, "No auth at all. Returning no-auth\n");
-        ntlm_errno = NTLM_ERR_LOGON;
-        return NULL;
+    // grab the *response blobs. these are fixed length 24 bytes of binary
+    const ntlmhdr *packet = &(auth->hdr);
+    {
+        const strhdr * str = &auth->lmresponse;
+
+        int16_t len = le16toh(str->len);
+        int32_t offset = le32toh(str->offset);
+
+        if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
+            debug("LM response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
+            ntlm_errno = NTLM_ERR_LOGON;
+            return NULL;
+        }
+        tmp.str = (char *)packet + offset;
+        tmp.l = len;
     }
     if (tmp.l > MAX_PASSWD_LEN) {
         debug("Password string exceeds %d bytes, rejecting\n", MAX_PASSWD_LEN);
         ntlm_errno = NTLM_ERR_LOGON;
         return NULL;
     }
 
+    /* Authenticating against the NT response doesn't seem to work... in SMB LM helper. */
     memcpy(pass, tmp.str, tmp.l);
     pass[min(MAX_PASSWD_LEN,tmp.l)] = '\0';
 
 #if 1
     debug("Empty LM pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
           user,lmencoded_empty_pass,tmp.str,tmp.l);
     if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
         fprintf(stderr,"Empty LM password supplied for user %s\\%s. "
                 "No-auth\n",domain,user);
         ntlm_errno=NTLM_ERR_LOGON;
         return NULL;
     }
 
-    tmp = ntlm_fetch_string(&(auth->hdr), auth_length, &auth->ntresponse, auth->flags);
-    if (tmp.str != NULL && tmp.l != 0) {
+    /* still fetch the NT response and check validity against empty password */
+    {
+        const strhdr * str = &auth->ntresponse;
+        int16_t len = le16toh(str->len);
+        int32_t offset = le32toh(str->offset);
+
+        if (len != ENCODED_PASS_LEN || offset + len > auth_length || offset == 0) {
+            debug("NT response: insane data (pkt-sz: %d, fetch len: %d, offset: %d)\n", auth_length, len, offset);
+            ntlm_errno = NTLM_ERR_LOGON;
+            return NULL;
+        }
+        tmp.str = (char *)packet + offset;
+        tmp.l = len;
+
         debug("Empty NT pass detection: user: '%s', ours:'%s', his: '%s' (length: %d)\n",
               user,ntencoded_empty_pass,tmp.str,tmp.l);
         if (memcmp(tmp.str,lmencoded_empty_pass,ENCODED_PASS_LEN)==0) {
             fprintf(stderr,"ERROR: Empty NT password supplied for user %s\\%s. No-auth\n", domain, user);
             ntlm_errno = NTLM_ERR_LOGON;
             return NULL;
         }
     }
 #endif
 
-    /* TODO: check against empty password!!!!! */
-
     debug("checking domain: '%s', user: '%s', pass='%s'\n", domain, user, pass);
 
     rv = SMB_Logon_Server(handle, user, pass, domain, 1);
     debug("Login attempt had result %d\n", rv);
 
     if (rv != NTLM_ERR_NONE) {	/* failed */
         ntlm_errno = rv;
         return NULL;
     }
     *(user - 1) = '\\';		/* hack. Performing, but ugly. */
 
     debug("credentials: %s\n", credentials);
     return credentials;
 }
 
 extern "C" void timeout_during_auth(int signum);
 
 static char got_timeout = 0;
 /** signal handler to be invoked when the authentication operation
  * times out */



More information about the squid-users mailing list