Skip to content

Commit d46ad00

Browse files
authored
Implement packet number skipping for attack detection and improve security (#5146)
1 parent cc93053 commit d46ad00

File tree

9 files changed

+215
-0
lines changed

9 files changed

+215
-0
lines changed

src/core/loss_detection.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,6 +1329,22 @@ QuicLossDetectionProcessAckBlocks(
13291329
uint32_t i = 0;
13301330
QUIC_SUBRANGE* AckBlock;
13311331
while ((AckBlock = QuicRangeGetSafe(AckBlocks, i++)) != NULL) {
1332+
//
1333+
// ATTACK DETECTION: Check if the skipped packet number is in this ACK
1334+
// block. If so, this indicates a potential injection attack.
1335+
//
1336+
if (Connection->Send.SkippedPacketNumber >= AckBlock->Low &&
1337+
Connection->Send.SkippedPacketNumber <= QuicRangeGetHigh(AckBlock)) {
1338+
QuicTraceLogConnError(
1339+
AttackDetected,
1340+
Connection,
1341+
"Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]",
1342+
Connection->Send.SkippedPacketNumber,
1343+
AckBlock->Low,
1344+
QuicRangeGetHigh(AckBlock));
1345+
QuicConnTransportError(Connection, QUIC_ERROR_PROTOCOL_VIOLATION);
1346+
return;
1347+
}
13321348

13331349
//
13341350
// Check to see if any packets in the LostPackets list are acknowledged,

src/core/packet_builder.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,27 @@ QuicPacketBuilderPrepare(
379379
Builder->Metadata->PacketId,
380380
Builder->BatchId);
381381

382+
//
383+
// Occassionally skip a packet number for improved security.
384+
//
385+
if (Connection->Send.NextSkippedPacketNumber == Connection->Send.NextPacketNumber) {
386+
Connection->Send.SkippedPacketNumber =
387+
Connection->Send.NextPacketNumber++;
388+
QuicTraceLogConnWarning(
389+
SkipPacketNumber,
390+
Connection,
391+
"Skipped packet number %llu",
392+
Connection->Send.SkippedPacketNumber);
393+
394+
//
395+
// Randomly skip a packet number (from 0 to 65535).
396+
//
397+
uint16_t RandomSkip = 0;
398+
CxPlatRandom(sizeof(RandomSkip), &RandomSkip);
399+
Connection->Send.NextSkippedPacketNumber =
400+
Connection->Send.NextPacketNumber + RandomSkip;
401+
}
402+
382403
Builder->Metadata->FrameCount = 0;
383404
Builder->Metadata->PacketNumber = Connection->Send.NextPacketNumber++;
384405
Builder->Metadata->Flags.KeyType = NewPacketKeyType;

src/core/send.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,21 @@ QuicSendInitialize(
3434
{
3535
CxPlatListInitializeHead(&Send->SendStreams);
3636
Send->MaxData = Settings->ConnFlowControlWindow;
37+
Send->SkippedPacketNumber = UINT64_MAX;
38+
39+
//
40+
// Randomize initial packet number between 0 and 256 for improved security.
41+
// This makes it harder for attackers to predict packet numbers.
42+
//
43+
uint8_t RandomValue = 0;
44+
CxPlatRandom(sizeof(RandomValue), &RandomValue);
45+
Send->NextPacketNumber = RandomValue;
46+
47+
//
48+
// Randomly skip a packet number (from 0 to 256).
49+
//
50+
CxPlatRandom(sizeof(RandomValue), &RandomValue);
51+
Send->NextSkippedPacketNumber = Send->NextPacketNumber + RandomValue;
3752
}
3853

3954
_IRQL_requires_max_(PASSIVE_LEVEL)

src/core/send.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,17 @@ typedef struct QUIC_SEND {
267267
//
268268
uint64_t NextPacketNumber;
269269

270+
//
271+
// The current skipped packet number for attack detection. If this is
272+
// acknowledged, it indicates an attack.
273+
//
274+
uint64_t SkippedPacketNumber;
275+
276+
//
277+
// The next packet number we will skip for attack detection.
278+
//
279+
uint64_t NextSkippedPacketNumber;
280+
270281
//
271282
// Last time send flush occurred. Used for pacing calculations.
272283
//

src/generated/linux/loss_detection.c.clog.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
#define _clog_MACRO_QuicTraceLogVerbose 1
1919
#define QuicTraceLogVerbose(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
2020
#endif
21+
#ifndef _clog_MACRO_QuicTraceLogConnError
22+
#define _clog_MACRO_QuicTraceLogConnError 1
23+
#define QuicTraceLogConnError(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
24+
#endif
2125
#ifndef _clog_MACRO_QuicTraceLogConnInfo
2226
#define _clog_MACRO_QuicTraceLogConnInfo 1
2327
#define QuicTraceLogConnInfo(a, ...) _clog_CAT(_clog_ARGN_SELECTOR(__VA_ARGS__), _clog_CAT(_,a(#a, __VA_ARGS__)))
@@ -241,6 +245,30 @@ tracepoint(CLOG_LOSS_DETECTION_C, PacketTxProbeRetransmit , arg2, arg3);\
241245

242246

243247

248+
/*----------------------------------------------------------
249+
// Decoder Ring for AttackDetected
250+
// [conn][%p] Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]
251+
// QuicTraceLogConnError(
252+
AttackDetected,
253+
Connection,
254+
"Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]",
255+
Connection->Send.SkippedPacketNumber,
256+
AckBlock->Low,
257+
QuicRangeGetHigh(AckBlock));
258+
// arg1 = arg1 = Connection = arg1
259+
// arg3 = arg3 = Connection->Send.SkippedPacketNumber = arg3
260+
// arg4 = arg4 = AckBlock->Low = arg4
261+
// arg5 = arg5 = QuicRangeGetHigh(AckBlock) = arg5
262+
----------------------------------------------------------*/
263+
#ifndef _clog_6_ARGS_TRACE_AttackDetected
264+
#define _clog_6_ARGS_TRACE_AttackDetected(uniqueId, arg1, encoded_arg_string, arg3, arg4, arg5)\
265+
tracepoint(CLOG_LOSS_DETECTION_C, AttackDetected , arg1, arg3, arg4, arg5);\
266+
267+
#endif
268+
269+
270+
271+
244272
/*----------------------------------------------------------
245273
// Decoder Ring for HandshakeConfirmedAck
246274
// [conn][%p] Handshake confirmed (ack)

src/generated/linux/loss_detection.c.clog.h.lttng.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,37 @@ TRACEPOINT_EVENT(CLOG_LOSS_DETECTION_C, PacketTxProbeRetransmit,
247247

248248

249249

250+
/*----------------------------------------------------------
251+
// Decoder Ring for AttackDetected
252+
// [conn][%p] Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]
253+
// QuicTraceLogConnError(
254+
AttackDetected,
255+
Connection,
256+
"Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]",
257+
Connection->Send.SkippedPacketNumber,
258+
AckBlock->Low,
259+
QuicRangeGetHigh(AckBlock));
260+
// arg1 = arg1 = Connection = arg1
261+
// arg3 = arg3 = Connection->Send.SkippedPacketNumber = arg3
262+
// arg4 = arg4 = AckBlock->Low = arg4
263+
// arg5 = arg5 = QuicRangeGetHigh(AckBlock) = arg5
264+
----------------------------------------------------------*/
265+
TRACEPOINT_EVENT(CLOG_LOSS_DETECTION_C, AttackDetected,
266+
TP_ARGS(
267+
const void *, arg1,
268+
unsigned long long, arg3,
269+
unsigned long long, arg4,
270+
unsigned long long, arg5),
271+
TP_FIELDS(
272+
ctf_integer_hex(uint64_t, arg1, (uint64_t)arg1)
273+
ctf_integer(uint64_t, arg3, arg3)
274+
ctf_integer(uint64_t, arg4, arg4)
275+
ctf_integer(uint64_t, arg5, arg5)
276+
)
277+
)
278+
279+
280+
250281
/*----------------------------------------------------------
251282
// Decoder Ring for HandshakeConfirmedAck
252283
// [conn][%p] Handshake confirmed (ack)

src/generated/linux/packet_builder.c.clog.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,26 @@ tracepoint(CLOG_PACKET_BUILDER_C, NoSrcCidAvailable , arg1);\
4747

4848

4949

50+
/*----------------------------------------------------------
51+
// Decoder Ring for SkipPacketNumber
52+
// [conn][%p] Skipped packet number %llu
53+
// QuicTraceLogConnWarning(
54+
SkipPacketNumber,
55+
Connection,
56+
"Skipped packet number %llu",
57+
Connection->Send.SkippedPacketNumber);
58+
// arg1 = arg1 = Connection = arg1
59+
// arg3 = arg3 = Connection->Send.SkippedPacketNumber = arg3
60+
----------------------------------------------------------*/
61+
#ifndef _clog_4_ARGS_TRACE_SkipPacketNumber
62+
#define _clog_4_ARGS_TRACE_SkipPacketNumber(uniqueId, arg1, encoded_arg_string, arg3)\
63+
tracepoint(CLOG_PACKET_BUILDER_C, SkipPacketNumber , arg1, arg3);\
64+
65+
#endif
66+
67+
68+
69+
5070
/*----------------------------------------------------------
5171
// Decoder Ring for GetPacketTypeFailure
5272
// [conn][%p] Failed to get packet type for control frames, 0x%x

src/generated/linux/packet_builder.c.clog.h.lttng.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@ TRACEPOINT_EVENT(CLOG_PACKET_BUILDER_C, NoSrcCidAvailable,
2020

2121

2222

23+
/*----------------------------------------------------------
24+
// Decoder Ring for SkipPacketNumber
25+
// [conn][%p] Skipped packet number %llu
26+
// QuicTraceLogConnWarning(
27+
SkipPacketNumber,
28+
Connection,
29+
"Skipped packet number %llu",
30+
Connection->Send.SkippedPacketNumber);
31+
// arg1 = arg1 = Connection = arg1
32+
// arg3 = arg3 = Connection->Send.SkippedPacketNumber = arg3
33+
----------------------------------------------------------*/
34+
TRACEPOINT_EVENT(CLOG_PACKET_BUILDER_C, SkipPacketNumber,
35+
TP_ARGS(
36+
const void *, arg1,
37+
unsigned long long, arg3),
38+
TP_FIELDS(
39+
ctf_integer_hex(uint64_t, arg1, (uint64_t)arg1)
40+
ctf_integer(uint64_t, arg3, arg3)
41+
)
42+
)
43+
44+
45+
2346
/*----------------------------------------------------------
2447
// Decoder Ring for GetPacketTypeFailure
2548
// [conn][%p] Failed to get packet type for control frames, 0x%x

src/manifest/clog.sidecar

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,30 @@
219219
],
220220
"macroName": "QuicTraceLogConnInfo"
221221
},
222+
"AttackDetected": {
223+
"ModuleProperites": {},
224+
"TraceString": "[conn][%p] Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]",
225+
"UniqueId": "AttackDetected",
226+
"splitArgs": [
227+
{
228+
"DefinationEncoding": "p",
229+
"MacroVariableName": "arg1"
230+
},
231+
{
232+
"DefinationEncoding": "llu",
233+
"MacroVariableName": "arg3"
234+
},
235+
{
236+
"DefinationEncoding": "llu",
237+
"MacroVariableName": "arg4"
238+
},
239+
{
240+
"DefinationEncoding": "llu",
241+
"MacroVariableName": "arg5"
242+
}
243+
],
244+
"macroName": "QuicTraceLogConnError"
245+
},
222246
"BindingCleanup": {
223247
"ModuleProperites": {},
224248
"TraceString": "[bind][%p] Cleaning up",
@@ -11525,6 +11549,22 @@
1152511549
],
1152611550
"macroName": "QuicTraceLogStreamWarning"
1152711551
},
11552+
"SkipPacketNumber": {
11553+
"ModuleProperites": {},
11554+
"TraceString": "[conn][%p] Skipped packet number %llu",
11555+
"UniqueId": "SkipPacketNumber",
11556+
"splitArgs": [
11557+
{
11558+
"DefinationEncoding": "p",
11559+
"MacroVariableName": "arg1"
11560+
},
11561+
{
11562+
"DefinationEncoding": "llu",
11563+
"MacroVariableName": "arg3"
11564+
}
11565+
],
11566+
"macroName": "QuicTraceLogConnWarning"
11567+
},
1152811568
"SockCreateFail": {
1152911569
"ModuleProperites": {},
1153011570
"TraceString": "[sock] Failed to create socket, status:%d",
@@ -14030,6 +14070,11 @@
1403014070
"TraceID": "ApplySettings",
1403114071
"EncodingString": "[conn][%p] Applying new settings"
1403214072
},
14073+
{
14074+
"UniquenessHash": "2577283e-0a65-186c-be40-d33b66b0062d",
14075+
"TraceID": "AttackDetected",
14076+
"EncodingString": "[conn][%p] Attack detected: Skipped packet number %llu ACKed in range [%llu, %llu]"
14077+
},
1403314078
{
1403414079
"UniquenessHash": "5d83e63e-7ce5-0102-8dd2-cbcf5946da2e",
1403514080
"TraceID": "BindingCleanup",
@@ -17500,6 +17545,11 @@
1750017545
"TraceID": "ShutdownImmediatePendingReliableReset",
1750117546
"EncodingString": "[strm][%p] Invalid immediate shutdown request (pending reliable reset)."
1750217547
},
17548+
{
17549+
"UniquenessHash": "2656ff28-78a8-28d2-b18f-0aa4ec664a0d",
17550+
"TraceID": "SkipPacketNumber",
17551+
"EncodingString": "[conn][%p] Skipped packet number %llu"
17552+
},
1750317553
{
1750417554
"UniquenessHash": "7b00c1b9-3578-872f-c41f-75bb4f92de18",
1750517555
"TraceID": "SockCreateFail",

0 commit comments

Comments
 (0)