how to get PSID from TOKEN_INFORMATION_CLASS? - c++

I try to use information from this post: https://stackoverflow.com/a/251267/393087
And the code I came up with is:
HANDLE hToken;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES, &hToken);
DWORD dwSize;
TOKEN_INFORMATION_CLASS tokenInformationClass;
GetTokenInformation(hToken, tokenInformationClass, NULL, sizeof(TOKEN_INFORMATION_CLASS), &dwSize);
Ok, so I got TOKEN_INFORMATION_CLASS, but how to get from this to PSID that ConvertSidToStringSid() needs ? There is nowhere PSID word in tic manual page ( http://msdn.microsoft.com/en-us/library/windows/desktop/aa379626(v=vs.85).aspx ).

Well actually this is trivial. Pick whatever token information class you want (my guess is you want TokenUser) and then make sure you pass the matching TOKEN_USER struct to GetTokenInformation, then reach into the TOKEN_USER struct to access TOKEN_USER::User::Sid to get the PSID.
Of course you may also want another token information class, but the principle is the same. Complete sample program (compiled as .cpp file in MSVC):
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <Sddl.h> // for ConvertSidToStringSid()
BOOL printTokenUserSid(HANDLE hToken)
{
PTOKEN_USER ptu = NULL;
DWORD dwSize = 0;
if(!GetTokenInformation(hToken, TokenUser, NULL, 0, &dwSize)
&& ERROR_INSUFFICIENT_BUFFER != GetLastError())
{
return FALSE;
}
if(NULL != (ptu = (PTOKEN_USER)LocalAlloc(LPTR, dwSize)))
{
LPTSTR StringSid = NULL;
if(!GetTokenInformation(hToken, TokenUser, ptu, dwSize, &dwSize))
{
LocalFree((HLOCAL)ptu);
return FALSE;
}
if(ConvertSidToStringSid(ptu->User.Sid, &StringSid))
{
_tprintf(_T("%s\n"), StringSid);
LocalFree((HLOCAL)StringSid);
LocalFree((HLOCAL)ptu);
return TRUE;
}
LocalFree((HLOCAL)ptu);
}
return FALSE;
}
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hToken = NULL;
if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hToken)
|| OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
if(!printTokenUserSid(hToken))
{
_tprintf(_T("Something failed, Win32 error: %d\n"), GetLastError());
}
CloseHandle(hToken);
}
return 0;
}

Related

Thread doesn't execute the function

