-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathlocal_negotiate.go
179 lines (148 loc) · 4.33 KB
/
local_negotiate.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package main
import (
"fmt"
"ntlmssp"
"syscall"
"unsafe"
)
var (
username = []byte("iv4n")
password = []byte("password")
servername = []byte("PC")
)
var (
security = syscall.NewLazyDLL("security.dll")
acquireCredentialsHandleA = security.NewProc("AcquireCredentialsHandleA")
acceptSecurityContext = security.NewProc("AcceptSecurityContext")
)
const (
SEC_E_OK = 0x00
SEC_I_CONTINUE_NEEDED = 0x90312
SEC_E_LOGON_DENIED = 0x8009030c
SEC_E_INVALID_TOKEN = 0x80090308
SECPKG_CRED_INBOUND = 0x01
SECBUFFER_TOKEN = 2
SECBUFFER_VERSION = 0
ASC_REQ_ALLOCATE_MEMORY = 0x100
ASC_REQ_CONNECTION = 0x800
SECURITY_NATIVE_DREP = 0x10
)
type (
secHandle struct {
dwLower uint64
dwUpper uint64
}
credHandle secHandle
ctxtHandle secHandle
timeStamp struct {
LowPart uint32
HighPart uint32
}
secBuffer struct {
cbBuffer uint32 // Size of the buffer, in bytes
BufferType uint32 // Type of the buffer (below)
pvBuffer uintptr // Pointer to the buffer
}
secBufferDesc struct {
ulVersion uint32 // Version number
cBuffers uint32 // Number of buffers
pBuffers *secBuffer // Pointer to array of buffers
}
)
func localNegotiate() {
lpPackageName := []byte("Negotiate")
hCredential := credHandle{}
time := timeStamp{}
ret, _, err := acquireCredentialsHandleA.Call(
0,
(uintptr)(unsafe.Pointer(&lpPackageName[0])),
SECPKG_CRED_INBOUND,
0, 0, 0, 0,
(uintptr)(unsafe.Pointer(&hCredential)),
(uintptr)(unsafe.Pointer(&time)),
)
if ret != SEC_E_OK {
fmt.Println(err)
return
}
hContext := ctxtHandle{}
secBufClient := secBuffer{}
secBufDescClient := secBufferDesc{}
initTokenContextBuffer(&secBufDescClient, &secBufClient)
type1 := ntlmssp.NewNegotiateMsg(nil)
type1.NegotiateFlags |= ntlmssp.NEGOTIATE_128BIT_SESSION_KEY |
ntlmssp.NEGOTIATE_56BIT_ENCRYPTION |
ntlmssp.NEGOTIATE_UNICODE_CHARSET |
ntlmssp.NEGOTIATE_EXTENDED_SESSION_SECURITY
bs := type1.Marshal('<')
secBufClient.cbBuffer = uint32(len(bs))
secBufClient.pvBuffer = (uintptr)(unsafe.Pointer(&bs[0]))
secBufServer := secBuffer{}
secBufDescServer := secBufferDesc{}
initTokenContextBuffer(&secBufDescServer, &secBufServer)
var fContextAttr uint32
var tsExpiry timeStamp
ret, _, err = acceptSecurityContext.Call(
(uintptr)(unsafe.Pointer(&hCredential)),
0,
(uintptr)(unsafe.Pointer(&secBufDescClient)),
ASC_REQ_ALLOCATE_MEMORY|ASC_REQ_CONNECTION,
SECURITY_NATIVE_DREP,
(uintptr)(unsafe.Pointer(&hContext)),
(uintptr)(unsafe.Pointer(&secBufDescServer)),
(uintptr)(unsafe.Pointer(&fContextAttr)),
(uintptr)(unsafe.Pointer(&tsExpiry)),
)
if ret != SEC_I_CONTINUE_NEEDED {
fmt.Println(err)
return
}
type2 := ntlmssp.NewChallengeMsg(loadByteArray(secBufServer.pvBuffer, secBufServer.cbBuffer))
type2.Display()
type3 := ntlmssp.NewAuthenticateMsg(nil)
type3.NegotiateFlags = type2.NegotiateFlags
// type3.NegotiateFlags &^= ntlmssp.NEGOTIATE_EXTENDED_SESSION_SECURITY
type3.SetUserName(username)
type3.SetWorkstation(servername)
type3.SetNTLMResponse(1, type2.ServerChallenge[:], password)
type3.Display()
bs = type3.Marshal('<')
initTokenContextBuffer(&secBufDescClient, &secBufClient)
secBufClient.pvBuffer = (uintptr)(unsafe.Pointer(&bs[0]))
secBufClient.cbBuffer = uint32(len(bs))
initTokenContextBuffer(&secBufDescServer, &secBufServer)
ret, _, err = acceptSecurityContext.Call(
(uintptr)(unsafe.Pointer(&hCredential)),
(uintptr)(unsafe.Pointer(&hContext)),
(uintptr)(unsafe.Pointer(&secBufDescClient)),
ASC_REQ_ALLOCATE_MEMORY|ASC_REQ_CONNECTION,
SECURITY_NATIVE_DREP,
(uintptr)(unsafe.Pointer(&hContext)),
(uintptr)(unsafe.Pointer(&secBufDescServer)),
(uintptr)(unsafe.Pointer(&fContextAttr)),
(uintptr)(unsafe.Pointer(&tsExpiry)),
)
if ret == SEC_E_INVALID_TOKEN {
fmt.Println("NTLM auth error,", err)
}
if ret == SEC_E_LOGON_DENIED {
fmt.Println("Username or password wrong,", err)
return
}
if ret == SEC_E_OK {
fmt.Println("Auth ok,", err)
}
}
func initTokenContextBuffer(bufDesc *secBufferDesc, buf *secBuffer) {
buf.BufferType = SECBUFFER_TOKEN
buf.cbBuffer = 0
buf.pvBuffer = 0
bufDesc.ulVersion = SECBUFFER_VERSION
bufDesc.cBuffers = 1
bufDesc.pBuffers = buf
}
func loadByteArray(addr uintptr, length uint32) []byte {
// I don't know the length while compiling
output := (*[512]byte)(unsafe.Pointer(addr))
return (*output)[:length]
}