Return Address Integrity Naif Saleh Almakhdhub 1,4 Abraham A. - - PowerPoint PPT Presentation

return address integrity
SMART_READER_LITE
LIVE PREVIEW

Return Address Integrity Naif Saleh Almakhdhub 1,4 Abraham A. - - PowerPoint PPT Presentation

RAI : Securing Embedded Systems with Return Address Integrity Naif Saleh Almakhdhub 1,4 Abraham A. Clements 3 Saurabh Bagchi 1 Mathias Payer 2 1 2 3 4 Sandia National Laboratories is a multimission laboratory managed and operated by National


slide-1
SLIDE 1

μRAI: Securing Embedded Systems with Return Address Integrity

1

1 2 3 4 Abraham A. Clements3 Saurabh Bagchi1 Mathias Payer2 Naif Saleh Almakhdhub1,4

Sandia National Laboratories is a multimission laboratory managed and operated by National Technology & Engineering Solutions of Sandia, LLC, a wholly owned subsidiary of Honeywell International Inc., for the U.S. Department of Energy’s National Nuclear Security Administration under contract DE-NA0003525. SAND-XXXX

slide-2
SLIDE 2

Current State of Security

[1] https://www.wired.com/story/broadpwn-wi-fi-vulnerability-ios-android/ [2] https://keenlab.tencent.com/en/2020/01/02/exploiting-wifi-stack-on-tesla-model-s/ [3] https://www.securityweek.com/rise-ics-malware-how-industrial-security-threats-are-becoming-more-surgical

2

[1] [2] [3]

Target:

Embedded and IoT devices Running Microcontroller Systems (MCUS)

Attack:

Control-flow Hijacking

slide-3
SLIDE 3

MCUS Challenges

3

Desktop MCUS

… … … … Code

Flash (code)

Stack … Heap … Data

RAM (Data)

… Stack … … … Heap … … Data … Code

Memory

0x08055555 0x08022222 0x08011111 0x08000000 0x08999555 0x08777222 0x08555111 0x08111000 0x08000000 0x02000000 0x02050000

✓ Large virtual memory (GBs) ✓ Basic defenses (e.g., ASLR) ✓ DEP  Small physical memory (MBs Flash, KBs RAM)  Basic defenses (e.g., ASLR) ✓ Smaller code  DEP (Disabled → Fixable) Larger code

slide-4
SLIDE 4

MCUS Defenses for Return Addresses (Conceptual)

4

Security Runtime Overhead 10%

Usage Location Integrity

μRAI

Return Address Integrity + Low runtime overhead + No special hardware Limited Security Guarantees High Overhead

Shadow Stack + TEE Randomized Safe Stack Safe Stack + Software Fault Isolation Shadow Stack + MPU CFI

Special hardware required Without extra hardware

slide-5
SLIDE 5

MCUS Defenses for Return Addresses (Related Work)

5

Security Runtime Overhead 10%

Usage Location Integrity

μRAI

Return Address Integrity + Low runtime overhead + No special hardware Limited Security Guarantees High Overhead

EPOXY

(SafeStack) [S&P17]

CFI CaRE

(Shadow stack) [RAID17]

ACES

[SEC18]

Minion

[NDSS18]

SCFP

[EuroS&P18]

C-FLAT

[CCS16]

LiteHAX

[ICCAD18]

uXOM

[SEC19]

RECFISH

[ECRTS19]

μArmor

[EuroS&P19]

Special hardware required Without extra hardware

Symbiote

[RAID11]

LR2

[NDSS16]

slide-6
SLIDE 6

Return Address Integrity (RAI)

  • Every attack requires corrupting a return addresses by overwriting it
  • Main limitation of defenses → return addresses are in writable memory
  • Example: Information hiding
  • Key solution is to prevent an attacker from corrupting return addresses

6

RAI Property: 1. Ensure the return address is never writable except by an authorized instruction 2. Return addresses are never pushed to the stack or any writable memory by an adversary

slide-7
SLIDE 7

Threat Model & μRAI Protection

