× Welcome to the Centrify Community! Looking for Express & Smart Card Help? Click Here

[Labs] Integrating ServiceNow Approvals to Centrify-enhanced sudo using the dzdo validator

[Labs] Integrating ServiceNow Approvals to Centrify-enhanced sudo using the dzdo validator

By Centrify Guru I ‎09-20-2016 05:22 PM

Background

Regulatory frameworks have evolved to require documented evidence of approval for development or infrastructure-related change control.  These activities usually require the exercise of elevated privileges.  Some examples of these requirements and guidelines can be found on PCI DSS, SANS Critical Security controls, ISO 27001 and others:

  doc-approvals.png

 

Centrify DirectAuthorize and DirectAudit provide end-to-end, role-based access controls for UNIX, Linux and Windows, in addition it provides mechanisms for validation and tracking of changes via ticketing or request systems.

 

Requirements

We've had customers that have two categories of requirements:

  • Tracking activities related to a particular change control or approved request
    For example: We want to track all privileged activities related to a change control in my security operations dashboard.
    We covered this on this on the original dzdo validator article.  When privileges are elevated, entries in both syslog or DirectAuthorize get created automatically.
    Using Centrify-enhanced sudo:
    $ dzdo tail /var/log/messages
    Enter the change control ticket number:1255
    

    syslog:

    Nov  7 15:04:39 engcen6 dzcheck.sample[35173]: User "dwirth@centrify.vms" will run "/usr/bin/tail /var/log/messages" as "root" with ticket number "1255"
    
    DA Console:
    DirectAudit Analyzer - dzdo.validator event.jpg
  • Implementing controls to prevent unauthorized changes
    For example:  We want to make sure that any privilege elevation is only allowed with an approved request.
    This lab covers a basic lab setup to implement this requirement.

 

Lab Diagram

dzdo-validator-lab.png 

 

What you'll need:

  • Centrify Standard Edition and a Centrify Zone with some UNIX roles defined
  • An AD-joined UNIX or Linux  system in the Centrify zone
    The system should be able to reach the ServiceNow instance directly, via proxy or via ServiceNow MIDServer.
  • A DirectAuthorize role for UNIX
  • A ServiceNow instance (Fuji release minimum) and a shared credential or token to query existing requests
    Make sure that the credential only has the minimal rights (e.g. read-only) for your requests.
  • Optional:  Centrify Privilege Service (Saas or On-Prem) to vault the SN user's credential. 

 

Use Case

  1. Privileged user obtains a change control manager approval via ServiceNow workflow request.
    The request has a change control window.  (date/time range)
  2. During the request validity timeframe, the privileged user needs to perform activities (using Centrify-ehnanced sudo) and when the commands are issued, the SN request number has to be provided.
  3. The dzdo.validator script uses the ServiceNow Perl API to validate if the request is approved or not.
    Additional validations can be added like user, time-range, etc;  these won't be covered for blog brevity.
  4. If the request is a approved, the Centrify-enhanced sudo command is allowed to execute.  If not, the user is notified.

 

Implementation  Overview

  1. Install the ServiceNow Perl API
  2. Test ServiceNow Instance connectivity
  3. Optional:  Protect the shared credential using Privilege Service
  4. Modify one of the sample scripts to work with ServiceNow Requests
  5. Modify the dzdo.validator script to call the ServiceNow Perl API script
  6. Implement the dzdo.validator via parameter or GPO
  7. Test your results

 

Install the ServiceNow Perl API

