def handle(self, sock, address): sock.settimeout(self.timeout) session = conpot_core.get_session('s7comm', address[0], address[1]) self.start_time = time.time() logger.info('New connection from {0}:{1}. ({2})'.format(address[0], address[1], session.id)) try: while True: data = sock.recv(4, socket.MSG_WAITALL) if len(data) == 0: break _, _, length = unpack('!BBH', data[:4]) data += sock.recv(length - 4) tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xe0: # connection request cotp_cr_request = COTP_ConnectionRequest().dissect(cotp_base_packet.payload) logger.debug('Received COTP Connection Request: dst-ref:{0} src-ref:{1} dst-tsap:{2} src-tsap:{3} ' 'tpdu-size:{4}. ({5})'.format(cotp_cr_request.dst_ref, cotp_cr_request.src_ref, cotp_cr_request.dst_tsap, cotp_cr_request.src_tsap, cotp_cr_request.tpdu_size, session.id)) # confirm connection response cotp_cc_response = COTP_ConnectionConfirm(cotp_cr_request.src_ref, cotp_cr_request.dst_ref, 0, cotp_cr_request.src_tsap, cotp_cr_request.dst_tsap, 0x0a).assemble() # encapsulate and transmit cotp_resp_base_packet = COTP_BASE_packet(0xd0, 0, cotp_cc_response).pack() tpkt_resp_packet = TPKT(3, cotp_resp_base_packet).pack() sock.send(tpkt_resp_packet) session.add_event({'request': data.encode('hex'), 'response': tpkt_resp_packet.encode('hex')}) data = sock.recv(1024) # another round of parsing payloads tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xf0: logger.debug('Received known COTP TPDU: {0}. ({1})'.format(cotp_base_packet.tpdu_type, session.id)) # will throw exception if the packet does not contain the S7 magic number (0x32) S7_packet = S7().parse(cotp_base_packet.trailer) logger.debug('Received S7 packet: magic:{0} pdu_type:{1} reserved:{2} req_id:{3} param_len:{4} ' 'data_len:{5} result_inf:{6}'.format( S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id)) # request pdu if S7_packet.pdu_type == 1: # 0xf0 == Request for connect / pdu negotiate if S7_packet.param == 0xf0: # create S7 response packet s7_resp_negotiate_packet = S7(3, 0, S7_packet.request_id, 0, S7_packet.parameters).pack() # wrap s7 the packet in cotp cotp_resp_negotiate_packet = COTP_BASE_packet(0xf0, 0x80, s7_resp_negotiate_packet).pack() # wrap the cotp packet tpkt_resp_packet = TPKT(3, cotp_resp_negotiate_packet).pack() sock.send(tpkt_resp_packet) session.add_event({'request': data.encode('hex'), 'response': tpkt_resp_packet.encode('hex')}) # handshake done, give some more data. data = sock.recv(1024) while data: tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xf0: S7_packet = S7().parse(cotp_base_packet.trailer) logger.debug('Received S7 packet: magic:{0} pdu_type:{1} reserved:{2} ' 'req_id:{3} param_len:{4} data_len:{5} result_inf:{6}'.format( S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id)) response_param, response_data = S7_packet.handle() s7_resp_ssl_packet = S7(7, 0, S7_packet.request_id, 0, response_param, response_data).pack() cotp_resp_ssl_packet = COTP_BASE_packet(0xf0, 0x80, s7_resp_ssl_packet).pack() tpkt_resp_packet = TPKT(3, cotp_resp_ssl_packet).pack() sock.send(tpkt_resp_packet) session.add_event({'request': data.encode('hex'), 'response': tpkt_resp_packet.encode('hex')}) data = sock.recv(1024) else: logger.debug( 'Received unknown COTP TPDU after handshake: {0}'.format(cotp_base_packet.tpdu_type)) else: logger.debug('Received unknown COTP TPDU before handshake: {0}'.format(cotp_base_packet.tpdu_type)) except socket.timeout: logger.debug('Socket timeout, remote: {0}. ({1})'.format(address[0], session.id))
def handle(self, sock, address): sock.settimeout(self.timeout) session = conpot_core.get_session("s7comm", address[0], address[1]) self.start_time = time.time() logger.info("New connection from {0}:{1}. ({2})".format(address[0], address[1], session.id)) session.add_event({"type": "NEW_CONNECTION"}) try: while True: data = sock.recv(4, socket.MSG_WAITALL) if len(data) == 0: session.add_event({"type": "CONNECTION_LOST"}) break _, _, length = unpack("!BBH", data[:4]) data += sock.recv(length - 4, socket.MSG_WAITALL) tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xE0: # connection request cotp_cr_request = COTP_ConnectionRequest().dissect(cotp_base_packet.payload) logger.debug( "Received COTP Connection Request: dst-ref:{0} src-ref:{1} dst-tsap:{2} src-tsap:{3} " "tpdu-size:{4}. ({5})".format( cotp_cr_request.dst_ref, cotp_cr_request.src_ref, cotp_cr_request.dst_tsap, cotp_cr_request.src_tsap, cotp_cr_request.tpdu_size, session.id, ) ) # confirm connection response cotp_cc_response = COTP_ConnectionConfirm( cotp_cr_request.src_ref, cotp_cr_request.dst_ref, 0, cotp_cr_request.src_tsap, cotp_cr_request.dst_tsap, 0x0A, ).assemble() # encapsulate and transmit cotp_resp_base_packet = COTP_BASE_packet(0xD0, 0, cotp_cc_response).pack() tpkt_resp_packet = TPKT(3, cotp_resp_base_packet).pack() sock.send(tpkt_resp_packet) session.add_event({"request": data.encode("hex"), "response": tpkt_resp_packet.encode("hex")}) data = sock.recv(1024) # another round of parsing payloads tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xF0: logger.debug( "Received known COTP TPDU: {0}. ({1})".format(cotp_base_packet.tpdu_type, session.id) ) # will throw exception if the packet does not contain the S7 magic number (0x32) S7_packet = S7().parse(cotp_base_packet.trailer) logger.debug( "Received S7 packet: magic:%s pdu_type:%s reserved:%s req_id:%s param_len:%s " "data_len:%s result_inf:%s session_id:%s", S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id, ) # request pdu if S7_packet.pdu_type == 1: # 0xf0 == Request for connect / pdu negotiate if S7_packet.param == 0xF0: # create S7 response packet s7_resp_negotiate_packet = S7( 3, 0, S7_packet.request_id, 0, S7_packet.parameters ).pack() # wrap s7 the packet in cotp cotp_resp_negotiate_packet = COTP_BASE_packet( 0xF0, 0x80, s7_resp_negotiate_packet ).pack() # wrap the cotp packet tpkt_resp_packet = TPKT(3, cotp_resp_negotiate_packet).pack() sock.send(tpkt_resp_packet) session.add_event( {"request": data.encode("hex"), "response": tpkt_resp_packet.encode("hex")} ) # handshake done, give some more data. data = sock.recv(1024) while data: tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xF0: S7_packet = S7().parse(cotp_base_packet.trailer) logger.debug( "Received S7 packet: magic:%s pdu_type:%s reserved:%s " "req_id:%s param_len:%s data_len:%s result_inf:%s session_id:%s", S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id, ) response_param, response_data = S7_packet.handle() s7_resp_ssl_packet = S7( 7, 0, S7_packet.request_id, 0, response_param, response_data ).pack() cotp_resp_ssl_packet = COTP_BASE_packet(0xF0, 0x80, s7_resp_ssl_packet).pack() tpkt_resp_packet = TPKT(3, cotp_resp_ssl_packet).pack() sock.send(tpkt_resp_packet) session.add_event( {"request": data.encode("hex"), "response": tpkt_resp_packet.encode("hex")} ) data = sock.recv(1024) else: logger.debug( "Received unknown COTP TPDU after handshake: {0}".format(cotp_base_packet.tpdu_type) ) session.add_event( { "error": "Received unknown COTP TPDU after handshake: {0}".format( cotp_base_packet.tpdu_type ) } ) else: logger.debug("Received unknown COTP TPDU before handshake: {0}".format(cotp_base_packet.tpdu_type)) session.add_event( {"error": "Received unknown COTP TPDU before handshake: {0}".format(cotp_base_packet.tpdu_type)} ) except socket.timeout: session.add_event({"type": "CONNECTION_LOST"}) logger.debug("Socket timeout, remote: {0}. ({1})".format(address[0], session.id))
def handle(self, sock, address): sock.settimeout(self.timeout) session = conpot_core.get_session('s7comm', address[0], address[1], sock.getsockname()[0], sock.getsockname()[1]) self.start_time = time.time() logger.info('New S7 connection from {0}:{1}. ({2})'.format( address[0], address[1], session.id)) session.add_event({'type': 'NEW_CONNECTION'}) try: while True: data = sock.recv(4, socket.MSG_WAITALL) if len(data) == 0: session.add_event({'type': 'CONNECTION_LOST'}) break _, _, length = unpack('!BBH', data[:4]) # check for length if length <= 4: logger.info('S7 error: Invalid length') session.add_event({'error': 'S7 error: Invalid length'}) break data += sock.recv(length - 4, socket.MSG_WAITALL) try: tpkt_packet = TPKT().parse(cleanse_byte_string(data)) cotp_base_packet = COTP_BASE_packet().parse( tpkt_packet.payload) except Exception as e: break if cotp_base_packet.tpdu_type == 0xe0: # connection request cotp_cr_request = COTP_ConnectionRequest().dissect( cotp_base_packet.payload) logger.info( 'Received COTP Connection Request: dst-ref:{0} src-ref:{1} dst-tsap:{2} src-tsap:{3} ' 'tpdu-size:{4}. ({5})'.format( cotp_cr_request.dst_ref, cotp_cr_request.src_ref, cotp_cr_request.dst_tsap, cotp_cr_request.src_tsap, cotp_cr_request.tpdu_size, session.id)) # confirm connection response cotp_cc_response = COTP_ConnectionConfirm( cotp_cr_request.src_ref, cotp_cr_request.dst_ref, 0, cotp_cr_request.src_tsap, cotp_cr_request.dst_tsap, 0x0a).assemble() # encapsulate and transmit cotp_resp_base_packet = COTP_BASE_packet( 0xd0, 0, cotp_cc_response).pack() tpkt_resp_packet = TPKT(3, cotp_resp_base_packet).pack() sock.send(tpkt_resp_packet) session.add_event({ 'request': codecs.encode(data, 'hex'), 'response': codecs.encode(tpkt_resp_packet, 'hex') }) data = sock.recv(1024) # another round of parsing payloads tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet().parse( tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xf0: logger.info( 'Received known COTP TPDU: {0}. ({1})'.format( cotp_base_packet.tpdu_type, session.id)) # will throw exception if the packet does not contain the S7 magic number (0x32) S7_packet = S7().parse(cotp_base_packet.trailer) logger.info( 'Received S7 packet: magic:%s pdu_type:%s reserved:%s req_id:%s param_len:%s ' 'data_len:%s result_inf:%s session_id:%s', S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id) # request pdu if S7_packet.pdu_type == 1: # 0xf0 == Request for connect / pdu negotiate if S7_packet.param == 0xf0: # create S7 response packet s7_resp_negotiate_packet = S7( 3, 0, S7_packet.request_id, 0, S7_packet.parameters).pack() # wrap s7 the packet in cotp cotp_resp_negotiate_packet = COTP_BASE_packet( 0xf0, 0x80, s7_resp_negotiate_packet).pack() # wrap the cotp packet tpkt_resp_packet = TPKT( 3, cotp_resp_negotiate_packet).pack() sock.send(tpkt_resp_packet) session.add_event({ 'request': codecs.encode(data, 'hex'), 'response': codecs.encode(tpkt_resp_packet, 'hex') }) # handshake done, give some more data. data = sock.recv(1024) while data: tpkt_packet = TPKT().parse(data) cotp_base_packet = COTP_BASE_packet( ).parse(tpkt_packet.payload) if cotp_base_packet.tpdu_type == 0xf0: S7_packet = S7().parse( cotp_base_packet.trailer) logger.info( 'Received S7 packet: magic:%s pdu_type:%s reserved:%s ' 'req_id:%s param_len:%s data_len:%s result_inf:%s session_id:%s', S7_packet.magic, S7_packet.pdu_type, S7_packet.reserved, S7_packet.request_id, S7_packet.param_length, S7_packet.data_length, S7_packet.result_info, session.id) response_param, response_data = S7_packet.handle( ) s7_resp_ssl_packet = S7( 7, 0, S7_packet.request_id, 0, response_param, response_data).pack() cotp_resp_ssl_packet = COTP_BASE_packet( 0xf0, 0x80, s7_resp_ssl_packet).pack() tpkt_resp_packet = TPKT( 3, cotp_resp_ssl_packet).pack() sock.send(tpkt_resp_packet) session.add_event({ 'request': codecs.encode(data, 'hex'), 'response': codecs.encode( tpkt_resp_packet, 'hex') }) data = sock.recv(1024) else: logger.info( 'Received unknown COTP TPDU after handshake: {0}'. format(cotp_base_packet.tpdu_type)) session.add_event({ 'error': 'Received unknown COTP TPDU after handshake: {0}'. format(cotp_base_packet.tpdu_type) }) else: logger.info( 'Received unknown COTP TPDU before handshake: {0}'. format(cotp_base_packet.tpdu_type)) session.add_event({ 'error': 'Received unknown COTP TPDU before handshake: {0}'. format(cotp_base_packet.tpdu_type) }) except socket.timeout: session.add_event({'type': 'CONNECTION_LOST'}) logger.debug('Socket timeout, remote: {0}. ({1})'.format( address[0], session.id)) except socket.error: session.add_event({'type': 'CONNECTION_LOST'}) logger.debug('Connection reset by peer, remote: {0}. ({1})'.format( address[0], session.id)) except Exception as e: logger.exception('Exception caught {0}, remote: {1}. ({2})'.format( e, address[0], session.id))