Thursday, December 4, 2014

The truth about mobile security

Here is the deck I gave during the Solution Connect 2014 event. Usually I don't make public posts with decks but since they did it, I will do the same :)

Tuesday, December 2, 2014

kprobes on Android arm64, the story

I am trying to bring kprobes support into Android (arm64); actually don't need the full kprobes stack at the moment but something light like jprobe would be enough. Of course having the full instrumentation capabilities... wow

Sandeep Prabhu first and later David (Dave) Long from Linaro are working on a similar task. I wrote and talked to both of them.

Here is where I stand:

I tried first the patch from Dave getting out a lot of problems, and finally I moved back to the original patch from Sandeep getting almost the same results.

- compiled the simple sample/kprobes/jprobes_example.c module and trying to load it, it's a simple instrumentation of do_fork showing params passed.
- I am working on two different kernels: goldfish android kernel (google repo branch  android-goldfish-3.10 ) 3.10 AND linaro-stable-kernel android 3.14 (origin branch linux-linaro-lsk-v3.14-android). 
Sandeep patch was initially wrote for 3.14.
- to test, I am using qemu (arm64 not yet available in google emulators), latest version google forked of qemu include ranchu (aarch64 armv8 vm), it's possible to run android on it. I wrote more, see my previous two articles: 

The jprobe is implanted correctly but when do_fork happens: Bad mode in Synchronous Abort handler detected

(#define in asm/ptrace.h patched - see below)

insmod jprobe_example.ko                                                       <
Planted jprobe at ffffffc000096800, handler addr ffffffbffc000000
shell@mini-emulator-arm64:/system/vito # ls
Bad mode in Synchronous Abort handler detected, code 0x84000005
CPU: 0 PID: 1068 Comm: sh Tainted: G           O 3.14.25+ #5
task: ffffffc03ee93d80 ti: ffffffc03dc58000 task.ti: ffffffc03dc58000
PC is at 0x0
LR is at 0x10001
pc : [<0000000000000000>] lr : [<0000000000010001>] pstate: 00100145
sp : ffffffc03dc5c040
x29: 0000000000000000 x28: 0000000000000000
x27: 0000000000000000 x26: 0000000000000000
x25: 00000000000000dc x24: 0000000001200011
x23: 0000000060000000 x22: 0000007fa4a765a0
x21: 0000007ff043e270 x20: 0000007fa4a78498
x19: 0000007ff043e270 x18: 0000005574556000
x17: 0000000000000000 x16: 00000000ffffffff
x15: 0000007ff043e318 x14: 0000005574557620
x13: 0000007fa471e2a8 x12: 0000007fa4775108
x11: 000000000000042c x10: 0000000000000001
x9 : 0000007fa4b580e8 x8 : 0000000000000000
x7 : 0000007fa4a76580 x6 : 0000007fa4b1a180
x5 : 0000000000000000 x4 : 0000007fa4b28000
x3 : 0000007fa4b1a000 x2 : 000000000000000c
x1 : 0000007fa4700ac8 x0 : 000000000000042f

Internal error: Oops - bad mode: 0 [#1] SMP
Modules linked in: jprobe_example(O)
CPU: 0 PID: 1068 Comm: sh Tainted: G           O 3.14.25+ #5
task: ffffffc03ee93d80 ti: ffffffc03dc58000 task.ti: ffffffc03dc58000
PC is at 0x0
LR is at 0x10001
pc : [<0000000000000000>] lr : [<0000000000010001>] pstate: 00100145
sp : ffffffc03dc5c040
x29: 0000000000000000 x28: 0000000000000000
x27: 0000000000000000 x26: 0000000000000000
x25: 00000000000000dc x24: 0000000001200011
x23: 0000000060000000 x22: 0000007fa4a765a0
x21: 0000007ff043e270 x20: 0000007fa4a78498
x19: 0000007ff043e270 x18: 0000005574556000
x17: 0000000000000000 x16: 00000000ffffffff
x15: 0000007ff043e318 x14: 0000005574557620
x13: 0000007fa471e2a8 x12: 0000007fa4775108
x11: 000000000000042c x10: 0000000000000001
x9 : 0000007fa4b580e8 x8 : 0000000000000000
x7 : 0000007fa4a76580 x6 : 0000007fa4b1a180
x5 : 0000000000000000 x4 : 0000007fa4b28000
x3 : 0000007fa4b1a000 x2 : 000000000000000c
x1 : 0000007fa4700ac8 x0 : 000000000000042f

Process sh (pid: 1068, stack limit = 0xffffffc03dc58058)
Stack: (0xffffffc03dc5c040 to 0xffffffc03dc5c000)
Call trace:
Code: bad PC value
---[ end trace 77f3ec18f6ecc57c ]---
Kernel panic - not syncing: Fatal exception

I kind of figure out something bad. PC is zero, :O who did that.. it must be something wrong with who is handling PC.
In the patched tree, ptrace.h is kind of "old":

original in my kernel, android goldfish: 
#define instruction_pointer(regs)       ((unsigned long)(regs)->pc)
in the patch sandeepa's tree: 
#define instruction_pointer(regs)       (regs)->pc
or dave's tree:
#define instruction_pointer(regs)       ((regs)->pc)

This change was introduced back in time by commit 27aa55c5e5

git diff 27aa55c5e5123fa8b8ad0156559d34d7edff58ca arch/arm64/include/asm/ptrace.h

  * Are the current registers suitable for user mode? (used to maintain
@@ -190,7 +183,7 @@ static inline int valid_user_regs(struct user_pt_regs *regs)
        return 0;

-#define instruction_pointer(regs)      (regs)->pc
+#define instruction_pointer(regs)      ((unsigned long)(regs)->pc)

so if I finally set back the original value casted with (unsigned long) in the define, the compilation obviously fails like this:

errors with ktrace.c

arch/arm64/kernel/kprobes.c: In function ‘skip_singlestep_missed’:
arch/arm64/kernel/kprobes.c:201:28: error: lvalue required as left operand of assignment
  instruction_pointer(regs) += sizeof(kprobe_opcode_t);
arch/arm64/kernel/kprobes.c: In function ‘setup_singlestep’:
arch/arm64/kernel/kprobes.c:241:29: error: lvalue required as left operand of assignment
   instruction_pointer(regs) = slot;
arch/arm64/kernel/kprobes.c: In function ‘post_kprobe_handler’:
arch/arm64/kernel/kprobes.c:286:29: error: lvalue required as left operand of assignment
   instruction_pointer(regs) = cur->ainsn.restore.addr;
arch/arm64/kernel/kprobes.c: In function ‘kprobe_fault_handler’:
arch/arm64/kernel/kprobes.c:325:29: error: lvalue required as left operand of assignment
   instruction_pointer(regs) = (unsigned long)cur->addr;
arch/arm64/kernel/kprobes.c: In function ‘setjmp_pre_handler’:
arch/arm64/kernel/kprobes.c:495:28: error: lvalue required as left operand of assignment
  instruction_pointer(regs) = (long)jp->entry;
At this point I can use the patched ptrace.h in Dave's tree //like less// or patch ktrace.c to fix the assignments like this //which I believe is not wrong//:

- instruction_pointer(regs) = slot;
+ (regs)->pc = slot;

I always end up with the same results:

(WITH kprobes.c FILE PATCHED and #define in .h left as original)

shell@mini-emulator-arm64:/data/local/tmp # 
init[1]: unhandled level 2 permission fault (11) at 0xffffffc0000a75cc, esr 0x8100000e
pgd = ffffffc03ddc4000
[ffffffc0000a75cc] *pgd=0000000000000000

CPU: 0 PID: 1 Comm: init Tainted: G           O 3.10.0+ #12
task: ffffffc03ec58000 ti: ffffffc03ec60000 task.ti: ffffffc03ec60000
PC is at do_no_restart_syscall+0x0/0x8
LR is at 0xffffffc03ec58940
pc : [] lr : [] pstate: 00000000
sp : ffffffc0005c0d90
x29: ffffffffffffffff x28: 0000000000000000
x27: 0000000000000000 x26: 0000000000000000
x25: 00000000000000dc x24: 0000000001200011
x23: 0000000060000000 x22: 00000000004173b4
x21: 0000007fce10e430 x20: 0000000000418104
x19: 0000007fce10e430 x18: 0000000000404298
x17: 0000000000486000 x16: 0000000000000001
x15: 0000000000000000 x14: 0000000000000000
x13: 0000007fce10e8f8 x12: 0000007fce10e500
x11: 0000000000000001 x10: 0000000000484000
x9 : 00000000004884e0 x8 : 0000000000000000
x7 : 0000000000000001 x6 : 0000000000022ab0
x5 : 15787f021d0f0000 x4 : 000000000048a000
x3 : 0000000000484000 x2 : 0000000000000014
x1 : 00000000ffffff80 x0 : 0000000000000b19

Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

CPU: 0 PID: 1 Comm: init Tainted: G           O 3.10.0+ #12
Call trace:
[] dump_backtrace+0x0/0x12c
[] show_stack+0x10/0x1c
[] dump_stack+0x1c/0x28
[] panic+0xe4/0x208
[] do_exit+0x880/0x948
[] do_group_exit+0x3c/0xd4
[] get_signal_to_deliver+0x158/0x4cc
[] do_signal+0x544/0x570
[] do_notify_resume+0x5c/0x68

I am kind of running out of ideas, I think it's a memory issue from mm.c or kind of paging issue (protected level 2 makes me thinking of) even attaching a debugger I don't believe it helps a lot!

Friday, November 21, 2014

Tutorials on how to build, edit and debug Android Kernel ARM64 (aarch64)

Lot of people connected to me look interested to the topic, here I decided to create a short tutorial on how download and build the kernel for aarch64 platform, make it run on QEMU (see previous article) and finally, navigate it in Eclipse, or edit it up to debugging the running kernel via GDB or in Eclipse through the IDE.

Yeahh, I know, I real kernel developer uses Vim or Emacs to play with the kernel code; unfortunately I am not a kernel developer, don't blame me!

Here the goal is not to write kernel code but to understand what happens, read the code with the help of Eclipse indexing and if you are brave, debug it!


1) need a proper toolchain for aarch64 installed (check ubuntu development essential for aarch64 package or just get what you need via single hit apt-get install). Ubuntu 14.04 has a repo with a good Linaro aarch64 toolchain 4.8 which works great!
2) optionally, get NDK from Google. The version 4.9 supports aarch64.
3) Eclipse Luna get it from, of course you need the package for C/C++ developers which includes CDT
4) Optionally, if you don't like the Eclipse base Cross GCC plugin, I would recommend to get ARM Cross GCC which ships magically with a Linaro aarch64-linu-gnu- predefined toolchain and is a lot less work in configuration and pain getting compiler macros.

Get the code and compile it, here is the video

Configure Eclipse to properly deal with Kernel Code (thanks here to the forum article)

Play with debugging

Just heard some comments, and adding this. Eclipse could, actually will, run out of memory during the re-indexing of such a big codebase. You need to tune up memory management in eclipse.ini. I attack here my eclipse.ini, the trick is to give more max heap memory -xmx and start with a bigger base minim memory -xms. Yes, I know, at the time I was looking into Java (version 6) the maximum cannot go over 1024Kb; had no time to investigate if this is still a valid limit. Set it to 2048 :)

Saturday, November 8, 2014

Ranchu where are you, kernel and emulator aarch64 (arm64)

With the release of lollipop Android L, few things have changes. First emulator64-arm64 is not included in the AOSP any more, it's a project on its own.

Find it here, git clone and compile:

As soon as a dedicated team of engineer will perform proper testing, one day or another expect to see it back. For the time being, it's kept in a different source repo.

Once you get it, you may wonder how to compile proper kernel, where is ranchu (beside the version you have on linaro), guess where it is? ranchu as natural successor of goldfish, Linux Kernel 3.10 is available (do not expect to see older versions)

1) get a proper toolchain (4.9 at least to have support for arm64, the one that ships in ubuntu repo aarch64-linux-gnu- should work fine too)

2) get the kernel source (you need this specific repo)

git clone -b android-goldfish-3.10

3) compile

make ARCH=arm64 ranchu_defconfig
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j8
(prerequisite install arm64 compiler toolchain from your repos or from google, NDK with compiler 4.9)

A working kernel is built and available as explained in my previous post

Second the build for arm64 is kind of screwed on AOSP 5.0 r2.
The vendorsetup for a full aosp 64 bit ranchu is not there, but funny enough the make script is!
Another good useful point is the mini_emulator which allows to have a running shell only mini version of android running on qemu. If your goal is to work with low level os stuff, this is your way.

mini emulator arm64

makefile are literally wrong, they point to armv7 build, thus you build the mini_emulator_arm64 and get out the armv7 32 bit version... woaahhh

so I fixed the files, you need also to include proper init.rc for ranchu, fstab and other bits.
this file contains my fixed scripts.

- just untar it in the AOSP/device/generic
on AOSP root folder, source the build env

source build/
lunch mini_emulator_arm64-userdebug 
m -j8

wait... you'll get out/products/mini-emulator-arm64 with *.img files to run the emulator like described in my previous article, it works!

full AOSP arm64 on qemu

here it's even easier, google was a bit more kind and left the make files there, you just miss the vendorsetup to get the lunch bundle. in the file above, download it, you have it. it extracts the file in the device/generic/qemu folder. just do it and select the new entry:

source build/
lunch ranchu_arm64-eng
m -j8

Tuesday, November 4, 2014

Android L AOSP(preview) under ARM64 (aarch64) QEMU emulator

As many others, I can't wait to put my hands on Android running on aarch64 (arm-v8) and as many other, it's difficult to afford such an expensive Juno board (the only development board arm-v8 available which I am aware of) If you Google a bit you'll bump into this cool article:

The Linaro team put together ahead of time, around may 2014, a version of the Kernel for aarch64 called ranchu (forked from 3.10) and patched/worked together with the qemu team to create a machine model ranchu capable of emulating aarch64. Everything is well explained in the article above. 

However, by compiling the latest Android L preview 2 AOSP, I ended up with serious issues during the zygote startup. It looks there is something seriously different in how is made, thus passing it to patchoat (at first time boot) something goes very wrong. Not going into details of the hell issue.

Sometimes, when things goes wrong, better to restart from scratch. It's the old rule learned since the old Windows 95 time, hit ctrl-alt-delete. 

While compiling the AOSP, I noticed that into the prebuilt folder you have something called emultator64-arm64 which sounds pretty much what I wanted; who said that Google is not providing amr64 emulation yet? :) Yes, it's not official, emulator images are not provided with the latest SDKv19 but I happily found another piece of gold. In the folder qemu-kernel/arm64/kernel-qemu this file sounds very much like the kernel prebuilt for the arm64 emulator. Why not trying compiling AOSP for generic arm64 support? in the end the device reference is there in the AOSP without any patching... and voila...

Here are the steps to follow:

1) get Android L developer preview AOSP

cd /data/src
mkdir AOSP 
repo init -u -b android-l-preview_r2
repo sync

wait a considerable amount of time to sync, almost 2 hours, prepare almost 100GB on your drive
note: you need repo command from google configured on your system.

2) have fun and compile (takes almost 1h on a decent machine)

source build/
lunch aosp_arm64-eng
m -j8
here is the lunch output

3) move to the prebuilt emulator folder, in my case I am under linux-x64, chose your arch

cd /data/src/AOSP/prebuilts/android-emulator/linux-x86_64

4) to run the emulator you need anyhow an AVD configuration or start it manually from the qemu binary without using the google emulator wrapper. I prefer to use the wrapper here as the command is cleaner.

create an AVD using your ANDROID SDK, launch 

./android avd

(from platform tools, you can create one via command line ./android create)

or if you have already defined AVDs, just use one of them, settings will be overwritten by the command, so whatever you have in your AVD you are just using the config.ini file (stored in the .android folder). Preferably, set your AVD with more then 1024 MB ram. 

5) now you are ready to launch the emulator, here is the command (all one line). 

testL is the name of the AVD prepared. Wait, wait wait for android to finish booting, remember you are on a slow emulation, it takes time. If you are curios to see what's going on, just run "logcat" at the prompt to see all the mess in real time. 

./emulator64-arm64 -kernel ../../qemu-kernel/arm64/kernel-qemu -data /data/src/AOSP/out/target/product/generic_arm64/system.img -system /data/src/AOSP/out/target/product/generic_arm64/system.img -cache /data/src/AOSP/out/target/product/generic_arm64/cache.img -ramdisk /data/src/AOSP/out/target/product/generic_arm64/ramdisk.img -avd testL

Output, kernel boot and android prompt:

console on port 5554, ADB on port 5555
Initializing cgroup subsys cpu
Linux version 3.10.0+ ( (gcc version 4.8 (GCC) ) #12 SMP Tue Sep 16 22:36:19 CEST 2014
CPU: AArch64 Processor [411fd070] revision 0
Machine: ranchu
debug: skip boot console de-registration.
Unknown earlyprintk arguments: ttyAMA0
PERCPU: Embedded 10 pages/cpu @ffffffc07ffdf000 s11456 r8192 d21312 u40960
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 517120
Kernel command line: console=ttyAMA0,38400 keep_bootcon earlyprintk=ttyAMA0
PID hash table entries: 4096 (order: 3, 32768 bytes)
Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
Memory: 2048MB = 2048MB total
Memory: 2058560k/2058560k available, 38592k reserved
Virtual kernel memory layout:
    vmalloc : 0xffffff8000000000 - 0xffffffbbffff0000   (245759 MB)
    vmemmap : 0xffffffbc00e00000 - 0xffffffbc02a00000   (    28 MB)
    modules : 0xffffffbffc000000 - 0xffffffc000000000   (    64 MB)
    memory  : 0xffffffc000000000 - 0xffffffc080000000   (  2048 MB)
      .init : 0xffffffc00057a000 - 0xffffffc0005a8cc0   (   188 kB)
      .text : 0xffffffc000080000 - 0xffffffc000579364   (  5093 kB)
      .data : 0xffffffc0005a9000 - 0xffffffc0005e7200   (   249 kB)
SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
Hierarchical RCU implementation.
 RCU restricting CPUs from NR_CPUS=4 to nr_cpu_ids=1.
NR_IRQS:64 nr_irqs:64 0
GIC CPU mask not found - kernel will fail to boot.
GIC CPU mask not found - kernel will fail to boot.
Architected local timer running at 62.50MHz (virt).
Console: colour dummy device 80x25
Calibrating delay loop (skipped), value calculated using timer frequency.. 125.00 BogoMIPS (lpj=625000)
pid_max: default: 32768 minimum: 301
Mount-cache hash table entries: 256
/cpus/cpu@0: Unknown CPU type
hw perfevents: no hardware support available
Brought up 1 CPUs
SMP: Total of 1 processors activated (125.00 BogoMIPS).
atomic64 test passed
NET: Registered protocol family 16
vdso: 2 pages (1 code, 1 data) at base ffffffc0005b1000
hw-breakpoint: found 6 breakpoint and 4 watchpoint registers.
software IO TLB [mem 0xbd400000-0xbd800000] (4MB) mapped at [ffffffc07d400000-ffffffc07d7fffff]
Serial: AMBA PL011 UART driver
9000000.pl011: ttyAMA0 at MMIO 0x9000000 (irq = 33) is a PL011 rev1
console [ttyAMA0] enabled
bio: create slab  at 0
SCSI subsystem initialized
Switching to clocksource arch_sys_counter
NET: Registered protocol family 2
TCP established hash table entries: 16384 (order: 6, 262144 bytes)
TCP bind hash table entries: 16384 (order: 6, 262144 bytes)
TCP: Hash tables configured (established 16384 bind 16384)
TCP: reno registered
UDP hash table entries: 1024 (order: 3, 32768 bytes)
UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
NET: Registered protocol family 1
RPC: Registered named UNIX socket transport module.
RPC: Registered udp transport module.
RPC: Registered tcp transport module.
RPC: Registered tcp NFSv4.1 backchannel transport module.
Unpacking initramfs...
Freeing initrd memory: 816K (ffffffc008000000 - ffffffc0080cc000)
fuse init (API version 7.22)
msgmni has been set to 4022
io scheduler noop registered
io scheduler cfq registered (default)
loop: module loaded
 vda: unknown partition table
 vdb: unknown partition table
 vdc: unknown partition table
tun: Universal TUN/TAP device driver, 1.6
tun: (C) 1999-2004 Max Krasnyansky 
mousedev: PS/2 mouse device common for all mice
input: qwerty2 as /devices/9040000.goldfish-events/input/input0
ashmem: initialized
logger: created 256K log 'log_main'
logger: created 256K log 'log_events'
logger: created 256K log 'log_radio'
logger: created 256K log 'log_system'
ip_tables: (C) 2000-2006 Netfilter Core Team
arp_tables: (C) 2002 David S. Miller
TCP: cubic registered
NET: Registered protocol family 10
ip6_tables: (C) 2000-2006 Netfilter Core Team
sit: IPv6 over IPv4 tunneling driver
NET: Registered protocol family 17
Bridge firewalling registered
Registering SWP/SWPB emulation handler
drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
Freeing unused kernel memory: 184K (ffffffc00057a000 - ffffffc0005a8000)
init (1): /proc/1/oom_adj is deprecated, please use /proc/1/oom_score_adj instead.
init: /dev/hw_random not found
init: /dev/hw_random not found
EXT4-fs (vda): mounted filesystem with ordered data mode. Opts: (null)
EXT4-fs (vdb): Ignoring removed nomblk_io_submit option
EXT4-fs (vdb): mounted filesystem with ordered data mode. Opts: nomblk_io_submit,errors=panic
EXT4-fs (vdc): Ignoring removed nomblk_io_submit option
EXT4-fs (vdc): mounted filesystem with ordered data mode. Opts: nomblk_io_submit,errors=panic
init: cannot find '/system/etc/', disabling 'flash_recovery'
healthd: BatteryVoltagePath not found
healthd: BatteryTemperaturePath not found
binder: 774:774 transaction failed 29189, size 0-0
logd.auditd: start
shell@generic_arm64:/ $ 

Wednesday, May 14, 2014

Mobile Device Protection Profile

In October 2013, US Government’s Common Criteria Evaluation and Validation Scheme (CCEVS) published the MDPP (Mobile Device) and MDMPP (Mobile Device Management) protection profiles. Protection profiles are entirely based on Common Criteria  (CC) security requirements and certification. 

The Common Criteria is an international standard adopted for security assessment, evaluation and certification of security features in the IT world.

I got a request for a PoV and started working on it, at least trying to understand the basis and finally end up writing this document:

Understanding MDPP, download it at the following address:

Friday, April 18, 2014

Mobile considerations on Heartbleed (Android)

Heartbleed became quickly popular due to the risks it poses to SSL privacy model. In real life, exploits and proof of concepts around showed that it's practically possible to steel credentials and certificates from an affected server. Being involved in Mobile Security, one of the most recurring questions I hear is: how Heartbleed impacts mobile world?

Heartbleed is an OpenSSL vuln, the "need to go, I am tired but must code this before" type, the classical vuln introduced when developing in a hurry, tired before going home at the end of your working hours. Only affected systems are the ones running OpenSSL. The core problem is the unsafe handling of a length parameter passed into the heartbeat payload which allow leak of information from the target host memory (returning part of the target stack content). Without going into details, this site provides enough insights:

Strip iOS and Windows Mobile out of the picture, Android is the only one using OpenSSL in his public AOSP.

When I think of Heartbleed, I tend to consider it as Server vulnerability, especially when looking at the logic of a possible real attack. From a profit standpoint, I really struggle imaging a complex attack scenario targeting a mobile client. Will discuss this with much detail later.

Let's first answer the one million dollar question, is it Android vulnerable? It depends, and of course, keep OpenSSL version in consideration.

Here you have a list of vulnerable OpenSSL versions:
  • OpenSSL 1.0.1 through 1.0.1f (inclusive) are vulnerable
  • OpenSSL 1.0.1g is NOT vulnerable
  • OpenSSL 1.0.0 branch is NOT vulnerable
  • OpenSSL 0.9.8 branch is NOT vulnerable
(Bug was introduced to OpenSSL in December 2011 and has been out in the wild since OpenSSL release 1.0.1 on 14th of March 2012. OpenSSL 1.0.1g released on 7th of April 2014 fixes the bug).

There is no point to get lost in the list, spend your time if you run a webserver or in general if you are exposing services based on OpenSSL (like SSL VPN software which should drive you crazy both server and client side). If your concern is Android, the two variables to play with are: version of OpenSSL and compile flag (-DOPENSSL_NO_HEARTBEAT).  Yes, the latter disables heartbeat functionalities at compile time, thus even if you are running on a vulnerable version, with the feature disabled you practically patched the issue at the root.

Now, let's go back to Android. Everything before version 4 (Ice Cream Sandwich) is running an old version of OpenSSL, not featuring heartbeat, thus clean and safe; end of the story, it was fast. Funny enough, against all my recommendations to avoid using pre-ICS versions, they are all not vulnerable. Android 4.0.0 and 4.0.4 (the first wide-spread ICS version) are running OpenSSL v1.0.0 which is again not vulnerable. Later versions are running on v1.0.1c. There we start worrying about it. 

All of a sudden, some enlightened engineer at Google decided that heartbeats are useless on a mobile client, who knows, it look like he knew about the vulnerability somehow :) (or at least detected something wrong in the piece of code) and disabled the feature at compile time starting from version 4.1.2. Said that, it looks that only Android 4.1.1 is vulnerable.

Andrew Blaich from Bluebox provided a table on his observations up to KitKat:

AOSP Version
OpenSSL Version
Vulnerable OpenSSL Version
Heartbeats Disabled
Overall Vulnerable

Another important problem to consider, adds Andrew, is that there is plenty of Android Apps that embed their own version of OpenSSL. If you are doing something like that while developing your App or your BSP/ROM, it's time to update and/or patch, issue new certificates and all the jazz you heard about.

Let's flip the coin. As a user you should know if your Apps are making this 'savvy' move to use their own OpenSSL.

To solve the issue, BlueBox released a scanner, available on the play store, which will scan your APKs and give an answer. I guess it needs privileges to run through.

Heartbleed Scanner Screenshot

Now, there are other couple of points I wish to consider:
  • how many Android 4.1.1 are out there?
  • what about the real impact? looking at the attack surface and considering a possible scenario, what an hacker could do?


The 4th of April, Google on a blog post states exactly the same thing: only Android 4.1.1 JellyBean could be affected by Heartbleed.

Google's statistics only show that over one-third of Android users are on some version in the 4.1.X range though, leaving it unclear just how many devices are vulnerable. It's a relatively small portion of the market.
Ad network firm Chitika ran an analysis of North American Web traffic from April 7 to April 13 for the Guardian, which show that 19% of Jelly Bean users were running the vulnerable 4.1.1 version. Now, it's up to you to decide if 19% is a small portion.

For non-rooted Android users which are affected, there is no way to patch the issue. The solution is a ROM (or BSP firmware) upgrade. Updates are usually released by hardware vendor's, you probably know, at notable slow pace. We can easily conclude that vulnerable clients will be around for a while. Rooted users could start looking to patched versions of the lib or to make their own patch recompiling the same version of OpenSSL they are running from the AOSP and messing around with the phone filesystem.


As a matter of fact, yes, clients are vulnerable. So far the attention has been focused on servers as they are much more open and profitable to exploitation. I have the feeling that the scenario won't change. For sure, I see space for improvement in client exploitation.

IBM Security Services is investigating additional methods of exploiting this vulnerability that are emerging to include Reverse Heartbleed exploitation as well as possible amplification attacks. The IBM MSS SOC has been researching both reverse Heartbleed and the possibility of Heartbleed Datagram TLS (DTLS) amplification attacks. IBM MSS SOC contends both attacks are valid and possible. Although similar to the Heartbleed attack, the reverse Heartbleed targets clients using OpenSSL 1.0.1-1.0.1f.

This blog describes the vulnerability from a source code standpoint. The bottom line message is that tls_process_heartbeat() is affected the same way of the more incriminated dtls_process_hearbeat(). This function is used also by client applications, thus not only servers are vuln as initially stated.

Due to the nature of the DTLS protocol and its use of UDP, there is the possibility of amplification attacks stemming from the use of DTLS. At this time, the SOC is unaware of any proof-of-concept code in the wild but will keep customers appraised as the situation develops. Xforce (IBM) is releasing IDPS updates for this vector at the time of this update. We will continue to incorporate IDPS coverage’s as they are released by their respective vendors.

I took this text out from the IBM Security Services MSS and ERS client report.

Without discussing too much development details, I found a module for metasploit to test the vulnerability, if you really need it when version crossed compile flag is not enough.

Another live tester for "reverse" vulnerability is here:
I am mainly concerned about VPN clients that uses OpenSSL; that's would worth the exploitation efforts.

Marc Rogers, principal security researcher with mobile security vendor Lookout Inc., said that while millions of devices may technically be vulnerable to Heartbleed due to the inclusion of a vulnerable OpenSSL version, many such devices might not have the necessary heartbeats functionality enabled, making an attack impossible.

Sensitive clients, like VPN or privacy holding apps (banking apps, social media, and in general any cloud client) that may or may not use its own OpenSSL are intrinsically at risk to expose keys. Be careful, I am not saying that data is likely to be considered in clear. Besides that, what are the real impacts on a plain vanilla Android?

Attack scenarios are high impractical. I am thinking of a browser client exposed; the leak of info could affect the SSL keys in use on the same session (the page which exploits the client), not a big deal, or any other tabs open at the same time. In the latter case, the attack should be targeted to the specific service with some evident limitations on the exploitability scenario. Another way the vulnerability could be exploited client side is via MiTM attack, terrible fascinating again back from the old times. Don't forget that heartbleed is supposed to be exploitable only after SSL handshake, thus you'll need to find a way to cheat on certificates validation of the mobile device to get something out of a serious service.

Exploiting client-side is much more difficult than server-side, requires more targeted preparation and finally type and amount of leaked data could be "not that interesting" to hackers (there is a size limit on what can be stolen). At the moment of writing, I am not aware of successful client-side exploits implementations.

Heartbleed is definitely a serious vulnerability to take care of immediately.