Initial Commit

This commit is contained in:
paranoidninja
2021-01-30 19:39:51 +05:30
parent cb95c1b5a6
commit e5c0472cc6
12 changed files with 373 additions and 0 deletions
+4
View File
@@ -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
View File
@@ -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;
}
+14
View File
@@ -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
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+97
View File
@@ -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
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
ENTRY(alignstack)
SECTIONS
{
.text :
{
*(.text.alignstack)
*(.text.getprivs)
}
}
+8
View File
@@ -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"
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.