2015-04-09 20:01:23 +00:00
|
|
|
# encoding: utf-8
|
2015-07-15 13:15:18 +00:00
|
|
|
# copyright: 2015, Vulcano Security GmbH
|
2015-10-06 16:55:44 +00:00
|
|
|
# author: Dominik Richter
|
|
|
|
# author: Christoph Hartmann
|
2015-04-09 20:01:23 +00:00
|
|
|
# license: All rights reserved
|
|
|
|
|
2017-02-02 12:26:48 +00:00
|
|
|
require 'utils/filter'
|
|
|
|
|
2016-03-08 18:06:55 +00:00
|
|
|
module Inspec::Resources
|
|
|
|
class Processes < Inspec.resource(1)
|
|
|
|
name 'processes'
|
|
|
|
desc 'Use the processes InSpec audit resource to test properties for programs that are running on the system.'
|
|
|
|
example "
|
|
|
|
describe processes('mysqld') do
|
2017-02-02 13:02:28 +00:00
|
|
|
its('entries.length') { should eq 1 }
|
2016-03-08 18:06:55 +00:00
|
|
|
its('users') { should eq ['mysql'] }
|
|
|
|
its('states') { should include 'S' }
|
|
|
|
end
|
2017-02-02 13:02:28 +00:00
|
|
|
describe processes(/.+/).where { label != 'unconfined' && pid < 1000 } do
|
|
|
|
its('users') { should cmp [] }
|
|
|
|
end
|
2016-03-08 18:06:55 +00:00
|
|
|
"
|
2015-04-09 20:01:23 +00:00
|
|
|
|
2016-03-08 18:06:55 +00:00
|
|
|
def initialize(grep)
|
2016-11-29 11:00:43 +00:00
|
|
|
@grep = grep
|
2016-03-08 18:06:55 +00:00
|
|
|
# turn into a regexp if it isn't one yet
|
|
|
|
if grep.class == String
|
2017-06-04 20:03:04 +00:00
|
|
|
# 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)
|
2016-03-08 18:06:55 +00:00
|
|
|
end
|
2017-06-04 20:03:04 +00:00
|
|
|
|
2016-09-26 18:03:19 +00:00
|
|
|
all_cmds = ps_axo
|
2016-03-08 18:06:55 +00:00
|
|
|
@list = all_cmds.find_all do |hm|
|
|
|
|
hm[:command] =~ grep
|
|
|
|
end
|
2017-06-04 20:03:04 +00:00
|
|
|
end
|
2017-05-25 20:46:53 +00:00
|
|
|
|
2017-06-04 20:03:04 +00:00
|
|
|
def exists?
|
|
|
|
!@list.empty?
|
2015-12-07 08:39:48 +00:00
|
|
|
end
|
2015-09-09 16:52:27 +00:00
|
|
|
|
2016-03-08 18:06:55 +00:00
|
|
|
def to_s
|
2016-11-29 11:00:43 +00:00
|
|
|
"Processes #{@grep.class == String ? @grep : @grep.inspect}"
|
2016-03-08 18:06:55 +00:00
|
|
|
end
|
2015-10-12 11:01:58 +00:00
|
|
|
|
2017-02-02 13:02:28 +00:00
|
|
|
def list
|
|
|
|
warn '[DEPRECATION] `processes.list` is deprecated. Please use `processes.entries` instead. It will be removed in version 2.0.0.'
|
|
|
|
@list
|
|
|
|
end
|
|
|
|
|
2017-02-02 12:26:48 +00:00
|
|
|
filter = FilterTable.create
|
|
|
|
filter.add_accessor(:where)
|
|
|
|
.add_accessor(:entries)
|
|
|
|
.add(:labels, field: 'label')
|
|
|
|
.add(:pids, field: 'pid')
|
|
|
|
.add(:cpus, field: 'cpu')
|
|
|
|
.add(:mem, field: 'mem')
|
|
|
|
.add(:vsz, field: 'vsz')
|
|
|
|
.add(:rss, field: 'rss')
|
|
|
|
.add(:tty, field: 'tty')
|
|
|
|
.add(:states, field: 'stat')
|
|
|
|
.add(:start, field: 'start')
|
|
|
|
.add(:time, field: 'time')
|
|
|
|
.add(:users, field: 'user')
|
2017-02-02 13:02:28 +00:00
|
|
|
.add(:commands, field: 'command')
|
|
|
|
.connect(self, :filtered_processes)
|
2017-02-02 12:26:48 +00:00
|
|
|
|
2016-03-08 18:06:55 +00:00
|
|
|
private
|
2015-09-09 16:52:27 +00:00
|
|
|
|
2017-02-02 13:02:28 +00:00
|
|
|
def filtered_processes
|
|
|
|
@list
|
|
|
|
end
|
|
|
|
|
2016-09-26 18:03:19 +00:00
|
|
|
def ps_axo
|
2016-05-09 19:19:56 +00:00
|
|
|
os = inspec.os
|
|
|
|
|
|
|
|
if os.linux?
|
2016-10-17 14:23:50 +00:00
|
|
|
command = 'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command'
|
2016-11-29 07:29:54 +00:00
|
|
|
regex = /^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
2017-06-04 20:03:04 +00:00
|
|
|
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 = /^(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+),(.+)$/
|
2016-05-09 19:19:56 +00:00
|
|
|
else
|
2016-10-17 14:23:50 +00:00
|
|
|
command = 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command'
|
2016-09-26 18:03:19 +00:00
|
|
|
regex = /^\s*([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
2016-05-09 19:19:56 +00:00
|
|
|
end
|
|
|
|
build_process_list(command, regex, os)
|
|
|
|
end
|
|
|
|
|
2016-09-26 18:03:19 +00:00
|
|
|
Process = Struct.new(:label, :pid,
|
2016-05-13 09:16:45 +00:00
|
|
|
:cpu, :mem, :vsz,
|
|
|
|
:rss, :tty, :stat,
|
2016-10-17 14:23:50 +00:00
|
|
|
:start, :time, :user, :command)
|
2016-05-13 09:16:45 +00:00
|
|
|
|
|
|
|
def build_process_list(command, regex, os)
|
2016-05-09 19:19:56 +00:00
|
|
|
cmd = inspec.command(command)
|
2016-03-08 18:06:55 +00:00
|
|
|
all = cmd.stdout.split("\n")[1..-1]
|
|
|
|
return [] if all.nil?
|
|
|
|
lines = all.map do |line|
|
2016-05-09 19:19:56 +00:00
|
|
|
line.match(regex)
|
2016-03-08 18:06:55 +00:00
|
|
|
end.compact
|
2016-05-13 09:16:45 +00:00
|
|
|
lines.map do |m|
|
|
|
|
a = m.to_a[1..-1] # grab all matching groups
|
2017-06-04 20:03:04 +00:00
|
|
|
a.unshift(nil) unless os.linux? || os.windows?
|
2016-09-26 18:03:19 +00:00
|
|
|
a[1] = a[1].to_i
|
|
|
|
a[4] = a[4].to_i
|
2016-05-13 09:16:45 +00:00
|
|
|
a[5] = a[5].to_i
|
|
|
|
Process.new(*a)
|
2016-03-08 18:06:55 +00:00
|
|
|
end
|
2015-04-09 20:01:23 +00:00
|
|
|
end
|
|
|
|
end
|
2015-08-28 19:27:35 +00:00
|
|
|
end
|