Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
zyxel-p870hn-hardware-hacking — From a bare PCB to root: hardware-hacking a ZyXEL P-870HN (BCM6368) over UART — CVE-2025-0890 + CVE-2024-40891, on my own hardware. | Kitploit
Tools/GitHubGitHub/danyw24/zyxel-p870hn-hardware-hacking
Embedded Systems SecurityPassword CrackingIoT SecurityVulnerability AnalysisExploitationReverse EngineeringHardware HackingLearning & EducationFirmware Analysis

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
GitHubdanyw24/zyxel-p870hn-hardware-hacking

zyxel-p870hn-hardware-hacking

From a bare PCB to root: hardware-hacking a ZyXEL P-870HN (BCM6368) over UART — CVE-2025-0890 + CVE-2024-40891, on my own hardware.

View Repository
281 month agoNot yet reviewed

From a bare PCB to root: hardware-hacking a ZyXEL P-870HN over UART

Two phone photos of an unlabeled router board → serial console → auth bypass → root shell — reproducing the real, still-unpatched chain CVE-2025-0890 (hidden supervisor account) + CVE-2024-40891 (CLI command injection) on hardware I own.

by damik0 · 2026-08-13 · a hardware-hacking walkthrough

  📷 PCB photos ─▶ 🔬 chip recon ─▶ 🏷️  model ID ─▶ 📍 find UART (J2)
       └─▶ 🔌 serial console ─▶ 🚪 hidden account ─▶ ⛓️  break out of CLI
              └─▶ 🐚 root shell ─▶ 🔓 dump + crack every credential

TL;DR

I had a random router board sitting on my desk. No case, no label, no idea what it was. Starting from nothing but two photos of it, I read every chip off the PCB, pinned down the exact model, found the serial (UART) header, hooked into it, walked in through a factory backdoor account, broke out of a locked-down vendor menu into a root Linux shell, and pulled every password off the box — cracked in under a second.

None of these bugs are mine. They're documented ZyXEL issues the vendor has said it won't patch. What this repo is about is the how, end to end, and the reasoning at each step.


First things first: this is my own hardware

  • The target is a router board I own.
  • Entry was through the physical serial port on the PCB — no remote attack, no third-party network, nothing exposed to the internet.
  • It sat on my bench, air-gapped, the whole time.
  • The goal was to run the full hardware-hacking loop end to end and document it so it's reproducible.

What I was poking at

I worked the ID out from the silkscreen board number 45-402-000022 and the barcode, cross-referenced against TechInfoDepot, OpenWrt's hardware table, and the FCC ID I88P870HN51B:

ModelZyXEL P-870HN-53b — VDSL2/ADSL2+ WiFi gateway, built by MitraStar
Era~2013 (date-codes point to week 21 / 2013); an ISP-distributed unit
SoCBroadcom BCM6368UKPBG — dual-core MIPS (BMIPS4350), ~400 MHz
RAM2× Winbond W9425G6JH-5 — 256 Mbit DDR2 ×16 each = 64 MB on a 32-bit bus
FlashMacronix MX29LV640EBTI-70G — 8 MB parallel NOR, TSOP-48
WiFiBroadcom BCM43222 (802.11n; dual-band silicon, wired to 2.4 GHz only)
DSL AFEBroadcom BCM6302
FirmwareLinux 2.6.30 + BusyBox v1.00, Broadcom CFE bootloader (built 2012-06-11)

Why the board number is the key that unlocks everything: ODM gateways like this are reference designs. Once the silkscreen part number matches a documented board, you inherit someone else's homework — the exact flash chip, the UART location and pinout, the default accounts. Identification isn't a formality; it's what turns blind probing into a targeted attack.


How it went down

Step 0 — getting the photos off my phone

Small quality-of-life thing first: I threw together a tiny LAN photo-uploader (Python stdlib, zero deps) so I could shoot the board with my phone and have the pics land straight on my machine. Half of a good session is killing friction like this.

Step 1 — reading the board

