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

ソフトウェアサイエンス特別講義A リバースエンジニアリング(2024/2/10 5限)

ひろみつ
February 13, 2024
3.8k

ソフトウェアサイエンス特別講義A リバースエンジニアリング(2024/2/10 5限)

ひろみつ

February 13, 2024
Tweet

Transcript

  1. about me 2001年度 第三学群情報学類入学(AC入試第二期) ◦ AC入試の提出資料:PHS用の着メロサイトの運営、MIDI→着メロファイルのコンバータ等 2003年 留年 2004年 休学

    2005年 学生ベンチャー「ニューフォレスター」 スタートアップメンバー なんやかんや 2009年 復学、ようやく卒業 現勤務先:株式会社エーディエス(柏市) ソフトウェア開発、植物工場監視システム 趣味:リバースエンジニアリング関係の同人誌出版、ライター(ラジオライフ)
  2. アンケート#1 Q1 あなたは「リバースエンジニアリング」を ◦ 知っている、他の人になんとなく説明できる ◦ やったことがある ◦ この授業で初めて聞いた Q2

    自分の持っている家電、パソコン、スマホ、オーディオを ◦ 分解したことがある ◦ 分解したことがない
  3. 組み込みネットワーク機器には Linuxがよく使われる ◦ オープンソース ◦ ネットワーク機能 ◦ SoCメーカ、基板開発メーカーがSDKとセットで出している それ以外のものもたまにある ◦

    FreeBSD ◦ iTRON ◦ FreeRTOS ◦ そのほか、ベアメタル(OSレス)等 ・ネットワークルータ ・ポケットWiFi ・ネットワークカメラ ・カラオケ機 ・TV(AndroidTV) ・高級なネットワーク機器 ・Nintendo Switch ・高級なネットワークカメラ ・ ・大変安価なWiFiカメラ
  4. 分解する お手元の基板をご覧ください ◦ SoC(System on Chip)いわゆるCPU Allwinner(台湾) R16 ◦ RAM

    ◦ eMMC (embedded Multi Media Card) いくつかの配線されていないパッド(丸い端子)がある ◦ 配線されていないパッドは、テストパッドなどとも呼ばれて、 開発の段階では使用されていたり、検査のためなどに使われている この中に、「UART」パッドがある
  5. UART端子とPCを接続する • USB-TTL(CMOS) シリアルコンバータ • Amazonで1000円ぐらいで買える • 引き出しに常備しておくといい • 機器の電圧によってはCMOS(3.3V),LVTTL(1.8V)のもの

    • ビットレートは最近の機器なら115200bps、 古いものなら38400や9600 • WindowsならTeraTermがおすすめ Mac、Linuxなら • > screen /dev/ttu.usbxxx 115200
  6. U-bootのソースコードを見てみる • s を押しながら電源を入れると デバッグモード(CUI)に入れる • これ以外の機器も似たような動きを するものが多い(キーは違う) mbr not

    exist base bootcmd=sunxi_flash phy_read 43800000 30 20;boota 43800000 bootcmd set setargs_nand key 0 cant find rcvy value cant find fstbt value no misc partition is found to be run cmd=sunxi_flash phy_read 43800000 30 20;boota 43800000 WORK_MODE_BOOT board_status_probe [ 0.580]key trigger [ 0.582]Hit any key to stop autoboot: 0 clover#
  7. Linuxの起動パラメータを変更する U-Bootのデバッグシェルではいろいろなコマンドが使える setenv (環境変数の設定) で cmdline 変数を書き換えると Linuxの起動パラメータが変更できる ◦ →起動するプログラムや挙動を無理やり変更できる

    ◦ カーネルコンパイルオプションで無効化することもある 起動パラメータに init=/bin/sh を付けると ◦ 本来呼び出されるinitプログラムの代わりに、単純シェルが起動して パスワードなどが不要な最小限のCUIが手に入ってしまう シェルとしての実体は「busybox」という実行ファイル
  8. ファームウェアが取り出せたら 中身を解析する ◦ ブートローダ ◦ 環境変数 ◦ Linuxカーネル ◦ ルートファイルシステム

    ◦ アプリ、データ ◦ binwalkコマンドが便利。binwalkでファイルシステムのオフセットを確定したら、 ◦ mountコマンドでマウントできる(こともある) アプリを逆コンパイルして調べる
  9. よく使うコマンド binwalk / file ・file <filename> ・binwalk <filename> ◦ -e

    オプション:判別されたデータブロックをファイル化する ◦ -eM : 上記でファイル化された中身も再帰的にファイル化する ◦ -E:エントロピーエッジの抽出 ◦ 暗号化領域は、特に格納されたデータのエントロピー(ランダム率)が高くなる なんでわかるか?「マジックバイト」を見る 慣れればhexdumpすればすぐわかるようになる
  10. 先頭部分とfileコマンドの出力例 PE32 executable (console) Intel 80386, for MS Windows JPEG

    image data, JFIF standard 1.01, resolution (DPCM), density 56x56, segment length 16, baseline, precision 8, 349x489, frames 3
  11. コンパイルと逆コンパイル 人間が読める CPUが実行する int check(){ time_t timer; struct tm* local;

    int year; timer = time(NULL); local = localtime(&timer); year = local->tm_year + 1900; if (year > 2023) return 1; return 0; } ソースコード(C言語) アセンブリリスト オブジェクトコード 実行可能ファイル MOV dword ptr [EBP + local_10],EAX MOV dword ptr [EBP + local_c],EDX LEA EAX=>local_10,[EBP + -0xc] PUSH EAX CALL localtime ADD ESP,0x4 MOV dword ptr [EBP + local_14],EAX MOV ECX,dword ptr [EBP + local_14] MOV EDX,dword ptr [ECX + 0x14] ADD EDX,0x76c 4D F0 8B 51 14 81 C2 6C 07 00 00 89 55 EC 81 7D EC E7 07 00 00 7E 07 B8 01 00 00 00 EB 02 33 C0 8B 4D FC 33 CD E8 34 00 00 00 8B E5 5D C3 CC CC 55 8B EC E8 98 FF FF FF 85 C0 74 10 68 24 30 40 00 FF 15 B8 20 40 00 83 C4 04 EB 0E 68 18 30 40 00 FF 15 B8 20 40 00 83 C4 04 33 C0 5D C3 3B 0D 04 30 40 00 75 01 C3 E9 79 02 00 00 56 6A 01 E8 4D F0 8B 51 14 81 C2 6C 07 00 00 89 55 EC 81 7D EC E7 07 00 00 7E 07 B8 01 00 00 00 EB 02 33 C0 8B 4D FC 33 CD E8 34 00 00 00 8B E5 5D C3 CC CC 55 8B EC E8 98 FF FF FF 85 C0 74 10 68 24 30 40 00 FF 15 B8 20 40 00 83 C4 04 EB 0E 68 18 30 40 00 FF 15 B8 20 40 00 83 C4 04 33 C0 5D C3 3B 0D 04 30 40 00 75 01 C3 E9 79 02 00 00 56 6A 01 E8 Cスタートアップコード ヘッダ等(MZ,ELF,….) 外部ライブラリへの参照 コンパイル 逆コンパイル Linux ELFファイルなら readelf –a <実行ファイル> で情報を見れる
  12. 完全に元には戻らないけども int __cdecl check(void) { tm *ptVar1; uint uVar2; undefined8

    local_10; local_10 = time((time_t *)0x0); ptVar1 = localtime(&local_10); uVar2 = (uint)(0x7e7 < ptVar1->tm_year + 0x76c); return uVar2; } int check(){ time_t timer; struct tm* local; int year; timer = time(NULL); local = localtime(&timer); year = local->tm_year + 1900; if (year > 2023) return 1; return 0; } 元のソースコード 逆コンパイルされたコード 2024年になると実行できなくなるソフトウェアに含まれそうなソースコードの例 4D F0 8B 51 14 81 C2 6C 07 00 00 89 55 EC 81 7D EC E7 07 00 00 7E 07 B8 01 00 00 00 EB 02 33 C0 8B 4D FC 33 CD E8 34 00 00 00 8B E5 5D C3 CC CC 55 8B EC E8 98 FF FF FF 85 C0 74 10 68 24 30 40 00 FF 15 B8 20 40 00 83 C4 04 EB 0E 68 18 30 40 00 FF 15 B8 20 40 00 83 C4 04 33 C0 5D C3 3B 0D 04 30 40 00 75 01 C3 E9 79 02 00 00 56 6A 01 E8
  13. 逆コンパイル結果をもとに ソースコードを見ながら動作と突き合わせて仕組みを解析する 逆アセンブルリストをもとに、機械語命令を変更することができる 0040105a 89 45 f4 MOV dword ptr

    [EBP + local_10],EAX 0040105d 89 55 f8 MOV dword ptr [EBP + local_c],EDX 00401060 8d 45 f4 LEA EAX=>local_10,[EBP + -0xc] 00401063 50 PUSH EAX 00401064 e8 97 ff CALL localtime tm * localtime(time_t * _Time) ff ff 00401069 83 c4 04 ADD ESP,0x4 0040106c 89 45 f0 MOV dword ptr [EBP + local_14],EAX 0040106f 8b 4d f0 MOV ECX,dword ptr [EBP + local_14] 00401072 8b 51 14 MOV EDX,dword ptr [ECX + 0x14] 00401075 81 c2 6c ADD EDX,0x76c 07 00 00 0040107b 89 55 ec MOV dword ptr [EBP + local_18],EDX 0040107e 81 7d ec CMP dword ptr [EBP + local_18],0x7e7 e7 07 00 00 00401085 7e 07 JLE LAB_0040108e 00401087 b8 01 00 MOV EAX,0x1 00 00 0040108c eb 02 JMP LAB_00401090 LAB_0040108e XREF[1]: 00401085(j) 0040108e 33 c0 XOR EAX,EAX LAB_00401090 XREF[1]: 0040108c(j) 00401090 8b 4d fc MOV ECX,dword ptr [EBP + local_8] 00401093 33 cd XOR ECX,EBP EAX:関数の戻り値を入れるレジスタ
  14. バイナリコードを変更すれば 当然動作も変わる アーキテクチャによっては命令長が変わるため、工夫が必要 ◦ NOPで埋める、etc アーキテクチャとは ◦ x86 :一般的なPC ◦

    ARM:組み込み向け、Androidスマホ ◦ MIPS:組み込み向け ◦ などなど 開発製品のソースコードを失った際の最後の手段 対策 アプリのハッシュなどを別途保存して 改ざんされていないかなどをチェックする コード署名の機能などを使う
  15. ほかの実例:ATOMCam 3000円ぐらいで買えるWiFiカメラ ◦ リアルタイム動画を見るためには メーカー純正の専用アプリが必要 ◦ メーカのAWSサーバを中継しているため ◦ アプリがスマホでしか動かない ◦

    SDカードの内容をコピーするのが不便:アプリの使い勝手が悪い アプリに割り込んで画像を横取りするルーチンを作る ◦ リアルタイム画像H264ストリームとしてローカルLANに自由に配信できる ◦ FTPサーバ機能を付けて、SDカードに自由にアクセスできるように ◦ SSHでshellコマンドを実行可能
  16. 実装方法:LD_PRELOADを使う 自作プログラム (libcallback.so) イメージ センサ メーカー製アプリ SoCメーカー製 SDK コールバック登録 画像が届いたら呼び出して

    Func set_encode_frame_callback(*pFunc) LD_PRELOAD=libcallback.so を付けてアプリを起動すると ライブラリの検索優先順を変更できる カメラ atomcam_toolsという名前で GitHubに公開されている set_encode_frame_callback(*pFunc)