/
ntlm_functions.go
75 lines (62 loc) · 1.62 KB
/
ntlm_functions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package ntlm
import (
"bytes"
"crypto/hmac"
"crypto/md5"
"crypto/rand"
"fmt"
"strings"
"time"
"golang.org/x/crypto/md4"
)
const TimeOffset = Uint64LE(116444736000000000)
func getStrBytes(str string, flag NegotiateFlag) []byte {
if (flag&NegotiateOEM == 0) || (flag&NegotiateUnicode == NegotiateUnicode) {
return utf8ToUtf16(str)
}
return []byte(str)
}
func NTLMHash(password string, flag NegotiateFlag) []byte {
md4h := md4.New()
md4h.Write(getStrBytes(password, flag))
return md4h.Sum(nil)
}
func HMACMD5(key, data []byte) []byte {
hm := hmac.New(md5.New, key)
hm.Write(data)
return hm.Sum(nil)
}
func NTLMV2Hash(username, password, domain string, flag NegotiateFlag) []byte {
userDom := fmt.Sprintf("%s%s", strings.ToUpper(username), domain)
userDomBytes := getStrBytes(userDom, flag)
return HMACMD5(NTLMHash(password, flag), userDomBytes)
}
func TimeStamp() Uint64LE {
now := time.Now().UTC()
return (Uint64LE(now.Unix()) + TimeOffset) * 10000000
}
func NewBlobWithChallenge(clientChallenge []byte, targetInfo []byte) Blob {
var bb = NewBlob()
bb.Challenge = clientChallenge
bb.TargetInfo = targetInfo
bb.Timestamp = TimeStamp()
return bb
}
func concat(a []byte, b []byte) []byte {
var buf = &bytes.Buffer{}
buf.Grow(len(a) + len(b))
buf.Write(a)
buf.Write(b)
return buf.Bytes()
}
func NTProof(ntlmV2Hash []byte, serverChallenge []byte, blob []byte) []byte {
return HMACMD5(ntlmV2Hash, concat(serverChallenge, blob))
}
func NtlmV2Response(ntProofStr []byte, blob []byte) []byte {
return concat(ntProofStr, blob)
}
func getRandom(bs int) []byte {
var ret = make([]byte, bs)
rand.Read(ret)
return ret
}