python-3.xhashpython-requestsntlm-authentication

How do I hash a password for use with HttpNtlmAuth


I can access a web app within my organization using a request with HttpNtlmAuth with my plaintext username and password but I would rather not store my password in plaintext in my code. I have read in the following other SO answers that you can pass a hash of the password instead of the plaintext but I am not sure how to do that:

  1. The chosen answer to this question mentioned "supplying your password or the hash of your password to HttpNtlmAuth" but doesn't elaborate.
  2. A comment on this thread mentioned hashing the password but there was no response on which algorithm to use.

I have tried using MD4/UTF-16 per this link and also tried MD5 according to this link but both of those returned a 401 (unauthorized) response. The following code returns a 200 response (success) with my plaintext password.

Am I using the wrong hash algorithm, or am I missing something else fundamental?

import hashlib
import requests
from requests_ntlm import HttpNtlmAuth

# these are not the actual values
USERNAME = 'domain\\username'
PASSWORD = 'password'
URL = 'https://internal_web_app/url.aspx?Parameters=values'

hashes = [
    PASSWORD,                                                    # No hash
    hashlib.new('md4', PASSWORD.encode('utf-16le')).hexdigest(), # NTLM
    hashlib.md5(PASSWORD.encode('utf-8')).hexdigest()            # MD5
]

for hash in hashes:
    # create a session
    session = requests.Session()
    # set up the authentication object with the respective string
    session.auth = HttpNtlmAuth(USERNAME, hash)
    # send a GET request (verify=False because the SSL cert is crappy)
    response = session.get(URL, verify=False)
    # expecting 200 for success and 401 for authentication failure
    print(response.status_code)

Output:

200
401
401

Solution

  • My objective was to avoid storing my password in the notebook. I realized that a workaround is to get the user in enter the password on running the script, using

    import getpass
    password = getpass.getpass()
    

    I've worked around my immediate issue, but I'm still curious about the hashing though (to enable this script to run unattended if possible) so if someone does figure it out please do submit a response.