SMB
Nmap discovered a Windows Directory service on the target port 139
and 445
Null Session
┌──(kali㉿kali)-[~/archive/htb/labs/authority]
└─$ smbclient -L //$IP/
Password for [WORKGROUP\kali]:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
Department Shares Disk
Development Disk
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
SYSVOL Disk Logon server share
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.11.222 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
There are 2 none default shares; Department Shares
and Development
I was able to access the Department Shares
share, but listing was denied
For the rest, I had either no access or listing
Development
┌──(kali㉿kali)-[~/archive/htb/labs/authority]
└─$ smbclient //$IP/Development
password for [workgroup\kali]:
Try "help" to get a list of possible commands.
smb: \> ls
. d 0 fri mar 17 14:20:38 2023
.. d 0 fri mar 17 14:20:38 2023
automation d 0 fri mar 17 14:20:40 2023
5888511 blocks of size 4096. 1357449 blocks available
smb: \> cd Automation
smb: \Automation\> ls
. d 0 fri mar 17 14:20:40 2023
.. d 0 fri mar 17 14:20:40 2023
ansible d 0 fri mar 17 14:20:50 2023
5888511 blocks of size 4096. 1357369 blocks available
smb: \Automation\> cd Ansible
smb: \Automation\Ansible\> ls
. d 0 fri mar 17 14:20:50 2023
.. d 0 fri mar 17 14:20:50 2023
adcs d 0 fri mar 17 14:20:48 2023
ldap d 0 fri mar 17 14:20:48 2023
pwm d 0 fri mar 17 14:20:48 2023
share d 0 fri mar 17 14:20:48 2023
5888511 blocks of size 4096. 1357289 blocks available
The Development
share is accessible and contains the Ansible directory
ansible is a suite of software tools that enables infrastructure as code. It is open-source and the suite includes software provisioning, configuration management, and application deployment functionality. Ansible can be used to automate tasks such as user and group management, domain controller configuration, and group policy management. Ansible uses a declarative language called YAML to define the desired state of the Active Directory environment, and it leverages WinRM or PowerShell remoting to communicate with Windows systems. By using Ansible with Active Directory, administrators can efficiently automate repetitive tasks, enforce consistency, and improve overall system management.
┌──(kali㉿kali)-[~/archive/htb/labs/authority]
└─$ mkdir -p smb/development ; cd smb/development ; smbget smb://$IP/Development -e -R
password for [kali] connecting to //10.10.11.222/development:
Using workgroup WORKGROUP, user kali
Encryption required and setup failed with error NT_STATUS_INVALID_PARAMETER_MIX.
smb://10.10.11.222/Development/Automation/Ansible/ADCS/.ansible-lint
smb://10.10.11.222/Development/Automation/Ansible/ADCS/.yamllint
smb://10.10.11.222/Development/Automation/Ansible/ADCS/defaults/main.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/LICENSE
smb://10.10.11.222/Development/Automation/Ansible/ADCS/meta/main.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/meta/preferences.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/molecule/default/converge.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/molecule/default/molecule.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/molecule/default/prepare.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/README.md
smb://10.10.11.222/Development/Automation/Ansible/ADCS/requirements.txt
smb://10.10.11.222/Development/Automation/Ansible/ADCS/requirements.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/SECURITY.md
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tasks/assert.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tasks/generate_ca_certs.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tasks/init_ca.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tasks/main.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tasks/requests.yml
smb://10.10.11.222/Development/Automation/Ansible/ADCS/templates/extensions.cnf.j2
smb://10.10.11.222/Development/Automation/Ansible/ADCS/templates/openssl.cnf.j2
smb://10.10.11.222/Development/Automation/Ansible/ADCS/tox.ini
smb://10.10.11.222/Development/Automation/Ansible/ADCS/vars/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/.bin/clean_vault
smb://10.10.11.222/Development/Automation/Ansible/LDAP/.bin/diff_vault
smb://10.10.11.222/Development/Automation/Ansible/LDAP/.bin/smudge_vault
smb://10.10.11.222/Development/Automation/Ansible/LDAP/.travis.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/defaults/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/files/pam_mkhomedir
smb://10.10.11.222/Development/Automation/Ansible/LDAP/handlers/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/meta/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/README.md
smb://10.10.11.222/Development/Automation/Ansible/LDAP/tasks/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/templates/ldap_sudo_groups.j2
smb://10.10.11.222/Development/Automation/Ansible/LDAP/templates/ldap_sudo_users.j2
smb://10.10.11.222/Development/Automation/Ansible/LDAP/templates/sssd.conf.j2
smb://10.10.11.222/Development/Automation/Ansible/LDAP/templates/sudo_group.j2
smb://10.10.11.222/Development/Automation/Ansible/LDAP/TODO.md
smb://10.10.11.222/Development/Automation/Ansible/LDAP/Vagrantfile
smb://10.10.11.222/Development/Automation/Ansible/LDAP/vars/debian.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/vars/main.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/vars/redhat.yml
smb://10.10.11.222/Development/Automation/Ansible/LDAP/vars/ubuntu-14.04.yml
smb://10.10.11.222/Development/Automation/Ansible/PWM/ansible.cfg
smb://10.10.11.222/Development/Automation/Ansible/PWM/ansible_inventory
smb://10.10.11.222/Development/Automation/Ansible/PWM/defaults/main.yml
smb://10.10.11.222/Development/Automation/Ansible/PWM/handlers/main.yml
smb://10.10.11.222/Development/Automation/Ansible/PWM/meta/main.yml
smb://10.10.11.222/Development/Automation/Ansible/PWM/README.md
smb://10.10.11.222/Development/Automation/Ansible/PWM/tasks/main.yml
smb://10.10.11.222/Development/Automation/Ansible/PWM/templates/context.xml.j2
smb://10.10.11.222/Development/Automation/Ansible/PWM/templates/tomcat-users.xml.j2
smb://10.10.11.222/Development/Automation/Ansible/SHARE/tasks/main.yml
Downloaded 78.22kB in 35 seconds
Since it appears to contains lots of data, I will download the whole share and enumerate them locally
┌──(kali㉿kali)-[~/…/smb/Development/Automation/Ansible]
└─$ ll
total 24K
4.0k drwxr-xr-x 3 kali kali 4.0k jul 17 15:26 SHARE
4.0k drwxr-xr-x 6 kali kali 4.0k jul 17 15:26 .
4.0k drwxr-xr-x 7 kali kali 4.0k jul 17 15:26 PWM
4.0k drwxr-xr-x 10 kali kali 4.0k jul 17 15:26 LDAP
4.0k drwxr-xr-x 8 kali kali 4.0k jul 17 15:26 ADCS
4.0k drwxr-xr-x 3 kali kali 4.0k jul 17 15:26 ..
It seems that the system administration is done via Ansible deploy new machines within the organization I can see that there are 4 directories
ADCS
likely refers to Active Directory CertificatesLDAP
is literally LDAPSHARE
seems to be relevant to the directory servicePWN
seems to be relevant to the/pwn
endpoint in the web server running on the port 8443, which I initially saw during the Recon phase
SHARE
┌──(kali㉿kali)-[~/…/smb/Development/Automation/Ansible]
└─$ cd SHARE ; ll
total 12K
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 tasks
4.0K drwxr-xr-x 3 kali kali 4.0K Jul 17 15:26 .
4.0K drwxr-xr-x 6 kali kali 4.0K Jul 17 15:26 ..
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/SHARE]
└─$ cd tasks ; ll
total 12K
4.0K -rwxr-xr-x 1 kali kali 1.9K Jul 17 15:26 main.yml
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 .
4.0K drwxr-xr-x 3 kali kali 4.0K Jul 17 15:26 ..
┌──(kali㉿kali)-[~/…/Automation/Ansible/SHARE/tasks]
└─$ cat main.yml
- name: Make subdirectories under Share
ansible.windows.win_file:
path: "{{item}}"
state: directory
loop:
- C:\Share\Internal
- C:\Share\Internal\IT\Public
- C:\Share\Internal\IT\Private
- C:\Share\Internal\HR\Public
- C:\Share\Internal\HR\Private
- C:\Share\Internal\R&D\Public
- C:\Share\Internal\R&D\Private
- C:\Share\Internal\Marketing\Public
- C:\Share\Internal\Marketing\Private
- C:\Share\Internal\Finance\Public
- C:\Share\Internal\Finance\Private
- C:\Share\Internal\Executives\Public
- C:\Share\Internal\Executives\Private
- C:\Share\Internal\Accounting\Public
- C:\Share\Internal\Accounting\Private
- name: Make user folders for all users
ansible.windows.win_powershell:
script: |
$path = "C:\Share\"
$users = (Get-ADUser -Filter * ).Name
foreach ($user in $users) {
New-Item -ItemType Directory -Force -Path $path\$user}
- name: Create User Share
win_share:
name: '{{item.share_name}}'
description: '{{item.share_description}}'
path: '{{item.path}}'
list: '{{item.list}}'
full: '{{item.full}}'
read: '{{item.read}}'
with_items:
- {path: 'C:\Share', share_name: 'User Share', share_description: 'Share for Users', full: 'Administrators, Domain Users', read: 'Domain Users', list: no }
- name: Enable inherited ACL
ansible.windows.win_acl_inheritance:
path: C:\Share
state: present
- name: ACL
ansible.windows.win_acl:
path: C:\Share
user: Administrator, Domain Users
rights: Full Control
type: 'Allow'
inherit: None
propagation: 'None'
The Share/tasks/main.yml
file seems to be responsible for creating users directory under the C:\Share
directory
There is also an ACL inheritance with Administrator
and Domain Users
having full control over the C:\Share
directory
The main.yml
file in Ansible’s tasks
directory serves as the entry point for defining tasks within a role or playbook. It contains YAML-formatted tasks that specify actions to be performed on target systems, such as package installation or configuration changes. This file helps organize and maintain the automation logic associated with the role or playbook.
LDAP
┌──(kali㉿kali)-[~/…/smb/Development/Automation/Ansible]
└─$ cd LDAP ; ll
total 60K
4.0k drwxr-xr-x 6 kali kali 4.0k jul 17 15:26 ..
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 vars
4.0k drwxr-xr-x 10 kali kali 4.0k jul 17 15:26 .
4.0k -rwxr-xr-x 1 kali kali 640 jul 17 15:26 Vagrantfile
4.0k -rwxr-xr-x 1 kali kali 119 jul 17 15:26 TODO.md
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 templates
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 tasks
8.0k -rwxr-xr-x 1 kali kali 5.7k jul 17 15:26 README.md
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 meta
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 handlers
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 files
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 defaults
4.0k -rwxr-xr-x 1 kali kali 1.4k jul 17 15:26 .travis.yml
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 .bin
There is a lot to go through in the LDAP
contains
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/LDAP]
└─$ cat tasks/main.yml
---
# tasks file for ansible-role-system_ldap
- name: "Gather OS specific variables"
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_version }}.yml"
- "{{ ansible_distribution|lower }}.yml"
- "{{ ansible_os_family|lower }}.yml"
- name: Install sssd, sssd-ldap, and sudo
package:
name: "{{ item }}"
state: latest
with_items: "{{ system_ldap_packages }}"
- name: Copy SSSD configuration file
template:
src: sssd.conf.j2
dest: /etc/sssd/sssd.conf
mode: 0600
backup: yes
owner: root
group: root
notify:
- restart sssd
- name: Query SSSD in nsswitch.conf
replace:
dest: /etc/nsswitch.conf
regexp: '^({{ item }}(?!.*\bsss\b).*)$'
replace: '\1 sss'
backup: yes
with_items:
- passwd
- shadow
- group
- services
- netgroup
- automount
- name: Don't query SSSD for sudoers in nsswitch.conf
replace:
dest: /etc/nsswitch.conf
regexp: '^(sudoers.*)(\bsss)(\b.*)$'
replace: '\1 \3'
backup: yes
- name: Query SSSD in pam.d/password-auth
lineinfile:
dest: /etc/pam.d/password-auth
insertbefore: "{{ item.before }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
with_items:
- { before: "^auth.*pam_deny.so",
regexp: "^auth.*pam_sss.so",
line: "auth sufficient pam_sss.so use_first_pass" }
- { before: "",
regexp: "^account.*pam_unix.so",
line: "account required pam_unix.so broken_shadow" }
- { before: "^account.*pam_permit.so",
regexp: "^account.*pam.sss.so",
line: "account [default=bad success=ok user_unknown=ignore] pam_sss.so" }
- { before: "^password.*pam_deny.so",
regexp: "^password.*pam_sss.so",
line: "password sufficient pam_sss.so use_authtok" }
- { before: "^session.*pam_succeed_if.so",
regexp: "^session.*pam_.*mkhomedir.so",
line: "session optional pam_oddjob_mkhomedir.so umask=0077" }
- { before: EOF,
regexp: "^session.*pam_sss.so",
line: "session optional pam_sss.so" }
when: ansible_os_family == 'RedHat'
- name: Query SSSD in pam.d/system-auth
lineinfile:
dest: /etc/pam.d/system-auth
insertbefore: "{{ item.before }}"
regexp: "{{ item.regexp }}"
line: "{{ item.line }}"
state: present
with_items:
- { before: "^auth.*pam_deny.so",
regexp: "^auth.*pam_sss.so",
line: "auth sufficient pam_sss.so use_first_pass" }
- { before: "",
regexp: "^account.*pam_unix.so",
line: "account required pam_unix.so broken_shadow" }
- { before: "^account.*pam_permit.so",
regexp: "^account.*pam.sss.so",
line: "account [default=bad success=ok user_unknown=ignore] pam_sss.so" }
- { before: "^password.*pam_deny.so",
regexp: "^password.*pam_sss.so",
line: "password sufficient pam_sss.so use_authtok" }
- { before: "^session.*pam_succeed_if.so",
regexp: "^session.*pam_.*mkhomedir.so",
line: "session optional pam_oddjob_mkhomedir.so umask=0077" }
- { before: EOF,
regexp: "^session.*pam_sss.so",
line: "session optional pam_sss.so" }
when: ansible_os_family == 'RedHat'
- name: Ensure home directories are created upon login on Debian
lineinfile:
dest: /etc/pam.d/common-account
regexp: 'pam_mkhomedir\.so'
line: "session required pam_mkhomedir.so skel=/etc/skel/ umask=0022"
state: present
when: ansible_os_family == 'Debian'
- name: Start and enable auth services
service:
name: "{{ item }}"
state: started
enabled: yes
with_items: "{{ system_ldap_services }}"
- name: Add LDAP users to sudoers
template:
src: ldap_sudo_users.j2
dest: "/etc/sudoers.d/ldap_sudo_users"
validate: "visudo -cf %s"
- name: Add LDAP groups to sudoers
template:
src: ldap_sudo_groups.j2
dest: "/etc/sudoers.d/ldap_sudo_groups"
validate: "visudo -cf %s"
- name: Add pam_mkhomedir for Debian machines
copy:
src: pam_mkhomedir
dest: /usr/share/pam-configs/mkhomedir
when: ansible_os_family == "Debian"
notify:
- run pam auth update
- name: Allow/Disallow password authentication in SSHD config for users
blockinfile:
dest: /etc/ssh/sshd_config
marker: "# {mark} ANSIBLE SYSTEM LDAP USER BLOCK"
block: |
Match user {{ system_ldap_access_filter_users | join(",") }}
PasswordAuthentication yes
validate: "/usr/sbin/sshd -T -f '%s'"
state: "{{ 'present' if system_ldap_allow_passwordauth_in_sshd and system_ldap_access_filter_users else 'absent' }}"
notify:
- restart sshd
- name: Allow/Disallow password authentication in SSHD config for groups
blockinfile:
dest: /etc/ssh/sshd_config
marker: "# {mark} ANSIBLE SYSTEM LDAP GROUP BLOCK"
block: |
Match group "{{ system_ldap_access_unix_groups | join(",") }}"
PasswordAuthentication yes
validate: "/usr/sbin/sshd -T -f '%s'"
state: "{{ 'present' if system_ldap_allow_passwordauth_in_sshd and system_ldap_access_unix_groups else 'absent' }}"
notify:
- restart sshd
Checking the tasks/main.yml
file reveals that this LDAP
playbook seems to setup a LDAP authentication by
- installing a chosen OS via Vagrant
- with sssd, sssd-ldap, and sudo configuration depending on the chosen OS
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/LDAP]
└─$ cat Vagrantfile
Vagrant.require_version ">= 1.7.0"
Vagrant.configure(2) do |config|
config.vm.box = "debian/stretch64"
# Disable the new default behavior introduced in Vagrant 1.7, to
# ensure that all Vagrant machines will use the same SSH key pair.
# See https://github.com/mitchellh/vagrant/issues/5005
config.ssh.insert_key = false
config.vm.synced_folder ".", "/home/vagrant/sync/", disabled: true
config.vm.synced_folder ".", "/vagrant/", disabled: true
config.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.playbook = "tests/playbook.yml"
ansible.vault_password_file = ".vault_password"
end
end
There’s supposed to be a password file for the deployed instance; .vault_password
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/LDAP]
└─$ cat TODO.md
- Change LDAP admin password after build -[COMPLETE]
- add tests for ubuntu 14, 16, debian 7 and 8, and centos 6 and 7
The TODO.md
file shows that the LDAP admin password has been changed
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/LDAP]
└─$ cat .travis.yml
---
language: python
python: "2.7"
# Use the new container infrastructure
sudo: false
# Install ansible
addons:
apt:
packages:
- python-pip
env:
global:
- secure: "YP54FaEPVveTtCzlJG3YPuhxUFQvbVkr1L/AA9NM9rwFciwQcLtIXD9iljD17xzoXRwvooNW90eX8XMR2zkhqzU9C+n3kHw2iQVtAdbI1X59lGAXAT7WBMlU6auFsoVzkFibHxJ1W9R1o5JE2iTdDuR0UzQNaTgLn3Dgt7iOWzwNni3dmqdtbPXY7e5x+JhlKHOU53bGnLxFVmbTWzu0Z8ZDuVvh01azHdR0sj8KmC4c8A8atZU0f2f4YyG/26tx78U6RmNFyj2UTmOHRgOtcQVOzfadbI9gZuc1U5JIkS0FEwZYaJOMYhohAqp9Aumo+cuPVJCvjaEXrlvEe4DAJ6aFigT+JR6NY7w+fgoK57HTgC/y7chY30+34ggp+/0aWmXFqdDUbFWs9ovhf0hVL4AcU+31BWdrEmuJjXAGaGMSrdTYJpMFsnjIqe3bUimH1LEm4+wogD/poGSkRsv9R7j1OeQotVDaivRh6WOBdbXEw5HENczsBzD3TztN8A54UzvVnrMnoPI+aH2uvSm/5JVvqWzWEzZHIpep7lbTgRk/1yjxQk6mXDGtrd9uo4e7ZeEr3rBqtA6qI4VggugHIbLGtqQvINdV9fOnDB1sLlslLEIKfT8BLpnDncPYYVV0r0wyC5ySP+RX7nqsixX5oOR7a1UyXBBQ9D0CX3x7x0Y="
install:
# Install ansible
- pip install ansible
# Check ansible version
- ansible --version
# Create ansible.cfg with correct roles_path
- printf '[defaults]\nroles_path=../' >ansible.cfg
before_script:
- echo "$VAULT_PASSWORD" > .vault_password
script:
# Basic role syntax check
- ansible-playbook tests/travis.yml -i localhost, --vault-password-file .vault_password --syntax-check
notifications:
webhooks:
urls:
- https://galaxy.ansible.com/api/v1/notifications/
- https://t2d.idolactiviti.es/notify
the .travis.yml
file is a yaml configuration file used in travis ci for automating the build, test, and deployment processes of a project. It contains instructions such as language, environment variables, dependencies, and deployment configurations. This file helps developers streamline their continuous integration and deployment workflows.
The base64 string is nothing but a binary data encoded in the base64 format
┌──(kali㉿kali)-[~/…/Automation/Ansible/LDAP/.bin]
└─$ ll
total 20K
4.0k drwxr-xr-x 10 kali kali 4.0k jul 17 15:26 ..
4.0k -rwxr-xr-x 1 kali kali 768 jul 17 15:26 smudge_vault
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 .
4.0k -rwxr-xr-x 1 kali kali 357 jul 17 15:26 diff_vault
4.0k -rwxr-xr-x 1 kali kali 677 jul 17 15:26 clean_vault
The .bin
directory contains 3 Bash scripts
┌──(kali㉿kali)-[~/…/Automation/Ansible/LDAP/.bin]
└─$ cat smudge_vault
#!/bin/bash
# Just print out the secrets file as-is if the password file doesn't exist
if [ ! -r '.vault_password' ]; then
cat
exit
fi
CONTENT="$(cat)"
# Store vault's stderr in RESULT and redirect decrypted stdout back to stdout
{
RESULT="$(echo "$CONTENT" | ansible-vault decrypt - --vault-password-file=.vault_password 2>&1 1>&$OUT)";
} {OUT}>&1
if echo "$RESULT" | grep -qP "Decryption successful|^$"; then
exit
elif echo "$RESULT" | grep -q "ERROR! input is not encrypted"; then
echo "A secrets.yml file was committed in cleartext."
echo "Please fix this before continuing."
exit 1
else
# This should be unreachable, but just in case.
echo "RESULT=$RESULT" >> .gitdebug
echo "CONTENT=$CONTENT" >> .gitdebug
exit 1
fi
┌──(kali㉿kali)-[~/…/Automation/Ansible/LDAP/.bin]
└─$ cat diff_vault
#!/bin/bash
# Just print out the secrets file as-is if the password file doesn't exist
if [ ! -r '.vault_password' ]; then
cat "$1"
exit
fi
export PAGER='cat'
CONTENT="$(ansible-vault view "$1" --vault-password-file=.vault_password 2>&1)"
if echo "$CONTENT" | grep -q 'ERROR! input is not encrypted'; then
cat "$1"
else
echo "$CONTENT"
fi
┌──(kali㉿kali)-[~/…/Automation/Ansible/LDAP/.bin]
└─$ cat clean_vault
#!/bin/bash
# Just print out the secrets file as-is if the password file doesn't exist
if [ ! -r '.vault_password' ]; then
cat
exit
fi
CONTENT="$(cat)"
# Store vault's stderr in RESULT and redirect encrypted stdout back to stdout
{
RESULT="$(echo "$CONTENT" | ansible-vault encrypt - --vault-password-file=.vault_password 2>&1 1>&$OUT)";
} {OUT}>&1
if echo "$RESULT" | grep -qP "Encryption successful|^$"; then
exit
elif echo "$RESULT" | grep -q "ERROR! input is already encrypted"; then
echo "$CONTENT"
else
# This should be unreachable, but just in case.
echo "RESULT=$RESULT" >> .gitdebug
echo "CONTENT=$CONTENT" >> .gitdebug
exit 1
fi
These 3 Bash scripts seem to be dealing with encryption/decryption of the .vault_password
file
ADCS
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/ADCS]
└─$ ll
total 76K
4.0K drwxr-xr-x 8 kali kali 4.0K Jul 17 16:48 .
4.0K drwxr-xr-x 6 kali kali 4.0K Jul 17 15:26 ..
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 vars
4.0K -rwxr-xr-x 1 kali kali 419 Jul 17 15:26 tox.ini
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 templates
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 tasks
4.0K -rwxr-xr-x 1 kali kali 924 Jul 17 15:26 SECURITY.md
4.0K -rwxr-xr-x 1 kali kali 264 Jul 17 15:26 requirements.yml
4.0K -rwxr-xr-x 1 kali kali 466 Jul 17 15:26 requirements.txt
8.0K -rwxr-xr-x 1 kali kali 7.2K Jul 17 15:26 README.md
4.0K drwxr-xr-x 3 kali kali 4.0K Jul 17 15:26 molecule
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 meta
12K -rwxr-xr-x 1 kali kali 12K Jul 17 15:26 LICENSE
4.0K drwxr-xr-x 2 kali kali 4.0K Jul 17 15:26 defaults
4.0K -rwxr-xr-x 1 kali kali 205 Jul 17 15:26 .yamllint
4.0K -rwxr-xr-x 1 kali kali 259 Jul 17 15:26 .ansible-lint
The ADCS
playbook contains lots of data and configuration files
I will start with the task/main.yml
file
┌──(kali㉿kali)-[~/…/Automation/Ansible/ADCS/tasks]
└─$ cat main.yml
---
# tasks file for ca
- name: Import assert.yml
ansible.builtin.import_tasks: assert.yml
run_once: yes
delegate_to: localhost
- name: Create root ca
block:
- name: Set path for root CA
ansible.builtin.set_fact:
ca_path: "{{ ca_openssl_path }}/{{ ca_common_name }}/rootCA"
ca_filename: rootCA
- name: Init root CA
ansible.builtin.include_tasks:
file: init_ca.yml
when:
- ca_init | bool
- ca_own_root | bool
- name: Set path for CA
ansible.builtin.set_fact:
ca_path: "{{ ca_openssl_path }}/{{ ca_common_name }}"
ca_filename: ca
- name: Create ca
block:
- name: Init CA
ansible.builtin.include_tasks:
file: init_ca.yml
- name: Generate ca certificates
ansible.builtin.include_tasks:
file: generate_ca_certs.yml
when:
- ca_own_root | bool
when:
- ca_init | bool
- name: Ensure publication location exists
ansible.builtin.file:
path: "{{ ca_publication_location }}"
state: directory
mode: "755"
owner: root
group: root
when:
- ca_publication_location is defined
- name: Handle requests
ansible.builtin.include_tasks:
file: requests.yml
loop: "{{ ca_requests }}"
loop_control:
loop_var: request
label: "{{ request.name | default(request) }}"
when:
- ca_requests is defined
It seems that this playbook is to setup a CA(Certificate Authority)
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/ADCS]
└─$ grep -v '^#' defaults/main.yml
---
ca_init: yes
ca_own_root: yes
ca_passphrase: SuP3rS3creT
ca_common_name: authority.htb
ca_country_name: NL
ca_email_address: admin@authority.htb
ca_organization_name: htb
ca_organizational_unit_name: htb
ca_state_or_province_name: Utrecht
ca_locality_name: Utrecht
ca_publication_location: "{{ httpd_data_directory | default('/tmp') }}/pub"
ca_openssl_path: "{{ _ca_openssl_path[ansible_os_family] | default(_ca_openssl_path['default'] ) }}"
There is a CLEARTEXT password for the certificate authority in the defaults/main.yml
file
PWM
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/PWM]
└─$ ll
total 40K
4.0k drwxr-xr-x 6 kali kali 4.0k jul 17 15:26 ..
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 templates
4.0k drwxr-xr-x 7 kali kali 4.0k jul 17 15:26 .
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 tasks
4.0k -rwxr-xr-x 1 kali kali 1.3k jul 17 15:26 README.md
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 meta
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 handlers
4.0k drwxr-xr-x 2 kali kali 4.0k jul 17 15:26 defaults
4.0k -rwxr-xr-x 1 kali kali 174 jul 17 15:26 ansible_inventory
4.0k -rwxr-xr-x 1 kali kali 491 jul 17 15:26 ansible.cfg
according to the enumeration made for the web server running on the port 8443
, the pwm is an open source password self-service application for LDAP directories.
Therefore, this playbook must be the configuration set to deploy the web app through Ansible
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/PWM]
└─$ cat tasks/main.yml
---
- name: Make sure C:\Temp exists
ansible.windows.win_file:
path: C:\Temp
state: directory
- name: Download Java
ansible.windows.win_get_url:
url: https://javadl.oracle.com/webapps/download/AutoDL?BundleId=246474_2dee051a5d0647d5be72a7c0abff270e
dest: C:\Temp\jre-8u333-windows-x64.exe
- name: Download Java
ansible.windows.win_get_url:
url: https://github.com/adoptium/temurin17-binaries/releases/download/jdk-17.0.4.1%2B1/OpenJDK17U-jdk_x64_windows_hotspot_17.0.4.1_1.msi
dest: C:\Temp\OpenJDK17U-jdk_x64_windows_hotspot_17.0.4.1_1.msi
- name: Install Java
ansible.windows.win_package:
path: C:\Temp\jre-8u333-windows-x64.exe
arguments:
- /s
state: present
- name: Install Java
ansible.windows.win_package:
path: C:\Temp\OpenJDK17U-jdk_x64_windows_hotspot_17.0.4.1_1.msi
arguments:
- /quiet
state: present
- name: Download Tomcat
ansible.windows.win_get_url:
url: https://dlcdn.apache.org/tomcat/tomcat-10/v10.0.21/bin/apache-tomcat-10.0.21.exe
dest: C:\Temp\apache-tomcat-10.0.21.exe
validate_certs: no
- name: Install Tomcat
ansible.windows.win_package:
path: C:\Temp\apache-tomcat-10.0.21.exe
arguments:
- /S
state: present
- name: Configure Tomcat
template:
src: templates/tomcat-users.xml.j2
dest: C:\Program Files\Apache Software Foundation\Tomcat 10.0\conf\tomcat-users.xml
- name: Configure Tomcat
template:
src: templates/context.xml.j2
dest: C:\Program Files\Apache Software Foundation\Tomcat 10.0\webapps\manager\META-INF\context.xml
- name: Download Pwm
ansible.windows.win_get_url:
url: https://github.com/pwm-project/pwm/releases/download/v2_0_3/pwm-2.0.3.war
dest: C:\Program Files\Apache Software Foundation\Tomcat 10.0\webapps\pwm.war
validate_certs: no
The playbook deploys a PWM instance by
- installing Tomcat and Java
- configuring them with the files in the
templates
directory - installing pwm under the Tomcat instance
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/PWM]
└─$ cat templates/tomcat-users.xml.j2
<?xml version='1.0' encoding='cp1252'?>
<tomcat-users xmlns="http://tomcat.apache.org/xml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<user username="admin" password="T0mc@tAdm1n" roles="manager-gui"/>
<user username="robot" password="T0mc@tR00t" roles="manager-script"/>
</tomcat-users>
The templates/tomcat-users.xml.j2
file contains the credentials for the Tomcat instance, and it appears to be default
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/PWM]
└─$ cat ansible_inventory
ansible_user: administrator
ansible_password: Welcome1
ansible_port: 5985
ansible_connection: winrm
ansible_winrm_transport: ntlm
ansible_winrm_server_cert_validation: ignore
The ansible_inventory
file contains the ansible credential, which is likely obsolete and outdated
┌──(kali㉿kali)-[~/…/Development/Automation/Ansible/PWM]
└─$ cat defaults/main.yml
---
pwm_run_dir: "{{ lookup('env', 'PWD') }}"
pwm_hostname: authority.htb.corp
pwm_http_port: "{{ http_port }}"
pwm_https_port: "{{ https_port }}"
pwm_https_enable: true
pwm_require_ssl: false
pwm_admin_login: !vault |
$ANSIBLE_VAULT;1.1;AES256
32666534386435366537653136663731633138616264323230383566333966346662313161326239
6134353663663462373265633832356663356239383039640a346431373431666433343434366139
35653634376333666234613466396534343030656165396464323564373334616262613439343033
6334326263326364380a653034313733326639323433626130343834663538326439636232306531
3438
pwm_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
31356338343963323063373435363261323563393235633365356134616261666433393263373736
3335616263326464633832376261306131303337653964350a363663623132353136346631396662
38656432323830393339336231373637303535613636646561653637386634613862316638353530
3930356637306461350a316466663037303037653761323565343338653934646533663365363035
6531
ldap_uri: ldap://127.0.0.1/
ldap_base_dn: "DC=authority,DC=htb"
ldap_admin_password: !vault |
$ANSIBLE_VAULT;1.1;AES256
63303831303534303266356462373731393561313363313038376166336536666232626461653630
3437333035366235613437373733316635313530326639330a643034623530623439616136363563
34646237336164356438383034623462323531316333623135383134656263663266653938333334
3238343230333633350a646664396565633037333431626163306531336336326665316430613566
3764
The defaults/main.yml
contains the encrypted ansible-vault
credentials
I might be able to make use of that