I found this code to get windows write privileges but it does not working - windows

Im trying to create new file on D: drive with c/c++
I found this code to get windows write privileges but it does not working
Can anybody help me i am new in c++?
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable (or disable privilege)
)
{
// Token privilege structure
TOKEN_PRIVILEGES tp;
// Used by local system to identify the privilege
LUID luid;
if(!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
printf("LookupPrivilegeValue() error: %u\n", GetLastError());
return FALSE;
}
else
printf("LookupPrivilegeValue() is OK\n");
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
// Don't forget to disable the privileges after you enabled them,
// or have already completed your task. Don't mess up your system :o)
if(bEnablePrivilege)
{
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
printf("tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED\n");
}
else
{
tp.Privileges[0].Attributes = 0;
printf("tp.Privileges[0].Attributes = 0\n");
}
// Enable the privilege (or disable all privileges).
if(!AdjustTokenPrivileges(
hToken,
FALSE, // If TRUE, function disables all privileges, if FALSE the function modifies privilege based on the tp
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL))
{
printf("AdjustTokenPrivileges() error: %u\n", GetLastError());
return FALSE;
}
else
{
printf("AdjustTokenPrivileges() is OK, last error if any: %u\n", GetLastError());
printf("Should be 0, means the operation completed successfully = ERROR_SUCCESS\n");
}
return TRUE;
}
my Main Function
int main()
{
LPCTSTR lpszPrivilege = L"SeSecurityPrivilege";
// Change this BOOL value to set/unset the SE_PRIVILEGE_ENABLED attribute
BOOL bEnablePrivilege = TRUE;
HANDLE hToken;
// Open a handle to the access token for the calling process. That is this running program
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
printf("OpenProcessToken() error %u\n", GetLastError());
return FALSE;
}
else
printf("OpenProcessToken() is OK\n");
// Call the user defined SetPrivilege() function to enable and set the needed privilege
BOOL test = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);
printf("The SetPrivilege() return value: %d\n\n", test);
ofstream myFile;
myFile.open("C:\\test.txt");
myFile << "I am C";
myFile.close();
bEnablePrivilege = FALSE;
BOOL test1 = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);
printf("The SetPrivilage() return value: %d\n", test1);
system("PAUSE");
return 0;
}
the output in console looks like this:
OpenProcessToken() is OK
LookupPrivilegeValue() is OK
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED
AdjustTokenPrivileges() is OK, last error if any: 1300
Should be 0, means the operation completed successfully = ERROR_SUCCESS
The SetPrivilege() return value: 1
LookupPrivilegeValue() is OK
tp.Privileges[0].Attributes = 0
AdjustTokenPrivileges() is OK, last error if any: 1300
Should be 0, means the operation completed successfully = ERROR_SUCCESS
The SetPrivilage() return value: 1
Press any key to continue . . .

SeSecurityPrivilege is the "Manage auditing and security log" user right (see the list of privilege constants). It has absolutely nothing to do with writing files. In fact, under normal circumstances, you don't need to enable any privilege to write a file to the root of a drive, although the process does need to be running as an administrator.
Error 1300 means "Not all privileges or groups referenced are assigned to the caller." That is, the privilege was not successfully enabled, because the process isn't entitled to it. This will be because the process isn't being run as an administrator.
So, first, you can remove almost all the code in your example, everything but the four lines that actually write the file. Then you just need to run the application as an administrator.
To do this, right-click on the executable file and select "Run as administrator". If you run the application in this way it will be able to write the file. (Note: in Windows XP, you don't need to do this, but you do need to be logged in as a user with administrative rights.)

AdjustTokenPrivileges cannot add or remove privileges from the token. It can only enable existing privileges that are currently disabled or disable existing privileges that are currently enabled.
ERROR 1300 means that you are not already have "SeSecurityPrivilege".So you can't enable or disable it.
For more information check:
Changing Privileges in a Token

Related

anyone using IXCLRDataProcess, GetRuntimeNameByAddress and ICLRDataTarget to get managed symbol?

the purpose is to get a mixed callstack. For managed symbol, I use IXCLRDATAProcess / GetRuntimeNameByAddress to resolve the corresponding managed callstack. I modify this project to get self-mixed callstack, it works on X86, but it failed on X64. after debugging, I find the issue is located in IXCLRDATAProcess. Our project is located in this.
this is my way to use IXCLRDATAProcess:
HANDLE processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
void** iface;
BOOL isWow64 = FALSE;
if (processHandle == NULL)
return NULL;
BOOLEAN result = IsWow64Process(processHandle, &isWow64);
DiagCLRDataTarget* dataTarget = new DiagCLRDataTarget(ProcessId, processHandle, isWow64, debugNative); //new DnCLRDataTarget;
ICLRDataTarget* target = static_cast<ICLRDataTarget*>(dataTarget);
HMODULE accessDll = LoadLibraryW(L"C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\mscordacwks.dll");
PFN_CLRDataCreateInstance entry = (PFN_CLRDataCreateInstance)GetProcAddress(accessDll, "CLRDataCreateInstance");
hr = entry(__uuidof(IXCLRDataProcess), target, (void**)&ifacePtr); // error
if (FAILED(hr)) {
std::cout << "error: " << GetLastError() << std::endl; // where we get error: 203:230 (0xE6) The pipe state is invalid.
*iface = ifacePtr;
}
m_clrDataProcess = static_cast<IXCLRDataProcess*>(iface);
then I use m_clrDataProcess to resolve the symbol, that is
hr = m_clrDataProcess->GetRuntimeNameByAddress(clrAddr, 0, maxSize - 1, &nameLen, buffer, &displacement);
due to the m_clrDataProcess being null, we can't resolve symbol from the frame address. Does anyone use these API or does anyone have some advice?

How to get the SID of the current machine?

I know how to get the SID for the current user. Conceptually the answer is:
Use OpenThreadToken (or OpenProcessToken) to get the security TOKEN of the running user
use GetTokenInformation to get the TOKEN_USER structure
and then TOKEN_USER.Sid is the Sid
So in pseudocode:
String GetCurrentUserSid()
{
// Get the calling thread's access token.
TOKEN hToken;
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, true, out hToken)
{
if (GetLastError() != ERROR_NO_TOKEN)
RaiseLastWin32Error();
// No thread token exists, try again against the process token
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, out hToken)
RaiseLastWin32Error();
}
try
{
// Obtain the size of the user information in the token.
DWORD cbReturned;
GetTokenInformation(hToken, TokenUser, nil, 0, out cbReturned);
//Allocate memory and try again for real
TOKEN_USER* tiUser = GetMemory(cbReturned);
if (!GetTokenInformation(hToken, TokenUser, tiUser, cbReturned, out cbReturned))
RaiseLastWin32Error();
}
finally
{
CloseHandle(hToken);
}
//Convert the structure to a string
return SidToString(tiUser.User.Sid);
}
But how to do it for the current machine?
String GetCurrentMachineSid()
{
// TODO: Ask Stackoverflow
}
Bonus Reading
The Machine SID Duplication Myth (and Why Sysprep Matters) 🕗
Machine SIDs and Domain SIDs 🕗
How to find SID of computer 🕗
You can see the machine SID on your computer by running Sysinternals
PsGetSid with no parameters
so i simply look under debugger how PsGetSid do this.
it get SID from POLICY_ACCOUNT_DOMAIN_INFO - DomainSid : Pointer to the SID of the account domain
code can be next
LSA_HANDLE PolicyHandle;
LSA_OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(ObjectAttributes) };
NTSTATUS status = LsaOpenPolicy(0, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
if (0 <= status)
{
POLICY_ACCOUNT_DOMAIN_INFO* ppadi;
status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi);
if (0 <= status)
{
PWSTR szSid;
BOOL b = ConvertSidToStringSidW(ppadi->DomainSid, &szSid);
LsaFreeMemory(ppadi);
if (b)
{
DbgPrint("%S\n", szSid);
LocalFree(szSid);
}
}
LsaClose(PolicyHandle);
}

"FltStartFiltering has not been called" Error of trying to attach a volume in DriverEntry

I have tried to attach a volume while the driver service starts, but I got "The filter is not ready for attachment to volumes because it has not finished initialize (FltStartFiltering has not been called)." and immediately I got blue screen. I have already called the FltStartFiltering but I don't know why it didn't work.
Below is my code:
status = FltRegisterFilter(DriverObject,
&FilterRegistration,
&MiniSpyData.Filter);
if (!NT_SUCCESS(status)) {
leave;
}
status = FltBuildDefaultSecurityDescriptor(&sd,
FLT_PORT_ALL_ACCESS);
if (!NT_SUCCESS(status)) {
leave;
}
RtlInitUnicodeString(&uniString, WOODY_PORT_NAME);
InitializeObjectAttributes(&oa,
&uniString,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,
sd);
status = FltCreateCommunicationPort(MiniSpyData.Filter,
&MiniSpyData.ServerPort,
&oa,
NULL,
SpyConnect,
SpyDisconnect,
SpyMessage,
1);
FltFreeSecurityDescriptor(sd);
if (!NT_SUCCESS(status)) {
leave;
}
//
// We are now ready to start filtering
//
status = FltStartFiltering(MiniSpyData.Filter);
if (!NT_SUCCESS(status)) {
FltUnregisterFilter(MiniSpyData.Filter);
}
else {
//Here is what I want to attach
RtlInitUnicodeString(&uniString, L"\\Device\\HarddiskVolume1");
PFLT_VOLUME vol;
FltGetVolumeFromName(&MiniSpyData.Filter, &uniString, &vol);
status = FltAttachVolume(&MiniSpyData.Filter, vol, NULL, NULL);
}
RtlInitUnicodeString(&uniString, L"\\Device\\HarddiskVolume1");
PFLT_VOLUME vol;
FltGetVolumeFromName(&MiniSpyData.Filter, &uniString, &vol);
status = FltAttachVolume(&MiniSpyData.Filter, vol, NULL, NULL);
The part above is simply not needed and wrong as well.
Let me explain:
The FltGetVolumeFromName routine take a PFLT_FILTER as the first parameter and from what I see in your code you are giving it a PFLT_FILTER*
You don't need to manually attach to volumes since you will automatically attach and be called in your instance context unless you set the FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT in your instance context registration flags. See this for more details.
You don't want to do this during boot because the volume might not be there yet and thus your potential BSOD.
Good luck.

How I can query logon type of the running process?

I want at least to distinguish cases when my software is being ran as batch job (LOGON32_LOGON_BATCH) from being ran interactively (LOGON32_LOGON_INTERACTIVE).
HANDLE hToken;
// Open the current process's token
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
// Get the token statistics, which include the logon session id
TOKEN_STATISTICS stats;
DWORD length;
if (GetTokenInformation(hToken, TokenStatistics, &stats, sizeof(stats), &length))
{
// Get data about the logon session, which includes the logon type
PSECURITY_LOGON_SESSION_DATA pData;
if (LsaGetLogonSessionData(&stats.AuthenticationId, &pData) == 0)
{
// From SECURITY_LOGON_TYPE enumeration
switch (pData->LogonType)
{
case Interactive:
wprintf(L"Interactive\n");
break;
case Batch:
wprintf(L"Batch\n");
break;
default:
wprintf(L"Other: %i\n", pData->LogonType);
break;
}
LsaFreeReturnBuffer(pData);
}
}
CloseHandle(hToken);
}

Get windows session's user name in c++

I am trying to understand better how Windows sessions (TS sessions and log on sessions) works (currently in XP), so maybe my whole question or what I am trying to do is impossible.
I am running a Windows service (in XP), which runs in session 0, and I am trying to get the username attached to this session using WTSQueryUserToken().
Now, in session 0 there are several usernames: SYSTEM, theuser (logged on user),NETWORK SERVICE, LOCAL SERVICE.
When I use WTSQueryUserToken() I get "theuser" (which is the Active session), but I am trying to get the username of my service (which is SYSTEM).
Is that possible or did I simply get it all wrong?
I use the following code to get user token for my process
HANDLE GetProcessOwnerToken(DWORD pid)
{
if (!pid) return NULL;
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) return NULL;
HANDLE hToken = NULL;
if(OpenProcessToken(hProcess, MAXIMUM_ALLOWED, &hToken))
{
HANDLE result = INVALID_HANDLE_VALUE;
if(DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &result))
{
if(result != INVALID_HANDLE_VALUE)
{
CloseHandle(hToken);
CloseHandle(hProcess);
return result;
}
}
CloseHandle(hToken);
}
CloseHandle(hProcess);
return NULL;
}
I have no idea if it works for services as well, I think it should.

Resources