Skip to content

Instantly share code, notes, and snippets.

@up-n-atom
Last active December 24, 2025 12:09
Show Gist options
  • Select an option

  • Save up-n-atom/13f1759dfa6135a73aa15258a8a35c7a to your computer and use it in GitHub Desktop.

Select an option

Save up-n-atom/13f1759dfa6135a73aa15258a8a35c7a to your computer and use it in GitHub Desktop.
Axon Networks AN5500 Jailbreak

ℹ️ The following method has been discussed and confirmed on https://discord.pon.wiki as I don't have physical access to the hardware.

Axon Networks AN5500 Jailbreak

The AN5500 is manufactured by Gemtek Technology Co. and deployed by Lumen/Quantum/CenturyLink for use on their PON network.

https://fccid.io/MXF-C5500XK

Firmware

The latest firmware can be acquired from CenturyLink https://www.centurylink.com/home/help/internet/modems-and-routers/c5500xk.html and extracted by binwalk.

mkdir c500xk && cd $_
wget http://internethelp.centurylink.com/internethelp/modems/C5500XK/firmware/CKX001-02.00.13.00.bin
binwalk -e CKX001-02.00.13.00.bin

Requirements

TTY serial access

Observations

OpenWrt

Failsafe

Failsafe mode is active and an entrypoint into the system.

Overlay

mount_root or rather /lib/libfstools.so has been modified to cleanse the /overlay of directories and files not whitelisted within /etc/overlay_whitelist.conf thus preventing nonobtuse root access.

Serial Console

The serial console ttyS0 is not the standard getty, it's locked down to /usr/bin/avec_console within /etc/inittab.

SSH

A limited chroot environment is exposed over SSH with the environment being generated by /etc/init.d/chroot and started by /opt/econet/etc/dropbear init scripts.

Strategy

With the typical edits being infeasible, we look towards what has been handed to us.

  1. Failsafe allows us access to the squashfs and the subsequent overlayfs, albeit whitelisted.
  2. We could trouble ourselves to disassemble avec_console looking for a signs of a backdoor.
  3. Lets not even bother with the chroot SSH but take note of dropbear's presence.

Choosing the path of least resistance, we opt for #1. The whitelist leaves a lot to discovery but the one file that stands out is /etc/config/dhcp. Those in the know, know that DHCP services have a bestowed privilege of executing shell scripts and dnsmasq is no exception; the dhcpscript option spells it out, so lets abuse that privilege.

But before we do that, there are two caveats... First, from the manpage: "<path> must be an absolute pathname, no PATH search occurs". Second and most important, it must be a file that has been whitelisted.

Nearly all the whitelisted files are configuration files, with the exception of a handful... For the brevity of this guide, /etc/urandom.seed is the least necessary to the system functionality and anything within, is seeded as binary, but more importantly, seeding takes place after network bringup — i.e. /etc/rc.d/S19dnsmasq before /etc/rc.d/S99urandom_seed.

Jailbreak

  1. Break into failsafe mode on bootup and mount the overlayfs
mount_root
  1. Modify the lease script in /etc/config/dhcp
uci set dhcp.dnsmasq_lan.dhcpscript="/etc/urandom.seed"
uci commit dhcp
  1. Generate the trojaned lease script /etc/urandom.seed
cat > /etc/urandom.seed << 'EOF'
#!/bin/sh

SCRIPT="/usr/lib/dnsmasq/dhcp_notify_event.sh"

[ -e /var/run/jailbreak.pid ] || (dropbear -P /var/run/jailbreak.pid -E -p 2222 &>/dev/null; uci -q set dhcp.dnsmasq_lan.dhcpscript="$SCRIPT" && uci -q commit dhcp && /etc/init.d/dnsmasq reload &>/dev/null)

exec $SCRIPT $@
EOF
  1. Modify the root password to something memorable and known
passwd
  1. Reboot with a network cable attached to a remote PC and SSH in after boot — e.g. ssh root@192.168.0.1:2222
reboot

Deobfuscate

PPPoE Password

The pppd daemon has been modified to accept an encrypted password file that is decrypted by /usr/lib/pppd/2.4.7/passwordfile.so.

The password file is generated by encrypting a plain-text password using the RSA algorithm and public key /etc/axon_ppp_public.pem — e.g. found in /lib/netifd/proto/ppp.sh

echo "$password" | openssl rsautl -out "$passwdfile" -pubin -inkey /etc/axon_ppp_public.pem -encrypt

The private key can be extracted from /usr/lib/pppd/2.4.7/passwordfile.so using binwalk on a remote PC.

scp -O root@192.168.0.1:2222:/usr/lib/pppd/2.4.7/passwordfile.so ./
binwalk -D="private:der:mv '%e' axon_ppp_private.der" ./passwordfile.so

A default password file also exists, /etc/ppp/ctlcred, and can be decrypted with the acquired private key — e.g.

scp -O root@192.168.0.1:2222:/etc/ppp/ctlcred ./
openssl pkeyutl -in ./ctlcred -inkey ./axon_ppp_private.der -decrypt
root@OpenWrt:/# cat /proc/cpuinfo
system type : EcoNet EN7580 SOC
machine : Unknown
processor : 0
cpu model : MIPS interAptiv (multi) V2.12
BogoMIPS : 852.78
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2 mt eva
shadow register sets : 1
kscratch registers : 3
package : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
VPE : 0
processor : 1
cpu model : MIPS interAptiv (multi) V2.12
BogoMIPS : 1150.97
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2 mt eva
shadow register sets : 1
kscratch registers : 3
package : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
VPE : 1
processor : 2
cpu model : MIPS interAptiv (multi) V2.12
BogoMIPS : 1145.24
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2 mt eva
shadow register sets : 1
kscratch registers : 3
package : 0
core : 1
VCED exceptions : not available
VCEI exceptions : not available
VPE : 0
processor : 3
cpu model : MIPS interAptiv (multi) V2.12
BogoMIPS : 861.38
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [0x0ffc, 0x0ffc, 0x0ffb, 0x0ffb]
isa : mips1 mips2 mips32r1 mips32r2
ASEs implemented : mips16 dsp dsp2 mt eva
shadow register sets : 1
kscratch registers : 3
package : 0
core : 1
VCED exceptions : not available
VCEI exceptions : not available
VPE : 1
root@OpenWrt:/# cat /proc/meminfo
MemTotal: 426332 kB
MemFree: 138068 kB
MemAvailable: 160248 kB
Buffers: 15904 kB
Cached: 48152 kB
SwapCached: 0 kB
Active: 93156 kB
Inactive: 21988 kB
Active(anon): 52444 kB
Inactive(anon): 1552 kB
Active(file): 40712 kB
Inactive(file): 20436 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 4 kB
Writeback: 0 kB
AnonPages: 51132 kB
Mapped: 30204 kB
Shmem: 2908 kB
Slab: 133332 kB
SReclaimable: 3984 kB
SUnreclaim: 129348 kB
KernelStack: 2416 kB
PageTables: 548 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
WritebackTmp: 0 kB
CommitLimit: 213164 kB
Committed_AS: 64712 kB
VmallocTotal: 1048372 kB
VmallocUsed: 0 kB
VmallocChunk: 0 kB
root@OpenWrt:/# cat /proc/mtd
dev: size erasesize name
mtd0: 00200000 00040000 "bootloader"
mtd1: 00200000 00040000 "dsd"
mtd2: 00275dd6 00040000 "kernel"
mtd3: 01570000 00040000 "rootfs"
mtd4: 04000000 00040000 "tclinux"
mtd5: 00275e83 00040000 "kernel_slave"
mtd6: 01590000 00040000 "rootfs_slave"
mtd7: 04000000 00040000 "tclinux_slave"
mtd8: 14000000 00040000 "system"
mtd9: 00200000 00040000 "uenv"
mtd10: 00180000 00040000 "art"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment