From 5eb380d74addd169fd68c5015b663ede436dab66 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 19 Jan 2024 19:26:42 +0100 Subject: [PATCH] websocket: Fix crash for fragmented messages The &transient attribute does not work well with $element as that won't be available within &until anymore apparently. Found after a few seconds building out the fuzzer. --- .../protocol/websocket/websocket-protocol.pac | 2 +- .../out | 37 ++++++++++++++++++ .../websocket/message-too-big-status.pcap | Bin 0 -> 1684 bytes .../websocket/two-binary-fragments.pcap | Bin 0 -> 2026 bytes .../base/protocols/websocket/events.zeek | 4 ++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Traces/websocket/message-too-big-status.pcap create mode 100644 testing/btest/Traces/websocket/two-binary-fragments.pcap diff --git a/src/analyzer/protocol/websocket/websocket-protocol.pac b/src/analyzer/protocol/websocket/websocket-protocol.pac index 01ab76ff9e..93cd4eb94a 100644 --- a/src/analyzer/protocol/websocket/websocket-protocol.pac +++ b/src/analyzer/protocol/websocket/websocket-protocol.pac @@ -80,7 +80,7 @@ type WebSocket_Message = record { first_frame: WebSocket_Frame(true, this); optional_more_frames: case first_frame.hdr.b.fin of { true -> no_more_frames: empty; - false -> more_frames: WebSocket_Frame(false, this)[] &until($element.hdr.b.fin) &transient; + false -> more_frames: WebSocket_Frame(false, this)[] &until($element.hdr.b.fin); }; } &let { opcode = first_frame.hdr.b.opcode; diff --git a/testing/btest/Baseline/scripts.base.protocols.websocket.events/out b/testing/btest/Baseline/scripts.base.protocols.websocket.events/out index 4bbd3de1cb..41bb69dcbe 100644 --- a/testing/btest/Baseline/scripts.base.protocols.websocket.events/out +++ b/testing/btest/Baseline/scripts.base.protocols.websocket.events/out @@ -89,3 +89,40 @@ websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_le websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason, websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8 websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close +message-too-big-status.pcap +websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=60956/tcp, resp_h=127.0.0.1, resp_p=8080/tcp], host=localhost:8080, uri=/, user_agent=Python/3.10 websockets/12.0, subprotocol=v1, client_protocols=[v1], server_extensions=, client_extensions=[permessage-deflate; client_max_window_bits], client_key=iTel1Ova5Nhz/G7VlI2qKg==, server_accept=YsQYYLj7ZCpzTLsVLb+w/ydy79E=] +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4 +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek +websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, ping +websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 31 +websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1009, reason, over size limit (4 > 2 bytes) +websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 31, data, \x03\xf1over size limit (4 > 2 bytes) +websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2 +websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason, +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8 +websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close +two-binary-fragments.pcap +websocket_established, CHhAvVGS1DHFjwGM9, 7, [ts=XXXXXXXXXX.XXXXXX, uid=CHhAvVGS1DHFjwGM9, id=[orig_h=127.0.0.1, orig_p=50198/tcp, resp_h=127.0.0.1, resp_p=8080/tcp], host=localhost:8080, uri=/, user_agent=Python/3.10 websockets/12.0, subprotocol=v1, client_protocols=[v1], server_extensions=, client_extensions=[permessage-deflate; client_max_window_bits], client_key=cQGA5Z1nvyUJ9XOVIaLaQA==, server_accept=zWaHVUKxEGPDs+xJeKtzkE1bm54=] +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, ping, payload_len, 4 +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 4, data, Zeek +websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, ping +websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, pong, payload_len, 4 +websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 4, data, Zeek +websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, pong +websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, binary, payload_len, 11 +websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 11, data, Hello Zeek! +websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, binary +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, F, rsv, 0, opcode, binary, payload_len, 5 +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 5, data, Hello +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, continuation, payload_len, 7 +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 7, data, there! +websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, binary +websocket_frame, CHhAvVGS1DHFjwGM9, T, fin, T, rsv, 0, opcode, close, payload_len, 2 +websocket_close, CHhAvVGS1DHFjwGM9, T, status, 1000, reason, +websocket_frame_data, CHhAvVGS1DHFjwGM9, T, len, 2, data, \x03\xe8 +websocket_message, CHhAvVGS1DHFjwGM9, T, opcode, close +websocket_frame, CHhAvVGS1DHFjwGM9, F, fin, T, rsv, 0, opcode, close, payload_len, 2 +websocket_close, CHhAvVGS1DHFjwGM9, F, status, 1000, reason, +websocket_frame_data, CHhAvVGS1DHFjwGM9, F, len, 2, data, \x03\xe8 +websocket_message, CHhAvVGS1DHFjwGM9, F, opcode, close diff --git a/testing/btest/Traces/websocket/message-too-big-status.pcap b/testing/btest/Traces/websocket/message-too-big-status.pcap new file mode 100644 index 0000000000000000000000000000000000000000..7f51e3f583fbfddd98f314b42d0046f12086e021 GIT binary patch literal 1684 zcmaKrOH30%7{_;)R+=VFM5C#Mgf&th(b5OSwp&1yR6vMgC}07D?RIDjWw&-0N(qGe ziVzkbDMKLMacd*+$v0=KB&kt$7^MhmyO=jmz(#Mlz)rQIXbLdNt7rEkP*{L?ka! zrHJSZ??}{>8&PHqkX6PlL%)Y|&|JctK?72+#T=A@u1mJIp$5Q#2U!1pq_G zfnVU+ZXoKkRXoQ5Rt)nTL#Nku+D5<{TY$e2?=jYa1Ve{CAY!@D=PNxQ8ZcGcn zt98Nh^32W6ASPg#r6hC7-7f+TEeZ@B1+g9=2)-aN20&-TCjuAEM#6v-J9>Qm9q}+1 z;NuscTg-nu6igOtG3;HZMXuk2 zuK$0IwqfMDrb==>eM5#s*RdHm$IbR>rR#{e3W=+5fGFjGZ^pbWiHNz6cO>e`&6c0r z#2~sE(gbOX*+MtQ!y+3Bb3t0_8JfY$=GB{;r%s#xPz+XpGu)oD(Z{kN3O(`)7roy4 zE_-WLbih+DG}rr&$4!Yq!tQj#Q7X?w6;7uN{F2o`>Lh*$ccpey58>F%9Ji7W4P0;6 zDB2Ao1HVCH4Rj8rJg|X`?HV45OCqL5vXYNS0u9_-s3eZ6S^?-r-0#_y+Og6*5?7{_ z#!4wA7ZJw~sEHtyh*BO{sh4tKBG{3rC)XdfDv2YLuX5EbuQ$35F7_IV7KX0G=ebbD z+apGH!f5~#VDQkQcmkDu0?VF-^-#(Kmvz{#V}r`1vT1{8XwXs;8ub2CMp-K7E22Jw z)GROI2Bx0MpcY|j9=X}}K}khKRem-i<;3=kO2o9`OYmwKl6mBM+sA*2x~xRoO{}p( SBBnbxK#j}jwYJSGiGKiM8Lou@ literal 0 HcmV?d00001 diff --git a/testing/btest/Traces/websocket/two-binary-fragments.pcap b/testing/btest/Traces/websocket/two-binary-fragments.pcap new file mode 100644 index 0000000000000000000000000000000000000000..043c46e61ff6a04f04d5a0529b0ca74a5cb51c56 GIT binary patch literal 2026 zcmaKtPi)&%9LJyCjz&gdY=S8Vrg;p3CX}XTn^ep;t+1@28Ctvkag_>Hj{BNMP3#bx zwH*SYK}BF3c0gzt)@~JtLUWp?9wwn3m^5)11!)pDDh&|ZfdOhdq(!CtelKxnn>0V^ zCpoeGdEfW_zW03V+sl`D(oCFMUnhivAE|G?rnlY_NEcjVyDLDVgd9{dN63*!etYd* zcmezRj$P-`QP+6RyNz>5AsTCAnF?5}3R@%^Iv35Tw^inOX&}1)rCLE_zvZ(cR zb{t4Z`l+e@t``SS47{oyS9>}R9r8asK=USpN&Eb_qLUWY@un$@IhxN>(^OM5JVHk^ zszqNCwM?4o)^Jvx9G*z)BgVvVGHscDN_XC{49&>M;whMDze)4qjugBni``S!n4w4Z zwMuOdXJ|&G7g}NNK>=M~1J^gt(LRr^&+TMr9AwX<* zv6b>-2b3N@fr2hbX=8o72 zGu`S&m?_OpZ{@+j)uFg|x@h2SAjZHsY~@INNVf7U5-@Ok(o6iXIYH?- za({2EG{=D_F)TbDA8&^sE>Csz8 w2hNuo5fzI$;QLz6EP(?%3){HWMEU>3FB=l=S*G!6pT?b_@dsQ7iF;n+e_Aa|%m4rY literal 0 HcmV?d00001 diff --git a/testing/btest/scripts/base/protocols/websocket/events.zeek b/testing/btest/scripts/base/protocols/websocket/events.zeek index 2b6eae6cde..5c4c1fd2cf 100644 --- a/testing/btest/scripts/base/protocols/websocket/events.zeek +++ b/testing/btest/scripts/base/protocols/websocket/events.zeek @@ -6,6 +6,10 @@ # @TEST-EXEC: zeek -b -r $TRACES/websocket/wstunnel-http.pcap %INPUT >>out # @TEST-EXEC: echo "broker-websocket.pcap" >>out # @TEST-EXEC: zeek -b -r $TRACES//websocket/broker-websocket.pcap %INPUT >>out +# @TEST-EXEC: echo "message-too-big-status.pcap" >>out +# @TEST-EXEC: zeek -b -r $TRACES//websocket/message-too-big-status.pcap %INPUT >>out +# @TEST-EXEC: echo "two-binary-fragments.pcap" >>out +# @TEST-EXEC: zeek -b -r $TRACES//websocket/two-binary-fragments.pcap %INPUT >>out # @TEST-EXEC: btest-diff out # @TEST-EXEC: test ! -f analyzer.log # @TEST-EXEC: test ! -f weird.log