mirror of
https://github.com/paranoidninja/PIC-Get-Privileges
synced 2026-06-08 16:38:12 +00:00
Initial Commit
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
make:
|
||||
nasm -f win64 adjuststack.asm -o adjuststack.o
|
||||
x86_64-w64-mingw32-gcc getprivs.c -Wall -m64 -ffunction-sections -fno-asynchronous-unwind-tables -nostdlib -fno-ident -O2 -c -o getprivs.o -Wl,-Tlinker.ld,--no-seh
|
||||
x86_64-w64-mingw32-ld -s adjuststack.o getprivs.o -o getprivs.exe
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
#include <windows.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#define DEREF( name )*(UINT_PTR *)(name)
|
||||
#define DEREF_64( name )*(DWORD64 *)(name)
|
||||
#define DEREF_32( name )*(DWORD *)(name)
|
||||
#define DEREF_16( name )*(WORD *)(name)
|
||||
#define DEREF_8( name )*(BYTE *)(name)
|
||||
|
||||
#define KERNEL32DLL_HASH 0x6A4ABC5B
|
||||
|
||||
//redefine UNICODE_STR struct
|
||||
typedef struct _UNICODE_STR
|
||||
{
|
||||
USHORT Length;
|
||||
USHORT MaximumLength;
|
||||
PWSTR pBuffer;
|
||||
} UNICODE_STR, *PUNICODE_STR;
|
||||
|
||||
//redefine PEB_LDR_DATA struct
|
||||
typedef struct _PEB_LDR_DATA
|
||||
{
|
||||
DWORD dwLength;
|
||||
DWORD dwInitialized;
|
||||
LPVOID lpSsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
LPVOID lpEntryInProgress;
|
||||
} PEB_LDR_DATA, * PPEB_LDR_DATA;
|
||||
|
||||
//redefine LDR_DATA_TABLE_ENTRY struct
|
||||
typedef struct _LDR_DATA_TABLE_ENTRY
|
||||
{
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
PVOID DllBase;
|
||||
PVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STR FullDllName;
|
||||
UNICODE_STR BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
LIST_ENTRY HashTableEntry;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
|
||||
|
||||
//redefine PEB_FREE_BLOCK struct
|
||||
typedef struct _PEB_FREE_BLOCK
|
||||
{
|
||||
struct _PEB_FREE_BLOCK * pNext;
|
||||
DWORD dwSize;
|
||||
} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK;
|
||||
|
||||
//redefine PEB struct
|
||||
typedef struct __PEB
|
||||
{
|
||||
BYTE bInheritedAddressSpace;
|
||||
BYTE bReadImageFileExecOptions;
|
||||
BYTE bBeingDebugged;
|
||||
BYTE bSpareBool;
|
||||
LPVOID lpMutant;
|
||||
LPVOID lpImageBaseAddress;
|
||||
PPEB_LDR_DATA pLdr;
|
||||
LPVOID lpProcessParameters;
|
||||
LPVOID lpSubSystemData;
|
||||
LPVOID lpProcessHeap;
|
||||
PRTL_CRITICAL_SECTION pFastPebLock;
|
||||
LPVOID lpFastPebLockRoutine;
|
||||
LPVOID lpFastPebUnlockRoutine;
|
||||
DWORD dwEnvironmentUpdateCount;
|
||||
LPVOID lpKernelCallbackTable;
|
||||
DWORD dwSystemReserved;
|
||||
DWORD dwAtlThunkSListPtr32;
|
||||
PPEB_FREE_BLOCK pFreeList;
|
||||
DWORD dwTlsExpansionCounter;
|
||||
LPVOID lpTlsBitmap;
|
||||
DWORD dwTlsBitmapBits[2];
|
||||
LPVOID lpReadOnlySharedMemoryBase;
|
||||
LPVOID lpReadOnlySharedMemoryHeap;
|
||||
LPVOID lpReadOnlyStaticServerData;
|
||||
LPVOID lpAnsiCodePageData;
|
||||
LPVOID lpOemCodePageData;
|
||||
LPVOID lpUnicodeCaseTableData;
|
||||
DWORD dwNumberOfProcessors;
|
||||
DWORD dwNtGlobalFlag;
|
||||
LARGE_INTEGER liCriticalSectionTimeout;
|
||||
DWORD dwHeapSegmentReserve;
|
||||
DWORD dwHeapSegmentCommit;
|
||||
DWORD dwHeapDeCommitTotalFreeThreshold;
|
||||
DWORD dwHeapDeCommitFreeBlockThreshold;
|
||||
DWORD dwNumberOfHeaps;
|
||||
DWORD dwMaximumNumberOfHeaps;
|
||||
LPVOID lpProcessHeaps;
|
||||
LPVOID lpGdiSharedHandleTable;
|
||||
LPVOID lpProcessStarterHelper;
|
||||
DWORD dwGdiDCAttributeList;
|
||||
LPVOID lpLoaderLock;
|
||||
DWORD dwOSMajorVersion;
|
||||
DWORD dwOSMinorVersion;
|
||||
WORD wOSBuildNumber;
|
||||
WORD wOSCSDVersion;
|
||||
DWORD dwOSPlatformId;
|
||||
DWORD dwImageSubsystem;
|
||||
DWORD dwImageSubsystemMajorVersion;
|
||||
DWORD dwImageSubsystemMinorVersion;
|
||||
DWORD dwImageProcessAffinityMask;
|
||||
DWORD dwGdiHandleBuffer[34];
|
||||
LPVOID lpPostProcessInitRoutine;
|
||||
LPVOID lpTlsExpansionBitmap;
|
||||
DWORD dwTlsExpansionBitmapBits[32];
|
||||
DWORD dwSessionId;
|
||||
ULARGE_INTEGER liAppCompatFlags;
|
||||
ULARGE_INTEGER liAppCompatFlagsUser;
|
||||
LPVOID lppShimData;
|
||||
LPVOID lpAppCompatInfo;
|
||||
UNICODE_STR usCSDVersion;
|
||||
LPVOID lpActivationContextData;
|
||||
LPVOID lpProcessAssemblyStorageMap;
|
||||
LPVOID lpSystemDefaultActivationContextData;
|
||||
LPVOID lpSystemAssemblyStorageMap;
|
||||
DWORD dwMinimumStackCommit;
|
||||
} _PEB, * _PPEB;
|
||||
|
||||
// main hashing function for ror13
|
||||
__forceinline DWORD ror13( DWORD d )
|
||||
{
|
||||
return _rotr( d, 13 );
|
||||
}
|
||||
|
||||
__forceinline DWORD hash( char * c )
|
||||
{
|
||||
register DWORD h = 0;
|
||||
do
|
||||
{
|
||||
h = ror13( h );
|
||||
h += *c;
|
||||
} while( *++c );
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
// function to fetch the base address of kernel32.dll from the Process Environment Block
|
||||
UINT64 GetKernel32() {
|
||||
ULONG_PTR kernel32dll, val1, val2, val3;
|
||||
USHORT usCounter;
|
||||
|
||||
// kernel32.dll is at 0x60 offset and __readgsqword is compiler intrinsic,
|
||||
// so we don't need to extract it's symbol
|
||||
kernel32dll = __readgsqword( 0x60 );
|
||||
|
||||
kernel32dll = (ULONG_PTR)((_PPEB)kernel32dll)->pLdr;
|
||||
val1 = (ULONG_PTR)((PPEB_LDR_DATA)kernel32dll)->InMemoryOrderModuleList.Flink;
|
||||
while( val1 ) {
|
||||
val2 = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)val1)->BaseDllName.pBuffer;
|
||||
usCounter = ((PLDR_DATA_TABLE_ENTRY)val1)->BaseDllName.Length;
|
||||
val3 = 0;
|
||||
|
||||
//calculate the hash of kernel32.dll
|
||||
do {
|
||||
val3 = ror13( (DWORD)val3 );
|
||||
if( *((BYTE *)val2) >= 'a' )
|
||||
val3 += *((BYTE *)val2) - 0x20;
|
||||
else
|
||||
val3 += *((BYTE *)val2);
|
||||
val2++;
|
||||
} while( --usCounter );
|
||||
|
||||
// compare the hash kernel32.dll
|
||||
if( (DWORD)val3 == KERNEL32DLL_HASH ) {
|
||||
//return kernel32.dll if found
|
||||
kernel32dll = (ULONG_PTR)((PLDR_DATA_TABLE_ENTRY)val1)->DllBase;
|
||||
return kernel32dll;
|
||||
}
|
||||
val1 = DEREF( val1 );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// custom strcmp function since this function will be called by GetSymbolAddress
|
||||
// which means we have to call strcmp before loading msvcrt.dll
|
||||
// so we are writing our own my_strcmp so that we don't have to play with egg or chicken dilemma
|
||||
int my_strcmp (const char *p1, const char *p2) {
|
||||
const unsigned char *s1 = (const unsigned char *) p1;
|
||||
const unsigned char *s2 = (const unsigned char *) p2;
|
||||
unsigned char c1, c2;
|
||||
do {
|
||||
c1 = (unsigned char) *s1++;
|
||||
c2 = (unsigned char) *s2++;
|
||||
if (c1 == '\0') {
|
||||
return c1 - c2;
|
||||
}
|
||||
}
|
||||
while (c1 == c2);
|
||||
return c1 - c2;
|
||||
}
|
||||
|
||||
UINT64 GetSymbolAddress( HANDLE hModule, LPCSTR lpProcName ) {
|
||||
UINT64 dllAddress = (UINT64)hModule,
|
||||
symbolAddress = 0,
|
||||
exportedAddressTable = 0,
|
||||
namePointerTable = 0,
|
||||
ordinalTable = 0;
|
||||
|
||||
if( hModule == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIMAGE_NT_HEADERS ntHeaders = NULL;
|
||||
PIMAGE_DATA_DIRECTORY dataDirectory = NULL;
|
||||
PIMAGE_EXPORT_DIRECTORY exportDirectory = NULL;
|
||||
|
||||
ntHeaders = (PIMAGE_NT_HEADERS)(dllAddress + ((PIMAGE_DOS_HEADER)dllAddress)->e_lfanew);
|
||||
dataDirectory = (PIMAGE_DATA_DIRECTORY)&ntHeaders->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT ];
|
||||
exportDirectory = (PIMAGE_EXPORT_DIRECTORY)( dllAddress + dataDirectory->VirtualAddress );
|
||||
|
||||
exportedAddressTable = ( dllAddress + exportDirectory->AddressOfFunctions );
|
||||
namePointerTable = ( dllAddress + exportDirectory->AddressOfNames );
|
||||
ordinalTable = ( dllAddress + exportDirectory->AddressOfNameOrdinals );
|
||||
|
||||
if (((UINT64)lpProcName & 0xFFFF0000 ) == 0x00000000) {
|
||||
exportedAddressTable += ( ( IMAGE_ORDINAL( (UINT64)lpProcName ) - exportDirectory->Base ) * sizeof(DWORD) );
|
||||
symbolAddress = (UINT64)( dllAddress + DEREF_32(exportedAddressTable) );
|
||||
}
|
||||
else {
|
||||
DWORD dwCounter = exportDirectory->NumberOfNames;
|
||||
while( dwCounter-- ) {
|
||||
char * cpExportedFunctionName = (char *)(dllAddress + DEREF_32( namePointerTable ));
|
||||
if( my_strcmp( cpExportedFunctionName, lpProcName ) == 0 ) {
|
||||
exportedAddressTable += ( DEREF_16( ordinalTable ) * sizeof(DWORD) );
|
||||
symbolAddress = (UINT64)(dllAddress + DEREF_32( exportedAddressTable ));
|
||||
break;
|
||||
}
|
||||
namePointerTable += sizeof(DWORD);
|
||||
ordinalTable += sizeof(WORD);
|
||||
}
|
||||
}
|
||||
|
||||
return symbolAddress;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
extern getprivs
|
||||
global alignstack
|
||||
|
||||
segment .text
|
||||
|
||||
alignstack:
|
||||
push rdi ; backup rdi since we will be using this as our main register
|
||||
mov rdi, rsp ; save stack pointer to rdi
|
||||
and rsp, byte -0x10 ; align stack with 16 bytes
|
||||
sub rsp, byte +0x20 ; allocate some space for our C function
|
||||
call getprivs ; call the C function
|
||||
mov rsp, rdi ; restore stack pointer
|
||||
pop rdi ; restore rdi
|
||||
ret ; return where we left
|
||||
Binary file not shown.
Binary file not shown.
+97
@@ -0,0 +1,97 @@
|
||||
#include "addresshunter.h"
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
// kernel32.dll exports
|
||||
typedef HMODULE(WINAPI* LOADLIBRARYA)(LPCSTR);
|
||||
typedef BOOL(WINAPI* CLOSEHANDLE)(HANDLE);
|
||||
typedef HANDLE(WINAPI* GETCURRENTPROCESS)();
|
||||
|
||||
// advapi32.dll exports
|
||||
typedef BOOL(WINAPI* OPENPROCESSTOKEN)(HANDLE, DWORD, PHANDLE);
|
||||
typedef BOOL(WINAPI* GETTOKENINFORMATION)(HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD);
|
||||
typedef BOOL(WINAPI* LOOKUPPRIVILEGENAMEW)(LPCWSTR, PLUID, LPWSTR, LPDWORD);
|
||||
|
||||
// msvcrt.dll exports
|
||||
typedef int(WINAPI* WPRINTF)(const wchar_t* format, ...);
|
||||
typedef void*(WINAPI* CALLOC)(size_t num, size_t size);
|
||||
|
||||
void getprivs() {
|
||||
//dlls to dynamically load during runtime
|
||||
UINT64 kernel32dll, msvcrtdll, advapi32dll;
|
||||
//symbols to dynamically resolve from dll during runtime
|
||||
UINT64 LoadLibraryAFunc, CloseHandleFunc,
|
||||
OpenProcessTokenFunc, GetCurrentProcessFunc, GetTokenInformationFunc, LookupPrivilegeNameWFunc,
|
||||
callocFunc, wprintfFunc;
|
||||
|
||||
// kernel32.dll exports
|
||||
kernel32dll = GetKernel32();
|
||||
|
||||
CHAR loadlibrarya_c[] = {'L', 'o', 'a', 'd', 'L', 'i', 'b', 'r', 'a', 'r', 'y', 'A', 0};
|
||||
LoadLibraryAFunc = GetSymbolAddress((HANDLE)kernel32dll, loadlibrarya_c);
|
||||
|
||||
CHAR getcurrentprocess_c[] = {'G', 'e', 't', 'C', 'u', 'r', 'r', 'e', 'n', 't', 'P', 'r', 'o', 'c', 'e', 's', 's', 0};
|
||||
GetCurrentProcessFunc = GetSymbolAddress((HANDLE)kernel32dll, getcurrentprocess_c);
|
||||
|
||||
CHAR closehandle_c[] = {'C', 'l', 'o', 's', 'e', 'H', 'a', 'n', 'd', 'l', 'e', 0};
|
||||
CloseHandleFunc = GetSymbolAddress((HANDLE)kernel32dll, closehandle_c);
|
||||
|
||||
// advapi32.dll exports
|
||||
CHAR advapi32_c[] = {'a', 'd', 'v', 'a', 'p', 'i', '3', '2', '.', 'd', 'l', 'l', 0};
|
||||
advapi32dll = (UINT64) ((LOADLIBRARYA)LoadLibraryAFunc)(advapi32_c);
|
||||
CHAR openprocesstoken_c[] = {'O', 'p', 'e', 'n', 'P', 'r', 'o', 'c', 'e', 's', 's', 'T', 'o', 'k', 'e', 'n', 0};
|
||||
OpenProcessTokenFunc = GetSymbolAddress((HANDLE)advapi32dll, openprocesstoken_c);
|
||||
CHAR gettokeninformation_c[] = { 'G', 'e', 't', 'T', 'o', 'k', 'e', 'n', 'I', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', 0 };
|
||||
GetTokenInformationFunc = GetSymbolAddress((HANDLE)advapi32dll, gettokeninformation_c);
|
||||
CHAR lookupprivilegenamew_c[] = {'L', 'o', 'o', 'k', 'u', 'p', 'P', 'r', 'i', 'v', 'i', 'l', 'e', 'g', 'e', 'N', 'a', 'm', 'e', 'W', 0};
|
||||
LookupPrivilegeNameWFunc = GetSymbolAddress((HANDLE)advapi32dll, lookupprivilegenamew_c);
|
||||
|
||||
// msvcrt.dll exports
|
||||
CHAR msvcrt_c[] = {'m', 's', 'v', 'c', 'r', 't', '.', 'd', 'l', 'l', 0};
|
||||
msvcrtdll = (UINT64) ((LOADLIBRARYA)LoadLibraryAFunc)(msvcrt_c);
|
||||
CHAR calloc_c[] = {'c', 'a', 'l', 'l', 'o', 'c', 0};
|
||||
callocFunc = GetSymbolAddress((HANDLE)msvcrtdll, calloc_c);
|
||||
CHAR wprintf_c[] = {'w', 'p', 'r', 'i', 'n', 't', 'f', 0};
|
||||
wprintfFunc = GetSymbolAddress((HANDLE)msvcrtdll, wprintf_c);
|
||||
|
||||
DWORD cbSize = sizeof(TOKEN_ELEVATION), tpSize, length;
|
||||
HANDLE hToken = NULL;
|
||||
TOKEN_ELEVATION Elevation;
|
||||
PTOKEN_PRIVILEGES tPrivs = NULL;
|
||||
WCHAR name[256];
|
||||
WCHAR priv_enabled[] = { L'[', L'+', L']', L' ', L'%', L'-', L'5', L'0', L'l', L's', L' ', L'E', L'n', L'a', L'b', L'l', L'e', L'd', L' ', L'(', L'D', L'e', L'f', L'a', L'u', L'l', L't', L')', L'\n', 0 };
|
||||
WCHAR priv_adjusted[] = { L'[', L'+', L']', L' ', L'%', L'-', L'5', L'0', L'l', L's', L' ', L'E', L'n', L'a', L'b', L'l', L'e', L'd', L' ', L'(', L'D', L'e', L'f', L'a', L'u', L'l', L't', L')', L'\n', 0 };
|
||||
WCHAR priv_disabled[] = { L'[', L'+', L']', L' ', L'%', L'-', L'5', L'0', L'l', L's', L' ', L'E', L'n', L'a', L'b', L'l', L'e', L'd', L' ', L'(', L'D', L'e', L'f', L'a', L'u', L'l', L't', L')', L'\n', 0 };
|
||||
WCHAR priv_elevated[] = {L'[', L'+', L']', L' ', L'E', L'l', L'e', L'v', L'a', L't', L'e', L'd', 0};
|
||||
WCHAR priv_restricted[] = {L'[', L'+', L']', L' ', L'R', L'e', L's', L't', L'r', L'i', L'c', L't', L'e', L'd', 0};
|
||||
|
||||
if (((OPENPROCESSTOKEN)OpenProcessTokenFunc)(((GETCURRENTPROCESS)GetCurrentProcessFunc)(), TOKEN_QUERY, &hToken)) {
|
||||
((GETTOKENINFORMATION)GetTokenInformationFunc)(hToken, TokenPrivileges, tPrivs, 0, &tpSize);
|
||||
tPrivs = (PTOKEN_PRIVILEGES)((CALLOC)callocFunc)(tpSize+1, sizeof(TOKEN_PRIVILEGES));
|
||||
|
||||
if (tPrivs) {
|
||||
if (((GETTOKENINFORMATION)GetTokenInformationFunc)(hToken, TokenPrivileges, tPrivs, tpSize, &tpSize)) {
|
||||
for(int i=0; i<tPrivs->PrivilegeCount; i++){
|
||||
length=256;
|
||||
((LOOKUPPRIVILEGENAMEW)LookupPrivilegeNameWFunc)(NULL, &tPrivs->Privileges[i].Luid, name, &length);
|
||||
if (tPrivs->Privileges[i].Attributes == 3) {
|
||||
((WPRINTF)wprintfFunc)(priv_enabled, name);
|
||||
} else if (tPrivs->Privileges[i].Attributes == 2) {
|
||||
((WPRINTF)wprintfFunc)(priv_adjusted, name);
|
||||
} else if (tPrivs->Privileges[i].Attributes == 0) {
|
||||
((WPRINTF)wprintfFunc)(priv_disabled, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((GETTOKENINFORMATION)GetTokenInformationFunc)(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
|
||||
if (Elevation.TokenIsElevated) {
|
||||
((WPRINTF)wprintfFunc)(priv_elevated);
|
||||
} else {
|
||||
((WPRINTF)wprintfFunc)(priv_restricted);
|
||||
}
|
||||
}
|
||||
((CLOSEHANDLE)CloseHandleFunc)(hToken);
|
||||
}
|
||||
}
|
||||
Executable
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,9 @@
|
||||
ENTRY(alignstack)
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
*(.text.alignstack)
|
||||
*(.text.getprivs)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
; compile with
|
||||
; nasm -f win64 runshellcode.asm -o runshellcode.o
|
||||
; x86_64-w64-mingw32-ld runshellcode.o -o runshellcode.exe
|
||||
|
||||
Global Start
|
||||
|
||||
Start:
|
||||
incbin "getprivs.bin"
|
||||
Executable
BIN
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user