Skip to content

Commit 51038b9

Browse files
committed
Added calculation of default access for a mandatory policy.
1 parent e445f74 commit 51038b9

9 files changed

Lines changed: 104 additions & 13 deletions

File tree

NtApiDotNet/GenericMapping.cs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,70 @@ public AccessMask UnmapMask(AccessMask mask)
123123
return result | remaining;
124124
}
125125

126+
/// <summary>
127+
/// Get the allowed access mask for a specified mandatory access policy.
128+
/// </summary>
129+
/// <param name="policy">The mandatory access policy.</param>
130+
/// <returns>The allowed access mask for the policy.</returns>
131+
/// <remarks>In general NoWriteUp will always be set on the policy.</remarks>
132+
public AccessMask GetAllowedMandatoryAccess(MandatoryLabelPolicy policy)
133+
{
134+
bool can_read = !policy.HasFlag(MandatoryLabelPolicy.NoReadUp);
135+
bool can_write = !policy.HasFlag(MandatoryLabelPolicy.NoWriteUp);
136+
bool can_execute = !policy.HasFlag(MandatoryLabelPolicy.NoExecuteUp);
137+
138+
AccessMask allowed_access;
139+
if (can_write)
140+
{
141+
allowed_access = GenericAll | GenericRead | GenericExecute | GenericAccessRights.Synchronize | GenericAccessRights.ReadControl;
142+
}
143+
else
144+
{
145+
allowed_access = GenericRead | GenericExecute | GenericAccessRights.Synchronize | GenericAccessRights.ReadControl;
146+
}
147+
AccessMask allowed_write_access = GenericAccessRights.Delete | GenericAccessRights.WriteDac | GenericAccessRights.WriteOwner | GenericAccessRights.AccessSystemSecurity;
148+
AccessMask allowed_read_access = GenericAccessRights.ReadControl;
149+
AccessMask allowed_execute_access = GenericAccessRights.Synchronize;
150+
151+
if (policy == MandatoryLabelPolicy.None)
152+
return GenericAll;
153+
154+
if (!can_read)
155+
{
156+
AccessMask temp_mask = 0;
157+
if (can_write)
158+
temp_mask = GenericWrite | allowed_write_access;
159+
if (can_execute)
160+
temp_mask |= (~GenericRead & GenericExecute) | GenericAccessRights.Synchronize;
161+
temp_mask = ~temp_mask & (GenericRead | allowed_read_access);
162+
allowed_access &= ~temp_mask;
163+
}
164+
165+
if (!can_execute)
166+
{
167+
AccessMask temp_mask = 0;
168+
if (can_write)
169+
temp_mask = GenericWrite | allowed_write_access;
170+
if (can_read)
171+
temp_mask |= GenericRead | allowed_read_access;
172+
temp_mask = ~temp_mask & ((~GenericRead & GenericExecute) | allowed_execute_access);
173+
allowed_access &= ~temp_mask;
174+
}
175+
176+
if (!can_write)
177+
{
178+
AccessMask temp_mask = 0;
179+
if (can_execute)
180+
temp_mask = (~GenericRead & GenericExecute) | allowed_execute_access;
181+
if (can_read)
182+
temp_mask |= GenericRead | allowed_read_access;
183+
temp_mask = ~temp_mask & (GenericWrite | allowed_write_access);
184+
allowed_access &= ~temp_mask;
185+
}
186+
187+
return allowed_access;
188+
}
189+
126190
/// <summary>
127191
/// Convert generic mapping to a string.
128192
/// </summary>

