Upgrade to Pro — share decks privately, control downloads, hide ads and more …

イ良い日ンマを作る(USBストレージ容量偽装の手法) / USB Storage Capacity Faking Techniques

shutingrz
February 04, 2023

イ良い日ンマを作る(USBストレージ容量偽装の手法) / USB Storage Capacity Faking Techniques

shutingrz

February 04, 2023
Tweet

More Decks by shutingrz

Other Decks in Technology

Transcript

  1. イ良い日ン マを作る
    しゅーと

    View Slide

  2. イ良い日ン マとは
    • 2018年、突如ネット上に現れたmicroSD
    • アググンと呼ばれるものもある
    • 基本的に容量偽装系ストレージ
    • 2022年、SSDに形を変えて
    パンピーを襲っている

    View Slide

  3. 容量偽装について
    • 実際のフラッシュ領域に対しての見せかけが異なる
    • 使えないわけではない
    • 返品期限までごまかすため?
    • 偽装方法には大きく2種類
    • 無視タイプ
    • 上書きタイプ
    https://www.rescue-center.jp/elementary/vol54.html

    View Slide

  4. 目標
    • 任意の容量だと嘘をつく
    • 1ペタバイトを目標
    • 書き込めるけど一定のサイズを超えると異常動作を起こす
    • 無視または上書き動作

    View Slide

  5. その前に

    View Slide

  6. USBデバイスを作る方法

    View Slide

  7. USBデバイスを作る方法
    • USBデバイスICを使う
    • 汎用マイコン内蔵のUSB PHYを使う
    • USBエミュレーションツールを使う

    View Slide

  8. Facedancer
    • USBデバイスのエミュレーションライブラリ(Python製!)
    • 対応ハードウェアのUSB APIを利用して機能を実現
    • GreatFET Oneと呼ばれるボードが現在最も再現性が高い
    • 今年6月発売のLUNAに合わせて進化を遂げるらしい
    GreatFET One LUNA

    View Slide

  9. facedancer-umass.py
    • イメージをマスストレージデバイスとして流し込むスクリプト
    • 以下で簡単にディスクイメージを作って接続できる
    • 接続するとターゲット上で認識される(未初期化)
    # 100MBサイズのディスクイメージ (何も初期化しない)
    dd if=/dev/zero of=disk_100MB.bin bs=100M count=1
    # スクリプト実行
    ./legacy-applets/facedancer-umass.py ./disk_100MB.bin
    コントロール用
    USBポート ターゲット用
    USBポート

    View Slide

  10. メモ: オンメモリだけで実現も
    • コードからfdを排除し全てdictに
    • プログラム終了時にはデータが失われる

    View Slide

  11. 任意の容量と嘘をつく

    View Slide

  12. ストレージサイズはどう認識される?
    • UMS(USB Mass Storage)クラスではSCSIコマンドを利用する
    • Read Capacity(10)でセクタ数とブロックサイズを提示
    • PCがそこからディスクのサイズを割り出す

    View Slide

  13. Facedancerでの実装
    • ブロックサイズは512バイト固定
    • セクタ数は読み込まれるイメージから算出される
    →ここを変更すれば任意のサイズを宣言できる!
    • ただしコードが全て最大32bit LBA
    • 現状は2TiBまでのディスクしか対応しない
    (GPTであれば認識可能だが)
    • →64bit LBA対応に改造して問題を回避👏
    https://github.com/shutingrz/Facedancer/commit/0fcd48586a1e20b568d6d11d3408c8e854dba1f8

    View Slide

  14. 未初期化状態の罠
    • リムーバブルディスクだと未初期化を未初期化と認識しない
    • →全セクタを走査しパーティションを探してるっぽい?→遅い!!
    • Windowsでのフォーマット時にメタデータを
    全セクタに書き込む→遅い!!
    • 10MBのディスク+FAT32で2分ちょっとかかる
    • Facedancerで偽装する場合は事前にフォーマットしないと無理

    View Slide

  15. 手始めに100GBの仮想ディスクを初期化
    • 以下のコマンドで事前にexFATでフォーマット
    • 問題なく100GBとしてマウントできた
    #100GBのスパースファイルを作成しGPT作成、exFATでフォーマット
    $truncate –s 100GB test.img
    $parted –s test.img mklabel gpt mkpart primary ntfs 1MiB 100%
    print quit
    $sudo losetup –f –show test.img
    $sudo kpartx –a /dev/loop2
    $sudo mkfs.exfat /dev/mapper/loop2p1
    # スクリプト実行
    $./legacy-applets/facedancer-umass.py ./test.img

    View Slide

  16. 調子に乗って2ペタバイト
    !?
    $truncate -s 2PB test.img
    truncate: failed to truncate 'test.img' at
    2000000000000000 bytes: File too large

    View Slide

  17. ext4の制限
    • ext4
    >このファイルシステムは、最初にLinuxカーネル2.6.19でスト
    レージ制限を拡張し、パフォーマンスを向上させるために使用さ
    れていました。 Ext2およびExt3と比較すると、Extファイルシス
    テムは標準の4Kブロックサイズを使用して、最大1EBのボ
    リュームサイズと最大16TBの単一ファイルサイズをサポートで
    きます。

    View Slide

  18. btrfsの中にスパースファイル作成
    • btrfsは16EBの単一ファイルをサポート
    • 10GBのbtrfsイメージを作りその中で2PBのディスクを作成
    • うまくいった
    • あとはいつも通りGPTからのexFATのフォーマット
    $truncate -s 10GB btr.img
    $mkfs.btrfs btr.img
    $sudo mount btr.img /mnt/target1
    $ truncate -s 2PB /mnt/target1/test.img <- いけた!
    $ ls –la /mnt/target1/test.img
    -rw-r--r-- 1 user user 2000000000000000 Jan 25 01:46 <- 2PBのファイル
    /mnt/target1/test.img

    View Slide

  19. 2PBのUSBドライブを見よ!
    • 無事マウントに成功
    • Facedancerの微修正が必要
    • ただしマウント完了まで30分必要
    • 全セクタを読み込むため
    • こういうものなの?
    • 容量偽装はできたので、
    時間かかる2PBは一旦封印

    View Slide

  20. 目標
    • 任意の容量だと嘘をつく
    • 1ペタバイトを目標
    • 書き込めるけど一定のサイズを超えると異常動作を起こす
    • 無視または上書き動作
    💮

    View Slide

  21. 一定のサイズを超えると異常動作を起こす
    • 今はbtrfsの実サイズを超えたら書き込みエラーが発生するはず
    • アググン/イ良い日ン マは書き込み自体はできる
    • イ良い日ン マ実現までの道のり:
    • 4GBのディスクイメージを用意
    • 32GBとみせかける
    • 書き込み要求セクタが4GBより上位の場合は書き込まない
    • 偽装と書き込み無視は全てFacedancer側で対応可能
    • 特定セクタより上の場合はprint()するだけのコードを書いた↓

    View Slide

  22. 試した が・・・
    • 転送速度が遅すぎて検証にならない
    • コントロールがwsl2のためUSB-IPで転送しているのも原因か
    • もっとディスクサイズを減らすことに
    350 KB/s

    View Slide

  23. というわけで見かけ32MBのディスク
    • ディスクイメージは16MB確保
    • 15MB分のセクタを超える場合書き込みを行わないように

    View Slide

  24. テストデータ
    • 1つあたり1.08MBのjpgファイル
    • 14枚目の途中で特定セクタに到達
    する計算

    View Slide

  25. デモ(1)
    • 途中で書き込みされなかった画像ファイル

    View Slide

  26. デモ(2)
    • 事象発生時のログと空き容量

    View Slide

  27. 目標
    • 任意の容量だと嘘をつく
    • 1ペタバイトを目標
    • 書き込めるけど一定のサイズを超えると異常動作を起こす
    • 書き込み無視
    💮
    💮

    View Slide

  28. まとめ
    • あくまでUSBエミュレーションを使ったものだができた
    • イ良い日ン マの作り方を完全に理解した
    • 実際にやるにはちゃんとしたICでのネイティブ実行が必要
    • Pico にUSBコントローラがあるのでTinyUSBライブラリで優勝?

    View Slide

  29. おわり

    View Slide