NextDrive Cube J1を分解せずにrootを取りたい!
この記事は、2025年3月31日にサービス終了した「NextDrive Cube J1」で、分解せずにrootシェルへ到達するまでの調査メモと手順をまとめたものです。
NextDrive Cube J1は、Wi-SUNモジュールを搭載したHEMSゲートウェイで、スマートメーターと通信をして消費電力等を監視することができます。
調査の過程で、USBメモリを挿すだけでUSBメモリ内のコードが実行される仕組みが見つかりました。
この仕組みを利用すると、基板上のシリアルポートにアクセスしなくてもrootで操作することができます。
手っ取り早く試したい方は、こちらの章からどうぞ。
また、Cube J1をHome Assistantのセンサーとして利用するためのツールをGitHubにて公開しています。こちらもぜひご覧ください。
Cube J1 MQTT
はじめに
我が家では、家全体の消費電力監視を、数年前に一時期出回った秋月電子の謎SoC基板で行っています。
別拠点でも監視がしたく、Wi-SUNモジュールを安く手に入れたいなぁとヤフオクを眺めていたところ、NextDrive Cube J1が沢山出品されており、気になって2台購入してみました。
分解手順は以下記事を参考にさせていただきました。
基板上にシリアルポートがあり、rootにもなれるため色々なことが簡単にできます。ただ、基板のスルーホールがハーフピッチのため作業が少し面倒です。
(基板左下の縦3つに並んだスルーホールがシリアルポート)

Cube J1の基板
そのため、分解せずにシリアルポートにアクセスせずに何とかできないかと考えたのがモチベーションです。
クイックスタート
Cube J1は、特定のファイルを置いたUSBメモリを挿入するとCube J1がUSBメモリ内のファイルを/tmpにコピーし、実行する仕組みがあるようです。
これを利用して、たとえばadbの待受設定などを行うスクリプトを実行させることで、ネットワーク越しに操作できる状態にできます。
USBメモリの準備
USBメモリのルートディレクトリに以下の構造でファイルを作成します。
USBメモリ
┣━ CubeJMTS.txt
┗━ production_tool
┗━ production_tool
CubeJMTS.txtは空のファイルで問題ありません。
production_toolの中身は以下のようにしました。
#!/system/bin/sh
# adb settings
setprop service.adb.tcp.port 5555
setprop persist.adb.tcp.port 5555
setprop persist.sys.usb.config mtp,adb
# restart adbd
stop adbd
sleep 1
start adbd
# finish led
ORIG_COLOR=$(getprop led.control.state)
for i in $(seq 1 10)
do
setprop led.control.state red
sleep 0.5
setprop led.control.state green
sleep 0.5
setprop led.control.state blue
sleep 0.5
done
setprop led.control.state "$ORIG_COLOR"
このスクリプトでは、adb周りの設定とadbdの再起動を行い、最後にLEDを点滅させています。
root化
Cube J1の電源を入れ、起動が完了するのを待ちます。
LEDの点滅が終わり、緑色または青色の点灯状態になれば起動完了です。
Cube J1に実際にUSBメモリを挿してみると以下のような感じになります。

root化の様子
あとは、Cube J1にWi-Fiで接続するとadb経由でアクセスが可能になります。
リモートアクセス
Cube J1は出荷時の状態ではWi-Fiアクセスポイントとして設定されており、以下の情報でCube J1に接続することができます。
シリアル番号はCube J1本体底面や外箱に記載されています。
- SSID:
CubeJ-[本体シリアル番号の下6桁] - パスワード:
12345678
接続が成功すると、恐らく192.168.100.1/24のアドレスが割り振られるはずです。
Cube J1本体のアドレスは192.168.100.1です。
adbで接続する
Cube J1にWi-Fiで接続したPCから以下で接続します。
adb connect [Cube J1のIPアドレス]:5555
adb root
# restarting adbd as root と表示されたら成功
adb shell
#で始まるプロンプトになれば成功しています。
Cube J1をWi-Fiクライアントとして設定する
こちらの項を参考に、/data/misc/wifi/wpa_supplicant.confを編集して任意のアクセスポイントに接続することができます。
Cube J1の調査
以下は、Cube J1の調査メモです。
本体を分解してシリアルポート経由でアクセスし、調査を行っています。
ハードウェア・OSについて
Cube J1のハードウェア・OSは以下の通りです。
- SoC: Rockchip RK3128 (Cortex-A7 4コア)
- RAM: 1GB
- OS: Buildroot 2016.11.1ベースの組み込みLinux
# cat /etc/os-release
NAME=Buildroot
VERSION=2016.11.1-00010-gd0cf3f7cb
ID=buildroot
VERSION_ID=2016.11.1
PRETTY_NAME="Buildroot 2016.11.1"
しかし、ルートディレクトリを覗くと何か雰囲気がおかしい……。
# ls /
acct default.prop init.environ.rc lost+found root sepolicy ueventd.rc
bin dev init.rc media run service_contexts usr
build.prop etc init.usb.configfs.rc mnt sbin storage var
cache file_contexts.bin init.usb.cubej.rc oem sdcard sys vendor
config fstab.cubej init.usb.rc opt seapp_contexts system
d init lib proc selinux tmp
data init.cubej.rc lib32 property_contexts selinux_version ueventd.cubej.rc
init.rcやbuild.propなどAndroidで見たことがあるファイル名がちらほら見えます。
あまり詳しくないのですがadbやlogcatなどが使えそうです。
Cube J1で動作しているサービスの調査
まずは、Cube J1上でどんなサービスがネットワーク越しにサービスしているかnetstatで確認してみます。
# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program Name
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 173/nginx:
tcp 0 0 127.0.0.1:5037 0.0.0.0:* LISTEN 192/adbd
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 173/nginx:
tcp 0 0 0.0.0.0:8883 0.0.0.0:* LISTEN 169/mosquitto
tcp 0 0 0.0.0.0:53 0.0.0.0:* LISTEN 448/dnsmasq
tcp 0 0 :::443 :::* LISTEN 173/nginx:
tcp 0 0 :::8883 :::* LISTEN 169/mosquitto
tcp 0 0 :::5555 :::* LISTEN 192/adbd
udp 0 0 0.0.0.0:5353 0.0.0.0:* 317/avahi-daemon:
udp 0 0 0.0.0.0:3610 0.0.0.0:* 171/ndeclite_agent
udp 0 0 0.0.0.0:53 0.0.0.0:* 448/dnsmasq
udp 0 0 0.0.0.0:67 0.0.0.0:* 448/dnsmasq
udp 0 0 0.0.0.0:38255 0.0.0.0:* 166/gndctrl
udp 0 0 0.0.0.0:38768 0.0.0.0:* 317/avahi-daemon:
これらのサービスの中で、今回調査を進めていく中でgndctrlに着目しました。
実行ファイル自体は/usr/sbin/gndctrlです。
(実際gendctrlがネットワーク越しに何をしているかは不明です)
stringsでファイルを調査してみたところ、怪しい文字列が沢山出てきました。
# strings /usr/sbin/gndctrl
(※出力は抜粋)
/mnt/usb/CubeJMTS.txt
This is not a valid Next Drive RMA USB.
どうやらNext Drive RMA USBという魔法のUSBメモリがあるようです。
実行されるスクリプト
もう少し詳しく調査したところlaunch_pt_init.shというスクリプトを発見しました。
# cat /usr/sbin/launch_pt_init.sh
#!/system/bin/sh
#
# Script for launch production tool
echo -e "Production utility installization ..."
CUBEJMTS="/mnt/usb/CubeJMTS.txt"
RESULT="/mnt/usb/TestResult.txt"
PT_UTILITY="/mnt/usb/production_tool"
TMP="/tmp"
TMP_PT_UTILITY="/tmp/production_tool"
#CubeJMTS.txt
if [ -e $CUBEJMTS ]; then
if [ -d $PT_UTILITY ]; then
echo "cp $CUBEJMTS to $TMP"
cp $CUBEJMTS $TMP
echo "cp $PT_UTILITY to $TMP"
cp -r $PT_UTILITY $TMP
echo "Production test start ..."
if [ -e $RESULT ]; then
rm -f $RESULT
fi
RES=`chmod -R +x $TMP_PT_UTILITY/*`
eval "$TMP_PT_UTILITY/production_tool &"
fi
fi
これはUSBメモリ内にCubeJMTS.txtが存在している場合、USBメモリ内のproduction_toolを/tmpへコピーし、evalで実行するというものです。
USBメモリ挿入時のイベントログを追ってみると、USBメモリ内にCubeJMTS.txtが存在している場合、「production test mode」へ入っていることが分かります。
(ログは抜粋です)
01-10 06:18:39.648 169 169 I gndctrl-uevent: event { 'add', '/devices/101c0000.usb/usb1/1-1/1-1:1.0/host2/target2:0:0/2:0:0:0/block/sda', 'block', '', 8, 0 }
01-10 06:18:39.649 169 169 I gndctrl-uevent: Mount /dev/block/sda1 to /mnt/usb
01-10 06:18:39.649 169 169 I gndctrl-uevent: /mnt/usb exists!
01-10 06:18:40.657 169 169 I gndctrl-uevent: production test mode
Wi-Fiについて (APモード / クライアントモード)
Cube J1からはCubeJ-XXXXXXというSSIDが吹いています。
これはp2p-wlan0-0インターフェースで、Wi-Fiアクセスポイントとして動作しています。
また、wlan0インターフェースはWi-Fiクライアントとして任意のアクセスポイントに接続可能です。
CubeJ-XXXXXXの調査
logcatでWi-Fi関連のログを調査してみたところ、SSIDやパスワードが平文で出力されていることが分かりました。
logcat | grep WifiP2pManagerStateM
01-10 12:31:33.844 188 323 W WifiP2pManagerStateM: connectToSupplicant
01-10 12:31:33.846 188 323 W WifiP2pManagerStateM: Connect to supplicant success
01-10 12:31:33.846 188 323 W WifiP2pManagerStateM: loadStatus
01-10 12:31:33.848 188 323 W WifiP2pManagerStateM: wpa_state 1
01-10 12:31:33.848 188 323 W WifiP2pManagerStateM: interface mac 6e:21:a2:XX:XX:XX p2p mac 6e:21:a2:XX:XX:XX
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: P2P_EVENT_PREFIX_STR
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: P2P_GROUP_STARTED_STR
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: interface p2p-wlan0-0
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: role GO
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: ssid "ssid="CubeJ-XXXXXX""
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: freq "freq=2462"
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: passphrase "passphrase="12345678""
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: go_dev_addr "go_dev_addr=6e:21:a2:XX:XX:XX"
01-10 12:31:40.341 188 323 W WifiP2pManagerStateM: flag [PERSISTENT]
パスワードは12345678で固定されているようです。
Wi-Fiクライアントの設定
Wi-Fiクライアントの設定は/data/misc/wifi/wpa_supplicant.confに保存されています。
以下のように設定することで、任意のアクセスポイントに接続可能です。
ctrl_interface=/data/misc/wifi/sockets
update_config=1
network={
ssid="ssid"
psk="password"
key_mgmt=WPA-PSK
}
Discussion