Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #cd for Powershell Sessions #18021

Merged
merged 2 commits into from May 25, 2023
Merged

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented May 23, 2023

Per PowerShell/PowerShell#10278 the .NET working directory is different from the Powershell one. Our Powershell Post API methods use a mix of Powershell and .NET methods. This means that after changing directory, methods that use .NET will fail when given relative paths because the current working directory is different. The proposed solution is to set the .NET working directory at the same time so they stay synchronized. With this in place, 3 tests will start to pass from the post/test/file module, leaving just one failure.

Also added is a method to escape Windows command literals that's more robust that what was added here which ended up breaking the cmd/windows/powershell_reverse_tcp payload when delivered via psexec.

Verification

  • Start msfconsole
  • use exploit/windows/smb/psexec
  • Set the payload to cmd/windows/powershell_reverse_tcp
  • Set the necessary options and run the module to open a session
  • Run loadpath test/modules
  • Run the post/test/file module with the new session.
  • The should delete a symbolic link target will fail but the rest will pass
    • should create directories passes 馃煝
    • should list the directory we just made passes 馃煝
    • should not recurse into symbolic link directories passes 馃煝

New Output

msf6 post(test/file) > run

[!] SESSION may not be compatible with this module:
[!]  * incompatible session type: powershell
[*] Running against session -1
[*] Session type is powershell and platform is windows
[+] should write binary data
[+] should read the binary data we just wrote
[+] should delete binary files
[+] should append binary data
[+] should test for file existence
[+] should create text files
[+] should read the text we just wrote
[+] should append text files
[+] should delete text files
[+] should move files
[+] should test for directory existence
[+] should create directories
[+] should list the directory we just made
[+] should recursively delete the directory we just made
[-] FAILED: should delete a symbolic link target
[+] should not recurse into symbolic link directories
[-] Passed: 15; Failed: 1
[*] Post module execution completed

Old Output

msf6 post(test/file) > run

[!] SESSION may not be compatible with this module:
[!]  * incompatible session type: powershell
[*] Running against session -1
[*] Session type is powershell and platform is windows
[+] should write binary data
[+] should read the binary data we just wrote
[+] should delete binary files
[+] should append binary data
[+] should test for file existence
[+] should create text files
[+] should read the text we just wrote
[+] should append text files
[+] should delete text files
[+] should move files
[+] should test for directory existence
[-] FAILED: should create directories
[-] FAILED: should list the directory we just made
[+] should recursively delete the directory we just made
[-] FAILED: should delete a symbolic link target
[-] FAILED: should not recurse into symbolic link directories
[-] Passed: 12; Failed: 4
[*] Post module execution completed
msf6 post(test/file) > 

# @param [Boolean] spaces Whether or not to escape spaces. If the string is being passed to echo, set this to false
# otherwise if it's an argument, set it to true.
# @return [String] The escaped string.
def self.escape_cmd_literal(string, spaces:)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spaces is optional here because sometimes they need to be escaped, and other times they do not.

This snippet demonstrates the issue. A small Python stub is used to print the arguments then one" "argument is passed to it showing that the space is kept but when passed to echo, the double quotes are kept.

Microsoft Windows [Version 10.0.17763.4377](c) 2018 Microsoft Corporation. All rights reserved.
msflab\smcintyre@DC C:\Users\smcintyre>type args.py
import sys; print(repr(sys.argv))
msflab\smcintyre@DC C:\Users\smcintyre>python args.py one" "argument
['args.py', 'one argument']
msflab\smcintyre@DC C:\Users\smcintyre>echo one" "argument 
one" "argument
msflab\smcintyre@DC C:\Users\smcintyre>

Allowing the user to specify means the escaped value can be used in both contexts. Psexec should not escape spaces because the command is passed to echo.

@jheysel-r7
Copy link
Contributor

Before

msf6 post(test/file) > run

[!] SESSION may not be compatible with this module:
[!]  * incompatible session type: powershell
[*] Running against session 2
[*] Session type is powershell and platform is windows
[+] should write binary data
[+] should read the binary data we just wrote
[+] should delete binary files
[+] should append binary data
[+] should test for file existence
[+] should create text files
[+] should read the text we just wrote
[+] should append text files
[+] should delete text files
[+] should move files
[+] should test for directory existence
[-] FAILED: should create directories
[-] FAILED: should list the directory we just made
[+] should recursively delete the directory we just made
[-] failed to create the symbolic link
[-] FAILED: should delete a symbolic link target
[-] FAILED: should not recurse into symbolic link directories
[-] Passed: 12; Failed: 4
[*] Post module execution completed