7

Normal application

Func2 main Func3 Func1 Func6 Func4 Func7 Func5

Unprivileged Privileged

MPU, VTOR

Corrupt return address

  • r corrupt sensitive

Memory Mapped IO (MMIO) Corrupt return address

μRAI

Func2 main Func3 Func1 Func6 Func4 Func7 Func5 MPU, VTOR : Normal function : Callable within exception handler : MMIO : State register encoding : Software-Fault Isolation (SFI)

  • Reads from memory
  • Writes to memory
  • Knows the code layout
  • Targets backward-edges
slide-8
SLIDE 8

8

μRAI: Overview

State Register Read + eXecute Jump Table

Jump return_location1 Jump return_location2 …

1

Enforces the RAI property

3

Low runtime overhead

2

Protects exception handlers and privileged execution Exception handler software-fault isolation Relative jump target lookup routine

slide-9
SLIDE 9

9

μRAI: Overview

State Register Read + eXecute Jump Table

Jump return_location1 Jump return_location2 …

1

Enforces the RAI property

3

Low runtime overhead

2

Protects exception handlers and privileged execution Exception handler software-fault isolation Relative jump target lookup routine

slide-10
SLIDE 10

μRAI and the State Register

  • State Register (SR):
  • Can be any general-purpose register → exclusively used by μRAI
  • Never spilled → cannot be overwritten through a memory corruption
  • Does not contain a return address → encoded values to resolve the return location
  • Example call graph:
  • Each edge → call
  • How encode SR?
  • An XOR chain

10

Func2 Func1 main

SR 2 SR 1

Func2 reads the SR to resolve the correct return location

slide-11
SLIDE 11

μRAI: Terminology

11

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Address <Func2>: … … … … … … … … … … … … … … … …

  • Function Keys (FKs): Hard-coded keys used to encode the SR

SR[Recursive] SR[Encoded] C

slide-12
SLIDE 12

μRAI: Terminology

12

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C

  • Function IDs (FIDs): Possible values of the SR for the function
slide-13
SLIDE 13

μRAI: Terminology

13

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C

  • Function Lookup Table (FLT): List of FIDs for the function
slide-14
SLIDE 14

μRAI: Transformation

14

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C

  • Encode the SR and call Func2
slide-15
SLIDE 15

μRAI: Transformation

15

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C⊕ key1

  • Func2 reads the SR and executes the corresponding direct jump
slide-16
SLIDE 16

μRAI: Transformation

16

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C⊕ key1

  • Func2 returns correctly and the SR is decoded
slide-17
SLIDE 17

μRAI: Transformation

17

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C

  • The previous SR value is restored
slide-18
SLIDE 18

μRAI: Transformation

18

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … … … … … … … … … … … … … … … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

SR[Recursive] SR[Encoded] C

  • The same happens for other calls. Func1 can then return correctly
slide-19
SLIDE 19

19

μRAI: Overview

State Register Read + eXecute Jump Table

Jump return_location1 Jump return_location2 …

1

Enforces the RAI property

3

Low runtime overhead

2

Protects exception handlers and privileged execution Exception handler software-fault isolation Relative jump target lookup routine

slide-20
SLIDE 20

μRAI: Enforce RAI for exception handlers

  • Exception handlers execute with privileges
  • Can disable the MPU → enable code injection
  • Can corrupt exception stack frame → break RAI property
  • Solution:
  • Apply SFI only to functions callable by exception handlers
  • Limit SFI overhead compared to full-SFI

20

Func1 Func2 Func3 Func5 Func4 main Exception Handler Func6

MPU VTOR Safe region Privileged Software-Fault Isolation

slide-21
SLIDE 21

21

μRAI: Overview

State Register Read + eXecute Jump Table

Jump return_location1 Jump return_location2 …

1

Enforces the RAI property

3

Low runtime overhead

2

Protects exception handlers and privileged execution Exception handler software-fault isolation Relative jump target lookup routine

slide-22
SLIDE 22

Target Lookup Routine (TLR)

  • How can we find the correct direct jump in the FLT efficiently?
  • Use a relative jump before the FLT
  • Resolve the correct return location efficiently regardless of FLT size

22

Address <Func1>: … … … … … … … Jump PC+SR FID Return Target 1 Jump location1 2 Jump location2 3 Jump ERROR 4 Jump location4 5 Jump location5 Use SR as an index

  • f a jump table

Align the FLT → make SR = 4 Assume the correct return location is location4 Comparing all FID can be slow!

slide-23
SLIDE 23

23

μRAI: Overview

State Register Read + eXecute Jump Table

Jump return_location1 Jump return_location2 …

1

Enforces the RAI property

3

Low runtime overhead

2

Protects exception handlers and privileged execution Exception handler software-fault isolation Relative jump target lookup routine

slide-24
SLIDE 24

Evaluation

  • Five MCUS applications on Cortex-M4:
  • PinLock
  • FatFs_uSD
  • FatFs_RAM
  • LCD_uSD
  • Animation
  • CoreMark benchmark[1]
  • Standard MCUS performance benchmark

[1] EEMBC, “Coremark - industry-standard benchmarks for embedded systems,” http://www.eembc.org/coremark

24

slide-25
SLIDE 25

RX Memory

Security Evaluation Using PinLock: Unlock The Lock

25

… … … … … …

RW Memory

buffer … … … … … …

RW Memory

ptr … … … … … …

RW Memory

buff

Jump Table

Jump return_location1 …

Buffer overflow Arbitrary write Stack pivot

buffer No return address to write to…

SP SP

Sensitive MMIO and Safe region Privileged

State Register

✓ μRAI prevents all control-flow hijacking attack scenarios targeting return addresses

No return address to pop from the stack No return address to

  • verflow…
slide-26
SLIDE 26

Performance results

  • Requiring full-SFI results in high overhead → average of 130.5%
  • μRAI results in low overhead → average of 0.1%

26

slide-27
SLIDE 27

μRAI: Conclusion

  • Control-flow hijacking on MCUS is a threat
  • μRAI secures MCUS against control-flow hijacking
  • Enforces the RAI property for MCUS → protects backward edges
  • Complemented with type-based CFI → end-to-end code pointer protection
  • Presents a portable encoding scheme
  • Does not require special hardware features (only a register and an MPU)
  • Applicable to other systems
  • Low runtime overhead

https://github.com/embedded-sec/uRAI

27

slide-28
SLIDE 28

Backup Slides

28

slide-29
SLIDE 29

Challenge: Path Explosion

29

Func3 Func1 Func2 main

𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿2

SR[Rec] SR[Enc] [ 𝐷 ⊕ 𝐺𝐿1 , 𝐷 ⊕ 𝐺𝐿2 ]

𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿3 𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿5 𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿6

SR[Rec] SR[Enc] 𝐷 SR[Rec] SR[Enc] [ 𝐷 ⊕ 𝐺𝐿3 , 𝐷 ⊕ 𝐺𝐿4 ] SR[Rec] SR[Enc] [ 𝐷 ⊕ 𝐺𝐿1 ⊕ 𝐺𝐿5, 𝐷 ⊕ 𝐺𝐿2 ⊕ 𝐺𝐿5, 𝐷 ⊕ 𝐺𝐿3 ⊕ 𝐺𝐿6, 𝐷 ⊕ 𝐺𝐿4 ⊕ 𝐺𝐿6 ]

  • Func3 has 2 call sites
  • FLT is size is 4!

𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿1 𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝐺𝐿4

slide-30
SLIDE 30

Path Explosion Solution: Segmentation

  • State register segmentation
  • Functions only use the bits in their assigned segment.

30

Recursion counter (Higher N bits) Encoded value (Lower 32-N bits) Segment 1

Segment K Segment M … Segment 2 Segment 1

slide-31
SLIDE 31

Path Explosion Solution: Segmentation

31

Func3 Func1 Func2 main

𝑇𝑆[𝐹𝑜𝑑1] ⊕ 𝐺𝐿2

SR[Rec] SR[Enc2] SR[Enc1] 𝐷 [ 𝐷 ⊕ 𝐺𝐿1, 𝐷 ⊕ 𝐺𝐿2 ]

𝑇𝑆[𝐹𝑜𝑑1] ⊕ 𝐺𝐿3 𝑇𝑆[𝐹𝑜𝑑2] ⊕ 𝐺𝐿5 𝑇𝑆[𝐹𝑜𝑑2] ⊕ 𝐺𝐿6

SR[Rec] SR[Enc2] SR[Enc1] 𝐷 𝐷 SR[Rec] SR[Enc2] SR[Enc1] 𝐷 [ 𝐷 ⊕ 𝐺𝐿3 , 𝐷 ⊕ 𝐺𝐿4 ] SR[Rec] SR[Enc2] SR[Enc1] [ 𝐷 ⊕ 𝐺𝐿5, 𝐷 ⊕ 𝐺𝐿6, ] Not used

  • Segmentation reduces

FLT from 4 to 2 𝑇𝑆[𝐹𝑜𝑑1] ⊕ 𝐺𝐿1 𝑇𝑆[𝐹𝑜𝑑1] ⊕ 𝐺𝐿4

slide-32
SLIDE 32

μRAI: Scalability

  • What if no more values can be found for the SR?
  • Solution:
  • Partition the call graph if no solution is found
  • Entering a new partition

→Save and reset the SR to a privileged safe region

  • Returning to a previous partition

→ Restore the SR

32

Func1 Func2 Func3 Func5 Func4 main Exception Handler Func6

Safe Region Privileged

slide-33
SLIDE 33

Store Instructions Protected with EH-SFI

33

App # of Store instruction

Static Total (Static/Total)% Dynamic

PinLock 56 516 10.9 7 FatFs_uSD 99 1,802 5.5 906K FatFs_RAM 7 1,116 0.6 7 LCD_uSD 99 2,814 3.5 48K Animation 99 2,760 3.6 66K CoreMark 56 1,024 5.5 7

slide-34
SLIDE 34

SR Layout: Recursion

  • The SR has two parts:
  • ENC: Encoded value
  • REC: Recursion counter

34

SR[Rec] SR[Enc] 𝐷 SR[Rec] SR[Enc] 𝐷 ⊕ 𝑙𝑓𝑧1

Func3 main

𝑇𝑆[𝐹𝑜𝑑] ⊕ 𝑙𝑓𝑧1

  • Cannot use XOR with recursion
  • Collision occurs with existing values Func1

→ 𝑻𝑺 ⊕ 𝐵𝑂𝑍 𝐿𝐹𝑍 ⊕ 𝐵𝑂𝑍 𝐿𝐹𝑍 = 𝑻𝑺 𝑻𝑺 𝑺𝒇𝒅 + 𝟐 before the call 𝑻𝑺 𝑺𝒇𝒅 − 𝟐 after return If 𝑻𝑺 𝑺𝒇𝒅 > 𝟏 → recursion

slide-35
SLIDE 35

μRAI: Handling recursion

35

Address <Func1>: … SR[Enc] = SR[Enc] ⊕ key1 … Call Func2 Func1_1 SR[Enc] = SR[Enc] ⊕ key1 … … … SR[Enc] = SR[Enc] ⊕ key2 … Call Func2 Func1_2 SR[Enc] = SR[Enc] ⊕ key2 … … Function ID (FID) Return Target C Jump return_location1 ELSE Jump ERROR Address <Func2>: … SR[Rec]++ … Call Func2 Func2_1 SR[Rec]-- … … … IF 0 < SR[Rec] < MAX_REC … Jump Func2_1 … ELSE … … Function ID (FID) Return Target C ⊕ key1 Jump Func1_1 C ⊕ key2 Jump Func1_2 ELSE Jump ERROR

  • If recursive → use a counter (recursion is discouraged in MCUS)

SR[Rec] SR[Enc] C