Example #1
0
	def _listener(self):
		'''Listen for transport messages on the signaling socket. The default maximum 
		packet size to receive is 1500 bytes. The interval argument specifies how
		often should the sock be checked for close, default is 180 s.
		This is a generator function and should be invoked as multitask.add(u._listener()).'''
		self.app.status.append('Listener Generator Initiated')
		try:
			while self.sock and self._stack:
				try:
					data, remote = (yield multitask.recvfrom(self.sock, self.max_size, timeout=self.interval))
					logger.debug('received[%d] from %s\n%s'%(len(data),remote,data))
					if self.state != self.FUZZING and self.state != self.FUZZING_COMPETED:
						self._stack.received(data, remote)
					else:
						m = rfc3261_IPv6.Message()
						try:
							if self.crash_fuzz==self.WAIT_CRSH_CHK and self.crash_porbe==self.CRASH_PROBE_REC:
								# If response to fuzz is received
								# m._parse(data)
								self.app.fuzzResponse[self.fuzz_index] = data.split('\n', 1)[0].replace('\r','')
								self.crash_porbe=self.FUZZ_RECV
							elif self.crash_fuzz==self.WAIT_CRSH_CHK and self.crash_porbe==self.CRASH_PROBE_SENT:
								# If response to probe received
								self._stack.received(data, remote)
								self.app.probeResponse[self.fuzz_index] = data.split('\n', 1)[0].replace('\r','')
						except ValueError, E: # TODO: send 400 response to non-ACK request
							logger.debug('Error in received message:', E)
							logger.debug(traceback.print_exc())
				except multitask.Timeout:
					if self.state == self.FUZZING and self.crash_detect:
						print (bcolors.FAIL+"Crash detected!"+bcolors.ENDC +" It seems that we found a server crash. Server is not responding. If this is a false-positive you can use --fuzz-crash-no-stop option to prevent the app stop at crash detection.")
						self.app.printResults()
						self.app.stop()
		except GeneratorExit: pass
		except: print 'User._listener exception', (sys and sys.exc_info() or None); traceback.print_exc(); raise
		logger.debug('terminating User._listener()')
Example #2
0
		def _send(self, data, addr): # generator version
			if self._snifferGen:
				# Reconfig socket needed because of scapy -------------------
				if rfc2396_IPv6.isIPv6(self.remoteTarget): # Unstable
					if self.app.options.int_ip == '0.0.0.0': self.app.options.int_ip= '::1'
					sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM if self.app.options.transport == self.UDP else socket.SOCK_STREAM)
				else:
					sock = socket.socket(type=socket.SOCK_DGRAM if self.app.options.transport == self.UDP else socket.SOCK_STREAM)
				sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
				sock.bind((self.app.options.int_ip, (self.app.options.port+1) if self.app.options.transport == self.TLS else self.app.options.port))
				self.sock = sock
			#------------------------------------------------------------
			try:
				logger.debug('sending[%d] to %s\n%s'%(len(data), addr, data))
				if self.sock:
					if self.sock.type == socket.SOCK_STREAM:
						try: 
							remote = self.sock.getpeername()
							if remote != addr:
								logger.debug('connected to wrong addr', remote, 'but sending to', addr)
						except socket.error: # not connected, try connecting
							try:
								self.sock.connect(addr)
							except socket.error:
								logger.debug('failed to connect to', addr)
						try:
							yield self.sock.send(data)
						except socket.error:
							logger.debug('socket error in send')
					elif self.sock.type == socket.SOCK_DGRAM:
						try:
							yield self.sock.sendto(data, addr)
						except socket.error:
							logger.debug('socket error in sendto' )
					else:
						logger.debug('invalid socket type', self.sock.type)
			except AttributeError: pass