I have written two functions which they can kill a process by its name. You can specify the name of a process, and after the execution of the program, that process will kill.
These two functions are working fine, but when I decided to run them via threads, they didn't execute. What is the problem with the following code:
#include <iostream>
#include <string>
#include <tchar.h>
#include <process.h>
#include <windows.h>
#include <tlhelp32.h>
BOOL TerminateMyProcess(DWORD dwProcessId, UINT uExitCode)
{
DWORD dwDesiredAccess = PROCESS_TERMINATE;
BOOL bInheritHandle = FALSE;
HANDLE hProcess = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
if (hProcess == NULL)
return FALSE;
BOOL result = TerminateProcess(hProcess, uExitCode);
CloseHandle(hProcess);
return result;
}
DWORD GetProcessList()
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return(FALSE);
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32))
{
CloseHandle(hProcessSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the snapshot of processes
do
{
std::string str(pe32.szExeFile);
if (str == "notepad.exe") // put the name of your process you want to kill
{
TerminateMyProcess(pe32.th32ProcessID, 1);
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return(TRUE);
}
DWORD WINAPI ThreadingOne(LPVOID arg_param) {
return GetProcessList();
}
auto main(int argc, const char* argv[]) -> decltype(0)
{
DWORD ThreadId;
HANDLE ThreadHandle = CreateThread(NULL, 0, ThreadingOne, (LPVOID)0, CREATE_SUSPENDED, &ThreadId);
ResumeThread(ThreadHandle);
return 0;
}
The thread function didn't start anyway. I didn't know what is the mistake with this threading. I should mention here, I just started multithreading earlier, so it is maybe a simple question but I am a newbie in threads world.

Error code 122 using SetupDiGetDeviceRegistryPropertyW to get the required size

I want to get the Device ID of a USB stick by using the Setup API, but first I am trying to understand some of the functions I have to use. The SetupDiGetDeviceRegistryProperty documentation says I can send NULL to the buffer and buffer size to get the required size, but I am getting the 122 error code, which means:
The data area passed to a system call is too small
Can anyone tell me what am I doing wrong?
Here is my code so far:
#include <Windows.h>
#include <wchar.h>
#include <SetupAPI.h>
#pragma comment(lib, "Setupapi.lib")
int wmain(int argc, wchar_t *arv[])
{
// SetupDiGetClassDevs
HDEVINFO hDeviceInfo;
DWORD filterDevInfo = DIGCF_ALLCLASSES;
hDeviceInfo = SetupDiGetClassDevsW(NULL, NULL, NULL, filterDevInfo);
if (hDeviceInfo != INVALID_HANDLE_VALUE)
{
// SetupDiEnumDeviceInfo
DWORD memberIndex = 0;
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(
hDeviceInfo,
memberIndex,
&devInfoData))
{
fwprintf(stderr, L"Error on enum: %u\n", GetLastError());
return 1;
}
// SetupDiGetDeviceRegistryProperty
DWORD propertyRetrieved = SPDRP_DEVICEDESC;
DWORD requiredSize;
// First call to get the required size for the buffer
if (!SetupDiGetDeviceRegistryPropertyW(
hDeviceInfo,
&devInfoData,
propertyRetrieved,
NULL,
NULL,
0,
&requiredSize))
{
fwprintf(stderr, L"Error on registry property: %u\n", GetLastError());
return 1;
}
}
else
{
wprintf(L"Error code: %u\n", GetLastError());
return 1;
}
return 0;
}

Thread32First returning bogus thread id

Thread32First returns true so I know the function isn't failing. However, it keeps returning the same value for the th32ThreadID data member of THREADENTRY32, 0. Doesn't matter what process I try it on, it continues to be the same thread id: 0.
Here's my code:
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
BOOL EnableDebugPriv(HANDLE proc);
int main()
{
HANDLE hSnapshot;
HANDLE hThread;
THREADENTRY32 thread32;
DWORD dwPid = 15404;
EnableDebugPriv(OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid));
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwPid);
if(hSnapshot == INVALID_HANDLE_VALUE)
{
printf("Error getting snapshot: %lu\n", GetLastError());
return 1;
}
thread32.dwSize = sizeof(THREADENTRY32);
if(!Thread32First(hSnapshot, &thread32))
{
printf("Error thread32first\n");
return 1;
}
printf("Thread Id: %lu\n", thread32.th32ThreadID);
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread32.th32ThreadID);
if(hThread == NULL)
{
printf("Error getting handle: %lu\n", GetLastError());
return 1;
}
return 0;
}
BOOL EnableDebugPriv(HANDLE proc)
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;
// pass our opened process handle
OpenProcessToken(proc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if(AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
{
CloseHandle(hToken);
return TRUE;
}
else
{
MessageBox(NULL,"Bro, you gotta be an admin to set privs like this", "Shit", MB_OK);
CloseHandle(hToken);
return FALSE;
}
}
Note: I am aware that using a static process ID like I am could cause problems. However, I make sure the process is still running with the same process ID. That's not the problem.

How to get the specific windows service executable file path from Visual C++

How can i get the executable file path of a running Windows service from another program when i only know the service name?
Use QueryServiceConfig(). The QUERY_SERVICE_CONFIG::lpBinaryPathName field will report the full command line that is used to run the service.
For example:
struct SCHandle
{
private:
SC_HANDLE hValue;
public:
SCHandle(SC_HANDLE Value) : hValue(Value) {}
~SCHandle() { if (hValue != NULL) CloseServiceHandle(hValue); }
operator SC_HANDLE() { return hValue; }
bool operator!() const { return (hValue == NULL); }
};
std::wstring GetServiceBinaryName(const std::wstring &ServiceName)
{
SCHandle hSCManager(OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT));
if (!hSCManager)
return L"";
SCHandle hService(OpenServiceW(hSCManager, ServiceName.c_str(), SERVICE_QUERY_CONFIG));
if (!hService)
return L"";
std::vector<BYTE> buffer;
DWORD dwBytesNeeded = sizeof(QUERY_SERVICE_CONFIGW);
LPQUERY_SERVICE_CONFIGW pConfig;
do
{
buffer.resize(dwBytesNeeded);
pConfig = (LPQUERY_SERVICE_CONFIGW) &buffer[0];
if (QueryServiceConfigW(hService, pConfig, buffer.size(), &dwBytesNeeded))
return pConfig->lpBinaryPathName;
}
while (GetLastError() == ERROR_INSUFFICIENT_BUFFER);
return L"";
}
#include <Psapi.h>
#include <windows.h>
#pragma comment(lib, "psapi.lib")
int wmain()
{
//insert your service PID here instead of 404
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, 404);
if (!hProcess)
return(0);
wchar_t szBuffer[MAX_PATH];
ZeroMemory(szBuffer, sizeof(szBuffer));
DWORD dwSize = sizeof(szBuffer) / sizeof(szBuffer[0]) - 1;
QueryFullProcessImageName(hProcess, 0, szBuffer, &dwSize);
return(0);
}
You have to start your code with the elevated rights to access system service information. Otherwise OpenProcess will return NULL and GetLastError will return ERROR_ACCESS_DENIED code.
Also you could use:
GetProcessImageFileName to get path in the system native
format;
GetModuleFileNameEx with the NULL module handle.
Update: If you have only service name, then you have to use a different approach:
int wmain()
{
LPQUERY_SERVICE_CONFIG lpsc;
SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, GENERIC_READ);
if (!hSCManager)
return(0);
SC_HANDLE hService = OpenService(hSCManager, L"Browser", SERVICE_QUERY_CONFIG);
if (!hService)
{
CloseServiceHandle(hSCManager);
return(0);
}
DWORD dwBytesNeeded = 0, dwBufSize;
if (!QueryServiceConfig(hService, NULL, 0, &dwBytesNeeded))
{
DWORD dwError = GetLastError();
if (ERROR_INSUFFICIENT_BUFFER == dwError)
{
dwBufSize = dwBytesNeeded;
lpsc = (LPQUERY_SERVICE_CONFIG)HeapAlloc(GetProcessHeap(), 0, dwBufSize);
}
else
{
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return(0);
}
}
if (QueryServiceConfig(hService, lpsc, dwBufSize, &dwBytesNeeded))
{
//lpsc->lpBinaryPathName contains exe path
}
HeapFree(GetProcessHeap(), 0, lpsc);
CloseServiceHandle(hService);
CloseServiceHandle(hSCManager);
return(0);
}

