1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
| local python = require 'python'
local rlpxBridge = python.import 'pydevp2p.bridge'
local NAME = "rlpx" local PORT = 30305 local rlpx = Proto(NAME, "Ethereum RLPx Protocol")
local fields = rlpx.fields fields.auth_size = ProtoField.uint16(NAME .. ".auth_size", "Auth Size") fields.ack_size = ProtoField.uint16(NAME .. ".ack_size", "Ack Size") fields.body = ProtoField.bytes(NAME .. ".body", "Data") fields.frame_header = ProtoField.bytes(NAME .. ".frame_header", "Frame Header") fields.frame_body = ProtoField.bytes(NAME .. ".frame_body", "Frame Body")
local known_ports = { 30303, 30304, 30305, 30306, 30307, 30308 }
local function table_has_value(tab, val) for _, value in ipairs(tab) do if value == val then return true end end
return false end
local function array_iterator(array, len) local index = 0 local count = len
return function() index = index + 1
if index <= count then return array[index] end
end end
function rlpx.dissector(tvb, pinfo, tree) local subtree = tree:add(rlpx, tvb()) local offset = 0
pinfo.cols.protocol = rlpx.name
local srcaddr = tostring(pinfo.src) local dstaddr = tostring(pinfo.dst)
local payload = tostring(tvb:bytes())
local auth_size = tvb(offset, 2) if (tvb:len() - auth_size:int() == 2) then if (table_has_value(known_ports, pinfo.src_port)) then offset = offset + 2 subtree:add(fields.ack_size, auth_size) pinfo.cols.info:set(pinfo.src_port .. " → " .. pinfo.dst_port .. " [HANDSHAKE] AUTH ACK") local dec_msg = rlpxBridge.handleRLPxHandshakeMsg(srcaddr, dstaddr, payload, pinfo.visited, pinfo.number) local payloadtree = subtree:add(fields.body, tvb(offset)) payloadtree:set_text("Handshake AUTH ACK") for element in array_iterator(dec_msg, dec_msg[0]) do payloadtree:add(element) end elseif (table_has_value(known_ports, pinfo.dst_port)) then offset = offset + 2 subtree:add(fields.auth_size, auth_size) pinfo.cols.info:set(pinfo.src_port .. " → " .. pinfo.dst_port .. " [HANDSHAKE] AUTH INIT") local dec_msg = rlpxBridge.handleRLPxHandshakeMsg(srcaddr, dstaddr, payload, pinfo.visited, pinfo.number) local payloadtree = subtree:add(fields.body, tvb(offset)) for element in array_iterator(dec_msg, dec_msg[0]) do payloadtree:add(element) end else subtree:add(fields.body, tvb(offset)) end else local dec_msg = rlpxBridge.handleRLPxMsg(srcaddr, dstaddr, payload, pinfo.visited, pinfo.number) local frame_header = dec_msg[0] local frame_body = dec_msg[1] local frame_type = dec_msg[2] if frame_type ~= nil then pinfo.cols.info:set(pinfo.src_port .. " → " .. pinfo.dst_port .. " " .. frame_type) end if frame_header ~= nil then local frame_header_tree = subtree:add(fields.frame_header, tvb(0, frame_header.headerSize)) frame_header_tree:add("Decrypted Header Data:", frame_header.header) frame_header_tree:add("Header MAC:", frame_header.headerMac) frame_header_tree:add("Frame Body MAC:", frame_header.frameMac) frame_header_tree:add("Frame Size:", frame_header.frameSize) frame_header_tree:add("Read Size:", frame_header.readSize) frame_header_tree:add("Header Data:", frame_header.headerData) pinfo.cols.info:append(" Len=" .. frame_header.readSize) end if frame_header ~= nil and frame_type ~= nil and frame_body ~= nil and frame_body[0] > 0 then local frame_body_tree = subtree:add(fields.frame_body, tvb(frame_header.headerSize)) for element in array_iterator(frame_body, frame_body[0]) do frame_body_tree:add(element) end end end end
DissectorTable.get("tcp.port"):add(PORT, rlpx) DissectorTable.get("tcp.port"):add("30303", rlpx) DissectorTable.get("tcp.port"):add("30304", rlpx) DissectorTable.get("tcp.port"):add("30305", rlpx) DissectorTable.get("tcp.port"):add("30306", rlpx) DissectorTable.get("tcp.port"):add("30307", rlpx) DissectorTable.get("tcp.port"):add("30308", rlpx)
|