The full instructions and requirements are here:  http://wiki.servicenow.com/index.php?title=Perl_API#gsc.tab=0

  1. Make sure you have the appropriate Perl plugins  (e.g. CentOS 6.x):
    SOAP::Lite  (e.g. yum install perl-SOAP-Lite)
    Crypt::SSLeay (e.g. yum install perl-Crypt-SSLeay)
    IO::Socket::SSL ( e.g. yum install perl-IO-Socket-SSL)
    File::Basename
    MIME::Types (e.g. yum install perl-MIME-Types)
    MIME::Type
    MIME::Base64
  2. Download the Servicenow Perl API  (link to 1.01 version) to your UNIX/Linux system
  3. Unzip the file in a new folder and run the following commands:
    ## create a new folder, download and unzip
    $ mkdir SN
    $ cd SN
    $ wget http://wiki.servicenow.com/images/e/e5/ServiceNow-Perl-API.zip
    $ unzip ServiceNoW-Perl-API.zip
    ## compile the files
    $ perl Makefile.PL $ make $ make test $ make install
    Follow the prompts, once you have all the ServiceNow Perl API libraries installed to use with your scripts.

 

Testing Connectivity with your ServiceNow Instance (Sample Script)

  1. Create a new file with these contents
    # This script retrieves all the requests from your servicenow instance
    # it is used to test connectivity.
    #!/usr/bin/perl -w
    use ServiceNow; use ServiceNow::Configuration;

    # This example uses Centrify Privilege Service's AAPM capability
    # by checking-out the password from the vault at runtime, we eliminate
    # the need to use a cleartext password in this script.
    # uses cgetaccount to check out the password for your-SN-user for 3 mins.
    # Alternatively you can enable OAuth and use Tokens (recommended)

    $SN_PASSWD = `cgetaccount -s -t 3 your-SN-user`; my $CONFIG = ServiceNow::Configuration->new(); $CONFIG->setSoapEndPoint("https://your-instance.service-now.com/"); $CONFIG->setUserName("your-SN-user"); $CONFIG->setUserPassword($SN_PASSWD); my $SN = ServiceNow->new($CONFIG); my @requests = $SN->queryRequestedItem(); my $count = scalar(@requests); print "Number of requests=" . $count . "\n"; foreach my $request (@requests) { print "Request number: $request->{'number'}\n"; print "Requested by: $request->{'sys_created_by'}\n"; print "Date Created: $request->{'sys_created_on'}\n"; print "Approval Status: $request->{'approval'}\n"; print "\n"

 2. To test the script, add the execution flag and run it

$ chmod +x checksn.sh
$ ./inc2.sh
Number of requests=34
Request number: RITM0000002
Requested by: fred.luddy
Date Created: 2016-05-02 18:15:39
Approval Status: requested

Request number: RITM0000004
Requested by: fred.luddy
Date Created: 2016-09-03 17:15:39
Approval Status: requested

Request number: RITM0000005
Requested by: fred.luddy
Date Created: 2016-05-22 19:15:43
Approval Status: requested
[output truncated]

Modify the Sample Script to work with Individual Ticket Numbers

To do this, you need to change the script to require arguments and check for usage.   The modified lines would look like this:

 

#!/usr/bin/perl -w

# You're checking for arguments here.  If there are no arguments
# show the usage and exit.  E.g.  checksn RTM00005

if (@ARGV)  {

# The previous program can go here.  Make sure you modify this line
# to look like this:

my @requests = $SN->queryRequestedItem({'number'=> $0})


}  else {
          print "USAGE:  checksn [ServiceNow Request ID]\n"
}
   

Note that there's no error logic for requests that are not found.  We're going to have to add this later.

 

Modify the dzdo.validator script to to use the ServiceNow Perl API script

 

Centrify provides a sample dzdo validator script called dzcheck.sample.  This script exists under /usr/share/centrifydc/bin.

With the author's limited scripting knowledge we were able to modify it to work this way:

 

  • Initialize the proper libraries and variables
  • Retrieve the password for the ServiceNow user (your-user) and store it in SN_PASSWD
  • Connect to ServiceNow instance
  • Prompt the user for a Change Control number
  • If the number is not found, log to syslog and the user will not be allowed to run the command
  • If the number is found but the status is not approved, log to syslog and the user will not be allowed to run the command
  • If the number is found and approved, log to syslog and allow the end user to run the command.

Note that additional error logic and checks can be added.

 

#!/bin/sh /usr/share/centrifydc/perl/run
# A modified demo for Centrify-enhanced sudo (dzdo) validator 
# Modified to work with ServiceNow Requests
use strict; use lib "../perl"; use lib '/usr/share/centrifydc/perl'; use CentrifyDC::Logger; use ServiceNow; use ServiceNow::Configuration;
# Use privilege service to retrieve SN shared account password
# Alternatively, you can modify the script to use an OAuth token
my $SN_PASSWD = `cgetaccount -s -t 3 your-user`; my $dzdo_user=$ENV{DZDO_USER}; my $dzdo_command=$ENV{DZDO_COMMAND}; my $dzdo_runasuser=$ENV{DZDO_RUNASUSER}; my $CONFIG = ServiceNow::Configuration->new(); $CONFIG->setSoapEndPoint("https://your-instance.service-now.com/"); $CONFIG->setUserName("your-user"); $CONFIG->setUserPassword($SN_PASSWD); my $SN = ServiceNow->new($CONFIG); my $logger = CentrifyDC::Logger->new('dzcheck'); printf STDERR "Enter the change control ticket number: "; my $user_input=<>; my @requests = $SN->queryRequestedItem({'number' => $user_input});
# Check if request(s) exist, if not, exit (1) if (scalar(@requests)==0) { system "adsendaudittrailevent", "-t", "tkt_id", "-i", "$user_input"; $logger->log('INFO', "Change control ticket number: %s", $user_input); $logger->log('INFO', "User \"%s\" will not be allowed to run \"%s\" as \"%s\" with ticket number (REASON:not found) \"%s\"", $dzdo_user, $dzdo_command, $dzdo_runasuser, $user_input); exit 1; }
foreach my $request (@requests) { my $req_status = $request->{'approval'}; # Exit if request is not in approved status if ($req_status ne "approved") { system "adsendaudittrailevent", "-t", "tkt_id", "-i", "$user_input"; $logger->log('INFO', "Change control ticket number: %s", $user_input); $logger->log('INFO', "User \"%s\" will not be allowed to run \"%s\" as \"%s\" with ticket number (REASON:not approved) \"%s\"", $dzdo_user, $dzdo_command, $dzdo_runasuser, $user_input,$req_status); exit 2; } }
# Run command and log if request is approved
system "adsendaudittrailevent", "-t", "tkt_id", "-i", "$user_input"; my $logger = CentrifyDC::Logger->new('dzcheck'); $logger->log('INFO', "Change control ticket number: %s", $user_input); $logger->log('INFO', "User \"%s\" will run \"%s\" as \"%s\" with ticket number \"%s\"", $dzdo_user, $dzdo_command, $dzdo_runasuser, $user_input); exit 0;

I've saved this script as dzcheck.snow in the same location.

 

Configure Centrify-enhanced sudo (dzdo) to use the ServiceNow Requests validator

  1. Open the /etc/centrifydc/centrifydc.conf file for editing
  2. Uncomment the dzdo.validator and set it to our scripts
    dzdo.validator: /usr/share/centrifydc/sbin/dzcheck.snow
  3.  Perform and adreload (or restart the agent)

 

Testing

We'll use a modified version of the sample script to check the requests for validity first, then we'll try to flush the cache using dzdo.

  1. Ticket does not exist  (ABC123)
    Request verification
    $ ./sncheck ABC123
    Request not found.
    $ dzdo adflush
    Enter the change control ticket number: ABC123
    Sorry, user dwirth is not allowed to execute '/usr/sbin/adflush' as root on engcen6.centrify.vms.
    
    # syslog contents
    Sep 20 18:00:52 engcen6 dzcheck.snow[35963]: Change control ticket number: ABC123
    Sep 20 18:00:52 engcen6 dzcheck.snow[35963]: User "dwirth@centrify.vms" will not be allowed to run "/usr/sbin/adflush" as "root" with ticket number (REASON:not found) "ABC123#012"
    Sep 20 18:00:52 engcen6 adclient[1526]: INFO  AUDIT_TRAIL|Centrify Suite|dzdo|1.0|1|dzdo denied|5|user=dwirth(type:ad,dwirth@CENTRIFY.VMS) pid=35961 utc=1474412452436 centrifyEventID=30001 status=DENIED service=dzdo command=/usr/sbin/adflush runas=root reason=Dzdo Validator checks failed. Do not permit to continue the privileged command.
  2. Ticket is not approved (RITM0010022)
    Request verification:
    $ ./sncheck RITM0010022
    number of requests=1
    Request number: RITM0010022
    Requested by: robertson.pimentel
    Date Created: 2016-09-16 16:55:06
    Approval Status: requested

    $ dzdo adflush
    Enter the change control ticket number: RITM0010022
    Sorry, user dwirth is not allowed to execute '/usr/sbin/adflush' as root on engcen6.centrify.vms.
    
    # syslog content
    Sep 20 18:03:04 engcen6 dzcheck.snow[36011]: Change control ticket number: RITM0010022
    Sep 20 18:03:04 engcen6 dzcheck.snow[36011]: User "dwirth@centrify.vms" will not be allowed to run "/usr/sbin/adflush" as "root" with ticket number (REASON:not approved) "RITM0010022#012"
    Sep 20 18:03:04 engcen6 adclient[1526]: INFO  AUDIT_TRAIL|Centrify Suite|dzdo|1.0|1|dzdo denied|5|user=dwirth(type:ad,dwirth@CENTRIFY.VMS) pid=36009 utc=1474412584884 centrifyEventID=30001 status=DENIED service=dzdo command=/usr/sbin/adflush runas=root reason=Dzdo Validator checks failed. Do not permit to continue the privileged command
  3. Ticket is approved (RITM001003)
    $ ./sncheck RITM0010003
    number of requests=1
    Request number: RITM0010003
    Requested by: diego.jimenez
    Date Created: 2016-09-11 14:57:57
    Approval Status: approved

    $ dzdo adflush
    Enter the change control ticket number: RITM0010003
    Demo Password:
    DNS cache flushed successfully.
    Authorization cache store flushed successfully.
    GC and DC caches expired successfully.
    The auditing service's name cache has been successfully flushed.
    The DirectAudit installation information cache has been successfully flushed.
    
    # syslog content Sep 20 18:06:22 engcen6 dzcheck.snow[36108]: Change control ticket number: RITM0010003 Sep 20 18:06:22 engcen6 dzcheck.snow[36108]: User "dwirth@centrify.vms" will run "/usr/sbin/adflush" as "root" with ticket number "RITM0010003#012" Sep 20 18:06:22 engcen6 adclient[1526]: INFO AUDIT_TRAIL|Centrify Suite|dzdo|1.0|0|dzdo granted|5|user=dwirth(type:ad,dwirth@CENTRIFY.VMS) pid=36106 utc=1474412782119 centrifyEventID=30000 status=GRANTED service=dzdo command=/usr/sbin/adflush runas=root role=UNIX Sysadmin/Global env=(none)

 

Benefits if you're using DirectAudit

If you have Enterprise Edition, DirectAudit's events will contain information about the Change Control and you can now search for all activity related to an individual change control number.

ben-da.png

 

Benefits if you're using the Centrify Splunk App

The Splunk App will display reports on the reasons why the privilege elevation failed.  You can also add alerts based on this to identify any privileged user trying to fish.

ben-splunk.png

 

Improvements

This is a lab blog post, therefore this is just a simple concept, but here are the improvements I'd make:

  • Use OAth tokens for ServiceNow instead of a shared credential
    http://wiki.servicenow.com/index.php?title=OAuth_Setup#gsc.tab=0
  • Compare the date of execution with the change control date range (we only did simple checks)
  • Provide better feedback to the user interactively
  • Allow the user to create a request if it's not in the system and notify the approver (cli-driven workflow)

 

Quick Overview Video

 Notes:  ServiceNow, PCI DSS, SANS and ISO 27001 logos are registered trademarks of their respective owners.

Showing results for 
Search instead for 
Do you mean 
Labels

Community Control Panel