Debug-toegang verkrijgen op een Brother-printer via Telnet

Context

Ik heb er altijd al van genoten om te ontdekken hoe dingen werken. Dat begon met hardware en het uit elkaar halen van interessante apparaten, en inmiddels doe ik hetzelfde met software. Nu ik heb geleerd hoe software werkt, is een van mijn doelen het ontsluiten van verborgen functies. Bij apparaten op basis van Linux betekent dat het verkrijgen van een root Linux-shell. Maar hoe zit dat met printers?

Het onderwerp

Het onderwerp van deze analyse is de Brother MFC-L8900CDW. In tegenstelling tot de reputatie van bepaalde andere printermerken en modellen, verbindt deze printer altijd en print hij consistent. mDNS stopt niet zomaar met werken, het papier raakt niet willekeurig bekneld en de toner gaat eeuwig mee. Echter, de CLI (Command Line Interface) van de fabrikant is beperkt als het gaat om diepgaande systeeminformatie.

De zoektocht begint

De eerste stap om tegenwoordig zaken uit te pluizen, is het verkrijgen van een firmware-binary en vervolgens AI te gebruiken om deze vanuit alle hoeken aan te vallen. (Sommige mensen zijn natuurlijk bekwaam genoeg om dit zelf te doen, maar ik hoor daar niet bij.)

Op sommige apparaten kun je een firmware-image direct downloaden, maar bij Brother wordt verwacht dat je hun eigen downloader gebruikt. Mijn AI-agent probeerde eerst direct naar de link te gaan die in de Brother firmware-updater app stond, maar hun server wees een gegiste XML-aanvraag af. Na wat dieper onderzoek in de firmware-update tool vonden we de lijst met modellen en gegevens die het systeem accepteert.

Hoewel Brother het formaat op elk moment kan wijzigen, is dit de aanvraag die werkte voor mijn printer:

curl -sS \
'https://firmverup.brother.co.jp/kne_bh7_update_nt_ssl/ifax2.asmx/fileUpdate' \
-H 'Content-Type: text/xml' \
--data-binary @- <<'XML'
<REQUESTINFO>
<FIRMUPDATETOOLINFO>
<FIRMCATEGORY>MAIN</FIRMCATEGORY>
<OS>MAC</OS>
<INSPECTMODE>0</INSPECTMODE>
</FIRMUPDATETOOLINFO>
<FIRMUPDATEINFO>
<MODELINFO>
<NAME>MFC-L8900CDW series</NAME>
<SPEC>0001</SPEC>
<DRIVER>EWS</DRIVER>
<FIRMINFO>
<FIRM>
<ID>MAIN</ID>
<VERSION>ZU2605160228</VERSION>
</FIRM>
</FIRMINFO>
</MODELINFO>
<DRIVERCNT>1</DRIVERCNT>
<LOGNO>2</LOGNO>
<NEEDRESPONSE>1</NEEDRESPONSE>
</FIRMUPDATEINFO>
</REQUESTINFO>
XML

Je kunt de firmwareversie vervangen door B0000000000, wat ook werkt. Als reactie stuurde de API van Brother het volgende terug:

<RESPONSEINFO>
<FIRMUPDATEINFO>
<VERSIONCHECK>0</VERSIONCHECK>
<MEMORYVERSION>a</MEMORYVERSION>
<FIRMID>MAIN</FIRMID>
<LATESTVERSION>ZV2608181949</LATESTVERSION>
<PATH>http://update-akamai.brother.co.jp/CS/D009UD_ZV.djf</PATH>
<DLTIME>175000</DLTIME>
</FIRMUPDATEINFO>
</RESPONSEINFO>

Analyse van de firmware

Zodra de firmware binnen was, ging GPT-6.1 Sol aan de slag. Dit zijn de bevindingen:

Conclusie over het besturingssysteem

De hoofdapplicatie-firmware maakt gebruik van het T-Kernel real-time operating system (RTOS) uit de TRON-familie op 32-bit little-endian ARM. Betrouwbaarheid van deze conclusie: hoog. De exacte T-Kernel release, CPU-core en SoC zijn nog niet vastgesteld.

Bewijs in extracted/ZlibRo.bin (hex-offsets relatief aan dat bestand):

  • 0x004b0168: T-Kernel/OS SVC in execution
  • 0x019c0450: Software Interrupt (SWI) #6 (T-Kernel/OS & Extended SVC)
  • 0x019c050f: Software Interrupt (SWI) #9 (T-Kernel/DS)
  • 0x019c7d7b: OS_Ver
  • 0x019c7d82: TSysName
  • 0x019c7d8b: T-Kernel
  • 0x019c7d94: TMaxTskId (gevolgd door configuratienames voor semaforen/mutexen/etc.)
  • 0x0002a624: TASK STACK INFORMATION voor ITRON
  • 0x002b3014: MFC-L8900CDW series (ook op 0x00c40f4c en 0x00c4148c)

Bewijs in extracted/KernelRo.bin:

  • 0x0000e188: T-Monitor Initialize
  • 0x0000e8a5: TM> prompt
  • 0x00009154: Undefined Instruction (ARM)
  • 0x00009170: Undefined Instruction (THUMB)
  • ARM exception registers R0-R15/CPSR en ARM processor modes zijn aanwezig.
  • De openingswoorden decoderen als ARM little-endian instructies, inclusief SUB lr, lr, #4 (0xe24ee004) en PUSH {r3,r12,lr} (0xe92d5008).
  • De RTOS-kernel is een aparte sectie van 141.932 bytes, geladen op 0x40100000.

Opslag en bibliotheken

Dit is een identificatie van strings, geen beveiligingsaudit:

  • ZlibRo.bin 0x010050e4: Datalight Reliance Nitro v3.0.6 Build 2306EC
  • ZlibRo.bin 0x003302e4: RTOS Edition for arm; gecompileerd op 21 dec 2015
  • ZlibRo.bin 0x010d6b50: Datalight FlashFX Tera v3.1 Build 2772E
  • ZlibRo.bin 0x00f391e0: Lua 5.2.3 versie-identificatie
  • ZlibRo.bin 0x008ddaa4: OpenSSL 1.0.1c; andere secties identificeren OpenSSL 1.0.2
  • ZlibRo.bin 0x005377b8: libpng versie 1.6.43
  • ZlibRo.bin 0x00692ec8: gSOAP/2.7
  • ZlibRo.bin 0x019bb300: wpa_supplicant v0.5.7-Devicescape

Let op: Versielabels kunnen overleven na vendor backports; ze bewijzen niet welke kwetsbaarheden aanwezig zijn of dat elke gebundelde module actief is.

Flash-layout en extractie

De update-wrapper begint met PJL EXECUTE BRDOWNLOAD / PROGRAM=FIRM. Dit pakket mapt file-offset 0x93 naar flash-adres 0xe0060000.

Een tabel met labels van 20 bytes plus 32-bit little-endian waarden begint op package-offset 0x8497. Hierin worden de kernel, paginatabel en zlib-secties benoemd. De hoofd-gecomprimeerde stream begint op package-offset 0x2b2e7.

OutputBytesLoad address
PageTable.bin33.7920xe0060000
KernelRo.bin141.9320x40100000
ZlibRo.bin28.186.9160x40222b00
ZlibRw.bin7000x41e00d00
Zlib2Rw.bin1.526.3960x43cb8f00

Binwalk vond ingebedde afbeeldingen en andere assets, maar geen herkenbaar Linux-bestandssysteem of kernel-image.

Hardware

Het datasheet van Brother specificeert een hoofdprocessor van 800 MHz, een subprocessor van 133 MHz en 512 MB geheugen. De image bevat SubCPU/print-engine controleberichten, wat consistent is met een RTOS-applicatie die printen, scannen, UI, netwerken en een aparte engine-controller coördineert.

Bronnen en vergelijkingsmateriaal

  • TRON Forum: T-Kernel en T-Monitor rollen (tron.org)
  • TRON Forum: Officiële bron-downloads (tron.org)
  • Brother model datasheet: (brother.lt)
  • STAR Labs: Onafhankelijke inspectie van een ander Brother-model met T-Kernel (starlabs.sg)

Analyse van de Debug-interface

Configuratieregisters in ZlibRo.bin zijn elk 20 bytes: integer waarde; name pointer; type; count; pointer naar eigen waarde.

Records voor TmConsEnable, TmDebugPort en TmBaudRate hebben waarden 0/0/115200. Kernelcode op 0x40109344 leest TmConsEnable en op 0x40109360-0x40109368 wordt de initiële seriële console-initialisatie overgeslagen wanneer die waarde nul is.

T-Monitor karakter I/O heeft toegang tot memory-mapped hardware op 0xd0c00000:

  • 0x4010e058: output karakter routine
  • 0x4010e0d0: seriële initialisatie (schrijft "T-Monitor Initialize")
  • 0x4010e1a0: input karakter routine
  • 0x4010e7c4 en 0x4010e8c0: interactieve loops met TM> prompt

Op 0x4010e280 laadt de command-dispatcher de tabel op adres 0x41e00e18. De initiële tabel in extracted/ZlibRw.bin (offset 0x118) bevat:

  • Help, H, handler 0x4010e318
  • null, null, handler 0x4010e1f8 (print "Unsupported command")

Separate Brother debug console

De applicatie bevat identifiers zoals telnetddebug en /telnetdebug_q, de tekst "Enter debug user mode" en help-strings voor debug-symbolen, task-stacks, heap-gebruik, uptime en console-output redirectie.

Overzicht van de Tech Stack

ComponentInformatie
CPU architectuur32-bit ARM, little-endian
Opslag bestandssysteemDatalight Reliance Nitro 3.0.6
Flash managementDatalight FlashFX Tera 3.1
ScriptingLua 5.2.3
Overige bibliothekenOpenSSL, gSOAP, libpng, wpa_supplicant
Firmware structuurSeparate kernel, gecomprimeerde applicatiecode, ingebedde web/UI assets
Hardware specs800 MHz hoofdprocessor, 133 MHz subprocessor, 512 MB RAM

Debug-toegang verkrijgen zonder modificaties

Indien Telnet is ingeschakeld op de printer (via de web UI), is het zeer eenvoudig om de drie debugging-modi te benaderen. Let op: Gebruik dit op eigen risico! Je kunt het systeem ernstig beschadigen als je parameters onjuist wijzigt.

  1. Log in op de command console met je admin-wachtwoord.
  2. Druk op Enter wanneer er om een gebruikersnaam wordt gevraagd.
  3. Zodra je bij de Local> prompt bent, typ je: SET USER 640184.571119

Voorbeeld van een sessie:

inventor7777@Mac-Studio - 20:17 ~ % telnet 192.168.50.16
Trying 192.168.50.16...
Connected to 192.168.50.16.
Escape character is '^]'.
Welcome. Type <return>, enter password at # prompt
#
Brother NC-8700w Command Console
Copyright(C) 2000-2017 Brother Industries, Ltd.
KASAGO TCP/IP Copyright (c) 2011 ZUKEN ELMIC, Inc.
Interface 1 : NC-9200h, Ethernet 10/100/1000BASE-T      (Inactive)
Interface 2 : NC-8700w, IEEE 802.11b/g/n                  (Active)
Interface 2 is selected for configuration
Type HELP for command list
Enter username>
Local> SET USER 640184.571119
Enter debug user mode.
Local> HELP
EXIT/^D                  Exit program
HElp                     Information on available commands
INitialize               Reset unit
CLear                    Remove configuration item
SET                      Modify unit parameters
SHow                     Display unit parameters
ZEro                     Zero statistical counts
DEbug                    Execute debug functions
REDirect                 Redirect printf() output
WATch [<addr>[ <intvl/cond>[ <unit>]]] Watch memory function
SNTPDEBUG                SNTP for debug functions
Type 'HElp <cmd>' for more information

Andere modi

Er zijn ook modi voor wireless QA en wireless development:

  • Wireless QA: SET USER 031227
  • Wireless Development: SET USER 031227.040119

Met het commando DEBUG SHOW HEAP kun je een volledige lijst verkrijgen van alle actieve taken en hoeveel heap-geheugen zij gebruiken.