Example #3
0
	def _fuzzing(self):
		# Msg to Fuzz generator ---------
		fuzzers = {'InviteCommonFuzzer': 'INVITE_COMMON', 'InviteStructureFuzzer': 'INVITE_STRUCTURE', 'InviteRequestLineFuzzer': 'INVITE_REQUEST_LINE','InviteOtherFuzzer': 'INVITE_OTHER', 'CANCELFuzzer': 'CANCEL', 'REGISTERFuzzer': 'REGISTER','SUBSCRIBEFuzzer': 'SUBSCRIBE', 'NOTIFYFuzzer': 'NOTIFY', 'ACKFuzzer': 'ACK'}

		def fuzzingCtrl(fuzz_index):
			if self.state == self.FUZZING:
				import datetime
				def log_perc_completed(i, partials, total=self.mutations):
					partials = map(int,(partials.split(',')))
					for partial in partials:
						if i == (partial*total/100):
							logger.info(str((datetime.datetime.now()-self.start_fuzz_time).total_seconds()*1000)+' msec'+':		'+str(int((total*partial/100)//1))+'/'+str(total)+' ('+str(int((partial)//1))+'%) messages sent')
				if not self.start_fuzz_time:
					self.start_fuzz_time = datetime.datetime.now()
				if self.crash_detect:
					log_perc_completed(fuzz_index,'1,2,4,8,10,20,30,40,50,60,70,80,90,100')
				else:
					log_perc_completed(fuzz_index,'25,50,75,100')
				
		def _createMutableMessage():
			# Msg to Fuzz generator ---------
			if not self.fuzzer == 'All':
				mutable_msg = s_get(fuzzers.get(self.fuzzer))
			else:
				mutable_msg = s_get(fuzzers.get('INVITE_COMMON'))
			return mutable_msg
			
		def _createFuzzerMsgGen(mutable_msg):
			def replaceDefaults(rendered_msg):
				from random import Random
				import string
				# branch
				self.curr_invite_branch = ''.join(Random().sample(string.ascii_lowercase+string.digits, 32))
				rendered_msg = rendered_msg.replace('somebranchvalue', self.curr_invite_branch)
				rendered_msg = rendered_msg.replace('somefromtagvalue', self.curr_invite_branch)
				rendered_msg = rendered_msg.replace('somecallidvalue', self.curr_invite_branch)
				# This stuff is new in this function and should be moved elsewhere
				# Works fine here for now though
				rendered_msg = rendered_msg.replace('TARGET_USER', self.remoteParty.uri.user)
				rendered_msg = rendered_msg.replace('HOST', self.remoteParty.uri.host)
				rendered_msg = rendered_msg.replace('USER', self.localParty.uri.user)
				rendered_msg = rendered_msg.replace('LOCAL_IP', self.localParty.uri.host)
				rendered_msg = rendered_msg.replace('192.168.96.69', self.localParty.uri.host)
				rendered_msg = rendered_msg.replace('192.168.99.99', self.localParty.uri.host)        
				rendered_msg = rendered_msg.replace('PORT', str(self.localParty.uri.port))
				rendered_msg = rendered_msg.replace(':password', '')
				return rendered_msg
				
			if not self.fuzzer == 'All':
				for i in range(min(self.mutations, self.fuzz_max_msgs)):
					mutable_msg.mutate()
					m = replaceDefaults(mutable_msg.render())
					yield (m)
			else:
				msg_counter = 0
				for item in fuzzers:
					mutable_msg = s_get(fuzzers.get(item))
					for i in range(mutable_msg.num_mutations()):
						msg_counter += 1
						if msg_counter < min(self.mutations, self.fuzz_max_msgs):
							mutable_msg.mutate()
							m = replaceDefaults(mutable_msg.render())
							yield (m)
		
		# Stop listener if no crash detection is been used
		if self.listenerOff: self._listenerGen.close()
		# Dest Address
		addr = self.remoteTarget.uri
		if addr and isinstance(addr, rfc2396_IPv6.URI):
			if not addr.host: raise ValueError, 'No host in destination uri'
			addr = (addr.host, addr.port or self.transport.type == 'tls' and self.transport.secure and 5061 or 5060)
		mutable_msg = _createMutableMessage()
		# Msg generator
		if not self.fuzzer == 'All':
			self.mutations = mutable_msg.num_mutations()
		else:
			self.mutations = 0
			for item in fuzzers:
				self.mutations += s_get(fuzzers.get(item)).num_mutations()
		Fuzz_Generator = _createFuzzerMsgGen(mutable_msg)
		if self.audit_file_name:
			self.audit_file_name = open(self.audit_file_name, 'w')
		print "Fuzzing %s messages to %s" % (self.mutations, addr)
		try:
			if self.sock:
				if self.sock.type == socket.SOCK_STREAM:
					pass
				elif self.sock.type == socket.SOCK_DGRAM:
					while True:
						try:
							data = str(Fuzz_Generator.next())
							if len(data) > 9216:
								data = data[:9216]
							try:
								# SEND FUZZ MSG
								self.sock.sendto(data, addr)
								# Index
								self.fuzz_index += 1
								fuzzingCtrl(self.fuzz_index)
								if self.audit_file_name:
									self.audit_file_name.write("Index "+str(self.fuzz_index)+"\n--\n"+data+"\n--\n\n")
								self.crash_fuzz=self.WAIT_CRSH_CHK
								# if crash detect => wait until crash detection is completed
								#print '1. Fuzz sent'
								while (self.crash_detect and self.crash_fuzz!=self.WAIT_FUZZ):
									yield multitask.sleep(1)
							except socket.error:
								logger.debug('socket error in sendto' )
						except StopIteration:
							self.state = self.FUZZING_COMPETED
							raise StopIteration()
						yield
				else:
					logger.debug('invalid socket type', self.sock.type)
		except AttributeError: pass
Example #4
0
	def _flood(self):
		from helper_functions import generateExtentions, loopExtentionsDictionary
		# Flood info messages ---------
		def floodingCtrl():
			if self.state == self.FLOODING:
				import datetime
				def log_perc_completed(i, partials, total=self.flood_num):
					partials = map(int,(partials.split(',')))
					for partial in partials:
						if i == (partial*total/100):
							logger.info(str((datetime.datetime.now()-self.start_flood_time).total_seconds()*1000)+' msec'+':		'+str(int((total*partial/100)//1))+'/'+str(total)+' ('+str(int((partial)//1))+'%) messages sent')
				if not self.start_flood_time:
					self.start_flood_time = datetime.datetime.now()
				self.flood_msg += 1
				log_perc_completed(self.flood_msg,'25,50,75,100')
		# Msg to flood generator ---------
		def _createBaseMessage():
			if self.flood_msg_file:
				with open (self.flood_msg_file, "r") as file_txt:
					file_txt=file_txt.read()
				m = rfc3261_IPv6.Message()
				try:
					if self.flood_noparse:
						m = file_txt
					else:
						m = m._parse(file_txt.rstrip()+'\r\n\r\n\r\n')
				except ValueError, E: pass # TODO: send 400 response to non-ACK request
			else:
				m = self._ua.createRequest(self.flood_method)
				m.To = rfc3261_IPv6.Header(str(self.app.options.to.uri), 'To')
				m.Contact = rfc3261_IPv6.Header(str(self._stack.uri), 'Contact')
				m.Contact.value.uri.user = self.localParty.uri.user
				m.Expires = rfc3261_IPv6.Header(str(self.app.options.register_interval), 'Expires')
			return m
		def _createFloodMsgGen(message_generated):
			if self.app.options.modify_extentions and not self.flood_noparse:
				if self.app.options.ExtDictionary is not None:
					try:
						dictionary = open(self.app.options.ExtDictionary,'r')
					except IOError:
						logger.error( "Could not open %s" % self.app.options.ExtDictionary )
						exit(1)
					self.ExtensionsGenerator =  loopExtentionsDictionary(dictionary)
				else:
					self.ExtensionsGenerator = generateExtentions(*(self.app.options.ExtRange,self.app.options.ExtZeropadding,self.app.options.ExtTemplate,self.app.options.ExtDefaults))
				self.message_generated = message_generated
				while True:
					message_generated = self.message_generated
					# Modify message_generated: extension (To,From), tag, Call-ID
					extension = self.ExtensionsGenerator.next()
					if message_generated.method == "INVITE":
						if self.app.options.registrar_ip != self.app.options.to.uri.host:
							SourceFakeAddr = self.app.options.registrar_ip
						else:
							SourceFakeAddr = str(self.app.options.to.uri.host).split('.')
							SourceFakeAddr[3] = str(random.randint(0,254))
							SourceFakeAddr = ".".join(SourceFakeAddr)
						message_generated.From.value.uri.user = message_generated.From.value.displayName =  extension
						message_generated.From.value.uri.host = SourceFakeAddr
					else:
						message_generated.From.value.uri.user = message_generated.From.value.displayName =  message_generated.To.value.uri.user = message_generated.To.value.displayName = extension
					message_generated.From.tag=str(random.randint(0,2**31))
					message_generated['Call-ID'] = rfc3261_IPv6.Header(str(random.randint(0,2**31)) + '@' + (message_generated.From.value.uri.host or 'localhost'), 'Call-ID')
					yield (message_generated)
			else:
				while True:
					yield (message_generated)
		# Dest Address
		addr = self.remoteTarget.uri
		if addr and isinstance(addr, rfc2396_IPv6.URI):
			if not addr.host: raise ValueError, 'No host in destination uri'
			addr = (addr.host, addr.port or self.transport.type == 'tls' and self.transport.secure and 5061 or 5060)
		# Msg generator
		base_msg = _createBaseMessage()
		flood_msg = _createFloodMsgGen(base_msg)
		if self.flood_noparse:
			print "Flooding %s NOPARSED messages to %s" % (self.flood_num, addr)
		else:
			print "Flooding %s %s messages to %s" % (self.flood_num, base_msg.method, addr)
		try:
			if self.sock:
				if self.sock.type == socket.SOCK_STREAM:
					try: 
						remote = self.sock.getpeername()
						if remote != addr:
							logger.debug('connected to wrong addr', remote, 'but sending to', addr)
					except socket.error: # not connected, try connecting
						try:
							self.sock.connect(addr)
						except socket.error:
							logger.debug('failed to connect to', addr)
					try:
						for i in range(self.flood_num):
							logger.debug('[Msg:%s/%s] sending[%d] to %s\n%s'%((self.flood_msg+1),self.flood_num,len(data), addr, ''))
							self.sock.send(data)
							floodingCtrl()
						self.app.stop()
						yield
						raise StopIteration()
					except socket.error:
						logger.debug('socket error in send')
				elif self.sock.type == socket.SOCK_DGRAM:
					try:
						for i in range(self.flood_num):
							data = str(flood_msg.next())
							logger.debug('[Msg:%s/%s] sending[%d] to %s\n%s'%((self.flood_msg+1),self.flood_num,len(data), addr, ''))
							logger.debug(data)
							self.sock.sendto(data, addr)
							floodingCtrl()
						self.app.stop()
						yield
						raise StopIteration()
					except socket.error:
						logger.debug('socket error in sendto' )
				else:
					logger.debug('invalid socket type', self.sock.type)
		except AttributeError: pass