jborean93 / pypsrp

PowerShell Remoting Protocol for Python
MIT License
324 stars 49 forks source link

Ansible PSRP Module not applying JEA role capability file correctly. #170

Closed youngercloud closed 1 year ago

youngercloud commented 1 year ago

Description: When using the Ansible PSRP module with a JEA role capability file, the file is not being applied correctly, leading to unlimited functionality instead of the expected limited cmdlets and functions defined in the role capability file.

Environment:

Ansible core version: 2.13.8
pypsrp version: 0.8.1
OS: Ubuntu 22.04.1 LTS (Ansible control node), Windows Server 2019 Datacenter (target machine)
PowerShell version: 5.1.17763.3770

Steps to reproduce:

  1. Configure a JEA session configuration file (sc.pssc) to reference the role capability file.
@{

  # This is a sample configuration for a Session Configuration file.

  # Version number of the schema used for this document
  SchemaVersion = '2.0.0.0'

  # ID used to uniquely identify this document
  GUID = 'ec521436-fa55-49e5-bd1b-a098a62994c6'

  # Author of this document
  Author = 'youngercloud''

  # Description of the functionality provided by these settings
  Description = 'Allows service user to connect without local administration privileges'

  # Session type defaults to apply for this session configuration. Can be 'RestrictedRemoteServer' (recommended), 'Empty', or 'Default'
  SessionType = 'Default'

  # Directory to place session transcripts for this session configuration
  # TranscriptDirectory = 'C:\Transcripts\'

  # Whether to run this session configuration as the machine's (virtual) administrator account
  RunAsVirtualAccount = $false

  GroupManagedServiceAccount = "MyDomain\service_account"

  # User roles (security groups), and the role capabilities that should be applied to them when applied to a session
  # When do the deployment, this can be a user
  RoleDefinitions =  @{ 'MyDomain\normal_account' = @{ RoleCapabilityFiles = 'C:\Program Files\WindowsPowerShell\Modules\normal_account\rc.psrc' }}
}
  1. Create a JEA role capability file (rc.psrc) with limited cmdlets and functions.
@{
  # This is a sample configuration for a RoleCapability file.

  # ID used to uniquely identify this document
  GUID = 'f4f63d0c-175f-45a8-8a17-3c69b0a085a5'
  # Author of this document
  Author = 'youngercloud'
  # Description of the functionality provided by these settings
  Description = 'Test JEA File'

  # Copyright statement for this document
  Copyright = '(c) 2022 Administrator. All rights reserved.'
  # Modules to import when applied to a session
  ModulesToImport = 'Microsoft.PowerShell.Core'
  VisibleCmdlets = 'Clear-Host','Exit-PSSession','Get-Command','Get-Module','Get-FormatData','Measure-Object', 'Select-Object','Out-Default','Out-String', 'Set-Variable','Get-Service','Get-Process','Write-Host','Write-Output'
  # Functions to make visible when applied to a session
  VisibleExternalCommands = 'C:\Windows\system32\chcp.com'
}
  1. Register the JEA endpoint on the target machine using Register-PSSessionConfiguration with the sc.pssc file.
Register-PSSessionConfiguration -Name TEST_JEA -Path "C:\Program Files\WindowsPowerShell\Modules\normal_account\sc.pssc"
  1. In the Ansible control node, create a playbook that uses the PSRP module to connect to the managed node and attempts to run a command within the JEA session.
- name: Add windows specific variables
  set_fact:
    ansible_psrp_user: normal_account@mydomain.net
    ansible_password: "{{ my_password }}"
    ansible_host: target_machine.mydomain.net
    ansible_port: 5986
    ansible_connection: psrp
    ansible_psrp_configuration_name: TEST_JEA
    ansible_psrp_auth: kerberos
    ansible_psrp_negotiate_service: HTTP
    ansible_psrp_cert_validation: ignore
    ansible_psrp_protocol: https
    ansible_psrp_read_timeout: 1200

- name: Get Command
  ansible.windows.win_shell: get-command
  register: result

- name: Print result
  debug:
    var: result
  1. Run the playbook and observe the output, which includes all the commands, instead of the expected limited cmdlets and functions defined in the role capability file.

Expected behavior: The output of the get-command should be limited to the cmdlets and functions specified in the JEA role capability file.

Actual behavior: The output of the get-command includes all the commands available, indicating that the JEA role capability file is not being applied correctly.

"stdout_lines": [
            "",
            "CommandType     Name                                               Version    Source                                   ",
            "-----------     ----                                               -------    ------                                   ",
            "Alias           Add-AppPackage                                     2.0.1.0    Appx                                     ",
            "Alias           Add-AppPackageVolume                               2.0.1.0    Appx                                     ",
            "Alias           Add-AppProvisionedPackage                          3.0        Dism                                     ",
            "Alias           Add-ProvisionedAppPackage                          3.0        Dism                                     ",
            "Alias           Add-ProvisionedAppxPackage                         3.0        Dism                                     ",
            "Alias           Add-WindowsFeature                                 2.0.0.0    ServerManager                            ",
            "Alias           Apply-WindowsUnattend                              3.0        Dism                                     ",
            "Alias           Disable-PhysicalDiskIndication                     2.0.0.0    Storage                                  ",
            "Alias           Disable-StorageDiagnosticLog                       2.0.0.0    Storage                                  ",
           ......(truncated)

Additional context: When testing the JEA endpoint using Enter-PSSessionConfiguration command directly on the target machine, the output appears as expected, showing only the limited cmdlets and functions defined in the role capability file. This suggests that the issue occurs when using the Ansible PSRP module.

PS C:\Users\Administrator> Enter-PSSession -ComputerName . -Credential $cred -ConfigurationName DnS_JEA
[localhost]: PS>get-command

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Clear-Host
Cmdlet          Exit-PSSession                                     3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Get-Command                                        3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Get-FormatData                                     3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Get-Module                                         3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Get-Process                                        3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Get-Service                                        3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Measure-Object                                     3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Out-Default                                        3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Out-String                                         3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Select-Object                                      3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Set-Variable                                       3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Write-Host                                         3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Write-Output                                       3.1.0.0    Microsoft.PowerShell.Utility

CC this issue @arslnmsd

jborean93 commented 1 year ago

Ansible can't use JEA, by definition it needs unrestricted access to be able to run the code that is needed. The win_shell command you are running with is just calling powershell.exe so it's a brand new process outside of the JEA session that the initial session is created in which is why it has unrestricted access and the session state you are seeing doesn't get applied.

I am actually surprised it got that far but this is not a valid scenario for Ansible and any of the limitations are placed on the server side and not the client.