Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/files/configure.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import requests

def main():
requests.put("http://localhost:8080/v2-beta/settings/api.host", data='{"id":"api.host","type":"activeSetting","baseType":"setting","name":"api.host","activeValue":null,"inDb":false,"source":null,"value":"172.22.6.76"}')

if __name__ == "__main__":
main()
48 changes: 48 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/files/setup-rancher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import requests
import socket
import os
import time
import debinterface

def get_ip():
adapters = debinterface.Interfaces().adapters
for adapter in adapters:
if "ens" in adapter.attributes['name'] and adapter.attributes['source'] == 'static':
return adapter.attributes['address']
raise Exception("Could not find address")

def setup_rancher():
ip = get_ip()

proxies = {
"http": None,
"https": None,
}

data = {"type":"setting","name":"telemetry.opt","value":"in"}
response = requests.post("http://localhost:8080/v2-beta/setting", json = data, proxies=proxies)
print(response)

null = None
false = False
data = {"id":"api.host","type":"activeSetting","baseType":"setting","name":"api.host","activeValue":null,"inDb":false,"source":null,"value":"http://" + ip + ":8080"}
response = requests.put("http://localhost:8080/v2-beta/settings/api.host", json=data, proxies=proxies)
print(response)

data = {"type":"registrationToken"}
response = requests.post("http://localhost:8080/v2-beta/projects/1a5/registrationtoken", json=data, proxies=proxies)
#link = response.json()["actions"]["activate"]
link = response.json()["links"]["self"]
print(link)

time.sleep(2)

response = requests.get(link, proxies=proxies)
command = response.json()["command"]
print(command)
os.system(command)

if not os.path.exists("/root/ran"):
time.sleep(10)
setup_rancher()
os.system("touch /root/ran")
13 changes: 13 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/manifests/flags.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class rancher::flags {
# this is how secgen
## $secgen_parameters = secgen_functions::get_parameters($::base64_inputs_file)
$leaked_filenames = ["flagsecret"] ##$secgen_parameters['leaked_filenames']
$strings_to_leak = ["flag message"] ##$secgen_parameters['strings_to_leak']

::secgen_functions::leak_files { 'root-home-folder':
storage_directory => "/root",
leaked_filenames => $leaked_filenames,
strings_to_leak => $strings_to_leak,
leaked_from => 'rancher',
}
}
41 changes: 41 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/manifests/install.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
class rancher::install {
Exec {
path => ['/bin', '/usr/bin', '/usr/local/bin', '/sbin', '/usr/sbin']
}

ensure_packages(['apt-transport-https', 'ca-certificates', 'curl', 'gnupg2', 'software-properties-common', 'python3-pip'])

docker::run {'rancher-server':
image => 'rancher/server',
ports => ['8080:8080'],
extra_parameters => '--restart=unless-stopped',
} ->
exec {'wait-for-rancher-server':
command => 'sleep 360',
timeout => 365,
} ->
# docker::image {'rancher/net': } ->
# docker::image {'rancher/network-manager': } ->
# docker::image {'rancher/dns': } ->
# docker::image {'rancher/healthcheck': } ->
# docker::image {'rancher/metadata': } ->
# docker::image {'rancher/scheduler': } ->
docker::image {'rancher/agent':
tag => 'v1.2.11',
} ->
docker::image {'alpine': } ->
file {'/root/setup-rancher.py':
source => 'puppet:///modules/rancher/setup-rancher.py',
mode => '0755',
} ->
exec {'install-debinterface':
command => 'pip3 install debinterface'
} ->
# exec {'configure-rancher':
# command => 'python3 /root/setup-rancher.py',
# environment => [],
# } ->
exec {'set-rancher-configuration-file-to-run-at-boot-via-crontab':
command => 'echo "@reboot root /usr/bin/python3 /root/setup-rancher.py >> /root/rancher_config_log.txt 2>> /root/rancher_config_log.txt" >> /etc/crontab; chmod 644 /etc/crontab'
}
}
3 changes: 3 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/rancher.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include docker
include rancher::install
include rancher::flags
34 changes: 34 additions & 0 deletions modules/vulnerabilities/unix/misc/rancher/secgen_metadata.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0"?>
<vulnerability xmlns="http://github.com/cliffe/SecGen/vulnerability"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://github.com/cliffe/SecGen/vulnerability">

<name>Rancher</name>
<author>Harry J. Hall</author>
<module_license>MIT</module_license>
<description>This exploit allows users of the rancher server to gain access to the hosts running docker that are managed by rancher.
It can be mitigated by limiting permissions of rancher users to read only for untrusted users.</description>

<type>docker</type>
<privilege>root_rwx</privilege>
<access>remote</access>
<platform>linux</platform>
<difficulty>medium</difficulty>

<read_fact>server_name</read_fact>
<read_fact>strings_to_leak</read_fact>
<read_fact>leaked_filenames</read_fact>
<read_fact>ports</read_fact>

<default_input into="strings_to_leak">
<generator type="message_generator" />
</default_input>

<default_input into="leaked_filenames">
<generator type="filename_generator" />
</default_input>

<reference>
https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/rancher_server.rb
</reference>
</vulnerability>