After

msf6 post(test/file) > run

[!] SESSION may not be compatible with this module:
[!]  * incompatible session type: powershell
[*] Running against session -1
[*] Session type is powershell and platform is windows
[+] should test for directory existence
[+] should create directories
[+] should list the directory we just made
[+] should recursively delete the directory we just made
[+] should delete a symbolic link target
[+] should not recurse into symbolic link directories
[+] should write binary data
[+] should read the binary data we just wrote
[+] should delete binary files
[+] should append binary data
[+] should test for file existence
[+] should create text files
[+] should read the text we just wrote
[+] should append text files
[+] should delete text files
[+] should move files
[*] Passed: 16; Failed: 0
[*] Post module execution completed

Did some investigating but ultimately wasn't sure what was causing should not recurse into symbolic link directories to pass in my test but fail in yours, @zeroSteiner. I included some target/ session info below incase that helps future investigation.

system info of target

msf6 post(test/file) > sessions -l

Active sessions
===============

  Id  Name  Type                Information                         Connection
  --  ----  ----                -----------                         ----------
  1         powershell windows  DESKTOP-8ATHH6O$ @ DESKTOP-8ATHH6O  192.168.1.81:4444 -> 192.168.1.81:53271 (172.16.199.140)

msf6 post(test/file) > sessions -i 1
[*] Starting interaction with 1...

PS C:\Windows\system32> whoami
nt authority\system
PS C:\Windows\system32> systeminfo

Host Name:                 DESKTOP-8ATHH6O
OS Name:                   Microsoft Windows 10 Pro
OS Version:                10.0.19045 N/A Build 19045
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free
Registered Owner:          Windows User
Registered Organization:
Product ID:                00331-10000-00001-AA073
Original Install Date:     9/28/2022, 8:31:33 AM
System Boot Time:          5/25/2023, 11:41:54 AM
System Manufacturer:       VMware, Inc.
System Model:              VMware7,1
System Type:               x64-based PC
Processor(s):              2 Processor(s) Installed.
                           [01]: Intel64 Family 6 Model 158 Stepping 10 GenuineIntel ~2592 Mhz
                           [02]: Intel64 Family 6 Model 158 Stepping 10 GenuineIntel ~2592 Mhz
BIOS Version:              VMware, Inc. VMW71.00V.18452719.B64.2108091906, 8/9/2021
Windows Directory:         C:\Windows
System Directory:          C:\Windows\system32
Boot Device:               \Device\HarddiskVolume1
System Locale:             en-us;English (United States)
Input Locale:              en-us;English (United States)
Time Zone:                 (UTC-05:00) Eastern Time (US & Canada)
Total Physical Memory:     8,703 MB
Available Physical Memory: 4,723 MB
Virtual Memory: Max Size:  10,111 MB
Virtual Memory: Available: 4,284 MB
Virtual Memory: In Use:    5,827 MB
Page File Location(s):     C:\pagefile.sys
Domain:                    WORKGROUP
Logon Server:              N/A
Hotfix(s):                 11 Hotfix(s) Installed.
                           [01]: KB5022502
                           [02]: KB4562830
                           [03]: KB4570334
                           [04]: KB4580325
                           [05]: KB4586864
                           [06]: KB5005716
                           [07]: KB5012170
                           [08]: KB5015684
                           [09]: KB5026361
                           [10]: KB5023794
                           [11]: KB5025315
Network Card(s):           2 NIC(s) Installed.
                           [01]: Intel(R) 82574L Gigabit Network Connection
                                 Connection Name: Ethernet0
                                 DHCP Enabled:    Yes
                                 DHCP Server:     172.16.199.254
                                 IP address(es)
                                 [01]: 172.16.199.140
                                 [02]: fe80::401:7a8:cd85:40f6
                           [02]: Bluetooth Device (Personal Area Network)
                                 Connection Name: Bluetooth Network Connection
                                 Status:          Media disconnected
Hyper-V Requirements:      A hypervisor has been detected. Features required for Hyper-V will not be displayed.

@jheysel-r7 jheysel-r7 merged commit d825515 into rapid7:master May 25, 2023
30 checks passed
@jheysel-r7 jheysel-r7 added rn-enhancement release notes enhancement enhancement labels May 25, 2023
@jheysel-r7
Copy link
Contributor

Release Notes

The Powershell Post API methods use a mix of Powershell and .NET methods which have different ways of keeping track of the current working directory. This changes fixes the ambiguity by synchronizing the current working directory referenced by each set of methods.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement rn-enhancement release notes enhancement
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

2 participants