I went chip by chip off the high-res photos. Package types tell you the story before you even read the markings: the BGA in the middle is the brain, the TSOP-48 is almost always parallel flash, the little can with a coax pigtail is the radio. The SoC was hiding under an RF shield (there for EMI + as a heat spreader), so I popped the can to read the marking underneath — a Broadcom BCM6368.

Annotated board map

The board, mapped: (1) BCM6368 SoC, (2) DDR2 RAM, (3) BCM43222 WiFi, (4) DSL line transformer, (5) Ethernet magnetics, (6) internal USB headers, (7)(8) board markings, (9) the J2 console header, (10) an unpopulated JTAG footprint.

Step 2 — putting a name to it

The silkscreen 45-402-000022 matched the documented board exactly, and every chip — SoC, flash, WiFi, the 64 MB of RAM — lined up piece by piece with the -53b variant. Now I didn't just know what it was; I knew where its UART lived and what account would let me in.

Step 3 — hunting the UART

Right next to the SoC there was a populated 6-pin right-angle header, silkscreened J2, with a triangle marking pin 1. Confirmed against OpenWrt's page for the model:

PinSignal
1VCC 3.3Vleave it disconnected
2Tx→ adapter RX
3Rx→ adapter TX
4GND→ adapter GND
5NC

115200 8N1, 3.3V TTL.

J2 wiring card

How you find a UART when there's no wiki telling you the pinout — the part that shows this isn't just following a recipe:

  • GND — continuity (beep) to the ground plane / shield, board unpowered.
  • VCC — a rail that sits at a steady ~3.3 V once powered.
  • TX — idles high at ~3.3 V (UART mark state) and visibly dips/flickers the instant the device boots and starts spewing its log. That flicker is the console talking.
  • RX — usually the quiet one: floating or weakly pulled, no boot activity.

And if you didn't know the baud? 115200 is the Broadcom CFE default, but blind you'd either sweep the common rates (9600 → 115200) until the garbage turns into ASCII, or measure the narrowest bit period on a scope and do 1 / t.

Step 4 — getting a console

I wired up a USB-TTL adapter (HW-597, PL2303) with the jumper on 3.3V. This matters: the BCM6368's UART is 3.3 V TTL, not RS-232 (±12 V) — hang a real serial port or a 5 V adapter off it and you cook the pin. Ground first, then RX/TX crossed, VCC left floating so nothing back-powers the board. Before applying power I confirmed GND and VCC with a multimeter, then:

screen /dev/ttyUSB0 115200

Powered it up, watched the CFE hand off to the kernel, watched BusyBox init come up, and landed on a login prompt.

Step 5 — the front door was wide open · CVE-2025-0890

The login fell to a hidden factory account ZyXEL never documents for the end user:

user:     supervisor
pass:     zyad1234

Full system privilege. This is the core of CVE-2025-0890.

Step 6 — busting out of the vendor cage · CVE-2024-40891

That login dropped me into a locked-down vendor CLI (consoled, a > prompt): no sh, none of the usual Linux tools — a jail wrapped around the real system. But it exposed a ping diagnostic, and that command built its argument straight into a shell string with zero sanitizing. So I fed it a shell metacharacter:

> ping 127.0.0.1; sh

…and dropped into a root BusyBox shell (#).

Why one semicolon is enough: the CLI handler does the equivalent of system("ping " + userinput). The ; closes the ping command and starts a second one — sh — which inherits the console's stdin/stdout, so you get an interactive shell. The account was already uid 0; the CLI was the only thing standing between me and a real shell, and unsanitized input tore that wall down. Chaining an authenticated CLI injection onto the hidden account is exactly the pattern tracked as CVE-2024-40891.

Step 7 — grabbing the loot

With root, I looked at the system and the flash:

# cat /proc/version
Linux version 2.6.30 ... (Buildroot 2010.02) #1 Mon Jun 11 2012

# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 004f5000 004f5000 "Physically mapped flash"     # 5,197,824 bytes = the whole firmware
Download Tool