Skip to content

Commit af83983

Browse files
authored
Fix heap-buffer-overflow in TelnetLayer due to stale offset in getOption/getOptionData (#2144) (#2148)
1 parent 851322b commit af83983

6 files changed

Lines changed: 43 additions & 2 deletions

File tree

Packet++/src/TelnetLayer.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,10 @@ namespace pcpp
370370
pos = getNextCommandField(pos, m_DataLen - offset);
371371

372372
if (pos && pos[1] == static_cast<int>(command))
373+
{
374+
offset = pos - m_Data;
373375
return static_cast<TelnetOption>(getSubCommand(pos, getFieldLen(pos, m_DataLen - offset)));
376+
}
374377
}
375378

376379
PCPP_LOG_DEBUG("Can't find requested command");
@@ -417,8 +420,9 @@ namespace pcpp
417420

418421
if (pos && pos[1] == static_cast<int>(command))
419422
{
420-
size_t lenBuffer = getFieldLen(m_Data, m_DataLen);
421-
uint8_t* posBuffer = getCommandData(m_Data, lenBuffer);
423+
offset = pos - m_Data;
424+
size_t lenBuffer = getFieldLen(pos, m_DataLen - offset);
425+
uint8_t* posBuffer = getCommandData(pos, lenBuffer);
422426

423427
length = lenBuffer;
424428
return posBuffer;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
00112233445566778899aabb08004500002e1234400040060000c0a80a01c0a80a0200173039000000000000000050187fff00000000fffffffa1700
100 Bytes
Binary file not shown.

Tests/Packet++Test/TestDefinition.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ PTF_TEST_CASE(NtpCreationTests);
236236

237237
// Implemented in TelnetTests.cpp
238238
PTF_TEST_CASE(TelnetCommandParsingTests);
239+
PTF_TEST_CASE(TelentCommandInvalidDataTests);
239240
PTF_TEST_CASE(TelnetDataParsingTests);
240241

241242
// Implemented in IcmpV6Tests.cpp

Tests/Packet++Test/Tests/TelnetTests.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,40 @@ PTF_TEST_CASE(TelnetCommandParsingTests)
255255
}
256256
}
257257

258+
PTF_TEST_CASE(TelentCommandInvalidDataTests)
259+
{
260+
// Regression test for heap-buffer-overflow in getOption(TelnetCommand) / getOptionData(TelnetCommand, size_t&)
261+
// when user data (escaped IAC) precedes a command. The stale offset bug caused reads past the buffer end.
262+
// Payload: FF FF (escaped IAC = user data) + FF FA 17 00 (IAC SB SendLocation 0x00)
263+
auto rawPacket1 = createPacketFromHexResource("PacketExamples/telnetCommandAfterData.dat");
264+
265+
pcpp::Packet telnetPacket(rawPacket1.get());
266+
auto* telnetLayer = telnetPacket.getLayerOfType<pcpp::TelnetLayer>();
267+
268+
PTF_ASSERT_NOT_NULL(telnetLayer);
269+
270+
// Total commands: 1 (the subnegotiation)
271+
PTF_ASSERT_EQUAL(telnetLayer->getTotalNumberOfCommands(), 1);
272+
273+
// getFirstCommand should find the subnegotiation
274+
PTF_ASSERT_EQUAL(telnetLayer->getFirstCommand(), pcpp::TelnetLayer::TelnetCommand::Subnegotiation, enumclass);
275+
276+
// getOption(Subnegotiation) should return SendLocation without crashing
277+
PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::TelnetCommand::Subnegotiation),
278+
pcpp::TelnetLayer::TelnetOption::SendLocation, enumclass);
279+
280+
// getOptionData(Subnegotiation) should return the subneg data without crashing
281+
size_t length = 0;
282+
auto* optData = telnetLayer->getOptionData(pcpp::TelnetLayer::TelnetCommand::Subnegotiation, length);
283+
PTF_ASSERT_NOT_NULL(optData);
284+
PTF_ASSERT_EQUAL(length, 1);
285+
PTF_ASSERT_EQUAL(optData[0], 0x00);
286+
287+
// getOption for a command that doesn't exist should return NoOption without crashing
288+
PTF_ASSERT_EQUAL(telnetLayer->getOption(pcpp::TelnetLayer::TelnetCommand::WillPerform),
289+
pcpp::TelnetLayer::TelnetOption::TelnetOptionNoOption, enumclass);
290+
}
291+
258292
PTF_TEST_CASE(TelnetDataParsingTests)
259293
{
260294

Tests/Packet++Test/main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ int main(int argc, char* argv[])
325325
PTF_RUN_TEST(NtpCreationTests, "ntp");
326326

327327
PTF_RUN_TEST(TelnetCommandParsingTests, "telnet");
328+
PTF_RUN_TEST(TelentCommandInvalidDataTests, "telnet");
328329
PTF_RUN_TEST(TelnetDataParsingTests, "telnet");
329330

330331
PTF_RUN_TEST(TpktLayerTest, "tpkt");

0 commit comments

Comments
 (0)