Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding PPL Checks #108

Merged
merged 5 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 62 additions & 9 deletions Seatbelt/Commands/Windows/ProcessesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
using Seatbelt.Output.TextWriters;
using Seatbelt.Output.Formatters;
using Seatbelt.Util;

using System.ComponentModel;
using System.Runtime.InteropServices;
using Seatbelt.Interop;

namespace Seatbelt.Commands.Windows
{
Expand Down Expand Up @@ -38,7 +40,29 @@ internal class ProcessesCommand : CommandBase
public ProcessesCommand(Runtime runtime) : base(runtime)
{
}

private int? GetProcessProtectionInfo(int ProcessId)
{
int pplValueString;
IntPtr ProcessHandle = Kernel32.OpenProcess(Interop.Kernel32.ProcessAccess.QueryLimitedInformation, false, ProcessId);
if (ProcessHandle == null)
{
WriteError($" [!] Could not get a handle to ProcessId " + ProcessId);
}
PsProtection ppl = new PsProtection();
int returnlength;
int status = Ntdll.NtQueryInformationProcess(ProcessHandle, PROCESSINFOCLASS.ProcessProtectionInformation, ref ppl, Marshal.SizeOf(ppl), out returnlength);
if (status != 0)
{
WriteError($" [!] Could not get Process Protection Info for ProcessId " + ProcessId);
var handleResult = Kernel32.CloseHandle(ProcessHandle);
return null;
}
else
{
pplValueString = ((byte)ppl.Type | (byte)ppl.Audit | ((int)ppl.Signer) << 4);
return pplValueString;
}
}
public override IEnumerable<CommandDTOBase?> Execute(string[] args)
{
// lists currently running processes that don't have "Microsoft Corporation" as the company name in their file info
Expand All @@ -64,16 +88,27 @@ select new
Path = (string)mo["ExecutablePath"],
CommandLine = (string)mo["CommandLine"],
};

foreach (var proc in query)
{
var isDotNet = false;
string? companyName = null;
string? description = null;
string? version = null;

string? version = null;
int? ProtectionLevelinfo = null;

if (!SecurityUtil.IsHighIntegrity() || proc.Process.Id == 0)
{
ProtectionLevelinfo = null;
}
else
{
ProtectionLevelinfo = GetProcessProtectionInfo(proc.Process.Id);
}

if (proc.Path != null)
{
{

isDotNet = FileUtil.IsDotNetAssembly(proc.Path);

try
Expand Down Expand Up @@ -132,15 +167,16 @@ select new
proc.Path,
proc.CommandLine,
isDotNet,
processModules
processModules,
ProtectionLevelinfo
);
}
}
}

