Linux Container Enumeration - Metasploit


This page contains detailed information about how to use the post/linux/gather/enum_containers metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Linux Container Enumeration
Module: post/linux/gather/enum_containers
Source code: modules/post/linux/gather/enum_containers.rb
Disclosure date: -
Last modification time: 2021-03-11 17:23:44 +0000
Supported architecture(s): -
Supported platform(s): Linux
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module attempts to enumerate containers on the target machine and optionally run a command on each active container found. Currently it supports Docker, LXC and RKT.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Basic Usage


There are two ways to execute this post module.

From the Meterpreter prompt

The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:

meterpreter > run post/linux/gather/enum_containers

From the msf prompt

The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.

msf > use post/linux/gather/enum_containers
msf post(enum_containers) > show options
    ... show and set options ...
msf post(enum_containers) > set SESSION session-id
msf post(enum_containers) > exploit

If you wish to run the post against all sessions from framework, here is how:

1 - Create the following resource script:


framework.sessions.each_pair do |sid, session|
  run_single("use post/linux/gather/enum_containers")
  run_single("set SESSION #{sid}")
  run_single("run")
end

2 - At the msf prompt, execute the above resource script:

msf > resource path-to-resource-script

Required Options


  • SESSION: The session to run this module on.

Knowledge Base


Container Platforms


This module looks for container platforms running on the target and then lists any currently running containers for each platform found. The currently supported container platforms are:

  1. Docker
  2. LXC
  3. RKT

Verification Steps


  1. Start msfconsole
  2. Get a session via exploit of your choice
  3. Load the module use post/linux/gather/enum_containers
  4. Set the session set session 1
  5. run the module run
  6. You should get feedback if any container platforms are runnable by the current user and if there are any active containers running on them

Options


SESSION

Which session to use, which can be viewed with sessions -l

CMD

Optional shell command to run on each running container

Scenarios


Scenario 1: Docker is installed with 4 running containers
msf5 post(linux/gather/enum_containers) > set session 4 session => 4 msf5 post(linux/gather/enum_containers) > run

[+] docker was found on the system! [+] docker: 1 Running Containers / 5 Total CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 853913ae1e17 nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp lucid_tu 0422ad0a1d6e nginx "/docker-entrypoint.…" About an hour ago Exited (0) About an hour ago gifted_thompson 35930fd284e1 nginx "/docker-entrypoint.…" 2 days ago Exited (0) 5 hours ago unruffled_gates a7149a9a858e nginx "/docker-entrypoint.…" 2 days ago Exited (127) 2 days ago pedantic_tesla cfa40ec4d85c nginx "/docker-entrypoint.…" 2 days ago Exited (0) 2 days ago fervent_gates [+] Results stored in: /home/gwillcox/.msf4/loot/20200805143522_default_172.27.129.4_host.docker_cont_134332.txt [*] Post module execution completed

Scenario 2: Docker, LXC and RKT are installed, and each of them are running their own containers
msf5 post(linux/gather/enum_containers) > set session 2 session => 2 msf5 post(linux/gather/enum_containers) > exploit

[+] docker was found on the system! [+] docker: 1 Running Containers / 5 Total CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 853913ae1e17 nginx "/docker-entrypoint.…" About an hour ago Up About an hour 80/tcp lucid_tu 0422ad0a1d6e nginx "/docker-entrypoint.…" About an hour ago Exited (0) About an hour ago gifted_thompson 35930fd284e1 nginx "/docker-entrypoint.…" 2 days ago Exited (0) 5 hours ago unruffled_gates a7149a9a858e nginx "/docker-entrypoint.…" 2 days ago Exited (127) 2 days ago pedantic_tesla cfa40ec4d85c nginx "/docker-entrypoint.…" 2 days ago Exited (0) 2 days ago fervent_gates [+] Results stored in: /home/gwillcox/.msf4/loot/20200805193841_default_172.27.129.4_host.docker_cont_169517.txt

[+] lxc was found on the system! [+] lxc: 1 Running Containers / 1 Total NAME STATE IPV4 IPV6 TYPE SNAPSHOTS one-fox RUNNING 10.166.198.97 (eth0) fd42:a29:a47e:79c6:216:3eff:fe1f:1dca (eth0) CONTAINER 0 [+] Results stored in: /home/gwillcox/.msf4/loot/20200805193842_default_172.27.129.4_host.lxc_contain_448673.txt

[+] rkt was found on the system! [+] rkt: 2 Running Containers / 1 Total UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS 1f5f73a2 etcd coreos.com/etcd:v3.1.7 running 32 minutes ago 32 minutes ago default:ip4=172.16.28.3 384c8a25 etcd coreos.com/etcd:v3.1.7 exited garbage 4 hours ago 4 hours ago default:ip4=172.16.28.2 [+] Results stored in: /home/gwillcox/.msf4/loot/20200805193842_default_172.27.129.4_host.rkt_contain_801968.txt

[*] Post module execution completed msf5 post(linux/gather/enum_containers) >

Scenario 3: No container software is runnable msf5 post(linux/gather/enum_containers) > set session 6 session => 6 msf5 post(linux/gather/enum_containers) > run [-] No container software appears to be installed or runnable by the current user [*] Post module execution completed

