CTF Binary » 履歴 » リビジョン 3
リビジョン 2 (kanata, 2025/04/13 14:33) → リビジョン 3/5 (kanata, 2025/05/10 09:23)
# CTF Binary {{last_updated_at}} {{>toc}} {{toc}} # Command gadgets - Binary解析 file string nm ldd ## vi バイナリ編集 ``` vi -b $1 :%!xxd :%!xxd -r ``` ## hexdump C付けないとよくわかんないことになる ``` hexdump -v -C ``` ## hexedit - Ctrl-xで保存・終了 - Ctrl-cで終了 ## od 16進数ダンプ ``` od -Ax -tx1z -v od -txCa ``` ## stringsで出力した文字を横並びで表示する ``` strings file |tr '\n' '\t'|fold -w 80 strings file |grep -v "\W"|tr '\n' '\t'|fold -w 80 strings file |sort|uniq|tr '\n' '\t'|fold -w 80 strings file |grep -v "\W"|sort|uniq|tr '\n' '\t'|fold -w 80 ``` ## readelf とりあえず-aオプションをつけとけばいい。 ~~~ readelf -a ~~~ ## objdump ~~~ objdump -d objdump -d -M intel binary_file > out.asm ~~~ >-M intel はintel記法で出力の意味 # gdb ## よく使うコマンド ディスアセンブルする。なんとなく、if文とかの場所がわかる。 ``` disassemble main ``` そこにブレークポイントを設定する。 ``` b *0x000000000040059e b *0x40059e ``` そこまで進める ``` run ``` 値を出力して確認してみる ``` x/1s $esi x/1s 0x4005a3 ``` 固定値が格納されているスタックの始まりのアドレスがわかったら、こんな感じで全部出力できる。(x/sは文字列の出力) ``` x/100s 0x400666 ``` int型だったりすると、よくわかんないから16進数表現にすればいい。 ``` x/100x 0x400666 ``` 任意の関数も呼べます ``` 0x00000000004010df: call 0x4006b6 ``` だったら、 ``` set $pc=0x4006b6 c ``` 引数に$pcを指定すれば、直後に実行される命令列が見れる。 ``` x/10i $pc ``` 常にアセンブラとレジスタの値を表示しておくこともできる。ほとんどolly dbg ``` layout asm layout reg ``` ---- フラグレジスタ 条件ジャンプとフラグ http://wisdom.sakura.ne.jp/programming/asm/assembly13.html |フラグレジスタの内訳|意味 | |--------------------|-----------------| |ビット 11 (OF) |オーバーフロー発生 | |ビット 10 (DF) | ストリング命令の方向を指定するフラグ |ビット 7 (SF) | 演算結果が負 | |ビット 6 (ZF) | 演算結果がゼロ | |ビット 2 (PF) | 演算結果の奇数パリティ (1 が偶数個のときに立つ) | |ビット 0 (CF) | キャリー発生 / ボロー発生 | なんだけど、リトルエンディアンなので、実際にはひっくり返ってる。 eflagsとかで表現されるが、setする時は$psになる。 状態表示 ``` (gdb) i r 中略 eflags 0x202 [ IF ] ``` 設定 ``` set $ps=0x242 ``` ## オリジナルな.gdb.init ``` set disassembly-flavor intel set follow-fork-mode child set history save on set history filename ~/.gdb_history set history size 32768 set history expansion on define xall i r eip esp ebp eax x/5i $eip x/32xw $esp end document xall Stack and disas helper end define xenv x/20s *environ end document xenv Print the environment variables from the stack end ``` 出力例 ``` (gdb) xall eip 0x80484d5 0x80484d5 esp 0xffffd290 0xffffd290 ebp 0xffffd2c8 0xffffd2c8 eax 0xffffd2a0 -11616 => 0x80484d5: call 0x8048350 <read@plt> 0x80484da: lea eax,[ebp-0x28] 0x80484dd: mov DWORD PTR [esp],eax 0xffffd290: 0x00000000 0xffffd2a0 0x00000032 0x08048319 0xffffd2a0: 0xffffd516 0x0000002f 0x0804a000 0x08048562 0xffffd2b0: 0x00000001 0xffffd374 0xffffd37c 0xf7e3b42d (gdb) xenv 0xffffd52b: "XDG_VTNR=7" 0xffffd536: "XDG_SESSION_ID=c2" 0xffffd5b2: "SHELL=/bin/bash" ``` ## gdb scriptの利用 打ち込みたいコマンドをメモしておいて,gdb起動と併せて実行できる。 ``` $ gdb –q –x scriptfile ./binary ``` ## アセンブラプログラムのデバックの方法 http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/kikaigo2008/gdb.pdf アセンブラプログラムのデバックは、gdb(gnu debugger)を使って行うことができます。 ブレークポイントの設定と実行開始 課題のプログラムは main から始まるので、まず、ここで停止するように、break コマンドでmain にブレークポイントを設定します。(gdb)とプロンプトがでるので、ここで、 ``` (gdb) break main ``` と入力します。次に、run コマンドmain まで実行します。 ``` (gdb) run ``` すると、実行が始まり、main で停止するはずです。 プログラムのdisassembleここで、プログラムがどのようなコードになっているかについて、確認してみましょう。メモリ上の機械語になったプログラムをアセンブリプログラムで表示するのがdisassemble コマンドです。 disassemble とは、アセンブルの反対、つまり、機械語からアセンブラに直すことです。main から始まるプログラムをdisassemble してみましょう。 ``` (gdb) disassemble main ``` main のところに、任意のラベル名を書くことでそのプログラムをdisassemble することができます。 プログラムのステップ実行1命令づつ実行するコマンドが、stepi です。 ``` (gdb) stepi ``` ここで、stepi コマンドを実行するごとに1命令づつ実行されているのがわかるはずです。 レジスタの表示step 実行している途中で、レジスタの表示をして見ましょう。表示には2つの方法があります。 ``` (gdb) info registers ``` では、すべてのレジスタの表示を行います。個別のレジスタを表示する場合には、 ``` (gdb) print $レジスタ名 ``` で表示させることができます。 実行の再開、ブレークポイントの設定continue コマンドは実行を次のブレークポイントまで(もしくは終わりまで)、実行を再開するコマン ドです。 ``` (gdb) continue ``` さて、main にブレークポイントを設定しましたが、main の代わりにラベル名を書くことで、そのラベルの前で実行を止めることができます。また、アドレスを指定したい場合には ``` (gdb) break *アドレス ``` で任意のアドレスで実行を中断することができます。 データの表示 データの表示を行うコマンドが x コマンドです。 ``` (gdb) x アドレス ``` で、アドレスの内容をプリントすることができます。x のあとには、データ表示のフォーマットができて、例えば、x/のあとに、表示するデータの数、10 進(d)、16進(x)、8進(o)とそのあとに、b(byte), h(half), w(word)と指定します。たとえば、 ``` (gdb) x/10dw 0x10000 ``` では、0x10000 番地から、32 ビットごと(w)に10進(d)で、10ワード表示するという意味になります。詳しくは、help x としてみてください。他のコマンドについても、help コマンドで調べることができます。 ``` (gdb) x/1s $esi 0x804c757: "visilooksgoodinhotpants" ``` で、レジスタの指し先が出力されます。 ## gdb参考 ももいろテクノロジー - gdbの使い方のメモ http://inaz2.hatenablog.com/entry/2014/05/03/044943 gdbについて http://tech-hack-maswag.blogspot.jp/2013/03/gdb.html?m=1 オンラインgdb https://www.onlinegdb.com/ epasveer/seer https://github.com/epasveer/seer >Qt実装のgdbのGUIフロントエンド # 最低限これだけ覚えておけばきっと解析できる命令 よく使うASM命令ベスト100位に説明つけてみた http://wiki.onakasuita.org/pukiwiki/?%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86ASM%E5%91%BD%E4%BB%A4%E3%83%99%E3%82%B9%E3%83%88100%E4%BD%8D%E3%81%AB%E8%AA%AC%E6%98%8E%E3%81%A4%E3%81%91%E3%81%A6%E3%81%BF%E3%81%9F # CPU architecture x86 >ハンド (逆) アセンブルを補助するための PDF リスト! http://d.hatena.ne.jp/a4lg/20120225/1330180431 http://dl.dropbox.com/u/2476414/TechResources/x86_opcodemap_1_a4.pdf >コンピュータアーキテクチャ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n4.pdf >0F拡張チートシート http://shiho-elliptic.tumblr.com/post/108012619924/0f http://elliptic-shiho.xyz/0F%20Opcode.pdf ARM >[組み込み]ARMの場合、アセンブラが解れば機械語も解るCommentsAdd Star http://d.hatena.ne.jp/kmt-t/20091105/1257380555 http://re-eject.gbadev.org/files/armref.pdf 機械語命令が ?? ?? ?? e? (リトルエンディアンなので、本当は 0xe? が先頭)になっているので、判別しやすい。 SPARC >AWKによるSPARC V8逆アセンブラ http://keisanki.at.webry.info/201001/article_2.html PowerPC >玄箱でアセンブリ 1 - はじめに http://www.mztn.org/ppcasm/ppcasm01.html http://www.freescale.com/files/32bit/doc/ref_manual/MPC603EUM.pdf http://www.freescale.com/files/32bit/doc/ref_manual/G2CORERM.pdf >Cell Broadband Engine アーキテクチャ http://cell.scei.co.jp/pdf/CBE_Architecture_v102_j.pdf >アセンブリ言語、はじめの一歩 http://www.comp.tmu.ac.jp/morbier/comparch/assem1new.html http://www.comp.tmu.ac.jp/morbier/comparch/6xx_pemchap8.pdf MIPS >コンピュータアーキテクチャ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n3.pdf >はじめて読むMIPS(リローデッド) http://www.cqpub.co.jp/interface/TechI/Vol39/app/mips_asm.pdf >MIPS I の命令形式 http://www.weblio.jp/wkpja/content/MIPS%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3_MIPS+I+%E3%81%AE%E5%91%BD%E4%BB%A4%E5%BD%A2%E5%BC%8F MMX >0から作るソフトウェア開発(をgoogle先生の検索で調べる) https://www.google.co.jp/search?hl=ja&as_qdr=y15&lr=lang_ja&num=100&q=site:softwaretechnique.jp%200x0F&gws_rd=ssl Z80 >8ビット CPU Z80命令セット http://www.yamamo10.jp/yamamoto/comp/Z80/instructions/index.php # x86 ## x86 - 解説 神解説 x86-64機械語入門 https://zenn.dev/mod_poppo/articles/x86-64-machine-code トリコロールな猫 - OllyDbgを使ってx86アセンブラを学ぶシリーズ https://note.mu/nekotricolor GNU/Linux (x86/x86-64) のシステムコールをアセンブラから呼んでみる https://blog.amedama.jp/entry/linux-system-call-assembler Linux システムコール 徹底入門 https://www.kimullaa.com/entry/2020/01/05/191221 x86-64 Assembly入門 https://speakerdeck.com/latte72/x86-64-assembly-essentials --- 神無料サンプル 31バイトでつくるアセンブラプログラミング: アセンブラ短歌の世界 https://play.google.com/store/books/details/%E5%9D%82%E4%BA%95%E5%BC%98%E4%BA%AE_31%E3%83%90%E3%82%A4%E3%83%88%E3%81%A7%E3%81%A4%E3%81%8F%E3%82%8B%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0?id=6aqYAgAAQBAJ&hl=ja > Google Play の無料サンプルが、ちょうどいい感じの所まで読める。 --- 神チートシート d.sunnyone.org - x86/x86_64関数呼び出しチートシートを書いた http://d.sunnyone.org/2012/09/x86x8664.html Windows X86 System Call Table (NT/2000/XP/2003/Vista/2008/7/8/10) http://j00ru.vexillium.org/syscalls/nt/32/ 解答略 @kaitou_ryaku x86の機械語をざっと見渡すには、このpdfが世界で一番整理されてると思う。 https://twitter.com/kaitou_ryaku/status/1067424249814540288 ハンド (逆) アセンブルのための x86 ニーモニックの覚え方 http://d.hatena.ne.jp/a4lg/20120225/1330180431 X86 Opcode and Instruction Reference http://ref.x86asm.net/coder64.html ## レジスタ一覧 X86アセンブラ/x86アーキテクチャ http://ja.wikibooks.org/wiki/X86%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9/x86%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3 X86_64のレジスタ http://www.mztn.org/lxasm64/amd04.html ## レジスタ | レジスタ | ビット | |----------|--------| | eax | 000 | | ecx | 001 | | edx | 010 | | ebx | 011 | | esp | 100 | | ebp | 101 | | esi | 110 | | edi | 111 | ## 基本の命令の形 http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n4.pdf 複雑 レジスタ=レジスタ+即値 | 8 | 2 | 3 | 3 | 8 | |------|-----------------------|----------|----------|------| | 命令 | reg or 即値フラグ(11) | レジスタ | 000 | 即値 | | 8 | 2 | 3 | 3 | 32 | |------|-----------------------|----------|----------|------| | 命令 | reg or 即値フラグ(11) | レジスタ | 000 | 即値 | | 8 | 32 | |------|------| | 命令 | 即値 | レジスタ=レジスタ+レジスタ | 8 | 2 | 3 | 3 | |------|-----------------------|----------|----------| | 命令 | reg or 即値フラグ(11) | レジスタ | レジスタ | レジスタ=レジスタ+主記憶 ややこしいので略(pdf参照) ## よく使う命令 https://dl.dropboxusercontent.com/u/2476414/TechResources/x86_opcodemap_1_a4.pdf | 命令 | OP | Note | |------|--------|------| | mov | b or 8 | | push | 5[0-7] or 68 or 6A | | pop | 5[8-F] | | add | 0[0-5] | | xor | 3[0-5] | | nop | 90 | | int | cd | | ret | c3 | システムコール >%EAXにシステムコール番号を入れて int 0x80 する。必要な引数は、%EBX %ECX %EDX に入れたりする。 >writeシステムコールの戻り値は、%EAXに入る(文字数が入る) 関数復帰 >ABIで決められているが、%EBX %ESP は、関数呼び出し前の値に戻して置かなければいけない。 >ret前に%EAXには関数の復帰値を入れる必要がある ## 様々な代入法 movで即値(5byte) ``` mov $0x1 %eax ``` xorで初期化後に、レジスタ下位バイト(8bit)代入(2Byte+2Byte) ``` xor %eax %eax mov %al ``` スタックにpushしてpop(2byte+1byte) ``` push $8 pop %eax ``` ## アセンブラ短歌 簡単なのは、ここで試せる(JavaScriptエミュレーション方式) http://07c00.com/asmtanka_on_js/ SECCON - Assembly Tanka on Web ちょと込み入ってても、こっちでも試せる(SandBox方式) http://x86.seccon.jp/99.html x86でwriteシステムコールにより、文字を出力する方法 - %EAXに4(writeシステムコールの意味)を設定 - %EBXに1(標準出力の意味)を設定 - %ECXに表示する文字の先頭アドレスを設定 - %EDXに出力する文字の長さを設定 - int 0x80(システムコール)を実行 その後 - %EAXにはwriteした文字数が設定される - retする前に%EAXには関数復帰値を設定する - %EBXは関数呼び出し前の値を保証するようABIに定められている。つまり、%EBXの値は元に戻す必要がある。 # クロスコンパイル/実行環境 ## Article 七誌の開発日記 - 全部入りbinutils http://7shi.hateblo.jp/entry/2013/07/30/011348 ももいろテクノロジー - x86/x86-64/ARM/AArch64/PowerPC/PowerPC64のアセンブリコードを読んでみる http://inaz2.hatenablog.com/entry/2015/11/21/182410 gotbolt - C → 様々なASMのリアルタイムオンラインコンパイラー。アセンブリ・REを勉強している方におすすめ https://godbolt.org/ GitHub - shutingrz/busybox-static-binaries-fat https://github.com/shutingrz/busybox-static-binaries-fat ## gdb kozosより [cross-gcc4-20130826.zip をインストール済みのCentOS6.5イメージ (OVAフォーマット)](http://kozos.jp/vmimage/burning-asm.html) [FreeBSDのVirtualBox用イメージを,OVAフォーマットにしたもの](http://kozos.jp/vmimage/) ### Memo ももいろテクノロジー - 各種アーキテクチャのクロスコンパイラ環境を構築する http://inaz2.hatenablog.com/entry/2015/12/01/204201 ## QEMU ### Memo 組み込みの人 - Aarch64で遊ぶ最も手軽な方法 http://d.hatena.ne.jp/embedded/20140819/p1 > dockerからのqemu katagaitai CTF勉強会|hard https://atnd.org/events/71808 > [fon.tar.gz](https://github.com/ctfs/write-ups-2014/blob/master/31c3-ctf-2014/pwn/nokia-1337/fon.tar.gz?raw=true)が、QEMU環境 > 動的解析できる別の ARM環境[このリンク先](http://pastebin.com/S9ssvy11)に手順を用意しています ももいろテクノロジー - qemu-debootstrapを使ってユーザモードQEMUで動くDockerイメージを作ってみる http://inaz2.hatenablog.com/entry/2015/11/26/220948 # Androidアプリの逆コンパイル メモ * [dex2jar](http://sourceforge.net/projects/dex2jar/) デコンパイラ * jd-gui ソースを読む * [apktool](http://ibotpeaches.github.io/Apktool/) リバースエンジニアリングツール BYTECODE VIEWER (AN ADVANCED YET USER FRIENDLY JAVA REVERSE ENGINEERING SUITE.) http://bytecodeviewer.com/ 改造apk(MOD)の作り方 & その対策 - Qiita https://qiita.com/yukiarrr/items/764adb88f5a485f714d8 1,000行で作るオペレーティングシステム https://seiya.me/blog/operating-system-in-1000-lines # .NETの逆コンパイル メモ ILSpy http://ilspy.net/ dnSpy https://github.com/0xd4d/dnSpy/releases/tag/v5.0.0 [凄すぎて大草原不可避な.NET デコンパイラdnSpyを使ってみる](https://qiita.com/NetSeed/items/54fbf30cb21c77c05c41) Reflexil http://reflexil.net/ # Javaバイトコード 知らなくても困らない Javaクラスのバイトコードの読み方 http://etc9.hatenablog.com/entry/2017/11/02/231509 # WebAssembly WebAssembly所感 https://zenn.dev/qnighy/articles/de8784dfeacde9 # Misc コンピュータアーキテクチャ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/ Hexinator というCTFのために生まれてきたようなバイナリエディタ https://hexinator.com/ POSTD - システムコールを経由する生のLinuxスレッド http://postd.cc/raw-linux-threads-via-system-calls/ Programming Field - スタック http://pf-j.sakura.ne.jp/program/stack.htm POSTD - Linuxシステムコール徹底ガイド http://postd.cc/the-definitive-guide-to-linux-system-calls/ 組み込みの人。 - gdbで標準ライブラリの中を探検する http://d.hatena.ne.jp/embedded/20130120/p1 ニコナレ - 機械学習を支えるx86-64の拡張命令セットを読む会 http://niconare.nicovideo.jp/watch/kn2333 C言語の文字列はどこに?-ELFバイナリに見る実行プログラムの挙動- https://drumato.hatenablog.com/entry/2019/05/03/111608 オブジェクトファイルのシンボルテーブルを最低限理解する。 https://drumato.hatenablog.com/entry/2019/05/16/201234 strace コマンドの使い方をまとめてみた http://blog.livedoor.jp/sonots/archives/18193659.html 定番のデバッグ・調査ツールであるstraceでエラーインジェクション https://gihyo.jp/admin/serial/01/ubuntu-recipe/0762?utm_source=feed 【CTF入門】ELFバイナリのリバースエンジニアリングに入門してみよう https://yukituna.com/3711/ 6502 アセンブラ プログラミング入門 https://euske.github.io/slides/asm6502/index.html ふつうのLinuxプログラミング-プロセスとハードウェア https://speakerdeck.com/sksat/hutuufalselinuxpuroguramingu-purosesutohadouea Linux システムコール 徹底入門 https://www.kimullaa.com/posts/202001051012/ eBPFのリバースエンジニアリング入門 https://engineering.mercari.com/blog/entry/20240228-b47712375d/ ゼロからのハイパーバイザ自作入門 https://zenn.dev/hidenori3/books/55ce98070299db