mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-24 12:42:38 +00:00
hardened agent (added systempaths class to pin paths, no more env_var support for backend api)
This commit is contained in:
+2
-1
@@ -7,6 +7,7 @@ using System.Net.NetworkInformation;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using AutopilotMonitor.Agent.Core.Logging;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
using AutopilotMonitor.Shared.Models;
|
||||
using Microsoft.Win32;
|
||||
|
||||
@@ -635,7 +636,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh.exe",
|
||||
FileName = SystemPaths.Netsh,
|
||||
Arguments = "wlan show interfaces",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
|
||||
+3
-2
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
using AutopilotMonitor.Shared.Models;
|
||||
|
||||
namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors.GatherCollectors
|
||||
@@ -56,7 +57,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors.GatherCollectors
|
||||
var encodedCommand = Convert.ToBase64String(Encoding.Unicode.GetBytes(command));
|
||||
psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
FileName = SystemPaths.PowerShell,
|
||||
Arguments = $"-NoProfile -ExecutionPolicy RemoteSigned -EncodedCommand {encodedCommand}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
@@ -68,7 +69,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors.GatherCollectors
|
||||
{
|
||||
psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
FileName = SystemPaths.Cmd,
|
||||
Arguments = $"/c {command}",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AutopilotMonitor.Agent.Core.Logging;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
using AutopilotMonitor.Shared;
|
||||
using AutopilotMonitor.Shared.Models;
|
||||
|
||||
@@ -401,7 +402,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Collectors
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "netsh.exe",
|
||||
FileName = SystemPaths.Netsh,
|
||||
Arguments = "wlan show interfaces",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using AutopilotMonitor.Agent.Core.Configuration;
|
||||
using AutopilotMonitor.Agent.Core.Logging;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
|
||||
namespace AutopilotMonitor.Agent.Core.Monitoring.Core
|
||||
{
|
||||
@@ -101,8 +102,10 @@ Remove-Item -Path $scriptPath -Force -ErrorAction SilentlyContinue
|
||||
// creates a new process group that breaks job inheritance, even under SYSTEM.
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/c start \"\" /b powershell.exe -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File \"{tempScriptPath}\"",
|
||||
FileName = SystemPaths.Cmd,
|
||||
// Absolute path to powershell.exe is passed to `start` to prevent PATH hijacking
|
||||
// (the `start` builtin does its own PATH resolution for the target command).
|
||||
Arguments = $"/c start \"\" /b \"{SystemPaths.PowerShell}\" -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File \"{tempScriptPath}\"",
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true,
|
||||
WorkingDirectory = Path.GetTempPath()
|
||||
|
||||
+2
-1
@@ -12,6 +12,7 @@ using AutopilotMonitor.Agent.Core.Logging;
|
||||
using AutopilotMonitor.Agent.Core.Monitoring.Collectors;
|
||||
using AutopilotMonitor.Agent.Core.Monitoring.Network;
|
||||
using AutopilotMonitor.Agent.Core.Monitoring.Tracking;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
using AutopilotMonitor.Shared;
|
||||
using AutopilotMonitor.Shared.Models;
|
||||
|
||||
@@ -635,7 +636,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Core
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "shutdown.exe",
|
||||
FileName = SystemPaths.Shutdown,
|
||||
Arguments = $"/r /t {_configuration.RebootDelaySeconds} /c \"Autopilot enrollment completed - rebooting\"",
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using AutopilotMonitor.Agent.Core.Logging;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
|
||||
namespace AutopilotMonitor.Agent.Core.Monitoring.Network
|
||||
{
|
||||
@@ -50,7 +51,7 @@ namespace AutopilotMonitor.Agent.Core.Monitoring.Network
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "tzutil",
|
||||
FileName = SystemPaths.TzUtil,
|
||||
Arguments = $"/s \"{windowsId}\"",
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace AutopilotMonitor.Agent.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolved absolute paths to Windows system binaries.
|
||||
///
|
||||
/// Rationale: launching processes by bare name (e.g. "cmd.exe", "tzutil") lets
|
||||
/// Windows walk the PATH to find them. As SYSTEM this is a DLL/binary-hijacking
|
||||
/// vector — an attacker able to plant a file in any PATH entry ahead of System32
|
||||
/// gets code execution with SYSTEM privileges. Always use these resolved paths.
|
||||
///
|
||||
/// <see cref="Environment.SystemDirectory"/> respects WOW64 redirection
|
||||
/// automatically:
|
||||
/// - 64-bit process on any Windows → C:\Windows\System32
|
||||
/// - 32-bit process on 64-bit Windows → C:\Windows\SysWOW64
|
||||
/// The agent ships as AnyCPU/net48 and runs 64-bit on 64-bit Windows, so this
|
||||
/// resolves to the real System32. It also honors non-default %SystemRoot%
|
||||
/// (rare, but seen in custom OEM images on drives other than C:).
|
||||
///
|
||||
/// All listed binaries are in-box on every supported Windows version
|
||||
/// (Windows 7 / 8.1 / 10 / 11 / Server 2012R2 – 2025).
|
||||
/// </summary>
|
||||
public static class SystemPaths
|
||||
{
|
||||
private static readonly string System32 = Environment.SystemDirectory;
|
||||
|
||||
/// <summary>C:\Windows\System32\cmd.exe</summary>
|
||||
public static readonly string Cmd = Path.Combine(System32, "cmd.exe");
|
||||
|
||||
/// <summary>C:\Windows\System32\shutdown.exe</summary>
|
||||
public static readonly string Shutdown = Path.Combine(System32, "shutdown.exe");
|
||||
|
||||
/// <summary>C:\Windows\System32\tzutil.exe</summary>
|
||||
public static readonly string TzUtil = Path.Combine(System32, "tzutil.exe");
|
||||
|
||||
/// <summary>C:\Windows\System32\netsh.exe</summary>
|
||||
public static readonly string Netsh = Path.Combine(System32, "netsh.exe");
|
||||
|
||||
/// <summary>
|
||||
/// C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
|
||||
/// Note: the "v1.0" folder is historical — it hosts every in-box PowerShell
|
||||
/// version including 5.1 on Windows 10/11. Do not "fix" it to v5.1.
|
||||
/// </summary>
|
||||
public static readonly string PowerShell = Path.Combine(System32, "WindowsPowerShell", "v1.0", "powershell.exe");
|
||||
}
|
||||
}
|
||||
@@ -105,9 +105,7 @@ namespace AutopilotMonitor.Agent
|
||||
bool enableGeoLocationConfig = true;
|
||||
bool useClientCertAuthConfig = true;
|
||||
|
||||
// Environment variable overrides built-in default
|
||||
apiBaseUrl = Environment.GetEnvironmentVariable("AUTOPILOT_MONITOR_API") ?? apiBaseUrl;
|
||||
// CLI override wins over environment variable/default
|
||||
// CLI override wins over built-in default
|
||||
if (!string.IsNullOrWhiteSpace(apiBaseUrlOverride))
|
||||
apiBaseUrl = apiBaseUrlOverride;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ using System.Net.Http;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using AutopilotMonitor.Agent.Core.Security;
|
||||
using AutopilotMonitor.Shared;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
@@ -451,7 +452,7 @@ namespace AutopilotMonitor.Agent
|
||||
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = "powershell.exe",
|
||||
FileName = SystemPaths.PowerShell,
|
||||
Arguments = $"-NoProfile -NonInteractive -EncodedCommand {encoded}",
|
||||
WindowStyle = ProcessWindowStyle.Hidden,
|
||||
CreateNoWindow = true,
|
||||
|
||||
@@ -1 +1 @@
|
||||
885
|
||||
887
|
||||
|
||||
Reference in New Issue
Block a user