metasploit-framework icon indicating copy to clipboard operation
metasploit-framework copied to clipboard

Fix shell_to_meterpreter wmic OS detection under different language

Open attilarepka opened this issue 2 years ago • 6 comments

This PR fixes shell_to_meterpreter behaviour under Windows 10 environment, when the OS language is set to some foreign language.

Details

Module shell_to_meterpreter uses wmic command to detect Windows architecture. When windows language is set to something else than English, the output of wmic command will not be capture by the regexp.

Verification

List the steps needed to make sure this thing works

  • [ ] Set victims Windows 10 machine's language to some other language ( e.g.: Italian, German, French, etc.)
  • [ ] Start msfconsole
  • [ ] Get a valid shell session to the victim machine
  • [ ] use post/multi/manage/shell_to_meterpreter
  • [ ] exploit
  • [ ] Verify you get a meterpreter session

attilarepka avatar Sep 01 '22 13:09 attilarepka

This PR fixes https://github.com/rapid7/metasploit-framework/issues/16785.

That seems unlikely. #16785 is due to use of wmic os get osarchitecture which is not a valid WMIC query on XP SP3.

image

bcoles avatar Sep 01 '22 23:09 bcoles

My apologies - I modified the PR name and details.

P.S.: Under Win XP SP3 the wmic cpu get DataWidth command should work, but needs to be verified and the regexp should be modified accordingly, maybe in a different PR.

attilarepka avatar Sep 02 '22 06:09 attilarepka

What is it about 64-bit that doesn't match but if arch =~ /64/m && arch =~ /bit/m does? Does it use a long dash () or something else? Can you show an example of the output in text format?


P.S.: Under Win XP SP3 the wmic cpu get DataWidth command should work

That query works, although that might be retrieving the CPU arch rather than the OS arch.

but needs to be verified and the regexp should be modified accordingly maybe in a different PR.

Out of scope for this PR and would need to be verified as you suggest.

bcoles avatar Sep 02 '22 06:09 bcoles

What is it about 64-bit that doesn't match but if arch =~ /64/m && arch =~ /bit/m does? Does it use a long dash () or something else? Can you show an example of the output in text format?

https://replit.com/languages/ruby Feel free to play around here with this bit of code:

arch = "64—bit"
# arch = "64 bites"
# arch = "64bitové"

if arch =~ /64/m && arch=~ /bit/m
  puts "64-bit architecture found"
elsif arch =~ /32/m && arch=~ /bit/m
  puts "32-bit architecture found"
else
  puts "Target is running Windows on an unsupported architecture such as Windows ARM!"
end

The only thing this regexp currently is not handling is case insensitivity, meaning if we have Bit vs bit this scenario won't be captured. ^ This needs verification if any localization uses capitalized version of bit.

That query works, although that might be retrieving the CPU arch rather than the OS arch.

According to this, the CPU check is a different command, but then again - needs verification.

attilarepka avatar Sep 02 '22 06:09 attilarepka

Feel free to play around here with this bit of code

Unfortunately this will still fail on some systems:

>wmic os get osarchitecture
OSArchitecture
64 ビット

bit may not appear in the response. (Also, the regex m modifier is unnecessary.)

A better approach may be to simply check whether any lines start with 32 or 64.

The output from wmic os get osarchitecture is very short.

>wmic os get osarchitecture
OSArchitecture
64-bit

Also, wmic reflects OSArchitecture in the response only if the query is valid.

>wmic os get asdf
Node - WIN-7
ERROR:
Description = Invalid query

You could confirm that the query was accepted and the response is valid by confirming OSArchitecture is in the response using something like this:

      arch = cmd_exec('wmic os get osarchitecture').to_s.downcase

      unless arch.include?('osarchitecture')
        print_error('Could not retrieve Windows system architecture!')
        return nil
      end

      if arch =~ /^64/
        payload_name = 'windows/x64/meterpreter/reverse_tcp'
        larch = [ARCH_X64]
        psh_arch = 'x64'
      if arch =~ /^32/
        payload_name = 'windows/meterpreter/reverse_tcp'
        larch = [ARCH_X86]
        psh_arch = 'x86'
      else
        print_error("wmic returned unsupported architecture: #{arch}")
        return nil
      end

The unsupported architecture check (ie, ARM) is really just a catch-all (introduced in https://github.com/rapid7/metasploit-framework/commit/1b9f9f062076fa96889efac124027c75ac7c3dd2) to return an error instead of presuming any non-64-bit system is 32-bit x86. Returning an error message stating the architecture is unsupported is more appropriate.

Without access to an ARM system, I have no idea what wmic os get osarchitecture would return. But given that we don't have ARM payloads for Windows it should not matter, unless ARM systems also return a line starting with 32 or 64.


As an aside, and outside the scope of this PR, detecting the OS architecture seems like the kind of functionality that we should have a library method to perform.

Using get_env('PROCESSOR_ARCHITECTURE') is one alternative (or using the Registry). This would also resolve the issue of shell_to_meterpreter failing on Windows XP. But this returns the processor architecture which won't necessarily match the OS architecture.

>echo %PROCESSOR_ARCHITECTURE%
AMD64

bcoles avatar Sep 12 '22 02:09 bcoles

Adding the Delayed tag to this due to blockers that @bcoles mentioned above. We will likely need to figure out some testing platforms to verify things and find potential solutions or any edge cases before these changes can be landed.

Will leave this PR open for now however if there are no updates it may be better to open a new issue report. This way I can mark it the report as confirmed so that we can keep discussions open whilst we figure out the best approach to this issue.

gwillcox-r7 avatar Oct 11 '22 04:10 gwillcox-r7

Thanks for your contribution to Metasploit Framework! We've looked at this pull request, and we agree that it seems like a good addition to Metasploit, but it looks like it is not quite ready to land. We've labeled it attic and closed it for now.

What does this generally mean? It could be one or more of several things:

  • It doesn't look like there has been any activity on this pull request in a while
  • We may not have the proper access or equipment to test this pull request, or the contributor doesn't have time to work on it right now.
  • Sometimes the implementation isn't quite right and a different approach is necessary.

We would love to land this pull request when it's ready. If you have a chance to address all comments, we would be happy to reopen and discuss how to merge this!

github-actions[bot] avatar Jan 04 '23 14:01 github-actions[bot]

Created issue #17896 to track OS architecture detection failure on non-English locales.

bcoles avatar Apr 17 '23 05:04 bcoles