adding yaml output

This commit is contained in:
AleaJactaEst 2019-11-06 21:36:42 +01:00
parent 63efd10dad
commit 02fd69dec5
2 changed files with 131 additions and 46 deletions

View file

@ -57,7 +57,7 @@ LOGGER = 'SpyKhanat'
#print(ip_packet) #print(ip_packet)
class SpyPcap(): class SpyPcap():
def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded): def __init__(self, khanat_host_service, pcap_file, msg_xml, filter_host_service, show_raw_packet, show_message_decoded, outyaml=None):
if khanat_host_service: if khanat_host_service:
self.khanat_host_service = re.compile(khanat_host_service) self.khanat_host_service = re.compile(khanat_host_service)
else: else:
@ -78,6 +78,7 @@ class SpyPcap():
msgRawXml = fp.read() msgRawXml = fp.read()
self.msgXml = ET.fromstring(msgRawXml) self.msgXml = ET.fromstring(msgRawXml)
self.decodeImpulse.loadMsg(self.msgXml) self.decodeImpulse.loadMsg(self.msgXml)
self.outyaml = outyaml
def readRaw(self): def readRaw(self):
file = open( self.pcap_file , 'rb') file = open( self.pcap_file , 'rb')
@ -145,7 +146,7 @@ class SpyPcap():
else: else:
max = hostdetected[host] max = hostdetected[host]
id = host id = host
logging.getLogger(LOGGER).info("khanat host :%s" % id) logging.getLogger(LOGGER).info(" host :%s" % id)
return id return id
def initialize_client(self, clientid): def initialize_client(self, clientid):
@ -212,7 +213,7 @@ class SpyPcap():
# def decode_client_receive_normal_message(self, msgin, clientid, dst): # def decode_client_receive_normal_message(self, msgin, clientid, dst):
# actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] ) # actions = self.client_state[clientid]['CImpulseDecoder'].decode(msgin, self.client_state[clientid]['CurrentReceivedNumber'], self.client_state[clientid]['LastReceivedAck'], self.client_state[clientid]['CurrentSendNumber'] )
# logging.getLogger(LOGGER).info("[Client -> Khanat] actions:%s" % str(actions)) # logging.getLogger(LOGGER).info("[Client -> Server] actions:%s" % str(actions))
# # decodeVisualProperties( msgin ); # # decodeVisualProperties( msgin );
def decode_client_send_normal_message(self, msgin, clientid, dst): def decode_client_send_normal_message(self, msgin, clientid, dst):
@ -228,24 +229,24 @@ class SpyPcap():
try: try:
cycle = msgin.readUint32("Cycle") cycle = msgin.readUint32("Cycle")
num = msgin.readUint8("num") num = msgin.readUint8("num")
logging.getLogger(LOGGER).debug("[Client -> Khanat] Cycle:%u num:%u" % (cycle, num)) logging.getLogger(LOGGER).debug("[Client -> Server] Cycle:%u num:%u" % (cycle, num))
for i in range(0, num): for i in range(0, num):
actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin)) actions.append(self.client_state[clientid]['CActionFactory'].unpack(msgin))
pass pass
except BitStream.OverflowError: except BitStream.OverflowError:
noerror = False noerror = False
except Exception as e: except Exception as e:
logging.getLogger(LOGGER).debug("[Client -> Khanat] end %s (not read:%u)" % (e.__class__, msgin.needRead())) logging.getLogger(LOGGER).debug("[Client -> Server] end %s (not read:%u)" % (e.__class__, msgin.needRead()))
raise e raise e
msgin.enable_LogErrorOnStreamOverflow() msgin.enable_LogErrorOnStreamOverflow()
logging.getLogger(LOGGER).debug("[Client -> Khanat] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions]))) logging.getLogger(LOGGER).debug("[Client -> Server] detail actions [%d] => %s" % ( len(actions), ', '.join([str(x) for x in actions])))
# decodeVisualProperties( msgin ); # decodeVisualProperties( msgin );
def decode_client_message(self, msgin, clientid, dst): def decode_client_message(self, msgin, clientid, dst, sequenceid):
CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber') CurrentReceivedNumber = msgin.readSint32('CurrentReceivedNumber')
SystemMode = msgin.readBool('SystemMode') SystemMode = msgin.readBool('SystemMode')
logging.getLogger(LOGGER).debug("[Client -> Khanat] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst)) logging.getLogger(LOGGER).debug("[Client -> Server] {CurrentReceivedNumber:%d, SystemMode:%d, src:%s, dst:%s}" % (CurrentReceivedNumber, SystemMode, clientid, dst))
self.initialize_client(clientid) self.initialize_client(clientid)
self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber self.client_state[clientid]['CurrentReceivedNumber'] = CurrentReceivedNumber
if not SystemMode: if not SystemMode:
@ -256,7 +257,7 @@ class SpyPcap():
self.client_state[clientid]['LastReceivedAck'] = LastReceivedAck self.client_state[clientid]['LastReceivedAck'] = LastReceivedAck
AckBitMask = msgin.readUint32('AckBitMask') AckBitMask = msgin.readUint32('AckBitMask')
self.client_state[clientid]['AckBitMask'] = AckBitMask self.client_state[clientid]['AckBitMask'] = AckBitMask
logging.getLogger(LOGGER).info("[Client -> Khanat] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck)) logging.getLogger(LOGGER).info("[Client -> Server] Normal Mode {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedAck:%d}" % (CurrentReceivedNumber, clientid, dst, LastReceivedAck))
#self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1) #self.decode_server(msgin, _CurrentReceivedNumber, _CurrentReceivedNumber-1)
self.decode_client_send_normal_message(msgin, clientid, dst) self.decode_client_send_normal_message(msgin, clientid, dst)
else: else:
@ -270,11 +271,11 @@ class SpyPcap():
UserKey = msgin.readUint32('UserKey') UserKey = msgin.readUint32('UserKey')
UserId = msgin.readUint32('UserId') UserId = msgin.readUint32('UserId')
LanguageCode = msgin.readString('LanguageCode') LanguageCode = msgin.readString('LanguageCode')
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" % logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, UserAddr:%d, UserId:%d, UserAddr:%d LanguageCode:%s}" %
(typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode)) (typeMessage, CurrentReceivedNumber, clientid, dst, UserAddr, UserKey, UserId, LanguageCode))
elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE:
LatestProbe = msgin.readSint32('LatestProbe') LatestProbe = msgin.readSint32('LatestProbe')
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s probe:%d {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage,
LatestProbe, CurrentReceivedNumber, clientid, dst)) LatestProbe, CurrentReceivedNumber, clientid, dst))
elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: elif message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE:
Synchronize = msgin.readUint32('Synchronize') Synchronize = msgin.readUint32('Synchronize')
@ -284,7 +285,7 @@ class SpyPcap():
md5Msg = bytes(MsgData) md5Msg = bytes(MsgData)
DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') DatabaseData = msgin.readArrayUint8(16, 'DatabaseData')
md5Database = bytes(DatabaseData) md5Database = bytes(DatabaseData)
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % ( logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (
typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode())) typeMessage, CurrentReceivedNumber, clientid, dst, Synchronize, stime, LatestSync, binascii.hexlify(md5Msg).decode(), binascii.hexlify(md5Database).decode()))
elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE: elif message == Enum.CLFECOMMON.SYSTEM_ACK_SYNC_CODE:
LastReceivedNumber = msgin.readSint32('LastReceivedNumber') LastReceivedNumber = msgin.readSint32('LastReceivedNumber')
@ -292,27 +293,27 @@ class SpyPcap():
LongAckBitField = CBitSet.CBitSet() LongAckBitField = CBitSet.CBitSet()
LongAckBitField.readSerial(msgin, 'LongAckBitField') LongAckBitField.readSerial(msgin, 'LongAckBitField')
LatestSync = msgin.readSint32('LatestSync') LatestSync = msgin.readSint32('LatestSync')
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % ( logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s {CurrentReceivedNumber:%d, src:%s, dst:%s, LastReceivedNumber:%d, LastAckInLongAck:%d, LatestSync:%d, LongAckBitField:%s}" % (
typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField)) typeMessage, CurrentReceivedNumber, clientid, dst, LastReceivedNumber, LastAckInLongAck, LatestSync, LongAckBitField))
elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_ACK_PROBE_CODE:
SizeLatestProbes = msgin.readSint32('SizeLatestProbes') SizeLatestProbes = msgin.readSint32('SizeLatestProbes')
LatestProbes = [] LatestProbes = []
for data in range(0, SizeLatestProbes): for data in range(0, SizeLatestProbes):
LatestProbes.append(msgin.readSint32('LatestProbes')) LatestProbes.append(msgin.readSint32('LatestProbes'))
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes))) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s, SizeLatestProbes:%d, LatestProbes:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst, SizeLatestProbes, str(LatestProbes)))
else: else:
logging.getLogger(LOGGER).info("[Client -> Khanat] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst)) logging.getLogger(LOGGER).info("[Client -> Server] System Mode:%s (%d) {CurrentReceivedNumber:%d, src:%s, dst:%s}" % (typeMessage, message, CurrentReceivedNumber, clientid, dst))
logging.getLogger(LOGGER).debug("[Client -> Khanat] msg:%s" % msgin.showAllData()) logging.getLogger(LOGGER).debug("[Client -> Server] msg:%s" % msgin.showAllData())
def decode_khanat_message(self, msgin, src, dst): def decode_khanat_message(self, msgin, src, dst, sequenceid):
CurrentSendNumber = msgin.readSint32('CurrentSendNumber') CurrentSendNumber = msgin.readSint32('CurrentSendNumber')
logging.getLogger(LOGGER).debug("[Khanat -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst)) logging.getLogger(LOGGER).debug("[Server -> Client] {CurrentSendNumber:%d, src:%s, dst:%s}" % (CurrentSendNumber, src, dst))
SystemMode = msgin.readBool('SystemMode') SystemMode = msgin.readBool('SystemMode')
self.initialize_client(dst) self.initialize_client(dst)
self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber self.client_state[dst]['CurrentSendNumber'] = CurrentSendNumber
if not SystemMode: if not SystemMode:
_LastReceivedAck = msgin.readSint32('LastReceivedAck'); _LastReceivedAck = msgin.readSint32('LastReceivedAck');
logging.getLogger(LOGGER).debug("[Khanat -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck)) logging.getLogger(LOGGER).debug("[Server -> Client] Normal Mode {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d}" % (CurrentSendNumber, src, dst, _LastReceivedAck))
actions = self.decode_server(dst, msgin, CurrentSendNumber, CurrentSendNumber-1) actions = self.decode_server(dst, msgin, CurrentSendNumber, CurrentSendNumber-1)
if actions: if actions:
logging.getLogger(LOGGER).debug('list actions: [' + str(len(actions)) + '] ' +','.join( [ str(x) for x in actions] ) ) logging.getLogger(LOGGER).debug('list actions: [' + str(len(actions)) + '] ' +','.join( [ str(x) for x in actions] ) )
@ -328,13 +329,13 @@ class SpyPcap():
logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE") logging.getLogger(LOGGER).info("Action : ACTION_DISCONNECTION_CODE")
elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE: elif action.Code == Enum.TActionCode.ACTION_GENERIC_CODE:
action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp'])
logging.getLogger(LOGGER).info("[Khanat -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action)) logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_CODE : {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, action:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, action))
elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE: elif action.Code == Enum.TActionCode.ACTION_GENERIC_MULTI_PART_CODE:
action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp']) action.genericAction(self.decodeImpulse, self.client_state[dst]['world'], self.client_state[dst]['GenericMultiPartTemp'])
logging.getLogger(LOGGER).debug("[Khanat -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action) logging.getLogger(LOGGER).debug("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE : %s" % action)
for id in self.client_state[dst]['GenericMultiPartTemp'].data: for id in self.client_state[dst]['GenericMultiPartTemp'].data:
if self.client_state[dst]['GenericMultiPartTemp'].data[id].isAvailable(): if self.client_state[dst]['GenericMultiPartTemp'].data[id].isAvailable():
logging.getLogger(LOGGER).info("[Khanat -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, id, self.client_state[dst]['GenericMultiPartTemp'].data[id].read().showAllData())) logging.getLogger(LOGGER).info("[Server -> Client] ACTION_GENERIC_MULTI_PART_CODE {CurrentSendNumber:%d, src:%s, dst:%s, _LastReceivedAck:%d, id:%d, msg:%s}" % (CurrentSendNumber, src, dst, _LastReceivedAck, id, self.client_state[dst]['GenericMultiPartTemp'].data[id].read().showAllData()))
elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE: elif action.Code == Enum.TActionCode.ACTION_DUMMY_CODE:
logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE") logging.getLogger(LOGGER).info("Action : ACTION_DUMMY_CODE")
self.add_registered_action(dst, action) self.add_registered_action(dst, action)
@ -344,34 +345,39 @@ class SpyPcap():
# self._Actions.pop(0) # self._Actions.pop(0)
else: else:
message = msgin.readUint8('message') message = msgin.readUint8('message')
logging.getLogger(LOGGER).debug("[Khanat -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).debug("[Server -> Client] System Mode {CurrentSendNumber:%d, src:%s, dst:%s, message:%d" % (CurrentSendNumber, src, dst, message))
if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE: if message == Enum.CLFECOMMON.SYSTEM_SYNC_CODE:
logging.getLogger(LOGGER).debug("[Khanat -> Client] Synchronize") logging.getLogger(LOGGER).debug("[Server -> Client] Synchronize")
Synchronize = msgin.readUint32('Synchronize') Synchronize = msgin.readUint32('Synchronize')
stime = msgin.readSint64('stime') stime = msgin.readSint64('stime')
LatestSync = msgin.readUint32('LatestSync') LatestSync = msgin.readUint32('LatestSync')
MsgData = msgin.readArrayUint8(16, 'MsgData') MsgData = msgin.readArrayUint8(16, 'MsgData')
DatabaseData = msgin.readArrayUint8(16, 'DatabaseData') DatabaseData = msgin.readArrayUint8(16, 'DatabaseData')
logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData))) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Synchronize {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, Synchronize:%d, stime:%d, LatestSync:%d, MsgData:%s, DatabaseData:%s}" % (CurrentSendNumber, src, dst, message, Synchronize, stime, LatestSync, str(MsgData), str(DatabaseData)))
elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE: elif message == Enum.CLFECOMMON.SYSTEM_STALLED_CODE:
logging.getLogger(LOGGER).debug("[Khanat -> Client] Stalled") logging.getLogger(LOGGER).debug("[Server -> Client] Stalled")
logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Stalled {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message))
elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE: elif message == Enum.CLFECOMMON.SYSTEM_PROBE_CODE:
logging.getLogger(LOGGER).debug("[Khanat -> Client] Probe") logging.getLogger(LOGGER).debug("[Server -> Client] Probe")
LatestProbe = msgin.readSint32('LatestProbe') LatestProbe = msgin.readSint32('LatestProbe')
logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / Probe {CurrentSendNumber:%d, src:%s, dst:%s, message:%d, LatestProbe:%d}" % (CurrentSendNumber, src, dst, message, LatestProbe))
elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE: elif message == Enum.CLFECOMMON.SYSTEM_SERVER_DOWN_CODE:
logging.getLogger(LOGGER).info("[Khanat -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message)) logging.getLogger(LOGGER).info("[Server -> Client] System Mode / BACK-END DOWN {CurrentSendNumber:%d, src:%s, dst:%s, message:%d}" % (CurrentSendNumber, src, dst, message))
else: else:
logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message) logging.getLogger(LOGGER).warning("CNET: received system %d in state Login" % message)
#cActionFactory = CAction.CActionFactory(None) #cActionFactory = CAction.CActionFactory(None)
#cActionFactory.unpack(msgin) #cActionFactory.unpack(msgin)
logging.getLogger(LOGGER).debug("[Khanat -> Client] msg:%s" % msgin.showAllData()) logging.getLogger(LOGGER).debug("[Server -> Client] msg:%s" % msgin.showAllData())
def read(self): def read(self):
file = open( self.pcap_file , 'rb') file = open( self.pcap_file , 'rb')
pcapfile = savefile.load_savefile(file,verbose=False) pcapfile = savefile.load_savefile(file,verbose=False)
khanat_host = self.detect_khanat_server(pcapfile.packets) khanat_host = self.detect_khanat_server(pcapfile.packets)
clientid = 1
serverid = 1
list_host = {}
sequenceid = 1
for pkt in pcapfile.packets: for pkt in pcapfile.packets:
eth_frame = ethernet.Ethernet(pkt.raw()) eth_frame = ethernet.Ethernet(pkt.raw())
if eth_frame.type == 2048: if eth_frame.type == 2048:
@ -396,18 +402,42 @@ class SpyPcap():
dst = "%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port) dst = "%s:%d" % (ip_packet.dst.decode(), udp_packet.dst_port)
if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src): if (self.khanat_host_service and self.khanat_host_service.match(src)) or ( not self.khanat_host_service and khanat_host == src):
_provenance = 'Khanat -> Client' _provenance = 'Server -> Client'
who = "Server"
if src not in list_host:
clientname = "Server %d" % serverid
list_host.setdefault(src, clientname)
serverid += 1
logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData()))
self.decode_khanat_message(msgin, src, dst) self.decode_khanat_message(msgin, src, dst, sequenceid)
else: else:
_provenance = 'Client -> Khanat' _provenance = 'Client -> Server'
if src not in list_host:
clientname = "Client %d" % clientid
list_host.setdefault(src, clientname)
clientid += 1
who = "Client"
logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData())) logging.getLogger(LOGGER).debug("[%s] (message received) [%s] %s" % (_provenance, datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"), msgin.showAllData()))
self.decode_client_message(msgin, src, dst) self.decode_client_message(msgin, src, dst, sequenceid)
if self.show_message_decoded: moredata='message decoded'
moredata='(message decoded)'
if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7: if not msgin.checkOnlyZeroAtEnd(): # msgin.needRead() > 7:
moredata = "(message decoded: not full)" moredata = "message partially decoded"
logging.getLogger(LOGGER).debug("[%s] %s %s" % (_provenance, moredata, msgin.showAllData())) if self.show_message_decoded:
logging.getLogger(LOGGER).debug("[%s] (%s) %s" % (_provenance, moredata, msgin.showAllData()))
if self.outyaml:
self.outyaml.write("\nmessage_%d:\n sequence: %d\n time: %s\n name: %s\n function: %s\n source: %s\n destination: %s\n state: %s\n message:\n" % (
sequenceid,
sequenceid,
datetime.fromtimestamp(pkt.timestamp).strftime("%Y/%m/%d %H:%M:%S"),
list_host[src],
who,
src,
dst,
moredata
))
for key in msgin.extractAllData():
self.outyaml.write(" - %s\n" % key)
sequenceid += 1
for client in self.client_state: for client in self.client_state:
logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber'])) logging.getLogger(LOGGER).debug("%s [server tick:%d, client tick:%d]" %(client, self.client_state[client]['CurrentSendNumber'], self.client_state[client]['CurrentReceivedNumber']))
@ -432,9 +462,11 @@ def main():
parser.add_argument("--khanat-host-service", help="filter to detect khanat host:service (FES)") parser.add_argument("--khanat-host-service", help="filter to detect khanat host:service (FES)")
parser.add_argument("--filter-host-service", help="filter host:service") parser.add_argument("--filter-host-service", help="filter host:service")
parser.add_argument("-d", "--debug", help="show debug message", action='store_true') parser.add_argument("-d", "--debug", help="show debug message", action='store_true')
parser.add_argument("-v", "--verbose", help="show verbose message", action='store_true')
parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True) parser.add_argument("-p", "--pcap-file", help="file pcap to read", required=True)
parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True) parser.add_argument("-m", "--msg-xml", help="file msg.xml (from server khanat)", required=True)
parser.add_argument("-r", "--raw", help="show message raw", action='store_true') parser.add_argument("-r", "--raw", help="show message raw", action='store_true')
parser.add_argument("--yaml", help="generate YAML file (decode all message)", type=argparse.FileType('w'), default=None)
parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true') parser.add_argument("--show-raw-packet", help="show packet (raw data)", action='store_true')
parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true') parser.add_argument("--show-message-decoded", help="show packet (raw data)", action='store_true')
@ -442,15 +474,23 @@ def main():
if args.debug: if args.debug:
level = logging.getLevelName('DEBUG') level = logging.getLevelName('DEBUG')
else: elif args.verbose:
level = logging.getLevelName('INFO') level = logging.getLevelName('INFO')
else:
level = logging.getLevelName('WARNING')
for logid in logger: for logid in logger:
logid.setLevel(level) logid.setLevel(level)
logging.getLogger(LOGGER).info("Begin") logging.getLogger(LOGGER).info("Begin")
spy = SpyPcap(khanat_host_service=args.khanat_host_service, pcap_file=args.pcap_file, msg_xml=args.msg_xml, filter_host_service=args.filter_host_service, spy = SpyPcap(khanat_host_service=args.khanat_host_service,
show_raw_packet=args.show_raw_packet, show_message_decoded=args.show_message_decoded) pcap_file=args.pcap_file,
msg_xml=args.msg_xml,
filter_host_service=args.filter_host_service,
show_raw_packet=args.show_raw_packet,
show_message_decoded=args.show_message_decoded,
outyaml=args.yaml)
if args.raw: if args.raw:
spy.readRaw() spy.readRaw()
else: else:

View file

@ -517,7 +517,7 @@ class BitStream():
self._groupWrite.append((p1, p2, name, 'BitStream', '')) self._groupWrite.append((p1, p2, name, 'BitStream', ''))
# ------------------------------------ # ------------------------------------
def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False): def readSerial(self, nbits, name="", decode=True, typeName='', emulate=False, signed=False):
v1 = self._read v1 = self._read
if nbits == 0: if nbits == 0:
return return
@ -543,6 +543,8 @@ class BitStream():
if emulate: if emulate:
self._read = oldRead self._read = oldRead
if decode and not emulate: if decode and not emulate:
if signed:
value = c_int32(value).value
self._groupRead.append((v1, v1+nbits, name, typeName, value)) self._groupRead.append((v1, v1+nbits, name, typeName, value))
return value return value
@ -560,7 +562,7 @@ class BitStream():
return v return v
def readSint32(self, name, decode=True): def readSint32(self, name, decode=True):
v = self.readSerial(32, name=name, decode=decode, typeName='Sint32') v = self.readSerial(32, name=name, decode=decode, typeName='Sint32', signed=True)
return c_int32(v).value return c_int32(v).value
def readUint16(self, name, decode=True): def readUint16(self, name, decode=True):
@ -568,7 +570,7 @@ class BitStream():
return v return v
def readSint16(self, name): def readSint16(self, name):
v = self.readSerial(16, name=name, typeName='Sint16') v = self.readSerial(16, name=name, typeName='Sint16', signed=True)
return c_int16(v).value return c_int16(v).value
def readUint8(self, name, decode=True, typeName='Uint8'): def readUint8(self, name, decode=True, typeName='Uint8'):
@ -576,7 +578,7 @@ class BitStream():
return v return v
def readSint8(self, name): def readSint8(self, name):
v = self.readSerial(8, name=name, typeName='Sint8') v = self.readSerial(8, name=name, typeName='Sint8', signed=True)
return c_int8(v).value return c_int8(v).value
def readUint64(self, name): def readUint64(self, name):
@ -865,6 +867,49 @@ class BitStream():
self._read = readBefore self._read = readBefore
return ret return ret
def extractAllData(self):
ret = ""
readBefore = self._read
self._read = 0
while self._read < self._pos:
if self._pos - self._read >= 8:
nsize = 8
else:
nsize = self._pos - self._read
data = self.readSerial(nsize, decode=False)
if nsize == 1:
ret += "{0:01b}".format(data)
elif nsize == 2:
ret += "{0:02b}".format(data)
elif nsize == 3:
ret += "{0:03b}".format(data)
elif nsize == 4:
ret += "{0:04b}".format(data)
elif nsize == 5:
ret += "{0:05b}".format(data)
elif nsize == 6:
ret += "{0:06b}".format(data)
elif nsize == 7:
ret += "{0:07b}".format(data)
else:
ret += "{0:08b}".format(data)
self._read = readBefore
ret2 = []
last = 0
for x, y, name, typeName, value in self._groupRead:
if not typeName:
nbbit = y - x
typeName = "%d bit" % nbbit
if nbbit > 1:
typeName += "s"
ret2.append("<" + str(x) + ':' + str(y-1) + "> " + '(' + typeName + ') ' + str(name) + ' => ' + str(value) + " : " + ret[x:y])
last = y
if last < self._pos:
ret2.append("<" + str(last) + ':' + str(self._pos - 1) + "> " + ret[last:])
return ret2
def checkOnlyZeroAtEnd(self): def checkOnlyZeroAtEnd(self):
readBefore = self._read readBefore = self._read
while self._read < self._pos: while self._read < self._pos: