Skip to content

Instantly share code, notes, and snippets.

@mgreen27
Last active November 4, 2023 09:18
Show Gist options
  • Select an option

  • Save mgreen27/518f7af0b2b1abce1c8e75978548d7c0 to your computer and use it in GitHub Desktop.

Select an option

Save mgreen27/518f7af0b2b1abce1c8e75978548d7c0 to your computer and use it in GitHub Desktop.

Revisions

  1. mgreen27 revised this gist Oct 26, 2023. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions blacklotus_demo.ps1
    2 additions, 2 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  2. mgreen27 revised this gist Oct 26, 2023. 1 changed file with 10 additions and 4 deletions.
    14 changes: 10 additions & 4 deletions blacklotus_demo.ps1
    10 additions, 4 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  3. mgreen27 revised this gist Oct 26, 2023. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions blacklotus_demo.ps1
    9 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
  4. mgreen27 created this gist Oct 23, 2023.
    127 changes: 127 additions & 0 deletions Patch-RDP.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    Function Patch-RDP {
    <#
    .SYNOPSIS
    Patch RDP to enable multiple RDP sessions on non RDP servers.
    Name: patch_rdp.ps1
    Version: 0.2
    Author: Matt Green - @mgreen27
    .DESCRIPTION
    Patch termsrv.dll to enable multiple RDP sessions on non RDP servers.
    This script will shutdown relevant services to sucessfully enable the
    patch.
    This script patches the existing c:\windows\system32\termsrv.dll and
    will invalidate authenticode.
    A backup will be created at c:\windows\system32\termsrv.dll.backup
    There are several switches availible.
    -remove patch
    -TargetBytes: defaults to latest dll version, you can add in hex
    values needed to patch additional versions.
    References:
    https://www.mysysadmintips.com/windows/clients/998-multiple-rdp-remote-desktop-sessions-in-windows-11
    #>

    Param(
    [Parameter(Mandatory=$false)] [Switch]$remove,
    [Parameter(Mandatory=$false)] $TargetBytes = '39 81 3C 06 00 00 0F 84 .. .. 0. 00'
    )


    if ( $TargetBytes.Length -eq 35 ) {
    Write-Host "`nPatch-RDP: Stopping relevant services"
    stop-service UmRdpService
    stop-service TermService
    stop-service EventLog -force

    $action = $null

    # take ownership and prep ACL
    $ACL_termsrv = get-acl c:\windows\system32\termsrv.dll

    $NEWACL_termsrv = get-acl $env:USERPROFILE
    Set-Acl c:\windows\system32\termsrv.dll $NEWACL_termsrv

    # We use termmgr.dll as this should have required ACL
    $ACL_termsrv = get-acl c:\windows\system32\termmgr.dll

    # Read DLL as byte-array in order to modify the bytes.
    $DLLBytes = get-content c:\windows\system32\termsrv.dll -raw -encoding byte # PowerShell traditional version
    $DLLTxt = $DLLBytes.forEach('ToString', 'X2') -join ' '
    $Ispatched = Select-String -InputObject $DLLTxt -Pattern 'B8 00 01 00 00 89 81 38 06 00 00 90' -CaseSensitive -SimpleMatch
    #$Unpatched = Select-String -InputObject $DLLTxt -Pattern '39 81 3C 06 00 00 0F 84 A1 8F 01 00' -CaseSensitive -SimpleMatch

    if( $Ispatched ) {
    Write-Host "`ttermsrv.dll Patch found"

    if( $remove) {
    fc.exe /b c:\windows\system32\termsrv.dll.backup c:\windows\system32\termsrv.dll
    Write-Host "`tCheck backup different manually before proceeding or quit script"
    pause

    Copy-Item c:\windows\system32\termsrv.dll.backup c:\windows\system32\termsrv.dll -Force
    Remove-Item C:\windows\system32\termsrv.dll.backup -Force

    $action = "patch removed"
    # final step of correct ACL added in common flow at end of script
    }
    else{
    Write-Host "`tLooks like this machine is already patched. exiting"
    # can add appropriate manual unpatch steps here but update is easier....
    }
    }
    else{
    Write-Host "`ttermsrv.dll Patch not found"

    if( $remove) {
    Write-Host "`tNothing to do... exiting"
    }
    else{
    $DLLTxt_replaced = $DLLTxt -replace $TargetBytes, 'B8 00 01 00 00 89 81 38 06 00 00 90' # termsrv.dll 10.0.17763.1697
    [byte[]] $DLLBytes_replaced = -split $DLLTxt_replaced -replace '^', '0x'
    Set-Content c:\windows\system32\termsrv.dll.patched -encoding byte -Value $DLLBytes_replaced

    # create backup
    Copy-Item c:\windows\system32\termsrv.dll c:\windows\system32\termsrv.dll.backup -Force

    fc.exe /b c:\windows\system32\termsrv.dll.backup c:\windows\system32\termsrv.dll
    fc.exe /b c:\windows\system32\termsrv.dll.patched c:\windows\system32\termsrv.dll
    Write-Host "`tCheck backup matches and patch different manually or quit script"
    pause

    Copy-Item c:\windows\system32\termsrv.dll.patched c:\windows\system32\termsrv.dll -Force
    Remove-Item C:\windows\system32\termsrv.dll.patched -Force
    $action = "patch added"
    }
    }

    # readd expected acl/permission
    set-acl c:\windows\system32\termsrv.dll $ACL_termsrv

    Write-Host "`nPatch-RDP: Restarting services"

    start-service UmRdpService
    start-service TermService
    start-service EventLog


    if( $action) {
    Write-Host "`nPatch-RDP: $action"
    }
    else{
    Write-Host "`nPatch-RDP: completed"
    }
    }
    else {
    Write-Host "`nPatch-RDP: Exiting - TargetBytes incorrect length."
    Write-Host "`t`$TargetBytes entered - $TargetBytes"
    Write-Host "`t`Should be hex values as a string with wildcards accepted."
    Write-Host "`t`$TargetBytes default - 39 81 3C 06 00 00 0F 84 .. .. 0. 00"
    }
    }