bla*_*d0t 6 windows winapi named-pipes
我在创建NamedPipe时遇到了设置安全描述符的问题.我希望从中等和低完整性过程打开在Windows服务中创建的管道(高完整性).
我正在使用Windows 7 x64.我不太明白我在这里做什么,但这里是我用来为我创建的管道创建安全描述符的代码.以下代码不允许我打开从低完整性过程中创建的高中和中等完整性管道:
PSID psidWorldSid = NULL, pAdminSID = NULL, pLowSID = NULL, pHighSID = NULL;
WCHAR wszIntegritySid[] = L"S-1-16-4096";
WCHAR wszSystemSid[] = L"S-1-16-16384";
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
SECURITY_ATTRIBUTES sa;
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority = SECURITY_WORLD_SID_AUTHORITY;
EXPLICIT_ACCESS ea[4];
// Create a security descriptor for the log file that allows
// access from both the privileged service and the non-privileged
// user mode programs
AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&psidWorldSid);
ZeroMemory(&ea, sizeof(ea));
ea[0].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) psidWorldSid;
// Create a SID for the BUILTIN\Administrators group.
AllocateAndInitializeSid(&SIDAuthNT, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
&pAdminSID);
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow the Administrators group full access to
// the key.
ea[1].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
ea[1].grfAccessMode = SET_ACCESS;
ea[1].grfInheritance= NO_INHERITANCE;
ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
ea[1].Trustee.ptstrName = (LPTSTR) pAdminSID;
AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
SECURITY_MANDATORY_LOW_RID,
0,
0, 0, 0, 0, 0, 0,
&pLowSID);
ea[2].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
ea[2].grfAccessMode = SET_ACCESS;
ea[2].grfInheritance= NO_INHERITANCE;
ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[2].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[2].Trustee.ptstrName = (LPTSTR) pLowSID;
AllocateAndInitializeSid(&siaWorldSidAuthority, 1,
SECURITY_MANDATORY_HIGH_RID,
0,
0, 0, 0, 0, 0, 0,
&pHighSID);
ea[3].grfAccessPermissions = FILE_ALL_ACCESS | GENERIC_WRITE | GENERIC_READ;
ea[3].grfAccessMode = SET_ACCESS;
ea[3].grfInheritance= NO_INHERITANCE;
ea[3].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[3].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[3].Trustee.ptstrName = (LPTSTR) pHighSID;
SetEntriesInAcl(4, ea, NULL, &pACL);
pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl( pSD, TRUE, pACL, FALSE );
ZeroMemory( &sa, sizeof(SECURITY_ATTRIBUTES));
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
m_hPipe = CreateNamedPipeA(
m_szName.c_str(),
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | BlockFlag,
PIPE_UNLIMITED_INSTANCES,
BUFFER_SIZE,
BUFFER_SIZE,
NMPWAIT_USE_DEFAULT_WAIT,
&sa
);
if (psidWorldSid)
FreeSid(psidWorldSid);
if (pAdminSID)
FreeSid(pAdminSID);
if (pLowSID)
FreeSid(pLowSID);
if (pHighSID)
FreeSid(pHighSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
Run Code Online (Sandbox Code Playgroud)
当我从字符串创建安全描述符时,它似乎工作得很好:
ConvertStringSecurityDescriptorToSecurityDescriptorW( L"S:(ML;;NW;;;LW)", SDDL_REVISION_1, &pSD, NULL);
当我从上面的字符串创建安全描述符时,我至少可以打开使用低完整性进程的中等完整性权限创建的管道.
谢谢你的任何建议.
此致,库巴
您显示的代码似乎是创建安全描述符并设置其自由访问控制列表(DACL).DACL与完整性控制机制完全没有任何关系.
为了使低完整性进程打开一个句柄,通过该句柄写入命名管道,命名管道对象需要在其强制完整性标签中标记为低完整性.此标签位于系统访问控制列表(SACL)中,而不是DACL中.这就是S:(...前缀在您用于创建SD via的安全描述符的SDDL字符串表示中的含义ConvertStringSecurityDescriptorToSecurityDescriptorW.
如果要在不从SDDL表示开始的情况下长期执行此操作,则必须创建正确类型的ACE SYSTEM_MANDATORY_LABEL_ACE,使用低完整性的SID(S-1-16-4096)和适当的完整性策略进行初始化(例如SYSTEM_MANDATORY_LABEL_NO_WRITE_UP),然后将其放入SACL中SetSecurityDescriptorSacl.
我能够解决问题.正如克里斯所指出的那样,管道是使用低完整性权限正确创建的,尽管我错过了我为用户提供的部分.
我通过设置SDDL来解决这个问题:S:(ML;;NW;;;LW)D:(A;;0x12019f;;;WD)
这将为Everyone用户设置权限,允许他打开,写入和读取管道.我已经检查过,现在可以从任何完整性级别和任何帐户全局访问管道.
更好的方法是0x12019b为"Everyone" 设置权限,因为它将为所有用户提供访问管道的权限,而无需向管道添加新实例的权限.然后,您必须0x12019f仅为创建管道的用户添加权限,但我不知道如何获取当前用户的ID.
在我的情况下非常适合,因为我只报告来自其他进程的数据信息以供系统服务进行解析,但是如果使用管道来控制系统服务,则可能不希望以不同的方式设置安全描述符.当您通过管道向系统服务发送数据时,请务必小心任何缓冲区/堆溢出,因为它可能会导致安全漏洞,从而留下可能允许本地权限升级的漏洞.
我希望这个问题可以帮助别人.
罗杰,出去!
| 归档时间: |
|
| 查看次数: |
3240 次 |
| 最近记录: |