-
Notifications
You must be signed in to change notification settings - Fork 679
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
813f15b
commit 6a67cab
Showing
10 changed files
with
751 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,22 @@ | ||
add_executable(FuzzTarget FuzzTarget.cpp) | ||
|
||
target_link_libraries(FuzzTarget PRIVATE Pcap++ -fsanitize=fuzzer) | ||
target_compile_definitions(FuzzTarget PUBLIC FILE_EXT=".pcap") | ||
target_include_directories(FuzzTarget PRIVATE $<TARGET_PROPERTY:EndianPortable,INTERFACE_INCLUDE_DIRECTORIES>) | ||
|
||
add_executable(FuzzTargetNg FuzzTarget.cpp) | ||
target_link_libraries(FuzzTargetNg PRIVATE Pcap++ -fsanitize=fuzzer) | ||
target_compile_definitions(FuzzTargetNg PUBLIC FILE_EXT=".pcapng") | ||
target_include_directories(FuzzTargetNg PRIVATE $<TARGET_PROPERTY:EndianPortable,INTERFACE_INCLUDE_DIRECTORIES>) | ||
|
||
add_executable(FuzzTargetSnoop FuzzTarget.cpp) | ||
target_link_libraries(FuzzTargetSnoop PRIVATE Pcap++ -fsanitize=fuzzer) | ||
target_compile_definitions(FuzzTargetSnoop PUBLIC FILE_EXT=".snoop") | ||
target_include_directories(FuzzTargetSnoop PRIVATE $<TARGET_PROPERTY:EndianPortable,INTERFACE_INCLUDE_DIRECTORIES>) | ||
|
||
add_executable(FuzzWriter FuzzWriter.cpp) | ||
target_link_libraries(FuzzWriter PRIVATE Pcap++ -fsanitize=fuzzer) | ||
target_compile_definitions(FuzzWriter PUBLIC FILE_EXT=".pcap" NG_WRITER) | ||
|
||
add_executable(FuzzWriterNg FuzzWriter.cpp) | ||
target_link_libraries(FuzzWriterNg PRIVATE Pcap++ -fsanitize=fuzzer) | ||
target_compile_definitions(FuzzWriterNg PUBLIC FILE_EXT=".pcapng") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
#ifndef DUMP_TO_FILE_H | ||
#define DUMP_TO_FILE_H | ||
|
||
#include <iostream> | ||
|
||
// This function is created as PcapPlusPlus doesn't seem to offer a way of | ||
// parsing Pcap files directly from memory | ||
static int dumpDataToPcapFile(const uint8_t *data, size_t size, const char* path) | ||
{ | ||
FILE *fd; | ||
int written = 0; | ||
|
||
fd = fopen(path, "wb"); | ||
if (fd == NULL) | ||
{ | ||
std::cerr << "Error opening pcap file for writing\n"; | ||
return -1; | ||
} | ||
|
||
written = fwrite(data, 1, size, fd); | ||
if (static_cast<size_t>(written) != size) | ||
{ | ||
std::cerr << "Error writing pcap file\n"; | ||
fclose(fd); | ||
return -1; | ||
} | ||
|
||
fclose(fd); | ||
return 0; | ||
} | ||
|
||
#endif // DUMP_TO_FILE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,76 @@ | ||
#include <iostream> | ||
|
||
#include <IPv4Layer.h> | ||
#include <Packet.h> | ||
#include <PcapFileDevice.h> | ||
#include <Packet.h> | ||
#include <Logger.h> | ||
#include "DumpToFile.h" | ||
#include "ReadParsedPacket.h" | ||
|
||
#include "Logger.h" | ||
|
||
#define TMP_FILEPATH "/tmp/fuzz_sample.pcap" | ||
static std::string tmpName; | ||
static std::string tmpFile; | ||
|
||
// This function is created as PcapPlusPlus doesn't seem to offer a way of | ||
// parsing Pcap files directly from memory | ||
int dumpDataToPcapFile(const uint8_t *data, size_t size) | ||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | ||
{ | ||
FILE *fd; | ||
int written = 0; | ||
if (tmpName.empty()) | ||
tmpName = tmpnam (NULL); | ||
|
||
fd = fopen(TMP_FILEPATH, "wb"); | ||
if (fd == NULL) | ||
{ | ||
std::cerr << "Error opening pcap file for writing\n"; | ||
return -1; | ||
} | ||
if (tmpFile.empty()) | ||
tmpFile = tmpName + FILE_EXT; | ||
|
||
written = fwrite(data, 1, size, fd); | ||
if (static_cast<size_t>(written) != size) | ||
if (dumpDataToPcapFile(data, size, tmpFile.c_str()) != 0) | ||
{ | ||
std::cerr << "Error writing pcap file\n"; | ||
fclose(fd); | ||
std::cerr << "Can't Dump buffer to the '" << tmpFile << "' file!!!!\n"; | ||
return -1; | ||
} | ||
|
||
fclose(fd); | ||
|
||
return 0; | ||
} | ||
pcpp::Logger::getInstance().suppressLogs(); | ||
|
||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) | ||
{ | ||
if (dumpDataToPcapFile(Data, Size) < 0) | ||
std::unique_ptr<pcpp::IFileReaderDevice> reader(pcpp::IFileReaderDevice::getReader(tmpFile)); | ||
if (!reader->open()) | ||
{ | ||
std::cerr << "Can't Dump buffer to a PCAP file!!!!\n"; | ||
return 0; | ||
std::cerr << "Error opening the '" << tmpFile << "' file\n"; | ||
return -1; | ||
} | ||
|
||
// Disable logs | ||
pcpp::Logger::getInstance().suppressLogs(); | ||
pcpp::IPcapDevice::PcapStats stats; | ||
reader->getStatistics(stats); | ||
std::cout << "Read " << stats.packetsRecv << " packets successfully and " | ||
<< stats.packetsDrop << " packets could not be read" << std::endl; | ||
|
||
// open a pcap file for reading | ||
pcpp::PcapFileReaderDevice reader(TMP_FILEPATH); | ||
if (!reader.open()) | ||
if (auto ngReader = dynamic_cast<pcpp::PcapNgFileReaderDevice*>(reader.get())) | ||
{ | ||
std::cerr << "Error opening the pcap file\n"; | ||
return 0; | ||
std::cout << "OS is '" << ngReader->getOS() << "'; Hardware is '" << ngReader->getHardware() << "'" | ||
<< "'; CaptureApplication is '" << ngReader->getCaptureApplication() | ||
<< "'; CaptureFileComment is '" << ngReader->getCaptureFileComment() | ||
<< "'" << std::endl; | ||
} | ||
|
||
// read the first (and only) packet from the file | ||
pcpp::RawPacket rawPacket; | ||
if (!reader.getNextPacket(rawPacket)) | ||
pcpp::RawPacketVector packets; | ||
if (reader->getNextPackets(packets, 1) != 1) | ||
{ | ||
std::cerr << "Couldn't read the first packet in the file\n"; | ||
return 0; | ||
} | ||
|
||
pcpp::RawPacket& rawPacket = *packets.front(); | ||
do | ||
{ | ||
// parse the raw packet into a parsed packet | ||
pcpp::Packet parsedPacket(&rawPacket); | ||
|
||
// verify the packet is IPv4 | ||
if (parsedPacket.isPacketOfType(pcpp::IPv4)) | ||
// go deeper only for .pcap and .pcapng format | ||
// for .snoop we are only fuzzing the reader | ||
if (0 == strcmp(FILE_EXT, ".pcap") || 0 == strcmp(FILE_EXT, ".pcapng")) | ||
{ | ||
// extract source and dest IPs | ||
pcpp::IPv4Address srcIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getSrcIPv4Address(); | ||
pcpp::IPv4Address destIP = parsedPacket.getLayerOfType<pcpp::IPv4Layer>()->getDstIPv4Address(); | ||
|
||
// print source and dest IPs | ||
std::cout << "Source IP is '" << srcIP.toString() << "'; Dest IP is '" << destIP.toString() << "'" | ||
<< std::endl; | ||
pcpp::Packet parsedPacket(&rawPacket); | ||
parsedPacket.toString(); | ||
auto layer = parsedPacket.getFirstLayer(); | ||
while (layer != NULL) | ||
{ | ||
std::cout << layer->toString() << std::endl; | ||
layer->getHeaderLen(); | ||
readParsedPacket(parsedPacket, layer); | ||
layer = layer->getNextLayer(); | ||
} | ||
parsedPacket.computeCalculateFields(); | ||
} | ||
} while (reader.getNextPacket(rawPacket)); | ||
|
||
// close the file | ||
reader.close(); | ||
} while (reader->getNextPacket(rawPacket)); | ||
|
||
reader->close(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
#include <functional> | ||
#include <Packet.h> | ||
#include <PcapFileDevice.h> | ||
|
||
#include "Logger.h" | ||
#include "DumpToFile.h" | ||
|
||
static std::string tmpName; | ||
static std::string tmpFile; | ||
static std::string outPcapFile; | ||
static int writes = 0; | ||
|
||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) | ||
{ | ||
if (tmpName.empty()) | ||
tmpName = tmpnam (NULL); | ||
|
||
if (tmpFile.empty()) | ||
tmpFile = tmpName + FILE_EXT; | ||
|
||
if (dumpDataToPcapFile(data, size, tmpFile.c_str()) != 0) | ||
{ | ||
std::cerr << "Can't Dump buffer to the '" << tmpFile << "' file!!!!\n"; | ||
return -1; | ||
} | ||
|
||
pcpp::Logger::getInstance().suppressLogs(); | ||
|
||
std::unique_ptr<pcpp::IFileReaderDevice> reader(pcpp::IFileReaderDevice::getReader(tmpFile)); | ||
if (!reader->open()) | ||
{ | ||
std::cerr << "Error opening the '" << tmpFile << "' file\n"; | ||
return -1; | ||
} | ||
|
||
if (outPcapFile.empty()) | ||
#ifdef NG_WRITER | ||
outPcapFile = tmpName + ".pcapng"; | ||
#else | ||
outPcapFile = tmpName + ".pcap"; | ||
#endif | ||
|
||
#ifdef NG_WRITER | ||
pcpp::PcapNgFileWriterDevice pcapWriter(outPcapFile); | ||
#else | ||
pcpp::PcapFileWriterDevice pcapWriter(outPcapFile, pcpp::LINKTYPE_ETHERNET); | ||
#endif | ||
if (writes++ == 10) | ||
{ | ||
writes = 1; | ||
remove(outPcapFile.c_str()); | ||
} | ||
if (!pcapWriter.open(writes != 1)) | ||
{ | ||
std::cerr << "Cannot open '" << outPcapFile << "' for writing" << std::endl; | ||
return -1; | ||
} | ||
|
||
pcpp::RawPacketVector packets; | ||
if (reader->getNextPackets(packets, 1) != 1) | ||
{ | ||
std::cerr << "Couldn't read the first packet in the file\n"; | ||
return 0; | ||
} | ||
|
||
pcpp::RawPacket& rawPacket = *packets.front(); | ||
do | ||
{ | ||
pcapWriter.writePacket(rawPacket); | ||
} while (reader->getNextPacket(rawPacket)); | ||
|
||
pcpp::IPcapDevice::PcapStats stats; | ||
pcapWriter.getStatistics(stats); | ||
std::cout << "Written " << stats.packetsRecv << " packets successfully to pcap writer and " | ||
<< stats.packetsDrop << " packets could not be written" << std::endl; | ||
|
||
pcapWriter.close(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
The fuzzers here are used by [oss-fuzz](https://github.com/google/oss-fuzz/tree/master/projects/pcapplusplus). | ||
Oss-fuzz uses its own [tracker for found issues](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=proj%3Apcapplusplus&can=1). | ||
|
||
Read more about oss-fuzz and fuzzing [here](https://google.github.io/oss-fuzz/). | ||
|
||
Current fuzzers either try to open and parse different pcap, pcapng and snoop files or convert pcap files to pcapng and vice versa. | ||
|
||
To analyze the fuzzing coverage (code that is called and that is not by the fuzzers) open https://introspector.oss-fuzz.com/project-profile?project=pcapplusplus and click on the `Code coverage report` link to follow to the latest coverage statistics. | ||
It may also generate it locally using the [instructions](https://google.github.io/oss-fuzz/advanced-topics/code-coverage/). | ||
|
||
The fuzzers are built as part of CI, you will be notified you break something. | ||
See [oss-fuzz instructions](https://google.github.io/oss-fuzz/advanced-topics/reproducing/#building-using-docker) how to build locally. | ||
You may also check [how it is built in CI](https://github.com/sashashura/PcapPlusPlus/blob/4d12307aac20d6387956a1eae0b5274a0d3f922b/.cirrus.yml#L71-L83). |
Oops, something went wrong.