1

I have been trying to get a remote listing of running windows processes including their CommandLine/ExecutablePath attribute through WMI as a non-administrator domain user for a monitoring tool. I have succeeded to get a process list using the answer below, but the CommandLine attribute was always empty.

[Which permissions/rights does a user need to have WMI access on remote machines?

Granting the 'debug programs' user right in the local security policy allows access to the CommandLine/ExecutablePath information. But then the monitoring user account could potentially invade processes, not just query information about them. Is there any lesser user right or other way to unlock the CommandLine information? I have used the wmic tool arguments shown below for testing.

wmic /node:"servername" /user:username /password:password PROCESS get name,commandline,executablepath

Thank you in advance for any insight you can give me.

Basdoorn
  • 51
  • 1
  • 5
  • 1
    To clarify, you're trying to access the WMI information directly through/with/for a monitoring tool? – HopelessN00b Jun 26 '14 at 17:42
  • The monitoring tool only requires an account to be input and will query WMI on its own. I am using the wmic command to mimic its requests and find out how the target server responds with certain settings. – Basdoorn Jun 26 '14 at 22:29

2 Answers2

2

I have finally managed to work around this issue, by giving an AD group more permissions for the individual services. This way, the monitoring tool might be able to control the services to be monitored, but at least not be able to invade any process running on the target machines. I have used the Powershell script below to accomplish this. You would have to input your own AD group and modify the list of Windows services to cater to your needs. It is possible to run this kind of script through group policy and apply it to a group of servers.

function AddSDDL() {
    Param(
        [Parameter(Mandatory=$True)]
        [string]$Username,
        [Parameter(Mandatory=$True)]
        [string]$Service
    )
    $servicetest = Get-Service | where {$_.name -eq "$service"}
    if (!$servicetest -and $service -ne "scmanager") {
        Write-Host "Service $service does not exist. Please supply the name and not the display name"
        return $false;
    }
    $domain = ($username.split("\"))[0]
    $user = ($username.split("\"))[1]
    $ntaccount = New-Object System.Security.Principal.NTAccount($domain,$user)
    $sid = ($ntaccount.Translate([System.Security.Principal.SecurityIdentifier])).value
    if (!$sid) {
        Write-Host "User $username cannot be resolved to a SID. Does the account exist?"
        return $false;
    }
    $sddl = [string](cmd /c "sc.exe sdshow $service");
    if ($sddl -match $sid) {
        Write-Host "User $username already has some sort of access in the SDDL. Remediate manually"
        return $false;
    }
    if($sddl -match "S:\(") {
        $sddl = $sddl -replace "S:\(","(A;;CCLCLORPRC;;;$sid)S:("
    } elseif($sddl -match "D:" -and $sddl.LastIndexOf(":") -lt 3) {
        $sddl += "(A;;CCLCLORPRC;;;$sid)";
    } else {
        Write-Host "SDDL contains multiple description types like D: and A:, but not S:, remediate manually"
        return $false;
    }
    $sddlCommand = "sc.exe sdset $service $sddl";
    Write-Host($sddlCommand);
    $sddlset = cmd /c $sddlCommand
    if ($sddlset -notlike "*SUCCESS*") {
        Write-Host "Permissions did not set"
        Write-Host "Full error: $sddlset"
    }
    else {
        Write-Host "Permissions set successfully for $username on $service"
    }

    return $true;
}

clear;

# default 2012 R2 scmanager: D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)(A;;CC;;;AC)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)
# default 2012 R2 w32time: D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CCLCSWRPLOCRRC;;;LS)(A;;CCSWWPLORC;;;LS)
# default 2008 R2 scmanager: D:(A;;CC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)
# default 2008 R2 w3svc: D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
# default 2008 R2 aspnet_state: D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)
# with list content (LC), read all properties (RP) and read permissions (RC) for authenticated users: D:(A;;CCLC;;;AU)(A;;CCLCRPRC;;;IU)(A;;CCLCRPRC;;;SU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)(A;;CC;;;AC)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)

$serviceNames = @("DHCPServer","TlntSvr","RpcSs","SamSs","DNS","Dnscache","LanmanWorkstation","Netlogon","Kdc","IsmServ","DFSR","W32Time","LanmanServer","WAS","aspnet_state","W3SVC","scmanager");
$serviceNames += Get-Service | Where-Object{$_.Name -like "*sql*"} | ForEach-Object{$_.Name};
$serviceNames += Get-Service | Where-Object{$_.Name -like "*ReportServer*"} | ForEach-Object{$_.Name};
foreach($serviceName in $serviceNames) {
    Write-Host("SDDL of $serviceName before update: ") -NoNewline;
    sc.exe sdshow $serviceName

    $wmiGroup = "YOUR_DOMAN\AD_GROUP_FOR_WMI_MONITORING"
    $modified = AddSDDL -Username $wmiGroup -Service $serviceName;

    if($modified) {
        Write-Host("SDDL of $serviceName after update: ") -NoNewline;
        sc.exe sdshow $serviceName
    }
}
Basdoorn
  • 51
  • 1
  • 5
0

Here they suggest the following solution using WmiSecurity:

WmiSecurity.exe /C="%computername%" /A /N=Root/CIMV2 /M=" DOMAIN\USER:REMOTEACCESS" /R

Alternatively, you can use the built-in utility like demonstrated here.

But I think that both solutions can't limit the access just to processes information.

EliadTech
  • 1,230
  • 9
  • 14
  • Thank you for your reply. I had already performed the steps listed for the manual setup. This way, I can access process information like Name, but not CommandLine. To get that information I still need the 'debug programs' user right assigned, which grants much more rights than I would like. – Basdoorn Jun 26 '14 at 22:33
  • I couldn't find a direct solution to that, but you can circumvent it if you have a list of all exe files that the monitoring tool can use. BTW, why do you care if the monitoring tool can see the full path? – EliadTech Jun 27 '14 at 09:51
  • The CommandLine tells me which instance of SQL Reporting Services it is. The other attributes of the processes like the executable name are identical. The different instances have different memory limits I want to send warning/critical alerts for. How would the circumvention you speak of work, because I do have the paths for all the processes I want to monitor in this way? – Basdoorn Jun 27 '14 at 13:25
  • I think that all monitoring utilities support custom scripts. You can wrap the WMI query with a script that, when executed, retrieves the paths as well - either by searching locally or by searching a list you created once manually. Or you can even take one more step and set the memory limits and warnings in that script. – EliadTech Jun 28 '14 at 19:23