Share
Embed
ソフトウェアサイエンス特別講義A リバースエンジニアリング(2024/2/10 5限)
ひろみつ
February 13, 2024
Transcript
53 slides
-
about me 2001年度 第三学群情報学類入学(AC入試第二期) ◦ AC入試の提出資料:PHS用の着メロサイトの運営、MIDI→着メロファイルのコンバータ等 2003年 留年 2004年 休学
2005年 学生ベンチャー「ニューフォレスター」 スタートアップメンバー なんやかんや 2009年 復学、ようやく卒業 現勤務先:株式会社エーディエス(柏市) ソフトウェア開発、植物工場監視システム 趣味:リバースエンジニアリング関係の同人誌出版、ライター(ラジオライフ) -
アンケート#1 Q1 あなたは「リバースエンジニアリング」を ◦ 知っている、他の人になんとなく説明できる ◦ やったことがある ◦ この授業で初めて聞いた Q2
自分の持っている家電、パソコン、スマホ、オーディオを ◦ 分解したことがある ◦ 分解したことがない -
リバースエンジニアリングとは 成果物(製品)から技術を推測すること ◦ 観察:本体をブラックボックスとして入出力を観察する ◦ 必要に応じて、不適合入力を与えてエラーを調べる ◦ 分解 ◦ 装置を分解して、構造から仕組みを調べる
◦ 基板から部品を取り外して回路図を書く ◦ ソフトウェアの分析 ◦ ファームウェアを解析する ◦ 逆コンパイル、逆アセンブル -
アンダーグラウンドなイメージがある? ・法律上、禁止されていない ・「分解禁止」→あくまでもメーカサポートの対象の話 ・個人の所有物なので自由である ◦ 他人に迷惑をかけないことは必要 ◦ 電波法→分解することで、認証の基準から外れることがある ◦ 電安法(PSE)→認証時の状態と違うものを販売してはいけない
・禁止行為:リバースエンジニアリングしたものをそのまま使う→著作権法 ・秘密の流出・損害を与えてはいけない→損害賠償 -
Open Source Software 略してOSS ・オープンソース = ソースコードが公開されている ・ソースコードがオープンだからって好き勝手していいわけではない ・いくつかのライセンスパターンがある ◦
GPL、LGPL ーー越えられない壁ーー ◦ MIT ◦ Apache ◦ BSD ◦ などなど -
組み込みネットワーク機器には Linuxがよく使われる ◦ オープンソース ◦ ネットワーク機能 ◦ SoCメーカ、基板開発メーカーがSDKとセットで出している それ以外のものもたまにある ◦
FreeBSD ◦ iTRON ◦ FreeRTOS ◦ そのほか、ベアメタル(OSレス)等 ・ネットワークルータ ・ポケットWiFi ・ネットワークカメラ ・カラオケ機 ・TV(AndroidTV) ・高級なネットワーク機器 ・Nintendo Switch ・高級なネットワークカメラ ・ ・大変安価なWiFiカメラ -
GPLだけ別格 ・GPLのソースコードを使用した製品を頒布した場合、頒布された者がソースコードを請求した 場合、開示しなければならない(ざっくり) ・GPLと関係ない部分は開示しなくていい ・開示したくない部分は静的リンクしないように工夫する必要がある ・LinuxはGPL ◦ 製品のOSとしてLinuxを使用(多くの場合、それぞれのCPUや基板に合わせてカスタムする必要がある ため、ソースコードに変更が加えられることがほとんど)した場合、製品を買った人は、そのソースコー ドを請求できる
・Linux以外のいろいろなOSSが組み込み機器の中に使われている ◦ 権利者表記をいろいろなところで見ることができる ◦ アプリのメニュー、取扱説明書の後ろの方 -
リバースエンジニアリングのススメ ・Linuxなど、OSSに関する部分は堂々とメーカーにソースコードを請求して、 本体を使ってあれこれいじって遊ぶことができるし、 成果物を発表することもできる ・組み込み機器開発についてよく学ぶことができる ・それ以外の部分もこっそりやって技術を身に付ける分にはまぁ問題ない ・是非やってみよう ◦ 学校ではあまり教えてくれない ◦
既刊同人誌の電子データを学習用に提供します ・仕事にはならない ◦ セキュリティ会社ならワンチャン -
分解する お手元の基板をご覧ください ◦ SoC(System on Chip)いわゆるCPU Allwinner(台湾) R16 ◦ RAM
◦ eMMC (embedded Multi Media Card) いくつかの配線されていないパッド(丸い端子)がある ◦ 配線されていないパッドは、テストパッドなどとも呼ばれて、 開発の段階では使用されていたり、検査のためなどに使われている この中に、「UART」パッドがある -
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 -
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# -
Linuxの起動パラメータを変更する U-Bootのデバッグシェルではいろいろなコマンドが使える setenv (環境変数の設定) で cmdline 変数を書き換えると Linuxの起動パラメータが変更できる ◦ →起動するプログラムや挙動を無理やり変更できる
◦ カーネルコンパイルオプションで無効化することもある 起動パラメータに init=/bin/sh を付けると ◦ 本来呼び出されるinitプログラムの代わりに、単純シェルが起動して パスワードなどが不要な最小限のCUIが手に入ってしまう シェルとしての実体は「busybox」という実行ファイル -
ファームウェアが取り出せたら 中身を解析する ◦ ブートローダ ◦ 環境変数 ◦ Linuxカーネル ◦ ルートファイルシステム
◦ アプリ、データ ◦ binwalkコマンドが便利。binwalkでファイルシステムのオフセットを確定したら、 ◦ mountコマンドでマウントできる(こともある) アプリを逆コンパイルして調べる -
よく使うコマンド binwalk / file ・file <filename> ・binwalk <filename> ◦ -e
オプション:判別されたデータブロックをファイル化する ◦ -eM : 上記でファイル化された中身も再帰的にファイル化する ◦ -E:エントロピーエッジの抽出 ◦ 暗号化領域は、特に格納されたデータのエントロピー(ランダム率)が高くなる なんでわかるか?「マジックバイト」を見る 慣れればhexdumpすればすぐわかるようになる -
先頭部分と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 -
特殊な対策の例 HDDのパーティションテーブルのマジック番号を書き換えてある ◦ 中身はExt3だけど、そこだけ変わっていてマウントできない ◦ 見つけるには経験と勘 一般的なファイルシステムを使わず、独自の構造体を使っている ◦ アプリを解析する必要がある ◦
勘で 単純な暗号化 ◦ XOR:テーブルを探したり、逆コンパイルしたりする、 ガチガチの暗号化 ◦ 証明書ストアや秘密領域を使って全然読めなくなっている -
バイナリエディタ 普通のエディタでバイナリファイルを開いても、文字化けしか見えない お勧め3選 ・Stirling ◦ 国産バイナリエディタ ・Hex Workshop ◦ 多機能、巨大ファイル編集可能
・ImHex ◦ 構造体定義機能 ◦ マルチプラットフォーム -
コンパイルと逆コンパイル 人間が読める 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 <実行ファイル> で情報を見れる -
完全に元には戻らないけども 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 -
逆コンパイル結果をもとに ソースコードを見ながら動作と突き合わせて仕組みを解析する 逆アセンブルリストをもとに、機械語命令を変更することができる 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:関数の戻り値を入れるレジスタ -
バイナリコードを変更すれば 当然動作も変わる アーキテクチャによっては命令長が変わるため、工夫が必要 ◦ NOPで埋める、etc アーキテクチャとは ◦ x86 :一般的なPC ◦
ARM:組み込み向け、Androidスマホ ◦ MIPS:組み込み向け ◦ などなど 開発製品のソースコードを失った際の最後の手段 対策 アプリのハッシュなどを別途保存して 改ざんされていないかなどをチェックする コード署名の機能などを使う -
ほかの実例:ATOMCam 3000円ぐらいで買えるWiFiカメラ ◦ リアルタイム動画を見るためには メーカー純正の専用アプリが必要 ◦ メーカのAWSサーバを中継しているため ◦ アプリがスマホでしか動かない ◦
SDカードの内容をコピーするのが不便:アプリの使い勝手が悪い アプリに割り込んで画像を横取りするルーチンを作る ◦ リアルタイム画像H264ストリームとしてローカルLANに自由に配信できる ◦ FTPサーバ機能を付けて、SDカードに自由にアクセスできるように ◦ SSHでshellコマンドを実行可能 -
ルーチンを作るといっても ・もともと販売されているカメラのアプリのソースコードはない ・SoCメーカのSDKとカメラのアプリの2つに分かれている ◦ SDKはNDA付きで機器メーカに渡されている ◦ 結構たくさん生産されているものなので、どうしても漏れる ◦ 漏れた資料が、海外の有料会員制サイトなどにアップロードされていることがある ◦
登録する際はクレジットカード情報を抜かれないように注意しよう ◦ Paypal経由が安心 ・SDKの資料を手に入れた ・アプリを逆アセンブルして資料の補完とした -
実装方法:LD_PRELOADを使う 自作プログラム (libcallback.so) イメージ センサ メーカー製アプリ SoCメーカー製 SDK コールバック登録 画像が届いたら呼び出して
Func set_encode_frame_callback(*pFunc) LD_PRELOAD=libcallback.so を付けてアプリを起動すると ライブラリの検索優先順を変更できる カメラ atomcam_toolsという名前で GitHubに公開されている set_encode_frame_callback(*pFunc) -
そんな改造していいの? ・起動方法として、メーカが明示していない、u-boot内の開発用の 機能「microSD内に”factory_t31_ZMC6tiIDQN”というファイルがあれ ば、それを読み込んで起動する」という方法を使っている ◦ OSSのソースコードとして公開されているので公知のことではある ◦ メーカが対策することも可能 ・「atomcam_tools」はメーカの方でも認知している ◦
「対策する予定はない」 ・たまたま、メーカとハッカーの関係性によりそうなっている ◦ これを、「改造ATOMCamです」とか言って売ったら、たぶん怒られる -
追加のテクニック Linuxのシェルにログインするパスワードがわからない場合 ◦ init=/bin/sh で限定シェルに入る、ファームウェアを吸い出す ◦ /etc/passwdを書き換える • root:のあとがxの場合:削除してしまう •
短いハッシュが書かれていた場合: • 「HashCat」などのソフトで解析する