-
Notifications
You must be signed in to change notification settings - Fork 1
/
Desktop.nim
345 lines (337 loc) · 14.9 KB
/
Desktop.nim
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
import winim/lean
import terminal, strutils
type
status* = enum
error, success, loading, warning
proc print*(STATUS: status, text: string) =
case STATUS
of error:
stdout.styledWrite(fgRed, "[-] ")
of success:
stdout.styledWrite(fgGreen, "[+] ")
of loading:
stdout.styledWrite(fgBlue, "[*] ")
of warning:
stdout.styledWrite(fgYellow, "[!] ")
stdout.write(text & "\n"); flushFile(stdout)
#proc GetAclInformation * (pAcl: PACL, pAclInformation: LPVOID, nAclInformationLength: DWORD, dwAclInformationClass: typedesc[ACL_SIZE_INFORMATION]): WINBOOL {.winapi, stdcall, dynlib: "advapi32", importc.}
proc AddTheAceDesktop * (hdesk: HANDLE, psid: PSID, debug : bool = false): BOOL =
var
aclSizeInfo: ACL_SIZE_INFORMATION
AclSizeInformationClass: int32 = cast[int32](2)
DESKTOP_ALL: DWORD = (DESKTOP_CREATEMENU or DESKTOP_CREATEWINDOW or DESKTOP_ENUMERATE or DESKTOP_HOOKCONTROL or DESKTOP_JOURNALPLAYBACK or DESKTOP_JOURNALRECORD or DESKTOP_READOBJECTS or DESKTOP_SWITCHDESKTOP or DESKTOP_WRITEOBJECTS or DELETE or READ_CONTROL or WRITE_DAC or WRITE_OWNER)
bDaclExist: BOOL
bDaclPresent: BOOL
bSuccess: BOOL = 0
dwNewAclSize: DWORD
dwSidSize: DWORD = 0
dwSdSizeNeeded: DWORD
pacl: PACL
pNewACL: PACL = nil
psd: PSECURITY_DESCRIPTOR = nil
psdNew: PSECURITY_DESCRIPTOR = nil
pTempAce: PVOID
si: SECURITY_INFORMATION = DACL_SECURITY_INFORMATION
functionreturn: BOOL = 0
if debug:
print(success, "AddTheAceDesktop to hdesk start!")
# obtain the security descriptor for the desktop object
functionreturn = GetUserObjectSecurity(hdesk, addr si, psd, dwSidSize, addr dwSdSizeNeeded)
if (functionreturn == 0):
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER):
psd = cast[PSECURITY_DESCRIPTOR](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded))
if (psd == nil):
echo "Psd is null"
return bSuccess
psdNew = cast[PSECURITY_DESCRIPTOR](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded))
if (psdNew == nil):
echo "PsdNew is null"
return bSuccess
dwSidSize = dwSdSizeNeeded
functionreturn = GetUserObjectSecurity(hdesk, addr si, psd, dwSidSize, addr dwSdSizeNeeded)
if (functionreturn == 0):
echo "2ccond GetUserObjectSecurity fail"
return bSuccess
if debug:
print(success, "GetUserObjectSecurity fine!")
# create a new security descriptor
functionreturn = InitializeSecurityDescriptor(psdNew,SECURITY_DESCRIPTOR_REVISION)
if (functionreturn == 0):
echo "InitializeSecurityDescriptor failed"
return bSuccess
if debug:
print(success, "InitializeSecurityDescriptor fine!")
# obtain the dacl from the security descriptor
functionreturn = GetSecurityDescriptorDacl(psd,addr bDaclPresent,addr pacl,addr bDaclExist)
if (functionreturn == 0):
echo "GetSecurityDescriptorDacl failed"
return bSuccess
if debug:
print(success, "GetSecurityDescriptorDacl fine!")
# initialize
ZeroMemory(addr aclSizeInfo, sizeof(ACL_SIZE_INFORMATION))
aclSizeInfo.AclBytesInUse = cast[DWORD](sizeof(ACL))
# call only if NULL dacl
if (pacl != nil):
# determine the size of the ACL info
functionreturn = GetAclInformation(pacl,cast[LPVOID](addr aclSizeInfo),cast[DWORD](sizeof(ACL_SIZE_INFORMATION)),AclSizeInformationClass)
if (functionreturn == 0):
print(error,"GetAclInformation failed!" & $GetLastError())
return bSuccess
else:
if(debug):
print(success,"GetAclInformation fine!" & $GetLastError())
# compute the size of the new acl
dwNewAclSize = cast[DWORD](aclSizeInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD))
# allocate buffer for the new acl
pNewAcl = cast[PACL](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNewAclSize))
if (pNewAcl == nil):
echo "pNewACL is null"
return bSuccess
if debug:
print(success, "pNewAcl fine!")
# initialize the new acl
functionreturn = InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)
if (functionreturn == 0):
echo "InitializeAcl failed"
return bSuccess
if debug:
print(success, "InitializeAcl fine!")
# if DACL is present, copy it to a new DACL
if (bDaclPresent): # only copy if DACL was present
# copy the ACEs to our new ACL
if (aclSizeInfo.AceCount):
if debug:
print(success, "aclSizeInfo.AceCount: " & $aclSizeInfo.AceCount)
var low = 0
for low in 0 ..< aclSizeInfo.AceCount:
# get an ACE
functionreturn = GetAce(pacl, cast[DWORD](low), addr pTempAce)
if (functionreturn == 0):
print(error,"GetACE failed!" & $GetLastError())
#return bSuccess
else:
if debug:
print(success, "GetAce fine!")
var asd: PACE_HEADER = cast[PACE_HEADER](addr pTempAce)
echo $cast[DWORD](asd.AceSize)
functionreturn = AddAce(pNewAcl,ACL_REVISION,MAXDWORD,cast[LPVOID](addr pTempAce),cast[DWORD](asd.AceSize))
if (functionreturn == 0):
print(error,"AddAce failed!" & $GetLastError())
#return bSuccess
else:
if debug:
print(success, "AddAce fine!")
# leave
#if (functionreturn == 0):
# return bSuccess
# add ace to the dacl
functionreturn = AddAccessAllowedAce(pNewAcl,ACL_REVISION,DESKTOP_ALL,psid)
if (functionreturn == 0):
echo "AddAccessAllowedAce failed"
return bSuccess
if debug:
print(success, "AddAccessAllowedAce fine!")
# set new dacl to the new security descriptor
functionreturn = SetSecurityDescriptorDacl(psdNew,true,pNewAcl,false)
if (functionreturn == 0):
echo "SetSecurityDescriptorDacl failed"
return bSuccess
if debug:
print(success, "SetSecurityDescriptorDacl fine!")
# set the new security descriptor for the desktop object
functionreturn = SetUserObjectSecurity(hdesk, addr si, psdNew)
if (functionreturn == 0):
echo "SetUserObjectSecurity failed"
return bSuccess
if debug:
print(success, "SetUserObjectSecurity fine!")
bSuccess = true
echo "Everything went fine"
# free buffers
if (pNewACL != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](pNewAcl))
if (psd != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](psd))
if (psdNew != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](psdNew))
return bSuccess
proc AddTheAceWindowStation * (hwinsta: HANDLE, psid: PSID, debug : bool = false): BOOL =
var
pace: PVOID
WINSTA_ALL: DWORD = (WINSTA_ACCESSCLIPBOARD or WINSTA_ACCESSGLOBALATOMS or WINSTA_CREATEDESKTOP or WINSTA_ENUMDESKTOPS or WINSTA_ENUMERATE or WINSTA_EXITWINDOWS or WINSTA_READATTRIBUTES or WINSTA_READSCREEN or WINSTA_WRITEATTRIBUTES or DELETE or READ_CONTROL or WRITE_DAC or WRITE_OWNER)
aclSizeInfo: ACL_SIZE_INFORMATION
GENERIC_ACCESS: DWORD = (GENERIC_READ or GENERIC_WRITE or GENERIC_EXECUTE or GENERIC_ALL)
AclSizeInformationClass: int32 = 2
bDaclExist: BOOL
bDaclPresent: BOOL
bSuccess: BOOL = 0
dwNewAclSize: DWORD
dwSidSize: DWORD = 0
dwSdSizeNeeded: DWORD
pacl: PACL
pNewACL: PACL = nil
psd: PSECURITY_DESCRIPTOR = nil
psdNew: PSECURITY_DESCRIPTOR = nil
pTempAce: PVOID
si: SECURITY_INFORMATION = DACL_SECURITY_INFORMATION
i: int
functionreturn: BOOL = 0
if debug:
print(success, "AddTheAceWindowStation to WINSTA start!")
# obtain the security descriptor for the desktop object
functionreturn = GetUserObjectSecurity(hwinsta, addr si, psd, dwSidSize, addr dwSdSizeNeeded)
if (functionreturn == 0):
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER):
psd = cast[PSECURITY_DESCRIPTOR](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded))
if (psd == nil):
echo "Psd is null"
return bSuccess
psdNew = cast[PSECURITY_DESCRIPTOR](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSdSizeNeeded))
if (psdNew == nil):
echo "PsdNew is null"
return bSuccess
dwSidSize = dwSdSizeNeeded
functionreturn = GetUserObjectSecurity(hwinsta, addr si, psd, dwSidSize, addr dwSdSizeNeeded)
if (functionreturn == 0):
echo "2ccond GetUserObjectSecurity fail"
return bSuccess
if debug:
print(success, "GetUserObjectSecurity fine!")
# create a new security descriptor
functionreturn = InitializeSecurityDescriptor(psdNew,SECURITY_DESCRIPTOR_REVISION)
if (functionreturn == 0):
print(error,"InitializeSecurityDescriptor failed!" & $GetLastError())
return bSuccess
else:
if (debug):
print(success, "InitializeSecurityDescriptor fine!")
# obtain the dacl from the security descriptor
functionreturn = GetSecurityDescriptorDacl(psd,addr bDaclPresent,addr pacl,addr bDaclExist)
if (functionreturn == 0):
print(error,"GetSecurityDescriptorDacl failed!" & $GetLastError())
return bSuccess
else:
print(success, "GetSecurityDescriptorDacl fine!")
# initialize
ZeroMemory(addr aclSizeInfo, sizeof(ACL_SIZE_INFORMATION))
aclSizeInfo.AclBytesInUse = cast[DWORD](sizeof(ACL))
# call only if NULL dacl
if (pacl != nil):
# determine the size of the ACL info
functionreturn = GetAclInformation(pacl,cast[LPVOID](addr aclSizeInfo),cast[DWORD](sizeof(ACL_SIZE_INFORMATION)),AclSizeInformationClass)
if (functionreturn == 0):
print(error,"GetAclInformation failed!" & $GetLastError())
return bSuccess
else:
if (debug):
print(success, "GetAclInformation fine!")
# compute the size of the new acl
dwNewAclSize = cast[DWORD](aclSizeInfo.AclBytesInUse + (2 * sizeof(ACCESS_ALLOWED_ACE)) + (2 * GetLengthSid(psid)) - (2 * sizeof(DWORD)))
# allocate buffer for the new acl
pNewAcl = cast[PACL](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwNewAclSize))
if (pNewAcl == nil):
echo "pNewACL is null"
return bSuccess
if debug:
print(success, "pNewACL fine!")
# initialize the new acl
functionreturn = InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)
if (functionreturn == 0):
echo "InitializeAcl failed"
return bSuccess
if debug:
print(success, "InitializeAcl fine!")
# if DACL is present, copy it to a new DACL
if debug:
print(success, "aclSizeInfo.AceCount: " & $aclSizeInfo.AceCount)
if (bDaclPresent): # only copy if DACL was present
# copy the ACEs to our new ACL
if (aclSizeInfo.AceCount):
#var counter = 0
if debug:
print(success, "aclSizeInfo.AceCount: " & $aclSizeInfo.AceCount)
for i in 0 ..< aclSizeInfo.AceCount:
# get an ACE
functionreturn = GetAce(pacl, cast[DWORD](i), addr pTempAce)
if (functionreturn == 0):
print(error,"GetACE failed!" & $GetLastError() )
#return bSuccess
else:
if debug:
print(success, "GetAce fine!")
var asd: PACE_HEADER = cast[PACE_HEADER](addr pTempAce)
echo $cast[DWORD](asd.AceSize)
functionreturn = AddAce(pNewAcl,ACL_REVISION,MAXDWORD,cast[LPVOID](addr pTempAce),cast[DWORD](asd.AceSize))
#pNewAcl = cast[PACL](addr pNewAcl)
if (functionreturn == 0):
print(error,"AddACE failed!" & $GetLastError())
#return bSuccess
else:
if debug:
print(success, "AddAce fine!")
# leave
#if (functionreturn == 0):
# return bSuccess
# add the first ace to the windowstation
pace = cast[PVOID](HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD)))
if (pace == nil):
echo "PACE is null"
return bSuccess
if debug:
print(success, "PACE fine!")
var paceACE: ACCESS_ALLOWED_ACE = cast[ACCESS_ALLOWED_ACE](pace)
paceACE.Header.AceType = ACCESS_ALLOWED_ACE_TYPE
paceACE.Header.AceFlags = CONTAINER_INHERIT_ACE or INHERIT_ONLY_ACE or OBJECT_INHERIT_ACE
paceACE.Header.AceSize = cast[uint16](sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD))
paceACE.Mask = GENERIC_ACCESS
functionreturn = CopySid(GetLengthSid(psid), addr paceACE.SidStart, psid)
if (functionreturn == 0):
echo "CopySid failed"
return bSuccess
if debug:
print(success, "CopySid fine!")
echo $cast[DWORD](paceACE.Header.AceSize)
functionreturn = AddAce(pNewAcl,ACL_REVISION,MAXDWORD,cast[LPVOID](addr pace),cast[DWORD](paceACE.Header.AceSize))
#pNewAcl = cast[PACL](addr pNewAcl)
if (functionreturn == 0):
print(error,"AddAce failed!" & $GetLastError())
return bSuccess
else:
echo "AddACE fine"
if debug:
print(success, "AddAce fine!")
# add the second ACE to the windowstation
paceACE.Header.AceFlags = NO_PROPAGATE_INHERIT_ACE
paceACE.Mask = WINSTA_ALL
functionreturn = AddAce(pNewAcl,ACL_REVISION,MAXDWORD,addr pace,cast[DWORD](paceACE.Header.AceSize))
if (functionreturn == 0):
print(error,"AddAce failed!" & $GetLastError())
return bSuccess
else:
echo "AddACE 2 fine"
if debug:
print(success, "AddAce2 fine!")
# set new dacl for the security descriptor
functionreturn = SetSecurityDescriptorDacl(cast[PSECURITY_DESCRIPTOR](addr psdNew),true,cast[PACL](addr pNewAcl),false)
if (functionreturn == 0):
echo "SetSecurityDescriptorDacl failed"
if debug:
print(success, "SetSecurityDescriptorDacl fine!")
# set the new security descriptor for the windowstation
functionreturn = SetUserObjectSecurity(hwinsta, addr si, addr psdNew)
if (functionreturn == 0):
echo "SetUserObjectSecurity failed"
if debug:
print(success, "SetUserObjectSecurity fine!")
bSuccess = true
# free buffers
if (pNewACL != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](pNewAcl))
if (pace != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](pace))
if (psd != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](psd))
if (psdNew != nil):
HeapFree(GetProcessHeap(), 0, cast[LPVOID](psdNew))
return bSuccess