def HTTPHandler(self, conn, request, response, requesttime, responsetime): if response == None: # Denial of Service (no server response) try: rangestr = util.getHeader(request, 'range') # check range value to reduce false positive rate if not rangestr.endswith('18446744073709551615'): return except: return self.alert('MS15-034 DoS [Request Method: "%s" URI: "%s" Range: "%s"]' % \ (request.method, request.uri, rangestr), conn.info()) else: # probing for vulnerable server try: rangestr = util.getHeader(request, 'range') # check range value to reduce false positive rate if not rangestr.endswith('18446744073709551615'): return except: return # indication of vulnerable server if rangestr and (response.status == '416' or \ response.reason == 'Requested Range Not Satisfiable'): self.alert( 'MS15-034 Vulnerable Server [Request Method: "%s" Range: "%s"]' % (request.method, rangestr), conn.info()) if request.method != 'GET': # this could be interesting pass # waiting on more details
def HTTPHandler(self, conn, request, response, requesttime, responsetime): if response == None: # Denial of Service (no server response) try: rangestr = util.getHeader(request,'range') # check range value to reduce false positive rate if not rangestr.endswith('18446744073709551615'): return except: return self.alert('MS15-034 DoS [Request Method: "%s" URI: "%s" Range: "%s"]' % \ (request.method, request.uri, rangestr), conn.info()) else: # probing for vulnerable server try: rangestr = util.getHeader(request,'range') # check range value to reduce false positive rate if not rangestr.endswith('18446744073709551615'): return except: return # indication of vulnerable server if rangestr and (response.status == '416' or \ response.reason == 'Requested Range Not Satisfiable'): self.alert('MS15-034 Vulnerable Server [Request Method: "%s" Range: "%s"]' % (request.method,rangestr), conn.info()) if request.method != 'GET': # this could be interesting pass # waiting on more details
def HTTPHandler(self, conn, request, response, requesttime, responsetime): if response and response.status != '200': return content_type = util.getHeader(response, 'content-type') if content_type not in ('application/x-shockwave-flash', 'application/octet-stream', 'application/vnd.adobe.flash-movie'): return # Check for known flash file header characters if not response.body.startswith(('CWS', 'ZWS', 'FWS')): return host = util.getHeader(request, 'host') # Grab file info as dict with keys: 'file_name', 'md5sum', 'uri' file_info = self.get_file_info(request, response) if self.md5sum == self.MD5 or self.md5sum == self.MD5_EXPLICIT_FILENAME: # Print MD5 sum in the alert self.alert( '{0}{1} ({2}) md5sum: {3}'.format(host, request.uri, content_type, file_info['md5sum']), **conn.info()) else: self.alert('{0}{1} ({2})'.format(host, request.uri, content_type), **conn.info()) # Dump the file if chosen if self.dump: # Name output files based on options if self.md5sum == self.MD5: origname = file_info['md5sum'] # Check for explicitly listed filename elif file_info['file_name']: origname = file_info['file_name'] # If explicit name not found, but still want MD5, give it MD5 elif self.md5sum == self.MD5_EXPLICIT_FILENAME: origname = file_info['md5sum'] # Else name the file by its URI (which can be long) else: origname = file_info['uri'] outname = self.__localfilename(self.__OUTDIR, origname) with open('{0}.flash'.format(outname), 'wb') as outfile: outfile.write(response.body) # Pass to subdecoder if necessary if 'HTTPHandler' in dir(self.subDecoder): self.subDecoder.HTTPHandler(conn, request, response, requesttime, responsetime) elif 'connectionHandler' in dir(self.subDecoder): self.subDecoder.connectionHandler(conn)
def sendFile(sock, addr, header, path) -> bytes: # open file file = open(path, "rb") # rb = read-only, binary # create threads nextSeg = threading.Thread(target=sendNextSegment, args=( sock, addr, file, header, )) lostSeg = threading.Thread(target=sendLostSegment, args=(sock, addr, file)) ackListener = threading.Thread(target=listenForAck, args=(sock, file)) # start threads print("Starting threads...") nextSeg.start() lostSeg.start() ackListener.start() # threads finished nextSeg.join() lostSeg.join() ackListener.join() print("Threads finished") print(lastHeader) seqN = util.getHeader(lastHeader, seqN=True)[0] header = util.nextHeader(lastHeader, newSeqN=seqN, newAckN=currentAckN) return header
def HTTPHandler(self, conn, request, response, requesttime, responsetime): if response and response.status != '200': return content_type = util.getHeader(response, 'content-type') if content_type not in ('application/x-shockwave-flash', 'application/octet-stream', 'application/vnd.adobe.flash-movie'): return # Check for known flash file header characters if not response.body.startswith(('CWS', 'ZWS', 'FWS')): return host = util.getHeader(request, 'host') # Grab file info as dict with keys: 'file_name', 'md5sum', 'uri' file_info = self.get_file_info(request, response) if self.md5sum == self.MD5 or self.md5sum == self.MD5_EXPLICIT_FILENAME: # Print MD5 sum in the alert self.alert('{0}{1} ({2}) md5sum: {3}'.format(host, request.uri, content_type, file_info['md5sum']), **conn.info()) else: self.alert('{0}{1} ({2})'.format(host, request.uri, content_type), **conn.info()) # Dump the file if chosen if self.dump: # Name output files based on options if self.md5sum == self.MD5: origname = file_info['md5sum'] # Check for explicitly listed filename elif file_info['file_name']: origname = file_info['file_name'] # If explicit name not found, but still want MD5, give it MD5 elif self.md5sum == self.MD5_EXPLICIT_FILENAME: origname = file_info['md5sum'] # Else name the file by its URI (which can be long) else: origname = file_info['uri'] outname = self.__localfilename(self.__OUTDIR, origname) with open('{0}.flash'.format(outname), 'wb') as outfile: outfile.write(response.body) # Pass to subdecoder if necessary if 'HTTPHandler' in dir(self.subDecoder): self.subDecoder.HTTPHandler(conn, request, response, requesttime, responsetime) elif 'connectionHandler' in dir(self.subDecoder): self.subDecoder.connectionHandler(conn)
def HTTPHandler(self, conn, request, response, requesttime, responsetime): self.debug('%s %s' % (repr(request), repr(response))) if (not self.direction or self.direction == 'cs' ) and request and request.method == 'POST' and request.body: contenttype, filename, data = self.POSTHandler(request.body) if not self.content_filter or self.content_filter.search( contenttype): if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += '_%s-%s' % (conn.clientip, conn.serverip) if self.append_ts: filename += '_%d' % (conn.ts) self.debug(os.path.join(self.outdir, filename)) f = open(os.path.join(self.outdir, filename), 'w') f.write(data) f.close() elif (not self.direction or self.direction == 'sc') and response and response.status[0] == '2': if not self.content_filter or self.content_filter.search( response.headers['content-type']): # Calculate URL host = util.getHeader(request, 'host') if host == '': host = conn.serverip url = host + request.uri # File already open if url in self.openfiles: self.debug("Adding response section to %s" % url) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) # New file else: filename = request.uri.split('?')[0].split('/')[-1] self.debug("New file with URL: %s" % url) if not self.name_filter or self.name_filter.search( filename): if self.append_conn: filename += '_%s-%s' % (conn.serverip, conn.clientip) if self.append_ts: filename += '_%d' % (conn.ts) if not len(filename): filename = '%s-%s_index.html' % (conn.serverip, conn.clientip) while os.path.exists( os.path.join(self.outdir, filename)): filename += '_' self.alert("New file: %s (%s)" % (filename, url), conn.info()) self.openfiles[url] = httpfile( os.path.join(self.outdir, filename), self) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) if self.openfiles[url].done(): self.alert( "File done: %s (%s)" % (self.openfiles[url].filename, url), conn.info()) del self.openfiles[url]
def listenForAck(sock, file) -> None: global currentAckN global ackRecv global remote_buffer_size global estimatedRTT global devRTT global TIMEOUT global cwnd global localWindow while True: if (file.closed and ackRecv == segSent): return None # listen for new packet packet, addr = sock.recvfrom(1040) recvSeqN, recvAckN, remote_buffer_size, recvAck = util.getHeader( packet[0:16], seqN=True, ackN=True, window=True, ack=True) # is ack if (recvAck == 1): currentAckN = recvSeqN + 1 print("Segment ACKed with sequence number: " + str(recvAckN - 1)) # discard acked packet from window flag = False mutex1.acquire() localCwnd = cwnd mutex1.release() for i in range(len(localCwnd)): if (localCwnd[i].getSeqN() == recvAckN - 1): # calculate RTT sampleRTT = time.time() - localCwnd[i].timestamp print('poped seq No.{0}'.format(localCwnd[i].getSeqN())) j = i flag = True ackRecv += 1 break if flag: full1.acquire() mutex1.acquire() cwnd.pop(j) mutex1.release() empty1.release() # congestion control, append window size by 1 if localWindow < WINDOW_MAX_SIZE and j == 0: mutex3.acquire() localWindow += 1 mutex3.release() estimatedRTT = 0.875 * estimatedRTT + 0.125 * sampleRTT devRTT = 0.75 * devRTT + 0.25 * abs(sampleRTT - estimatedRTT) # lock mutex2.acquire() TIMEOUT = estimatedRTT + 4 * devRTT mutex2.release()
def send(addr, header, userCount, path): time.sleep(2) src, dest, seqN, ackN, window, _, _, _ = util.unpackHeader(header) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind(('', src + userCount)) # initial packet with file size header = util.makeHeader(src + userCount, dest, seqN + 1, ackN, window + 1, int("01000000", 2)) data = struct.pack("!I", os.path.getsize(path)) sock.sendto(header + data, addr) print("Initial packet with file size sent") # receive ack from client with port switch packet, addr = sock.recvfrom(1040) recvSeqN, recvAckN, recvAck = util.getHeader(packet[0:16], seqN=True, ackN=True, ack=True) print("seqN = " + str(recvSeqN) + " ackN = " + str(recvAckN) + " ack = " + str(recvAck)) print("mySeqN" + str(seqN + 2)) if (recvAckN == seqN + 2 and recvAck == 1): print("File size acknowledged") # update window for recieving ack currentAckN = recvSeqN + 1 header = util.nextHeader(header, newSeqN=seqN + 1, newAckN=currentAckN) # send file in truncks print("Start sending file...") sucHeader = sendFile(sock, addr, header, path) print("All segment transmitted!") # send fin bit to prompt to close header = util.nextHeader(sucHeader, asf="001") sock.sendto(header, addr) ack = 0 start = time.time() while (ack == 1 or time.time() - start > 2): packet, addr = sock.recvfrom(1024) ack = util.getHeader(packet[0:16], ack=True) sock.close()
class HTTPDecoder(dshell.TCPDecoder): '''extend HTTPDecoder to handle HTTP request/responses will call HTTPHandler( conn=Connection(), request=dpkt.http.Request, response=dpkt.http.Response, requesttime=timestamp, responsetime=timestamp ) after each response. config: noresponse: if True and connection closes w/o response, will call with response,responsetime=None,None (True) gunzip: if True will decompress gzip encoded response bodies (default True) ''' def __init__(self, **kwargs): self.noresponse = True self.gunzip = True dshell.TCPDecoder.__init__(self, **kwargs) self.requests = {} # Custom error handler for data reassembly --- ignores errors, keep data def errorH(self, **x): return True def blobHandler(self, conn, blob): '''buffer the request blob and call the handler once we have the response blob''' if blob.direction == 'cs': try: self.requests[conn] = (blob.starttime, dpkt.http.Request(blob.data( self.errorH))) except Exception, e: self.UnpackError(e) elif blob.direction == 'sc' and conn in self.requests: try: if 'HTTPHandler' in dir(self): response = dpkt.http.Response(blob.data(self.errorH)) if self.gunzip and 'gzip' in util.getHeader( response, 'content-encoding'): bodyUnzip = self.decompressGzipContent(response.body) if bodyUnzip != None: response.body = bodyUnzip self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=response, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn] except Exception, e: self.UnpackError(e) self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=None, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn]
def HTTPHandler(self, conn, request, response, requesttime, responsetime): payload = None self.debug('%s %s' % (repr(request), repr(response))) if (not self.direction or self.direction == 'cs') and request and request.method == 'POST' and request.body: payload = request elif (not self.direction or self.direction == 'sc') and response and response.status[0] == '2': payload = response if payload: if not (not self.content_filter or self.content_filter.search(payload.headers['content-type'])): payload = None if payload: # Calculate URL host = util.getHeader(request, 'host') if host == '': host = conn.serverip url = host + request.uri # File already open if url in self.openfiles: self.debug("Adding response section to %s" % url) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) # New file else: filename = request.uri.split('?')[0].split('/')[-1] if 'content-disposition' in payload.headers: cdparts = self.splitstrip(payload.headers['content-disposition'], ';') for cdpart in cdparts: try: k, v = self.splitstrip(cdpart, '=') if k == 'filename': filename = v except: pass self.debug("New file with URL: %s" % url) if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += '_%s-%s' % (conn.serverip, conn.clientip) if self.append_ts: filename += '_%d' % (conn.ts) if not len(filename): filename = '%s-%s_index.html' % ( conn.serverip, conn.clientip) while os.path.exists(os.path.join(self.outdir, filename)): filename += '_' self.alert("New file: %s (%s)" % (filename, url), conn.info()) self.openfiles[url] = httpfile( os.path.join(self.outdir, filename), self) (s, e) = self.openfiles[url].handleresponse(payload) self.write(" --> Range: %d - %d\n" % (s, e)) if self.openfiles[url].done(): self.alert("File done: %s (%s)" % (self.openfiles[url].filename, url), conn.info()) del self.openfiles[url]
def sendLostSegment(sock, addr, file) -> None: global currentAckN global TIMEOUT global localWindow # cwnd not empty while True: flag = False # transmission timeout mutex2.acquire() TO = TIMEOUT mutex2.release() mutex1.acquire() length = len(cwnd) if file.closed and length == 0: print('lost thread closed') return None if (length > 0): timestamp = cwnd[0].timestamp lostHeader = cwnd[0].header lostSeqN = cwnd[0].getSeqN() lostData = cwnd[0].data diffTime = time.time() - timestamp if (diffTime > TO): cwnd[0].timestamp = time.time() mutex1.release() flag = True mutex3.acquire() localWindow = localWindow / 2 mutex3.release() else: mutex1.release() # time.sleep(TO - diffTime) time.sleep(0.3) continue else: mutex1.release() if flag: print("TIMEOUT with {0}".format(TO)) # congestion control invoked by timeout, divide cwnd by 2 # empty1._value = int(empty1._value / 2) newHeader = util.nextHeader(lostHeader, newSeqN=lostSeqN, newAckN=currentAckN) sock.sendto(newHeader + lostData, addr) print("Lost segment sent with sequence number: " + str(util.getHeader(newHeader, seqN=True)))
def HTTPHandler(self, conn, request, response, requesttime, responsetime): self.debug('%s %s' % (repr(request), repr(response))) if (not self.direction or self.direction == 'cs') and request and request.method == 'POST' and request.body: contenttype, filename, data = self.POSTHandler(request.body) if not self.content_filter or self.content_filter.search(contenttype): if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += '_%s-%s' % (conn.clientip, conn.serverip) if self.append_ts: filename += '_%d' % (conn.ts) self.debug(os.path.join(self.outdir, filename)) f = open(os.path.join(self.outdir, filename), 'w') f.write(data) f.close() elif (not self.direction or self.direction == 'sc') and response and response.status[0] == '2': if not self.content_filter or self.content_filter.search(response.headers['content-type']): # Calculate URL host = util.getHeader(request, 'host') if host == '': host = conn.serverip url = host + request.uri # File already open if url in self.openfiles: self.debug("Adding response section to %s" % url) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) # New file else: filename = request.uri.split('?')[0].split('/')[-1] self.debug("New file with URL: %s" % url) if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += '_%s-%s' % (conn.serverip, conn.clientip) if self.append_ts: filename += '_%d' % (conn.ts) if not len(filename): filename = '%s-%s_index.html' % ( conn.serverip, conn.clientip) while os.path.exists(os.path.join(self.outdir, filename)): filename += '_' self.alert("New file: %s (%s)" % (filename, url), conn.info()) self.openfiles[url] = httpfile( os.path.join(self.outdir, filename), self) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) if self.openfiles[url].done(): self.alert("File done: %s (%s)" % (self.openfiles[url].filename, url), conn.info()) del self.openfiles[url]
def sendFirstSegment(sock, addr, file, header) -> bool: segment = file.read(MSS) if (len(segment) != 0): header = util.nextHeader(header, newAckN=currentAckN) cwnd.append(packet(header, segment)) sock.sendto(header + segment, addr) print("First segment sent with sequence number: " + str(util.getHeader(header, seqN=True))) return True else: file.close() print("Error: No data read") return False
def HTTPHandler(self, conn, request, response, requesttime, responsetime): self.debug("%s %s" % (repr(request), repr(response))) if (not self.direction or self.direction == "cs") and request and request.method == "POST" and request.body: contenttype, filename, data = self.POSTHandler(request.body) if not self.content_filter or self.content_filter.search(contenttype): if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += "_%s-%s" % (conn.clientip, conn.serverip) if self.append_ts: filename += "_%d" % (conn.ts) self.debug(filename) f = open(filename, "w") f.write(data) f.close() elif (not self.direction or self.direction == "sc") and response and response.status[0] == "2": if not self.content_filter or self.content_filter.search(response.headers["content-type"]): # Calculate URL host = util.getHeader(request, "host") if host == "": host = conn.serverip url = host + request.uri # File already open if url in self.openfiles: self.debug("Adding response section to %s" % url) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) # New file else: filename = request.uri.split("?")[0].split("/")[-1] self.debug("New file with URL: %s" % url) if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += "_%s-%s" % (conn.serverip, conn.clientip) if self.append_ts: filename += "_%d" % (conn.ts) if not len(filename): filename = "%s-%s_index.html" % (conn.serverip, conn.clientip) while os.path.exists(filename): filename += "_" self.alert("New file: %s (%s)" % (filename, url), conn.info()) self.openfiles[url] = httpfile(filename) (s, e) = self.openfiles[url].handleresponse(response) self.write(" --> Range: %d - %d\n" % (s, e)) if self.openfiles[url].done(): self.alert("File done: %s (%s)" % (self.openfiles[url].filename, url), conn.info()) del self.openfiles[url]
def get_file_info(self, request, response): """Checks for an explicitly listed file name. Returns a dictionary containing the explicitly listed filename (if present), the URI, and an md5sum (if requested) """ file_info = {'file_name': '', 'uri': '', 'md5sum': ''} content = util.getHeader(response, 'content-disposition') if content and 'filename' in content: # RFC 1806: content contains a string with parameters separated by semi-colons text = content.split(';') for parm in text: if parm.strip().startswith('filename='): file_info['file_name'] = parm.split('filename=', 1)[1] # CAVEAT: When the URI is very long and it is used as a filename in a dump, # then the file name may become unwieldy file_info['uri'] = request.uri if self.md5sum == self.MD5 or self.md5sum == self.MD5_EXPLICIT_FILENAME: file_info['md5sum'] = self.__body_md5(response) return file_info
def blobHandler(self,conn,blob): '''buffer the request blob and call the handler once we have the response blob''' if blob.direction=='cs': try: self.requests[conn]=(blob.starttime,dpkt.http.Request(blob.data(self.errorH))) except Exception, e: self.UnpackError(e) elif blob.direction=='sc' and conn in self.requests: try: if 'HTTPHandler' in dir(self): response=dpkt.http.Response(blob.data(self.errorH)) if self.gunzip and 'gzip' in util.getHeader(response, 'content-encoding'): bodyUnzip = self.decompressGzipContent(response.body) if bodyUnzip != None: response.body = bodyUnzip self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=response, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn] except Exception,e: self.UnpackError(e) self.HTTPHandler(conn=conn,request=self.requests[conn][1],response=None,requesttime=self.requests[conn][0],responsetime=blob.starttime) del self.requests[conn]
def HTTPHandler(self, conn, request, response, requesttime, responsetime): host = '' loc = '' lastmodified = '' #request_time, request, response = self.httpDict[conn.addr] # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' loc = '' if status[:2] == '30': loc = util.getHeader(response, 'location') if len(loc): loc = '-> ' + loc lastmodified = util.HTTPlastmodified(response) referer = util.getHeader(request, 'referer') useragent = util.getHeader(request, 'user-agent') via = util.getHeader(request, 'via') try: responsesize = len(response.body.rstrip('\0')) except: responsesize = 0 if self.md5: md5 = self._bodyMD5(response) else: md5 = '' # File objects try: if len(response.body) > 0: responsefile = dfile.dfile( name=request.uri, data=response.body) else: responsefile = '' except: responsefile = '' if request.method == 'POST' and len(request.body): ulcontenttype, ulfilename, uldata = self.POSTHandler(request.body) uploadfile = dfile.dfile(name=ulfilename, data=uldata) else: uploadfile = None requestInfo = '%s %s%s HTTP/%s' % (request.method, host if host != request.uri else '', # With CONNECT method, the URI is or contains the host, making this redudant request.uri[:self.maxurilen] + '[truncated]' if self.maxurilen > 0 and len( request.uri) > self.maxurilen else request.uri, request.version) if response: responseInfo = '%s %s %s %s' % (status, reason, loc, lastmodified) else: responseInfo = '' self.alert("%-80s // %s" % (requestInfo, responseInfo), referer=referer, useragent=useragent, request=requestInfo, response=responseInfo, request_time=requesttime, response_time=responsetime, request_method=request.method, host=host, uri=request.uri, status=status, reason=reason, lastmodified=lastmodified, md5=md5, responsesize=responsesize, contenttype=util.getHeader(response, 'content-type'), responsefile=responsefile, uploadfile=uploadfile, via=via, **conn.info()) if self.out.sessionwriter: self.write(request.data, direction='cs') if response: self.write(response.body, direction='sc')
def HTTPHandler(self, conn, request, response, requesttime, responsetime): # # Establish kw_items dictionary for extracted details from tcp/ip layer and request/response # kw_items = conn.info() # # Extract useful information from HTTP *request* # for h in request.headers.keys(): kw_items[h] = util.getHeader(request, h) # Rename user-agent for backward compatability if 'user-agent' in kw_items: kw_items['useragent'] = kw_items.pop('user-agent') # Override non-existent host header with server IP address if kw_items['host'] == '': kw_items['host'] = conn.serverip # request info string for standard output requestInfo = '%s %s%s HTTP/%s' % ( request.method, kw_items['host'] if kw_items['host'] != request.uri else '', # With CONNECT method, the URI is or contains the host, making this redudant request.uri[:self.maxurilen] + '[truncated]' if self.maxurilen > 0 and len(request.uri) > self.maxurilen else request.uri, request.version) # # Extract useful information from HTTP *response* (if available) # status = '' reason = '' responsesize = 0 loc = '' lastmodified = '' md5 = '' if response != None: try: responsesize = len(response.body.rstrip('\0')) except: responsesize = 0 if self.md5: md5 = self._bodyMD5(response) else: md5 = '' try: status = response.status except: status = '' try: reason = response.reason except: reason = '' for h in response.headers.keys(): if not h in kw_items: kw_items[h] = util.getHeader(response, h) else: kw_items['server_' + h] = util.getHeader(response, h) if 'content-type' in kw_items: kw_items['contenttype'] = kw_items.pop('content-type') loc = '' if status[:2] == '30': loc = util.getHeader(response, 'location') if len(loc): loc = '-> ' + loc lastmodified = util.HTTPlastmodified(response) # response info string for standard output responseInfo = '%s %s %s %s' % (status, reason, loc, lastmodified) else: responseInfo = '' # # File objects # try: if len(response.body) > 0: responsefile = dfile.dfile(name=request.uri, data=response.body) else: responsefile = '' except: responsefile = '' if request.method == 'POST' and len(request.body): ulcontenttype, ulfilename, uldata = self.POSTHandler(request.body) uploadfile = dfile.dfile(name=ulfilename, data=uldata) else: uploadfile = None # # Call alert with text info and kw values # self.alert("%-80s // %s" % (requestInfo, responseInfo), request=requestInfo, response=responseInfo, request_time=requesttime, response_time=responsetime, request_method=request.method, uri=request.uri, status=status, reason=reason, lastmodified=lastmodified, md5=md5, responsesize=responsesize, responsefile=responsefile, uploadfile=uploadfile, **kw_items) if self.out.sessionwriter: self.write(request.data, direction='cs') if response: self.write(response.body, direction='sc')
def errorH(self, **x): return True def blobHandler(self, conn, blob): '''buffer the request blob and call the handler once we have the response blob''' if conn not in self.requests: try: self.requests[conn] = ( blob.starttime, dpkt.http.Request(blob.data(self.errorH))) except Exception, e: self.UnpackError(e) else: try: if 'HTTPHandler' in dir(self): response = dpkt.http.Response(blob.data(self.errorH)) if self.gunzip and 'gzip' in util.getHeader(response, 'content-encoding'): bodyUnzip = self.decompressGzipContent(response.body) if bodyUnzip != None: response.body = bodyUnzip self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=response, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn] except Exception, e: self.UnpackError(e) self.HTTPHandler(conn=conn, request=self.requests[conn][ 1], response=None, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn]
def getSeqN(self) -> int: return util.getHeader(self.header, seqN=True)[0]
def HTTPHandler(self, conn, request, response, requesttime, responsetime): if not request: return # Obtain the response content try: if 'gzip' in util.getHeader(response, 'content-encoding'): self.response_body = self.decompressGzipContent(response.body) if self.response_body == None: self.response_body = '(gunzip failed)\n' + response.body else: self.response_body = '(gzip encoded)\n' + self.response_body else: self.response_body = response.body except AttributeError as e: self.response_body = None # Obtain the request content try: if 'gzip' in util.getHeader(request, 'content-encoding'): self.request_body = self.decompressGzipContent(request.body) if self.request_body == None: self.request_body = '(gunzip failed)\n' + request.body else: self.request_body = '(gzip encoded)\n' + self.request_body else: self.request_body = request.body except AttributeError as e: self.request_body = None # Identify the Exploit/Hijacking Tool self.request_ioc = self.check_payload(request.headers, request.uri, self.request_body) if self.request_ioc: # REQUEST if request.method in ('GET', 'POST', 'HEAD'): self.direction = "sc" self.request_method = request.method self.request_user_agent = request.headers.get('user-agent') self.request_host = util.getHeader(request, 'host') self.request_rangestr = util.getHeader(request, 'range') self.request_body = request.body self.request_referer = util.getHeader(request, 'referer') if request.headers.has_key('user-agent'): self.request_user_agent = request.headers['user-agent'] self.out.write( "\nRequest Timestamp (UTC): {0} \nPenetration/Exploit/Hijacking Tool: {1}\nUser-Agent: {2}\nRequest Method: {3}\nURI: {4}\nSource IP: {5} - Source port: {6} - MAC: {7}\nHost requested: {8}\nReferer: {9}\n" .format(datetime.datetime.utcfromtimestamp(requesttime), self.request_ioc, self.request_user_agent, self.request_method, request.uri, conn.sip, conn.sport, conn.smac, self.request_host, self.request_referer), formatTag="H2", direction=self.direction) # Show request body content if self.showcontent: self.out.write("\n{0}\n".format(self.request_body), formatTag="H2", direction=self.direction) if not response: self.direction = "cs" self.out.write('\nNo response\n', formatTag="H2", direction=self.direction) # RESPONSE else: self.direction = "cs" self.response_content_type = util.getHeader( response, 'content-type') self.response_contentencoding = util.getHeader( response, 'content-encoding') self.response_status = response.status self.response_reason = response.reason self.out.write( "\nResponse Timestamp (UTC): {0} \nResponse Reason: {1}\nResponse Status: {2}\nDestination IP: {3} - Destination port: {4} - MAC: {5}\n" .format( datetime.datetime.utcfromtimestamp(responsetime), self.response_reason, self.response_status, conn.dip, conn.dport, conn.dmac), formatTag="H2", direction=self.direction) # Show response body content if self.showcontent: self.out.write("\n{0}\n".format(self.response_body), formatTag="H2", direction=self.direction)
return True def blobHandler(self, conn, blob): '''buffer the request blob and call the handler once we have the response blob''' if conn not in self.requests: try: self.requests[conn] = (blob.starttime, dpkt.http.Request(blob.data( self.errorH))) except Exception, e: self.UnpackError(e) else: try: if 'HTTPHandler' in dir(self): response = dpkt.http.Response(blob.data(self.errorH)) if self.gunzip and 'gzip' in util.getHeader( response, 'content-encoding'): bodyUnzip = self.decompressGzipContent(response.body) if bodyUnzip != None: response.body = bodyUnzip self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=response, requesttime=self.requests[conn][0], responsetime=blob.starttime) del self.requests[conn] except Exception, e: self.UnpackError(e) self.HTTPHandler(conn=conn, request=self.requests[conn][1], response=None, requesttime=self.requests[conn][0],
def HTTPHandler(self, conn, request, response, requesttime, responsetime): if not request: return # Obtain the response content try: if 'gzip' in util.getHeader(response, 'content-encoding'): self.response_body = self.decompressGzipContent(response.body) if self.response_body == None: self.response_body = '(gunzip failed)\n' + response.body else: self.response_body = '(gzip encoded)\n' + self.response_body else: self.response_body = response.body except AttributeError as e: self.response_body = None # Obtain the request content try: if 'gzip' in util.getHeader(request, 'content-encoding'): self.request_body = self.decompressGzipContent(request.body) if self.request_body == None: self.request_body = '(gunzip failed)\n' + request.body else: self.request_body = '(gzip encoded)\n' + self.request_body else: self.request_body = request.body except AttributeError as e: self.request_body = None # Identify the Exploit/Hijacking Tool self.request_ioc = self.check_payload(request.headers, request.uri, self.request_body) if self.request_ioc: # REQUEST if request.method in ('GET', 'POST', 'HEAD'): self.direction = "sc" self.request_method = request.method self.request_user_agent = request.headers.get('user-agent') self.request_host = util.getHeader(request, 'host') self.request_rangestr = util.getHeader(request,'range') self.request_body = request.body self.request_referer = util.getHeader(request, 'referer') if request.headers.has_key('user-agent'): self.request_user_agent = request.headers['user-agent'] self.out.write("\nRequest Timestamp (UTC): {0} \nPenetration/Exploit/Hijacking Tool: {1}\nUser-Agent: {2}\nRequest Method: {3}\nURI: {4}\nSource IP: {5} - Source port: {6} - MAC: {7}\nHost requested: {8}\nReferer: {9}\n".format(datetime.datetime.utcfromtimestamp( requesttime), self.request_ioc, self.request_user_agent, self.request_method, request.uri, conn.sip, conn.sport, conn.smac, self.request_host, self.request_referer), formatTag="H2", direction=self.direction) # Show request body content if self.showcontent: self.out.write("\n{0}\n".format(self.request_body), formatTag="H2", direction=self.direction) if not response: self.direction = "cs" self.out.write('\nNo response\n', formatTag="H2", direction=self.direction) # RESPONSE else: self.direction = "cs" self.response_content_type = util.getHeader(response, 'content-type') self.response_contentencoding = util.getHeader(response, 'content-encoding') self.response_status = response.status self.response_reason = response.reason self.out.write("\nResponse Timestamp (UTC): {0} \nResponse Reason: {1}\nResponse Status: {2}\nDestination IP: {3} - Destination port: {4} - MAC: {5}\n".format(datetime.datetime.utcfromtimestamp( responsetime), self.response_reason, self.response_status, conn.dip, conn.dport, conn.dmac), formatTag="H2", direction=self.direction) # Show response body content if self.showcontent: self.out.write("\n{0}\n".format(self.response_body), formatTag="H2", direction=self.direction)
def HTTPHandler(self, conn, request, response, requesttime, responsetime): payload = None self.debug('%s %s' % (repr(request), repr(response))) if (not self.direction or self.direction == 'cs') and request and request.method == 'POST' and request.body: payload = request elif (not self.direction or self.direction == 'sc') and response and response.status[0] == '2': payload = response if payload: if not (not self.content_filter or self.content_filter.search(payload.headers['content-type'])): payload = None if payload: # Calculate URL host = util.getHeader(request, 'host') if host == '': host = conn.serverip url = host + request.uri # File already open if url in self.openfiles: self.debug("Adding response section to %s" % url) (s, e) = self.openfiles[url].handleresponse(response) # self.write(" --> Range: %d - %d\n" % (s, e)) # New file else: filename = request.uri.split('?')[0].split('/')[-1] if 'content-disposition' in payload.headers: cdparts = self.splitstrip(payload.headers['content-disposition'], ';') for cdpart in cdparts: try: k, v = self.splitstrip(cdpart, '=') if k == 'filename': filename = v except: pass self.debug("New file with URL: %s" % url) if not self.name_filter or self.name_filter.search(filename): if self.append_conn: filename += '_%s-%s' % (conn.serverip, conn.clientip) if self.append_ts: filename += '_%d' % (conn.ts) if not len(filename): filename = '%s-%s_index.html' % ( conn.serverip, conn.clientip) filename.replace('.exe', 'e') while os.path.exists(os.path.join(self.outdir, filename)): filename += '_' filename = filename + '.exe' # self.alert("New file: %s (%s)" % # (filename, url), conn.info()) self.openfiles[url] = httpfile( os.path.join(self.outdir, filename), self) (s, e) = self.openfiles[url].handleresponse(payload) # self.write(" --> Range: %d - %d\n" % (s, e)) if self.openfiles[url].done(): try: pefile.PE(self.openfiles[url].filename, fast_load=True) # send files to celery workers to be analysed self.alert("File done: %s (%s)" % (self.openfiles[url].filename, url), conn.info()) import requests import json # first check if file has already been scanned # if true just print id # if false send it # REST_URL = "http://172.31.60.31:1337/tasks/create/file" REST_URL = "http://172.31.60.31:1337" SAMPLE_FILE = str(self.openfiles[url].filename) file_hash = self.md5(SAMPLE_FILE) request = requests.get(REST_URL + "/files/view/md5/" + str(file_hash)) if request.status_code == 200: # file already has been scanned, just print json_decoder = json.JSONDecoder() task_id = json_decoder.decode(request.text)["sample"]["id"] self.alert("File " + SAMPLE_FILE + " already scanned with task_id %s", str(task_id)) else: # send the file to be scanned with open(SAMPLE_FILE, "rb") as sample: multipart_file = {"file": sample, "memory": "true"} request = requests.post(REST_URL + "/tasks/create/file", files=multipart_file) json_decoder = json.JSONDecoder() task_id = json_decoder.decode(request.text)["task_id"] self.alert("File " + SAMPLE_FILE + " has been sent to APTDetector-Sandbox with task_id %s", str(task_id)) # Add your code for error checking if task_id is None. except pefile.PEFormatError as e: item = str(self.openfiles[url].filename) if item.startswith("./"): item = item.split("/")[1] os.remove(item) del self.openfiles[url]
def HTTPHandler(self,conn,request,response,requesttime,responsetime): host = '' loc = '' uri = '' lastmodified = '' #request_time, request, response = self.httpDict[conn.addr] # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' if self.urlfilter: if not re.search(self.urlfilter, host+request.uri): return if '?' in request.uri: [uri_location, uri_data] = request.uri.split('?',1) else: uri_location = request.uri uri_data = '' if self.maxurilen > 0 and len(uri_location)> self.maxurilen: uri_location = uri_location[:self.maxurilen]+'[truncated]' else: uri_location = uri_location if response == None: response_message = "%s (%s) %s%s" % (request.method, 'NO RESPONSE', host, uri_location) else: response_message = "%s (%s) %s%s (%s)" % (request.method, response.status, host, uri_location, util.getHeader(response, 'content-type')) urlParams = util.URLDataToParameterDict(uri_data) postParams = util.URLDataToParameterDict(request.body) clientCookies = self._parseCookies(util.getHeader(request, 'cookie')) serverCookies = self._parseCookies(util.getHeader(response, 'set-cookie')) self.alert(response_message, urlParams=urlParams, postParams=postParams, clientCookies=clientCookies, serverCookies=serverCookies, **conn.info() ) referer = util.getHeader(request, 'referer') if len(referer): self.out.write(' Referer: %s\n' % referer) if clientCookies: self.out.write(' Client Transmitted Cookies:\n', direction='cs') for key in clientCookies: self.out.write(' %s -> %s\n' % (util.printableUnicode(key),util.printableUnicode(clientCookies[key])), direction='cs') if serverCookies: self.out.write(' Server Set Cookies:\n', direction='sc') for key in serverCookies: self.out.write(' %s -> %s\n' % (util.printableUnicode(key),util.printableUnicode(serverCookies[key])), direction='sc') if urlParams: self.out.write(' URLParameters:\n', direction='cs') for key in urlParams: self.out.write(' %s -> %s\n' % (util.printableUnicode(key),util.printableUnicode(urlParams[key])), direction='cs') if postParams: self.out.write(' POSTParameters:\n', direction='cs') for key in postParams: self.out.write(' %s -> %s\n' % (util.printableUnicode(key),util.printableUnicode(postParams[key])), direction='cs') elif len(request.body): self.out.write(' POST Body:\n', direction='cs') if len(request.body) > self.maxpost and self.maxpost > 0: self.out.write('%s[truncated]\n' % util.printableUnicode(request.body[:self.maxpost]), direction='cs') else: self.out.write(util.printableUnicode(request.body) + u"\n", direction='cs') if self.showcontent or self.showhtml: if self.showhtml and 'html' not in util.getHeader(response, 'content-type'): return if 'gzip' in util.getHeader(response, 'content-encoding'): content = self.decompressGzipContent(response.body) if content == None: content = '(gunzip failed)\n' + response.body else: content = '(gzip encoded)\n' + content else: content = response.body self.out.write("Body Content:\n", direction='sc') self.out.write(util.printableUnicode(content) + u"\n", direction='sc')
def HTTPHandler(self, conn, request, response, requesttime, responsetime): host = '' loc = '' lastmodified = '' # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' loc = '' if status[:2] == '30': loc = util.getHeader(response, 'location') if len(loc): loc = '-> {0}'.format(loc) lastmodified = util.HTTPlastmodified(response) referer = util.getHeader(request, 'referer') useragent = util.getHeader(request, 'user-agent') via = util.getHeader(request, 'via') contenttype = util.getHeader(response, 'content-type') if self.color: self.color_code = self.set_color(contenttype, response) try: responsesize = len(response.body.rstrip('\0')) except: responsesize = 0 if self.md5: md5 = self._bodyMD5(response) else: md5 = '' # File objects try: if len(response.body) > 0: responsefile = dfile.dfile( name=request.uri, data=response.body) else: responsefile = '' except: responsefile = '' if request.method == 'POST' and len(request.body): ulcontenttype, ulfilename, uldata = self.POSTHandler(request.body) uploadfile = dfile.dfile(name=ulfilename, data=uldata) else: uploadfile = None requestInfo = '{0} {1}{2} HTTP/{3}'.format( request.method, host, request.uri[:self.maxurilen] + '[truncated]' if self.maxurilen > 0 and len( request.uri) > self.maxurilen else request.uri, request.version) if response: responseInfo = '{0} {1} {2} {3}'.format(status, reason, loc, lastmodified) else: responseInfo = '' print "{0}".format(self.color_code) self.alert("{0:<80} // {1}".format(requestInfo, responseInfo) , referer=referer, useragent=useragent, request=requestInfo, response=responseInfo, request_time=requesttime, response_time=responsetime, request_method=request.method, host=host, uri=request.uri, status=status, reason=reason, lastmodified=lastmodified, md5=md5, responsesize=responsesize, contenttype=contenttype, responsefile=responsefile, uploadfile=uploadfile, via=via, **conn.info()) #Reset terminal colors to the users default print "{0}".format(ansi_colors.DEFAULT) if self.out.sessionwriter: self.write(request.data, direction='cs') if response: self.write(response.body, direction='sc')
def HTTPHandler(self, conn, request, response, requesttime, responsetime): host = '' loc = '' uri = '' lastmodified = '' #request_time, request, response = self.httpDict[conn.addr] # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' if self.urlfilter: if not re.search(self.urlfilter, host + request.uri): return if '?' in request.uri: [uri_location, uri_data] = request.uri.split('?', 1) else: uri_location = request.uri uri_data = '' if self.maxurilen > 0 and len(uri_location) > self.maxurilen: uri_location = uri_location[:self.maxurilen] + '[truncated]' else: uri_location = uri_location if response == None: response_message = "%s (%s) %s%s" % ( request.method, 'NO RESPONSE', host, uri_location) else: response_message = "%s (%s) %s%s (%s)" % ( request.method, response.status, host, uri_location, util.getHeader(response, 'content-type')) urlParams = util.URLDataToParameterDict(uri_data) postParams = util.URLDataToParameterDict(request.body) clientCookies = self._parseCookies(util.getHeader(request, 'cookie')) serverCookies = self._parseCookies( util.getHeader(response, 'set-cookie')) self.alert(response_message, urlParams=urlParams, postParams=postParams, clientCookies=clientCookies, serverCookies=serverCookies, **conn.info() ) referer = util.getHeader(request, 'referer') if len(referer): self.out.write(' Referer: %s\n' % referer) if clientCookies: self.out.write(' Client Transmitted Cookies:\n', direction='cs') for key in clientCookies: self.out.write(' %s -> %s\n' % (util.printableUnicode(key), util.printableUnicode(clientCookies[key])), direction='cs') if serverCookies: self.out.write(' Server Set Cookies:\n', direction='sc') for key in serverCookies: self.out.write(' %s -> %s\n' % (util.printableUnicode(key), util.printableUnicode(serverCookies[key])), direction='sc') if urlParams: self.out.write(' URLParameters:\n', direction='cs') for key in urlParams: self.out.write(' %s -> %s\n' % (util.printableUnicode(key), util.printableUnicode(urlParams[key])), direction='cs') if postParams: self.out.write(' POSTParameters:\n', direction='cs') for key in postParams: self.out.write(' %s -> %s\n' % (util.printableUnicode(key), util.printableUnicode(postParams[key])), direction='cs') elif len(request.body): self.out.write(' POST Body:\n', direction='cs') if len(request.body) > self.maxpost and self.maxpost > 0: self.out.write('%s[truncated]\n' % util.printableUnicode( request.body[:self.maxpost]), direction='cs') else: self.out.write( util.printableUnicode(request.body) + u"\n", direction='cs') if self.showcontent or self.showhtml: if self.showhtml and 'html' not in util.getHeader(response, 'content-type'): return if 'gzip' in util.getHeader(response, 'content-encoding'): content = self.decompressGzipContent(response.body) if content == None: content = '(gunzip failed)\n' + response.body else: content = '(gzip encoded)\n' + content else: content = response.body self.out.write("Body Content:\n", direction='sc') self.out.write( util.printableUnicode(content) + u"\n", direction='sc')
def HTTPHandler(self, conn, request, response, requesttime, responsetime): host = '' loc = '' lastmodified = '' #request_time, request, response = self.httpDict[conn.addr] # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' loc = '' if status[:2] == '30': loc = util.getHeader(response, 'location') if len(loc): loc = '-> ' + loc lastmodified = util.HTTPlastmodified(response) referer = util.getHeader(request, 'referer') useragent = util.getHeader(request, 'user-agent') via = util.getHeader(request, 'via') try: responsesize = len(response.body.rstrip('\0')) except: responsesize = 0 if self.md5: md5 = self._bodyMD5(response) else: md5 = '' # File objects try: if len(response.body) > 0: responsefile = dfile.dfile( name=request.uri, data=response.body) else: responsefile = '' except: responsefile = '' if request.method == 'POST' and len(request.body): ulcontenttype, ulfilename, uldata = self.POSTHandler(request.body) uploadfile = dfile.dfile(name=ulfilename, data=uldata) else: uploadfile = None requestInfo = '%s %s%s HTTP/%s' % (request.method, host, request.uri[:self.maxurilen] + '[truncated]' if self.maxurilen > 0 and len( request.uri) > self.maxurilen else request.uri, request.version) if response: responseInfo = '%s %s %s %s' % (status, reason, loc, lastmodified) else: responseInfo = '' self.alert("%-80s // %s" % (requestInfo, responseInfo), referer=referer, useragent=useragent, request=requestInfo, response=responseInfo, request_time=requesttime, response_time=responsetime, request_method=request.method, host=host, uri=request.uri, status=status, reason=reason, lastmodified=lastmodified, md5=md5, responsesize=responsesize, contenttype=util.getHeader(response, 'content-type'), responsefile=responsefile, uploadfile=uploadfile, via=via, **conn.info()) if self.out.sessionwriter: self.write(request.data, direction='cs') if response: self.write(response.body, direction='sc')
def HTTPHandler(self, conn, request, response, requesttime, responsetime): host = '' loc = '' lastmodified = '' # extract method,uri,host from response host = util.getHeader(request, 'host') if host == '': host = conn.serverip try: status = response.status except: status = '' try: reason = response.reason except: reason = '' loc = '' if status[:2] == '30': loc = util.getHeader(response, 'location') if len(loc): loc = '-> ' + loc lastmodified = util.HTTPlastmodified(response) referer = util.getHeader(request, 'referer') useragent = util.getHeader(request, 'user-agent') via = util.getHeader(request, 'via') content_type = util.getHeader(response, 'content-type') if self.color: color_code = self.set_color(content_type) else: color_code = '\x1b[37m' print color_code, try: responsesize = len(response.body.rstrip('\0')) except: responsesize = 0 if self.md5: md5 = self._bodyMD5(response) else: md5 = '' # File objects try: if len(response.body) > 0: responsefile = dfile.dfile(name=request.uri, data=response.body) else: responsefile = '' except: responsefile = '' if request.method == 'POST' and len(request.body): ulcontenttype, ulfilename, uldata = self.POSTHandler(request.body) uploadfile = dfile.dfile(name=ulfilename, data=uldata) else: uploadfile = None requestInfo = '%s %s%s HTTP/%s' % ( request.method, host, request.uri[:self.maxurilen] + '[truncated]' if self.maxurilen > 0 and len(request.uri) > self.maxurilen else request.uri, request.version) if response: responseInfo = '%s %s %s %s' % (status, reason, loc, lastmodified) else: responseInfo = '' self.generate_alert(conn, color_code, requestInfo, responseInfo, referer=referer, useragent=useragent, request=requestInfo, response=responseInfo, request_time=requesttime, response_time=responsetime, request_method=request.method, host=host, uri=request.uri, status=status, reason=reason, lastmodified=lastmodified, md5=md5, responsesize=responsesize, contenttype=util.getHeader(response, 'content-type'), responsefile=responsefile, uploadfile=uploadfile, via=via) if self.out.sessionwriter: self.write(request.data, direction='cs') if response: self.write(response.body, direction='sc')