Failing dll injection

I'm in the process of making a security program for my network. One of it's instances is to check and monitor what api's and libraries are called. The dll to do that and the program that go along with it are already finished. But there is a problem that I cant seem to fix.
When trying to inject my dll into system processes (such as explorer.exe, my main test system process) with NtCreateThreadEx I get the return value: C0000022, it means something along the lines of: Status_Access_Denied (it returns in NTSTATUS, but DWORD will do)
I have no idea what to do, I'm running as Administrator, I raised my privileges, and used the proper functions, still I get c0000022
Here's the code I'm using to inject
#include "main.h"
typedef DWORD NTSTATUS;
struct NtCreateThreadExBuffer{
ULONG Size;
ULONG Unknown1;
ULONG Unknown2;
PULONG Unknown3;
ULONG Unknown4;
ULONG Unknown5;
ULONG Unknown6;
PULONG Unknown7;
ULONG Unknown8;
};
typedef NTSTATUS (WINAPI *LPFUN_NtCreateThreadEx)
(
OUT PHANDLE hThread,
IN ACCESS_MASK DesiredAccess,
IN LPVOID ObjectAttributes,
IN HANDLE ProcessHandle,
IN LPTHREAD_START_ROUTINE lpStartAddress,
IN LPVOID lpParameter,
IN BOOL CreateSuspended,
IN ULONG StackZeroBits,
IN ULONG SizeOfStackCommit,
IN ULONG SizeOfStackReserve,
OUT LPVOID lpBytesBuffer
);
using namespace std;
//#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
#define CREATE_THREAD_ACCESS ( PROCESS_ALL_ACCESS )
BOOL LoadDll(char *procName, char *dllName);
BOOL InjectDLL(DWORD dwProcessID, char *dllName);
BOOL LoadDll(char *dllName, DWORD dwProcID){
printf("Process Id to Inject: %d",dwProcID);
if(!dwProcID){
printf("No vailid PID\n");
return false;
}
FILE* FileCheck = fopen(dllName, "r");
if(FileCheck==NULL){
printf("\nUnable to inject %s", dllName);
return false;
}
fclose(FileCheck);
if(!InjectDLL(dwProcID, dllName)){
printf("injection failed\n");
return false;
} else {
return true;
}
}
BOOL InjectDLL(DWORD dwProcessID, char *dllName){
HANDLE hProc;
HANDLE hToken;
char buf[50]={0};
LPVOID RemoteString, LoadLibAddy;
if(!dwProcessID)return false;
HANDLE hCurrentProc = GetCurrentProcess();
if (!OpenProcessToken(hCurrentProc,TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,&hToken)){
printf("OpenProcessToken Error:%d\n", GetLastError());
} else {
if (!RaisePrivleges(hToken, (char*)SE_DEBUG_NAME)){
printf("SetPrivleges SE_DEBUG_NAME Error:%d\n", GetLastError());
}
}
if (hToken)CloseHandle(hToken);
hProc = OpenProcess(CREATE_THREAD_ACCESS, FALSE, dwProcessID);
printf("\nHandle to process: %x\n", hProc);
if(!hProc){
printf("OpenProcess() failed: %d", GetLastError());
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if(!LoadLibAddy){
printf("GetProcAddress() failed: %d", GetLastError());
return false;
}
RemoteString = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(dllName), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
if(RemoteString == NULL){
printf("VirtualAllocEx() failed: %d", GetLastError());
return false;
}
printf("\nRemote address: %x\n", RemoteString);
if(WriteProcessMemory(hProc, (LPVOID)RemoteString, dllName, strlen(dllName), NULL) == NULL){
printf("WriteProcessMemory() failed: %d", GetLastError());
return false;
}
/*
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
printf("CreateRemoteThread() failed: %d", GetLastError());
return false;
}
*/
HMODULE modNtDll = GetModuleHandle("ntdll.dll");
if( !modNtDll )
{
printf("n failed to get module handle for ntdll.dll, Error=0x%.8x", GetLastError());
return 0;
}
LPFUN_NtCreateThreadEx funNtCreateThreadEx =
(LPFUN_NtCreateThreadEx) GetProcAddress(modNtDll, "NtCreateThreadEx");
if( !funNtCreateThreadEx )
{
printf("n failed to get function (NTCreateThreadEx) address from ntdll.dll, Error=0x%.8x\nTrying CreateRemoteThread api\n", GetLastError());
if(!CreateRemoteThread(hProc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL)){
printf("CreateRemoteThread() failed: %d", GetLastError());
return false;
} else {
printf("CreateRemoteThread success!\n");
return true;
}
return 0;
}
NtCreateThreadExBuffer ntbuffer;
memset (&ntbuffer,0,sizeof(NtCreateThreadExBuffer));
DWORD temp1 = 0;
DWORD temp2 = 0;
HANDLE pRemoteThread = NULL;
ntbuffer.Size = sizeof(NtCreateThreadExBuffer);
ntbuffer.Unknown1 = 0x10003;
ntbuffer.Unknown2 = 0x8;
ntbuffer.Unknown3 = &temp2;
ntbuffer.Unknown4 = 0;
ntbuffer.Unknown5 = 0x10004;
ntbuffer.Unknown6 = 4;
ntbuffer.Unknown7 = &temp1;
ntbuffer.Unknown8 = 0;
NTSTATUS status = funNtCreateThreadEx(
&pRemoteThread,
0x1FFFFF,
NULL,
hProc,
(LPTHREAD_START_ROUTINE) LoadLibAddy,
(LPVOID)RemoteString,
FALSE, //start instantly
NULL,
NULL,
NULL,
&ntbuffer
);
printf("NTCreateThreadEx return: %x\n", status);
// Resume the thread execution
WaitForSingleObject(pRemoteThread, INFINITE);
//Check the return code from remote thread function
DWORD dwExitCode;
if( GetExitCodeThread(pRemoteThread, (DWORD*) &dwExitCode) )
{
printf("\n Remote thread returned with status = %d\n", dwExitCode);
}
CloseHandle(pRemoteThread);
CloseHandle(hProc);
return true;
}
BOOL RaisePrivleges( HANDLE hToken, char *pPriv ){
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid.HighPart = 0;
tkp.Privileges[0].Luid.LowPart = 0;
if (!LookupPrivilegeValue(NULL, pPriv, &tkp.Privileges[0].Luid)){
printf("LookupPrivilegeValue Error:%d\n", GetLastError());
return FALSE;
}
int iRet = AdjustTokenPrivileges(hToken, FALSE, &tkp, 0x10, (PTOKEN_PRIVILEGES)NULL, 0);
if (iRet == NULL){
printf( "AdjustTokenPrivileges Error:%d\n", GetLastError());
return TRUE;
} else {
iRet = GetLastError();
switch (iRet){
case ERROR_NOT_ALL_ASSIGNED:
printf("AdjustTokenPrivileges ERROR_NOT_ALL_ASSIGNED\n" );
return FALSE;
case ERROR_SUCCESS:
return TRUE;
default:
printf("AdjustTokenPrivileges Unknow Error:%d\n", iRet);
return FALSE;
}
}
}
1) If you're running on VISTA or later then you're possibly trying to inject into a 'protected process' from a 'non protected process'. See Process Security and Access Rights in MSDN. Non protected processes can't create threads in protected processes; though I must admit I'd expect the call to open process to fail when you request the inappropriate access rights rather than the subsequent create thread call to fail.
2) Why are you using NtCreateThreadEx() rather than simply calling CreateRemoteThread()?
3) This probably isn't the cause of your problem, but... You're failing to allocate memory for the null terminator in the string, you should be allocating strlen(dllName) + 1.
4) I assume that the process that is doing the injecting and the process that you're injecting into are both the same architecture, you're not running an x86 exe on x64 and expecting to inject into an x64 exe?
Since it's hard to find the right answer to this problem, I am posting even though the thread is old.
I was trying to inject into x64 service on Win7 x64 and kept running into same problems. My solution was:
Compile both the injector and injection dll as x64.
Instead of CreateRemoteThread & NtCreateThreadEx (both failing) use RtlCreateUserThread.
You must specify the full path to the injected DLL, otherwise it will not be found.