def onIncomingData(self, data=None, fromAddr=None): """ """ try: ip, port = fromAddr # separator feature is disabled if data is not None: # log event data_size = len(data) if self.logEventReceived: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data=data, data_length=str(data_size)), src_ip=ip, src_port=port) else: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data_length=str(data_size)), src_ip=ip, src_port=port) if self.logEventReceived: tpl.addRaw(raw=data) self.logRecvEvent(shortEvt="data", tplEvt=tpl) # handle data self.handleIncomingData(data, lower=tpl) # separator feature is enabled, split the buffer by the separator else: datas = self.buf[fromAddr].split(self.cfg['sep-in']) for data in datas[:-1]: pdu = data + self.cfg['sep-in'] # log event pdu_size = len(data) if self.logEventReceived: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data=pdu, data_length=str(pdu_size)), src_ip=ip, src_port=port) else: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data_length=str(pdu_size)), src_ip=ip, src_port=port) if self.logEventReceived: tpl.addRaw(raw=pdu) self.logRecvEvent(shortEvt="data reassembled", tplEvt=tpl) # handle data self.handleIncomingData(pdu, lower=tpl) self.buf[fromAddr] = datas[-1] except Exception as e: self.error(str(e))
def onReceiving(self, data, fromAddr, toAddr, lower): """ Function to overwrite Called on incoming data @param data: data received @type data: string @param lower: template data received @type lower: templatemessage """ # extract transport info self.lastActivity = time.time() srcIp, srcPort = fromAddr dstIp, dstPort = toAddr # the separator feature is disabled, to nothing if self.cfg['sep-disabled']: try: self.handleIncomingData(data=data, lower=lower, fromAddr=fromAddr, toAddr=toAddr) except Exception as e: self.error( "on handle incoming tcp data, upper layer problem: %s" % str(e) ) else: # bufferize data if self.buf.has_key(fromAddr): self.buf[fromAddr] = ''.join([self.buf[fromAddr], data]) else: self.buf[fromAddr] = data # split data with the separator datas = self.buf[fromAddr].split(self.cfg['sep-in']) for d in datas[:-1]: tcp_data = d + self.cfg['sep-in'] tcp_data_size = len(tcp_data) # construct high template and log it tpl = TestTemplatesLib.TemplateMessage() tpl.addLayer( layer=AdapterIP.ip( source=srcIp, destination=dstIp, more=AdapterIP.received(), version=self.cfg['ip-version'] ) ) if self.logEventReceived: tcp_layer = templates.tcp(source=srcPort, destination=dstPort, more=templates.received(data=tcp_data, data_length=str(tcp_data_size) ) ) else: tcp_layer = templates.tcp(source=srcPort, destination=dstPort, more=templates.received(data_length=str(tcp_data_size) ) ) tpl.addLayer( layer=tcp_layer ) if self.logEventReceived: tpl.addRaw(raw=tcp_data) self.logRecvEvent( shortEvt = 'data reassembled', tplEvt = tpl ) # handle data self.handleIncomingData( tcp_data, lower=tpl, fromAddr=fromAddr, toAddr=toAddr) self.buf[fromAddr] = datas[-1]
def decode(self, sock): """ """ self.debug('decode sock rsp: %s' % sock) tpl = None summary = 'response' try: sock_rsp = struct.unpack('!2BH4B', sock) # CD is the result code with one of the following values: CD = str(sock_rsp[1]) # 90: request granted # 91: request rejected or failed # 92: request rejected becasue SOCKS server cannot connect to # identd on the client # 93: request rejected because the client program and identd # report different user-ids. if sock_rsp[1] == 90: summary = 'granted' if sock_rsp[1] == 91: summary = 'rejected' # VN is the version of the reply code and should be 0 VN = str(sock_rsp[0]) tpl = templates.socks(version=VN, result=CD, remotePort=str(sock_rsp[2]), remoteAddress='.'.join(map( str, sock_rsp[3:])), more=templates.received()) except Exception as e: self.error('unable to decode sock4 response: %s' % e) return (tpl, summary)
def hasReceivedPing(self, timeout=1.0): """ Waits to receive "ping" event until the end of the timeout. @param timeout: time to wait response in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout) tpl_rsp = TestTemplatesLib.TemplateMessage() if self.cfg['agent-support']: layer_agent = TestTemplatesLib.TemplateLayer('AGENT') layer_agent.addKey(name='name', data=self.cfg['agent']['name']) layer_agent.addKey(name='type', data=self.cfg['agent']['type']) tpl_rsp.addLayer(layer_agent) tpl_rsp.addLayer(AdapterIP.ip(more=AdapterIP.received())) tpl_rsp.addLayer(AdapterTCP.tcp(more=AdapterTCP.received())) if self.cfg['ssl-support']: tpl_rsp.addLayer(AdapterSSL.ssl(more=AdapterSSL.received())) tpl_rsp.addLayer( templates.ws(opcode=codec.WEBSOCKET_OPCODE_PING, more=templates.received())) return self.received(expected=tpl_rsp, timeout=timeout)
def onInactivityTimeout(self): """ """ tpl = TestTemplatesLib.TemplateMessage() tpl.addLayer( layer=AdapterIP.ip( more=AdapterIP.received() ) ) tpl.addLayer( layer=templates.udp( more=templates.received() ) ) self.onInactivity(lower=tpl)
def hasReceivedPong(self, timeout=1.0): """ Waits to receive "pong" event until the end of the timeout. @param timeout: time to wait response in second (default=1s) @type timeout: float @return: an event matching with the template or None otherwise @rtype: templatemessage """ if not (isinstance(timeout, int) or isinstance(timeout, float)) or isinstance(timeout, bool): raise TestAdapterLib.ValueException( TestAdapterLib.caller(), "timeout argument is not a float or integer (%s)" % type(timeout)) tpl_rsp = TestTemplatesLib.TemplateMessage() if self.cfg['agent-support']: layer_agent = TestTemplatesLib.TemplateLayer('AGENT') layer_agent.addKey(name='name', data=self.cfg['agent']['name']) layer_agent.addKey(name='type', data=self.cfg['agent']['type']) tpl_rsp.addLayer(layer_agent) tpl_rsp.addLayer(AdapterIP.ip(more=AdapterIP.received())) tpl_rsp.addLayer(AdapterTCP.tcp(more=AdapterTCP.received())) if self.cfg['ssl-support']: tpl_rsp.addLayer(AdapterSSL.ssl(more=AdapterSSL.received())) tpl_rsp.addLayer( templates.ws(opcode=codec.WEBSOCKET_OPCODE_PONG, more=templates.received())) return self.received(expected=tpl_rsp, timeout=timeout)
def onInactivityTimeout(self): """ """ tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received(), src_ip=self.cfg['dst-ip'], src_port=self.cfg['dst-port']) self.onInactivity(lower=tpl)
def onIncomingDecodedData(self, data, tpl): """ """ # log received event tpl = self.encapsule(tpl=tpl, ssl_event=templates.received(data=data)) if self.logEventReceived: tpl.addRaw(raw=data) self.logRecvEvent(shortEvt="data", tplEvt=tpl) return tpl
def hasReceivedData(self, tpl, timeout, data=None, sslVersion=None, sslCipher=None): """ """ # construct the expected template tpl_ssl = templates.received(data=data) expected = self.getExpectedTemplate( mainTpl=tpl, tpl=tpl_ssl ) # try to match the template evt = self.received( expected = expected, timeout = timeout ) return evt
def hasClientData(self, timeout=1.0, clientId=None, data=None, versionIp=None, sourceIp=None, destinationIp=None, sourcePort=None, destinationPort=None): """ Waits to receive "data" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @param data: data expected @type data: string/operators @param versionIp: version ip expected @type versionIp: string/operators/none @param sourceIp: source ip expected @type sourceIp: string/operators/none @param destinationIp: destination ip expected @type destinationIp: string/operators/none @param sourcePort: source port expected @type sourcePort: string/operators/none @param destinationPort: destination port expected @type destinationPort: string/operators/none @return: an event matching with the template or None otherwise @rtype: templatemessage """ if not (isinstance(timeout, int) or isinstance(timeout, float)) or isinstance(timeout, bool): raise TestAdapterLib.ValueException( TestAdapterLib.caller(), "timeout argument is not a float or integer (%s)" % type(timeout)) # construct the expected template tpl = templates.received(data=data, id=clientId) expected = self.getExpectedTemplate(tpl=tpl, versionIp=versionIp, sourceIp=sourceIp, destinationIp=destinationIp, sourcePort=sourcePort, destinationPort=destinationPort) # try to match the template evt = self.received(expected=expected, timeout=timeout) return evt
def hasReceivedData(self, timeout=1.0, data=None, versionIp=None, sourceIp=None, destinationIp=None, sourcePort=None, destinationPort=None): """ Waits to receive "data" event until the end of the timeout @param timeout: time max to wait to receive event in second (default=1s) @type timeout: float @param data: data expected @type data: string/operators @param versionIp: version ip expected @type versionIp: string/operators/none @param sourceIp: source ip expected @type sourceIp: string/operators/none @param destinationIp: destination ip expected @type destinationIp: string/operators/none @param sourcePort: source port expected @type sourcePort: string/operators/none @param destinationPort: destination port expected @type destinationPort: string/operators/none @return: an event matching with the template or None otherwise @rtype: templatemessage """ TestAdapterLib.check_timeout(caller=TestAdapterLib.caller(), timeout=timeout) # construct the expected template tpl = templates.received(data=data) expected = self.getExpectedTemplate(tpl=tpl, versionIp=versionIp, sourceIp=sourceIp, destinationIp=destinationIp, sourcePort=sourcePort, destinationPort=destinationPort) # try to match the template evt = self.received(expected=expected, timeout=timeout) return evt
def decodenego(self, sock): """ """ self.debug('decode sock nego rsp') tpl = None summary = 'response' try: sock_rsp = struct.unpack('!2B', sock) # extract version V = str(sock_rsp[0]) # '00' NO AUTHENTICATION REQUIRED # '01' GSSAPI # '02' USERNAME/PASSWORD # '03' to X'7F' IANA ASSIGNED # '80' to X'FE' RESERVED FOR PRIVATE METHODS # 'FF' NO ACCEPTABLE METHODS METHOD = 'unknown' if sock_rsp[1] == 0: METHOD = 'no authentication required' if sock_rsp[1] == 1: METHOD = 'gssapi' if sock_rsp[1] == 2: METHOD = 'username/password' if sock_rsp[1] == 255: METHOD = 'no acceptable methods' summary = METHOD tpl = templates.socks(version=V, methods=str(sock_rsp[1]), methods_str=METHOD, more=templates.received()) except Exception as e: self.error('unable to decode sock5 nego response: %s' % e) return (tpl, summary)
def decode(self, sock): """ Support ipv4 only for now """ self.debug('decode sock rsp') tpl = None summary = 'response' try: sock_rsp = struct.unpack('!4B4BH', sock) if sock_rsp[1] == 0: summary = 'succeeded' tpl = templates.socks(version=str(sock_rsp[0]), result=str(sock_rsp[1]), reserved=str(sock_rsp[2]), remoteType=str(sock_rsp[3]), remotePort=str(sock_rsp[8]), remoteAddress='.'.join( map(str, sock_rsp[4:8])), more=templates.received()) except Exception as e: self.error('unable to decode sock5 response: %s' % e) return (tpl, summary)
left = buffer[hdrs_len + length:] else: self.debug("ws need more data fin=0") left = buffer # need mode data needMore = True if not needMore: self.debug('decode complete') tpl = templates.ws(fin=fin, mask=has_mask, rsv1=rsv1, rsv2=rsv2, rsv3=rsv3, opcode=opcode, data=payload, data_length=len(payload), more=templates.received()) tpl.addRaw(buffer) except Exception as e: self.error('unable to decode ws data: %s' % e) return (payload, left, needMore, tpl) def encodeWsData(self, tpl): """ Encode ws message @param data: data @type data: string @param opcode: opcode @type opcode: integer """
def decodeWsData(self, buffer): """ Decode ws message @param buffer: buffer @type buffer: string """ tpl = None payload = '' opcode = None left = '' needMore = False try: try: hdrs_len = 2 # B = 1 octet # H = 2 octets # I = 4 octets fixed_hdr = struct.unpack('!2B', buffer[:hdrs_len]) remaining = buffer[hdrs_len:] except struct.error as e: left = buffer # need more data needMore = True self.debug("ws need more data in header") else: fin = fixed_hdr[0] >> 7 & 1 rsv1 = fixed_hdr[0] >> 6 & 1 rsv2 = fixed_hdr[0] >> 5 & 1 rsv3 = fixed_hdr[0] >> 4 & 1 opcode = fixed_hdr[0] & 0xf has_mask = fixed_hdr[1] >> 7 & 1 length = fixed_hdr[1] & 0x7f self.debug("ws header: %s, %s, %s, %s, %s, %s, %s" % (fin, rsv1, rsv2, rsv3, opcode, has_mask, length)) if length == 126: try: hdrs_extended_len = 2 size = buffer[hdrs_len:hdrs_len + hdrs_extended_len] ext_lenght_hdr = struct.unpack( '!H', buffer[hdrs_len:hdrs_len + hdrs_extended_len]) except struct.error as e: left = buffer # need more data needMore = True self.debug("ws need more data in data") else: length_ext = ext_lenght_hdr[0] self.debug("ws lenght extended: %s" % length_ext) if fin: if len( buffer ) < hdrs_len + hdrs_extended_len + length_ext: self.debug( "data extended, need more data (%s/%s)" % (len(buffer), length_ext)) left = buffer # need more data needMore = True else: payload = buffer[hdrs_len + hdrs_extended_len:hdrs_len + hdrs_extended_len + length_ext] left = buffer[hdrs_len + hdrs_extended_len + length_ext:] else: left = buffer # need more data needMore = True else: if fin: if len(buffer) < hdrs_len + length: self.debug( "fin=1 but insufficient data in buffer, need more (%s/%s)" % (len(buffer), length)) left = buffer # need mode data needMore = True else: payload = buffer[hdrs_len:hdrs_len + length] left = buffer[hdrs_len + length:] else: self.debug("ws need more data fin=0") left = buffer # need mode data needMore = True if not needMore: self.debug('decode complete') tpl = templates.ws(fin=fin, mask=has_mask, rsv1=rsv1, rsv2=rsv2, rsv3=rsv3, opcode=opcode, data=payload, data_length=len(payload), more=templates.received()) tpl.addRaw(buffer) except Exception as e: self.error('unable to decode ws data: %s' % e) return (payload, left, needMore, tpl)
def onClientIncomingData(self, clientAddress, data=None): """ """ try: ip, port = clientAddress id = self.clients[clientAddress]['id'] # separator feature is disabled if data is not None: # log event data_size = len(data) if self.logEventReceived: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data=data, data_length=str(data_size), id=id), src_ip=ip, src_port=port) else: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data_length=str(data_size), id=id), src_ip=ip, src_port=port) if self.logEventReceived: tpl.addRaw(raw=data) self.logRecvEvent(shortEvt="client #%s data" % self.clients[clientAddress]['id'], tplEvt=tpl) # handle data self.handleIncomingData(clientAddress=clientAddress, data=data, lower=tpl) # separator feature is enabled, split the buffer by the separator else: datas = self.clients[clientAddress]['buffer'].split( self.cfg['sep-in']) for data in datas[:-1]: pdu = data + self.cfg['sep-in'] # log event pdu_size = len(data) if self.logEventReceived: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data=pdu, data_length=str(pdu_size), id=id), src_ip=ip, src_port=port) else: tpl = self.encapsule(ip_event=AdapterIP.received(), udp_event=templates.received( data_length=str(pdu_size), id=id), src_ip=ip, src_port=port) if self.logEventReceived: tpl.addRaw(raw=pdu) self.logRecvEvent( shortEvt="client #%s data reassembled" % id, tplEvt=tpl) # handle data self.handleIncomingData(clientAddress=clientAddress, data=pdu, lower=tpl) self.clients[clientAddress]['buffer'] = datas[-1] except Exception as e: self.error(str(e))