mirror of
https://github.com/inspec/inspec
synced 2024-11-22 20:53:11 +00:00
Added windows support to the processes resource
Signed-off-by: username-is-already-taken2 <digitalgaz@hotmail.com>
This commit is contained in:
parent
75728f786c
commit
9d9baeb09f
5 changed files with 90 additions and 12 deletions
|
@ -60,18 +60,33 @@ The following examples show how to use this InSpec audit resource.
|
|||
its('list.length') { should eq 1 }
|
||||
end
|
||||
|
||||
### Test if the init process is owned by the root user
|
||||
### Test if the process is owned by a specifc user
|
||||
|
||||
describe processes('init') do
|
||||
its('users') { should eq ['root'] }
|
||||
end
|
||||
|
||||
describe processes('winlogon') do
|
||||
its('users') { should cmp "NT AUTHORITY\\SYSTEM" }
|
||||
end
|
||||
|
||||
|
||||
### Test if a high-priority process is running
|
||||
|
||||
describe processes('some_process') do
|
||||
describe processes('linux_process') do
|
||||
its('states') { should eq ['R<'] }
|
||||
end
|
||||
|
||||
describe processes('windows_process') do
|
||||
its('labels') { should cmp "High" }
|
||||
end
|
||||
|
||||
### Test if a process exists on the system
|
||||
|
||||
describe processes('some_process') do
|
||||
it { should exist }
|
||||
end
|
||||
|
||||
### Test for a process using a specific Regexp
|
||||
|
||||
If the process name is too common for a string to uniquely find it,
|
||||
|
@ -81,3 +96,28 @@ needed.
|
|||
describe processes(Regexp.new("/usr/local/bin/swap -d")) do
|
||||
its('list.length') { should eq 1 }
|
||||
end
|
||||
|
||||
### Notes for auditing Windows systems
|
||||
|
||||
Sometimes with system properties there isn't a direct comparison between different operating systems.
|
||||
Most of the `property_name`'s do align between the different OS's.
|
||||
|
||||
There are however some exception's, for example, within linux `states` offers multiple properties.
|
||||
Windows doesn't have direct comparison that is a single property so instead `states` is mapped to the property of `Responding`, This is a boolean true/false flag to help determine if the process is hung.
|
||||
|
||||
Below is a mapping table to help you understand what property the unix field maps to the windows `Get-Process` Property
|
||||
|
||||
| *unix ps field* | *windows PowerShell Property* |
|
||||
|:---------------:|:-----------------------------:|
|
||||
|labels |PriorityClass|
|
||||
|pids |Id|
|
||||
|cpus |CPU|
|
||||
|mem |PM|
|
||||
|vsz |VirtualMemorySize|
|
||||
|rss |NPM|
|
||||
|tty |SessionId|
|
||||
|states |Responding|
|
||||
|start |StartTime|
|
||||
|time |TotalProcessorTime|
|
||||
|users |UserName|
|
||||
|commands |Path|
|
||||
|
|
|
@ -25,15 +25,24 @@ module Inspec::Resources
|
|||
@grep = grep
|
||||
# turn into a regexp if it isn't one yet
|
||||
if grep.class == String
|
||||
grep = '(/[^/]*)*' + grep if grep[0] != '/'
|
||||
grep = Regexp.new('^' + grep + '(\s|$)')
|
||||
# if windows ignore case as we can't make up our minds
|
||||
if inspec.os.windows?
|
||||
grep = '(?i)' + grep
|
||||
else
|
||||
grep = '(/[^/]*)*' + grep unless grep[0] == '/'
|
||||
grep = '^' + grep + '(\s|$)'
|
||||
end
|
||||
grep = Regexp.new(grep)
|
||||
end
|
||||
|
||||
all_cmds = ps_axo
|
||||
@list = all_cmds.find_all do |hm|
|
||||
hm[:command] =~ grep
|
||||
end
|
||||
end
|
||||
|
||||
return skip_resource 'The `processes` resource is not supported on your OS yet.' if inspec.os.windows?
|
||||
def exists?
|
||||
!@list.empty?
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
@ -74,6 +83,10 @@ module Inspec::Resources
|
|||
if os.linux?
|
||||
command = 'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command'
|
||||
regex = /^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
||||
elsif os.windows?
|
||||
command = '$Proc = Get-Process -IncludeUserName | Where-Object {$_.Path -ne $null } | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")'
|
||||
# Wanted to use /(?:^|,)([^,]*)/; works on rubular.com not sure why here?
|
||||
regex = /^(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+)$/
|
||||
else
|
||||
command = 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command'
|
||||
regex = /^\s*([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
||||
|
@ -95,7 +108,7 @@ module Inspec::Resources
|
|||
end.compact
|
||||
lines.map do |m|
|
||||
a = m.to_a[1..-1] # grab all matching groups
|
||||
a.unshift(nil) unless os.linux?
|
||||
a.unshift(nil) unless os.linux? || os.windows?
|
||||
a[1] = a[1].to_i
|
||||
a[4] = a[4].to_i
|
||||
a[5] = a[5].to_i
|
||||
|
|
|
@ -303,10 +303,10 @@ class MockLoader
|
|||
'crontab -l' => cmd.call('crontab-root'),
|
||||
# crontab display for non-current user
|
||||
'crontab -l -u foouser' => cmd.call('crontab-foouser'),
|
||||
# zfs output for dataset tank/tmp
|
||||
'/sbin/zfs get -Hp all tank/tmp' => cmd.call('zfs-get-all-tank-tmp'),
|
||||
# zfs output for pool tank
|
||||
'/sbin/zpool get -Hp all tank' => cmd.call('zpool-get-all-tank'),
|
||||
# zfs output for dataset tank/tmp
|
||||
'/sbin/zfs get -Hp all tank/tmp' => cmd.call('zfs-get-all-tank-tmp'),
|
||||
# zfs output for pool tank
|
||||
'/sbin/zpool get -Hp all tank' => cmd.call('zpool-get-all-tank'),
|
||||
# docker
|
||||
"docker ps -a --no-trunc --format '{{ json . }}'" => cmd.call('docker-ps-a'),
|
||||
"docker version --format '{{ json . }}'" => cmd.call('docker-version'),
|
||||
|
@ -314,8 +314,9 @@ class MockLoader
|
|||
"docker inspect 71b5df59442b" => cmd.call('docker-inspec'),
|
||||
# docker images
|
||||
"83c36bfade9375ae1feb91023cd1f7409b786fd992ad4013bf0f2259d33d6406" => cmd.call('docker-images'),
|
||||
}
|
||||
|
||||
# get-process cmdlet for processes resource
|
||||
'$Proc = Get-Process -IncludeUserName | Where-Object {$_.Path -ne $null } | Select-Object PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path | ConvertTo-Csv -NoTypeInformation;$Proc.Replace("""","").Replace("`r`n","`n")' => cmd.call('get-process_processes')
|
||||
}
|
||||
@backend
|
||||
end
|
||||
|
||||
|
|
3
test/unit/mock/cmd/get-process_processes
Normal file
3
test/unit/mock/cmd/get-process_processes
Normal file
|
@ -0,0 +1,3 @@
|
|||
PriorityClass,Id,CPU,PM,VirtualMemorySize,NPM,SessionId,Responding,StartTime,TotalProcessorTime,UserName,Path
|
||||
Normal,2456,0.296875,4808704,118202368,14576,1,True,5/31/2017 9:13:17 AM,00:00:00.2968750,WINVAGR-QQQNHPN\Administrator,C:\Windows\system32\mmc.exe
|
||||
High,396,0.15625,1323008,53710848,7776,1,True,5/31/2017 9:12:56 AM,00:00:00.1562500,NT AUTHORITY\SYSTEM,C:\Windows\system32\winlogon.exe
|
|
@ -109,6 +109,7 @@ describe 'Inspec::Resources::Processes' do
|
|||
resource = MockLoader.new(:centos6).load_resource('processes', 'postgres: bifrost bifrost')
|
||||
_(resource.users.sort).must_equal ['opscode-pgsql']
|
||||
_(resource.states.sort).must_equal ['Ss']
|
||||
_(resource.exists?).must_equal true
|
||||
end
|
||||
|
||||
it 'command name matches with output (string)' do
|
||||
|
@ -120,4 +121,24 @@ describe 'Inspec::Resources::Processes' do
|
|||
resource = MockLoader.new(:centos6).load_resource('processes', /mysqld/)
|
||||
_(resource.to_s).must_equal 'Processes /mysqld/'
|
||||
end
|
||||
|
||||
it 'command name matches with output (string)' do
|
||||
resource = MockLoader.new(:windows).load_resource('processes', 'winlogon.exe')
|
||||
_(resource.to_s).must_equal 'Processes winlogon.exe'
|
||||
end
|
||||
|
||||
it 'retrieves the users and states as arrays on windows os' do
|
||||
resource = MockLoader.new(:windows).load_resource('processes', 'winlogon.exe')
|
||||
_(resource.users.sort).must_equal ['NT AUTHORITY\\SYSTEM']
|
||||
end
|
||||
|
||||
it 'process should exist' do
|
||||
resource = MockLoader.new(:windows).load_resource('processes', 'winlogon.exe')
|
||||
_(resource.exists?).must_equal true
|
||||
end
|
||||
|
||||
it 'process should_not exist' do
|
||||
resource = MockLoader.new(:windows).load_resource('processes', 'unicorn.exe')
|
||||
_(resource.exists?).must_equal false
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue