Skip to content

Instantly share code, notes, and snippets.

@hiroyuki-sato
Last active July 20, 2022 08:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiroyuki-sato/5d2aaf4de2f9289c62ca3c427aed050b to your computer and use it in GitHub Desktop.
Save hiroyuki-sato/5d2aaf4de2f9289c62ca3c427aed050b to your computer and use it in GitHub Desktop.
NTLM手計算

NTLM 認証プロトコルとセキュリティサポート プロバイダ より

文中のコードはRuby

NTLM レスポンス

  • ユーザパスワード: SecREt01
  • Type 2 チャレンジ: 0x0123456789abcdef

Unicodeベースの大文字小文字が混在したパスワードは16進数で 「0x53006500630052004500740030003100」となる。

"SecREt01".encode("UTF-16LE").unpack("H*").first.gsub(/..(?=.)/, '\0 ')
=> "53 00 65 00 63 00 52 00 45 00 74 00 30 00 31 00"

この値の MD4 ハッシュを計算するこ とで、「0xcd06ca7c7e10c99b1d33b7485a2ed808」という値が生成される。これが NTLM ハ ッシュである。

require 'openssl'
OpenSSL::Digest::MD4.digest("SecREt01".encode("UTF-16LE")).unpack("H*").first.gsub(/..(?=.)/, '\0 ')
=> "cd 06 ca 7c 7e 10 c9 9b 1d 33 b7 48 5a 2e d8 08"

これを 21 バイトになるように NULL パディングして「0xcd06ca7c7e10c99b1d33b7485a2ed8080000000000」という値が生成される。

digest = OpenSSL::Digest::MD4.digest("SecREt01".encode("UTF-16LE"))
v = digest + "\x00" * (21 - digest.size)
v.unpack("H*").first.gsub(/..(?=.)/, '\0 ')
=> "cd 06 ca 7c 7e 10 c9 9b 1d 33 b7 48 5a 2e d8 08 00 00 00 00 00"

この値を 3 つの 7 バイトの値に分割し、「0xcd06ca7c7e10c9」、「0x9b1d33b7485a2e」、 「0xd8080000000000」という値が生成される。

digest = OpenSSL::Digest::MD4.digest("SecREt01".encode("UTF-16LE"))
v = digest + "\x00" * (21 - digest.size)
v.scan(/.{1,7}/).map{ |d| d.unpack("H*").first.gsub(/..(?=.)/, '\0 ') }
=> ["cd 06 ca 7c 7e 10 c9", "9b 1d 33 b7 48 5a 2e", "d8 08 00 00 00 00 00"]

この 3 つの値は 3 つの DES 鍵を生成するのに用いられる。最初の値 11001101 00000110 11001010 01111100 01111110 00010000 11001001からは パリティ処理を行なった DES 鍵として 11001101 10000011 10110011 01001111 11000111 11110001 01000011 10010010 (16 進数で「0xcd83b34fc7f14392」)が生成される。

No. 元の値 DESパリティ処理後
No.1 cd 06 ca 7c 7e 10 c9 cd 83 b3 4f c7 f1 43 92
No.2 9b 1d 33 b7 48 5a 2e 9b 8f 4c 76 75 43 68 5d
No.2 d8 08 00 00 00 00 00 d9 04 01 01 01 01 01 01

これら 3 つの鍵が、Type 2 メッセージのチャレンジ(「0x0123456789abcdef」)の DES 暗号 化に用いられる。これにより、以下の値、 「0x25a98c1c31e81847」 (1 つ目の鍵を使用)、 「0x466b29b2df4680f3」 (2 つ目を使用)、 「0x9958fb8c213a9cc6」 (3 つ目の鍵を使用) が 生成される。

これら 3 つの暗号文を結合して、24 バイトのバイト列としたものが、以下の NTLM レス ポンスである。 0x25a98c1c31e81847466b29b2df4680f39958fb8c213a9cc6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment