gpt4 book ai didi

c++ - Win32 API : Creating file public for current user but private for everyone else

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:34:47 30 4
gpt4 key购买 nike

我正在使用 Win32 API 在 C 语言中测试以下代码,目的是创建一个新文件,该文件可供当前用户访问,但对其他所有人私有(private)(不可访问)。

为此我拒绝了所有人 SID 的所有权限,然后为当前用户 SID 设置了权限。

文件已成功创建并且权限显然已成功设置(请参见下面的屏幕截图),但是当我尝试使用记事本打开文件时,它显示“访问被拒绝”(我的文件资源管理器正在同一 session 下运行),如果我打开命令提示符并执行“type file_created.txt”,也会出现相同的“访问被拒绝”。

我当然可以手动恢复权限,因为我是管理员,但我的想法是让它以编程方式工作。

具有所有人权限的图像: enter image description here

具有当前用户权限的图像: enter image description here

代码:

#include <windows.h>
#include <AccCtrl.h>
#include <aclapi.h>

#include <stdio.h>
#include <stdexcept>
#include <string>

#undef UNICODE

int GetCurrentUserSid(PSID* pSID)
{
const int MAX_NAME = 256;
DWORD i, dwSize = 0;
HANDLE hToken;
PTOKEN_USER user;
TOKEN_INFORMATION_CLASS TokenClass = TokenUser;

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ | TOKEN_QUERY, &hToken))
return GetLastError();
else
wprintf(L"OpenProcessToken() - got the handle to the access token!\n");

if (!GetTokenInformation(hToken, TokenClass, NULL, 0, &dwSize))
{
DWORD dwResult = GetLastError();
if (dwResult != ERROR_INSUFFICIENT_BUFFER)
{
wprintf(L"GetTokenInformation() failed, error %u\n", dwResult);
return FALSE;
}
else
wprintf(L"GetTokenInformation() - have an ample buffer...\n");
}
else
wprintf(L"GetTokenInformation() - buffer for Token group is OK\n");

user = (PTOKEN_USER)LocalAlloc(GPTR, dwSize);
if (!GetTokenInformation(hToken, TokenClass, user, dwSize, &dwSize))
{
wprintf(L"GetTokenInformation() failed, error %u\n", GetLastError());
return FALSE;
}
else
wprintf(L"GetTokenInformation() for getting the TokenGroups is OK\n");

DWORD dw_sid_len = GetLengthSid(user->User.Sid);
*pSID = (SID*)LocalAlloc(GPTR, dw_sid_len);
CopySid(dw_sid_len, *pSID, user->User.Sid);
return 0;
}

DWORD set_file_security(LPSTR filename)
{
PACL pNewDACL = NULL;
PSID current_user = NULL;
DWORD sid_size = SECURITY_MAX_SID_SIZE;
SID everyone_sid;
DWORD dwRes;
if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) ==
FALSE) {
throw std::runtime_error("CreateWellKnownSid() failed: " +
std::to_string(GetLastError()));
}

GetCurrentUserSid(&current_user);

EXPLICIT_ACCESSA ea[2];
ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESSA));

ea[0].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL;
ea[0].grfAccessMode = GRANT_ACCESS;
ea[0].grfInheritance = NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.ptstrName = reinterpret_cast<char*>(current_user);

ea[1].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL;
ea[1].grfAccessMode = DENY_ACCESS;
ea[1].grfInheritance = NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.ptstrName = reinterpret_cast<char*>(&everyone_sid);

dwRes = SetEntriesInAclA(2, ea, NULL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) {
printf("SetEntriesInAcl Error %u\n", dwRes);
//TODO: goto Cleanup;
}

PSECURITY_DESCRIPTOR pSD = NULL;

// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
_tprintf(_T("LocalAlloc Error %u\n"), GetLastError());
goto Cleanup;
}

if (!InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION))
{
_tprintf(_T("InitializeSecurityDescriptor Error %u\n"),
GetLastError());
goto Cleanup;
}

// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
pNewDACL,
FALSE)) // not a default DACL
{
_tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
GetLastError());
goto Cleanup;
}
SECURITY_ATTRIBUTES sa;
// Initialize a security attributes structure.
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;

HANDLE hFile = CreateFileA(filename, GENERIC_ALL, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
CloseHandle(hFile);

//dwRes = SetNamedSecurityInfoA(filename, SE_FILE_OBJECT,
// DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL);
//if (ERROR_SUCCESS != dwRes) {
// printf("SetNamedSecurityInfo Error %u\n", dwRes);
// //goto Cleanup;
//}

Cleanup:

if (pNewDACL != NULL)
LocalFree((HLOCAL)pNewDACL);

return dwRes;
}

int main()
{
//return 0;

// Create Everyone SID.
DWORD sid_size = SECURITY_MAX_SID_SIZE;
SID everyone_sid;
if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) ==
FALSE) {
throw std::runtime_error("CreateWellKnownSid() failed: " +
std::to_string(GetLastError()));
}

LPSTR filename = "created_file.txt";

set_file_security(filename);

return 0;
}

注意:我意识到代码存在内存泄漏和其他问题,我只是快速进行黑客攻击以测试这个想法。

最佳答案

在 Windows 操作系统中,显式拒绝权限优先于显式允许权限。因此,由于“Everyone”组包含您的帐户,因此即使您为自己启用了该文件,访问该文件也会被拒绝。事实上你完全不需要拒绝规则,如果某些用户的对象ACL中没有设置访问权限,默认情况下访问将被拒绝。

关于c++ - Win32 API : Creating file public for current user but private for everyone else,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40077701/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com