Scenario 4: List all containers and execute the env command on all running containers
msf5 post(linux/gather/enum_containers) > set session 6 session => 6 msf5 post(linux/gather/enum_containers) > set CMD "env" CMD => env msf5 post(linux/gather/enum_containers) > run

[+] docker was found on the system! [+] docker: 1 Running Containers / 5 Total CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 853913ae1e17 nginx "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp lucid_tu 0422ad0a1d6e nginx "/docker-entrypoint.…" 2 hours ago Exited (0) 2 hours ago gifted_thompson 35930fd284e1 nginx "/docker-entrypoint.…" 2 days ago Exited (0) 6 hours ago unruffled_gates a7149a9a858e nginx "/docker-entrypoint.…" 2 days ago Exited (127) 2 days ago pedantic_tesla cfa40ec4d85c nginx "/docker-entrypoint.…" 2 days ago Exited (0) 2 days ago fervent_gates [+] Results stored in: /home/gwillcox/.msf4/loot/20200805202620_default_172.27.129.4_host.docker_cont_406553.txt

[*] Executing command on docker container lucid_tu [+] PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=853913ae1e17 NGINX_VERSION=1.19.1 NJS_VERSION=0.4.2 PKG_RELEASE=1~buster HOME=/root [+] lxc was found on the system! [+] lxc: 1 Running Containers / 1 Total NAME STATE IPV4 IPV6 TYPE SNAPSHOTS one-fox RUNNING 10.166.198.97 (eth0) fd42:a29:a47e:79c6:216:3eff:fe1f:1dca (eth0) CONTAINER 0 [+] Results stored in: /home/gwillcox/.msf4/loot/20200805202623_default_172.27.129.4_host.lxc_contain_977736.txt

[*] Executing command on lxc container one-fox [+] PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin container=lxc HOME=/root USER=root LANG=C.UTF-8 [+] rkt was found on the system! [+] rkt: 2 Running Containers / 1 Total UUID APP IMAGE NAME STATE CREATED STARTED NETWORKS 1f5f73a2 etcd coreos.com/etcd:v3.1.7 running 1 hour ago 1 hour ago default:ip4=172.16.28.3 384c8a25 etcd coreos.com/etcd:v3.1.7 exited garbage 5 hours ago 5 hours ago default:ip4=172.16.28.2 [+] Results stored in: /home/gwillcox/.msf4/loot/20200805202625_default_172.27.129.4_host.rkt_contain_522670.txt

[] Executing command on rkt container 1f5f73a2 [-] RKT containers do not support command execution Use rkt enter '1f5f73a2' to manually enumerate this container [+] USER=root HOME=/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/system/bin:/system/sbin:/system/xbin LANG=C PWD=/home/gwillcox/git/metasploit-framework [] Executing command on rkt container 384c8a25 [-] RKT containers do not support command execution Use rkt enter '384c8a25' to manually enumerate this container [+] USER=root HOME=/root PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/system/bin:/system/sbin:/system/xbin LANG=C PWD=/home/gwillcox/git/metasploit-framework [*] Post module execution completed msf5 post(linux/gather/enum_containers) >

Go back to menu.

Msfconsole Usage


Here is how the linux/gather/enum_containers post exploitation module looks in the msfconsole:

msf6 > use post/linux/gather/enum_containers

msf6 post(linux/gather/enum_containers) > show info

       Name: Linux Container Enumeration
     Module: post/linux/gather/enum_containers
   Platform: Linux
       Arch: 
       Rank: Normal

Provided by:
  stealthcopter

Compatible session types:
  Meterpreter
  Shell

Basic options:
  Name     Current Setting  Required  Description
  ----     ---------------  --------  -----------
  CMD                       no        Optional command to run on each running container
  SESSION                   yes       The session to run this module on.

Description:
  This module attempts to enumerate containers on the target machine 
  and optionally run a command on each active container found. 
  Currently it supports Docker, LXC and RKT.

Module Options


This is a complete list of options available in the linux/gather/enum_containers post exploitation module:

msf6 post(linux/gather/enum_containers) > show options

Module options (post/linux/gather/enum_containers):

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   CMD                       no        Optional command to run on each running container
   SESSION                   yes       The session to run this module on.

Advanced Options


Here is a complete list of advanced options supported by the linux/gather/enum_containers post exploitation module:

msf6 post(linux/gather/enum_containers) > show advanced

Module advanced options (post/linux/gather/enum_containers):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Post Actions


This is a list of all post exploitation actions which the linux/gather/enum_containers module can do:

msf6 post(linux/gather/enum_containers) > show actions

Post actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the linux/gather/enum_containers post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 post(linux/gather/enum_containers) > show evasion

Module evasion options:

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

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

Invalid container type <CONTAINER_TYPE>


Here is a relevant code snippet related to the "Invalid container type <CONTAINER_TYPE>" error message:

