diff --git a/modules/vulnerabilities/unix/misc/rancher/files/configure.py b/modules/vulnerabilities/unix/misc/rancher/files/configure.py new file mode 100644 index 000000000..25d5e198d --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/files/configure.py @@ -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() \ No newline at end of file diff --git a/modules/vulnerabilities/unix/misc/rancher/files/setup-rancher.py b/modules/vulnerabilities/unix/misc/rancher/files/setup-rancher.py new file mode 100644 index 000000000..dc21b5d25 --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/files/setup-rancher.py @@ -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") \ No newline at end of file diff --git a/modules/vulnerabilities/unix/misc/rancher/manifests/flags.pp b/modules/vulnerabilities/unix/misc/rancher/manifests/flags.pp new file mode 100644 index 000000000..66d28bb63 --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/manifests/flags.pp @@ -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', + } +} diff --git a/modules/vulnerabilities/unix/misc/rancher/manifests/install.pp b/modules/vulnerabilities/unix/misc/rancher/manifests/install.pp new file mode 100644 index 000000000..3bcba5c3d --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/manifests/install.pp @@ -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' + } +} diff --git a/modules/vulnerabilities/unix/misc/rancher/rancher.pp b/modules/vulnerabilities/unix/misc/rancher/rancher.pp new file mode 100644 index 000000000..caa24e226 --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/rancher.pp @@ -0,0 +1,3 @@ +include docker +include rancher::install +include rancher::flags diff --git a/modules/vulnerabilities/unix/misc/rancher/secgen_metadata.xml b/modules/vulnerabilities/unix/misc/rancher/secgen_metadata.xml new file mode 100644 index 000000000..0c96f104a --- /dev/null +++ b/modules/vulnerabilities/unix/misc/rancher/secgen_metadata.xml @@ -0,0 +1,34 @@ + + + + Rancher + Harry J. Hall + MIT + 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. + + docker + root_rwx + remote + linux + medium + + server_name + strings_to_leak + leaked_filenames + ports + + + + + + + + + + + https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/http/rancher_server.rb + + \ No newline at end of file