NtApiDotNet/NtObjectWithDuplicate.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,23 @@ public abstract class NtObjectWithDuplicate<O, A> : NtObject where O : NtObject
2626
{
2727
internal abstract class NtTypeFactoryImplBase : NtTypeFactory
2828
{
29-
protected NtTypeFactoryImplBase(Type container_access_rights_type, bool can_open)
30-
: base(typeof(A), container_access_rights_type, typeof(O), can_open)
29+
protected NtTypeFactoryImplBase(Type container_access_rights_type, bool can_open, MandatoryLabelPolicy default_policy)
30+
: base(typeof(A), container_access_rights_type, typeof(O), can_open, default_policy)
31+
{
32+
}
33+
34+
protected NtTypeFactoryImplBase(Type container_access_rights_type, bool can_open)
35+
: this(container_access_rights_type, can_open, MandatoryLabelPolicy.NoWriteUp)
36+
{
37+
}
38+
39+
protected NtTypeFactoryImplBase(bool can_open, MandatoryLabelPolicy default_policy)
40+
: this(typeof(A), can_open, default_policy)
3141
{
3242
}
3343

3444
protected NtTypeFactoryImplBase(bool can_open)
35-
: this(typeof(A), can_open)
45+
: this(can_open, MandatoryLabelPolicy.NoWriteUp)
3646
{
3747
}
3848

NtApiDotNet/NtProcess.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ internal NtProcess(SafeKernelObjectHandle handle) : base(handle)
218218

219219
internal sealed class NtTypeFactoryImpl : NtTypeFactoryImplBase
220220
{
221-
public NtTypeFactoryImpl() : base(false)
221+
public NtTypeFactoryImpl() : base(false, MandatoryLabelPolicy.NoWriteUp | MandatoryLabelPolicy.NoReadUp)
222222
{
223223
}
224224
}

NtApiDotNet/NtSecurityNative.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -865,6 +865,7 @@ public enum AceFlags : byte
865865
[Flags]
866866
public enum MandatoryLabelPolicy : uint
867867
{
868+
None = 0x0,
868869
NoWriteUp = 0x1,
869870
NoReadUp = 0x2,
870871
NoExecuteUp = 0x4,

NtApiDotNet/NtThread.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ internal NtThread(SafeKernelObjectHandle handle)
9797

9898
internal sealed class NtTypeFactoryImpl : NtTypeFactoryImplBase
9999
{
100-
public NtTypeFactoryImpl() : base(false)
100+
public NtTypeFactoryImpl() : base(false, MandatoryLabelPolicy.NoWriteUp | MandatoryLabelPolicy.NoReadUp)
101101
{
102102
}
103103
}

NtApiDotNet/NtType.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,15 @@ public bool IsValidAccess(AccessMask access_mask)
417417
return (GenericMapping.MapMask(access_mask) & ~ValidAccess).IsEmpty;
418418
}
419419

420+
/// <summary>
421+
/// Get the maximum access mask for the types default mandatory access policy.
422+
/// </summary>
423+
/// <returns>The allowed access mask for the type with the default policy.</returns>
424+
public AccessMask GetDefaultMandatoryAccess()
425+
{
426+
return GenericMapping.GetAllowedMandatoryAccess(_type_factory.DefaultMandatoryPolicy);
427+
}
428+
420429
/// <summary>
421430
/// Overridden ToString method.
422431
/// </summary>
@@ -441,13 +450,13 @@ public NtType(string name)
441450
{
442451
}
443452

444-
internal NtType(string name, GenericMapping generic_mapping, Type access_rights_type, Type container_access_rights_type)
453+
internal NtType(string name, GenericMapping generic_mapping, Type access_rights_type, Type container_access_rights_type, MandatoryLabelPolicy default_policy)
445454
{
446455
if (!access_rights_type.IsEnum)
447456
{
448457
throw new ArgumentException("Specify an enumerated type", "access_rights_type");
449458
}
450-
_type_factory = new NtTypeFactory(access_rights_type, container_access_rights_type, typeof(object), false);
459+
_type_factory = new NtTypeFactory(access_rights_type, container_access_rights_type, typeof(object), false, default_policy);
451460
Name = name;
452461
ValidAccess = CalculateValidAccess(access_rights_type) | CalculateValidAccess(container_access_rights_type);
453462
GenericMapping = generic_mapping;
@@ -659,7 +668,7 @@ public static NtType GetTypeByType<T>() where T : NtObject
659668
/// <returns>The fake NT type object.</returns>
660669
public static NtType GetFakeType(string name, GenericMapping generic_mapping, Type access_rights_type, Type container_access_rights_type)
661670
{
662-
return new NtType(name, generic_mapping, access_rights_type, container_access_rights_type);
671+
return new NtType(name, generic_mapping, access_rights_type, container_access_rights_type, MandatoryLabelPolicy.NoWriteUp);
663672
}
664673

665674
/// <summary>
@@ -690,7 +699,9 @@ public static NtType GetFakeType(string name, GenericMapping generic_mapping, Ty
690699
public static NtType GetFakeType(string name, AccessMask generic_read, AccessMask generic_write,
691700
AccessMask generic_exec, AccessMask generic_all, Type access_rights_type, Type container_access_rights_type)
692701
{
693-
return new NtType(name, new GenericMapping() { GenericRead = generic_read, GenericWrite = generic_write, GenericExecute = generic_exec, GenericAll = generic_all }, access_rights_type, container_access_rights_type);
702+
return new NtType(name, new GenericMapping() { GenericRead = generic_read, GenericWrite = generic_write,
703+
GenericExecute = generic_exec, GenericAll = generic_all }, access_rights_type, container_access_rights_type,
704+
MandatoryLabelPolicy.NoWriteUp);
694705
}
695706

696707
/// <summary>

NtApiDotNet/NtTypeFactory.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ internal class NtTypeFactory
3737
public Type AccessRightsType { get; }
3838
public Type ContainerAccessRightsType { get; }
3939
public bool CanOpen { get; }
40+
public MandatoryLabelPolicy DefaultMandatoryPolicy { get; }
4041

4142
public virtual NtObject FromHandle(SafeKernelObjectHandle handle)
4243
{
@@ -48,12 +49,13 @@ public virtual NtResult<NtObject> Open(ObjectAttributes obj_attributes, AccessMa
4849
return NtStatus.STATUS_NOT_IMPLEMENTED.CreateResultFromError<NtObject>(throw_on_error);
4950
}
5051

51-
internal NtTypeFactory(Type access_rights_type, Type container_access_rights_type, Type object_type, bool can_open)
52+
internal NtTypeFactory(Type access_rights_type, Type container_access_rights_type, Type object_type, bool can_open, MandatoryLabelPolicy default_policy)
5253
{
5354
AccessRightsType = access_rights_type;
5455
ContainerAccessRightsType = container_access_rights_type;
5556
ObjectType = object_type;
5657
CanOpen = can_open;
58+
DefaultMandatoryPolicy = default_policy;
5759
}
5860

5961
public static Dictionary<string, NtTypeFactory> GetAssemblyNtTypeFactories(Assembly assembly)

NtApiDotNet/Win32/ServiceUtils.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,10 +1110,12 @@ public static NtType GetServiceNtType(string type_name)
11101110
{
11111111
case "service":
11121112
return new NtType("Service", GetServiceGenericMapping(),
1113-
typeof(ServiceAccessRights), typeof(ServiceAccessRights));
1113+
typeof(ServiceAccessRights), typeof(ServiceAccessRights),
1114+
MandatoryLabelPolicy.NoWriteUp);
11141115
case "scm":
11151116
return new NtType("SCM", GetScmGenericMapping(),
1116-
typeof(ServiceControlManagerAccessRights), typeof(ServiceControlManagerAccessRights));
1117+
typeof(ServiceControlManagerAccessRights), typeof(ServiceControlManagerAccessRights),
1118+
MandatoryLabelPolicy.NoWriteUp);
11171119
}
11181120
return null;
11191121
}

NtObjectManager/NtSecurityCmdlets.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,6 +829,7 @@ public sealed class NewNtSecurityDescriptorCmdlet : PSCmdlet
829829
/// <summary>
830830
/// <para type="description">Specify a default NT type for the security descriptor.</para>
831831
/// </summary>
832+
[Parameter(ParameterSetName = "FromToken"), Parameter(ParameterSetName = "FromSddl"), Parameter(ParameterSetName = "FromBytes"), Parameter(ParameterSetName = "FromKey")]
832833
public NtType Type { get; set; }
833834

834835
/// <summary>
@@ -863,7 +864,7 @@ protected override void ProcessRecord()
863864
{
864865
if (MapType && Type == null)
865866
{
866-
WriteWarning("Must specify NtType for MapType to work correctly.");
867+
WriteWarning("Must specify Type for MapType to work correctly.");
867868
}
868869

869870
SecurityDescriptor sd = null;

0 commit comments

Comments
 (0)