42:	    when 'rkt'
43:	      # Apparently rkt doesn't play nice with 2>&1 for most commands, though `rkt help`
44:	      # seems to be fine so this is why its used here vs just 'rkt'
45:	      command = 'rkt help >/dev/null 2>&1 && echo true'
46:	    else
47:	      print_error("Invalid container type #{container_type}")
48:	      return false
49:	    end
50:	    cmd_exec(command) =~ /true$/
51:	  end
52:	

Invalid container type '<CONTAINER_TYPE>'


Here is a relevant code snippet related to the "Invalid container type '<CONTAINER_TYPE>'" error message:

70:	                  'rkt list | tail -n +2 | wc -l'
71:	                else
72:	                  'rkt list | tail -n +2 | grep running | wc -l'
73:	                end
74:	    else
75:	      print_error("Invalid container type '#{container_type}'")
76:	      return 0
77:	    end
78:	
79:	    result = cmd_exec(command)
80:	    if result =~ /denied/

Was unable to enumerate the number of <CONTAINER_TYPE> containers due to a lack of permissions!


Here is a relevant code snippet related to the "Was unable to enumerate the number of <CONTAINER_TYPE> containers due to a lack of permissions!" error message:

76:	      return 0
77:	    end
78:	
79:	    result = cmd_exec(command)
80:	    if result =~ /denied/
81:	      print_error("Was unable to enumerate the number of #{container_type} containers due to a lack of permissions!")
82:	      return 0
83:	    else
84:	      result.to_i
85:	    end
86:	  end

Invalid container type '<CONTAINER_TYPE>'


Here is a relevant code snippet related to the "Invalid container type '<CONTAINER_TYPE>'" error message:

100:	        end
101:	      end.join.strip
102:	    when 'rkt'
103:	      result = cmd_exec('rkt list')
104:	    else
105:	      print_error("Invalid container type '#{container_type}'")
106:	      return nil
107:	    end
108:	    result
109:	  end
110:	

Invalid container type '<CONTAINER_TYPE>'


Here is a relevant code snippet related to the "Invalid container type '<CONTAINER_TYPE>'" error message:

116:	    when 'lxc'
117:	      command = 'lxc list -c n,s --format csv 2>/dev/null | grep ,RUNNING|cut -d, -f1'
118:	    when 'rkt'
119:	      command = 'rkt list | tail -n +2 | cut -f1'
120:	    else
121:	      print_error("Invalid container type '#{container_type}'")
122:	      return nil
123:	    end
124:	    cmd_exec(command).each_line.map(&:strip)
125:	  end
126:	

RKT containers do not support command executionnUse the command "rkt enter '<CONTAINER_IDENTIFIER>'" to manually enumerate this container


Here is a relevant code snippet related to the "RKT containers do not support command executionnUse the command "rkt enter '<CONTAINER_IDENTIFIER>'" to manually enumerate this container" error message:

130:	    when 'docker'
131:	      command = "docker exec '#{container_identifier}' #{command}"
132:	    when 'lxc'
133:	      command = "lxc exec '#{container_identifier}' -- #{command}"
134:	    when 'rkt'
135:	      print_error("RKT containers do not support command execution\nUse the command \"rkt enter '#{container_identifier}'\" to manually enumerate this container")
136:	      return nil
137:	    else
138:	      print_error("Invalid container type '#{container_type}'")
139:	      return nil
140:	    end

Invalid container type '<CONTAINER_TYPE>'


Here is a relevant code snippet related to the "Invalid container type '<CONTAINER_TYPE>'" error message:

133:	      command = "lxc exec '#{container_identifier}' -- #{command}"
134:	    when 'rkt'
135:	      print_error("RKT containers do not support command execution\nUse the command \"rkt enter '#{container_identifier}'\" to manually enumerate this container")
136:	      return nil
137:	    else
138:	      print_error("Invalid container type '#{container_type}'")
139:	      return nil
140:	    end
141:	    vprint_status("Running #{command}")
142:	    cmd_exec(command)
143:	  end

No container software appears to be installed or runnable by the current user


Here is a relevant code snippet related to the "No container software appears to be installed or runnable by the current user" error message:

145:	  # Run Method for when run command is issued
146:	  def run
147:	    platforms = %w[docker lxc rkt].select { |p| runnable(p) }
148:	
149:	    if platforms.empty?
150:	      print_error('No container software appears to be installed or runnable by the current user')
151:	      return
152:	    end
153:	
154:	    platforms.each do |platform|
155:	      print_good("#{platform} was found on the system!")

No active or inactive containers were found for <PLATFORM>n


Here is a relevant code snippet related to the "No active or inactive containers were found for <PLATFORM>n" error message:

154:	    platforms.each do |platform|
155:	      print_good("#{platform} was found on the system!")
156:	      num_containers = count_containers(platform, count_inactive: false)
157:	
158:	      if num_containers == 0
159:	        print_error("No active or inactive containers were found for #{platform}\n")
160:	      else
161:	        num_running_containers = count_containers(platform, count_inactive: true)
162:	        print_good("#{platform}: #{num_running_containers} Running Containers / #{num_containers} Total")
163:	      end
164:	

Go back to menu.


Go back to menu.

See Also


Check also the following modules related to this module:

Authors


  • stealthcopter

Version


This page has been produced using Metasploit Framework version 6.2.26-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.