SlideShare a Scribd company logo
Attacking the Linux PRNG on
Android & Embedded Devices
David Kaplan, Sagi Kedmi, Roee Hay & Avi Dayan
IBM Security Systems
agenda
• Motivation and Introduction
• Linux Random Number Generator
agenda
• Motivation and Introduction
• Linux Random Number Generator
• Our Attack
• 1st
Attack Vector – Local Atk.
• Demo
• 2nd
Attack Vector – Remote Atk.
agenda
• Motivation and Introduction
• Linux Random Number Generator
• Our Attack
• 1st
Attack Vector – Local Atk.
• Demo
• 2nd
Attack Vector – Remote Atk.
• Mitigations
MOTIVATION
motivation_keystore_buffer_overflow
• We discovered CVE-2014-3100, a stack-based Buffer
Overflow in Keystore
• Service responsible for securely storing crypto related data
• We had privately reported to Google and they provided a
patch available in KITKAT. Whitepaper.
• Exploit must overcome various defense mechanisms, including
Stack Canaries.
/* KeyStore is a secured storage for key-value pairs. In this implementation,
* each file stores one key-value pair. Keys are encoded in file names, and
* values are encrypted with checksums. The encryption key is protected by a
* user-defined password. To keep things simple, buffers are always larger than
* the maximum space we needed, so boundary checks on buffers are omitted. */
motivation_keystore_buffer_overflow
Stack canaries and their enforcement
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
__stack_chk_guard
Stack Guard
initialization
32 bits
128
bits
• On libbionic load:
__stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM));
• Function Prologue:
● Place __stack_chk_guard on the stack (before ret).
• Function Epilogue:
● Compare saved stack canary with __stack_chk_guard;
→ Crash if mismatch
motivation_keystore_buffer_overflow
Stack canaries and their enforcement
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
__stack_chk_guard
Stack Guard
initialization
32 bits
128
bits
• On libbionic load:
__stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM));
• Function Prologue:
● Place __stack_chk_guard on the stack (before ret).
• Function Epilogue:
● Compare saved stack canary with __stack_chk_guard;
→ Crash if mismatch
● fork() → execve().
● execve() → Auxiliary vector (AUXV)
● AUXV[AT_RANDOM] = 16 Random bytes from the PRNG
● libbionic assigns canary = first 4 bytes of AT_RANDOM
Canary origins; *nix process creation model
motivation_keystore_buffer_overflow
Stack canaries and their enforcement
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
__stack_chk_guard
Stack Guard
initialization
32 bits
128
bits
• On libbionic load:
__stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM));
• Function Prologue:
● Place __stack_chk_guard on the stack (before ret).
• Function Epilogue:
● Compare saved stack canary with __stack_chk_guard;
→ Crash if mismatch
● fork() → execve().
● execve() → Auxiliary vector (AUXV)
● AUXV[AT_RANDOM] = 16 Random bytes from the PRNG
● libbionic assigns canary = first 4 bytes of AT_RANDOM
Canary origins; *nix process creation model
Remember this; We'll get back to it
motivation_keystore_buffer_overflow
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
__stack_chk_guard
Stack Guard
initialization
32 bits
128
bits
Attacks on the Stack-Smashing Protection:
• Naive Online Bruteforce of the Canary Value
• Impractical: 2^32 attempts on average.
motivation_keystore_buffer_overflow
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
__stack_chk_guard
Stack Guard
initialization
32 bits
128
bits
Attacks on the Stack-Smashing Protection:
• Naive Online Bruteforce of the Canary Value
• Impractical: 2^32 attempts on average.
• Online Learning of the Canary Value
• By another info leak issue
• Re-forking server:
• Very efficient: 514 attempts until
success on average
motivation_keystore_buffer_overflow
LR
Saved
Registers
Canary
(32 bits)
Buffer
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
Stack Guard
initialization
32 bits
128
bits
__stack_chk_guard
Attacks on the Stack-Smashing Protection:
• Naive Online Bruteforce of the Canary Value
• Impractical: 2^32 attempts on average.
• Online Learning of the Canary Value
• By another info leak issue
• Re-forking server:
• Very efficient: 514 attempts until
success on average
• Overwrite __stack_chk_guard
• By overwriting some pointer
motivation_keystore_buffer_overflow
LR
Saved
Registers
Canary
(32 bits)
Buffer
Attacks on the Stack-Smashing Protection:
• Naive Online Bruteforce of the Canary Value
• Impractical: 2^32 attempts on average.
• Online Learning of the Canary Value
• By another info leak issue
• Re-forking server:
• Very efficient: 514 attempts until
success on average
• Overwrite __stack_chk_guard
• By overwriting some pointer
• Our attack: Offline reconstruction of the
PRNG’s internal state
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
Stack Guard
initialization
32 bits
128
bits
__stack_chk_guard__stack_chk_guard__stack_chk_guard
motivation_wrap_up
LR
Saved
Registers
Canary
(32 bits)
Buffer
Wrap things up:
• We found a vulnerability in a critical service
in Android 4.3.
• In an effort to exploit it, we had to overcome
a stack canary, we couldn't do so using
known techniques.
• Canaries are 4 random bytes that are
extracted from the Linux PRNG.
• Aimed to find a weakness in the PRNG that
will allow us to intelligently guess the canary.
• End up with a full-fledged attack on the Linux
PRNG.
Stack
layout
Linux PRNG
AUXV(AT_RANDOM)
Stack Guard
initialization
32 bits
128
bits
__stack_chk_guard__stack_chk_guard__stack_chk_guard
LINUX PRNG
INPUT POOL
BLOCKING POOL
NON-BLOCKING POOL
/dev/urandom
/dev/random
get_random_bytes()
lprng_overview
Bird's eye view
• Output is hashed twice using SHA1
• Extracts in blocks of 10 bytes and truncates if necessary.
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
INTERRUPT
DISK
INPUT
T
I
M
E
R
time
if KEC >= 192 bits
*KEC = Kernel Entropy Count
entropy_sources
63 31 0
seconds nanoseconds
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
INTERRUPT
DISK
INPUT
T
I
M
E
R
time
if KEC < 192 bits
*KEC = Kernel Entropy Count
boot_time_vulnerability
63 31 0
seconds nanoseconds
NON-BLOCKING-POOL
ktime_t
EXTRACTION (PULL)
boot_time_vulnerability
63 31 0
seconds nanoseconds
boot_timeline
Device
powers on
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
May occur
In different
order
OUR WORK
Prior art on weakness in early boot *
Present practical run-time attack
Formalize attack
Demonstrate PoC against current mobile platforms
contribution
* Heninger et al. 2012, Becherer et al. 2009, Ding et al. 2014
Given a LEAK of a value extracted from the non-blocking pool and
LOW ENTROPY AT BOOT, the STATE of the PRNG can be
determined until external entropy is too high
attack_outcome
NON-BLOCKING-POOL
seed_t1
EXTRACTION (PULL)
63 31 0
seconds nseconds
Using the PRNG against itself
●
Recall: Low boot-time entropy degenerates
the PRNG and that the output of the PRNG is
hashed twice using SHA1.
●
Fact: Crypto. hash functions are designed to
be collision resistant.
attack_leak
NON-BLOCKING-POOL
EXTRACTION (PULL)
≠
seed_t2
seed_t1
63 31 0
seconds nseconds
NON-BLOCKING-POOL
seed_t1
EXTRACTION (PULL)
63 31 0
seconds nseconds
Using the PRNG against itself
●
Recall: Low boot-time entropy degenerates
the PRNG and that the output of the PRNG is
hashed twice using SHA1.
●
Fact: Crypto. hash functions are designed to
be collision resistant.
●
It is highly unlikely that PRNGs that are
seeded with different seeds will result in the
same output. Regardless of the order of
extractions.
attack_leak
NON-BLOCKING-POOL
EXTRACTION (PULL)
≠
seed_t2
seed_t1
63 31 0
seconds nseconds
NON-BLOCKING-POOL
seed_t1
EXTRACTION (PULL)
63 31 0
seconds nseconds
Using the PRNG against itself
●
Recall: Low boot-time entropy degenerates
the PRNG and that the output of the PRNG is
hashed twice using SHA1.
●
Fact: Crypto. hash functions are designed to
be collision resistant.
●
It is highly unlikely that PRNGs that are
seeded with different seeds will result in the
same output. Regardless of the order of
extractions.
●
Result: Every leak(sequence of random
bytes) from the non blocking pool is almost
certainly the offspring of one specific seed.
attack_leak
NON-BLOCKING-POOL
EXTRACTION (PULL)
≠
seed_t2
seed_t1
63 31 0
seconds nseconds
Using the PRNG against itself
●
Given a leak from the nonblocking pool of a
“Real” PRNG we could simulate offline PRNGs
with different seeds and compare extractions
with the online leak.
attack_overview
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Using the PRNG against itself
●
Given a leak from the nonblocking pool of a
“Real” PRNG we could simulate offline PRNGs
with different seeds and compare extractions
with the online leak.
●
Due to SHA1's collision resistance, if one of
the simulated PRNGs produces a sequence of
random bytes that is the same as the leak
value – we almost certainly found the seed.
attack_overview
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Using the PRNG against itself
●
Given a leak from the nonblocking pool of a
“Real” PRNG we could simulate offline PRNGs
with different seeds and compare extractions
with the online leak.
●
Due to SHA1's collision resistance, if one of
the simulated PRNGs produces a sequence of
random bytes that is the same as the leak
value – we almost certainly found the seed.
●
Once we have the seed we can produce the
same outputs of the “Real” PRNG until noise
from the Input pool is mixed to the
Nonblocking pool
attack_overview
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Even After the mixing, the PRNG is vulnerable
●
Note: in the whitepaper we demonstrated a
more intricate attack flow
attack_overview
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Problems we faced:
●
The Nonblocking pool seed is 8 bytes long,
Say we consider only the nanoseconds and
assuming uniform distribution
attack_overview
10
9
=2
log2
(10
9
)
≃2
30
63 31 0
seconds nanoseconds
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Problems we faced:
●
The Nonblocking pool seed is 8 bytes long,
Say we consider only the nanoseconds and
assuming uniform distribution
●
Hidden entropy source – Concurrency
attack_overview
10
9
=2
log2
(10
9
)
≃2
30
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
1
2
3
4
3
4
POOL
STATE
Yellow Path
- Process A: extract from pool
- Process A: mix into pool
- Process B: extract from pool
- Process B: mix into pool
Green Path
- Process A: extract from pool
- Process B: extract from pool
- Process A: mix into pool
- Process B: mix into pool
Problems we faced:
●
The Nonblocking pool seed is 8 bytes long,
Say we consider only the nanoseconds and
assuming uniform distribution
●
Hidden entropy source – Concurrency
●
What can be attacked?
●
Where can we get the leak value?
attack_overview
10
9
=2
log2
(10
9
)
≃2
30
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
Where can we find leaks and attack targets ?
attack_overview
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
Device
powers on
Terminology
attack_overview
Device
powers on
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Kernel
Boot-time
Leak/Target
Platform
Boot-time
Leak/Target
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
1st
Attack Vector
Malware → PRNG Seed →
Keystore's Canary
Instrumenting a device
●
Samsung Galaxy S4, Android 4.3
s4_offline_study
Instrumenting a device
●
Samsung Galaxy S4, Android 4.3
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
s4_offline_study
Instrumenting a device
●
Samsung Galaxy S4, Android 4.3
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
●
Fixed the seeds to see catch some bias in
the order of extractions – find bias in conc.
s4_offline_study
Instrumenting a device
●
Samsung Galaxy S4, Android 4.3
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
●
Fixed the seeds to see catch some bias in
the order of extractions – find bias in conc.
●
In total, we rebooted(script) the device more
than 2000 times, each time we dumped the
kernel ring buffer to a file.
s4_offline_study
Details
s4_attack_leak
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
Device
powers on
Platform
Boot-time
Leak/Target
Details
●
Android designers chose to spawn every app
process by forking a master process – Zygote
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
Details
●
Android designers chose to spawn every app
process by forking a master process – Zygote
●
Zygote(app_process) is fork'ed and exec'ed by
init at platform boot-time
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
Details
●
Android designers chose to spawn every app
process by forking a master process – Zygote
●
Zygote(app_process) is fork'ed and exec'ed by
init at platform boot-time
●
*nix-like vs. App process creation model.
Exec() ?
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
Details
●
Android designers chose to spawn every app
process by forking a master process – Zygote
●
Zygote(app_process) is fork'ed and exec'ed by
init at platform boot-time
●
*nix-like vs. App process creation model.
Exec() ?
●
Recall: exec() enforces ASLR and assigns the
AT_RANDOM
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
Details
●
Result: All Applications in Android has the
same Canary value (AT_RANDOM) and largely
the same address space layout
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
fork()
AUXV(AT_RANDOM)
Zygote Linux PRNG
AUXV(AT_RANDOM) – Zygote's
WhatsApp
AUXV(AT_RANDOM) – Zygote's
Contacts
AUXV(AT_RANDOM) – Zygote's
MALWARE
fork()
leak/target
Details
●
Result: All Applications in Android has the
same Canary value (AT_RANDOM) and largely
the same address space layout
s4_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
fork()
AUXV(AT_RANDOM)
Zygote Linux PRNG
AUXV(AT_RANDOM) – Zygote's
WhatsApp
AUXV(AT_RANDOM) – Zygote's
Contacts
AUXV(AT_RANDOM) – Zygote's
MALWARE
fork() fork()
leak/target
s4_attack_leak_concurrency
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given a leak, what's the probability of
finding the original seed ?
●
Zygote's AT_RANDOM is our leak
It's a platform boot-time leak, which means It
occurs in the 'Concurrency Hell' phase
leak/target
s4_attack_leak_concurrency
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given a leak, what's the probability of
finding the original seed ?
●
Zygote's AT_RANDOM is our leak
It's a platform boot-time leak, which means It
occurs in the 'Concurrency Hell' phase
●
An offline study of the samples revealed bias
towards a specific extraction path from the
nonblocking pool
leak/target
s4_attack_leak_concurrency
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given a leak, what's the probability of
finding the original seed ?
●
Zygote's AT_RANDOM is our leak
It's a platform boot-time leak, which means It
occurs in the 'Concurrency Hell' phase
●
An offline study of the samples revealed bias
towards a specific extraction path from the
nonblocking pool
●
20% of the samples had Zygote's AT_RANDOM
bytes somewhere in the extraction path
leak/target
s4_attack_leak_concurrency
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given a leak, what's the probability of
finding the original seed ?
●
Given a leak and assuming we try all 230
possible seeds the chance is
leak/target
1
5
H (snb)=23.5bits
s4_non-blocking_seed
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
= LEAK ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
s4_attack_targets
leak/target
Given a seed, Probabilities of finding
the canary of early boot services
= LEAK ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given a seed, Probabilities of finding
the canary of early boot services
SIM.
PRNG
seed_t_k
RANDOM VALUE
s4_attack_targets
leak/target
6
100
= LEAK ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given Zygote's AT_RANDOM, the
probability of guessing the Keystore's
canary value is:
SIM.
PRNG
seed_t_k
RANDOM VALUE
s4_attack_targets
leak/target
1
5
⋅
6
100
≃0.01→1%
Remember where we came from...
we needed to guess 32 random bits
= LEAK ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
Given Zygote's AT_RANDOM, the
probability of guessing the Keystore's
canary value is:
SIM.
PRNG
seed_t_k
RANDOM VALUE
s4_attack_targets
leak/target
1
5
⋅
6
100
≃0.01→1%
1
232
≃0.00000000023→0.000000023%
DEMO
s4_demo
= LEAK ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
SIM.
PRNG
seed_t_k
RANDOM VALUE
leak/target
2nd
Attack Vector
Ping6 → PRNG Seed →
IPv6 Fragment Injection &
Getting Keystore's Canary
Instrumenting a device
●
Samsung Galaxy S2, Android 4.1.2
s2_offline_study
Instrumenting a device
●
Samsung Galaxy S2, Android 4.1.2
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
s2_offline_study
Instrumenting a device
●
Samsung Galaxy S2, Android 4.1.2
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
●
Fixed the seeds to see catch some bias in
the order of extractions – find bias in conc.
s2_offline_study
Instrumenting a device
●
Samsung Galaxy S2, Android 4.1.2
●
printk() input and nonblocking pool seeds -
find a bias in the seed value
●
printk() get_random_bytes() callers and
amount of random bytes requested – find
leak and attack targets
●
Fixed the seeds to see catch some bias in
the order of extractions – find bias in conc.
●
In total, we rebooted(script) the device more
than 2000 times, each time we dumped the
kernel ring buffer to a file.
s2_offline_study
Details
s2_attack_leak
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
Device
powers on
Kernel
Boot-time
Leak/Target
Details
●
While the kernel is brought up, an IPv6 module
initializes and extracts 4 random bytes. Lets
call them rand.
s2_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
Details
●
While the kernel is brought up, an IPv6 module
initializes and extracts 4 random bytes. Lets
call them rand.
●
IPv6 packet fragment identifier is computed by
a deterministic function.
s2_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
f(rand, ipv6_dst_addr)=ipv6_frag_id
Details
●
While the kernel is brought up, an IPv6 module
initializes and extracts 4 random bytes. Lets
call them rand.
●
IPv6 packet fragment identifier is computed by
a deterministic function.
●
The pair (ipv6_dst_addr,ipv6_frag_id) is our leak.
Why?
s2_attack_leak
REAL
PRNG
= LEAK ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
leak/target
f(rand, ipv6_dst_addr)=ipv6_frag_id
Details
●
While the kernel is brought up, an IPv6 module
initializes and extracts 4 random bytes. Lets
call them rand.
●
IPv6 packet fragment identifier is computed by
a deterministic function.
●
The pair (ipv6_dst_addr,ipv6_frag_id) is our leak.
Why?
●
We simulate PRNGs up to rand, and feed it to
the deterministic function f
s2_attack_leak
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
f(rand, ipv6_dst_addr)=ipv6_frag_id
Details
●
While the kernel is brought up, an IPv6 module
initializes and extracts 4 random bytes. Lets
call them rand.
●
IPv6 packet fragment identifier is computed by
a deterministic function.
●
The pair (ipv6_dst_addr,ipv6_frag_id) is our leak.
Why?
●
We simulate PRNGs up to rand, and feed it to
the deterministic function f
●
OK, fine, but how did you get ipv6_dst_addr?
s2_attack_leak
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
f(rand, ipv6_dst_addr)=ipv6_frag_id
IPv6 fragmentation & ICMPv6 Echo Req.
●
IP packets that exceed the path MTU, are
divided into fragments which are sent and
then reassembled by receiver.
s2_attack_leak
leak/target
IPv6 fragmentation & ICMPv6 Echo Req.
●
IP packets that exceed the path MTU, are
divided into fragments which are sent and
then reassembled by receiver.
●
Each fragment of the packet contains the
same fragment id. Which is used by the
receiver to identify fragments of a packet.
s2_attack_leak
leak/target
IPv6 fragmentation & ICMPv6 Echo Req.
●
IP packets that exceed the path MTU, are
divided into fragments which are sent and
then reassembled by receiver.
●
Each fragment of the packet contains the
same fragment id. Which is used by the
receiver to identify fragments of a packet.
●
IPv6 fragmentation doesn't happen very
often. How do we make it happen ?
s2_attack_leak
leak/target
IPv6 fragmentation & ICMPv6 Echo Req.
●
Ping6 – a utility for sending ICMPv6 Echo
Requests which requires the target to
send an ICMPv6 Echo Replay with the
exactly the same data.
s2_attack_leak
leak/target
IPv6 fragmentation & ICMPv6 Echo Req.
●
Ping6 – a utility for sending ICMPv6 Echo
Requests which requires the target to
send an ICMPv6 Echo Replay with the
exactly the same data.
●
Result: Sending ICMPv6 Echo Request
with data > MTU will make the receiver
send a fragmented reply
s2_attack_leak
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
A
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
SSID=
Schiphol
Free
A
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
SSID=
Schiphol
Free
A V
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
SSID=
Schiphol
Free
Fragmented ICMPv6
Echo Request
A V
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
SSID=
Schiphol
Free
Fragmented ICMPv6
Echo Request
Fragmented ICMPv6
Echo Reply
A V
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
s2_attack_get_leak
Amsterdam
Schiphol
Airport
SSID=
Schiphol
Free
Fragmented ICMPv6
Echo Request
Fragmented ICMPv6
Echo Reply
Attacker got the leak:
● V computed ipv6_frag_id
with A's ipv6_src_addr
● A knows ipv6_frag_id and
ipv6_dst_addr.
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
leak/target
A V
s2_attack_finding_seed
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
Given the leak we find the seed
H (snb)=18.4bits
leak/target
s2_attack_targets
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
Given the seed what can we attack ?
●
IPv6 Fragment injection – We can derive the
exact fragment id V will use for any destination
address.
leak/target
s2_attack_targets
REAL
PRNG
= ipv6_frag_id ?
seed_t_k
LEAK
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
Given the seed what can we attack ?
●
IPv6 Fragment injection – We can derive the
exact fragment id V will use for any destination
address.
●
Canary value of early boot services.
For instance, with a probability of 1/20 we can
compute Keystore's canary value, given the
seed.
targetleak
= ipv6_frag_id ?
SIM.
PRNG
seed_t_1
SIM.
PRNG
seed_t_k
SIM .
PRNG
seed_t_n
... ...
rand_t_1 rand_t_k
f(rnd,dst) f(rnd,dst) f(rnd,dst)
rand_t_n
SIM.
PRNG
seed_t_k
RANDOM VALUE
s2_attack_targets
Probabilities of finding the canary
of early boot services
leak target
Mitigations
mitigations
Current mitigations
●
Save entropy across boots
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
T
I
M
E
R
INTERRUPT
DISK
INPUT
time
if KEC >= 192 bits
mitigations
Current mitigations
●
Save entropy across boots
●
Trusted external entropy injection –
web service / HWRNG
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
T
I
M
E
R
INTERRUPT
DISK
INPUT
time
if KEC >= 192 bits
mitigations
Problem with those mitigations
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
Device
powers on
Injecting
Entropy to
Pools
Entropy
mitigations
Problem with those mitigations
Kernel
starts booting
PRNG is
initialized
Kernel boot
Finished &
Platform starts
booting
Input Pool mixed
into Nonblocking
Pool :(
Phone is
ready
Concurrency Hell
Best
Leak/Target
Good
Leak/Target
Bad
Leak/Target
Device
powers on
Kernel
Boot-time
Leak/Target
Injecting
Entropy to
Pools
Entropy
Entropy injection occurs after the
kernel boots up
mitigations
Current mitigations
●
Initialize the seeds using a hardware RNG
●
RDRAND,RDSEED Intel's ISA
●
Early random, Qualcomm
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
T
I
M
E
R
INTERRUPT
DISK
INPUT
time
if KEC >= 192 bits
mitigations
Current mitigations
●
Initialize the seeds using a hardware RNG
●
RDRAND,RDSEED Intel's ISA
●
Early random, Qualcomm
●
Mix device-specific data to nonblocking and
blocking pools
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
T
I
M
E
R
INTERRUPT
DISK
INPUT
time
if KEC >= 192 bits
mitigations
Current mitigations
●
Initialize the seeds using a hardware RNG
●
RDRAND,RDSEED Intel's ISA
●
Early random, Qualcomm
●
Mix device-specific data to nonblocking and
blocking pools
●
Changes to newer kernels allow for more
boot time entropy
INPUT POOL NON-BLOCKING-POOL
ktime_t ktime_t
EXTRACTION (PULL)
T
I
M
E
R
INTERRUPT
DISK
INPUT
time
if KEC >= 192 bits
talk_wrap_up
• Linux-based devices with low boot time entropy may
allow a practical, low-cost attack on the PRNG
• The attack requires an offline study of a device and an
online leak
• Allows the attacker to predict a random number which is
generated by the victim's PRNG
• Two manifestations - Local/Remote Atk.
• Mitigations
?
Thank you
Thanks Nadja Kahan for the illustrations !
http://www.nadjakahan.com

More Related Content

PPTX
Secure coding for developers
PDF
For the Greater Good: Leveraging VMware's RPC Interface for fun and profit by...
PDF
Can We Prevent Use-after-free Attacks?
PDF
Take a Jailbreak -Stunning Guards for iOS Jailbreak- by Kaoru Otsuka
PDF
Advanced Evasion Techniques by Win32/Gapz
PDF
DeathNote of Microsoft Windows Kernel
PPTX
ShinoBOT Suite
PDF
Использование KASan для автономного гипервизора
Secure coding for developers
For the Greater Good: Leveraging VMware's RPC Interface for fun and profit by...
Can We Prevent Use-after-free Attacks?
Take a Jailbreak -Stunning Guards for iOS Jailbreak- by Kaoru Otsuka
Advanced Evasion Techniques by Win32/Gapz
DeathNote of Microsoft Windows Kernel
ShinoBOT Suite
Использование KASan для автономного гипервизора

What's hot (20)

PDF
How to Root 10 Million Phones with One Exploit
PDF
syzbot and the tale of million kernel bugs
PDF
Fuzzing malware for fun & profit. Applying Coverage-Guided Fuzzing to Find Bu...
PDF
Zero bugs found? Hold my beer AFL! how to improve coverage-guided fuzzing and...
PPTX
Memory Corruption: from sandbox to SMM
PDF
john-devkit: 100 типов хешей спустя / john-devkit: 100 Hash Types Later
PDF
Introduction to Memory Exploitation (CppEurope 2021)
PPT
OWASP Much ado about randomness
PDF
Chromium Sandbox on Linux (BlackHoodie 2018)
PDF
Статический анализ кода в контексте SSDL
PDF
Ricardo J. Rodríguez & Daniel Uroz - When ROP meets Turing: Automatic Generat...
PDF
Specializing the Data Path - Hooking into the Linux Network Stack
PDF
One Shellcode to Rule Them All: Cross-Platform Exploitation
PDF
Reconstructing Gapz: Position-Independent Code Analysis Problem
PDF
CSW2017 Amanda rousseau cansecwest2017_net_hijacking_powershell
PDF
Kernel Recipes 2014 - Writing Code: Keep It Short, Stupid!
PPTX
08 - Return Oriented Programming, the chosen one
PDF
[CB17] Trueseeing: Effective Dataflow Analysis over Dalvik Opcodes
PDF
Linux: the first second
PPTX
PowerShell Inside Out: Applied .NET Hacking for Enhanced Visibility by Satosh...
How to Root 10 Million Phones with One Exploit
syzbot and the tale of million kernel bugs
Fuzzing malware for fun & profit. Applying Coverage-Guided Fuzzing to Find Bu...
Zero bugs found? Hold my beer AFL! how to improve coverage-guided fuzzing and...
Memory Corruption: from sandbox to SMM
john-devkit: 100 типов хешей спустя / john-devkit: 100 Hash Types Later
Introduction to Memory Exploitation (CppEurope 2021)
OWASP Much ado about randomness
Chromium Sandbox on Linux (BlackHoodie 2018)
Статический анализ кода в контексте SSDL
Ricardo J. Rodríguez & Daniel Uroz - When ROP meets Turing: Automatic Generat...
Specializing the Data Path - Hooking into the Linux Network Stack
One Shellcode to Rule Them All: Cross-Platform Exploitation
Reconstructing Gapz: Position-Independent Code Analysis Problem
CSW2017 Amanda rousseau cansecwest2017_net_hijacking_powershell
Kernel Recipes 2014 - Writing Code: Keep It Short, Stupid!
08 - Return Oriented Programming, the chosen one
[CB17] Trueseeing: Effective Dataflow Analysis over Dalvik Opcodes
Linux: the first second
PowerShell Inside Out: Applied .NET Hacking for Enhanced Visibility by Satosh...
Ad

Similar to [Blackhat EU'14] Attacking the Linux PRNG on Android and Embedded Devices (20)

PDF
[Usenix's WOOT'14] Attacking the Linux PRNG and Android - Weaknesses in Seedi...
PDF
CNIT 141: 2. Randomness
PDF
How to exploit rand()?
PDF
Linux randomnumbergenerator
PDF
inside-linux-kernel-rng-presentation-sept-13-2022.pdf
PDF
Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...
PDF
Sullivan randomness-infiltrate 2014
PPT
Much ado about randomness. What is really a random number?
PDF
Filippo, Plain simple reality of entropy
PPTX
Linux binary analysis and exploitation
PDF
The entropic principle: /dev/u?random and NetBSD by Taylor R Campbell
PDF
Trust boundaries - Confidence 2015
PDF
Intel Random Number Generator
PDF
Master Canary Forging by Yuki Koike - CODE BLUE 2015
PDF
What is pseudo random number
PDF
Erlang, random numbers, and the security: London Erlang User Group Talk Slide...
PPTX
Information and network security 30 random numbers
PDF
J45015460
PDF
Breaking Secure Mobile Applications - Hack In The Box 2014 KL
PDF
When Crypto Attacks! (Yahoo 2009)
[Usenix's WOOT'14] Attacking the Linux PRNG and Android - Weaknesses in Seedi...
CNIT 141: 2. Randomness
How to exploit rand()?
Linux randomnumbergenerator
inside-linux-kernel-rng-presentation-sept-13-2022.pdf
Because "use urandom" isn't everything: a deep dive into CSPRNGs in Operating...
Sullivan randomness-infiltrate 2014
Much ado about randomness. What is really a random number?
Filippo, Plain simple reality of entropy
Linux binary analysis and exploitation
The entropic principle: /dev/u?random and NetBSD by Taylor R Campbell
Trust boundaries - Confidence 2015
Intel Random Number Generator
Master Canary Forging by Yuki Koike - CODE BLUE 2015
What is pseudo random number
Erlang, random numbers, and the security: London Erlang User Group Talk Slide...
Information and network security 30 random numbers
J45015460
Breaking Secure Mobile Applications - Hack In The Box 2014 KL
When Crypto Attacks! (Yahoo 2009)
Ad

Recently uploaded (20)

PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Approach and Philosophy of On baking technology
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Chapter 3 Spatial Domain Image Processing.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPT
Teaching material agriculture food technology
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Machine learning based COVID-19 study performance prediction
Review of recent advances in non-invasive hemoglobin estimation
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Approach and Philosophy of On baking technology
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Chapter 3 Spatial Domain Image Processing.pdf
The AUB Centre for AI in Media Proposal.docx
Unlocking AI with Model Context Protocol (MCP)
Building Integrated photovoltaic BIPV_UPV.pdf
Spectral efficient network and resource selection model in 5G networks
Mobile App Security Testing_ A Comprehensive Guide.pdf
Big Data Technologies - Introduction.pptx
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
sap open course for s4hana steps from ECC to s4
Per capita expenditure prediction using model stacking based on satellite ima...
Digital-Transformation-Roadmap-for-Companies.pptx
Teaching material agriculture food technology

[Blackhat EU'14] Attacking the Linux PRNG on Android and Embedded Devices

  • 1. Attacking the Linux PRNG on Android & Embedded Devices David Kaplan, Sagi Kedmi, Roee Hay & Avi Dayan IBM Security Systems
  • 2. agenda • Motivation and Introduction • Linux Random Number Generator
  • 3. agenda • Motivation and Introduction • Linux Random Number Generator • Our Attack • 1st Attack Vector – Local Atk. • Demo • 2nd Attack Vector – Remote Atk.
  • 4. agenda • Motivation and Introduction • Linux Random Number Generator • Our Attack • 1st Attack Vector – Local Atk. • Demo • 2nd Attack Vector – Remote Atk. • Mitigations
  • 6. motivation_keystore_buffer_overflow • We discovered CVE-2014-3100, a stack-based Buffer Overflow in Keystore • Service responsible for securely storing crypto related data • We had privately reported to Google and they provided a patch available in KITKAT. Whitepaper. • Exploit must overcome various defense mechanisms, including Stack Canaries. /* KeyStore is a secured storage for key-value pairs. In this implementation, * each file stores one key-value pair. Keys are encoded in file names, and * values are encrypted with checksums. The encryption key is protected by a * user-defined password. To keep things simple, buffers are always larger than * the maximum space we needed, so boundary checks on buffers are omitted. */
  • 7. motivation_keystore_buffer_overflow Stack canaries and their enforcement LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) __stack_chk_guard Stack Guard initialization 32 bits 128 bits • On libbionic load: __stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM)); • Function Prologue: ● Place __stack_chk_guard on the stack (before ret). • Function Epilogue: ● Compare saved stack canary with __stack_chk_guard; → Crash if mismatch
  • 8. motivation_keystore_buffer_overflow Stack canaries and their enforcement LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) __stack_chk_guard Stack Guard initialization 32 bits 128 bits • On libbionic load: __stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM)); • Function Prologue: ● Place __stack_chk_guard on the stack (before ret). • Function Epilogue: ● Compare saved stack canary with __stack_chk_guard; → Crash if mismatch ● fork() → execve(). ● execve() → Auxiliary vector (AUXV) ● AUXV[AT_RANDOM] = 16 Random bytes from the PRNG ● libbionic assigns canary = first 4 bytes of AT_RANDOM Canary origins; *nix process creation model
  • 9. motivation_keystore_buffer_overflow Stack canaries and their enforcement LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) __stack_chk_guard Stack Guard initialization 32 bits 128 bits • On libbionic load: __stack_chk_guard = *(uintptr_t *)getauxval(AT_RANDOM)); • Function Prologue: ● Place __stack_chk_guard on the stack (before ret). • Function Epilogue: ● Compare saved stack canary with __stack_chk_guard; → Crash if mismatch ● fork() → execve(). ● execve() → Auxiliary vector (AUXV) ● AUXV[AT_RANDOM] = 16 Random bytes from the PRNG ● libbionic assigns canary = first 4 bytes of AT_RANDOM Canary origins; *nix process creation model Remember this; We'll get back to it
  • 10. motivation_keystore_buffer_overflow LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) __stack_chk_guard Stack Guard initialization 32 bits 128 bits Attacks on the Stack-Smashing Protection: • Naive Online Bruteforce of the Canary Value • Impractical: 2^32 attempts on average.
  • 11. motivation_keystore_buffer_overflow LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) __stack_chk_guard Stack Guard initialization 32 bits 128 bits Attacks on the Stack-Smashing Protection: • Naive Online Bruteforce of the Canary Value • Impractical: 2^32 attempts on average. • Online Learning of the Canary Value • By another info leak issue • Re-forking server: • Very efficient: 514 attempts until success on average
  • 12. motivation_keystore_buffer_overflow LR Saved Registers Canary (32 bits) Buffer Stack layout Linux PRNG AUXV(AT_RANDOM) Stack Guard initialization 32 bits 128 bits __stack_chk_guard Attacks on the Stack-Smashing Protection: • Naive Online Bruteforce of the Canary Value • Impractical: 2^32 attempts on average. • Online Learning of the Canary Value • By another info leak issue • Re-forking server: • Very efficient: 514 attempts until success on average • Overwrite __stack_chk_guard • By overwriting some pointer
  • 13. motivation_keystore_buffer_overflow LR Saved Registers Canary (32 bits) Buffer Attacks on the Stack-Smashing Protection: • Naive Online Bruteforce of the Canary Value • Impractical: 2^32 attempts on average. • Online Learning of the Canary Value • By another info leak issue • Re-forking server: • Very efficient: 514 attempts until success on average • Overwrite __stack_chk_guard • By overwriting some pointer • Our attack: Offline reconstruction of the PRNG’s internal state Stack layout Linux PRNG AUXV(AT_RANDOM) Stack Guard initialization 32 bits 128 bits __stack_chk_guard__stack_chk_guard__stack_chk_guard
  • 14. motivation_wrap_up LR Saved Registers Canary (32 bits) Buffer Wrap things up: • We found a vulnerability in a critical service in Android 4.3. • In an effort to exploit it, we had to overcome a stack canary, we couldn't do so using known techniques. • Canaries are 4 random bytes that are extracted from the Linux PRNG. • Aimed to find a weakness in the PRNG that will allow us to intelligently guess the canary. • End up with a full-fledged attack on the Linux PRNG. Stack layout Linux PRNG AUXV(AT_RANDOM) Stack Guard initialization 32 bits 128 bits __stack_chk_guard__stack_chk_guard__stack_chk_guard
  • 16. INPUT POOL BLOCKING POOL NON-BLOCKING POOL /dev/urandom /dev/random get_random_bytes() lprng_overview Bird's eye view • Output is hashed twice using SHA1 • Extracts in blocks of 10 bytes and truncates if necessary.
  • 17. INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) INTERRUPT DISK INPUT T I M E R time if KEC >= 192 bits *KEC = Kernel Entropy Count entropy_sources 63 31 0 seconds nanoseconds
  • 18. INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) INTERRUPT DISK INPUT T I M E R time if KEC < 192 bits *KEC = Kernel Entropy Count boot_time_vulnerability 63 31 0 seconds nanoseconds
  • 20. boot_timeline Device powers on Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready May occur In different order
  • 22. Prior art on weakness in early boot * Present practical run-time attack Formalize attack Demonstrate PoC against current mobile platforms contribution * Heninger et al. 2012, Becherer et al. 2009, Ding et al. 2014
  • 23. Given a LEAK of a value extracted from the non-blocking pool and LOW ENTROPY AT BOOT, the STATE of the PRNG can be determined until external entropy is too high attack_outcome
  • 24. NON-BLOCKING-POOL seed_t1 EXTRACTION (PULL) 63 31 0 seconds nseconds Using the PRNG against itself ● Recall: Low boot-time entropy degenerates the PRNG and that the output of the PRNG is hashed twice using SHA1. ● Fact: Crypto. hash functions are designed to be collision resistant. attack_leak NON-BLOCKING-POOL EXTRACTION (PULL) ≠ seed_t2 seed_t1 63 31 0 seconds nseconds
  • 25. NON-BLOCKING-POOL seed_t1 EXTRACTION (PULL) 63 31 0 seconds nseconds Using the PRNG against itself ● Recall: Low boot-time entropy degenerates the PRNG and that the output of the PRNG is hashed twice using SHA1. ● Fact: Crypto. hash functions are designed to be collision resistant. ● It is highly unlikely that PRNGs that are seeded with different seeds will result in the same output. Regardless of the order of extractions. attack_leak NON-BLOCKING-POOL EXTRACTION (PULL) ≠ seed_t2 seed_t1 63 31 0 seconds nseconds
  • 26. NON-BLOCKING-POOL seed_t1 EXTRACTION (PULL) 63 31 0 seconds nseconds Using the PRNG against itself ● Recall: Low boot-time entropy degenerates the PRNG and that the output of the PRNG is hashed twice using SHA1. ● Fact: Crypto. hash functions are designed to be collision resistant. ● It is highly unlikely that PRNGs that are seeded with different seeds will result in the same output. Regardless of the order of extractions. ● Result: Every leak(sequence of random bytes) from the non blocking pool is almost certainly the offspring of one specific seed. attack_leak NON-BLOCKING-POOL EXTRACTION (PULL) ≠ seed_t2 seed_t1 63 31 0 seconds nseconds
  • 27. Using the PRNG against itself ● Given a leak from the nonblocking pool of a “Real” PRNG we could simulate offline PRNGs with different seeds and compare extractions with the online leak. attack_overview REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 28. Using the PRNG against itself ● Given a leak from the nonblocking pool of a “Real” PRNG we could simulate offline PRNGs with different seeds and compare extractions with the online leak. ● Due to SHA1's collision resistance, if one of the simulated PRNGs produces a sequence of random bytes that is the same as the leak value – we almost certainly found the seed. attack_overview REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 29. Using the PRNG against itself ● Given a leak from the nonblocking pool of a “Real” PRNG we could simulate offline PRNGs with different seeds and compare extractions with the online leak. ● Due to SHA1's collision resistance, if one of the simulated PRNGs produces a sequence of random bytes that is the same as the leak value – we almost certainly found the seed. ● Once we have the seed we can produce the same outputs of the “Real” PRNG until noise from the Input pool is mixed to the Nonblocking pool attack_overview REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 30. Even After the mixing, the PRNG is vulnerable ● Note: in the whitepaper we demonstrated a more intricate attack flow attack_overview REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 31. Problems we faced: ● The Nonblocking pool seed is 8 bytes long, Say we consider only the nanoseconds and assuming uniform distribution attack_overview 10 9 =2 log2 (10 9 ) ≃2 30 63 31 0 seconds nanoseconds REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 32. Problems we faced: ● The Nonblocking pool seed is 8 bytes long, Say we consider only the nanoseconds and assuming uniform distribution ● Hidden entropy source – Concurrency attack_overview 10 9 =2 log2 (10 9 ) ≃2 30 REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE 1 2 3 4 3 4 POOL STATE Yellow Path - Process A: extract from pool - Process A: mix into pool - Process B: extract from pool - Process B: mix into pool Green Path - Process A: extract from pool - Process B: extract from pool - Process A: mix into pool - Process B: mix into pool
  • 33. Problems we faced: ● The Nonblocking pool seed is 8 bytes long, Say we consider only the nanoseconds and assuming uniform distribution ● Hidden entropy source – Concurrency ● What can be attacked? ● Where can we get the leak value? attack_overview 10 9 =2 log2 (10 9 ) ≃2 30 REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE
  • 34. Where can we find leaks and attack targets ? attack_overview Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target Device powers on
  • 35. Terminology attack_overview Device powers on Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Kernel Boot-time Leak/Target Platform Boot-time Leak/Target Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target
  • 36. 1st Attack Vector Malware → PRNG Seed → Keystore's Canary
  • 37. Instrumenting a device ● Samsung Galaxy S4, Android 4.3 s4_offline_study
  • 38. Instrumenting a device ● Samsung Galaxy S4, Android 4.3 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets s4_offline_study
  • 39. Instrumenting a device ● Samsung Galaxy S4, Android 4.3 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets ● Fixed the seeds to see catch some bias in the order of extractions – find bias in conc. s4_offline_study
  • 40. Instrumenting a device ● Samsung Galaxy S4, Android 4.3 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets ● Fixed the seeds to see catch some bias in the order of extractions – find bias in conc. ● In total, we rebooted(script) the device more than 2000 times, each time we dumped the kernel ring buffer to a file. s4_offline_study
  • 41. Details s4_attack_leak Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target Device powers on Platform Boot-time Leak/Target
  • 42. Details ● Android designers chose to spawn every app process by forking a master process – Zygote s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 43. Details ● Android designers chose to spawn every app process by forking a master process – Zygote ● Zygote(app_process) is fork'ed and exec'ed by init at platform boot-time s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 44. Details ● Android designers chose to spawn every app process by forking a master process – Zygote ● Zygote(app_process) is fork'ed and exec'ed by init at platform boot-time ● *nix-like vs. App process creation model. Exec() ? s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 45. Details ● Android designers chose to spawn every app process by forking a master process – Zygote ● Zygote(app_process) is fork'ed and exec'ed by init at platform boot-time ● *nix-like vs. App process creation model. Exec() ? ● Recall: exec() enforces ASLR and assigns the AT_RANDOM s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 46. Details ● Result: All Applications in Android has the same Canary value (AT_RANDOM) and largely the same address space layout s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... fork() AUXV(AT_RANDOM) Zygote Linux PRNG AUXV(AT_RANDOM) – Zygote's WhatsApp AUXV(AT_RANDOM) – Zygote's Contacts AUXV(AT_RANDOM) – Zygote's MALWARE fork() leak/target
  • 47. Details ● Result: All Applications in Android has the same Canary value (AT_RANDOM) and largely the same address space layout s4_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... fork() AUXV(AT_RANDOM) Zygote Linux PRNG AUXV(AT_RANDOM) – Zygote's WhatsApp AUXV(AT_RANDOM) – Zygote's Contacts AUXV(AT_RANDOM) – Zygote's MALWARE fork() fork() leak/target
  • 48. s4_attack_leak_concurrency REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given a leak, what's the probability of finding the original seed ? ● Zygote's AT_RANDOM is our leak It's a platform boot-time leak, which means It occurs in the 'Concurrency Hell' phase leak/target
  • 49. s4_attack_leak_concurrency REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given a leak, what's the probability of finding the original seed ? ● Zygote's AT_RANDOM is our leak It's a platform boot-time leak, which means It occurs in the 'Concurrency Hell' phase ● An offline study of the samples revealed bias towards a specific extraction path from the nonblocking pool leak/target
  • 50. s4_attack_leak_concurrency REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given a leak, what's the probability of finding the original seed ? ● Zygote's AT_RANDOM is our leak It's a platform boot-time leak, which means It occurs in the 'Concurrency Hell' phase ● An offline study of the samples revealed bias towards a specific extraction path from the nonblocking pool ● 20% of the samples had Zygote's AT_RANDOM bytes somewhere in the extraction path leak/target
  • 51. s4_attack_leak_concurrency REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given a leak, what's the probability of finding the original seed ? ● Given a leak and assuming we try all 230 possible seeds the chance is leak/target 1 5
  • 52. H (snb)=23.5bits s4_non-blocking_seed REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 53. = LEAK ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE s4_attack_targets leak/target Given a seed, Probabilities of finding the canary of early boot services
  • 54. = LEAK ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given a seed, Probabilities of finding the canary of early boot services SIM. PRNG seed_t_k RANDOM VALUE s4_attack_targets leak/target 6 100
  • 55. = LEAK ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given Zygote's AT_RANDOM, the probability of guessing the Keystore's canary value is: SIM. PRNG seed_t_k RANDOM VALUE s4_attack_targets leak/target 1 5 ⋅ 6 100 ≃0.01→1% Remember where we came from... we needed to guess 32 random bits
  • 56. = LEAK ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... Given Zygote's AT_RANDOM, the probability of guessing the Keystore's canary value is: SIM. PRNG seed_t_k RANDOM VALUE s4_attack_targets leak/target 1 5 ⋅ 6 100 ≃0.01→1% 1 232 ≃0.00000000023→0.000000023%
  • 57. DEMO s4_demo = LEAK ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... SIM. PRNG seed_t_k RANDOM VALUE leak/target
  • 58. 2nd Attack Vector Ping6 → PRNG Seed → IPv6 Fragment Injection & Getting Keystore's Canary
  • 59. Instrumenting a device ● Samsung Galaxy S2, Android 4.1.2 s2_offline_study
  • 60. Instrumenting a device ● Samsung Galaxy S2, Android 4.1.2 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets s2_offline_study
  • 61. Instrumenting a device ● Samsung Galaxy S2, Android 4.1.2 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets ● Fixed the seeds to see catch some bias in the order of extractions – find bias in conc. s2_offline_study
  • 62. Instrumenting a device ● Samsung Galaxy S2, Android 4.1.2 ● printk() input and nonblocking pool seeds - find a bias in the seed value ● printk() get_random_bytes() callers and amount of random bytes requested – find leak and attack targets ● Fixed the seeds to see catch some bias in the order of extractions – find bias in conc. ● In total, we rebooted(script) the device more than 2000 times, each time we dumped the kernel ring buffer to a file. s2_offline_study
  • 63. Details s2_attack_leak Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target Device powers on Kernel Boot-time Leak/Target
  • 64. Details ● While the kernel is brought up, an IPv6 module initializes and extracts 4 random bytes. Lets call them rand. s2_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target
  • 65. Details ● While the kernel is brought up, an IPv6 module initializes and extracts 4 random bytes. Lets call them rand. ● IPv6 packet fragment identifier is computed by a deterministic function. s2_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target f(rand, ipv6_dst_addr)=ipv6_frag_id
  • 66. Details ● While the kernel is brought up, an IPv6 module initializes and extracts 4 random bytes. Lets call them rand. ● IPv6 packet fragment identifier is computed by a deterministic function. ● The pair (ipv6_dst_addr,ipv6_frag_id) is our leak. Why? s2_attack_leak REAL PRNG = LEAK ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... leak/target f(rand, ipv6_dst_addr)=ipv6_frag_id
  • 67. Details ● While the kernel is brought up, an IPv6 module initializes and extracts 4 random bytes. Lets call them rand. ● IPv6 packet fragment identifier is computed by a deterministic function. ● The pair (ipv6_dst_addr,ipv6_frag_id) is our leak. Why? ● We simulate PRNGs up to rand, and feed it to the deterministic function f s2_attack_leak REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target f(rand, ipv6_dst_addr)=ipv6_frag_id
  • 68. Details ● While the kernel is brought up, an IPv6 module initializes and extracts 4 random bytes. Lets call them rand. ● IPv6 packet fragment identifier is computed by a deterministic function. ● The pair (ipv6_dst_addr,ipv6_frag_id) is our leak. Why? ● We simulate PRNGs up to rand, and feed it to the deterministic function f ● OK, fine, but how did you get ipv6_dst_addr? s2_attack_leak REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target f(rand, ipv6_dst_addr)=ipv6_frag_id
  • 69. IPv6 fragmentation & ICMPv6 Echo Req. ● IP packets that exceed the path MTU, are divided into fragments which are sent and then reassembled by receiver. s2_attack_leak leak/target
  • 70. IPv6 fragmentation & ICMPv6 Echo Req. ● IP packets that exceed the path MTU, are divided into fragments which are sent and then reassembled by receiver. ● Each fragment of the packet contains the same fragment id. Which is used by the receiver to identify fragments of a packet. s2_attack_leak leak/target
  • 71. IPv6 fragmentation & ICMPv6 Echo Req. ● IP packets that exceed the path MTU, are divided into fragments which are sent and then reassembled by receiver. ● Each fragment of the packet contains the same fragment id. Which is used by the receiver to identify fragments of a packet. ● IPv6 fragmentation doesn't happen very often. How do we make it happen ? s2_attack_leak leak/target
  • 72. IPv6 fragmentation & ICMPv6 Echo Req. ● Ping6 – a utility for sending ICMPv6 Echo Requests which requires the target to send an ICMPv6 Echo Replay with the exactly the same data. s2_attack_leak leak/target
  • 73. IPv6 fragmentation & ICMPv6 Echo Req. ● Ping6 – a utility for sending ICMPv6 Echo Requests which requires the target to send an ICMPv6 Echo Replay with the exactly the same data. ● Result: Sending ICMPv6 Echo Request with data > MTU will make the receiver send a fragmented reply s2_attack_leak leak/target
  • 74. s2_attack_get_leak Amsterdam Schiphol Airport REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target
  • 75. s2_attack_get_leak Amsterdam Schiphol Airport A REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target
  • 77. s2_attack_get_leak Amsterdam Schiphol Airport SSID= Schiphol Free A V REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target
  • 78. s2_attack_get_leak Amsterdam Schiphol Airport SSID= Schiphol Free Fragmented ICMPv6 Echo Request A V REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target
  • 79. s2_attack_get_leak Amsterdam Schiphol Airport SSID= Schiphol Free Fragmented ICMPv6 Echo Request Fragmented ICMPv6 Echo Reply A V REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target
  • 80. s2_attack_get_leak Amsterdam Schiphol Airport SSID= Schiphol Free Fragmented ICMPv6 Echo Request Fragmented ICMPv6 Echo Reply Attacker got the leak: ● V computed ipv6_frag_id with A's ipv6_src_addr ● A knows ipv6_frag_id and ipv6_dst_addr. REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n leak/target A V
  • 81. s2_attack_finding_seed REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n Given the leak we find the seed H (snb)=18.4bits leak/target
  • 82. s2_attack_targets REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n Given the seed what can we attack ? ● IPv6 Fragment injection – We can derive the exact fragment id V will use for any destination address. leak/target
  • 83. s2_attack_targets REAL PRNG = ipv6_frag_id ? seed_t_k LEAK SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n Given the seed what can we attack ? ● IPv6 Fragment injection – We can derive the exact fragment id V will use for any destination address. ● Canary value of early boot services. For instance, with a probability of 1/20 we can compute Keystore's canary value, given the seed. targetleak
  • 84. = ipv6_frag_id ? SIM. PRNG seed_t_1 SIM. PRNG seed_t_k SIM . PRNG seed_t_n ... ... rand_t_1 rand_t_k f(rnd,dst) f(rnd,dst) f(rnd,dst) rand_t_n SIM. PRNG seed_t_k RANDOM VALUE s2_attack_targets Probabilities of finding the canary of early boot services leak target
  • 86. mitigations Current mitigations ● Save entropy across boots INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) T I M E R INTERRUPT DISK INPUT time if KEC >= 192 bits
  • 87. mitigations Current mitigations ● Save entropy across boots ● Trusted external entropy injection – web service / HWRNG INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) T I M E R INTERRUPT DISK INPUT time if KEC >= 192 bits
  • 88. mitigations Problem with those mitigations Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target Device powers on Injecting Entropy to Pools Entropy
  • 89. mitigations Problem with those mitigations Kernel starts booting PRNG is initialized Kernel boot Finished & Platform starts booting Input Pool mixed into Nonblocking Pool :( Phone is ready Concurrency Hell Best Leak/Target Good Leak/Target Bad Leak/Target Device powers on Kernel Boot-time Leak/Target Injecting Entropy to Pools Entropy Entropy injection occurs after the kernel boots up
  • 90. mitigations Current mitigations ● Initialize the seeds using a hardware RNG ● RDRAND,RDSEED Intel's ISA ● Early random, Qualcomm INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) T I M E R INTERRUPT DISK INPUT time if KEC >= 192 bits
  • 91. mitigations Current mitigations ● Initialize the seeds using a hardware RNG ● RDRAND,RDSEED Intel's ISA ● Early random, Qualcomm ● Mix device-specific data to nonblocking and blocking pools INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) T I M E R INTERRUPT DISK INPUT time if KEC >= 192 bits
  • 92. mitigations Current mitigations ● Initialize the seeds using a hardware RNG ● RDRAND,RDSEED Intel's ISA ● Early random, Qualcomm ● Mix device-specific data to nonblocking and blocking pools ● Changes to newer kernels allow for more boot time entropy INPUT POOL NON-BLOCKING-POOL ktime_t ktime_t EXTRACTION (PULL) T I M E R INTERRUPT DISK INPUT time if KEC >= 192 bits
  • 93. talk_wrap_up • Linux-based devices with low boot time entropy may allow a practical, low-cost attack on the PRNG • The attack requires an offline study of a device and an online leak • Allows the attacker to predict a random number which is generated by the victim's PRNG • Two manifestations - Local/Remote Atk. • Mitigations
  • 94. ? Thank you Thanks Nadja Kahan for the illustrations ! http://www.nadjakahan.com