internal class ProcessesDTO : CommandDTOBase
{
public ProcessesDTO(string processName, int processId, int parentProcessId, string? companyName, string? description, string? version, string? path, string commandLine, bool? isDotNet, List<Module> modules)
public ProcessesDTO(string processName, int processId, int parentProcessId, string? companyName, string? description, string? version, string? path, string commandLine, bool? isDotNet, List<Module> modules, int? ProtectionLevelinfo)
{
ProcessName = processName;
ProcessId = processId;
Expand All @@ -152,6 +188,7 @@ public ProcessesDTO(string processName, int processId, int parentProcessId, stri
CommandLine = commandLine;
IsDotNet = isDotNet;
Modules = modules;
ProcessProtectionLevelinfo = ProtectionLevelinfo;
}
public string ProcessName { get; set; }
public string? CompanyName { get; set; }
Expand All @@ -163,6 +200,7 @@ public ProcessesDTO(string processName, int processId, int parentProcessId, stri
public string CommandLine { get; set; }
public bool? IsDotNet { get; set; }
public List<Module> Modules { get; set; }
public int? ProcessProtectionLevelinfo { get; set; }
}

[CommandOutputType(typeof(ProcessesDTO))]
Expand All @@ -174,7 +212,21 @@ public ProcessFormatter(ITextWriter writer) : base(writer)

public override void FormatResult(CommandBase? command, CommandDTOBase result, bool filterResults)
{
var dto = (ProcessesDTO)result;
var dto = (ProcessesDTO)result;

string? ProtectionLevelString;
if (dto.ProcessProtectionLevelinfo == null)
{
ProtectionLevelString = null;
}
else
{
string pplValue = ((int)dto.ProcessProtectionLevelinfo).ToString("X");
ProtectionValueName protectionLevel = (ProtectionValueName)Enum.Parse(typeof(ProtectionValueName), pplValue, true);
string protectionValueName = protectionLevel.ToString();
string pplValueHex = "(0x" + pplValue + ")";
ProtectionLevelString = protectionValueName + pplValueHex;
}

WriteLine(" {0,-40} : {1}", "ProcessName", dto.ProcessName);
WriteLine(" {0,-40} : {1}", "ProcessId", dto.ProcessId);
Expand All @@ -185,6 +237,7 @@ public override void FormatResult(CommandBase? command, CommandDTOBase result, b
WriteLine(" {0,-40} : {1}", "Path", dto.Path);
WriteLine(" {0,-40} : {1}", "CommandLine", dto.CommandLine);
WriteLine(" {0,-40} : {1}", "IsDotNet", dto.IsDotNet);
WriteLine(" {0,-40} : {1}", "ProcessProtectionInformation", ProtectionLevelString);

if (dto.Modules.Count != 0)
{
Expand Down
23 changes: 23 additions & 0 deletions Seatbelt/Interop/Kernel32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ internal class Kernel32
public static extern bool FindNextFile(IntPtr hFindFile, out WIN32_FIND_DATA
lpFindFileData);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
ProcessAccess processAccess,
bool bInheritHandle,
int processId);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FindClose(IntPtr hFindFile);

Expand Down Expand Up @@ -67,5 +73,22 @@ public struct WIN32_FIND_DATA
IntPtr hPipe,
out int ClientProcessId);

[Flags]
public enum ProcessAccess
{
AllAccess = 0x001FFFFF,
Terminate = 0x00000001,
CreateThread = 0x00000002,
VirtualMemoryOperation = 0x00000008,
VirtualMemoryRead = 0x00000010,
VirtualMemoryWrite = 0x00000020,
DuplicateHandle = 0x00000040,
CreateProcess = 0x000000080,
SetQuota = 0x00000100,
SetInformation = 0x00000200,
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x00001000,
Synchronize = 0x00100000
}
}
}
90 changes: 90 additions & 0 deletions Seatbelt/Interop/Ntdll.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;


namespace Seatbelt.Interop
{
internal class Ntdll
{
#region Function Definitions
[DllImport("ntdll.dll", SetLastError = true)]
public static extern int NtQueryInformationProcess(
IntPtr processHandle,
PROCESSINFOCLASS processInformationClass,
ref PsProtection processInformation,
int processInformationLength,
out int returnLength);
}
#endregion

#region Enum Definitions
[Flags]
public enum PROCESSINFOCLASS
{
ProcessProtectionInformation = 0x3D,
}
[StructLayout(LayoutKind.Sequential)]
public struct PsProtection
{
public PsProtectedType Type;
public PsProtectedSigner Signer;
public PsProtectedAudit Audit;
}
[Flags]
public enum PsProtectedType
{
PsProtectedTypeNone = 0x0,
PsProtectedTypeProtectedLight = 0x1,
PsProtectedTypeProtected = 0x2,
PsProtectedTypeMax = 0x3,
}
[Flags]
public enum PsProtectedSigner
{
PsProtectedSignerNone = 0x0,
PsProtectedSignerAuthenticode = 0x1,
PsProtectedSignerCodeGen = 0x2,
PsProtectedSignerAntimalware = 0x3,
PsProtectedSignerLsa = 0x4,
PsProtectedSignerWindows = 0x5,
PsProtectedSignerWinTcb = 0x6,
PsProtectedSignerMax = 0x7,
}

public enum PsProtectedAudit
{
None = 0x0
}

[Flags]
public enum ProtectionValueName
{
PsProtectedTypeNone = 0,
PsProtectedSignerAuthenticodeLight = 11,
PsProtectedSignerCodeGenLight = 21,
PsProtectedSignerAntimalwareLight = 31,
PsProtectedSignerLsaLight = 41,
PsProtectedSignerWindowsLight = 51,
PsProtectedSignerWinTcbLight = 61,
PsProtectedSignerMaxLight = 71,
PsProtectedSignerAuthenticode = 12,
PsProtectedSignerCodeGen = 22,
PsProtectedSignerAntimalware = 32,
PsProtectedSignerLsa = 42,
PsProtectedSignerWindows = 52,
PsProtectedSignerWinTcb = 62,
PsProtectedSignerMax = 72,
PsProtectedSignerAuthenticodeMax = 13,
PsProtectedSignerCodeGenMax = 23,
PsProtectedSignerAntimalwareMax = 33,
PsProtectedSignerLsaMax = 43,
PsProtectedSignerWindowsMax = 53,
PsProtectedSignerWinTcbMax = 63,
PsProtectedSignerMaxMax = 73
}
#endregion
}


1 change: 1 addition & 0 deletions Seatbelt/Seatbelt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
<Compile Include="Commands\Windows\HotfixesCommand.cs" />
<Compile Include="Commands\Windows\MicrosoftUpdatesCommand.cs" />
<Compile Include="Commands\Windows\SecurityPackagesCredentialsCommand.cs" />
<Compile Include="Interop\Ntdll.cs" />
<Compile Include="Interop\SecBuffer.cs" />
<Compile Include="Interop\SecBufferDesc.cs" />
<Compile Include="Commands\Windows\PowerShellHistory.cs" />
Expand Down