python/samba/tests/LMv2_generate_response.py
authorStefan Metzmacher <metze@samba.org>
Thu, 3 Mar 2022 21:00:16 +0000 (22:00 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 2 Feb 2024 10:31:16 +0000 (11:31 +0100)
python/samba/tests/LMv2_generate_response.py [new file with mode: 0755]

diff --git a/python/samba/tests/LMv2_generate_response.py b/python/samba/tests/LMv2_generate_response.py
new file mode 100755 (executable)
index 0000000..2e5d815
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2013 by the Massachusetts Institute of Technology.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# XXX current status:
+# * Done and tested
+#   - AES encryption, checksum, string2key, prf
+#   - cf2 (needed for FAST)
+# * Still to do:
+#   - DES enctypes and cksumtypes
+#   - RC4 exported enctype (if we need it for anything)
+#   - Unkeyed checksums
+#   - Special RC4, raw DES/DES3 operations for GSSAPI
+# * Difficult or low priority:
+#   - Camellia not supported by PyCrypto
+#   - Cipher state only needed for kcmd suite
+#   - Nonstandard enctypes and cksumtypes like des-hmac-sha1
+
+import sys
+import os
+
+sys.path.insert(0, "bin/python")
+os.environ["PYTHONUNBUFFERED"] = "1"
+
+from math import gcd
+from functools import reduce
+from struct import pack, unpack
+from binascii import crc32
+from cryptography.hazmat.primitives import hashes
+from cryptography.hazmat.primitives import hmac
+from cryptography.hazmat.primitives.ciphers import algorithms as ciphers
+from cryptography.hazmat.primitives.ciphers import modes
+from cryptography.hazmat.primitives.ciphers.base import Cipher
+from cryptography.hazmat.backends import default_backend
+from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
+from samba.tests import TestCase
+from samba.credentials import Credentials
+from samba import generate_random_bytes as get_random_bytes
+from samba.common import get_string, get_bytes
+
+def h2b(hexstr):
+    return bytes.fromhex(hexstr)
+def b2h(bstr):
+    return bytes.hex(bstr)
+
+nthash = h2b('c5533ff38381e875c447b5192c8bea36')
+print("nthash: %r" % b2h(nthash))
+
+user="Administrator"
+domain="SUBDOM21"
+
+userblob=user.upper().encode('UTF-16-LE')
+userblob=user.encode('UTF-16-LE')
+userblob=user.encode('ASCII')
+domainblob=domain.upper().encode('UTF-16-LE')
+domainblob=domain.encode('UTF-16-LE')
+domainblob=domain.encode('ASCII')
+
+print("userblob: %r" % b2h(userblob))
+print("domainblob: %r" % b2h(domainblob))
+
+hmac_ctx = hmac.HMAC(nthash, hashes.MD5(), default_backend())
+hmac_ctx.update(userblob)
+hmac_ctx.update(domainblob)
+nthashv2 = hmac_ctx.finalize()
+print("nthashv2: %s" % b2h(nthashv2))
+
+chal1= h2b('dd318b00a25389e1')
+print("chal1: %s" % b2h(chal1))
+
+lmv2 = h2b('86559c637f1860d9901177841aeb762a0000000000000000')
+print("lmv2: %s" % b2h(lmv2))
+
+chal2 = lmv2[16:]
+print("chal2: %s" % b2h(chal2))
+expres= lmv2[0:16]
+print("expres: %s" % b2h(expres))
+
+hmac_ctx = hmac.HMAC(nthashv2, hashes.MD5(), default_backend())
+hmac_ctx.update(chal1)
+hmac_ctx.update(chal2)
+res = hmac_ctx.finalize()
+
+print("resres: %s" % b2h(res))