-- dissector for AIM/ICQ OFT protocol -- (2009) Franck GUENICHOT -- Mostly based on OFT Headers information from "On Sending Files via OSCAR" file by Jonathan Clark -- used for the Network Forensics Puzzle Contest by Jonathan Ham packetnum = -1 oft = Proto("oft","OFT", "Oscar File Transfer Protocol") -- Fields local f = oft.fields local types = { [0x0101] = "Prompt",[0x0202] = "Acknowledge",[0x0204] = "Done",[0x0205] = "Receiver Resume",[0x0106] = "Sender Resume",[0x0207] = "Resume Acknowledge"} local encryption = { [0] = "None"} local compression = { [0] = "None"} local encodings = { [0] = "ASCII", [2] = "UTF-16BE or UCS-2BE", [3] = "ISO-8859-1"} f.version = ProtoField.string("oft.version", "Version") f.length = ProtoField.uint16("oft.length", "Length") f.Type = ProtoField.uint16("oft.type","Type",base.HEX,types) f.cookie = ProtoField.bytes("oft.cookie","Cookie") f.encrypt = ProtoField.uint16("oft.encrypt","Encryption",nil,encryption) f.compress = ProtoField.uint16("oft.compress","Compression",nil,compression) f.totfil = ProtoField.uint16("oft.totfil", "Total File(s)") f.fillft = ProtoField.uint16("oft.fillft", "File(s) Left") f.totprts = ProtoField.uint16("oft.totprts","Total Parts") f.prtslft = ProtoField.uint16("oft.prtlft", "Parts Left") f.totsize = ProtoField.uint32("oft.totsize","Total Size") f.size = ProtoField.uint32("oft.size","Size") f.modtime = ProtoField.uint32("oft.modtime","Modification Time") f.checksum = ProtoField.uint32("oft.checksum","Checksum",base.HEX) f.rvcdrfk = ProtoField.uint32("oft.rvcdrfk","Received Resource Fork Checksum",base.HEX) f.rfsize = ProtoField.uint32("oft.rfsize","Ressource Fork") f.cretime = ProtoField.uint32("oft.cretime","Creation Time") f.rchksum = ProtoField.uint32("oft.rchksum", "Received Checksum",base.HEX) f.rfcsum = ProtoField.uint32("oft.rfcsum", "Resource Fork Checksum,base",base.HEX) f.nrecvd = ProtoField.uint32("oft.nrecvd","Bytes Received") f.idstring = ProtoField.string("oft.idstring","Identification String") f.flags = ProtoField.uint8("oft.flags","Flags",base.HEX) f.encoding = ProtoField.uint16("oft.encoding", "Encoding",base.HEX,encodings) f.encsubcode = ProtoField.uint16("oft.encsubcode","Encoding Subcode",base.HEX) f.db = ProtoField.bytes("oft.db","Dummy Block") f.lnameoff = ProtoField.uint8("oft.lnameoff","List Name Offset") f.lsizeoff = ProtoField.uint8("oft.lsizeoff","List Size Offset") f.macfileinfo = ProtoField.string("oft.macfileinfo","Mac File Information") f.data = ProtoField.bytes("oft.data","Data") f.filename = ProtoField.stringz("oft.filename","Filename") -- dissector function function oft.dissector(buffer,pinfo,tree) local subtree = tree:add (oft, buffer(), "Oscar File Transfer Protocol ("..buffer:len()..")") pinfo.cols.protocol = "OFT" local offset = 0 local version = buffer(offset,4) if not (version:string() == "OFT2") then pinfo.cols.info = "Raw Data" data = buffer(offset,buffer:len()) subtree:add(f.data, data) return end subtree:add(f.version,version) offset = offset + 4 local length = buffer(offset,2) subtree:add(f.length,length) offset = offset + 2 local Type = buffer(offset,2) subtree:add(f.Type,Type) offset = offset + 2 local cookie = buffer(offset,8) subtree:add(f.cookie,cookie) offset = offset + 8 local encrypt = buffer(offset,2) subtree:add(f.encrypt, encrypt) offset = offset + 2 local compress = buffer(offset,2) subtree:add(f.compress,compress) offset = offset + 2 local totfil = buffer(offset,2) subtree:add(f.totfil, totfil) offset = offset + 2 local fillft = buffer(offset,2) subtree:add(f.fillft,fillft) offset = offset + 2 local totprts = buffer(offset,2) subtree:add(f.totprts,totprts) offset = offset + 2 local prtslft = buffer(offset,2) subtree:add(f.prtslft,prtslft) offset = offset + 2 local totsize = buffer(offset,4) subtree:add(f.totsize,totsize) offset = offset + 4 local size = buffer(offset,4) subtree:add(f.size,size) offset = offset + 4 local modtime = buffer(offset,4) subtree:add(f.modtime,modtime) offset = offset + 4 local checksum = buffer(offset,4) subtree:add(f.checksum,checksum) offset = offset + 4 local rvcdrfk = buffer(offset,4) subtree:add(f.rvcdrfk,rvcdrfk) offset = offset + 4 local rfsize = buffer(offset,4) subtree:add(f.rfsize,rfsize) offset = offset + 4 local cretime = buffer(offset,4) subtree:add(f.cretime,cretime) offset = offset + 4 local rfcsum = buffer(offset,4) subtree:add(f.rfcsum,rfcsum) offset = offset + 4 local nrecvd = buffer(offset,4) subtree:add(f.nrecvd,nrecvd) offset = offset + 4 local rchksum = buffer(offset,4) subtree:add(f.rchksum,rchksum) offset = offset + 4 local idstring = buffer(offset,32) subtree:add(f.idstring,idstring) offset = offset + 32 local flags = buffer(offset,1) subtree:add(f.flags,flags) offset = offset + 1 local lnameoff = buffer(offset,1) subtree:add(f.lnameoff,lnameoff) offset = offset + 1 local lsizeoff = buffer(offset,1) subtree:add(f.lsizeoff,lsizeoff) offset = offset + 1 local db = buffer(offset,69) subtree:add(f.db,db) offset = offset + 69 local macfileinfo = buffer(offset,16) subtree:add(f.macfileinfo,macfileinfo) offset = offset + 16 local encoding = buffer(offset,2) subtree:add(f.encoding, encoding) offset = offset + 2 local encsubcode = buffer(offset,2) subtree:add(f.encsubcode,encsubcode) offset = offset + 2 local filename = buffer(offset,64) subtree:add(f.filename, filename) pinfo.cols.info = (version:string()) pinfo.cols.info:append (" Type: " .. types[Type:uint()]) end tcp_table = DissectorTable.get("tcp.port") tcp_table:add (5190, oft)